@cdx-ui/styles 0.0.1-beta.8 → 0.0.1-beta.80
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/README.md +116 -20
- package/css/theme.css +201 -85
- package/css/vanilla.css +124 -54
- package/lib/commonjs/applyThemeOverride.js +154 -0
- package/lib/commonjs/applyThemeOverride.js.map +1 -0
- package/lib/commonjs/index.js +82 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/palette.js +262 -0
- package/lib/commonjs/palette.js.map +1 -0
- package/lib/commonjs/theming.js +255 -0
- package/lib/commonjs/theming.js.map +1 -0
- package/lib/commonjs/types.js +75 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/useCdxFonts.js +7 -231
- package/lib/commonjs/useCdxFonts.js.map +1 -1
- package/lib/commonjs/useForgeFonts.js +237 -0
- package/lib/commonjs/useForgeFonts.js.map +1 -0
- package/lib/module/applyThemeOverride.js +149 -0
- package/lib/module/applyThemeOverride.js.map +1 -0
- package/lib/module/index.js +11 -20
- package/lib/module/index.js.map +1 -1
- package/lib/module/palette.js +257 -0
- package/lib/module/palette.js.map +1 -0
- package/lib/module/theming.js +239 -0
- package/lib/module/theming.js.map +1 -0
- package/lib/module/types.js +71 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/useCdxFonts.js +2 -220
- package/lib/module/useCdxFonts.js.map +1 -1
- package/lib/module/useForgeFonts.js +223 -0
- package/lib/module/useForgeFonts.js.map +1 -0
- package/lib/runtime/prestige-vs-default.json +1 -0
- package/lib/runtime/pulse-vs-default.json +1 -0
- package/lib/runtime/token-to-css-var.json +672 -0
- package/lib/typescript/applyThemeOverride.d.ts +26 -0
- package/lib/typescript/applyThemeOverride.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +8 -57
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/palette.d.ts +60 -0
- package/lib/typescript/palette.d.ts.map +1 -0
- package/lib/typescript/theming.d.ts +40 -0
- package/lib/typescript/theming.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +90 -0
- package/lib/typescript/types.d.ts.map +1 -0
- package/lib/typescript/useCdxFonts.d.ts +2 -11
- package/lib/typescript/useCdxFonts.d.ts.map +1 -1
- package/lib/typescript/useForgeFonts.d.ts +12 -0
- package/lib/typescript/useForgeFonts.d.ts.map +1 -0
- package/package.json +27 -8
- package/runtime/prestige-vs-default.json +1 -0
- package/runtime/pulse-vs-default.json +1 -0
- package/runtime/token-to-css-var.json +672 -0
- package/src/__tests__/applyThemeOverride.test.ts +552 -0
- package/src/__tests__/generateColorScale.test.ts +296 -0
- package/src/__tests__/theming.test.ts +647 -0
- package/src/applyThemeOverride.ts +139 -0
- package/src/index.ts +36 -60
- package/src/palette.ts +307 -0
- package/src/theming.ts +268 -0
- package/src/types.ts +112 -0
- package/src/useCdxFonts.ts +2 -230
- package/src/useForgeFonts.ts +230 -0
- package/tokens/presets/.manifest.json +3 -3
- package/tokens/presets/poise.json +319 -39
- package/tokens/presets/prestige.json +1 -1
- package/tokens/presets/pulse.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @cdx-ui/styles
|
|
2
2
|
|
|
3
|
-
Design tokens and theme infrastructure for the
|
|
3
|
+
Design tokens and theme infrastructure for the Forge Design System. Tokens flow from Figma Variables through a Style Dictionary pipeline into CSS custom properties, Tailwind v4 theme variables, and runtime theming artifacts — supporting three presets (Poise, Prestige, Pulse), light/dark modes, cross-platform fonts, and FI white-label overrides.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -22,7 +22,7 @@ Import `theme.css` and `utilities.css` in your global stylesheet, after Tailwind
|
|
|
22
22
|
@import '@cdx-ui/styles/utilities.css';
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
`theme.css` declares all token variables — primitives in `@theme static`, mode-dependent semantics in `@variant light/dark`, and platform fonts in `@variant ios/android/web`. `utilities.css` provides composite typography utilities (`heading-xl` through `body-xs`).
|
|
25
|
+
`theme.css` declares all token variables — primitives in `@theme static`, mode-dependent semantics in `@variant light/dark`, and platform fonts in `@variant ios/android/web`. `utilities.css` provides composite typography utilities (`heading-xl` through `body-xs`, plus `label-sm` and `label-xs`).
|
|
26
26
|
|
|
27
27
|
Components then use standard Tailwind utilities backed by theme variables:
|
|
28
28
|
|
|
@@ -51,9 +51,9 @@ import prestige from '@cdx-ui/styles/presets/prestige.json';
|
|
|
51
51
|
import pulse from '@cdx-ui/styles/presets/pulse.json';
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
### TypeScript
|
|
54
|
+
### TypeScript exports
|
|
55
55
|
|
|
56
|
-
The package exports DTCG-compatible type definitions
|
|
56
|
+
The package exports DTCG-compatible type definitions, runtime constants, palette generation utilities, theming functions, and the `useForgeFonts` hook:
|
|
57
57
|
|
|
58
58
|
```typescript
|
|
59
59
|
import type {
|
|
@@ -63,13 +63,97 @@ import type {
|
|
|
63
63
|
ThemeOverrideMetadata,
|
|
64
64
|
TokenGroup,
|
|
65
65
|
TokenValue,
|
|
66
|
+
Preset,
|
|
66
67
|
Mode,
|
|
67
68
|
Platform,
|
|
69
|
+
CssVariableMaps,
|
|
70
|
+
RuntimeMap,
|
|
71
|
+
PaletteCategory,
|
|
72
|
+
PaletteScale,
|
|
73
|
+
PaletteStep,
|
|
74
|
+
PaletteTokenMap,
|
|
75
|
+
ApplyThemeOverrideOptions,
|
|
76
|
+
ApplyThemeOverrideResult,
|
|
68
77
|
} from '@cdx-ui/styles';
|
|
78
|
+
|
|
79
|
+
import {
|
|
80
|
+
useForgeFonts,
|
|
81
|
+
OVERRIDE_SCHEMA_VERSION,
|
|
82
|
+
SUPPORTED_OVERRIDE_SCHEMA_VERSIONS,
|
|
83
|
+
INPUT_TOKEN_MAP,
|
|
84
|
+
presetFonts,
|
|
85
|
+
DEFAULT_PRESET,
|
|
86
|
+
generateColorScale,
|
|
87
|
+
generatePalettesFromInputs,
|
|
88
|
+
deriveBaseColorKey,
|
|
89
|
+
applyThemeOverride,
|
|
90
|
+
isSchemaVersionSupported,
|
|
91
|
+
presetPatchToUniwindMaps,
|
|
92
|
+
themeOverrideToUniwindMaps,
|
|
93
|
+
} from '@cdx-ui/styles';
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Types:**
|
|
97
|
+
|
|
98
|
+
- `ThemeObject` — Complete Forge UI theme object (DTCG-compatible), including `modes`, `platform`, and `$extensions`.
|
|
99
|
+
- `ThemeOverride` — Hybrid FI override structure with `inputs` (brand values for palette generation) and optional per-mode `overrides`.
|
|
100
|
+
- `ThemeMetadata` / `ThemeOverrideMetadata` — Metadata stored under `$extensions.com.forge.ui.theme` and `$extensions.com.forge.ui.themeOverride`.
|
|
101
|
+
- `Preset` — Union type: `'poise' | 'prestige' | 'pulse'`.
|
|
102
|
+
- `TokenValue` / `TokenGroup` — DTCG leaf node and recursive group types.
|
|
103
|
+
- `Mode` / `Platform` — `'light' | 'dark'` and `'web' | 'ios' | 'android'`.
|
|
104
|
+
- `CssVariableMaps` — Per-mode CSS variable maps ready for `Uniwind.updateCSSVariables`.
|
|
105
|
+
- `RuntimeMap` — Token dot-paths → CSS custom property names.
|
|
106
|
+
- `PaletteCategory` / `PaletteScale` / `PaletteStep` / `PaletteTokenMap` — Palette generation types.
|
|
107
|
+
- `ApplyThemeOverrideOptions` / `ApplyThemeOverrideResult` — Options and result types for `applyThemeOverride`.
|
|
108
|
+
|
|
109
|
+
**Constants:**
|
|
110
|
+
|
|
111
|
+
- `OVERRIDE_SCHEMA_VERSION` — Current override contract version (`'1.0.0'`). Consuming apps gate FI override compatibility on this value.
|
|
112
|
+
- `SUPPORTED_OVERRIDE_SCHEMA_VERSIONS` — Array of schema versions accepted by this package version (includes current and optionally one prior version during transition windows).
|
|
113
|
+
- `INPUT_TOKEN_MAP` — Maps known input keys (`brandPrimary`, `accentPrimary`, `basePrimary`, `displayFont`) to the token path pattern each affects. Used by override application to route inputs to the correct palette namespace.
|
|
114
|
+
- `presetFonts` — Allowed display font families per preset, used by the Theme Editor for font selection and by consuming apps for validation.
|
|
115
|
+
- `DEFAULT_PRESET` — The default preset (`'poise'`).
|
|
116
|
+
|
|
117
|
+
**Palette generation:**
|
|
118
|
+
|
|
119
|
+
- `generateColorScale(hex, category)` — Generates an 11-step Leonardo contrast scale (50–950) plus an `input` step from a single hex color. Categories: `'brand' | 'accent' | 'base'`. Returns a `PaletteTokenMap` keyed by token dot-paths (e.g. `color.brand.50` through `color.brand.input`).
|
|
120
|
+
- `generatePalettesFromInputs(inputs)` — Iterates `brandPrimary`, `accentPrimary`, `basePrimary` from an override's `inputs` object; calls `generateColorScale` for each present value. Returns a merged `PaletteTokenMap`.
|
|
121
|
+
- `deriveBaseColorKey(brandHex)` — Derives a neutral base color key from a brand hex (brand hue/lightness at 5% saturation). Used by the Theme Editor to automatically compute `basePrimary` from `brandPrimary`.
|
|
122
|
+
|
|
123
|
+
**Theming utilities:**
|
|
124
|
+
|
|
125
|
+
- `applyThemeOverride(override, options?)` — High-level orchestrator: validates schema version → applies preset patch (if non-default base) → generates palettes from inputs → merges FI overrides → calls `Uniwind.updateCSSVariables` per mode. Returns a discriminated union: `{ applied: true, light, dark }` or `{ applied: false, reason }`. Options: `runtimeMap`, `runtimePlatform`. Bundles the default runtime map internally. Requires `uniwind` as a peer dependency.
|
|
126
|
+
- `isSchemaVersionSupported(override)` — Schema version gate; returns `true` if the override's `schemaVersion` is in `SUPPORTED_OVERRIDE_SCHEMA_VERSIONS`.
|
|
127
|
+
- `presetPatchToUniwindMaps(patch, runtimeMap, runtimePlatform)` — Walks a nested DTCG preset patch; buckets leaves by mode/platform into per-mode CSS variable maps.
|
|
128
|
+
- `themeOverrideToUniwindMaps(override, runtimeMap)` — Processes a hybrid FI override: palette generation from `inputs`, font mapping, per-mode `overrides` merge, and token-reference alias resolution.
|
|
129
|
+
|
|
130
|
+
A tree-shakeable subpath is also available:
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
import {
|
|
134
|
+
applyThemeOverride,
|
|
135
|
+
presetPatchToUniwindMaps,
|
|
136
|
+
themeOverrideToUniwindMaps,
|
|
137
|
+
} from '@cdx-ui/styles/theming';
|
|
69
138
|
```
|
|
70
139
|
|
|
71
|
-
|
|
72
|
-
|
|
140
|
+
**Hooks:**
|
|
141
|
+
|
|
142
|
+
- `useForgeFonts` — Loads all preset display fonts (nine families, three per preset) plus platform web fonts (Inter, IBM Plex Mono) via `expo-font`. Returns `{ loaded: boolean; error: Error | null }`. Call in your root layout and gate rendering on the returned `loaded` boolean. See [Getting Started](../../docs/getting-started.md) for usage.
|
|
143
|
+
- `useCdxFonts` — **Deprecated** alias for `useForgeFonts`. Retained for backward compatibility during the CDX → Forge rename transition. See [Getting Started](../../docs/getting-started.md) for the migration path.
|
|
144
|
+
|
|
145
|
+
### Runtime artifacts
|
|
146
|
+
|
|
147
|
+
The build produces runtime JSON artifacts importable from the package:
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
import runtimeMap from '@cdx-ui/styles/runtime/token-to-css-var.json';
|
|
151
|
+
import prestigePatch from '@cdx-ui/styles/runtime/prestige-vs-default.json';
|
|
152
|
+
import pulsePatch from '@cdx-ui/styles/runtime/pulse-vs-default.json';
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
- **`runtime/token-to-css-var.json`** — Flat map of ~664 token dot-paths to CSS custom property names (e.g. `"color.brand.500": "--color-brand-500"`). Used internally by `applyThemeOverride`; importable for custom apply logic.
|
|
156
|
+
- **`runtime/prestige-vs-default.json`** / **`runtime/pulse-vs-default.json`** — Sparse preset patches (diff from build default to target preset). Used internally by `applyThemeOverride` when `basePreset` differs from the build default.
|
|
73
157
|
|
|
74
158
|
## Token pipeline
|
|
75
159
|
|
|
@@ -90,8 +174,11 @@ tokens/presets/
|
|
|
90
174
|
poise.json # Default build preset
|
|
91
175
|
prestige.json
|
|
92
176
|
pulse.json
|
|
177
|
+
.manifest.json # SHA-256 checksums (written by fetch)
|
|
93
178
|
```
|
|
94
179
|
|
|
180
|
+
`.manifest.json` records the SHA-256 hash of each preset JSON after fetch. It is used by CI and downstream tooling to detect whether preset files changed between fetches — if the checksums match, the build step can be skipped.
|
|
181
|
+
|
|
95
182
|
Each file is assembled from four Figma collections: **Primitives** (shared), **FI Primitives** (Candescent mode — brand/accent/base colors), **Semantics ({Preset})** (Light + Dark modes), and **Platform** (Web/iOS/Android fonts). Alias references are preserved as DTCG `"{path.to.token}"` syntax.
|
|
96
183
|
|
|
97
184
|
#### Figma MCP alternative
|
|
@@ -111,26 +198,25 @@ pnpm tokens:build
|
|
|
111
198
|
| File | Contents |
|
|
112
199
|
| --------------- | --------------------------------------------------------------------------------------------------- |
|
|
113
200
|
| `theme.css` | `@theme static` (primitives + semantic defaults), `@variant light/dark`, `@variant ios/android/web` |
|
|
114
|
-
| `utilities.css` | `@utility` blocks for composite typography (headings, body,
|
|
201
|
+
| `utilities.css` | `@utility` blocks for composite typography (headings, body-xl through body-xs, label-sm, label-xs) |
|
|
115
202
|
| `vanilla.css` | Non-Tailwind fallback — `:root` variables + `@media (prefers-color-scheme: dark)` + classes |
|
|
116
203
|
|
|
117
|
-
**
|
|
204
|
+
**Runtime artifacts** (generated by `tokens:build`):
|
|
118
205
|
|
|
119
|
-
| Artifact
|
|
120
|
-
|
|
|
121
|
-
| Runtime map
|
|
122
|
-
| Preset patches
|
|
123
|
-
| Validation manifest | API deploy bundle | Allow-listed paths and types for server-side override validation |
|
|
206
|
+
| Artifact | File | Purpose |
|
|
207
|
+
| ------------------ | ---------------------------------- | ------------------------------------------------------------------ |
|
|
208
|
+
| **Runtime map** | `runtime/token-to-css-var.json` | Theme object path → CSS custom property name for sparse flattening |
|
|
209
|
+
| **Preset patches** | `runtime/{preset}-vs-default.json` | Sparse diff from build default → each non-default preset |
|
|
124
210
|
|
|
125
211
|
### Validating font tokens
|
|
126
212
|
|
|
127
|
-
Font registration names in `
|
|
213
|
+
Font registration names in `useForgeFonts` must exactly match the `--font-*` values emitted into `theme.css` — a mismatch causes silent fallback to platform default fonts with no error. The validation script catches this drift as a build/CI failure:
|
|
128
214
|
|
|
129
215
|
```bash
|
|
130
216
|
pnpm fonts:validate
|
|
131
217
|
```
|
|
132
218
|
|
|
133
|
-
It parses every `--font-*` declaration from `css/theme.css` (across `@theme static`, `@variant light/dark`, and `@variant ios/android/web`), reads the font map keys from `src/
|
|
219
|
+
It parses every `--font-*` declaration from `css/theme.css` (across `@theme static`, `@variant light/dark`, and `@variant ios/android/web`), reads the font map keys from `src/useForgeFonts.ts` source, and verifies a matching key exists for every non-system value. System fonts (`SF Pro`, `SF Mono`, `Roboto`, `Roboto Mono`) are read from `figma.config.json` and excluded — they are platform built-ins resolved natively by React Native. `var()` aliases are skipped because they resolve to other variables that are themselves validated.
|
|
134
220
|
|
|
135
221
|
On success the script prints `Font validation: N CSS values checked, N matched, 0 mismatches.` and exits 0. On failure it lists each mismatch with its variable name, value, and CSS section, then exits non-zero. The script is wired into `.github/workflows/ci.yml` as a pre-build step so font-token drift fast-fails before the heavier build/lint/test stages.
|
|
136
222
|
|
|
@@ -146,7 +232,7 @@ Light/dark mode switching is handled by Uniwind `@variant light/dark` blocks in
|
|
|
146
232
|
|
|
147
233
|
### FI overrides
|
|
148
234
|
|
|
149
|
-
Financial institution white-labelling uses
|
|
235
|
+
Financial institution white-labelling uses the hybrid override format — brand inputs (a single hex color expanded into a full palette at runtime) plus optional per-mode semantic token overrides. The Theme API is a pass-through store; validation is performed by the Theme Editor before save. Consuming apps apply overrides at runtime via `applyThemeOverride` (which handles palette generation, runtime map lookup, and `Uniwind.updateCSSVariables` calls internally). See [Override Structure](../../docs/internal/token-architecture/16-override-structure.md) for the payload format and responsibility contract, and [Theme Definition](../../docs/internal/token-architecture/02-theme-definition.md) for the full theme object schema.
|
|
150
236
|
|
|
151
237
|
## Package structure
|
|
152
238
|
|
|
@@ -156,15 +242,25 @@ styles/
|
|
|
156
242
|
│ ├── theme.css # Auto-generated — all token variable declarations
|
|
157
243
|
│ ├── utilities.css # Auto-generated — composite typography @utility blocks
|
|
158
244
|
│ └── vanilla.css # Auto-generated — non-Tailwind fallback
|
|
245
|
+
├── runtime/
|
|
246
|
+
│ ├── token-to-css-var.json # Build-generated — token path → CSS variable name map
|
|
247
|
+
│ ├── prestige-vs-default.json # Build-generated — sparse preset patch (Poise → Prestige)
|
|
248
|
+
│ └── pulse-vs-default.json # Build-generated — sparse preset patch (Poise → Pulse)
|
|
159
249
|
├── scripts/
|
|
160
250
|
│ ├── figma-fetch-variables.mjs # Figma Variables REST API fetch
|
|
161
251
|
│ ├── build-tokens.mjs # Style Dictionary build + artifact generation
|
|
162
|
-
│ └── validate-font-tokens.mjs # CI check: --font-* values match
|
|
252
|
+
│ └── validate-font-tokens.mjs # CI check: --font-* values match useForgeFonts keys
|
|
163
253
|
├── src/
|
|
164
|
-
│ ├── index.ts #
|
|
165
|
-
│
|
|
254
|
+
│ ├── index.ts # Public barrel: types, constants, palette, theming, hooks
|
|
255
|
+
│ ├── palette.ts # Color scale generation (Leonardo contrast algorithm)
|
|
256
|
+
│ ├── theming.ts # Sparse flatten helpers (presetPatchToUniwindMaps, themeOverrideToUniwindMaps)
|
|
257
|
+
│ ├── applyThemeOverride.ts # High-level orchestrator (schema gate → patch → palette → apply)
|
|
258
|
+
│ ├── types.ts # DTCG types, override contract, constants
|
|
259
|
+
│ ├── useForgeFonts.ts # Font loader hook (expo-font) — loads all preset display fonts
|
|
260
|
+
│ └── useCdxFonts.ts # Deprecated alias for useForgeFonts
|
|
166
261
|
├── tokens/
|
|
167
262
|
│ └── presets/
|
|
263
|
+
│ ├── .manifest.json # SHA-256 checksums (written by fetch)
|
|
168
264
|
│ ├── poise.json # Poise theme object (build default)
|
|
169
265
|
│ ├── prestige.json # Prestige theme object
|
|
170
266
|
│ └── pulse.json # Pulse theme object
|
|
@@ -175,7 +271,7 @@ styles/
|
|
|
175
271
|
└── tsconfig.build.json
|
|
176
272
|
```
|
|
177
273
|
|
|
178
|
-
`css/` files are auto-generated — do not edit directly.
|
|
274
|
+
`css/` and `runtime/` files are auto-generated — do not edit directly.
|
|
179
275
|
|
|
180
276
|
## Building
|
|
181
277
|
|