@tenphi/glaze 0.3.0 → 0.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/README.md +96 -7
- package/dist/index.cjs +42 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +44 -5
- package/dist/index.d.mts +44 -5
- package/dist/index.mjs +42 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -70,7 +70,7 @@ const success = primary.extend({ hue: 157 });
|
|
|
70
70
|
// Compose into a palette and export
|
|
71
71
|
const palette = glaze.palette({ primary, danger, success });
|
|
72
72
|
const tokens = palette.tokens({ prefix: true });
|
|
73
|
-
// → {
|
|
73
|
+
// → { light: { 'primary-surface': 'okhsl(...)', ... }, dark: { 'primary-surface': 'okhsl(...)', ... } }
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
## Core Concepts
|
|
@@ -262,7 +262,8 @@ Create a single color token without a full theme:
|
|
|
262
262
|
const accent = glaze.color({ hue: 280, saturation: 80, lightness: 52, mode: 'fixed' });
|
|
263
263
|
|
|
264
264
|
accent.resolve(); // → ResolvedColor with light/dark/lightContrast/darkContrast
|
|
265
|
-
accent.token(); // → { '': 'okhsl(...)', '@dark': 'okhsl(...)' }
|
|
265
|
+
accent.token(); // → { '': 'okhsl(...)', '@dark': 'okhsl(...)' } (tasty format)
|
|
266
|
+
accent.tasty(); // → { '': 'okhsl(...)', '@dark': 'okhsl(...)' } (same as token)
|
|
266
267
|
accent.json(); // → { light: 'okhsl(...)', dark: 'okhsl(...)' }
|
|
267
268
|
```
|
|
268
269
|
|
|
@@ -307,7 +308,7 @@ theme.tokens({ format: 'hsl' }); // → 'hsl(270.5, 45.2%, 95.8%)'
|
|
|
307
308
|
theme.tokens({ format: 'oklch' }); // → 'oklch(96.5% 0.0123 280.0)'
|
|
308
309
|
```
|
|
309
310
|
|
|
310
|
-
The `format` option works on all export methods: `theme.tokens()`, `theme.json()`, `theme.css()`, `palette.tokens()`, `palette.json()`, `palette.css()`, and standalone `glaze.color().token()` / `.json()`.
|
|
311
|
+
The `format` option works on all export methods: `theme.tokens()`, `theme.tasty()`, `theme.json()`, `theme.css()`, `palette.tokens()`, `palette.tasty()`, `palette.json()`, `palette.css()`, and standalone `glaze.color().token()` / `.tasty()` / `.json()`.
|
|
311
312
|
|
|
312
313
|
Available formats:
|
|
313
314
|
|
|
@@ -410,18 +411,93 @@ const palette = glaze.palette({ primary, danger, success, warning });
|
|
|
410
411
|
|
|
411
412
|
### Token Export
|
|
412
413
|
|
|
414
|
+
Tokens are grouped by scheme variant, with plain color names as keys:
|
|
415
|
+
|
|
413
416
|
```ts
|
|
414
417
|
const tokens = palette.tokens({ prefix: true });
|
|
415
418
|
// → {
|
|
419
|
+
// light: { 'primary-surface': 'okhsl(...)', 'danger-surface': 'okhsl(...)' },
|
|
420
|
+
// dark: { 'primary-surface': 'okhsl(...)', 'danger-surface': 'okhsl(...)' },
|
|
421
|
+
// }
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
Custom prefix mapping:
|
|
425
|
+
|
|
426
|
+
```ts
|
|
427
|
+
palette.tokens({ prefix: { primary: 'brand-', danger: 'error-' } });
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Tasty Export (for [Tasty](https://cube-ui-kit.vercel.app/?path=/docs/tasty-documentation--docs) style system)
|
|
431
|
+
|
|
432
|
+
The `tasty()` method exports tokens in the [Tasty](https://cube-ui-kit.vercel.app/?path=/docs/tasty-documentation--docs) style-to-state binding format — `#name` color token keys with state aliases (`''`, `@dark`, etc.):
|
|
433
|
+
|
|
434
|
+
```ts
|
|
435
|
+
const tastyTokens = palette.tasty({ prefix: true });
|
|
436
|
+
// → {
|
|
416
437
|
// '#primary-surface': { '': 'okhsl(...)', '@dark': 'okhsl(...)' },
|
|
417
438
|
// '#danger-surface': { '': 'okhsl(...)', '@dark': 'okhsl(...)' },
|
|
418
439
|
// }
|
|
419
440
|
```
|
|
420
441
|
|
|
442
|
+
Apply as global styles to make color tokens available app-wide:
|
|
443
|
+
|
|
444
|
+
```ts
|
|
445
|
+
import { useGlobalStyles } from '@cube-dev/ui-kit';
|
|
446
|
+
|
|
447
|
+
// In your root component
|
|
448
|
+
useGlobalStyles('body', tastyTokens);
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
For zero-runtime builds, use `tastyStatic` to generate the CSS at build time:
|
|
452
|
+
|
|
453
|
+
```ts
|
|
454
|
+
import { tastyStatic } from '@cube-dev/ui-kit';
|
|
455
|
+
|
|
456
|
+
tastyStatic('body', tastyTokens);
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
Alternatively, register as a recipe via `configure()`:
|
|
460
|
+
|
|
461
|
+
```ts
|
|
462
|
+
import { configure, tasty } from '@cube-dev/ui-kit';
|
|
463
|
+
|
|
464
|
+
configure({
|
|
465
|
+
recipes: {
|
|
466
|
+
'all-themes': tastyTokens,
|
|
467
|
+
},
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
const Page = tasty({
|
|
471
|
+
styles: {
|
|
472
|
+
recipe: 'all-themes',
|
|
473
|
+
fill: '#primary-surface',
|
|
474
|
+
color: '#primary-text',
|
|
475
|
+
},
|
|
476
|
+
});
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
Or spread directly into component styles:
|
|
480
|
+
|
|
481
|
+
```ts
|
|
482
|
+
const Card = tasty({
|
|
483
|
+
styles: {
|
|
484
|
+
...tastyTokens,
|
|
485
|
+
fill: '#primary-surface',
|
|
486
|
+
color: '#primary-text',
|
|
487
|
+
},
|
|
488
|
+
});
|
|
489
|
+
```
|
|
490
|
+
|
|
421
491
|
Custom prefix mapping:
|
|
422
492
|
|
|
423
493
|
```ts
|
|
424
|
-
palette.
|
|
494
|
+
palette.tasty({ prefix: { primary: 'brand-', danger: 'error-' } });
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
Custom state aliases:
|
|
498
|
+
|
|
499
|
+
```ts
|
|
500
|
+
palette.tasty({ states: { dark: '@dark', highContrast: '@hc' } });
|
|
425
501
|
```
|
|
426
502
|
|
|
427
503
|
### JSON Export (Framework-Agnostic)
|
|
@@ -488,17 +564,22 @@ Control which scheme variants appear in exports:
|
|
|
488
564
|
```ts
|
|
489
565
|
// Light only
|
|
490
566
|
palette.tokens({ modes: { dark: false, highContrast: false } });
|
|
567
|
+
// → { light: { ... } }
|
|
491
568
|
|
|
492
569
|
// Light + dark (default)
|
|
493
570
|
palette.tokens({ modes: { highContrast: false } });
|
|
571
|
+
// → { light: { ... }, dark: { ... } }
|
|
494
572
|
|
|
495
573
|
// All four variants
|
|
496
574
|
palette.tokens({ modes: { dark: true, highContrast: true } });
|
|
575
|
+
// → { light: { ... }, dark: { ... }, lightContrast: { ... }, darkContrast: { ... } }
|
|
497
576
|
```
|
|
498
577
|
|
|
578
|
+
The `modes` option works the same way on `tokens()`, `tasty()`, `json()`, and `css()`.
|
|
579
|
+
|
|
499
580
|
Resolution priority (highest first):
|
|
500
581
|
|
|
501
|
-
1. `tokens({ modes })` / `json({ modes })` / `css({ ... })` — per-call override
|
|
582
|
+
1. `tokens({ modes })` / `tasty({ modes })` / `json({ modes })` / `css({ ... })` — per-call override
|
|
502
583
|
2. `glaze.configure({ modes })` — global config
|
|
503
584
|
3. Built-in default: `{ dark: true, highContrast: false }`
|
|
504
585
|
|
|
@@ -609,8 +690,15 @@ const note = primary.extend({ hue: 302 });
|
|
|
609
690
|
|
|
610
691
|
const palette = glaze.palette({ primary, danger, success, warning, note });
|
|
611
692
|
|
|
612
|
-
// Export as
|
|
693
|
+
// Export as flat token map grouped by variant
|
|
613
694
|
const tokens = palette.tokens({ prefix: true });
|
|
695
|
+
// tokens.light → { 'primary-surface': 'okhsl(...)', 'danger-surface': 'okhsl(...)' }
|
|
696
|
+
// tokens.dark → { 'primary-surface': 'okhsl(...)', 'danger-surface': 'okhsl(...)' }
|
|
697
|
+
|
|
698
|
+
// Export as tasty style-to-state bindings (for Tasty style system)
|
|
699
|
+
const tastyTokens = palette.tasty({ prefix: true });
|
|
700
|
+
// tastyTokens['#primary-surface'] → { '': 'okhsl(...)', '@dark': 'okhsl(...)' }
|
|
701
|
+
// Use as a recipe or spread into component styles (see Tasty Export section)
|
|
614
702
|
|
|
615
703
|
// Export as RGB for broader CSS compatibility
|
|
616
704
|
const rgbTokens = palette.tokens({ prefix: true, format: 'rgb' });
|
|
@@ -656,7 +744,8 @@ brand.colors({ surface: { lightness: 97 }, text: { base: 'surface', lightness: '
|
|
|
656
744
|
| `theme.export()` | Export configuration as JSON-safe object |
|
|
657
745
|
| `theme.extend(options)` | Create a child theme |
|
|
658
746
|
| `theme.resolve()` | Resolve all colors |
|
|
659
|
-
| `theme.tokens(options?)` | Export as token map |
|
|
747
|
+
| `theme.tokens(options?)` | Export as flat token map grouped by variant |
|
|
748
|
+
| `theme.tasty(options?)` | Export as [Tasty](https://cube-ui-kit.vercel.app/?path=/docs/tasty-documentation--docs) style-to-state bindings |
|
|
660
749
|
| `theme.json(options?)` | Export as plain JSON |
|
|
661
750
|
| `theme.css(options?)` | Export as CSS custom property declarations |
|
|
662
751
|
|
package/dist/index.cjs
CHANGED
|
@@ -998,6 +998,20 @@ function buildTokenMap(resolved, prefix, states, modes, format = "okhsl") {
|
|
|
998
998
|
}
|
|
999
999
|
return tokens;
|
|
1000
1000
|
}
|
|
1001
|
+
function buildFlatTokenMap(resolved, prefix, modes, format = "okhsl") {
|
|
1002
|
+
const result = { light: {} };
|
|
1003
|
+
if (modes.dark) result.dark = {};
|
|
1004
|
+
if (modes.highContrast) result.lightContrast = {};
|
|
1005
|
+
if (modes.dark && modes.highContrast) result.darkContrast = {};
|
|
1006
|
+
for (const [name, color] of resolved) {
|
|
1007
|
+
const key = `${prefix}${name}`;
|
|
1008
|
+
result.light[key] = formatVariant(color.light, format);
|
|
1009
|
+
if (modes.dark) result.dark[key] = formatVariant(color.dark, format);
|
|
1010
|
+
if (modes.highContrast) result.lightContrast[key] = formatVariant(color.lightContrast, format);
|
|
1011
|
+
if (modes.dark && modes.highContrast) result.darkContrast[key] = formatVariant(color.darkContrast, format);
|
|
1012
|
+
}
|
|
1013
|
+
return result;
|
|
1014
|
+
}
|
|
1001
1015
|
function buildJsonMap(resolved, modes, format = "okhsl") {
|
|
1002
1016
|
const result = {};
|
|
1003
1017
|
for (const [name, color] of resolved) {
|
|
@@ -1079,6 +1093,9 @@ function createTheme(hue, saturation, initialColors) {
|
|
|
1079
1093
|
return resolveAllColors(hue, saturation, colorDefs);
|
|
1080
1094
|
},
|
|
1081
1095
|
tokens(options) {
|
|
1096
|
+
return buildFlatTokenMap(resolveAllColors(hue, saturation, colorDefs), "", resolveModes(options?.modes), options?.format);
|
|
1097
|
+
},
|
|
1098
|
+
tasty(options) {
|
|
1082
1099
|
return buildTokenMap(resolveAllColors(hue, saturation, colorDefs), "", {
|
|
1083
1100
|
dark: options?.states?.dark ?? globalConfig.states.dark,
|
|
1084
1101
|
highContrast: options?.states?.highContrast ?? globalConfig.states.highContrast
|
|
@@ -1092,9 +1109,26 @@ function createTheme(hue, saturation, initialColors) {
|
|
|
1092
1109
|
}
|
|
1093
1110
|
};
|
|
1094
1111
|
}
|
|
1112
|
+
function resolvePrefix(options, themeName) {
|
|
1113
|
+
if (options?.prefix === true) return `${themeName}-`;
|
|
1114
|
+
if (typeof options?.prefix === "object" && options.prefix !== null) return options.prefix[themeName] ?? `${themeName}-`;
|
|
1115
|
+
return "";
|
|
1116
|
+
}
|
|
1095
1117
|
function createPalette(themes) {
|
|
1096
1118
|
return {
|
|
1097
1119
|
tokens(options) {
|
|
1120
|
+
const modes = resolveModes(options?.modes);
|
|
1121
|
+
const allTokens = {};
|
|
1122
|
+
for (const [themeName, theme] of Object.entries(themes)) {
|
|
1123
|
+
const tokens = buildFlatTokenMap(theme.resolve(), resolvePrefix(options, themeName), modes, options?.format);
|
|
1124
|
+
for (const variant of Object.keys(tokens)) {
|
|
1125
|
+
if (!allTokens[variant]) allTokens[variant] = {};
|
|
1126
|
+
Object.assign(allTokens[variant], tokens[variant]);
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
return allTokens;
|
|
1130
|
+
},
|
|
1131
|
+
tasty(options) {
|
|
1098
1132
|
const states = {
|
|
1099
1133
|
dark: options?.states?.dark ?? globalConfig.states.dark,
|
|
1100
1134
|
highContrast: options?.states?.highContrast ?? globalConfig.states.highContrast
|
|
@@ -1102,11 +1136,7 @@ function createPalette(themes) {
|
|
|
1102
1136
|
const modes = resolveModes(options?.modes);
|
|
1103
1137
|
const allTokens = {};
|
|
1104
1138
|
for (const [themeName, theme] of Object.entries(themes)) {
|
|
1105
|
-
const
|
|
1106
|
-
let prefix = "";
|
|
1107
|
-
if (options?.prefix === true) prefix = `${themeName}-`;
|
|
1108
|
-
else if (typeof options?.prefix === "object" && options.prefix !== null) prefix = options.prefix[themeName] ?? `${themeName}-`;
|
|
1109
|
-
const tokens = buildTokenMap(resolved, prefix, states, modes, options?.format);
|
|
1139
|
+
const tokens = buildTokenMap(theme.resolve(), resolvePrefix(options, themeName), states, modes, options?.format);
|
|
1110
1140
|
Object.assign(allTokens, tokens);
|
|
1111
1141
|
}
|
|
1112
1142
|
return allTokens;
|
|
@@ -1127,11 +1157,7 @@ function createPalette(themes) {
|
|
|
1127
1157
|
darkContrast: []
|
|
1128
1158
|
};
|
|
1129
1159
|
for (const [themeName, theme] of Object.entries(themes)) {
|
|
1130
|
-
const
|
|
1131
|
-
let prefix = "";
|
|
1132
|
-
if (options?.prefix === true) prefix = `${themeName}-`;
|
|
1133
|
-
else if (typeof options?.prefix === "object" && options.prefix !== null) prefix = options.prefix[themeName] ?? `${themeName}-`;
|
|
1134
|
-
const css = buildCssMap(resolved, prefix, suffix, format);
|
|
1160
|
+
const css = buildCssMap(theme.resolve(), resolvePrefix(options, themeName), suffix, format);
|
|
1135
1161
|
for (const key of [
|
|
1136
1162
|
"light",
|
|
1137
1163
|
"dark",
|
|
@@ -1164,6 +1190,12 @@ function createColorToken(input) {
|
|
|
1164
1190
|
highContrast: options?.states?.highContrast ?? globalConfig.states.highContrast
|
|
1165
1191
|
}, resolveModes(options?.modes), options?.format)["#__color__"];
|
|
1166
1192
|
},
|
|
1193
|
+
tasty(options) {
|
|
1194
|
+
return buildTokenMap(resolveAllColors(input.hue, input.saturation, defs), "", {
|
|
1195
|
+
dark: options?.states?.dark ?? globalConfig.states.dark,
|
|
1196
|
+
highContrast: options?.states?.highContrast ?? globalConfig.states.highContrast
|
|
1197
|
+
}, resolveModes(options?.modes), options?.format)["#__color__"];
|
|
1198
|
+
},
|
|
1167
1199
|
json(options) {
|
|
1168
1200
|
return buildJsonMap(resolveAllColors(input.hue, input.saturation, defs), resolveModes(options?.modes), options?.format)["__color__"];
|
|
1169
1201
|
}
|