@tenphi/glaze 0.0.0-snapshot.75f81fa → 0.0.0-snapshot.78261ef
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 +63 -21
- package/dist/index.cjs +77 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +57 -25
- package/dist/index.d.mts +57 -25
- package/dist/index.mjs +77 -23
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -70,8 +70,8 @@ const danger = primary.extend({ hue: 23 });
|
|
|
70
70
|
const success = primary.extend({ hue: 157 });
|
|
71
71
|
|
|
72
72
|
// Compose into a palette and export
|
|
73
|
-
const palette = glaze.palette({ primary, danger, success });
|
|
74
|
-
const tokens = palette.tokens(
|
|
73
|
+
const palette = glaze.palette({ primary, danger, success }, { primary: 'primary' });
|
|
74
|
+
const tokens = palette.tokens();
|
|
75
75
|
// → { light: { 'primary-surface': 'okhsl(...)', 'surface': 'okhsl(...)', ... }, dark: { ... } }
|
|
76
76
|
```
|
|
77
77
|
|
|
@@ -390,6 +390,7 @@ Available tuning parameters:
|
|
|
390
390
|
| `minGapTarget` | 0.05 | Target minimum gap between pigment and bg lightness |
|
|
391
391
|
| `alphaMax` | 0.6 | Asymptotic maximum alpha |
|
|
392
392
|
| `bgHueBlend` | 0.2 | Blend weight pulling pigment hue toward bg hue |
|
|
393
|
+
| `darkShadowCurve` | 0.4 | Power curve for dark-scheme alpha (0-1). Lower = more dampening; 1 = no dampening |
|
|
393
394
|
|
|
394
395
|
### Standalone Shadow Computation
|
|
395
396
|
|
|
@@ -647,7 +648,7 @@ const t = (100 - lightness) / 100;
|
|
|
647
648
|
const invertedL = lo + (hi - lo) * t / (t + darkCurve * (1 - t)); // darkCurve default: 0.5
|
|
648
649
|
```
|
|
649
650
|
|
|
650
|
-
The `darkCurve` parameter (default `0.5`, range 0–1) controls how much the dark-mode inversion expands lightness deltas. Lower values produce stronger expansion; `1` gives linear (legacy) behavior. Unlike a power curve, the Möbius transformation provides **proportional expansion** — small and large deltas are scaled by similar ratios, preserving the visual hierarchy of the light theme.
|
|
651
|
+
The `darkCurve` parameter (default `0.5`, range 0–1) controls how much the dark-mode inversion expands lightness deltas. Lower values produce stronger expansion; `1` gives linear (legacy) behavior. Accepts a `[normal, highContrast]` pair for separate HC tuning (e.g. `darkCurve: [0.5, 0.3]`); a single number applies to both. Unlike a power curve, the Möbius transformation provides **proportional expansion** — small and large deltas are scaled by similar ratios, preserving the visual hierarchy of the light theme.
|
|
651
652
|
|
|
652
653
|
**`fixed`** — mapped without inversion (not affected by `darkCurve`):
|
|
653
654
|
|
|
@@ -661,7 +662,7 @@ const mappedL = (lightness * (hi - lo)) / 100 + lo;
|
|
|
661
662
|
| accent-fill (L=52) | 52 | 66.9 | 53.4 | 56.6 |
|
|
662
663
|
| accent-text (L=100) | 100 | 15 | 15 | 95 |
|
|
663
664
|
|
|
664
|
-
In high-contrast variants, the `darkLightness` window is bypassed
|
|
665
|
+
In high-contrast variants, the `darkLightness` window is bypassed — auto uses the Möbius curve over the full [0, 100] range, and fixed uses identity (`L`). To use a different curve shape for HC, pass a `[normal, hc]` pair to `darkCurve` (e.g. `darkCurve: [0.5, 0.3]`).
|
|
665
666
|
|
|
666
667
|
### Saturation
|
|
667
668
|
|
|
@@ -701,6 +702,15 @@ Combine multiple themes into a single palette:
|
|
|
701
702
|
const palette = glaze.palette({ primary, danger, success, warning });
|
|
702
703
|
```
|
|
703
704
|
|
|
705
|
+
Optionally designate a primary theme at creation time:
|
|
706
|
+
|
|
707
|
+
```ts
|
|
708
|
+
const palette = glaze.palette(
|
|
709
|
+
{ primary, danger, success, warning },
|
|
710
|
+
{ primary: 'primary' },
|
|
711
|
+
);
|
|
712
|
+
```
|
|
713
|
+
|
|
704
714
|
### Prefix Behavior
|
|
705
715
|
|
|
706
716
|
Palette export methods (`tokens()`, `tasty()`, `css()`) default to `prefix: true` — all tokens are automatically prefixed with the theme name to avoid collisions:
|
|
@@ -719,15 +729,28 @@ Custom prefix mapping:
|
|
|
719
729
|
palette.tokens({ prefix: { primary: 'brand-', danger: 'error-' } });
|
|
720
730
|
```
|
|
721
731
|
|
|
722
|
-
To disable prefixing entirely, pass `prefix: false` explicitly.
|
|
732
|
+
To disable prefixing entirely, pass `prefix: false` explicitly.
|
|
733
|
+
|
|
734
|
+
### Collision Detection
|
|
735
|
+
|
|
736
|
+
When two themes produce the same output key (via `prefix: false`, custom prefix maps, or primary unprefixed aliases), the first-written value wins and a `console.warn` is emitted:
|
|
737
|
+
|
|
738
|
+
```ts
|
|
739
|
+
const palette = glaze.palette({ a, b });
|
|
740
|
+
palette.tokens({ prefix: false });
|
|
741
|
+
// ⚠ glaze: token "surface" from theme "b" collides with theme "a" — skipping.
|
|
742
|
+
```
|
|
723
743
|
|
|
724
744
|
### Primary Theme
|
|
725
745
|
|
|
726
|
-
|
|
746
|
+
The primary theme's tokens are duplicated without prefix, providing convenient short aliases alongside the prefixed versions. Set at palette creation to apply to all exports automatically:
|
|
727
747
|
|
|
728
748
|
```ts
|
|
729
|
-
const palette = glaze.palette(
|
|
730
|
-
|
|
749
|
+
const palette = glaze.palette(
|
|
750
|
+
{ primary, danger, success },
|
|
751
|
+
{ primary: 'primary' },
|
|
752
|
+
);
|
|
753
|
+
const tokens = palette.tokens();
|
|
731
754
|
// → {
|
|
732
755
|
// light: {
|
|
733
756
|
// 'primary-surface': 'okhsl(...)', // prefixed (all themes)
|
|
@@ -738,11 +761,18 @@ const tokens = palette.tokens({ primary: 'primary' });
|
|
|
738
761
|
// }
|
|
739
762
|
```
|
|
740
763
|
|
|
764
|
+
Override or disable per-export:
|
|
765
|
+
|
|
766
|
+
```ts
|
|
767
|
+
palette.tokens({ primary: 'danger' }); // use danger as primary for this call
|
|
768
|
+
palette.tokens({ primary: false }); // no primary for this call
|
|
769
|
+
```
|
|
770
|
+
|
|
741
771
|
The `primary` option works on `tokens()`, `tasty()`, and `css()`. It combines with any prefix mode — when using a custom prefix map, primary tokens are still duplicated without prefix:
|
|
742
772
|
|
|
743
773
|
```ts
|
|
744
|
-
palette.tokens({ prefix: { primary: 'p-', danger: 'd-' }
|
|
745
|
-
// → 'p-surface' + 'surface' (alias) + 'd-surface'
|
|
774
|
+
palette.tokens({ prefix: { primary: 'p-', danger: 'd-' } });
|
|
775
|
+
// → 'p-surface' + 'surface' (alias from palette-level primary) + 'd-surface'
|
|
746
776
|
```
|
|
747
777
|
|
|
748
778
|
An error is thrown if the primary name doesn't match any theme in the palette.
|
|
@@ -752,7 +782,11 @@ An error is thrown if the primary name doesn't match any theme in the palette.
|
|
|
752
782
|
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.):
|
|
753
783
|
|
|
754
784
|
```ts
|
|
755
|
-
const
|
|
785
|
+
const palette = glaze.palette(
|
|
786
|
+
{ primary, danger, success },
|
|
787
|
+
{ primary: 'primary' },
|
|
788
|
+
);
|
|
789
|
+
const tastyTokens = palette.tasty();
|
|
756
790
|
// → {
|
|
757
791
|
// '#primary-surface': { '': 'okhsl(...)', '@dark': 'okhsl(...)' },
|
|
758
792
|
// '#danger-surface': { '': 'okhsl(...)', '@dark': 'okhsl(...)' },
|
|
@@ -848,7 +882,11 @@ const css = theme.css();
|
|
|
848
882
|
Use in a stylesheet:
|
|
849
883
|
|
|
850
884
|
```ts
|
|
851
|
-
const
|
|
885
|
+
const palette = glaze.palette(
|
|
886
|
+
{ primary, danger, success },
|
|
887
|
+
{ primary: 'primary' },
|
|
888
|
+
);
|
|
889
|
+
const css = palette.css();
|
|
852
890
|
|
|
853
891
|
const stylesheet = `
|
|
854
892
|
:root { ${css.light} }
|
|
@@ -865,7 +903,7 @@ Options:
|
|
|
865
903
|
| `format` | `'rgb'` | Color format (`'rgb'`, `'hsl'`, `'okhsl'`, `'oklch'`) |
|
|
866
904
|
| `suffix` | `'-color'` | Suffix appended to each CSS property name |
|
|
867
905
|
| `prefix` | `true` (palette) | (palette only) `true` uses `"<themeName>-"`, or provide a custom map |
|
|
868
|
-
| `primary` |
|
|
906
|
+
| `primary` | inherited | (palette only) Override or disable (`false`) the palette-level primary for this call |
|
|
869
907
|
|
|
870
908
|
```ts
|
|
871
909
|
// Custom suffix
|
|
@@ -876,8 +914,8 @@ theme.css({ suffix: '' });
|
|
|
876
914
|
theme.css({ format: 'hsl' });
|
|
877
915
|
// → "--surface-color: hsl(...);"
|
|
878
916
|
|
|
879
|
-
// Palette with primary
|
|
880
|
-
palette.css(
|
|
917
|
+
// Palette with primary (inherited from palette creation)
|
|
918
|
+
palette.css();
|
|
881
919
|
// → "--primary-surface-color: rgb(...);\n--surface-color: rgb(...);\n--danger-surface-color: rgb(...);"
|
|
882
920
|
```
|
|
883
921
|
|
|
@@ -914,7 +952,7 @@ glaze.configure({
|
|
|
914
952
|
lightLightness: [10, 100], // Light scheme lightness window [lo, hi] (bypassed in HC)
|
|
915
953
|
darkLightness: [15, 95], // Dark scheme lightness window [lo, hi] (bypassed in HC)
|
|
916
954
|
darkDesaturation: 0.1, // Saturation reduction in dark scheme (0–1)
|
|
917
|
-
darkCurve: 0.5, // Möbius beta for dark auto-inversion (0–1
|
|
955
|
+
darkCurve: 0.5, // Möbius beta for dark auto-inversion (0–1); or [normal, hc] pair
|
|
918
956
|
states: {
|
|
919
957
|
dark: '@dark', // State alias for dark mode tokens
|
|
920
958
|
highContrast: '@high-contrast',
|
|
@@ -926,6 +964,7 @@ glaze.configure({
|
|
|
926
964
|
shadowTuning: { // Default tuning for all shadow colors
|
|
927
965
|
alphaMax: 0.6,
|
|
928
966
|
bgHueBlend: 0.2,
|
|
967
|
+
darkShadowCurve: 0.4, // Power curve for dark-scheme alpha dampening (0-1)
|
|
929
968
|
},
|
|
930
969
|
});
|
|
931
970
|
```
|
|
@@ -1049,17 +1088,20 @@ const success = primary.extend({ hue: 157 });
|
|
|
1049
1088
|
const warning = primary.extend({ hue: 84 });
|
|
1050
1089
|
const note = primary.extend({ hue: 302 });
|
|
1051
1090
|
|
|
1052
|
-
const palette = glaze.palette(
|
|
1091
|
+
const palette = glaze.palette(
|
|
1092
|
+
{ primary, danger, success, warning, note },
|
|
1093
|
+
{ primary: 'primary' },
|
|
1094
|
+
);
|
|
1053
1095
|
|
|
1054
1096
|
// Export as flat token map grouped by variant (prefix defaults to true)
|
|
1055
|
-
const tokens = palette.tokens(
|
|
1097
|
+
const tokens = palette.tokens();
|
|
1056
1098
|
// tokens.light → { 'primary-surface': '...', 'surface': '...', 'danger-surface': '...' }
|
|
1057
1099
|
|
|
1058
1100
|
// Export as tasty style-to-state bindings (for Tasty style system)
|
|
1059
|
-
const tastyTokens = palette.tasty(
|
|
1101
|
+
const tastyTokens = palette.tasty();
|
|
1060
1102
|
|
|
1061
1103
|
// Export as CSS custom properties (rgb format by default)
|
|
1062
|
-
const css = palette.css(
|
|
1104
|
+
const css = palette.css();
|
|
1063
1105
|
// css.light → "--primary-surface-color: rgb(...);\n--surface-color: rgb(...);\n--danger-surface-color: rgb(...);"
|
|
1064
1106
|
|
|
1065
1107
|
// Standalone shadow computation
|
|
@@ -1115,7 +1157,7 @@ brand.colors({ surface: { lightness: 97 }, text: { base: 'surface', lightness: '
|
|
|
1115
1157
|
| Method | Description |
|
|
1116
1158
|
|---|---|
|
|
1117
1159
|
| `glaze.configure(config)` | Set global configuration |
|
|
1118
|
-
| `glaze.palette(themes)` | Compose themes into a palette |
|
|
1160
|
+
| `glaze.palette(themes, options?)` | Compose themes into a palette (options: `{ primary? }`) |
|
|
1119
1161
|
| `glaze.getConfig()` | Get current global config |
|
|
1120
1162
|
| `glaze.resetConfig()` | Reset to defaults |
|
|
1121
1163
|
|
package/dist/index.cjs
CHANGED
|
@@ -843,7 +843,8 @@ const DEFAULT_SHADOW_TUNING = {
|
|
|
843
843
|
lightnessBounds: [.05, .2],
|
|
844
844
|
minGapTarget: .05,
|
|
845
845
|
alphaMax: 1,
|
|
846
|
-
bgHueBlend: .2
|
|
846
|
+
bgHueBlend: .2,
|
|
847
|
+
darkShadowCurve: .4
|
|
847
848
|
};
|
|
848
849
|
function resolveShadowTuning(perColor) {
|
|
849
850
|
return {
|
|
@@ -977,7 +978,7 @@ function mobiusCurve(t, beta) {
|
|
|
977
978
|
}
|
|
978
979
|
function mapLightnessDark(l, mode, isHighContrast) {
|
|
979
980
|
if (mode === "static") return l;
|
|
980
|
-
const beta = globalConfig.darkCurve;
|
|
981
|
+
const beta = isHighContrast ? pairHC(globalConfig.darkCurve) : pairNormal(globalConfig.darkCurve);
|
|
981
982
|
const [darkLo, darkHi] = lightnessWindow(isHighContrast, "dark");
|
|
982
983
|
if (mode === "fixed") return l * (darkHi - darkLo) / 100 + darkLo;
|
|
983
984
|
const [lightLo, lightHi] = lightnessWindow(isHighContrast, "light");
|
|
@@ -985,7 +986,7 @@ function mapLightnessDark(l, mode, isHighContrast) {
|
|
|
985
986
|
return darkLo + (darkHi - darkLo) * mobiusCurve(t, beta);
|
|
986
987
|
}
|
|
987
988
|
function lightMappedToDark(lightL, isHighContrast) {
|
|
988
|
-
const beta = globalConfig.darkCurve;
|
|
989
|
+
const beta = isHighContrast ? pairHC(globalConfig.darkCurve) : pairNormal(globalConfig.darkCurve);
|
|
989
990
|
const [lightLo, lightHi] = lightnessWindow(isHighContrast, "light");
|
|
990
991
|
const [darkLo, darkHi] = lightnessWindow(isHighContrast, "dark");
|
|
991
992
|
const t = (lightHi - clamp(lightL, lightLo, lightHi)) / (lightHi - lightLo);
|
|
@@ -1137,7 +1138,13 @@ function resolveShadowForScheme(def, ctx, isDark, isHighContrast) {
|
|
|
1137
1138
|
if (def.fg) fgVariant = getSchemeVariant(ctx.resolved.get(def.fg), isDark, isHighContrast);
|
|
1138
1139
|
const intensity = isHighContrast ? pairHC(def.intensity) : pairNormal(def.intensity);
|
|
1139
1140
|
const tuning = resolveShadowTuning(def.tuning);
|
|
1140
|
-
|
|
1141
|
+
const result = computeShadow(bgVariant, fgVariant, intensity, tuning);
|
|
1142
|
+
if (isDark && tuning.darkShadowCurve < 1 && result.alpha > 0) {
|
|
1143
|
+
const normalized = result.alpha / tuning.alphaMax;
|
|
1144
|
+
const exponent = 1 / tuning.darkShadowCurve;
|
|
1145
|
+
result.alpha = tuning.alphaMax * Math.pow(normalized, exponent);
|
|
1146
|
+
}
|
|
1147
|
+
return result;
|
|
1141
1148
|
}
|
|
1142
1149
|
function variantToLinearRgb(v) {
|
|
1143
1150
|
return okhslToLinearSrgb(v.h, v.s, v.l);
|
|
@@ -1415,10 +1422,14 @@ function createTheme(hue, saturation, initialColors) {
|
|
|
1415
1422
|
};
|
|
1416
1423
|
},
|
|
1417
1424
|
extend(options) {
|
|
1418
|
-
|
|
1419
|
-
|
|
1425
|
+
const newHue = options.hue ?? hue;
|
|
1426
|
+
const newSat = options.saturation ?? saturation;
|
|
1427
|
+
const inheritedColors = {};
|
|
1428
|
+
for (const [name, def] of Object.entries(colorDefs)) if (def.inherit !== false) inheritedColors[name] = def;
|
|
1429
|
+
return createTheme(newHue, newSat, options.colors ? {
|
|
1430
|
+
...inheritedColors,
|
|
1420
1431
|
...options.colors
|
|
1421
|
-
} : { ...
|
|
1432
|
+
} : { ...inheritedColors });
|
|
1422
1433
|
},
|
|
1423
1434
|
resolve() {
|
|
1424
1435
|
return resolveAllColors(hue, saturation, colorDefs);
|
|
@@ -1452,40 +1463,74 @@ function validatePrimaryTheme(primary, themes) {
|
|
|
1452
1463
|
throw new Error(`glaze: primary theme "${primary}" not found in palette. Available: ${available}.`);
|
|
1453
1464
|
}
|
|
1454
1465
|
}
|
|
1455
|
-
|
|
1466
|
+
/**
|
|
1467
|
+
* Resolve the effective primary for an export call.
|
|
1468
|
+
* `false` disables, a string overrides, `undefined` inherits from palette.
|
|
1469
|
+
*/
|
|
1470
|
+
function resolveEffectivePrimary(exportPrimary, palettePrimary) {
|
|
1471
|
+
if (exportPrimary === false) return void 0;
|
|
1472
|
+
return exportPrimary ?? palettePrimary;
|
|
1473
|
+
}
|
|
1474
|
+
/**
|
|
1475
|
+
* Filter a resolved color map, skipping keys already in `seen`.
|
|
1476
|
+
* Warns on collision and keeps the first-written value (first-write-wins).
|
|
1477
|
+
* Returns a new map containing only non-colliding entries.
|
|
1478
|
+
*/
|
|
1479
|
+
function filterCollisions(resolved, prefix, seen, themeName, isPrimary) {
|
|
1480
|
+
const filtered = /* @__PURE__ */ new Map();
|
|
1481
|
+
const label = isPrimary ? `${themeName} (primary)` : themeName;
|
|
1482
|
+
for (const [name, color] of resolved) {
|
|
1483
|
+
const key = `${prefix}${name}`;
|
|
1484
|
+
if (seen.has(key)) {
|
|
1485
|
+
console.warn(`glaze: token "${key}" from theme "${label}" collides with theme "${seen.get(key)}" — skipping.`);
|
|
1486
|
+
continue;
|
|
1487
|
+
}
|
|
1488
|
+
seen.set(key, label);
|
|
1489
|
+
filtered.set(name, color);
|
|
1490
|
+
}
|
|
1491
|
+
return filtered;
|
|
1492
|
+
}
|
|
1493
|
+
function createPalette(themes, paletteOptions) {
|
|
1494
|
+
validatePrimaryTheme(paletteOptions?.primary, themes);
|
|
1456
1495
|
return {
|
|
1457
1496
|
tokens(options) {
|
|
1458
|
-
|
|
1497
|
+
const effectivePrimary = resolveEffectivePrimary(options?.primary, paletteOptions?.primary);
|
|
1498
|
+
if (options?.primary !== void 0) validatePrimaryTheme(effectivePrimary, themes);
|
|
1459
1499
|
const modes = resolveModes(options?.modes);
|
|
1460
1500
|
const allTokens = {};
|
|
1501
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1461
1502
|
for (const [themeName, theme] of Object.entries(themes)) {
|
|
1462
1503
|
const resolved = theme.resolve();
|
|
1463
|
-
const
|
|
1504
|
+
const prefix = resolvePrefix(options, themeName, true);
|
|
1505
|
+
const tokens = buildFlatTokenMap(filterCollisions(resolved, prefix, seen, themeName), prefix, modes, options?.format);
|
|
1464
1506
|
for (const variant of Object.keys(tokens)) {
|
|
1465
1507
|
if (!allTokens[variant]) allTokens[variant] = {};
|
|
1466
1508
|
Object.assign(allTokens[variant], tokens[variant]);
|
|
1467
1509
|
}
|
|
1468
|
-
if (themeName ===
|
|
1469
|
-
const unprefixed = buildFlatTokenMap(resolved, "", modes, options?.format);
|
|
1510
|
+
if (themeName === effectivePrimary) {
|
|
1511
|
+
const unprefixed = buildFlatTokenMap(filterCollisions(resolved, "", seen, themeName, true), "", modes, options?.format);
|
|
1470
1512
|
for (const variant of Object.keys(unprefixed)) Object.assign(allTokens[variant], unprefixed[variant]);
|
|
1471
1513
|
}
|
|
1472
1514
|
}
|
|
1473
1515
|
return allTokens;
|
|
1474
1516
|
},
|
|
1475
1517
|
tasty(options) {
|
|
1476
|
-
|
|
1518
|
+
const effectivePrimary = resolveEffectivePrimary(options?.primary, paletteOptions?.primary);
|
|
1519
|
+
if (options?.primary !== void 0) validatePrimaryTheme(effectivePrimary, themes);
|
|
1477
1520
|
const states = {
|
|
1478
1521
|
dark: options?.states?.dark ?? globalConfig.states.dark,
|
|
1479
1522
|
highContrast: options?.states?.highContrast ?? globalConfig.states.highContrast
|
|
1480
1523
|
};
|
|
1481
1524
|
const modes = resolveModes(options?.modes);
|
|
1482
1525
|
const allTokens = {};
|
|
1526
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1483
1527
|
for (const [themeName, theme] of Object.entries(themes)) {
|
|
1484
1528
|
const resolved = theme.resolve();
|
|
1485
|
-
const
|
|
1529
|
+
const prefix = resolvePrefix(options, themeName, true);
|
|
1530
|
+
const tokens = buildTokenMap(filterCollisions(resolved, prefix, seen, themeName), prefix, states, modes, options?.format);
|
|
1486
1531
|
Object.assign(allTokens, tokens);
|
|
1487
|
-
if (themeName ===
|
|
1488
|
-
const unprefixed = buildTokenMap(resolved, "", states, modes, options?.format);
|
|
1532
|
+
if (themeName === effectivePrimary) {
|
|
1533
|
+
const unprefixed = buildTokenMap(filterCollisions(resolved, "", seen, themeName, true), "", states, modes, options?.format);
|
|
1489
1534
|
Object.assign(allTokens, unprefixed);
|
|
1490
1535
|
}
|
|
1491
1536
|
}
|
|
@@ -1498,7 +1543,8 @@ function createPalette(themes) {
|
|
|
1498
1543
|
return result;
|
|
1499
1544
|
},
|
|
1500
1545
|
css(options) {
|
|
1501
|
-
|
|
1546
|
+
const effectivePrimary = resolveEffectivePrimary(options?.primary, paletteOptions?.primary);
|
|
1547
|
+
if (options?.primary !== void 0) validatePrimaryTheme(effectivePrimary, themes);
|
|
1502
1548
|
const suffix = options?.suffix ?? "-color";
|
|
1503
1549
|
const format = options?.format ?? "rgb";
|
|
1504
1550
|
const allLines = {
|
|
@@ -1507,17 +1553,19 @@ function createPalette(themes) {
|
|
|
1507
1553
|
lightContrast: [],
|
|
1508
1554
|
darkContrast: []
|
|
1509
1555
|
};
|
|
1556
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1510
1557
|
for (const [themeName, theme] of Object.entries(themes)) {
|
|
1511
1558
|
const resolved = theme.resolve();
|
|
1512
|
-
const
|
|
1559
|
+
const prefix = resolvePrefix(options, themeName, true);
|
|
1560
|
+
const css = buildCssMap(filterCollisions(resolved, prefix, seen, themeName), prefix, suffix, format);
|
|
1513
1561
|
for (const key of [
|
|
1514
1562
|
"light",
|
|
1515
1563
|
"dark",
|
|
1516
1564
|
"lightContrast",
|
|
1517
1565
|
"darkContrast"
|
|
1518
1566
|
]) if (css[key]) allLines[key].push(css[key]);
|
|
1519
|
-
if (themeName ===
|
|
1520
|
-
const unprefixed = buildCssMap(resolved, "", suffix, format);
|
|
1567
|
+
if (themeName === effectivePrimary) {
|
|
1568
|
+
const unprefixed = buildCssMap(filterCollisions(resolved, "", seen, themeName, true), "", suffix, format);
|
|
1521
1569
|
for (const key of [
|
|
1522
1570
|
"light",
|
|
1523
1571
|
"dark",
|
|
@@ -1599,8 +1647,8 @@ glaze.configure = function configure(config) {
|
|
|
1599
1647
|
/**
|
|
1600
1648
|
* Compose multiple themes into a palette.
|
|
1601
1649
|
*/
|
|
1602
|
-
glaze.palette = function palette(themes) {
|
|
1603
|
-
return createPalette(themes);
|
|
1650
|
+
glaze.palette = function palette(themes, options) {
|
|
1651
|
+
return createPalette(themes, options);
|
|
1604
1652
|
};
|
|
1605
1653
|
/**
|
|
1606
1654
|
* Create a theme from a serialized export.
|
|
@@ -1621,13 +1669,19 @@ glaze.shadow = function shadow(input) {
|
|
|
1621
1669
|
const bg = parseOkhslInput(input.bg);
|
|
1622
1670
|
const fg = input.fg ? parseOkhslInput(input.fg) : void 0;
|
|
1623
1671
|
const tuning = resolveShadowTuning(input.tuning);
|
|
1624
|
-
|
|
1672
|
+
const result = computeShadow({
|
|
1625
1673
|
...bg,
|
|
1626
1674
|
alpha: 1
|
|
1627
1675
|
}, fg ? {
|
|
1628
1676
|
...fg,
|
|
1629
1677
|
alpha: 1
|
|
1630
1678
|
} : void 0, input.intensity, tuning);
|
|
1679
|
+
if (input.dark && tuning.darkShadowCurve < 1 && result.alpha > 0) {
|
|
1680
|
+
const normalized = result.alpha / tuning.alphaMax;
|
|
1681
|
+
const exponent = 1 / tuning.darkShadowCurve;
|
|
1682
|
+
result.alpha = tuning.alphaMax * Math.pow(normalized, exponent);
|
|
1683
|
+
}
|
|
1684
|
+
return result;
|
|
1631
1685
|
};
|
|
1632
1686
|
/**
|
|
1633
1687
|
* Format a resolved color variant as a CSS string.
|