Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 0 additions & 96 deletions .eslintrc

This file was deleted.

2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
18
22
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# @devseed-ui/hug-chakra

## 0.1.0
Beta release
Beta release

## 2.0.0
Major release with Chakra UI v3 and React 19 requirement.
65 changes: 36 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ https://user-images.githubusercontent.com/1090606/156192701-350da28a-7bf4-4129-a
```
</details>

As you can see from the video, the grid will always be centered on the page (with a maximum width bound to the theme property `config.hug.layoutMax`), the leading/trailing columns will take up the rest of the space and will shrink until they disappear.
As you can see from the video, the grid will always be centered on the page (with a maximum width as defined in the [component recipe](./lib/hug.recipe.ts)), the leading/trailing columns will take up the rest of the space and will shrink until they disappear.
The centered grid will also always have a buffer from the side of the page which is something that does not exist in a traditional css grid.

This approach allows the creation of complex and interesting element placement. An example is a block that would be "bleeding" out of the page content (common with images).
Expand Down Expand Up @@ -99,9 +99,11 @@ content-end
full-end
```

_**Note**: Even though the line name `content-1` does not exist, it is the same as `content-start`. We considered it a better expertience to have consistent start and end names for the content (`content-start`/`content-end`)._
> [!NOTE]
> Even though the line name `content-1` does not exist, it is the same as `content-start`. We considered it a better experience to have consistent start and end names for the content (`content-start`/`content-end`)._

_**Caveat**: Lines `content-5` though `content-12` will exist depending on the media query. For example, for small screens you'll have `full-start`, `content-start`, `content-2`, `content-3`, `content-4`, `content-end`, `full-end`._
> [!IMPORTANT]
> Lines `content-5` though `content-12` will exist depending on the media query. For example, for small screens you'll have `full-start`, `content-start`, `content-2`, `content-3`, `content-4`, `content-end`, `full-end`._

## Nested Hug

Expand Down Expand Up @@ -151,39 +153,44 @@ Example:
```

## Configuring Hug
The values used by HUG can be configured in the Chakra UI theme. Since they do not necessarily refer to css properties, they're under the `config` property of the theme.
The hug config must be added to the Chakra UI theme before using the Hug component.
```js
import { createSystem, defaultConfig, defineConfig } from '@chakra-ui/react';
import { hugConfig } from '@devseed-ui/hug-chakra';

const config = defineConfig({
// Your custom theme values here
});

export default createSystem(defaultConfig, hugConfig, config);
```

The values used by HUG can then be customized in the Chakra UI theme as a recipe under the name `hug`.

The default values are:
```js
{
layoutMax: 'container.xl',
gaps: {
base: '4',
md: '8',
lg: '12'
},
columns: {
base: 4,
md: 8,
lg: 12
theme: {
recipes: {
hug: {
base: {
maxW: '8xl',
gap: {
base: 4,
md: 8,
lg: 12
},
columns: {
base: 4,
md: 8,
lg: 12
}
}
}
}
}
}
```

To change them you can use the `extendHugConfig` function from HUG together with the `extendTheme` function from Chakra UI:
```js
import { extendTheme } from '@chakra-ui/react';
import { extendHugConfig } from '@devseed-ui/hug-chakra';

export default extendTheme({
config: {
...extendHugConfig({
layoutMax: 'container.2xl'
})
}
});
```

## Usage details

### Nested Hug needs to be a direct descendant of another Hug
Expand Down
59 changes: 59 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import globals from 'globals';
import pluginJs from '@eslint/js';
import tseslint from 'typescript-eslint';
import pluginReact from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks';
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';

/** @type {import('eslint').Linter.Config[]} */
export default [
{
files: ['**/*.{js,mjs,cjs,ts,jsx,tsx}'],
settings: { react: { version: 'detect' } },
languageOptions: { ecmaVersion: 2020, globals: globals.browser },
plugins: { 'react-hooks': reactHooks }
},
pluginJs.configs.recommended,
...tseslint.configs.recommended,
pluginReact.configs.flat.recommended,
eslintPluginPrettierRecommended,
{
name: 'Custom Rules',
rules: {
// Helps with cleaning debug statements by erroring on console.
'no-console': 'error',
// It's no longer needed to import React, so this just prevents weird
// errors when you don't.
'react/react-in-jsx-scope': 'off',
// Array indexes as keys should not be used. The occasional time it is
// needed, an ignore can be added.
'react/no-array-index-key': 'error',
// Helps with enforcing rules of hooks. Very helpful to catch wrongly
// placed hooks, like conditional usage.
'react-hooks/rules-of-hooks': 'error',
// Ensure that components are PascalCase
'react/jsx-pascal-case': 'error',
// Force self closing components when there are no children.
// Prevents `<MyComp prop='1'></MyComp>`
'react/self-closing-comp': 'error',
// Disable unused vars, handles TS-specific cases (type params,
// interfaces) better than base rule.
// https://typescript-eslint.io/rules/no-unused-vars/#what-benefits-does-this-rule-have-over-typescript
'@typescript-eslint/no-unused-vars': [
'error',
{
args: 'all',
argsIgnorePattern: '^_',
caughtErrors: 'all',
caughtErrorsIgnorePattern: '^_',
destructuredArrayIgnorePattern: '^_',
varsIgnorePattern: '^_',
ignoreRestSiblings: true
}
],
// Warn when `any` type is used. It's sometimes necessary, but should be
// avoided when possible.
'@typescript-eslint/no-explicit-any': 'warn'
}
}
];
31 changes: 8 additions & 23 deletions lib/config.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,10 @@
export interface HugConfigProps {
layoutMax: string;
gaps: Record<string, string>;
columns: Record<string, number>;
}
import { defineConfig } from '@chakra-ui/react';
import { hugRecipe } from './hug.recipe';

export const HugConfig = {
layoutMax: 'container.xl',
gaps: {
base: '4',
md: '8',
lg: '12'
},
columns: {
base: 4,
md: 8,
lg: 12
export const hugConfig = defineConfig({
theme: {
recipes: {
hug: hugRecipe
}
}
};

export function extendHugConfig(config: Partial<HugConfigProps>): {
hug: HugConfigProps;
} {
return { hug: { ...HugConfig, ...config } };
}
});
17 changes: 17 additions & 0 deletions lib/hug.recipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { defineRecipe } from '@chakra-ui/react';

export const hugRecipe = defineRecipe({
base: {
maxW: '8xl',
gap: {
base: 4,
md: 8,
lg: 12
},
columns: {
base: 4,
md: 8,
lg: 12
}
}
});
Loading