Files
zeekay 828edc8024 chore: rip all TAMAGUI/Tamagui/tamagui refs, replace with HANZOGUI/Hanzogui/hanzogui
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.
2026-05-26 17:47:23 -07:00

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')
})
})
})