@tenphi/glaze 1.0.0 → 1.1.1
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 +1 -1
- package/dist/index.cjs +398 -237
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +101 -36
- package/dist/index.d.mts +101 -36
- package/dist/index.mjs +395 -238
- package/dist/index.mjs.map +1 -1
- package/docs/api.md +111 -53
- package/docs/migration.md +5 -0
- package/package.json +1 -1
package/docs/api.md
CHANGED
|
@@ -32,21 +32,37 @@ Full reference for every public method, option, and type exported by `@tenphi/gl
|
|
|
32
32
|
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
33
33
|
| `glaze(hue, saturation?, config?)` | Create a theme from hue (0–360) and saturation (0–100). Optional `config` overrides the global config for this theme. |
|
|
34
34
|
| `glaze({ hue, saturation }, config?)` | Create a theme from an options object, with optional per-theme config override. |
|
|
35
|
-
| `glaze.
|
|
35
|
+
| `glaze.themeFrom(data)` | Create a theme from a `theme.export()` snapshot (`kind: 'theme'`). |
|
|
36
|
+
| `glaze.from(data)` | Compat alias for `glaze.themeFrom`. |
|
|
36
37
|
| `glaze.fromHex(hex)` | Create a theme from a hex color (`#rgb` or `#rrggbb`). Extracts hue and saturation. |
|
|
37
38
|
| `glaze.fromRgb(r, g, b)` | Create a theme from RGB values (0–255). Extracts hue and saturation. |
|
|
39
|
+
| `glaze.paletteFrom(data)` | Create a palette from a `palette.export()` snapshot (`kind: 'palette'`). |
|
|
40
|
+
| `glaze.colorFrom(data)` | Create a color token from a `token.export()` snapshot (`kind: 'color'`). |
|
|
41
|
+
| `glaze.isThemeExport(data)` | Type guard for theme authoring snapshots. |
|
|
42
|
+
| `glaze.isColorTokenExport(data)` | Type guard for color-token authoring snapshots. |
|
|
43
|
+
| `glaze.isPaletteExport(data)` | Type guard for palette authoring snapshots. |
|
|
38
44
|
|
|
39
45
|
```ts
|
|
40
46
|
const a = glaze(280, 80);
|
|
41
47
|
const b = glaze({ hue: 280, saturation: 80 });
|
|
42
48
|
const c = glaze.fromHex('#7a4dbf');
|
|
43
49
|
const d = glaze.fromRgb(122, 77, 191);
|
|
44
|
-
const e = glaze.
|
|
50
|
+
const e = glaze.themeFrom(a.export());
|
|
45
51
|
|
|
46
52
|
// Per-theme config override:
|
|
47
53
|
const rawTheme = glaze(280, 80, { lightTone: false, darkTone: false });
|
|
48
54
|
```
|
|
49
55
|
|
|
56
|
+
Authoring restore triad (parallel to `.export()` on each instance):
|
|
57
|
+
|
|
58
|
+
| Export | Restore |
|
|
59
|
+
| ------ | ------- |
|
|
60
|
+
| `theme.export()` | `glaze.themeFrom()` |
|
|
61
|
+
| `token.export()` | `glaze.colorFrom()` |
|
|
62
|
+
| `palette.export()` | `glaze.paletteFrom()` |
|
|
63
|
+
|
|
64
|
+
Every snapshot includes `kind` + `version` (`GLAZE_EXPORT_VERSION`, currently `1`). Legacy snapshots without those fields still restore. Wrong `kind`, or a `version` outside `1..=GLAZE_EXPORT_VERSION`, throws.
|
|
65
|
+
|
|
50
66
|
The optional `config` parameter is a `GlazeConfigOverride` — see [Per-instance config override](#per-instance-config-override).
|
|
51
67
|
|
|
52
68
|
---
|
|
@@ -66,7 +82,7 @@ A `GlazeTheme` exposes:
|
|
|
66
82
|
| `theme.has(name)` | Check if a color is defined. |
|
|
67
83
|
| `theme.list()` | List all defined color names. |
|
|
68
84
|
| `theme.reset()` | Clear all color definitions. |
|
|
69
|
-
| `theme.export()`
|
|
85
|
+
| `theme.export(override?)` | Export the theme configuration as a JSON-safe object (optional config override at export time). |
|
|
70
86
|
| `theme.extend(options)` | Create a child theme inheriting all color definitions (see [`extend`](#themeextendoptions) below). |
|
|
71
87
|
| `theme.resolve()` | Resolve all colors and return a `Map<string, ResolvedColor>`. |
|
|
72
88
|
| `theme.tokens(options?)` | Export as a flat token map grouped by scheme variant. |
|
|
@@ -334,16 +350,27 @@ A Tailwind CSS v4 `@theme` block (light baseline) plus dark / high-contrast over
|
|
|
334
350
|
| `highContrastSelector` | `'.high-contrast'` | Selector wrapping the light high-contrast overrides. The combined dark + high-contrast block uses `${darkSelector}${highContrastSelector}` (e.g. `.dark.high-contrast`). |
|
|
335
351
|
| `modes` | global config | Which scheme variants to include. The `@theme` block (light) is always emitted when colors exist. |
|
|
336
352
|
|
|
337
|
-
### `theme.export()`
|
|
353
|
+
### `theme.export(override?)`
|
|
338
354
|
|
|
339
355
|
```ts
|
|
340
356
|
const snapshot = theme.export();
|
|
341
|
-
// → {
|
|
357
|
+
// → {
|
|
358
|
+
// kind: 'theme',
|
|
359
|
+
// version: 1,
|
|
360
|
+
// hue: 280,
|
|
361
|
+
// saturation: 80,
|
|
362
|
+
// colors: { surface: { ... }, ... },
|
|
363
|
+
// config: { lightTone: {...}, darkTone: {...}, pastel: false, ... },
|
|
364
|
+
// }
|
|
342
365
|
|
|
343
|
-
const restored = glaze.
|
|
366
|
+
const restored = glaze.themeFrom(snapshot);
|
|
344
367
|
```
|
|
345
368
|
|
|
346
|
-
|
|
369
|
+
Returns a deep-cloned, JSON-safe authoring snapshot (definitions + frozen
|
|
370
|
+
effective config — not resolved color strings). Freezes
|
|
371
|
+
`getConfig() ∪ instance local ∪ override` at call time. Restored themes pin
|
|
372
|
+
that freeze as their local override. Distinct from `theme.json()`, which
|
|
373
|
+
emits resolved color strings.
|
|
347
374
|
|
|
348
375
|
---
|
|
349
376
|
|
|
@@ -395,7 +422,7 @@ type ColorDef = RegularColorDef | ShadowColorDef | MixColorDef;
|
|
|
395
422
|
| `mode` | `'auto' \| 'fixed' \| 'static'` | Adaptation mode. Default: `'auto'`. See [Adaptation modes](#adaptation-modes). |
|
|
396
423
|
| `autoFlip` | `boolean` | Flip out-of-bounds results (relative `tone` overshoot / unmet `contrast`) to the opposite side instead of clamping. Default: the global `autoFlip` (`true`). See [`autoFlip`](#autoflip). |
|
|
397
424
|
| `opacity` | `number` | Fixed alpha 0–1. Output includes alpha in the CSS value. Combining with `contrast` is not recommended (a `console.warn` is emitted). |
|
|
398
|
-
| `pastel` | `boolean` | Per-color override for the hue-independent "safe" chroma limit used in OKHSL↔sRGB conversions (luminance, contrast solving, output formatting). Falls through to the
|
|
425
|
+
| `pastel` | `boolean` | Per-color override for the hue-independent "safe" chroma limit used in OKHSL↔sRGB conversions (luminance, contrast solving, output formatting). Falls through to the per-theme / per-token `pastel` override when omitted. Default: unset. See [Per-color `pastel`](#per-color-pastel). |
|
|
399
426
|
| `role` | `RoleInput` | Semantic role against `base` (`'text'` / `'surface'` / `'border'` or an alias). Fixes APCA contrast polarity. Resolved via: explicit `role` → name inference → opposite of the base's role → `'text'`. See [Roles](#roles). |
|
|
400
427
|
| `inherit` | `boolean` | Whether this color is inherited by child themes via `extend()`. Default: `true`. Set to `false` to make the color local to the current theme. |
|
|
401
428
|
|
|
@@ -420,7 +447,8 @@ It gives an exact contrast step for neutrals and a stable visual progression for
|
|
|
420
447
|
chromatic colors. In dark mode with `mode: 'auto'`, it is anchored to the
|
|
421
448
|
base's per-scheme tone. If `base + delta` falls outside `[0, 100]`, the result
|
|
422
449
|
is clamped to the boundary, or — with `autoFlip` (default on) — mirrored to the
|
|
423
|
-
other side of the base.
|
|
450
|
+
other side of the base. If the mirrored target is also out of range, the original
|
|
451
|
+
delta is kept and clamped on the authored side.
|
|
424
452
|
|
|
425
453
|
**Extreme tone** (`'max'` / `'min'`) forces the color to the scheme's tone extreme without a contrast hack or a magic number. `'max'` resolves to author tone 100 and `'min'` to 0; both flow through scheme mapping like an absolute tone, so under `mode: 'auto'` they invert in dark (`'max'` is lightest in light, darkest in dark). Use `mode: 'static'` to pin the same extreme across schemes, or `mode: 'fixed'` to keep the same end without inverting. No `base` required.
|
|
426
454
|
|
|
@@ -430,7 +458,7 @@ A dependent color with `base` but no `tone` inherits the base's tone (equivalent
|
|
|
430
458
|
|
|
431
459
|
`autoFlip` governs what happens when a result would fall outside its valid range:
|
|
432
460
|
|
|
433
|
-
- **Relative `tone` overshoot:** when `base ± delta` exceeds `[0, 100]`, `autoFlip` mirrors the delta to the other side of the base (e.g. `'+30'` becomes `'-30'`) instead of clamping to the boundary.
|
|
461
|
+
- **Relative `tone` overshoot:** when `base ± delta` exceeds `[0, 100]`, `autoFlip` mirrors the delta to the other side of the base (e.g. `'+30'` becomes `'-30'`) instead of clamping to the boundary. If the mirrored target is also outside `[0, 100]`, the original delta is kept and clamped on the authored side.
|
|
434
462
|
- **`contrast` direction:** when the requested tone direction can't meet the floor, `autoFlip` lets the solver try the opposite side (the same behavior as the global `autoFlip`).
|
|
435
463
|
|
|
436
464
|
`autoFlip` defaults to the global `autoFlip` (`true`). Set `autoFlip: false` on a color to clamp instead of mirror — useful when you want a relative offset to stay on the authored side of the base, or to keep an unmet contrast pinned to one direction's extreme.
|
|
@@ -523,7 +551,7 @@ Relative hue is always relative to the **theme seed hue**, not to a base color.
|
|
|
523
551
|
|
|
524
552
|
#### Per-color `pastel`
|
|
525
553
|
|
|
526
|
-
`pastel: true` on a single color def overrides the
|
|
554
|
+
`pastel: true` on a single color def overrides the per-theme / per-token `pastel` override for that color only. It toggles the hue-independent "safe" chroma limit used in every OKHSL↔sRGB conversion that touches this color: luminance calculations during contrast solving, gamut clamping during sRGB blend / mix edges, and output formatting. The effective flag is carried on the resolved variant (`ResolvedColorVariant.pastel`) so formatting matches the gamut mapping applied during resolution.
|
|
527
555
|
|
|
528
556
|
```ts
|
|
529
557
|
const theme = glaze(280, 80);
|
|
@@ -535,7 +563,7 @@ theme.colors({
|
|
|
535
563
|
// theme.css().light contains different rgb() triples for `--plain` and `--soft`
|
|
536
564
|
```
|
|
537
565
|
|
|
538
|
-
Omit the field to inherit the
|
|
566
|
+
Omit the field to inherit the theme/token `pastel` override (default `false`) — useful for keeping the default behavior while opting a single accent into the pastel gamut.
|
|
539
567
|
|
|
540
568
|
The flag is part of the def object, so `extend()` copies it through to child themes alongside the rest of the def. Override it again on the child to flip a single color back:
|
|
541
569
|
|
|
@@ -665,7 +693,7 @@ glaze.color(color: GlazeFromInput | GlazeColorInput | GlazeColorValue, config?:
|
|
|
665
693
|
| `opacity` | `number` | Fixed alpha 0–1. |
|
|
666
694
|
| `base` | `GlazeColorToken \| GlazeColorValue` | Optional dependency. See [Pairing colors](#pairing-colors). |
|
|
667
695
|
| `contrast` | `HCPair<ContrastSpec>` | Contrast floor against `base` (WCAG or APCA). Without `base`, anchored to the literal seed. |
|
|
668
|
-
| `pastel` | `boolean` | Per-color `pastel` override. Falls through to the
|
|
696
|
+
| `pastel` | `boolean` | Per-color `pastel` override. Falls through to the per-theme / per-token `pastel` override when omitted. See [Per-color `pastel`](#per-color-pastel). |
|
|
669
697
|
| `role` | `RoleInput` | Semantic role against `base` / the seed (see [Roles](#roles)). Fixes APCA polarity. |
|
|
670
698
|
| `name` | `string` | Debug label for warnings; doesn't change output keys. Reserved names (`'value'`, `'seed'`, `'externalBase'`) are rejected. |
|
|
671
699
|
|
|
@@ -683,7 +711,7 @@ glaze.color(color: GlazeFromInput | GlazeColorInput | GlazeColorValue, config?:
|
|
|
683
711
|
| `contrast` | Contrast floor (WCAG or APCA). Without `base`, anchored to the literal seed; with `base`, solved per scheme. |
|
|
684
712
|
| `base` | `GlazeColorToken` or raw `GlazeColorValue`. See [Pairing colors](#pairing-colors). |
|
|
685
713
|
| `opacity` | Fixed alpha 0–1. Combining with `contrast` is not recommended — `console.warn` is emitted. |
|
|
686
|
-
| `pastel` | Per-color `pastel` override. Falls through to the
|
|
714
|
+
| `pastel` | Per-color `pastel` override. Falls through to the per-theme / per-token `pastel` override when omitted. See [Per-color `pastel`](#per-color-pastel). |
|
|
687
715
|
| `role` | Semantic role against `base` / the seed (see [Roles](#roles)). Fixes APCA polarity. |
|
|
688
716
|
| `name` | Debug label only — surfaces in warnings/errors. Does not change output keys. |
|
|
689
717
|
|
|
@@ -691,14 +719,14 @@ Named CSS colors (`'red'`, `'blueviolet'`) are not supported.
|
|
|
691
719
|
|
|
692
720
|
### Defaults
|
|
693
721
|
|
|
694
|
-
Every input form defaults to `mode: 'auto'` so the resolved token adapts between light and dark like an ordinary theme color.
|
|
722
|
+
Every input form defaults to `mode: 'auto'` so the resolved token adapts between light and dark like an ordinary theme color. Tokens store a **sparse local** config override; omitted fields fall through to the live global at resolve time (same as themes). Authoring `.export(override?)` freezes `getConfig() ∪ local ∪ override` at call time.
|
|
695
723
|
|
|
696
724
|
- **Value-shorthand** (bare strings, value objects, and `{ from, ...overrides }`):
|
|
697
|
-
- Light variant preserves the input tone exactly (`lightTone: false`).
|
|
698
|
-
-
|
|
725
|
+
- Light variant preserves the input tone exactly (`lightTone: false` as a local default).
|
|
726
|
+
- Other omitted fields track the live global config.
|
|
699
727
|
- **Structured input** (`{ hue, saturation, tone, ... }`):
|
|
700
|
-
-
|
|
701
|
-
-
|
|
728
|
+
- Omitted tone windows and other fields track the live global config (same as a theme color).
|
|
729
|
+
- `pastel` is instance-only — set via the config override or per-color `pastel`, not `glaze.configure()`.
|
|
702
730
|
|
|
703
731
|
```ts
|
|
704
732
|
// Bare string — adapts automatically
|
|
@@ -731,25 +759,27 @@ A `GlazeColorToken` exposes:
|
|
|
731
759
|
| `token.dtcg(options?)` | DTCG color tokens, one per scheme variant (no color-name key). Each entry is a full `{ $type: 'color', $value }` token. Options: `colorSpace` (`'srgb'` \| `'oklch'`), `modes`. |
|
|
732
760
|
| `token.dtcgResolver({ name, ... })` | A single DTCG Resolver-Module document for this color, keyed by `name` across all scheme variants. `name` is **required**. Same options as `theme.dtcgResolver()` plus `name`. |
|
|
733
761
|
| `token.tailwind({ name, ... })` | Tailwind v4 `@theme` block + dark / high-contrast overrides for this color. `name` is **required** (forms `--color-<name>`). Same options as `theme.tailwind()` plus `name`. |
|
|
734
|
-
| `token.export()`
|
|
762
|
+
| `token.export(override?)` | JSON-safe snapshot — freezes effective config at call time; pass to `glaze.colorFrom(...)` to rehydrate. Optional `override` merges over the instance local (and nested `base` exports). |
|
|
735
763
|
|
|
736
764
|
### Per-instance config override
|
|
737
765
|
|
|
738
766
|
The optional `config` argument (`GlazeConfigOverride`) overrides
|
|
739
|
-
resolve-relevant
|
|
740
|
-
`[lo, hi]`, `{ lo, hi, eps }`, or `false` (full range).
|
|
741
|
-
|
|
742
|
-
|
|
767
|
+
resolve-relevant fields for a token or theme. A tone window can be
|
|
768
|
+
`[lo, hi]`, `{ lo, hi, eps }`, or `false` (full range). Both themes and
|
|
769
|
+
standalone tokens keep a sparse local override — omitted fields (except
|
|
770
|
+
instance-only `pastel`) fall through to the live global at resolve time.
|
|
743
771
|
|
|
744
772
|
`GlazeConfigOverride`:
|
|
745
773
|
|
|
746
|
-
| Field | Default (from global) | Description |
|
|
747
|
-
| ------------------ |
|
|
748
|
-
| `lightTone` | `[10, 100]`
|
|
749
|
-
| `darkTone` | `[15, 95]`
|
|
750
|
-
| `darkDesaturation` | `0.1`
|
|
751
|
-
| `autoFlip` | `true`
|
|
752
|
-
| `
|
|
774
|
+
| Field | Default (from global / fixed) | Description |
|
|
775
|
+
| ------------------ | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
776
|
+
| `lightTone` | `[10, 100]` | Light tone window: `[lo, hi]`, `{ lo, hi, eps }`, or `false` (disable clamping). |
|
|
777
|
+
| `darkTone` | `[15, 95]` | Dark tone window: `[lo, hi]`, `{ lo, hi, eps }`, or `false` (disable clamping). |
|
|
778
|
+
| `darkDesaturation` | `0.1` | Saturation reduction in dark scheme (0–1). |
|
|
779
|
+
| `autoFlip` | `true` | Default for each color's `autoFlip`: when solving `contrast` (or applying a relative `tone` that overshoots), allow crossing to the opposite side instead of clamping. |
|
|
780
|
+
| `pastel` | `false` (instance-only) | Theme/token-level pastel default for colors that omit per-color `pastel`. Not available on `glaze.configure()`. |
|
|
781
|
+
| `inferRole` | `true` | Infer color `role` from the name when unset. |
|
|
782
|
+
| `shadowTuning` | `undefined` | Default shadow tuning (meaningful for themes; harmless on color tokens). |
|
|
753
783
|
|
|
754
784
|
Config overrides apply to both `glaze.color()` tokens and `glaze()` themes:
|
|
755
785
|
|
|
@@ -764,16 +794,13 @@ glaze.color('#000000', {
|
|
|
764
794
|
});
|
|
765
795
|
|
|
766
796
|
// Structured form with config override
|
|
767
|
-
glaze.color({ hue: 152, saturation: 95, tone: 74 }, { darkTone: false });
|
|
797
|
+
glaze.color({ hue: 152, saturation: 95, tone: 74 }, { darkTone: false, pastel: true });
|
|
768
798
|
|
|
769
799
|
// Theme with config override
|
|
770
|
-
const rawTheme = glaze(280, 80, { lightTone: false });
|
|
800
|
+
const rawTheme = glaze(280, 80, { lightTone: false, pastel: true });
|
|
771
801
|
```
|
|
772
802
|
|
|
773
|
-
|
|
774
|
-
Themes behave differently: overridden fields stay fixed, while fields omitted
|
|
775
|
-
from the override are read from the live global config at resolve time. See
|
|
776
|
-
[Theme config override](#theme-config-override).
|
|
803
|
+
See [Theme config override](#theme-config-override).
|
|
777
804
|
|
|
778
805
|
### Theme config override
|
|
779
806
|
|
|
@@ -797,11 +824,17 @@ const child = t.extend({ config: { darkTone: false } });
|
|
|
797
824
|
// child: lightTone { lo: 0, hi: 50 } (inherited) + darkTone: false (added)
|
|
798
825
|
```
|
|
799
826
|
|
|
800
|
-
`theme.export()`
|
|
827
|
+
`theme.export(override?)` freezes `getConfig() ∪ instance local ∪ override` at
|
|
828
|
+
call time. Restoring via `glaze.themeFrom(data)` (or the compat alias
|
|
829
|
+
`glaze.from`) pins that freeze as the restored theme's local override — matching
|
|
830
|
+
standalone color-token behavior.
|
|
801
831
|
|
|
802
832
|
### `glaze.colorFrom(data)`
|
|
803
833
|
|
|
804
|
-
Inverse of `token.export()`. The exported snapshot includes the original input,
|
|
834
|
+
Inverse of `token.export()`. The exported snapshot includes the original input,
|
|
835
|
+
all overrides (with any `base` token recursively serialized), and the effective
|
|
836
|
+
config freeze from export time — so later `glaze.configure()` calls don't change
|
|
837
|
+
rehydrated tokens.
|
|
805
838
|
|
|
806
839
|
```ts
|
|
807
840
|
const text = glaze.color({ from: '#1a1a1a', contrast: 'AA' });
|
|
@@ -1085,15 +1118,41 @@ const palette = glaze.palette(
|
|
|
1085
1118
|
|
|
1086
1119
|
A `GlazePalette` exposes:
|
|
1087
1120
|
|
|
1088
|
-
| Method | Description
|
|
1089
|
-
| -------------------------------- |
|
|
1090
|
-
| `palette.
|
|
1091
|
-
| `palette.
|
|
1092
|
-
| `palette.
|
|
1093
|
-
| `palette.
|
|
1094
|
-
| `palette.
|
|
1095
|
-
| `palette.
|
|
1096
|
-
| `palette.
|
|
1121
|
+
| Method | Description |
|
|
1122
|
+
| -------------------------------- | ---------------------------------------------------------------------------------------------------- |
|
|
1123
|
+
| `palette.list()` | Theme names in insertion order. |
|
|
1124
|
+
| `palette.primary` | Primary theme name, if set. |
|
|
1125
|
+
| `palette.theme(name)` | Get a live theme instance by name. |
|
|
1126
|
+
| `palette.themes()` | Shallow copy of the theme map (same instances the palette holds). |
|
|
1127
|
+
| `palette.export(override?)` | Authoring snapshot — restorable via `glaze.paletteFrom()`. Optional override forwarded to themes. |
|
|
1128
|
+
| `palette.tokens(options?)` | Flat token map grouped by scheme variant. |
|
|
1129
|
+
| `palette.tasty(options?)` | [Tasty](https://tasty.style) style-to-state bindings. |
|
|
1130
|
+
| `palette.json(options?)` | Per-theme **resolved** color JSON (not restorable as authoring config). |
|
|
1131
|
+
| `palette.css(options?)` | CSS custom property declaration strings. |
|
|
1132
|
+
| `palette.dtcg(options?)` | Per-scheme W3C DTCG token trees. |
|
|
1133
|
+
| `palette.dtcgResolver(options?)` | One DTCG Resolver-Module document for every scheme. |
|
|
1134
|
+
| `palette.tailwind(options?)` | One Tailwind CSS v4 theme with scheme overrides. |
|
|
1135
|
+
|
|
1136
|
+
### `palette.export(override?)` / `glaze.paletteFrom()`
|
|
1137
|
+
|
|
1138
|
+
```ts
|
|
1139
|
+
const snapshot = palette.export();
|
|
1140
|
+
// → {
|
|
1141
|
+
// kind: 'palette',
|
|
1142
|
+
// version: 1,
|
|
1143
|
+
// primary: 'brand',
|
|
1144
|
+
// themes: { brand: { kind: 'theme', ... }, danger: { ... } },
|
|
1145
|
+
// }
|
|
1146
|
+
|
|
1147
|
+
const restored = glaze.paletteFrom(JSON.parse(JSON.stringify(snapshot)));
|
|
1148
|
+
const brand = restored.theme('brand')!;
|
|
1149
|
+
```
|
|
1150
|
+
|
|
1151
|
+
Optional `override` is forwarded to each nested `theme.export(override)`.
|
|
1152
|
+
Config snapshot vs resolved output: use `export()` / `paletteFrom()` to
|
|
1153
|
+
persist and restore the authoring graph (themes, color defs, relations). Use
|
|
1154
|
+
`json()` / `tokens()` / `css()` / … to emit resolved color strings for apps
|
|
1155
|
+
and design tools.
|
|
1097
1156
|
|
|
1098
1157
|
### `GlazePaletteExportOptions`
|
|
1099
1158
|
|
|
@@ -1297,7 +1356,7 @@ On `theme.css()`, `theme.tasty()`, `palette.css()`, `palette.tasty()`, and stand
|
|
|
1297
1356
|
--accent-color: oklch(0.62 0.03 var(--accent-hue));
|
|
1298
1357
|
```
|
|
1299
1358
|
|
|
1300
|
-
**Requirements:** every exported color must be pastel (`pastel: true`
|
|
1359
|
+
**Requirements:** every exported color must be pastel (`pastel: true` on the theme/token override or per-color). Pastel mode bounds chroma by the hue-independent safe chroma at each lightness, so emitted `C` stays in sRGB for any rotated hue. Non-pastel palettes throw rather than emit values that would clip under rotation.
|
|
1301
1360
|
|
|
1302
1361
|
**Limitations:** `oklch` only (native CSS `var()` in the hue slot). Shadow and mix colors stay inline (blended hue). Standalone `.token()` / `.tasty()` do not support `splitHue` (return shape cannot carry the `$name-hue` declaration).
|
|
1303
1362
|
|
|
@@ -1332,7 +1391,7 @@ Light: accent-fill tone=52, accent-text tone='+20' → lighter than the fill
|
|
|
1332
1391
|
Dark: accent-fill maps into the dark window, sign preserved
|
|
1333
1392
|
```
|
|
1334
1393
|
|
|
1335
|
-
Offsets that would push past `[0, 100]` clamp to the boundary, or — with `autoFlip` (default on) — mirror to the other side of the base. Set `autoFlip: false` to keep the authored side and clamp instead.
|
|
1394
|
+
Offsets that would push past `[0, 100]` clamp to the boundary, or — with `autoFlip` (default on) — mirror to the other side of the base. If the mirror also overshoots, the original side is kept and clamped. Set `autoFlip: false` to keep the authored side and clamp instead.
|
|
1336
1395
|
|
|
1337
1396
|
**`static`** — no adaptation, same tone in every scheme.
|
|
1338
1397
|
|
|
@@ -1433,7 +1492,6 @@ boundaries, not the tone transfer.
|
|
|
1433
1492
|
| `modes.highContrast` | `false` | Include HC variants. |
|
|
1434
1493
|
| `shadowTuning` | `undefined` | Default tuning for all shadow colors. Per-color tuning merges field-by-field. |
|
|
1435
1494
|
| `autoFlip` | `true` | Default for each color's `autoFlip`. When solving `contrast` (or applying a relative `tone` that overshoots `[0, 100]`), allow crossing to the opposite side instead of clamping. With `false`, only the requested direction is considered; unmet contrasts pin the tone to that direction's extreme (and emit a warning) and overshooting offsets clamp to the boundary. Override per color via [`autoFlip`](#autoflip). |
|
|
1436
|
-
| `pastel` | `false` | Hue-independent "safe" chroma limit across all colors so scaling saturation never exceeds the sRGB boundary at any hue for the given lightness. Override per color via [`pastel`](#per-color-pastel). |
|
|
1437
1495
|
| `inferRole` | `true` | Infer each color's [`role`](#roles) from its name when no explicit `role` is set. Set to `false` to opt out of name-based inference (the base-opposite and foreground-default fallbacks still apply). |
|
|
1438
1496
|
|
|
1439
1497
|
| Method | Description |
|
|
@@ -1442,7 +1500,7 @@ boundaries, not the tone transfer.
|
|
|
1442
1500
|
| `glaze.getConfig()` | Snapshot the current resolved config (shallow copy). |
|
|
1443
1501
|
| `glaze.resetConfig()` | Reset to defaults (also bumps the version counter). |
|
|
1444
1502
|
|
|
1445
|
-
|
|
1503
|
+
Themes and standalone color tokens keep a sparse local `GlazeConfigOverride` and merge the live global at resolve time for omitted fields. Authoring `.export(override?)` freezes the effective merge at call time; restored instances pin that freeze. `pastel` is instance-only (theme/token override or per-color) — not set via `configure()`.
|
|
1446
1504
|
|
|
1447
1505
|
---
|
|
1448
1506
|
|
|
@@ -1484,7 +1542,7 @@ available result.
|
|
|
1484
1542
|
| Relative `tone` without `base` in a **theme** color | Validation error |
|
|
1485
1543
|
| `contrast` without `base` in `glaze.color()` | Anchors against the literal seed (no error) |
|
|
1486
1544
|
| Relative `tone` without `base` in `glaze.color()` | Anchors against the literal seed (no error) |
|
|
1487
|
-
| Relative `tone` overshoots `[0, 100]` | Mirror to the other side of the base (`autoFlip` on, default), or clamp to the boundary (`autoFlip` off) |
|
|
1545
|
+
| Relative `tone` overshoots `[0, 100]` | Mirror to the other side of the base (`autoFlip` on, default), or clamp to the boundary (`autoFlip` off). If the mirror also overshoots, clamp on the authored side. |
|
|
1488
1546
|
| `tone` resolves outside 0–100 | Clamp silently |
|
|
1489
1547
|
| `'max'` / `'min'` without `base` | Allowed — resolves to the scheme's tone extreme (root color) |
|
|
1490
1548
|
| `saturation` outside 0–1 | Clamp silently |
|
package/docs/migration.md
CHANGED
|
@@ -16,6 +16,11 @@ If you're starting from scratch, see [methodology.md](methodology.md) first —
|
|
|
16
16
|
|
|
17
17
|
## Choosing an export
|
|
18
18
|
|
|
19
|
+
Glaze has two layers of “export”:
|
|
20
|
+
|
|
21
|
+
1. **Authoring snapshots** — `theme.export(override?)` / `token.export(override?)` / `palette.export(override?)`, restored with `glaze.themeFrom` / `colorFrom` / `paletteFrom`. These carry definitions, relations, and a config freeze taken at export time (`kind` + `version`). Live instances keep only a sparse local override; omitted global fields track `configure()` until export.
|
|
22
|
+
2. **Resolved output** — the seven shapes below. These are color strings / design-token documents for apps and tools, **not** restorable as authoring config.
|
|
23
|
+
|
|
19
24
|
Glaze emits the same resolved colors in seven shapes. Pick one based on your
|
|
20
25
|
renderer or tooling.
|
|
21
26
|
|
package/package.json
CHANGED