7.7 KiB
7.7 KiB
tasks — enterprise-react-ui-theme-dracula
0. Pre-flight (non-negotiable)
- 0.1 Confirm clean working tree (
git statusreports nothing) and no in-flight worktrees with uncommitted work (git worktree listthengit statusin each) - 0.2 If any worktrees exist under
.claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against. - 0.3 Confirm the package set in
MANIFEST.mdmatchesfind packages -maxdepth 3 -name package.jsoncount. Drift here means a prior change archived without regenerating the manifest.
1. Package scaffolding
- 1.1 Create
packages/react/react-ui-theme-dracula/directory. - 1.2 Author
package.jsonat version0.1.0with peer-deps@suaveplan/react-uiand@suaveplan/react-i18n(bothworkspace:^),tslibfromcatalog:buildas the only runtime dep, devDeps for the testing wrappers + biome + vitest from catalog refs."sideEffects": ["./src/translations/index.js", "./styles/dracula.css"]so the side-effect import that registers translations and the CSS file are not tree-shaken away. - 1.3 Author
tsconfig.jsonextending@suaveplan/typescript-config/library-browser. - 1.4 Author
vitest.config.tsusingcreateTestConfig()from@suaveplan/testing/config, istanbul provider, thresholds 100/100/100/100. - 1.5 Author the subpath
exportsmap:.,./theme/dracula,./tailwind-preset,./styles/dracula.css,./translations/<locale>for each of the five locales. - 1.6 Confirm subpath count matches the §6 / §13 step-8 helper output.
2. Palette + ThemePlugin
- 2.1 Create
src/theme/dracula.tswith the canonical Dracula palette asdraculaCssVariables: ThemeTokenSet. Inline-comment every foreground/background pair with its measured contrast ratio. - 2.2 Tune any pair below WCAG AA (4.5:1 normal text / 3:1 large + UI) and document the adjustment delta in the same comment.
- 2.3 Construct
draculaTheme: ThemePlugin<'dracula'>withname,labelKey: 'react-ui-theme-dracula.label',cssVariables,tailwindPreset,variantOverrides,motionTokens,colorScheme: 'dark',fontStack(Dracula's recommended JetBrains Mono / Inter pairing). - 2.4 Author
src/theme/dracula.mdwith the six required sections (≥200 words excluding code blocks).
3. Variant overrides — both axes
- 3.1 Create
src/theme/variant-overrides/button.tsoverridingButton.variants.variant.defaultwith the Dracula purple shadow and addingButton.variants.size.xl(h-14 px-10 text-xl). - 3.2 Create
src/theme/variant-overrides/card.tsoverridingCard.variants.variant.defaultwith Dracula border + foreground tokens (override-only path). - 3.3 Author sibling
.mdfiles for each. - 3.4 Author sibling
.test.tsfiles; the Button test pins both the override merge AND the brand-newsize: 'xl'resolution through a narroweduseThemedVariants<'dracula', 'Button'>('Button')call.
4. Motion tokens
- 4.1 Create
src/theme/motion-tokens.tswithrespectReducedMotion: 'soft', halved durations under reduced-motion, spring disabled, crossfade easings preserved. - 4.2 Author
motion-tokens.md. - 4.3 Author
motion-tokens.test.tsmockingmatchMedia('(prefers-reduced-motion: reduce)')and asserting the soft branch resolves the documented values.
5. Tailwind preset + CSS file
- 5.1 Create
src/tailwind-preset/tailwind-preset.tsregistering the Dracula colour scale (50–950) plus the brand-newxlsize token. Plain object literal — no runtime tailwind import. - 5.2 Author
tailwind-preset.md. - 5.3 Author
tailwind-preset.test.tsasserting the preset shape. - 5.4 Create
src/styles/dracula.cssdeclaring the[data-theme='dracula']block under@layer basefor non-Tailwind / SSR-fallback consumers.
6. Translations × 5 locales
- 6.1 Create
src/translations/en-GB.jsonwith{ "react-ui-theme-dracula.label": "Dracula" }. (Source of truth; English keeps the brand name.) - 6.2 Create
src/translations/zh-CN.json("德古拉"— confirm with native reviewer in PR). - 6.3 Create
src/translations/ar-AE.json("دراكولا"— confirm with native reviewer in PR). - 6.4 Create
src/translations/cy-GB.json("Dracula"— proper noun stays untranslated). - 6.5 Create
src/translations/ru-RU.json("Дракула"— confirm with native reviewer in PR). - 6.6 Create
src/translations/augmentation.d.tsaugmentingContributedTranslationKeyswith'react-ui-theme-dracula.label': true. - 6.7 Create
src/translations/index.tsexporting the runtimeregister/unregisterhelpers wired intodraculaTheme.onRegister/onUnregister. Side-effect-importsaugmentation.d.ts. - 6.8 Author
src/translations/index.md. - 6.9 Author
src/translations/index.test.tscovering register / unregister for all five locales + the type-levelexpectTypeOfassertion that'react-ui-theme-dracula.label'is assignable toTranslationKey.
7. Index + barrel
- 7.1 Create
src/index.tswith explicit named re-exports —draculaTheme,draculaCssVariables,draculaTailwindPreset— plus the side-effect import of./translations/index.js. Noexport *(CLAUDE.md §10). - 7.2 Verify zero
export *matches insidesrc/<feature>/index.tswith the §13 step-4a grep.
8. Contract tests
- 8.1 Create
tests/contract.test.tsx: render<ThemeProvider themes={[draculaTheme]} defaultTheme='dracula'><div data-testid='probe' /></ThemeProvider>, assertdata-theme='dracula'on the root, assertgetComputedStyleresolves--backgroundto the dracula token, assertuseThemedVariants<'dracula', 'Button'>('Button')({ size: 'xl' })returns a non-empty class string. - 8.2 Create
tests/no-radix-deps.test.ts: parsepackage.json, assert no@radix-ui/*orreact-domkey in any dep block. - 8.3 Create
tests/wcag-aa.test.ts: iterate the documented foreground/background pairs, run them through a contrast-ratio helper, assert every pair clears AA.
9. Storybook integration in react-ui
- 9.1 In
packages/react/react-ui/src/components/button/button.stories.tsx, add aWithTheme: draculastory that wraps<Button>in<ReactUiProvider themes={[lightTheme, draculaTheme]} defaultTheme='dracula'>(importingdraculaThemeas a devDep). Story import is dev-only so it does not introduce a runtime cycle.
10. README + docs sweep
- 10.1 Author
packages/react/react-ui-theme-dracula/README.mdwith package name, description, install (bun add @suaveplan/react-ui-theme-dracula), basic usage, narrowed-variant usage, custom Tailwind extension example, modules table linking every co-located.md. - 10.2 Run
bun run docs:checkand confirm all sibling.mdfiles exist and meet the ≥200-word floor.
11. Pre-publish gate
- 11.1
bunx turbo lint typecheck test --filter=@suaveplan/react-ui-theme-draculagreen. - 11.2
bunx turbo test:coverage --filter=@suaveplan/react-ui-theme-draculaat 100/100/100/100. - 11.3
bunx turbo build --filter=@suaveplan/react-ui-theme-draculagreen. - 11.4
bun scripts/lint/check-test-runner-imports.tsgreen for this package (zero directvitest/bun:testimports — CLAUDE.md §11). - 11.5 §13 step-4 banned-pattern grep returns zero matches.
- 11.6 §13 step-9 secret scan returns zero matches.
- 11.7 Refresh
MANIFEST.mdviabun scripts/folder-reorg/generate-manifest.tsand refreshMISSING.ymlviabun scripts/generate-missing.ts. UpdateSTATUS.mdandSUMMARY.mdper §13b. - 11.8
bunx markdownlint-cli2 --fixthen a clean second pass with no--fix.