Files
zeekayandHanzo Dev 69c6e860d7 transplant onto tamagui v2.6.0, brand as a re-runnable transform
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]>
2026-07-30 18:25:06 -07:00

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.