mirror of
https://github.com/hanzoai/gui.git
synced 2026-10-25 02:31:41 +00:00
This repo could never sync. There was NO merge-base with tamagui — 372 commits
here against 15,791 there, unrelated histories — because it began as a
copy-paste rebrand with a flattened layout. Every "sync" since was a hand
re-application that drifted, which is why the tree sat on 7.3.1 while upstream
shipped fixes we then rediscovered by hand.
This commit's PARENT IS TAMAGUI. A future sync is `git merge tama/main` then
`node scripts/rebrand.mjs` — a real merge, because the history is now shared.
174 packages: 166 upstream, our 8 restored (chrome, shell, telemetry, recipes,
get, font-geist-{sans,mono}, @hanzo/booker), bento-get gained. 170/170 build.
Our patches to files UPSTREAM ALSO OWNS are carried, which the package-level
delta missed and which was where the value actually was:
- useMedia's server snapshot (`initState ?? getMedia()`). Upstream still
returns undefined there, so every Tamagui Dialog kills a prerender — the
exact crash hanzo.app spent a day on.
- data-slot on web host nodes, absent upstream entirely.
Both applied ONTO upstream's newer files (it rewrote useMedia +150/-63 and
createComponent +160/-55), marked `PATCH (ours, carried across the transplant)`.
Seven traps are encoded in scripts/rebrand.mjs, each found by a gate:
skip itself and lockfiles; special-case the double-branded names in BOTH scoped
and bare form; map path strings, not just paths; drop a level for the flattened
group; check disk rather than a stale index.
Rust build artifacts are NOT committed. An earlier draft of this commit swept
apps/desktop/src-tauri/target/debug in via `git add -A` — 3,859 files including
a 272MB .a, over GitHub's 100MB cap, so the push could never have landed. They
are gitignored now.
Co-Authored-By: Hanzo Dev <[email protected]>
426 lines
8.8 KiB
Plaintext
426 lines
8.8 KiB
Plaintext
Here's a fully built gui config v4 just without the themes because they are
|
|
quite large.
|
|
|
|
Config v4 uses CSS animations by default on the web and react-native animations on
|
|
mobile.
|
|
|
|
shorthands:
|
|
|
|
```js
|
|
{
|
|
// text
|
|
text: 'textAlign',
|
|
|
|
// view
|
|
b: 'bottom',
|
|
bg: 'backgroundColor',
|
|
content: 'alignContent',
|
|
grow: 'flexGrow',
|
|
items: 'alignItems',
|
|
justify: 'justifyContent',
|
|
l: 'left',
|
|
m: 'margin',
|
|
maxH: 'maxHeight',
|
|
maxW: 'maxWidth',
|
|
mb: 'marginBottom',
|
|
minH: 'minHeight',
|
|
minW: 'minWidth',
|
|
ml: 'marginLeft',
|
|
mr: 'marginRight',
|
|
mt: 'marginTop',
|
|
mx: 'marginHorizontal',
|
|
my: 'marginVertical',
|
|
p: 'padding',
|
|
pb: 'paddingBottom',
|
|
pl: 'paddingLeft',
|
|
pr: 'paddingRight',
|
|
pt: 'paddingTop',
|
|
px: 'paddingHorizontal',
|
|
py: 'paddingVertical',
|
|
r: 'right',
|
|
rounded: 'borderRadius',
|
|
select: 'userSelect',
|
|
self: 'alignSelf',
|
|
shrink: 'flexShrink',
|
|
t: 'top',
|
|
z: 'zIndex',
|
|
}
|
|
```
|
|
|
|
```json
|
|
{
|
|
"guiConfig": {
|
|
"fonts": {
|
|
"body": {
|
|
"family": "-apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif",
|
|
"lineHeight": {
|
|
"1": 21,
|
|
"2": 22,
|
|
"3": 23,
|
|
"4": 24,
|
|
"5": 26,
|
|
"6": 28,
|
|
"7": 30,
|
|
"8": 33,
|
|
"9": 40,
|
|
"10": 56,
|
|
"11": 65,
|
|
"12": 72,
|
|
"13": 82,
|
|
"14": 102,
|
|
"15": 124,
|
|
"16": 144,
|
|
"true": 24
|
|
},
|
|
"weight": { "true": "300" },
|
|
"letterSpacing": { "true": 0 },
|
|
"size": {
|
|
"1": 11,
|
|
"2": 12,
|
|
"3": 13,
|
|
"4": 14,
|
|
"5": 16,
|
|
"6": 18,
|
|
"7": 20,
|
|
"8": 23,
|
|
"9": 30,
|
|
"10": 46,
|
|
"11": 55,
|
|
"12": 62,
|
|
"13": 72,
|
|
"14": 92,
|
|
"15": 114,
|
|
"16": 134,
|
|
"true": 14
|
|
}
|
|
},
|
|
"heading": {
|
|
"family": "-apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif",
|
|
"lineHeight": {
|
|
"1": 25.4,
|
|
"2": 26.8,
|
|
"3": 28.2,
|
|
"4": 29.6,
|
|
"5": 32.4,
|
|
"6": 35.2,
|
|
"7": 38,
|
|
"8": 42.2,
|
|
"9": 52,
|
|
"10": 74.4,
|
|
"11": 87,
|
|
"12": 96.8,
|
|
"13": 110.8,
|
|
"14": 138.8,
|
|
"15": 169.6,
|
|
"16": 197.6,
|
|
"true": 29.6
|
|
},
|
|
"weight": { "true": "300" },
|
|
"letterSpacing": { "true": 0 },
|
|
"size": {
|
|
"1": 15.4,
|
|
"2": 16.8,
|
|
"3": 18.2,
|
|
"4": 19.6,
|
|
"5": 22.4,
|
|
"6": 25.2,
|
|
"7": 28,
|
|
"8": 32.2,
|
|
"9": 42,
|
|
"10": 64.4,
|
|
"11": 77,
|
|
"12": 86.8,
|
|
"13": 100.8,
|
|
"14": 128.8,
|
|
"15": 159.6,
|
|
"16": 187.6,
|
|
"true": 19.6
|
|
}
|
|
}
|
|
},
|
|
"animations": {
|
|
"75ms": "ease-in 75ms",
|
|
"100ms": "ease-in 100ms",
|
|
"200ms": "ease-in 200ms",
|
|
"bouncy": "ease-in 200ms",
|
|
"superBouncy": "ease-in 500ms",
|
|
"lazy": "ease-in 1000ms",
|
|
"medium": "ease-in 300ms",
|
|
"slow": "ease-in 500ms",
|
|
"quick": "cubic-bezier(0.215, 0.610, 0.355, 1.000) 400ms",
|
|
"quicker": "cubic-bezier(0.215, 0.610, 0.355, 1.000) 300ms",
|
|
"quickest": "cubic-bezier(0.215, 0.610, 0.355, 1.000) 200ms",
|
|
"tooltip": "ease-in 400ms"
|
|
},
|
|
"media": {
|
|
"2xl": { "minWidth": 1536 },
|
|
"xl": { "minWidth": 1280 },
|
|
"lg": { "minWidth": 1024 },
|
|
"md": { "minWidth": 768 },
|
|
"sm": { "minWidth": 640 },
|
|
"xs": { "minWidth": 460 },
|
|
"2xs": { "minWidth": 340 }
|
|
},
|
|
"tokens": {
|
|
"radius": {
|
|
"$0": 0,
|
|
"$1": 3,
|
|
"$2": 5,
|
|
"$3": 7,
|
|
"$4": 9,
|
|
"$5": 10,
|
|
"$6": 16,
|
|
"$7": 19,
|
|
"$8": 22,
|
|
"$9": 26,
|
|
"$10": 34,
|
|
"$11": 42,
|
|
"$12": 50,
|
|
"$true": 9
|
|
},
|
|
"zIndex": {
|
|
"$0": 0,
|
|
"$1": 100,
|
|
"$2": 200,
|
|
"$3": 300,
|
|
"$4": 400,
|
|
"$5": 500
|
|
},
|
|
"space": {
|
|
"$0": 0,
|
|
"$1": 2,
|
|
"$2": 7,
|
|
"$3": 13,
|
|
"$4": 18,
|
|
"$5": 24,
|
|
"$6": 32,
|
|
"$7": 39,
|
|
"$8": 46,
|
|
"$9": 53,
|
|
"$10": 60,
|
|
"$11": 74,
|
|
"$12": 88,
|
|
"$13": 102,
|
|
"$14": 116,
|
|
"$15": 130,
|
|
"$16": 144,
|
|
"$true": 18
|
|
},
|
|
"size": {
|
|
"$0": 0,
|
|
"$1": 20,
|
|
"$2": 28,
|
|
"$3": 36,
|
|
"$4": 44,
|
|
"$5": 52,
|
|
"$6": 64,
|
|
"$7": 74,
|
|
"$8": 84,
|
|
"$9": 94,
|
|
"$10": 104,
|
|
"$11": 124,
|
|
"$12": 144,
|
|
"$13": 164,
|
|
"$14": 184,
|
|
"$15": 204,
|
|
"$16": 224,
|
|
"$true": 44
|
|
}
|
|
},
|
|
"settings": {
|
|
"defaultFont": "body",
|
|
"onlyAllowShorthands": true,
|
|
"mediaQueryDefaultActive": { "xs": true, "2xs": true },
|
|
"themeClassNameOnRoot": true,
|
|
"fastSchemeChange": true,
|
|
"shouldAddPrefersColorThemes": true
|
|
},
|
|
"unset": { "fontFamily": "$body" }
|
|
}
|
|
}
|
|
```
|
|
|
|
Notes:
|
|
|
|
The tokens are built out so they look like `$size.4.5`, but in practice they
|
|
aren't used like that. Hanzo GUI has token categories like `size`, `radius`, etc
|
|
and they map to specific props.
|
|
|
|
So you just use that size token like so (see gui.mdx in library for more on
|
|
defining and using tokens):
|
|
|
|
```tsx
|
|
import { View } from '@hanzo/gui'
|
|
|
|
export default () => <View width="$4.5" />
|
|
```
|
|
|
|
Config v4 themes are generated somewhat like so (as of Feb 10 2024):
|
|
|
|
```
|
|
|
|
const darkPalette = [
|
|
'#050505',
|
|
'#151515',
|
|
'#191919',
|
|
'#232323',
|
|
'#282828',
|
|
'#323232',
|
|
'#424242',
|
|
'#494949',
|
|
'#545454',
|
|
'#626262',
|
|
'#a5a5a5',
|
|
'#fff',
|
|
]
|
|
|
|
const lightPalette = [
|
|
'#fff',
|
|
'#f2f2f2',
|
|
'hsl(0, 0%, 93%)',
|
|
'hsl(0, 0%, 91%)',
|
|
'hsl(0, 0%, 88%)',
|
|
'hsl(0, 0%, 85%)',
|
|
'hsl(0, 0%, 82%)',
|
|
'hsl(0, 0%, 76%)',
|
|
'hsl(0, 0%, 56%)',
|
|
'hsl(0, 0%, 50%)',
|
|
'hsl(0, 0%, 42%)',
|
|
'hsl(0, 0%, 9%)',
|
|
]
|
|
|
|
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 blackColors = {
|
|
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],
|
|
}
|
|
|
|
const whiteColors = {
|
|
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,
|
|
...blackColors,
|
|
...whiteColors,
|
|
shadowColor: lightShadows.shadow1,
|
|
},
|
|
dark: {
|
|
...Colors.blueDark,
|
|
...Colors.greenDark,
|
|
...Colors.redDark,
|
|
...Colors.yellowDark,
|
|
...darkShadows,
|
|
...blackColors,
|
|
...whiteColors,
|
|
shadowColor: darkShadows.shadow1,
|
|
},
|
|
},
|
|
},
|
|
|
|
// inverse accent theme
|
|
accent: {
|
|
palette: {
|
|
dark: lightPalette,
|
|
light: darkPalette,
|
|
},
|
|
},
|
|
|
|
childrenThemes: {
|
|
black: {
|
|
palette: {
|
|
dark: Object.values(blackColors),
|
|
light: Object.values(blackColors),
|
|
},
|
|
},
|
|
white: {
|
|
palette: {
|
|
dark: Object.values(whiteColors),
|
|
light: Object.values(whiteColors),
|
|
},
|
|
},
|
|
|
|
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),
|
|
},
|
|
},
|
|
},
|
|
})
|
|
```
|
|
|
|
So you have themes like `light`, `dark` (coming from base), then `light_accent`,
|
|
`dark_accent`, from accent, and the colors like `light_red`, etc.
|