5.7 KiB
5.7 KiB
Tasks — react-ui i18n deferred tooling
Three independent workstreams. Stories (Phase 1) is the largest; the two scripts (Phases 2, 3) are smaller and can run in parallel.
Phase 1 — Stories for the new i18n surface
- 1.1
src/i18n/formatted-number/formatted-number.stories.tsx— default + playground + variants (Latin / Arabic-Indic / percent / unit notation,aspolymorphism). Wrapped in<TranslationProvider>+<RegistryProvider>+<ReactUiI18nBridge>. - 1.2
src/i18n/formatted-currency/formatted-currency.stories.tsx— USD / EUR / GBP / JPY across en-GB / fr-FR / zh-CN, display modes (symbol/narrowSymbol/code/name). - 1.3
src/i18n/formatted-date/formatted-date.stories.tsx—Date/ ISO / epoch ms inputs; preset names + rawIntl.DateTimeFormatOptions; invalid-input renders empty. - 1.4
src/i18n/formatted-list/formatted-list.stories.tsx— conjunction / disjunction / unit; long / short / narrow. - 1.5
src/i18n/formatted-relative-time/formatted-relative-time.stories.tsx— auto-mode (withfakeClockfor deterministic story snapshots), explicit unit, future / past. - 1.6
src/i18n/plural/plural.stories.tsx— en-GB / ar-AE / ru-RU showing different category buckets. - 1.7
src/i18n/formatted-message/formatted-message.stories.tsx— rich-text tag interpolation, plural viacount. - 1.8
src/i18n/react-ui-i18n-bridge/react-ui-i18n-bridge.stories.tsx— Radix<DirectionProvider>propagation demo (popover, dropdown-menu, dialog, tooltip rendered side-by-side under en-GB and ar-AE). - 1.9
src/i18n/formatted-cell/formatted-cell.stories.tsx— composed inside<DataTable>columns for each formatter kind. - 1.10
src/i18n/validation-message-bridge/validation-message-bridge.stories.tsx— bridge inside<Alert>and<Toast>. - 1.11
src/components/input/input-number/input-number.stories.tsx— en-GB / de-DE / ar-AE locales, controlled / uncontrolled, percent / currency display options. - 1.12 Story-snapshot test (mirroring existing
*.stories.test.tsxpattern in react-ui) for every new story.
Phase 2 — check:i18n-keys translation key drift gate
- 2.1 Pick the AST parser already used elsewhere in the repo for source walks (
@babel/parseris the typical choice; verify the catalog). - 2.2 Author
scripts/check-i18n-keys.ts. Walksrc/components/**/*.{ts,tsx}andsrc/i18n/**/*.{ts,tsx}. Detect:t("react-ui.…")/t("react-ui.…", …)tDynamic("react-ui.…")<FormattedMessage i18nKey="react-ui.…" /><Trans i18nKey="react-ui.…" />
- 2.3 Diff discovered keys against
src/locales/en-GB.json. Build the orphan list and the missing list. - 2.4 Author
scripts/check-i18n-keys.test.ts— fixture directory exercises both diagnostics + the happy path. - 2.5 Add
"check:i18n-keys": "bun scripts/check-i18n-keys.ts"topackage.json::scripts. - 2.6 Wire
check:i18n-keysintoturbo.json's lint pipeline so CI fails on drift. - 2.7 Run the script against the current source — expect zero diagnostics. If diagnostics appear, file each as a separate fix in this change.
Phase 3 — check:registry-eject shadcn ejection compile gate
- 3.1 Confirm the registry transform's exact rewriting rules (which import specifiers are rewritten, which preserved). Document at the top of the script.
- 3.2 Author
scripts/check-registry-eject.ts:- Read every
registry/r/<name>.json. - For each entry: copy listed source files into
mkdtempdirectory. - Apply registry transform.
- Synthesize a consumer
tsconfig.json(extends@suaveplan/typescript-config/library.json, declarespathsfor@suaveplan/react-i18n+ React peers). - Run
tsc --noEmitover the transformed tree. - On failure, surface the underlying tsc diagnostics with the registry-entry name as context.
- Read every
- 3.3 Detect missing registry entries — for every directory in
src/components/**/andsrc/i18n/**/that has a public default-exporting*.tsx, assert the matchingregistry/r/<name>.jsonexists. - 3.4 Author
scripts/check-registry-eject.test.ts— happy-path test (pick one trivial component + verify ejection compiles); failure-path tests (corrupt transform output, drop a registry entry). - 3.5 Add
"check:registry-eject": "bun scripts/check-registry-eject.ts"topackage.json::scripts. - 3.6 Wire
check:registry-ejectintoturbo.json's lint pipeline. - 3.7 Run the script against the current registry — expect zero diagnostics.
Phase 4 — Pre-publish gate + spec fold
- 4.1
bunx turbo lint typecheck test --filter=@suaveplan/react-uigreen. - 4.2
bunx turbo test:coverage --filter=@suaveplan/react-ui≥ 100 / 100 / 100 / 100 (story-snapshot + script tests must contribute to coverage). - 4.3
bunx turbo build --filter=@suaveplan/react-uigreen. - 4.4
bun run check:i18n-keyszero-defect. - 4.5
bun run check:registry-ejectzero-defect. - 4.6 §13 banned-pattern / missing-
.md/ barrel-shape / runner-import scans clean. - 4.7 Downstream sweep
bunx turbo test --filter=...@suaveplan/react-uigreen (sanity check; no runtime surface change expected). - 4.8 Fold spec deltas into
openspec/specs/react-ui-i18n/spec.md. The two new scripts get their own Requirements with verification scenarios; stories are an artifact-presence requirement (one Scenario per primitive:<feature>.stories.tsx exists). - 4.9 Update
STATUS.mdto reflect the closure of the deferred items. - 4.10 Run
bunx markdownlint-cli2 --fixacross touched markdown. - 4.11 Move
openspec/changes/react-ui-i18n-deferred-tooling/→openspec/archive/<yyyy-mm-dd>-react-ui-i18n-deferred-tooling/.