@tenphi/glaze 0.11.1 → 0.12.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/dist/index.cjs +218 -152
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +114 -33
- package/dist/index.d.mts +114 -33
- package/dist/index.mjs +218 -152
- package/dist/index.mjs.map +1 -1
- package/docs/api.md +17 -11
- package/docs/methodology.md +12 -6
- package/package.json +1 -1
package/docs/api.md
CHANGED
|
@@ -240,6 +240,8 @@ type MinContrast = number | 'AA' | 'AAA' | 'AA-large' | 'AAA-large';
|
|
|
240
240
|
|
|
241
241
|
You can also pass any numeric ratio directly (e.g., `contrast: 4.5`, `contrast: 11`). The constraint is applied independently for each scheme — if the `lightness` already satisfies the floor it's kept, otherwise the solver adjusts lightness until the target is met.
|
|
242
242
|
|
|
243
|
+
By default, `autoFlip` lets the solver cross to the opposite side of the base color when the requested lightness direction cannot satisfy contrast. Set `glaze.configure({ autoFlip: false })` to keep strict directionality: unmet colors pin to that direction's 0 or 100 lightness extreme instead of falling back to the original requested value.
|
|
244
|
+
|
|
243
245
|
**Full lightness spectrum in HC mode:** in high-contrast variants the `lightLightness` and `darkLightness` window constraints are bypassed entirely. Colors can reach the full 0–100 range, maximizing perceivable contrast.
|
|
244
246
|
|
|
245
247
|
#### Per-color hue override
|
|
@@ -306,7 +308,8 @@ glaze.color(value: GlazeColorValue, overrides?: GlazeColorOverrides, scaling?: G
|
|
|
306
308
|
| `okhsl()` | `'okhsl(152 95% 74%)'` | Glaze's own emit format. Alpha dropped with warning. |
|
|
307
309
|
| `oklch()` | `'oklch(0.85 0.18 152)'` | Glaze's own emit format. Alpha dropped with warning. |
|
|
308
310
|
| `OkhslColor` object | `{ h: 152, s: 0.95, l: 0.74 }` | Glaze's native shape (h: 0–360, s/l: 0–1). Passing 0–100 for `s`/`l` throws with a hint to use the structured form. |
|
|
309
|
-
|
|
|
311
|
+
| `RgbColor` object | `{ r: 38, g: 252, b: 178 }` | sRGB 0–255. RGB tuple `[r, g, b]` is not supported — use this object form. |
|
|
312
|
+
| `OklchColor` object | `{ l: 0.85, c: 0.18, h: 152 }` | OKLCh (L/C: 0–1, H: degrees), same semantics as `oklch()` strings. |
|
|
310
313
|
|
|
311
314
|
`GlazeColorInput` (the structured input) is `{ hue, saturation, lightness, ... }`:
|
|
312
315
|
|
|
@@ -328,11 +331,11 @@ Named CSS colors (`'red'`, `'blueviolet'`) are not supported.
|
|
|
328
331
|
|
|
329
332
|
Every input form defaults to `mode: 'auto'` so the resolved token adapts between light and dark like an ordinary theme color. The *scaling* snapshot taken at create time differs by input form:
|
|
330
333
|
|
|
331
|
-
- **
|
|
334
|
+
- **Value-shorthand** (hex, `rgb()` / `hsl()` / `okhsl()` / `oklch()` strings, `{ r, g, b }`, `{ h, s, l }`, `{ l, c, h }`):
|
|
332
335
|
- Light variant preserves the input lightness exactly (`lightLightness: false`).
|
|
333
|
-
- Dark variant
|
|
334
|
-
- **
|
|
335
|
-
- Both
|
|
336
|
+
- Dark variant uses `globalConfig.darkLightness` (default `[15, 95]`), snapshotted at create time.
|
|
337
|
+
- **Structured input** (`{ hue, saturation, lightness, ... }`):
|
|
338
|
+
- Both variants use `globalConfig.lightLightness` / `globalConfig.darkLightness` (defaults `[10, 100]` / `[15, 95]`) — same as a theme color.
|
|
336
339
|
- All windows are **snapshotted at color-creation time** so later `glaze.configure()` calls don't retroactively change exported tokens. `token.export()` round-trips byte-for-byte.
|
|
337
340
|
|
|
338
341
|
To opt back into the legacy fixed-linear default (no Möbius inversion), pass `{ mode: 'fixed' }` as the second arg, or supply an explicit `scaling` (see [`GlazeColorScaling`](#glazecolorscaling)).
|
|
@@ -357,10 +360,10 @@ Overrides for the value-shorthand overload's second argument:
|
|
|
357
360
|
|
|
358
361
|
Per-call lightness-window override. Mirrors `GlazeConfig`'s field names:
|
|
359
362
|
|
|
360
|
-
| Key | Default for
|
|
363
|
+
| Key | Default for value-shorthand | Default for structured input | Effect |
|
|
361
364
|
|---|---|---|---|
|
|
362
365
|
| `lightLightness` | `false` | `globalConfig.lightLightness` (snapshotted) | `false` = preserve input. Pass `[lo, hi]` to opt into a remap window. |
|
|
363
|
-
| `darkLightness` | `
|
|
366
|
+
| `darkLightness` | `globalConfig.darkLightness` (snapshotted) | `globalConfig.darkLightness` (snapshotted) | `false` = preserve input in dark too. Pass `[lo, hi]` to override the window (e.g. `[15, 100]` for a `#000` → white dark flip). |
|
|
364
367
|
|
|
365
368
|
Passing `scaling` is **all-or-nothing** — both fields are replaced. To keep one field's default while overriding the other, restate the default explicitly.
|
|
366
369
|
|
|
@@ -368,10 +371,10 @@ Passing `scaling` is **all-or-nothing** — both fields are replaced. To keep on
|
|
|
368
371
|
// Preserve raw lightness in dark mode too
|
|
369
372
|
glaze.color('#26fcb2', undefined, { darkLightness: false });
|
|
370
373
|
|
|
371
|
-
// Opt
|
|
372
|
-
glaze.color('#
|
|
374
|
+
// Opt into theme-style light remap + extended dark (e.g. #000 → white in dark)
|
|
375
|
+
glaze.color('#000000', undefined, {
|
|
373
376
|
lightLightness: [10, 100],
|
|
374
|
-
darkLightness: [15,
|
|
377
|
+
darkLightness: [15, 100],
|
|
375
378
|
});
|
|
376
379
|
|
|
377
380
|
// Structured form takes scaling as the second positional arg
|
|
@@ -931,6 +934,7 @@ glaze.configure({
|
|
|
931
934
|
| `modes.dark` | `true` | Include dark variants in exports. |
|
|
932
935
|
| `modes.highContrast` | `false` | Include HC variants. |
|
|
933
936
|
| `shadowTuning` | `undefined` | Default tuning for all shadow colors. Per-color tuning merges field-by-field. |
|
|
937
|
+
| `autoFlip` | `true` | When solving `contrast`, allow the solver to switch away from the requested lightness direction if that side can't meet the target. With `false`, only the requested direction is considered; unmet contrasts pin the lightness to that direction's extreme (and emit a warning). |
|
|
934
938
|
|
|
935
939
|
| Method | Description |
|
|
936
940
|
|---|---|
|
|
@@ -1070,5 +1074,7 @@ import {
|
|
|
1070
1074
|
| `lightnessRange` | `[0, 1]` | Search bounds. |
|
|
1071
1075
|
| `epsilon` | `1e-4` | Convergence threshold. |
|
|
1072
1076
|
| `maxIterations` | `14` | Max binary-search iterations per branch. |
|
|
1077
|
+
| `initialDirection` | higher-contrast side | Direction to search first (`'lighter'` or `'darker'`). Theme resolution sets this from the requested lightness relative to the base color. |
|
|
1078
|
+
| `flip` | `false` | When `true`, try the opposite direction if the initial one doesn't meet the target. When `false`, only the initial direction is searched — unmet contrasts pin the result to that direction's extreme. |
|
|
1073
1079
|
|
|
1074
|
-
Result: `{ lightness, contrast, met, branch: 'lighter' | 'darker' | 'preferred' }`.
|
|
1080
|
+
Result: `{ lightness, contrast, met, branch: 'lighter' | 'darker' | 'preferred', flipped? }`. `flipped: true` indicates the initial direction failed and the opposite direction satisfied the target.
|
package/docs/methodology.md
CHANGED
|
@@ -10,6 +10,8 @@ The default theme is what most components consume — its tokens are emitted unp
|
|
|
10
10
|
|
|
11
11
|
You design the default theme once, and `extend()` propagates that design across every status hue.
|
|
12
12
|
|
|
13
|
+
Every color definition has an **`inherit`** flag (default: `true`) controlling whether it flows into child themes via `extend()`. Set `inherit: false` to scope a color to its parent theme only — this is how sibling themes stay lean, carrying only the tokens they actually need.
|
|
14
|
+
|
|
13
15
|
## Hue / saturation seeds
|
|
14
16
|
|
|
15
17
|
Declare hues as named constants up top, plus a single shared seed saturation:
|
|
@@ -123,15 +125,15 @@ The disabled chip + label pair uses `mode: 'auto'` and **explicit numeric contra
|
|
|
123
125
|
```ts
|
|
124
126
|
'disabled-surface': {
|
|
125
127
|
base: 'surface', lightness: '-1', saturation: 0.2,
|
|
126
|
-
contrast: [1.
|
|
128
|
+
contrast: [1.5, 2], inherit: false,
|
|
127
129
|
},
|
|
128
130
|
'disabled-surface-text': {
|
|
129
|
-
base: 'surface', lightness: '
|
|
130
|
-
contrast:
|
|
131
|
+
base: 'disabled-surface', lightness: '+1', saturation: 0.3,
|
|
132
|
+
contrast: 3, inherit: false,
|
|
131
133
|
},
|
|
132
134
|
```
|
|
133
135
|
|
|
134
|
-
|
|
136
|
+
Each token anchors to its immediate parent surface — `*-surface` contrasts against the root `surface`, while `*-surface-text` contrasts against its own chip (`disabled-surface`). This keeps the disabled state self-contained and resolves to consistent ratios in light, dark, and HC (chip ≈ 1.5–2× vs surface, label ≈ 3× on chip). An alpha-tinted overlay would have asymmetric behavior — composited alpha against a near-white light surface produces a much weaker chip than the same overlay against a near-dark dark surface, and the disabled state would stop *looking* disabled in one of the schemes.
|
|
135
137
|
|
|
136
138
|
The general rule: when a color needs to *feel the same across schemes*, anchor it with `mode: 'auto'` + a numeric contrast against a surface, not with a preset.
|
|
137
139
|
|
|
@@ -143,7 +145,9 @@ The general rule: when a color needs to *feel the same across schemes*, anchor i
|
|
|
143
145
|
},
|
|
144
146
|
```
|
|
145
147
|
|
|
146
|
-
`mode: 'fixed'` skips the dark-scheme Möbius inversion and only does a linear window mapping, so `surface-inverse` reads as a dark surface in *every* scheme — light, dark, and HC.
|
|
148
|
+
`mode: 'fixed'` skips the dark-scheme Möbius inversion and only does a linear window mapping, so `surface-inverse` reads as a dark surface in *every* scheme — light, dark, and HC. In high-contrast variants the window is bypassed entirely (identity), so the color stays at its raw lightness across all four schemes.
|
|
149
|
+
|
|
150
|
+
Use it for tooltips, code blocks, popovers with their own dark theme. Pair with `#white` for foreground text.
|
|
147
151
|
|
|
148
152
|
This is the canonical "I want this color to stay recognizable" pattern. The other `mode: 'fixed'` use is the entire accent system below.
|
|
149
153
|
|
|
@@ -197,6 +201,8 @@ Mirrors the neutral disabled pair from above but with higher saturation so the c
|
|
|
197
201
|
},
|
|
198
202
|
```
|
|
199
203
|
|
|
204
|
+
The HC pair `[1.4, 1.3]` is intentionally *lower* in high-contrast mode — the tinted chip naturally gains more contrast against `surface` when the lightness window bypasses (identity mapping), so we loosen the constraint to leave room for stronger text-on-chip contrast. The text token uses `contrast: 1.51`, which is the maximum value that stays below Glaze's auto-flip threshold (the solver would otherwise invert the color past the midpoint, producing a result on the wrong side of its base). This keeps the label legible without flipping into an unexpected hue.
|
|
205
|
+
|
|
200
206
|
These are inherited (no `inherit: false`), so each colored sibling theme automatically emits `<theme>-accent-disabled-surface` and `<theme>-accent-disabled-surface-text`. PRIMARY-style disabled buttons stay tinted with the active theme's hue (danger-tinted danger button, success-tinted success button), preserving brand identity even in the disabled state.
|
|
201
207
|
|
|
202
208
|
## Per-color hue overrides (code highlighting)
|
|
@@ -206,7 +212,7 @@ The `code-*` tokens use **absolute `hue` numbers** regardless of the seed. Each
|
|
|
206
212
|
```ts
|
|
207
213
|
'code-comment': { base: 'surface', hue: 280, saturation: 0.1, lightness: '-1', contrast: [4.5, 7], inherit: false },
|
|
208
214
|
'code-keyword': { base: 'surface', hue: 348, saturation: 1, lightness: '-1', contrast: [5, 7.5], inherit: false },
|
|
209
|
-
'code-string': { base: 'surface', hue:
|
|
215
|
+
'code-string': { base: 'surface', hue: SUCCESS_HUE, saturation: 1, lightness: '-1', contrast: [4.5, 7], inherit: false },
|
|
210
216
|
// …code-punctuation, code-number, code-function, code-attribute follow the same shape
|
|
211
217
|
```
|
|
212
218
|
|
package/package.json
CHANGED