mirror of
https://github.com/hanzoai/gui.git
synced 2026-10-25 02:31:41 +00:00
Eradicate every upstream-fork token from source. Scope is the published
hanzogui ecosystem — the artifacts on npm (@hanzogui/*@7.0.0) are already
clean; this sweep brings the source tree to parity.
Categories handled (in sed precedence order to avoid token collisions):
- URL rewrites: github.com/tamagui/tamagui -> github.com/hanzoai/gui,
tamagui.dev -> gui.hanzo.ai
- Package namespace: @tamagui/X -> @hanzogui/X (imports, package.json deps,
__tests__ fixtures, build scripts)
- Env vars: NEXT_PUBLIC_IS_TAMAGUI_*, IS_TAMAGUI_*, DEBUG_TAMAGUI_*,
TAMAGUI_* (TARGET, IS_SERVER/CLIENT, ENVIRONMENT, OPTIMIZE_THEMES,
HEADLESS, DEBUG, KEEP_THEMES, PACKAGE_EXPORTS, PRO_SECRET, etc.) all
collapse to GUI_* prefix (short, matches @hanzogui/ namespace ergonomics)
- Vite envPrefix: ['TAMAGUI_'] -> ['GUI_'] in pkgs/compiler/vite-plugin
- PascalCase identifiers: Tamagui -> Hanzogui (any remaining
TamaguiCustomConfig, TamaguiInternalConfig, etc. in source)
- Lowercase strings/comments/log labels: tamagui -> hanzogui
- Filename: scripts/rename-from-tamagui.sh -> scripts/rename-from-tama.sh
(and the script's internal rules were rewritten to be self-consistent —
it still consumes upstream tamagui sources and produces hanzogui output)
- Dockerfile.local ARG names: ARG IS_TAMAGUI_DEV -> ARG IS_GUI_DEV,
ARG TAMAGUI_PRO_SECRET -> ARG GUI_PRO_SECRET, etc.
- .env.development: NEXT_PUBLIC_IS_TAMAGUI_DEV -> NEXT_PUBLIC_IS_GUI_DEV
- bun.lock regenerated via bun install
Decisions on edge cases:
- .gitignore / .dockerignore / .oxfmtrc.jsonc / templates: kept .tamagui
entries alongside the new .hanzogui entries as safety so legacy cache
directories from older installations are still ignored. Net additive.
- pkgs/packages/build/__tests__/fixtures/{simple,watch}-package: the fixture
+ builder (hanzogui-build.js) + integration.test.ts all reference
TAMAGUI_TARGET symmetrically (test asserts builder DCE-eliminates it).
Renamed all three to GUI_TARGET — test contract is preserved end-to-end.
- pkgs/compiler/static/src/helpers/requireHanzoguiCore.ts: file was already
renamed; internals already use HanzoguiPlatform / @hanzogui/core. No-op.
- plans/toast2.md: renamed to use hanzogui (no longer tracking upstream
tamagui issues — this fork is independent).
- assets/banners.sketch: binary Sketch file (zip archive). Skipped — same
treatment as svg/plist/pbxproj. Internal XML may still contain "tamagui"
but it's only visible inside the design tool.
- bun.lock: 2 remaining @tamagui/constants references come from third-party
transitive (@take-out/helpers depends on it). Cannot rewrite upstream
package metadata.
- LICENSE files (root + per-pkg): preserved unchanged. MIT attribution to
Tamagui Inc is a legal requirement.
- .git/config upstream remote: untouched (per task spec).
- pkgs/ui/switch/src/Switch.draggable-tmp: scratchpad, left alone.
Smoke tests:
- bun install: clean (lockfile regenerated, 1 package installed)
- @hanzogui/constants: builds in 302 ms
- @hanzogui/web (200+ source files): builds in 4187 ms
- @hanzogui/vite-plugin: builds in 997 ms
- @hanzogui/static: builds in 2547 ms
Residual count after sweep:
- git grep -ci tamagui (excluding LICENSE, lockfiles, binaries, draggable-tmp,
rename script, intentional .gitignore safety entries): 0 source matches.
158 files changed.
125 lines
3.5 KiB
TypeScript
125 lines
3.5 KiB
TypeScript
import dedent from 'dedent'
|
|
import * as React from 'react'
|
|
import { afterAll, beforeAll, describe, expect, test } from 'vitest'
|
|
import { mkdirSync, writeFileSync, rmSync, existsSync } from 'node:fs'
|
|
import { join } from 'node:path'
|
|
|
|
import { extractForWeb } from './lib/extract'
|
|
|
|
Error.stackTraceLimit = Number.MAX_SAFE_INTEGER
|
|
process.env.GUI_TARGET = 'web'
|
|
window['React'] = React
|
|
|
|
describe('styled() tests', () => {
|
|
test('loads dynamic styled() in file and extracts CSS', async () => {
|
|
const output = await extractForWeb(
|
|
dedent`
|
|
import { MyStack } from '@hanzogui/test-design-system'
|
|
import { styled } from '@hanzogui/core'
|
|
|
|
// not exported
|
|
const InlineStyled = styled(MyStack, {
|
|
backgroundColor: 'orange'
|
|
})
|
|
|
|
export function Test() {
|
|
return <InlineStyled />
|
|
}
|
|
`,
|
|
{ options: { enableDynamicEvaluation: true } }
|
|
)
|
|
if (!output) {
|
|
throw new Error(`No output`)
|
|
}
|
|
|
|
// styled() extraction should produce CSS rules for backgroundColor
|
|
expect(output.styles).toContain('background-color')
|
|
expect(output.styles).toContain('orange')
|
|
// should also extract the JSX usage
|
|
expect(output.js).toContain('className')
|
|
})
|
|
|
|
test('extracts to className at call-site', async () => {
|
|
const output = await extractForWeb(`
|
|
import { MyStack } from '@hanzogui/test-design-system'
|
|
|
|
export function Test() {
|
|
return <MyStack />
|
|
}
|
|
`)
|
|
if (!output) {
|
|
throw new Error(`No output`)
|
|
}
|
|
|
|
expect(output.js).toMatchSnapshot()
|
|
expect(output.styles).toMatchSnapshot()
|
|
})
|
|
|
|
describe('cross-file styled() optimization', () => {
|
|
const tmpDir = join(__dirname, '.tmp-cross-file-test')
|
|
const componentFile = join(tmpDir, 'MyBox.tsx')
|
|
|
|
beforeAll(() => {
|
|
mkdirSync(tmpDir, { recursive: true })
|
|
writeFileSync(
|
|
componentFile,
|
|
dedent`
|
|
import { styled, View } from '@hanzogui/core'
|
|
|
|
export const MyBox = styled(View, {
|
|
backgroundColor: 'red',
|
|
padding: 10,
|
|
})
|
|
`
|
|
)
|
|
})
|
|
|
|
afterAll(() => {
|
|
if (existsSync(tmpDir)) {
|
|
rmSync(tmpDir, { recursive: true })
|
|
}
|
|
})
|
|
|
|
test('extracts CSS for styled component imported from another file', async () => {
|
|
const componentSource = dedent`
|
|
import { styled, View } from '@hanzogui/core'
|
|
|
|
export const MyBox = styled(View, {
|
|
backgroundColor: 'red',
|
|
padding: 10,
|
|
})
|
|
`
|
|
|
|
// first process the component file (like vite plugin would)
|
|
const componentOutput = await extractForWeb(componentSource, {
|
|
sourcePath: componentFile,
|
|
options: { enableDynamicEvaluation: true },
|
|
})
|
|
expect(componentOutput).toBeTruthy()
|
|
expect(componentOutput!.styles).toContain('background-color')
|
|
|
|
// now process the consumer file - MyBox should be in the dynamic cache
|
|
const consumerSource = dedent`
|
|
import { MyBox } from './MyBox'
|
|
|
|
export function Test() {
|
|
return <MyBox />
|
|
}
|
|
`
|
|
|
|
const consumerPath = join(tmpDir, 'Consumer.tsx')
|
|
const output = await extractForWeb(consumerSource, {
|
|
sourcePath: consumerPath,
|
|
options: { enableDynamicEvaluation: true },
|
|
})
|
|
|
|
if (!output) {
|
|
throw new Error(`No output - file was skipped entirely`)
|
|
}
|
|
|
|
// the consumer file should get className optimization
|
|
expect(output.js).toContain('className')
|
|
})
|
|
})
|
|
})
|