@clhaas/palette-kit 0.1.8 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codex/skills/color-pipeline-implementer/SKILL.md +23 -0
- package/.codex/skills/commit-message-crafter/SKILL.md +63 -0
- package/.codex/skills/commit-message-crafter/references/benchmarks.md +20 -0
- package/.codex/skills/contrast-solver-helper/SKILL.md +20 -0
- package/.codex/skills/exporters-builder/SKILL.md +20 -0
- package/.codex/skills/markdownlint-writer/SKILL.md +32 -0
- package/.codex/skills/phase-implementation-runbook/SKILL.md +92 -0
- package/.codex/skills/type-contract-auditor/SKILL.md +21 -0
- package/.github/skills/review-guide/SKILL.md +23 -0
- package/.github/skills/review-guide/references/review-guide-v0.3.md +629 -0
- package/.markdownlint.json +4 -0
- package/AGENTS.md +16 -0
- package/CHANGELOG.md +34 -0
- package/README.md +79 -169
- package/biome.json +43 -0
- package/dist/cli/args.d.ts +12 -0
- package/dist/cli/args.js +56 -0
- package/dist/cli/args.test.js +22 -0
- package/dist/cli/codegen/__snapshots__/tokens.test.js.snap +87 -0
- package/dist/cli/codegen/tokens.d.ts +12 -0
- package/dist/cli/codegen/tokens.js +139 -0
- package/dist/cli/codegen/tokens.test.d.ts +1 -0
- package/dist/cli/codegen/tokens.test.js +51 -0
- package/dist/cli/config.d.ts +40 -0
- package/dist/cli/config.js +34 -0
- package/dist/cli/validate.d.ts +2 -0
- package/dist/cli/validate.js +33 -0
- package/dist/cli/validate.test.d.ts +1 -0
- package/dist/cli/validate.test.js +40 -0
- package/dist/cli.js +138 -140
- package/dist/contrast/apca.d.ts +2 -2
- package/dist/contrast/apca.js +14 -4
- package/dist/contrast/apca.test.d.ts +1 -0
- package/dist/contrast/apca.test.js +16 -0
- package/dist/contrast/index.d.ts +4 -0
- package/dist/contrast/index.js +4 -0
- package/dist/contrast/scoring.d.ts +4 -0
- package/dist/contrast/scoring.js +31 -0
- package/dist/contrast/scoring.test.d.ts +1 -0
- package/dist/contrast/scoring.test.js +148 -0
- package/dist/contrast/solver.d.ts +13 -0
- package/dist/contrast/solver.js +170 -0
- package/dist/contrast/solver.test.d.ts +1 -0
- package/dist/contrast/solver.test.js +75 -0
- package/dist/contrast/types.d.ts +17 -0
- package/dist/contrast/types.js +1 -0
- package/dist/contrast/utils.d.ts +4 -0
- package/dist/contrast/utils.js +18 -0
- package/dist/contrast/wcag2.d.ts +3 -0
- package/dist/contrast/wcag2.js +19 -0
- package/dist/contrast/wcag2.test.d.ts +1 -0
- package/dist/contrast/wcag2.test.js +17 -0
- package/dist/core/createTheme.d.ts +35 -0
- package/dist/core/createTheme.js +24 -0
- package/dist/core/dx-helpers.test.d.ts +1 -0
- package/dist/core/dx-helpers.test.js +61 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +2 -0
- package/dist/core/onSolid.test.d.ts +1 -0
- package/dist/core/onSolid.test.js +118 -0
- package/dist/core/qa.v1.test.d.ts +1 -0
- package/dist/core/qa.v1.test.js +112 -0
- package/dist/core/resolve.d.ts +3 -0
- package/dist/core/resolve.js +8 -0
- package/dist/core/resolve.test.d.ts +1 -0
- package/dist/core/resolve.test.js +89 -0
- package/dist/core/resolveMany.d.ts +8 -0
- package/dist/core/resolveMany.js +17 -0
- package/dist/core/tokenRegistry.d.ts +23 -0
- package/dist/core/tokenRegistry.js +83 -0
- package/dist/core/tokenRegistry.test.d.ts +1 -0
- package/dist/core/tokenRegistry.test.js +133 -0
- package/dist/engine/applyOperators.d.ts +3 -0
- package/dist/engine/applyOperators.js +23 -0
- package/dist/engine/context.d.ts +4 -0
- package/dist/engine/context.js +1 -0
- package/dist/engine/gamut.d.ts +13 -0
- package/dist/engine/gamut.js +101 -0
- package/dist/engine/gamut.test.d.ts +1 -0
- package/dist/engine/gamut.test.js +23 -0
- package/dist/engine/generateScale.d.ts +15 -0
- package/dist/engine/generateScale.js +29 -0
- package/dist/engine/generateScale.test.d.ts +1 -0
- package/dist/engine/generateScale.test.js +32 -0
- package/dist/engine/index.d.ts +8 -0
- package/dist/engine/index.js +4 -0
- package/dist/engine/normalize.d.ts +43 -0
- package/dist/engine/normalize.js +403 -0
- package/dist/engine/normalize.test.d.ts +1 -0
- package/dist/engine/normalize.test.js +136 -0
- package/dist/engine/onSolid.d.ts +3 -0
- package/dist/engine/onSolid.js +110 -0
- package/dist/engine/resolveBaseColor.d.ts +25 -0
- package/dist/engine/resolveBaseColor.js +127 -0
- package/dist/engine/resolveBaseColor.test.d.ts +1 -0
- package/dist/engine/resolveBaseColor.test.js +97 -0
- package/dist/export/__snapshots__/exportTheme.test.js.snap +74 -0
- package/dist/export/exportTheme.d.ts +47 -0
- package/dist/export/exportTheme.js +170 -0
- package/dist/export/exportTheme.test.d.ts +1 -0
- package/dist/export/exportTheme.test.js +118 -0
- package/dist/export/index.d.ts +1 -0
- package/dist/export/index.js +1 -0
- package/dist/export/serializeColor.d.ts +1 -0
- package/dist/export/serializeColor.js +1 -0
- package/dist/export/serializeColor.test.d.ts +1 -0
- package/dist/export/serializeColor.test.js +54 -0
- package/dist/export.d.ts +1 -0
- package/dist/export.js +1 -0
- package/dist/index.d.ts +3 -22
- package/dist/index.js +2 -18
- package/dist/operators/emphasis.d.ts +3 -0
- package/dist/operators/emphasis.js +113 -0
- package/dist/operators/emphasis.test.d.ts +1 -0
- package/dist/operators/emphasis.test.js +69 -0
- package/dist/operators/index.d.ts +3 -0
- package/dist/operators/index.js +2 -0
- package/dist/operators/state.d.ts +3 -0
- package/dist/operators/state.js +102 -0
- package/dist/operators/state.test.d.ts +1 -0
- package/dist/operators/state.test.js +48 -0
- package/dist/operators/types.d.ts +13 -0
- package/dist/operators/types.js +1 -0
- package/dist/operators/utils.d.ts +16 -0
- package/dist/operators/utils.js +23 -0
- package/dist/presets/curves.d.ts +28 -0
- package/dist/presets/curves.js +145 -0
- package/dist/presets/index.d.ts +2 -0
- package/dist/presets/index.js +1 -0
- package/dist/presets/tokens/index.d.ts +3 -0
- package/dist/presets/tokens/index.js +3 -0
- package/dist/presets/tokens/minimal-ui.d.ts +6 -0
- package/dist/presets/tokens/minimal-ui.js +53 -0
- package/dist/presets/tokens/modern-ui.d.ts +5 -0
- package/dist/presets/tokens/modern-ui.js +83 -0
- package/dist/presets/tokens/presets.test.d.ts +1 -0
- package/dist/presets/tokens/presets.test.js +31 -0
- package/dist/presets/tokens/radixLike-ui.d.ts +6 -0
- package/dist/presets/tokens/radixLike-ui.js +77 -0
- package/dist/serialize/index.d.ts +1 -0
- package/dist/serialize/index.js +1 -0
- package/dist/serialize/normalizeOutput.d.ts +6 -0
- package/dist/serialize/normalizeOutput.js +45 -0
- package/dist/serialize/serializeColor.d.ts +21 -0
- package/dist/serialize/serializeColor.js +178 -0
- package/dist/serialize/serializeResolved.test.d.ts +1 -0
- package/dist/serialize/serializeResolved.test.js +45 -0
- package/dist/serialize.d.ts +1 -0
- package/dist/serialize.js +1 -0
- package/dist/types/index.d.ts +187 -0
- package/dist/types/index.js +1 -0
- package/dist/utils/clamp.d.ts +1 -0
- package/dist/utils/clamp.js +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/lerp.d.ts +1 -0
- package/dist/utils/lerp.js +1 -0
- package/dist/utils/parseColor.d.ts +6 -0
- package/dist/utils/parseColor.js +67 -0
- package/dist/utils/parseColor.test.d.ts +1 -0
- package/dist/utils/parseColor.test.js +51 -0
- package/dist/utils/smoothstep.d.ts +1 -0
- package/dist/utils/smoothstep.js +5 -0
- package/package.json +19 -12
- package/planning/phase-10-review.md +550 -0
- package/planning/phase-7-review.md +411 -0
- package/planning/phase-8-review.md +669 -0
- package/planning/phase-9-review.md +564 -0
- package/planning/roadmap-v0.3.md +284 -0
- package/planning/spec-serializer-v0.3.md +324 -0
- package/planning/spec-v0.3.md +305 -0
- package/src/cli/args.test.ts +28 -0
- package/src/cli/args.ts +66 -0
- package/src/cli/codegen/__snapshots__/tokens.test.ts.snap +87 -0
- package/src/cli/codegen/tokens.test.ts +61 -0
- package/src/cli/codegen/tokens.ts +191 -0
- package/src/cli/config.ts +71 -0
- package/src/cli/validate.test.ts +49 -0
- package/src/cli/validate.ts +38 -0
- package/src/cli.ts +183 -0
- package/src/contrast/apca.test.ts +20 -0
- package/src/contrast/apca.ts +26 -0
- package/src/contrast/index.ts +4 -0
- package/src/contrast/scoring.test.ts +188 -0
- package/src/contrast/scoring.ts +48 -0
- package/src/contrast/solver.test.ts +147 -0
- package/src/contrast/solver.ts +235 -0
- package/src/contrast/types.ts +20 -0
- package/src/contrast/utils.ts +28 -0
- package/src/contrast/wcag2.test.ts +21 -0
- package/src/contrast/wcag2.ts +24 -0
- package/src/core/createTheme.ts +78 -0
- package/src/core/dx-helpers.test.ts +82 -0
- package/src/core/index.ts +7 -0
- package/src/core/onSolid.test.ts +146 -0
- package/src/core/qa.v1.test.ts +149 -0
- package/src/core/resolve.test.ts +99 -0
- package/src/core/resolve.ts +11 -0
- package/src/core/resolveMany.ts +22 -0
- package/src/core/tokenRegistry.test.ts +153 -0
- package/src/core/tokenRegistry.ts +114 -0
- package/src/engine/applyOperators.ts +32 -0
- package/src/engine/context.ts +8 -0
- package/src/engine/gamut.test.ts +30 -0
- package/src/engine/gamut.ts +144 -0
- package/src/engine/generateScale.test.ts +46 -0
- package/src/engine/generateScale.ts +48 -0
- package/src/engine/index.ts +8 -0
- package/src/engine/normalize.test.ts +222 -0
- package/src/engine/normalize.ts +550 -0
- package/src/engine/onSolid.ts +178 -0
- package/src/engine/resolveBaseColor.test.ts +117 -0
- package/src/engine/resolveBaseColor.ts +203 -0
- package/src/export/__snapshots__/exportTheme.test.ts.snap +74 -0
- package/src/export/exportTheme.test.ts +144 -0
- package/src/export/exportTheme.ts +251 -0
- package/src/export/index.ts +1 -0
- package/src/export/serializeColor.test.ts +73 -0
- package/src/export/serializeColor.ts +1 -0
- package/src/export.ts +1 -0
- package/src/index.ts +3 -0
- package/src/operators/emphasis.test.ts +85 -0
- package/src/operators/emphasis.ts +132 -0
- package/src/operators/index.ts +3 -0
- package/src/operators/state.test.ts +66 -0
- package/src/operators/state.ts +122 -0
- package/src/operators/types.ts +14 -0
- package/src/operators/utils.ts +44 -0
- package/src/presets/curves.ts +168 -0
- package/src/presets/index.ts +2 -0
- package/src/presets/tokens/index.ts +3 -0
- package/src/presets/tokens/minimal-ui.ts +55 -0
- package/src/presets/tokens/modern-ui.ts +85 -0
- package/src/presets/tokens/presets.test.ts +46 -0
- package/src/presets/tokens/radixLike-ui.ts +79 -0
- package/src/serialize/index.ts +1 -0
- package/src/serialize/normalizeOutput.ts +63 -0
- package/src/serialize/serializeColor.ts +260 -0
- package/src/serialize/serializeResolved.test.ts +57 -0
- package/src/serialize.ts +1 -0
- package/src/types/index.ts +207 -0
- package/src/utils/clamp.ts +2 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/lerp.ts +1 -0
- package/src/utils/parseColor.test.ts +66 -0
- package/src/utils/parseColor.ts +87 -0
- package/src/utils/smoothstep.ts +6 -0
- package/tsconfig.build.json +11 -0
- package/tsconfig.json +15 -0
- package/dist/alpha/generateAlphaScale.d.ts +0 -5
- package/dist/alpha/generateAlphaScale.js +0 -34
- package/dist/contrast/onSolid.d.ts +0 -6
- package/dist/contrast/onSolid.js +0 -28
- package/dist/contrast/solveText.d.ts +0 -2
- package/dist/contrast/solveText.js +0 -31
- package/dist/createTheme.d.ts +0 -38
- package/dist/createTheme.js +0 -148
- package/dist/data/radixSeeds.d.ts +0 -3
- package/dist/data/radixSeeds.js +0 -34
- package/dist/diagnostics/analyzeScale.d.ts +0 -2
- package/dist/diagnostics/analyzeScale.js +0 -7
- package/dist/diagnostics/analyzeTheme.d.ts +0 -2
- package/dist/diagnostics/analyzeTheme.js +0 -35
- package/dist/diagnostics/warnings.d.ts +0 -2
- package/dist/diagnostics/warnings.js +0 -20
- package/dist/engine/curves.d.ts +0 -9
- package/dist/engine/curves.js +0 -48
- package/dist/engine/oklch.d.ts +0 -8
- package/dist/engine/oklch.js +0 -40
- package/dist/engine/templates.d.ts +0 -14
- package/dist/engine/templates.js +0 -45
- package/dist/exporters/selectColorMode.d.ts +0 -2
- package/dist/exporters/selectColorMode.js +0 -19
- package/dist/exporters/toCssVars.d.ts +0 -13
- package/dist/exporters/toCssVars.js +0 -108
- package/dist/exporters/toJson.d.ts +0 -3
- package/dist/exporters/toJson.js +0 -25
- package/dist/exporters/toReactNative.d.ts +0 -54
- package/dist/exporters/toReactNative.js +0 -33
- package/dist/exporters/toTailwind.d.ts +0 -17
- package/dist/exporters/toTailwind.js +0 -111
- package/dist/exporters/toTs.d.ts +0 -3
- package/dist/exporters/toTs.js +0 -43
- package/dist/generateScale.d.ts +0 -48
- package/dist/generateScale.js +0 -274
- package/dist/overlays/generateOverlayScale.d.ts +0 -2
- package/dist/overlays/generateOverlayScale.js +0 -34
- package/dist/text/generateTextScale.d.ts +0 -8
- package/dist/text/generateTextScale.js +0 -18
- package/dist/text/resolveOnBgText.d.ts +0 -9
- package/dist/text/resolveOnBgText.js +0 -28
- package/dist/tokens/presetRadixLikeUi.d.ts +0 -5
- package/dist/tokens/presetRadixLikeUi.js +0 -55
- package/dist/types.d.ts +0 -69
- /package/dist/{types.js → cli/args.test.d.ts} +0 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
# Palette Kit — SPEC v0.3
|
|
2
|
+
|
|
3
|
+
> Especificação formal da versão v0.3 do Palette Kit.
|
|
4
|
+
> Documento orientado à implementação, com foco absoluto em Developer Experience (DX), contratos explícitos e evolução sustentável do produto.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. Visão geral
|
|
9
|
+
|
|
10
|
+
A v0.3 transforma o Palette Kit em uma biblioteca **runtime-first**, com **DX elevada por padrão**, contratos públicos claros e **tooling opcional** (serializers, exporters, CLI e codegen).
|
|
11
|
+
|
|
12
|
+
A biblioteca passa a atender bem:
|
|
13
|
+
|
|
14
|
+
- desenvolvedores comuns (uso direto no runtime)
|
|
15
|
+
- times grandes (token registry, exporters, codegen)
|
|
16
|
+
- ambientes web e mobile (web / React Native)
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 2. Produto
|
|
21
|
+
|
|
22
|
+
- **Runtime-first** é o caminho oficial
|
|
23
|
+
- CLI, exporters e codegen são **helpers**, não dependências obrigatórias
|
|
24
|
+
- A lib deve ser **útil imediatamente após instalar**
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 3. Resolver (core)
|
|
29
|
+
|
|
30
|
+
### 3.1 Contrato
|
|
31
|
+
|
|
32
|
+
- `createTheme()` permanece como entrypoint
|
|
33
|
+
- `theme.resolve()` e `theme.onSolid()` retornam **BaseResolvedColor**
|
|
34
|
+
- `BaseResolvedColor`:
|
|
35
|
+
- **não é exportado como type**
|
|
36
|
+
- **tem shape estável garantido em toda a linha v0.x**
|
|
37
|
+
- Strings de cor **não** são retornadas automaticamente
|
|
38
|
+
|
|
39
|
+
### 3.2 Justificativa
|
|
40
|
+
|
|
41
|
+
- Mantém o core agnóstico de output
|
|
42
|
+
- Evita acoplamento com CSS, React Native ou JSON
|
|
43
|
+
- Facilita evolução futura (novos formatos, novos targets)
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 4. Serializer público (camadas de DX)
|
|
48
|
+
|
|
49
|
+
### 4.1 Objetivo
|
|
50
|
+
|
|
51
|
+
Fornecer uma **ponte oficial e tipada** entre o resolver e o mundo real (CSS, RN, JSON), sem esconder decisões importantes do desenvolvedor.
|
|
52
|
+
|
|
53
|
+
### 4.2 APIs obrigatórias
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
serializeColor(oklch, options?) -> ResolvedColor
|
|
57
|
+
serializeResolved(baseResolved, options?) -> ResolvedColor
|
|
58
|
+
theme.serialize(query, options?) -> ResolvedColor
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 4.3 Requisitos
|
|
62
|
+
|
|
63
|
+
- Suporte a:
|
|
64
|
+
- `oklch()`
|
|
65
|
+
- `hex`, `rgb()`, `rgba()`
|
|
66
|
+
- `color(display-p3 ...)`
|
|
67
|
+
- Opções:
|
|
68
|
+
- `preferSpace`
|
|
69
|
+
- `includeSpaces`
|
|
70
|
+
- `precision`
|
|
71
|
+
- `strict`
|
|
72
|
+
- Estratégia de gamut mapping default:
|
|
73
|
+
- `preferP3ThenCompress`
|
|
74
|
+
- `ResolvedColor`:
|
|
75
|
+
- contém strings serializadas
|
|
76
|
+
- pode incluir múltiplos espaços
|
|
77
|
+
- pode incluir metadados opcionais
|
|
78
|
+
- **JSDoc obrigatório**, explicando:
|
|
79
|
+
- trade-offs entre espaços de cor
|
|
80
|
+
- implicações de gamut mapping
|
|
81
|
+
- impacto de precisão e strict mode
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 5. Exporters públicos (CSS / JSON)
|
|
86
|
+
|
|
87
|
+
### 5.1 Objetivo
|
|
88
|
+
|
|
89
|
+
Gerar artefatos determinísticos para projetos que desejam tokens persistentes, sem obrigar esse modelo no runtime.
|
|
90
|
+
|
|
91
|
+
### 5.2 APIs públicas
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
exportThemeCss(theme, tokenMap, options)
|
|
95
|
+
exportThemeJson(theme, tokenMap, options)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 5.3 Regras
|
|
99
|
+
|
|
100
|
+
- Exporters **não são obrigatórios** para uso do runtime
|
|
101
|
+
- Outputs devem ser:
|
|
102
|
+
- determinísticos
|
|
103
|
+
- ordenados
|
|
104
|
+
- previsíveis
|
|
105
|
+
- CSS:
|
|
106
|
+
- CSS variables com fallback
|
|
107
|
+
- override progressivo via `@supports`
|
|
108
|
+
- JSON:
|
|
109
|
+
- estrutura estável
|
|
110
|
+
- separação explícita por contexto (`light` / `dark`)
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 6. Token Registry (caminho deluxe)
|
|
115
|
+
|
|
116
|
+
### 6.1 Modelo
|
|
117
|
+
|
|
118
|
+
Tokens são definidos como **objetos ricos**, não apenas nomes:
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
{
|
|
122
|
+
name: "bg.app",
|
|
123
|
+
description: "Application background",
|
|
124
|
+
query: { role, usage, surface },
|
|
125
|
+
category: "background",
|
|
126
|
+
states?: {
|
|
127
|
+
hover?: boolean
|
|
128
|
+
active?: boolean
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 6.2 Regras
|
|
134
|
+
|
|
135
|
+
- Registry é **declarativo**
|
|
136
|
+
- Tokens:
|
|
137
|
+
- não carregam valores de cor
|
|
138
|
+
- sempre resolvem via `theme.resolve`
|
|
139
|
+
- Registry é consumido por:
|
|
140
|
+
- exporters
|
|
141
|
+
- CLI
|
|
142
|
+
- codegen
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## 7. Estados — modelo híbrido
|
|
147
|
+
|
|
148
|
+
- Token registry define **tokens base**
|
|
149
|
+
- Estados (`hover`, `active`, etc.) são **operadores**
|
|
150
|
+
- CLI e exporters:
|
|
151
|
+
- podem gerar tokens derivados
|
|
152
|
+
- nunca duplicam lógica de resolução
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 8. Presets de token map (obrigatórios)
|
|
157
|
+
|
|
158
|
+
### Presets oficiais
|
|
159
|
+
|
|
160
|
+
1. `minimal-ui`
|
|
161
|
+
2. `radixLike-ui`
|
|
162
|
+
3. `modern-ui`
|
|
163
|
+
|
|
164
|
+
Cada preset define:
|
|
165
|
+
|
|
166
|
+
- tokens base
|
|
167
|
+
- categorias
|
|
168
|
+
- estados suportados
|
|
169
|
+
- documentação embutida (descrições e intenção semântica)
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 9. CLI tooling
|
|
174
|
+
|
|
175
|
+
### 9.1 `palette-kit init`
|
|
176
|
+
|
|
177
|
+
- Cria `palette.config.ts`
|
|
178
|
+
- Arquivo totalmente tipado
|
|
179
|
+
- Com JSDoc explicativo
|
|
180
|
+
- Sem comportamento mágico
|
|
181
|
+
- Não gera tokens automaticamente
|
|
182
|
+
|
|
183
|
+
### 9.2 `palette-kit build`
|
|
184
|
+
|
|
185
|
+
- Gera artefatos em `dist/palette/`:
|
|
186
|
+
- `tokens.css`
|
|
187
|
+
- `tokens.json`
|
|
188
|
+
- `tokens.ts`
|
|
189
|
+
- `tokens.d.ts`
|
|
190
|
+
- Pode gerar:
|
|
191
|
+
- `report.md` (opcional)
|
|
192
|
+
- Flag `--watch` é opcional e **não MVP**
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## 10. Codegen de types (DX máximo)
|
|
197
|
+
|
|
198
|
+
### 10.1 Objetivos
|
|
199
|
+
|
|
200
|
+
- Autocomplete completo
|
|
201
|
+
- Navegação por objeto
|
|
202
|
+
- Zero custo em runtime
|
|
203
|
+
|
|
204
|
+
### 10.2 Outputs
|
|
205
|
+
|
|
206
|
+
- Objeto navegável:
|
|
207
|
+
|
|
208
|
+
```ts
|
|
209
|
+
tokens.bg.app
|
|
210
|
+
tokens.text.primary
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
- Unions:
|
|
214
|
+
|
|
215
|
+
```ts
|
|
216
|
+
type TokenName = ...
|
|
217
|
+
type ColorRole = ...
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### 10.3 Regras
|
|
221
|
+
|
|
222
|
+
- JSDoc por token
|
|
223
|
+
- Compatível com editores comuns
|
|
224
|
+
- Core runtime continua aceitando `string`
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## 11. Autocomplete sem amarrar o core
|
|
229
|
+
|
|
230
|
+
- Runtime:
|
|
231
|
+
- aceita `string`
|
|
232
|
+
- Tooling:
|
|
233
|
+
- gera types específicos por projeto
|
|
234
|
+
- APIs automaticamente se beneficiam desses tipos
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## 12. `theme.color(role, options)` com inferência forte
|
|
239
|
+
|
|
240
|
+
### Comportamento
|
|
241
|
+
|
|
242
|
+
- Inferir automaticamente:
|
|
243
|
+
- `usage`
|
|
244
|
+
- `surface`
|
|
245
|
+
- `variant`
|
|
246
|
+
- Inferência baseada no prefixo do role
|
|
247
|
+
|
|
248
|
+
### Strict mode
|
|
249
|
+
|
|
250
|
+
- `strict: true`
|
|
251
|
+
- erro claro, didático e acionável
|
|
252
|
+
- `strict: false`
|
|
253
|
+
- fallback seguro
|
|
254
|
+
- warning explícito
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## 13. Ergonomia adicional
|
|
259
|
+
|
|
260
|
+
### APIs
|
|
261
|
+
|
|
262
|
+
- `resolveMany(queries[])`
|
|
263
|
+
- `withContext("light" | "dark")` retorna um tema bound
|
|
264
|
+
|
|
265
|
+
### Helpers
|
|
266
|
+
|
|
267
|
+
- `theme.colorCss(...)`
|
|
268
|
+
- `theme.onSolidCss(...)`
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## 14. Packaging
|
|
273
|
+
|
|
274
|
+
- Um único pacote npm
|
|
275
|
+
- Uso de **subpath exports**:
|
|
276
|
+
|
|
277
|
+
```json
|
|
278
|
+
{
|
|
279
|
+
"exports": {
|
|
280
|
+
".": "./dist/index.js",
|
|
281
|
+
"./serialize": "./dist/serialize.js",
|
|
282
|
+
"./export": "./dist/export.js",
|
|
283
|
+
"./cli": "./dist/cli.js"
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## 15. Princípios de DX
|
|
291
|
+
|
|
292
|
+
- Runtime-first por default
|
|
293
|
+
- Contratos explícitos e previsíveis
|
|
294
|
+
- Zero comportamento oculto
|
|
295
|
+
- JSDoc tratado como parte da API
|
|
296
|
+
- Determinismo acima de “conveniência mágica”
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## 16. Critérios de aceite
|
|
301
|
+
|
|
302
|
+
- Build passa
|
|
303
|
+
- Nenhum import circular
|
|
304
|
+
- API pública corresponde integralmente à spec
|
|
305
|
+
- DX validável apenas via autocomplete + hover docs
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { CliUsageError, parseArgs } from "./args.js";
|
|
4
|
+
|
|
5
|
+
describe("cli args", () => {
|
|
6
|
+
it("parses init command", () => {
|
|
7
|
+
const parsed = parseArgs(["init"]);
|
|
8
|
+
expect(parsed.command).toBe("init");
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it("parses build command with flags", () => {
|
|
12
|
+
const parsed = parseArgs(["build", "--config", "custom.ts", "--outDir", "out", "--report"]);
|
|
13
|
+
expect(parsed.command).toBe("build");
|
|
14
|
+
expect(parsed.flags.config).toBe("custom.ts");
|
|
15
|
+
expect(parsed.flags.outDir).toBe("out");
|
|
16
|
+
expect(parsed.flags.report).toBe(true);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("recognizes help and version flags", () => {
|
|
20
|
+
expect(parseArgs(["--help"]).help).toBe(true);
|
|
21
|
+
expect(parseArgs(["--version"]).version).toBe(true);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("throws on unknown arguments", () => {
|
|
25
|
+
expect(() => parseArgs(["build", "wat"])).toThrow(CliUsageError);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
package/src/cli/args.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export class CliUsageError extends Error {
|
|
2
|
+
override name = "CliUsageError";
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export const HELP_TEXT = `palette-kit <command>
|
|
6
|
+
|
|
7
|
+
Commands:
|
|
8
|
+
palette-kit init [--force] [--path <dir>]
|
|
9
|
+
palette-kit build [--config <path>] [--outDir <dir>] [--report]
|
|
10
|
+
|
|
11
|
+
Options:
|
|
12
|
+
-h, --help Show help
|
|
13
|
+
-v, --version Show version
|
|
14
|
+
`;
|
|
15
|
+
|
|
16
|
+
export type ParsedArgs = {
|
|
17
|
+
command?: string;
|
|
18
|
+
help: boolean;
|
|
19
|
+
version: boolean;
|
|
20
|
+
flags: Record<string, string | boolean>;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const COMMANDS = ["init", "build"] as const;
|
|
24
|
+
|
|
25
|
+
export const parseArgs = (argv: string[]): ParsedArgs => {
|
|
26
|
+
const first = argv[0];
|
|
27
|
+
const command = first && !first.startsWith("-") ? first : undefined;
|
|
28
|
+
const rest = command ? argv.slice(1) : argv;
|
|
29
|
+
const flags: Record<string, string | boolean> = {};
|
|
30
|
+
|
|
31
|
+
let i = 0;
|
|
32
|
+
while (i < rest.length) {
|
|
33
|
+
const value = rest[i];
|
|
34
|
+
if (value === undefined) break;
|
|
35
|
+
if (value === "-h" || value === "--help") {
|
|
36
|
+
flags.help = true;
|
|
37
|
+
i += 1;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (value === "-v" || value === "--version") {
|
|
41
|
+
flags.version = true;
|
|
42
|
+
i += 1;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (value.startsWith("--")) {
|
|
46
|
+
const key = value.slice(2);
|
|
47
|
+
const next = rest[i + 1];
|
|
48
|
+
if (next && !next.startsWith("--")) {
|
|
49
|
+
flags[key] = next;
|
|
50
|
+
i += 2;
|
|
51
|
+
} else {
|
|
52
|
+
flags[key] = true;
|
|
53
|
+
i += 1;
|
|
54
|
+
}
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
throw new CliUsageError(`Unknown argument: ${value}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
command,
|
|
62
|
+
help: Boolean(flags.help),
|
|
63
|
+
version: Boolean(flags.version),
|
|
64
|
+
flags,
|
|
65
|
+
};
|
|
66
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`codegen tokens > generates navigable tokens.ts and tokens.d.ts 1`] = `
|
|
4
|
+
"/* This file is generated by palette-kit build (Phase 7). */
|
|
5
|
+
|
|
6
|
+
export const tokens = {
|
|
7
|
+
bg: {
|
|
8
|
+
/**
|
|
9
|
+
* App background.
|
|
10
|
+
* @token bg.app
|
|
11
|
+
* @category bg
|
|
12
|
+
*/
|
|
13
|
+
app: "bg.app",
|
|
14
|
+
},
|
|
15
|
+
border: {
|
|
16
|
+
/**
|
|
17
|
+
* Default border color.
|
|
18
|
+
* @token border.default
|
|
19
|
+
* @category border
|
|
20
|
+
*/
|
|
21
|
+
"default": "border.default",
|
|
22
|
+
},
|
|
23
|
+
text: {
|
|
24
|
+
/**
|
|
25
|
+
* Primary text on standard surfaces.
|
|
26
|
+
* @token text.primary
|
|
27
|
+
* @category text
|
|
28
|
+
* @states hover
|
|
29
|
+
*/
|
|
30
|
+
primary: "text.primary",
|
|
31
|
+
},
|
|
32
|
+
} as const;
|
|
33
|
+
|
|
34
|
+
export const tokenNames = [
|
|
35
|
+
"bg.app",
|
|
36
|
+
"border.default",
|
|
37
|
+
"text.primary"
|
|
38
|
+
] as const;
|
|
39
|
+
|
|
40
|
+
export type TokenName = (typeof tokenNames)[number];
|
|
41
|
+
|
|
42
|
+
export type ColorRole = TokenName;
|
|
43
|
+
"
|
|
44
|
+
`;
|
|
45
|
+
|
|
46
|
+
exports[`codegen tokens > generates navigable tokens.ts and tokens.d.ts 2`] = `
|
|
47
|
+
"/* This file is generated by palette-kit build (Phase 7). */
|
|
48
|
+
|
|
49
|
+
export declare const tokens: {
|
|
50
|
+
bg: {
|
|
51
|
+
/**
|
|
52
|
+
* App background.
|
|
53
|
+
* @token bg.app
|
|
54
|
+
* @category bg
|
|
55
|
+
*/
|
|
56
|
+
app: "bg.app";
|
|
57
|
+
};
|
|
58
|
+
border: {
|
|
59
|
+
/**
|
|
60
|
+
* Default border color.
|
|
61
|
+
* @token border.default
|
|
62
|
+
* @category border
|
|
63
|
+
*/
|
|
64
|
+
"default": "border.default";
|
|
65
|
+
};
|
|
66
|
+
text: {
|
|
67
|
+
/**
|
|
68
|
+
* Primary text on standard surfaces.
|
|
69
|
+
* @token text.primary
|
|
70
|
+
* @category text
|
|
71
|
+
* @states hover
|
|
72
|
+
*/
|
|
73
|
+
primary: "text.primary";
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export declare const tokenNames: readonly [
|
|
78
|
+
"bg.app",
|
|
79
|
+
"border.default",
|
|
80
|
+
"text.primary"
|
|
81
|
+
];
|
|
82
|
+
|
|
83
|
+
export type TokenName = (typeof tokenNames)[number];
|
|
84
|
+
|
|
85
|
+
export type ColorRole = TokenName;
|
|
86
|
+
"
|
|
87
|
+
`;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import type { TokenRegistry } from "../../types/index.js";
|
|
4
|
+
import { generateTokenArtifacts } from "./tokens.js";
|
|
5
|
+
|
|
6
|
+
describe("codegen tokens", () => {
|
|
7
|
+
const registry: TokenRegistry = {
|
|
8
|
+
tokens: {
|
|
9
|
+
"bg.app": {
|
|
10
|
+
name: "bg.app",
|
|
11
|
+
description: "App background.",
|
|
12
|
+
category: "bg",
|
|
13
|
+
query: { role: "bg.app", usage: "bg", surface: "app" },
|
|
14
|
+
},
|
|
15
|
+
"text.primary": {
|
|
16
|
+
name: "text.primary",
|
|
17
|
+
description: "Primary text on standard surfaces.",
|
|
18
|
+
category: "text",
|
|
19
|
+
query: { role: "text.primary", usage: "text", surface: "surface" },
|
|
20
|
+
states: { hover: true },
|
|
21
|
+
},
|
|
22
|
+
"border.default": {
|
|
23
|
+
name: "border.default",
|
|
24
|
+
description: "Default border color.",
|
|
25
|
+
category: "border",
|
|
26
|
+
query: { role: "border.default", usage: "border", surface: "surface" },
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
it("generates navigable tokens.ts and tokens.d.ts", () => {
|
|
32
|
+
const { tokensTs, tokensDts } = generateTokenArtifacts(registry);
|
|
33
|
+
|
|
34
|
+
expect(tokensTs).toContain('export const tokens = {');
|
|
35
|
+
expect(tokensTs).toContain('bg: {');
|
|
36
|
+
expect(tokensTs).toContain('app: "bg.app"');
|
|
37
|
+
expect(tokensTs).toContain('text: {');
|
|
38
|
+
expect(tokensTs).toContain('primary: "text.primary"');
|
|
39
|
+
|
|
40
|
+
expect(tokensTs).toMatchSnapshot();
|
|
41
|
+
expect(tokensDts).toMatchSnapshot();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("is deterministic regardless of registry object order", () => {
|
|
45
|
+
const shuffled: TokenRegistry = {
|
|
46
|
+
tokens: {
|
|
47
|
+
"text.primary": registry.tokens["text.primary"],
|
|
48
|
+
"bg.app": registry.tokens["bg.app"],
|
|
49
|
+
"border.default": registry.tokens["border.default"],
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const a = generateTokenArtifacts(registry);
|
|
54
|
+
const b = generateTokenArtifacts(shuffled);
|
|
55
|
+
|
|
56
|
+
expect(b.tokenNames).toEqual(a.tokenNames);
|
|
57
|
+
expect(b.tokensTs).toBe(a.tokensTs);
|
|
58
|
+
expect(b.tokensDts).toBe(a.tokensDts);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|