@marianmeres/design-tokens 1.3.0 → 1.4.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/AGENTS.md +65 -34
- package/API.md +205 -44
- package/README.md +31 -0
- package/dist/css/amber-olive-safari.css +24 -50
- package/dist/css/blue-orange.css +24 -50
- package/dist/css/cyan-red.css +24 -50
- package/dist/css/cyan-slate.css +24 -50
- package/dist/css/emerald-amber-forest.css +24 -50
- package/dist/css/emerald-pink.css +24 -50
- package/dist/css/fuchsia-emerald.css +24 -50
- package/dist/css/gray.css +24 -50
- package/dist/css/indigo-amber.css +24 -50
- package/dist/css/lime-fuchsia-neon.css +24 -50
- package/dist/css/mauve-lime-electric.css +24 -50
- package/dist/css/mauve-teal.css +24 -50
- package/dist/css/mauve.css +24 -50
- package/dist/css/mist-indigo-fjord.css +24 -50
- package/dist/css/mist-violet-aurora.css +24 -50
- package/dist/css/mist.css +24 -50
- package/dist/css/monokai-cyan.css +24 -50
- package/dist/css/monokai-green.css +24 -50
- package/dist/css/monokai-pink.css +24 -50
- package/dist/css/olive-amber-safari.css +24 -50
- package/dist/css/olive.css +24 -50
- package/dist/css/orange-pink-sunset.css +24 -50
- package/dist/css/pink-emerald.css +24 -50
- package/dist/css/pink-teal.css +24 -50
- package/dist/css/purple-yellow.css +24 -50
- package/dist/css/rainbow.css +24 -50
- package/dist/css/red-blue.css +24 -50
- package/dist/css/red-cyan.css +24 -50
- package/dist/css/red-sky-slate.css +24 -50
- package/dist/css/red-sky.css +24 -50
- package/dist/css/rose-teal.css +24 -50
- package/dist/css/sky-amber.css +24 -50
- package/dist/css/slate-cyan.css +24 -50
- package/dist/css/slate-teal-ocean.css +24 -50
- package/dist/css/stone-orange-earth.css +24 -50
- package/dist/css/stone.css +24 -50
- package/dist/css/taupe-olive-clay.css +24 -50
- package/dist/css/taupe-rose-blush.css +24 -50
- package/dist/css/taupe.css +24 -50
- package/dist/css/teal-rose.css +24 -50
- package/dist/css/violet-lime.css +24 -50
- package/dist/css/violet-rose-dusk.css +24 -50
- package/dist/css/zinc.css +24 -50
- package/dist/generate.d.ts +56 -7
- package/dist/generate.js +91 -39
- package/dist/mod.d.ts +9 -1
- package/dist/reboot-bridge.d.ts +20 -5
- package/dist/reboot-bridge.js +45 -12
- package/dist/themes/mod.d.ts +7 -0
- package/dist/themes/mod.js +95 -0
- package/dist/types.d.ts +20 -4
- package/package.json +10 -1
package/AGENTS.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# @marianmeres/design-tokens — Agent Guide
|
|
2
2
|
|
|
3
3
|
## Quick Reference
|
|
4
|
+
|
|
4
5
|
- **Stack**: Deno / TypeScript
|
|
5
6
|
- **Run**: `deno task test` | **Watch**: `deno task test:watch`
|
|
6
7
|
- **Build (npm)**: `deno task npm:build`
|
|
7
|
-
- **Build (CSS)**: `deno task css:build` (generates pre-built CSS files
|
|
8
|
+
- **Build (CSS)**: `deno task css:build` (generates pre-built CSS files; accepts `CSS_PREFIX` env var, default `"stuic-"`)
|
|
9
|
+
- **Build (themes barrel)**: `deno task themes:build` (regenerates `src/themes/mod.ts`)
|
|
8
10
|
- **Build (preview)**: `deno task preview:build`
|
|
9
11
|
- **Publish**: `deno task publish` (JSR + npm)
|
|
10
12
|
- **Format**: `deno fmt` (tabs, 90 chars, indent 4)
|
|
@@ -16,10 +18,11 @@ CSS custom property generator for design token systems. Takes a structured
|
|
|
16
18
|
declarations with automatic hover/active state derivation via `color-mix()`.
|
|
17
19
|
|
|
18
20
|
Entry points:
|
|
21
|
+
|
|
19
22
|
- `.` — core generation functions, types, color palette
|
|
20
23
|
- `./reboot` — Bootstrap Reboot `--bs-*` variable bridge
|
|
21
|
-
- `./themes` —
|
|
22
|
-
- `./css/*.css` — pre-built CSS files
|
|
24
|
+
- `./themes` — 43 pre-built theme definitions + `themeNames` constant + `bundledThemes` / `bundledThemeNames` / `getBundledTheme` runtime helpers
|
|
25
|
+
- `./css/*.css` — pre-built CSS files (**npm only** — JSR does not support directory exports)
|
|
23
26
|
|
|
24
27
|
## Project Structure
|
|
25
28
|
|
|
@@ -29,64 +32,85 @@ Entry points:
|
|
|
29
32
|
types.ts — core type definitions (ThemeSchema, TokenSchema, etc.)
|
|
30
33
|
generate.ts — token generation + CSS output (generateCssTokens, toCssString, generateThemeCss)
|
|
31
34
|
utils.ts — hex color parsing (hexToRgb, hexToRgbTriplet)
|
|
32
|
-
colors.ts — Tailwind color palette (v3 + v4.2 additions: taupe, mauve, mist, olive)
|
|
35
|
+
colors.ts — Tailwind color palette (v3 + v4.2 additions: taupe, mauve, mist, olive), as const
|
|
33
36
|
reboot-bridge.ts — Bootstrap Reboot --bs-* variable mapping
|
|
34
37
|
/themes
|
|
35
|
-
mod.ts —
|
|
38
|
+
mod.ts — auto-generated barrel + runtime registry (via scripts/build-themes-mod.ts)
|
|
36
39
|
*.ts — individual theme files (default export: ThemeSchema)
|
|
37
|
-
/css — pre-built CSS files (generated by scripts/build-css.ts)
|
|
40
|
+
/css — pre-built CSS files (generated by scripts/build-css.ts; filenames = kebab-case theme names)
|
|
38
41
|
/tests — test files (deno test --allow-read)
|
|
39
42
|
/scripts
|
|
40
43
|
build-npm.ts — npm package build (also copies css/ into dist)
|
|
41
|
-
build-css.ts — generates css/*.css from all themes
|
|
44
|
+
build-css.ts — generates css/*.css from all themes; honors CSS_PREFIX env var
|
|
45
|
+
build-themes-mod.ts — auto-generates src/themes/mod.ts + inline registry helpers
|
|
42
46
|
/theme-preview-builder — HTML preview tool
|
|
47
|
+
/mcp.ts — MCP tool definitions (generate-theme-css, preview-bundled-theme)
|
|
43
48
|
```
|
|
44
49
|
|
|
45
50
|
## Public API Surface
|
|
46
51
|
|
|
47
52
|
### Functions (from `./src/mod.ts`)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
|
51
|
-
| `
|
|
52
|
-
| `
|
|
53
|
-
| `
|
|
54
|
-
| `
|
|
53
|
+
|
|
54
|
+
| Function | Purpose |
|
|
55
|
+
| --------------------------------------------- | --------------------------------------------------------------------------------------------------- |
|
|
56
|
+
| `generateCssTokens(schema, prefix, options?)` | Generate token key-value pairs. Third arg: `GenerateOptions` object or `"light"`/`"dark"` shorthand |
|
|
57
|
+
| `toCssString(tokens, selector?)` | Convert tokens to a CSS declaration block (groups by base color name) |
|
|
58
|
+
| `generateThemeCss(schema, prefix, options?)` | Generate complete CSS for light + optional dark mode; supports `cssLayer` wrapping |
|
|
59
|
+
| `hexToRgb(hex)` | Parse hex to `[r, g, b]` tuple |
|
|
60
|
+
| `hexToRgbTriplet(hex)` | Convert hex to `"r, g, b"` string |
|
|
55
61
|
|
|
56
62
|
### Functions (from `./reboot`)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
|
60
|
-
| `
|
|
63
|
+
|
|
64
|
+
| Function | Purpose |
|
|
65
|
+
| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
66
|
+
| `generateRebootBridge(tokens, prefix)` | Map tokens to `--bs-*` variables. `-rgb` companions only emitted for literal hex values — auto-derived `color-mix()` values cannot produce triplets |
|
|
67
|
+
| `generateThemedCss(schema, prefix, options?)` | Combined tokens + reboot bridge CSS |
|
|
68
|
+
|
|
69
|
+
### Functions (from `./themes`)
|
|
70
|
+
|
|
71
|
+
| Function | Purpose |
|
|
72
|
+
| ----------------------- | --------------------------------------------------------------------------- |
|
|
73
|
+
| `getBundledTheme(name)` | Look up bundled theme by camelCase name; returns `ThemeSchema \| undefined` |
|
|
61
74
|
|
|
62
75
|
### Key Types
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
|
66
|
-
| `
|
|
67
|
-
| `
|
|
68
|
-
| `
|
|
69
|
-
| `
|
|
70
|
-
| `
|
|
76
|
+
|
|
77
|
+
| Type | Purpose |
|
|
78
|
+
| ----------------------- | ------------------------------------------------------------------------------- |
|
|
79
|
+
| `ThemeSchema` | `{ light: TokenSchema; dark?: TokenSchema }` |
|
|
80
|
+
| `TokenSchema` | Intent colors, role paired/single colors |
|
|
81
|
+
| `ColorPair` | `{ DEFAULT, foreground, hover?, active?, foregroundHover?, foregroundActive? }` |
|
|
82
|
+
| `ColorValue` | `{ DEFAULT, hover?, active? }` |
|
|
83
|
+
| `SingleColor` | `string \| ColorValue` |
|
|
84
|
+
| `GeneratedTokens` | `Record<string, string>` |
|
|
85
|
+
| `GenerateOptions` | `{ mode?, deriveStates?, surfaceForegroundContrast? }` |
|
|
86
|
+
| `GenerateThemeOptions` | `Omit<GenerateOptions, "mode"> & { cssLayer? }` |
|
|
87
|
+
| `RolePairedKey` | Required: `"background" \| "muted" \| "surface"` |
|
|
88
|
+
| `RolePairedOptionalKey` | Optional: `"surface-1"` (all bundled themes ship it) |
|
|
71
89
|
|
|
72
90
|
### Constants
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
|
91
|
+
|
|
92
|
+
| Export | Purpose |
|
|
93
|
+
| ------------------- | ---------------------------------------------------------------- |
|
|
94
|
+
| `colors` | Tailwind hex palette (with `as const`, full literal types) |
|
|
95
|
+
| `themeNames` | Kebab-case theme names (readonly tuple) |
|
|
96
|
+
| `bundledThemes` | Map of camelCase name → ThemeSchema (no leaky non-theme exports) |
|
|
97
|
+
| `bundledThemeNames` | Array of camelCase theme names |
|
|
76
98
|
|
|
77
99
|
## Critical Conventions
|
|
78
100
|
|
|
79
101
|
1. All public functions must have JSDoc and explicit return types (Deno/JSR requirement)
|
|
80
102
|
2. Token naming: `--{prefix}color-{key}`, `--{prefix}color-{key}-hover`, etc.
|
|
81
|
-
3.
|
|
82
|
-
4.
|
|
83
|
-
5.
|
|
84
|
-
6.
|
|
103
|
+
3. Prefix is auto-normalized — `"my"` and `"my-"` both produce `--my-color-*`. Empty string produces unprefixed.
|
|
104
|
+
4. Hover/active auto-derived via `color-mix(in oklch, ...)` — light darkens with black, dark lightens with white. Disable with `deriveStates: false`.
|
|
105
|
+
5. Surface-intent tokens derived via `color-mix(in srgb, ...)` from intent + background. Foreground contrast defaults to 50% — tune via `surfaceForegroundContrast`.
|
|
106
|
+
6. Theme files use `export default` with `ThemeSchema` type annotation. All bundled themes include an optional `surface-1` paired role (extra elevation).
|
|
107
|
+
7. Formatting: tabs, 90-char line width, 4-space indent width (`deno fmt`)
|
|
108
|
+
8. MCP handlers must return `Promise<string>` — framework contract from `jsr:@marianmeres/mcp-server/types`.
|
|
85
109
|
|
|
86
110
|
## Adding a New Theme
|
|
87
111
|
|
|
88
112
|
1. Create `src/themes/{name}.ts` with `export default` of `ThemeSchema`
|
|
89
|
-
2. Run `deno task themes:build` to regenerate `src/themes/mod.ts`
|
|
113
|
+
2. Run `deno task themes:build` to regenerate `src/themes/mod.ts` (barrel + registry)
|
|
90
114
|
3. Run `deno task css:build` to regenerate CSS files
|
|
91
115
|
4. Run `deno task preview:build` to rebuild the preview tool
|
|
92
116
|
5. If the theme uses new color families, update `COLOR_FAMILIES` in `theme-preview-builder/index.html`
|
|
@@ -95,5 +119,12 @@ Entry points:
|
|
|
95
119
|
|
|
96
120
|
- [ ] Read existing patterns in similar files
|
|
97
121
|
- [ ] Run `deno task test` — all tests must pass
|
|
122
|
+
- [ ] `deno check src/mod.ts src/themes/mod.ts src/reboot-bridge.ts mcp.ts scripts/*.ts` — typecheck
|
|
98
123
|
- [ ] Follow `deno fmt` conventions
|
|
99
124
|
- [ ] Ensure new exports have JSDoc + explicit return types
|
|
125
|
+
- [ ] If changing generator output (CSS text), note as potential BC change
|
|
126
|
+
|
|
127
|
+
## Known Limitations
|
|
128
|
+
|
|
129
|
+
- **JSR does not support directory exports** → pre-built CSS is npm-only.
|
|
130
|
+
- **Reboot `-rgb` companions** are omitted for tokens whose values are `color-mix()` expressions (auto-derived hovers). Provide explicit hex `hover` / `active` if you need full alpha-blend support through Reboot's `rgba(var(--bs-…-rgb), α)` rules.
|
package/API.md
CHANGED
|
@@ -2,38 +2,53 @@
|
|
|
2
2
|
|
|
3
3
|
## Functions
|
|
4
4
|
|
|
5
|
-
### `generateCssTokens(schema, prefix,
|
|
5
|
+
### `generateCssTokens(schema, prefix, options?)`
|
|
6
6
|
|
|
7
7
|
Generate CSS token key-value pairs from a single-mode token schema.
|
|
8
8
|
|
|
9
9
|
**Parameters:**
|
|
10
|
+
|
|
10
11
|
- `schema` (`TokenSchema`) — Color definitions for intent, role paired, and role single colors
|
|
11
|
-
- `prefix` (`string`) — CSS variable prefix
|
|
12
|
-
- `
|
|
12
|
+
- `prefix` (`string`) — CSS variable prefix. Auto-normalized: `"my"` and `"my-"` are equivalent. `""` produces unprefixed tokens.
|
|
13
|
+
- `options` (`GenerateOptions | "light" | "dark"`, optional) — A mode string for quick switching, or an options object. Default: `{}`
|
|
14
|
+
- `mode` (`"light" | "dark"`, optional) — Affects auto-derivation direction. Light darkens with black, dark lightens with white. Default: `"light"`
|
|
15
|
+
- `deriveStates` (`boolean`, optional) — When `false`, missing hover/active fall back to DEFAULT instead of being derived via `color-mix()`. Useful for environments without `color-mix()` support. Default: `true`
|
|
16
|
+
- `surfaceForegroundContrast` (`number`, optional) — Mix percentage (0–100) used to derive the `surface-{intent}-foreground` token. Higher values increase contrast against the tinted surface background. Default: `50`
|
|
13
17
|
|
|
14
18
|
**Returns:** `GeneratedTokens` — Key-value record of token names to CSS values (keys without the `--` prefix)
|
|
15
19
|
|
|
16
20
|
**Example:**
|
|
21
|
+
|
|
17
22
|
```typescript
|
|
18
23
|
import { generateCssTokens } from "@marianmeres/design-tokens";
|
|
19
24
|
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
// Shorthand mode string
|
|
26
|
+
const tokens = generateCssTokens(schema.light, "app-", "dark");
|
|
27
|
+
|
|
28
|
+
// Full options object
|
|
29
|
+
const flat = generateCssTokens(schema.light, "app", {
|
|
30
|
+
mode: "light",
|
|
31
|
+
deriveStates: false,
|
|
32
|
+
surfaceForegroundContrast: 70,
|
|
33
|
+
});
|
|
34
|
+
// { "app-color-primary": "#2563eb", "app-color-primary-hover": "#2563eb", ... }
|
|
22
35
|
```
|
|
23
36
|
|
|
24
37
|
---
|
|
25
38
|
|
|
26
39
|
### `toCssString(tokens, selector?)`
|
|
27
40
|
|
|
28
|
-
Convert a tokens record to a formatted CSS declaration block, grouped by base color name.
|
|
41
|
+
Convert a tokens record to a formatted CSS declaration block, grouped by base color name (e.g. all `surface-*` tokens cluster together).
|
|
29
42
|
|
|
30
43
|
**Parameters:**
|
|
44
|
+
|
|
31
45
|
- `tokens` (`GeneratedTokens`) — Key-value token pairs (from `generateCssTokens`)
|
|
32
46
|
- `selector` (`string`, optional) — CSS selector for the block. Default: `":root"`
|
|
33
47
|
|
|
34
48
|
**Returns:** `string` — Formatted CSS string
|
|
35
49
|
|
|
36
50
|
**Example:**
|
|
51
|
+
|
|
37
52
|
```typescript
|
|
38
53
|
import { generateCssTokens, toCssString } from "@marianmeres/design-tokens";
|
|
39
54
|
|
|
@@ -46,22 +61,30 @@ const css = toCssString(tokens, ":root.dark");
|
|
|
46
61
|
|
|
47
62
|
---
|
|
48
63
|
|
|
49
|
-
### `generateThemeCss(schema, prefix)`
|
|
64
|
+
### `generateThemeCss(schema, prefix, options?)`
|
|
50
65
|
|
|
51
66
|
Generate complete CSS for a theme with light mode and optional dark mode.
|
|
52
67
|
|
|
53
68
|
**Parameters:**
|
|
69
|
+
|
|
54
70
|
- `schema` (`ThemeSchema`) — Theme with required `light` and optional `dark` token schemas
|
|
55
|
-
- `prefix` (`string`) — CSS variable prefix
|
|
71
|
+
- `prefix` (`string`) — CSS variable prefix (trailing dash optional)
|
|
72
|
+
- `options` (`GenerateThemeOptions`, optional) — Accepts all `GenerateOptions` (except `mode`, which is set per section) plus:
|
|
73
|
+
- `cssLayer` (`string`, optional) — Wrap the output in `@layer {name} { ... }`. Useful for CSS cascade control.
|
|
56
74
|
|
|
57
|
-
**Returns:** `string` — Complete CSS with `:root` for light and `:root.dark` for dark mode
|
|
75
|
+
**Returns:** `string` — Complete CSS with `:root` for light and `:root.dark` for dark mode, optionally wrapped in `@layer`.
|
|
58
76
|
|
|
59
77
|
**Example:**
|
|
78
|
+
|
|
60
79
|
```typescript
|
|
61
80
|
import { generateThemeCss } from "@marianmeres/design-tokens";
|
|
62
81
|
import { zinc } from "@marianmeres/design-tokens/themes";
|
|
63
82
|
|
|
64
|
-
const css = generateThemeCss(zinc, "app-");
|
|
83
|
+
const css = generateThemeCss(zinc, "app-", { cssLayer: "tokens" });
|
|
84
|
+
// @layer tokens {
|
|
85
|
+
// :root { ... }
|
|
86
|
+
// :root.dark { ... }
|
|
87
|
+
// }
|
|
65
88
|
```
|
|
66
89
|
|
|
67
90
|
---
|
|
@@ -71,17 +94,19 @@ const css = generateThemeCss(zinc, "app-");
|
|
|
71
94
|
Parse a hex color string to RGB components. Supports 3-digit (`#abc`) and 6-digit (`#aabbcc`) formats, with or without `#` prefix.
|
|
72
95
|
|
|
73
96
|
**Parameters:**
|
|
97
|
+
|
|
74
98
|
- `hex` (`string`) — Hex color string
|
|
75
99
|
|
|
76
100
|
**Returns:** `[number, number, number] | null` — RGB tuple, or `null` if invalid
|
|
77
101
|
|
|
78
102
|
**Example:**
|
|
103
|
+
|
|
79
104
|
```typescript
|
|
80
105
|
import { hexToRgb } from "@marianmeres/design-tokens";
|
|
81
106
|
|
|
82
107
|
hexToRgb("#2563eb"); // → [37, 99, 235]
|
|
83
|
-
hexToRgb("fff");
|
|
84
|
-
hexToRgb("nope");
|
|
108
|
+
hexToRgb("fff"); // → [255, 255, 255]
|
|
109
|
+
hexToRgb("nope"); // → null
|
|
85
110
|
```
|
|
86
111
|
|
|
87
112
|
---
|
|
@@ -91,11 +116,13 @@ hexToRgb("nope"); // → null
|
|
|
91
116
|
Convert a hex color to an `"r, g, b"` triplet string suitable for CSS `rgb()` usage.
|
|
92
117
|
|
|
93
118
|
**Parameters:**
|
|
119
|
+
|
|
94
120
|
- `hex` (`string`) — Hex color string
|
|
95
121
|
|
|
96
122
|
**Returns:** `string | null` — Comma-separated RGB triplet, or `null` if invalid
|
|
97
123
|
|
|
98
124
|
**Example:**
|
|
125
|
+
|
|
99
126
|
```typescript
|
|
100
127
|
import { hexToRgbTriplet } from "@marianmeres/design-tokens";
|
|
101
128
|
|
|
@@ -106,31 +133,37 @@ hexToRgbTriplet("#2563eb"); // → "37, 99, 235"
|
|
|
106
133
|
|
|
107
134
|
### `generateRebootBridge(tokens, prefix)`
|
|
108
135
|
|
|
109
|
-
|
|
136
|
+
_Import from `@marianmeres/design-tokens/reboot`_
|
|
110
137
|
|
|
111
138
|
Map design tokens to Bootstrap Reboot `--bs-*` CSS variables. Automatically generates `-rgb` triplet companions for hex color values.
|
|
112
139
|
|
|
113
140
|
**Parameters:**
|
|
141
|
+
|
|
114
142
|
- `tokens` (`GeneratedTokens`) — Generated token pairs (from `generateCssTokens`)
|
|
115
|
-
- `prefix` (`string`) — The same prefix used in `generateCssTokens`
|
|
143
|
+
- `prefix` (`string`) — The same prefix used in `generateCssTokens` (trailing dash optional)
|
|
116
144
|
|
|
117
145
|
**Returns:** `GeneratedTokens` — Bootstrap bridge variables (`bs-body-bg`, `bs-link-color`, etc.)
|
|
118
146
|
|
|
147
|
+
**Note on `-rgb` companions:** Bootstrap's alpha-blended rules (e.g. `rgba(var(--bs-link-color-rgb), 0.5)`) require raw RGB triplets. This bridge emits `--bs-*-rgb` only when the underlying token resolves to a literal hex color. Auto-derived hover/active tokens are `color-mix()` expressions and cannot produce triplets — the companions are omitted, and Reboot rules that rely on them fall back to defaults. Provide explicit hex `hover` / `active` values on your `ColorPair`s if you need full alpha-blend support.
|
|
148
|
+
|
|
119
149
|
---
|
|
120
150
|
|
|
121
|
-
### `generateThemedCss(schema, prefix)`
|
|
151
|
+
### `generateThemedCss(schema, prefix, options?)`
|
|
122
152
|
|
|
123
|
-
|
|
153
|
+
_Import from `@marianmeres/design-tokens/reboot`_
|
|
124
154
|
|
|
125
155
|
Generate complete themed CSS including both design tokens AND the Bootstrap Reboot bridge.
|
|
126
156
|
|
|
127
157
|
**Parameters:**
|
|
158
|
+
|
|
128
159
|
- `schema` (`ThemeSchema`) — Theme schema with light and optional dark modes
|
|
129
|
-
- `prefix` (`string`) — CSS variable prefix
|
|
160
|
+
- `prefix` (`string`) — CSS variable prefix (trailing dash optional)
|
|
161
|
+
- `options` (`Omit<GenerateThemeOptions, "cssLayer">`, optional) — Forwarded to `generateCssTokens` for each mode (see `generateCssTokens`)
|
|
130
162
|
|
|
131
163
|
**Returns:** `string` — Combined CSS with token variables and `--bs-*` bridge variables
|
|
132
164
|
|
|
133
165
|
**Example:**
|
|
166
|
+
|
|
134
167
|
```typescript
|
|
135
168
|
import { generateThemedCss } from "@marianmeres/design-tokens/reboot";
|
|
136
169
|
import { zinc } from "@marianmeres/design-tokens/themes";
|
|
@@ -141,14 +174,37 @@ const css = generateThemedCss(zinc, "app-");
|
|
|
141
174
|
|
|
142
175
|
---
|
|
143
176
|
|
|
177
|
+
### `getBundledTheme(name)`
|
|
178
|
+
|
|
179
|
+
_Import from `@marianmeres/design-tokens/themes`_
|
|
180
|
+
|
|
181
|
+
Look up a bundled theme by its camelCase name. Returns `undefined` if the name is not a known theme.
|
|
182
|
+
|
|
183
|
+
**Parameters:**
|
|
184
|
+
|
|
185
|
+
- `name` (`string`) — Theme name (camelCase, e.g. `"blueOrange"`)
|
|
186
|
+
|
|
187
|
+
**Returns:** `ThemeSchema | undefined`
|
|
188
|
+
|
|
189
|
+
**Example:**
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
import { getBundledTheme } from "@marianmeres/design-tokens/themes";
|
|
193
|
+
|
|
194
|
+
const theme = getBundledTheme("mauveTeal");
|
|
195
|
+
if (theme) { /* use theme */ }
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
144
200
|
## Types
|
|
145
201
|
|
|
146
202
|
### `ThemeSchema`
|
|
147
203
|
|
|
148
204
|
```typescript
|
|
149
205
|
type ThemeSchema = {
|
|
150
|
-
|
|
151
|
-
|
|
206
|
+
light: TokenSchema;
|
|
207
|
+
dark?: TokenSchema;
|
|
152
208
|
};
|
|
153
209
|
```
|
|
154
210
|
|
|
@@ -160,17 +216,17 @@ Complete theme definition with required light mode and optional dark mode.
|
|
|
160
216
|
|
|
161
217
|
```typescript
|
|
162
218
|
type TokenSchema = {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
219
|
+
colors: {
|
|
220
|
+
intent: WithRequired<IntentColorKey, ColorPair>;
|
|
221
|
+
role: {
|
|
222
|
+
paired: WithKnown<RolePairedKey, RolePairedOptionalKey, ColorPair>;
|
|
223
|
+
single: WithRequired<RoleSingleKey, SingleColor>;
|
|
224
|
+
};
|
|
225
|
+
};
|
|
170
226
|
};
|
|
171
227
|
```
|
|
172
228
|
|
|
173
|
-
Single-mode token schema. Intent colors define primary UI actions; role colors define structural UI elements.
|
|
229
|
+
Single-mode token schema. Intent colors define primary UI actions; role colors define structural UI elements. Arbitrary string keys are allowed on every collection (for custom additions).
|
|
174
230
|
|
|
175
231
|
---
|
|
176
232
|
|
|
@@ -178,14 +234,16 @@ Single-mode token schema. Intent colors define primary UI actions; role colors d
|
|
|
178
234
|
|
|
179
235
|
```typescript
|
|
180
236
|
type ColorPair = {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
237
|
+
DEFAULT: string;
|
|
238
|
+
foreground: string;
|
|
239
|
+
hover?: string;
|
|
240
|
+
active?: string;
|
|
241
|
+
foregroundHover?: string;
|
|
242
|
+
foregroundActive?: string;
|
|
185
243
|
};
|
|
186
244
|
```
|
|
187
245
|
|
|
188
|
-
Color with a foreground companion. Hover/active are auto-derived when omitted.
|
|
246
|
+
Color with a foreground companion. Hover/active are auto-derived when omitted. `foregroundHover` and `foregroundActive` default to `foreground` — provide them if your foreground should change on interaction.
|
|
189
247
|
|
|
190
248
|
---
|
|
191
249
|
|
|
@@ -193,9 +251,9 @@ Color with a foreground companion. Hover/active are auto-derived when omitted.
|
|
|
193
251
|
|
|
194
252
|
```typescript
|
|
195
253
|
type ColorValue = {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
254
|
+
DEFAULT: string;
|
|
255
|
+
hover?: string;
|
|
256
|
+
active?: string;
|
|
199
257
|
};
|
|
200
258
|
```
|
|
201
259
|
|
|
@@ -213,6 +271,32 @@ Either a plain CSS color string or an object with optional hover/active states.
|
|
|
213
271
|
|
|
214
272
|
---
|
|
215
273
|
|
|
274
|
+
### `GenerateOptions`
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
type GenerateOptions = {
|
|
278
|
+
mode?: "light" | "dark";
|
|
279
|
+
deriveStates?: boolean;
|
|
280
|
+
surfaceForegroundContrast?: number;
|
|
281
|
+
};
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Options passed to `generateCssTokens`. See the function docs above for field meanings.
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
### `GenerateThemeOptions`
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
type GenerateThemeOptions = Omit<GenerateOptions, "mode"> & {
|
|
292
|
+
cssLayer?: string;
|
|
293
|
+
};
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Options passed to `generateThemeCss`. Omits `mode` (set automatically per section) and adds `cssLayer` for optional `@layer` wrapping.
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
216
300
|
### `GeneratedTokens`
|
|
217
301
|
|
|
218
302
|
```typescript
|
|
@@ -237,6 +321,18 @@ type IntentColorKey = "primary" | "accent" | "destructive" | "warning" | "succes
|
|
|
237
321
|
type RolePairedKey = "background" | "muted" | "surface";
|
|
238
322
|
```
|
|
239
323
|
|
|
324
|
+
Required paired role keys.
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
### `RolePairedOptionalKey`
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
type RolePairedOptionalKey = "surface-1";
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Optional paired role keys. Conventional but not required — all bundled themes define `surface-1` as an additional elevation layer. Additional arbitrary string keys are also allowed.
|
|
335
|
+
|
|
240
336
|
---
|
|
241
337
|
|
|
242
338
|
### `RoleSingleKey`
|
|
@@ -247,6 +343,27 @@ type RoleSingleKey = "foreground" | "border" | "input" | "ring";
|
|
|
247
343
|
|
|
248
344
|
---
|
|
249
345
|
|
|
346
|
+
### `WithRequired` / `WithOptional` / `WithKnown`
|
|
347
|
+
|
|
348
|
+
Helper types for schema collections:
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
type WithRequired<K extends string, V> =
|
|
352
|
+
& Record<K, V>
|
|
353
|
+
& Record<string, V>;
|
|
354
|
+
|
|
355
|
+
type WithOptional<K extends string, V> =
|
|
356
|
+
& Partial<Record<K, V>>
|
|
357
|
+
& Record<string, V>;
|
|
358
|
+
|
|
359
|
+
type WithKnown<Req extends string, Opt extends string, V> =
|
|
360
|
+
& Record<Req, V>
|
|
361
|
+
& Partial<Record<Opt, V>>
|
|
362
|
+
& Record<string, V>;
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
250
367
|
## Constants
|
|
251
368
|
|
|
252
369
|
### `colors`
|
|
@@ -262,31 +379,75 @@ Tailwind CSS color palette as hex values. Contains `black`, `white`, and 26 colo
|
|
|
262
379
|
```typescript
|
|
263
380
|
import { colors } from "@marianmeres/design-tokens";
|
|
264
381
|
|
|
265
|
-
colors.blue[600]
|
|
266
|
-
colors.mauve[500]
|
|
267
|
-
colors.white
|
|
382
|
+
colors.blue[600]; // → "#2563eb"
|
|
383
|
+
colors.mauve[500]; // → "#79697b"
|
|
384
|
+
colors.white; // → "#ffffff"
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
### `bundledThemes`
|
|
390
|
+
|
|
391
|
+
_Import from `@marianmeres/design-tokens/themes`_
|
|
392
|
+
|
|
393
|
+
Map of all bundled themes keyed by their camelCase name. Safe to iterate — the non-theme exports (`themeNames`, `ThemeSchema`) are filtered out.
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
import { bundledThemes } from "@marianmeres/design-tokens/themes";
|
|
397
|
+
|
|
398
|
+
Object.keys(bundledThemes); // → ["amberOliveSafari", "blueOrange", ...]
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
### `bundledThemeNames`
|
|
404
|
+
|
|
405
|
+
_Import from `@marianmeres/design-tokens/themes`_
|
|
406
|
+
|
|
407
|
+
Array of all bundled theme names (camelCase), discovered at runtime from `bundledThemes`.
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
### `themeNames`
|
|
412
|
+
|
|
413
|
+
_Import from `@marianmeres/design-tokens/themes`_
|
|
414
|
+
|
|
415
|
+
Kebab-case theme name strings matching the generated CSS filenames (without extension). Typed as a `readonly` tuple.
|
|
416
|
+
|
|
417
|
+
```typescript
|
|
418
|
+
import { themeNames } from "@marianmeres/design-tokens/themes";
|
|
419
|
+
|
|
420
|
+
themeNames; // → ["amber-olive-safari", "blue-orange", ..., "zinc"]
|
|
268
421
|
```
|
|
269
422
|
|
|
270
423
|
---
|
|
271
424
|
|
|
272
425
|
## Bundled Themes
|
|
273
426
|
|
|
274
|
-
|
|
427
|
+
_Import from `@marianmeres/design-tokens/themes`_
|
|
428
|
+
|
|
429
|
+
43 pre-built `ThemeSchema` definitions, each with light + dark mode:
|
|
275
430
|
|
|
276
|
-
|
|
431
|
+
`amberOliveSafari`, `blueOrange`, `cyanRed`, `cyanSlate`, `emeraldAmberForest`, `emeraldPink`, `fuchsiaEmerald`, `gray`, `indigoAmber`, `limeFuchsiaNeon`, `mauve`, `mauveLimeElectric`, `mauveTeal`, `mist`, `mistIndigoFjord`, `mistVioletAurora`, `monokaiCyan`, `monokaiGreen`, `monokaiPink`, `olive`, `oliveAmberSafari`, `orangePinkSunset`, `pinkEmerald`, `pinkTeal`, `purpleYellow`, `rainbow`, `redBlue`, `redCyan`, `redSky`, `redSkySlate`, `roseTeal`, `skyAmber`, `slateCyan`, `slateTealOcean`, `stone`, `stoneOrangeEarth`, `taupe`, `taupeOliveClay`, `taupeRoseBlush`, `tealRose`, `violetLime`, `violetRoseDusk`, `zinc`
|
|
277
432
|
|
|
278
|
-
|
|
433
|
+
All bundled themes include a `surface-1` paired role (on top of the required `background`, `muted`, `surface`) as a conventional extra elevation.
|
|
279
434
|
|
|
280
435
|
---
|
|
281
436
|
|
|
282
437
|
## Pre-built CSS
|
|
283
438
|
|
|
284
|
-
|
|
439
|
+
_npm only — JSR does not support directory exports, so the pre-built CSS files are not available via JSR._
|
|
285
440
|
|
|
286
|
-
All bundled themes are also distributed as pre-built CSS files
|
|
441
|
+
All bundled themes are also distributed as pre-built CSS files. Import via `@marianmeres/design-tokens/css/{theme-name}.css`.
|
|
287
442
|
|
|
288
443
|
```typescript
|
|
289
444
|
import "@marianmeres/design-tokens/css/mauve-teal.css";
|
|
290
445
|
```
|
|
291
446
|
|
|
292
|
-
|
|
447
|
+
The default prefix on the published files is `stuic-` (i.e. tokens are named `--stuic-color-primary`, etc.). To regenerate the CSS files locally with a different prefix, set the `CSS_PREFIX` environment variable before running the build:
|
|
448
|
+
|
|
449
|
+
```bash
|
|
450
|
+
CSS_PREFIX=app- deno task css:build
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
Available files: `amber-olive-safari.css`, `blue-orange.css`, `cyan-red.css`, `mauve-teal.css`, `mist-indigo-fjord.css`, `taupe-rose-blush.css`, etc. (one per bundled theme).
|
package/README.md
CHANGED
|
@@ -37,6 +37,8 @@ const theme: ThemeSchema = {
|
|
|
37
37
|
background: { DEFAULT: "#ffffff", foreground: "#171717" },
|
|
38
38
|
muted: { DEFAULT: "#f5f5f5", foreground: "#737373" },
|
|
39
39
|
surface: { DEFAULT: "#e5e5e5", foreground: "#171717" },
|
|
40
|
+
// Optional extra elevation (all bundled themes include it):
|
|
41
|
+
"surface-1": { DEFAULT: "#d4d4d4", foreground: "#171717" },
|
|
40
42
|
},
|
|
41
43
|
single: {
|
|
42
44
|
foreground: "#171717",
|
|
@@ -49,6 +51,7 @@ const theme: ThemeSchema = {
|
|
|
49
51
|
},
|
|
50
52
|
};
|
|
51
53
|
|
|
54
|
+
// The prefix's trailing dash is optional — "my" and "my-" are equivalent.
|
|
52
55
|
const css = generateThemeCss(theme, "my-");
|
|
53
56
|
// → :root { --my-color-primary: #2563eb; ... }
|
|
54
57
|
```
|
|
@@ -62,6 +65,7 @@ All bundled themes are available as pre-built CSS files with the `stuic-` prefix
|
|
|
62
65
|
```
|
|
63
66
|
|
|
64
67
|
Or via bundler import:
|
|
68
|
+
|
|
65
69
|
```ts
|
|
66
70
|
import "@marianmeres/design-tokens/css/mauve-teal.css";
|
|
67
71
|
```
|
|
@@ -98,6 +102,10 @@ const myTheme: ThemeSchema = {
|
|
|
98
102
|
DEFAULT: colors.slate[200],
|
|
99
103
|
foreground: colors.slate[900],
|
|
100
104
|
},
|
|
105
|
+
"surface-1": {
|
|
106
|
+
DEFAULT: colors.slate[300],
|
|
107
|
+
foreground: colors.slate[900],
|
|
108
|
+
},
|
|
101
109
|
},
|
|
102
110
|
single: {
|
|
103
111
|
foreground: colors.slate[900],
|
|
@@ -126,6 +134,29 @@ import { generateThemeCss } from "@marianmeres/design-tokens";
|
|
|
126
134
|
const css = generateThemeCss(zinc, "app-");
|
|
127
135
|
```
|
|
128
136
|
|
|
137
|
+
Dynamic lookup via the registry (useful when the theme name comes from config):
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
import { bundledThemeNames, getBundledTheme } from "@marianmeres/design-tokens/themes";
|
|
141
|
+
|
|
142
|
+
const theme = getBundledTheme("mauveTeal");
|
|
143
|
+
if (theme) {
|
|
144
|
+
const css = generateThemeCss(theme, "app-");
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Options
|
|
149
|
+
|
|
150
|
+
`generateThemeCss` and `generateCssTokens` accept an options object:
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
generateThemeCss(zinc, "app-", {
|
|
154
|
+
deriveStates: false, // disable color-mix hover/active derivation
|
|
155
|
+
surfaceForegroundContrast: 70, // stronger contrast on surface-{intent}-foreground
|
|
156
|
+
cssLayer: "tokens", // wrap output in @layer tokens { ... }
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
129
160
|
## Reboot bridge
|
|
130
161
|
|
|
131
162
|
Maps design tokens to Bootstrap Reboot's `--bs-*` CSS variables:
|