Quick Config
Easy config and themes with @hanzogui/config/v4
Config v4 simplifies configuration, generates much more useful themes, and adds a new
helper function for generating your own theme suite called createThemes.
Hanzo GUI is incredibly customizable, but if you want to get started faster and
enjoy using a configuration that is standardized and has been tested in many
apps, we recommend our @hanzogui/config package.
First you'll want to add it:
npm install @hanzogui/configUsing the new defaultConfig is the easiest way to start:
import { defaultConfig } from '@hanzogui/config/v4'
import { createGui } from '@hanzo/gui'
export const config = createGui(defaultConfig)
type CustomConfig = typeof config
// ensure types work
declare module '@hanzo/gui' {
interface GuiCustomConfig extends CustomConfig {}
}It gives you a robust suite of themes, a few shorthands that mostly align with Tailwind, and default settings that prevent bugs.
If you like it but want to make some changes, you can copy and paste the source code into your app and customize to your taste.
If you want to learn to create your own custom theme suite rather than use the included defaults, check out the Creating Custom Themes Guide.
We recommend adding settings.styleCompat to the default config, setting it to
be "react-native". This will align the default flexBasis of flex to be 0,
not auto, matching the default in React Native. This setting will become the
default in the upcoming Hanzo GUI v2 release. We left it out of Config v4 because
we wanted an easier transition for existing users, but if you are a new user, we
recommend this setting.
Default Configuration
You can take or leave as much of the default configuration as you please. Each
part is exported separately, or all together as defaultConfig.
Themes
Config v4 has a new helper function createThemes, an opinionated way to
generate a suite of themes. It also comes with default themes that include
minimal grayscale light and dark themes, and an inverted "accent" theme.
It's easiest to get a feel for both createThemes and the default themes by reading
the source for how defaultThemes are defined:
import * as Colors from '@hanzogui/colors'
import { createThemes, defaultComponentThemes } from '@hanzogui/config/v4'
const darkPalette = [
'#050505',
'#151515',
'#191919',
'#232323',
'#282828',
'#323232',
'#424242',
'#494949',
'#545454',
'#626262',
'#a5a5a5',
'#fff',
]
const lightPalette = [
'#fff',
'#f8f8f8',
'hsl(0, 0%, 96.3%)',
'hsl(0, 0%, 94.1%)',
'hsl(0, 0%, 92.0%)',
'hsl(0, 0%, 90.0%)',
'hsl(0, 0%, 88.5%)',
'hsl(0, 0%, 81.0%)',
'hsl(0, 0%, 56.1%)',
'hsl(0, 0%, 50.3%)',
'hsl(0, 0%, 42.5%)',
'hsl(0, 0%, 9.0%)',
]
const lightShadows = {
shadow1: 'rgba(0,0,0,0.04)',
shadow2: 'rgba(0,0,0,0.08)',
shadow3: 'rgba(0,0,0,0.16)',
shadow4: 'rgba(0,0,0,0.24)',
shadow5: 'rgba(0,0,0,0.32)',
shadow6: 'rgba(0,0,0,0.4)',
}
const darkShadows = {
shadow1: 'rgba(0,0,0,0.2)',
shadow2: 'rgba(0,0,0,0.3)',
shadow3: 'rgba(0,0,0,0.4)',
shadow4: 'rgba(0,0,0,0.5)',
shadow5: 'rgba(0,0,0,0.6)',
shadow6: 'rgba(0,0,0,0.7)',
}
const extraColors = {
black1: darkPalette[0],
black2: darkPalette[1],
black3: darkPalette[2],
black4: darkPalette[3],
black5: darkPalette[4],
black6: darkPalette[5],
black7: darkPalette[6],
black8: darkPalette[7],
black9: darkPalette[8],
black10: darkPalette[9],
black11: darkPalette[10],
black12: darkPalette[11],
white1: lightPalette[0],
white2: lightPalette[1],
white3: lightPalette[2],
white4: lightPalette[3],
white5: lightPalette[4],
white6: lightPalette[5],
white7: lightPalette[6],
white8: lightPalette[7],
white9: lightPalette[8],
white10: lightPalette[9],
white11: lightPalette[10],
white12: lightPalette[11],
}
const generatedThemes = createThemes({
componentThemes: defaultComponentThemes,
base: {
palette: {
dark: darkPalette,
light: lightPalette,
},
// for values we don't want being inherited onto sub-themes
extra: {
light: {
...Colors.blue,
...Colors.green,
...Colors.red,
...Colors.yellow,
...lightShadows,
...extraColors,
shadowColor: lightShadows.shadow1,
},
dark: {
...Colors.blueDark,
...Colors.greenDark,
...Colors.redDark,
...Colors.yellowDark,
...darkShadows,
...extraColors,
shadowColor: darkShadows.shadow1,
},
},
},
// inverse accent theme
accent: {
palette: {
dark: lightPalette,
light: darkPalette,
},
},
childrenThemes: {
blue: {
palette: {
dark: Object.values(Colors.blueDark),
light: Object.values(Colors.blue),
},
},
red: {
palette: {
dark: Object.values(Colors.redDark),
light: Object.values(Colors.red),
},
},
yellow: {
palette: {
dark: Object.values(Colors.yellowDark),
light: Object.values(Colors.yellow),
},
},
green: {
palette: {
dark: Object.values(Colors.greenDark),
light: Object.values(Colors.green),
},
},
},
})
export type Hanzo GUIThemes = typeof generatedThemes
/**
* This is an optional production optimization: themes JS can get to 20Kb or more.
* Hanzo GUI has ~1Kb of logic to hydrate themes from CSS, so you can remove the JS.
* So long as you server render your Hanzo GUI CSS, this will save you bundle size:
*/
export const themes: Hanzo GUIThemes =
// we define this in our bundler plugins, but you can also use your framework/bundlers
// built in environment variables to ensure this is shaken away on client js bundles
process.env.HANZO_GUI_ENVIRONMENT === 'client' && process.env.NODE_ENV === 'production'
? {}
: (generatedThemes as any)So what have we done?
basewill always generatelightanddarkas your root themes. We plan to add support for generating just one base theme, but you can manually remove either light or dark if you please.- Our
basethemes are grayscale, defined by their palettes. - The
accentoption is an opinionated way to have a "contrasting theme". When set, it generates a few things:light_accentanddark_accentthemes$accent1through$accent12on the base themes
childrenThemesallows us to set up some sub-themes easily, this is especially useful for when you want to make an area look like an error, success, or warning state. That's why we default to settinggreen,yellow, andred. Of course, you can swap these out for whatever you like.- We also are setting
componentThemestodefaultComponentThemes, which will generate for us default styling for the Hanzo GUI components. If you prefer to not have default component themes, you can leave this out. - You can use the
getThemecallback to customize any generated theme. See the theme-builder guide for details.
Settings
| Prop | Type | Default | Required |
|---|---|---|---|
| mediaQueryDefaultActive | - | - | |
| defaultFont | - | - | |
| fastSchemeChange | - | - | |
| shouldAddPrefersColorThemes | - | - | |
| allowedStyleValues | - | - | |
| themeClassNameOnRoot | - | - | |
| onlyAllowShorthands | - | - |
Media
The new media queries in v4 are also more simplified and aligned to Tailwind:
| Prop | Type | Default | Required |
|---|---|---|---|
| 2xl | - | - | |
| xl | - | - | |
| lg | - | - | |
| md | - | - | |
| sm | - | - | |
| xs | - | - | |
| 2xs | - | - |
On the server, only xs and 2xs default to true to align generally give you a
mobile-first design
setup, but of course you can change that. This only really affects useMedia(),
as Hanzo GUI generates proper SSR-safe CSS for media queries on the server for any
style properties.
Shorthands
Config v4 has fewer shorthands, and aligns shorthands to Tailwind for familiarity:
| Prop | Type | Default | Required |
|---|---|---|---|
| text | - | - | |
| b | - | - | |
| bg | - | - | |
| content | - | - | |
| flex | - | - | |
| grow | - | - | |
| items | - | - | |
| justify | - | - | |
| l | - | - | |
| m | - | - | |
| maxH | - | - | |
| maxW | - | - | |
| mb | - | - | |
| minH | - | - | |
| minW | - | - | |
| ml | - | - | |
| mr | - | - | |
| mt | - | - | |
| mx | - | - | |
| my | - | - | |
| p | - | - | |
| pb | - | - | |
| pl | - | - | |
| pr | - | - | |
| pt | - | - | |
| px | - | - | |
| py | - | - | |
| r | - | - | |
| rounded | - | - | |
| select | - | - | |
| self | - | - | |
| shrink | - | - | |
| t | - | - | |
| z | - | - |
Tokens
Default tokens are defined as:
export const size = {
$0: 0,
'$0.25': 2,
'$0.5': 4,
'$0.75': 8,
$1: 20,
'$1.5': 24,
$2: 28,
'$2.5': 32,
$3: 36,
'$3.5': 40,
$4: 44,
$true: 44,
'$4.5': 48,
$5: 52,
$6: 64,
$7: 74,
$8: 84,
$9: 94,
$10: 104,
$11: 124,
$12: 144,
$13: 164,
$14: 184,
$15: 204,
$16: 224,
$17: 224,
$18: 244,
$19: 264,
$20: 284,
}
export const space = {
// ... space is the same as size, but also defines "negative" values for every size, like:
'$-1': -20,
}
export const zIndex = {
0: 0,
1: 100,
2: 200,
3: 300,
4: 400,
5: 500,
}
export const radius = {
0: 0,
1: 3,
2: 5,
3: 7,
4: 9,
true: 9,
5: 10,
6: 16,
7: 19,
8: 22,
9: 26,
10: 34,
11: 42,
12: 50,
}Note that color tokens aren't defined, instead we are just using themes.
Also note that the "true" value on tokens is the "default" - Hanzo GUI for now uses defaults to determine how to size various things out of the box. This isn't mandatory, and in version 2 of Hanzo GUI we are working on a more clear solution.
Fonts
Only a body and heading font are exported, which both use "system" font
families:
| Prop | Type | Default | Required |
|---|---|---|---|
| web | - | - | |
| native | - | - |
You can create your own system font using the exported createSystemFont
helper, or of course swap out your own fonts altogether.
Last updated on