@tenphi/glaze 0.3.0 → 0.5.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 +281 -44
- package/dist/index.cjs +202 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +129 -11
- package/dist/index.d.mts +129 -11
- package/dist/index.mjs +202 -61
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -441,23 +441,26 @@ function parseHex(hex) {
|
|
|
441
441
|
}
|
|
442
442
|
return null;
|
|
443
443
|
}
|
|
444
|
+
function fmt$1(value, decimals) {
|
|
445
|
+
return parseFloat(value.toFixed(decimals)).toString();
|
|
446
|
+
}
|
|
444
447
|
/**
|
|
445
448
|
* Format OKHSL values as a CSS `okhsl(H S% L%)` string.
|
|
446
449
|
* h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
|
|
447
450
|
*/
|
|
448
451
|
function formatOkhsl(h, s, l) {
|
|
449
|
-
return `okhsl(${h
|
|
452
|
+
return `okhsl(${fmt$1(h, 1)} ${fmt$1(s, 1)}% ${fmt$1(l, 1)}%)`;
|
|
450
453
|
}
|
|
451
454
|
/**
|
|
452
|
-
* Format OKHSL values as a CSS `rgb(R
|
|
455
|
+
* Format OKHSL values as a CSS `rgb(R G B)` string with rounded integer values.
|
|
453
456
|
* h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
|
|
454
457
|
*/
|
|
455
458
|
function formatRgb(h, s, l) {
|
|
456
459
|
const [r, g, b] = okhslToSrgb(h, s / 100, l / 100);
|
|
457
|
-
return `rgb(${(r * 255)
|
|
460
|
+
return `rgb(${Math.round(r * 255)} ${Math.round(g * 255)} ${Math.round(b * 255)})`;
|
|
458
461
|
}
|
|
459
462
|
/**
|
|
460
|
-
* Format OKHSL values as a CSS `hsl(H
|
|
463
|
+
* Format OKHSL values as a CSS `hsl(H S% L%)` string.
|
|
461
464
|
* h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
|
|
462
465
|
*/
|
|
463
466
|
function formatHsl(h, s, l) {
|
|
@@ -474,10 +477,10 @@ function formatHsl(h, s, l) {
|
|
|
474
477
|
else if (max === g) hh = ((b - r) / delta + 2) * 60;
|
|
475
478
|
else hh = ((r - g) / delta + 4) * 60;
|
|
476
479
|
}
|
|
477
|
-
return `hsl(${hh
|
|
480
|
+
return `hsl(${fmt$1(hh, 1)} ${fmt$1(ss * 100, 1)}% ${fmt$1(ll * 100, 1)}%)`;
|
|
478
481
|
}
|
|
479
482
|
/**
|
|
480
|
-
* Format OKHSL values as a CSS `oklch(L
|
|
483
|
+
* Format OKHSL values as a CSS `oklch(L C H)` string.
|
|
481
484
|
* h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
|
|
482
485
|
*/
|
|
483
486
|
function formatOklch(h, s, l) {
|
|
@@ -485,7 +488,7 @@ function formatOklch(h, s, l) {
|
|
|
485
488
|
const C = Math.sqrt(a * a + b * b);
|
|
486
489
|
let hh = Math.atan2(b, a) * (180 / Math.PI);
|
|
487
490
|
hh = constrainAngle(hh);
|
|
488
|
-
return `oklch(${(L
|
|
491
|
+
return `oklch(${fmt$1(L, 4)} ${fmt$1(C, 4)} ${fmt$1(hh, 1)})`;
|
|
489
492
|
}
|
|
490
493
|
|
|
491
494
|
//#endregion
|
|
@@ -711,14 +714,70 @@ function pairNormal(p) {
|
|
|
711
714
|
function pairHC(p) {
|
|
712
715
|
return Array.isArray(p) ? p[1] : p;
|
|
713
716
|
}
|
|
717
|
+
function isShadowDef(def) {
|
|
718
|
+
return def.type === "shadow";
|
|
719
|
+
}
|
|
720
|
+
const DEFAULT_SHADOW_TUNING = {
|
|
721
|
+
saturationFactor: .18,
|
|
722
|
+
maxSaturation: .25,
|
|
723
|
+
lightnessFactor: .25,
|
|
724
|
+
lightnessBounds: [.05, .2],
|
|
725
|
+
minGapTarget: .05,
|
|
726
|
+
alphaMax: .6,
|
|
727
|
+
bgHueBlend: .2
|
|
728
|
+
};
|
|
729
|
+
function resolveShadowTuning(perColor) {
|
|
730
|
+
return {
|
|
731
|
+
...DEFAULT_SHADOW_TUNING,
|
|
732
|
+
...globalConfig.shadowTuning,
|
|
733
|
+
...perColor,
|
|
734
|
+
lightnessBounds: perColor?.lightnessBounds ?? globalConfig.shadowTuning?.lightnessBounds ?? DEFAULT_SHADOW_TUNING.lightnessBounds
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
function circularLerp(a, b, t) {
|
|
738
|
+
let diff = b - a;
|
|
739
|
+
if (diff > 180) diff -= 360;
|
|
740
|
+
else if (diff < -180) diff += 360;
|
|
741
|
+
return ((a + diff * t) % 360 + 360) % 360;
|
|
742
|
+
}
|
|
743
|
+
function computeShadow(bg, fg, intensity, tuning) {
|
|
744
|
+
const EPSILON = 1e-6;
|
|
745
|
+
const clampedIntensity = clamp(intensity, 0, 100);
|
|
746
|
+
const contrastWeight = fg ? Math.abs(bg.l - fg.l) : 1;
|
|
747
|
+
const deltaL = clampedIntensity / 100 * contrastWeight;
|
|
748
|
+
const h = fg ? circularLerp(fg.h, bg.h, tuning.bgHueBlend) : bg.h;
|
|
749
|
+
const s = fg ? Math.min(fg.s * tuning.saturationFactor, tuning.maxSaturation) : 0;
|
|
750
|
+
let lSh = clamp(bg.l * tuning.lightnessFactor, tuning.lightnessBounds[0], tuning.lightnessBounds[1]);
|
|
751
|
+
lSh = Math.max(Math.min(lSh, bg.l - tuning.minGapTarget), 0);
|
|
752
|
+
const t = deltaL / Math.max(bg.l - lSh, EPSILON);
|
|
753
|
+
const alpha = tuning.alphaMax * Math.tanh(t / tuning.alphaMax);
|
|
754
|
+
return {
|
|
755
|
+
h,
|
|
756
|
+
s,
|
|
757
|
+
l: lSh,
|
|
758
|
+
alpha
|
|
759
|
+
};
|
|
760
|
+
}
|
|
714
761
|
function validateColorDefs(defs) {
|
|
715
762
|
const names = new Set(Object.keys(defs));
|
|
716
763
|
for (const [name, def] of Object.entries(defs)) {
|
|
717
|
-
if (def
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
764
|
+
if (isShadowDef(def)) {
|
|
765
|
+
if (!names.has(def.bg)) throw new Error(`glaze: shadow "${name}" references non-existent bg "${def.bg}".`);
|
|
766
|
+
if (isShadowDef(defs[def.bg])) throw new Error(`glaze: shadow "${name}" bg "${def.bg}" references another shadow color.`);
|
|
767
|
+
if (def.fg !== void 0) {
|
|
768
|
+
if (!names.has(def.fg)) throw new Error(`glaze: shadow "${name}" references non-existent fg "${def.fg}".`);
|
|
769
|
+
if (isShadowDef(defs[def.fg])) throw new Error(`glaze: shadow "${name}" fg "${def.fg}" references another shadow color.`);
|
|
770
|
+
}
|
|
771
|
+
continue;
|
|
772
|
+
}
|
|
773
|
+
const regDef = def;
|
|
774
|
+
if (regDef.contrast !== void 0 && !regDef.base) throw new Error(`glaze: color "${name}" has "contrast" without "base".`);
|
|
775
|
+
if (regDef.lightness !== void 0 && !isAbsoluteLightness(regDef.lightness) && !regDef.base) throw new Error(`glaze: color "${name}" has relative "lightness" without "base".`);
|
|
776
|
+
if (isAbsoluteLightness(regDef.lightness) && regDef.base !== void 0) console.warn(`glaze: color "${name}" has absolute "lightness" and "base". Absolute lightness takes precedence.`);
|
|
777
|
+
if (regDef.base && !names.has(regDef.base)) throw new Error(`glaze: color "${name}" references non-existent base "${regDef.base}".`);
|
|
778
|
+
if (regDef.base && isShadowDef(defs[regDef.base])) throw new Error(`glaze: color "${name}" base "${regDef.base}" references a shadow color.`);
|
|
779
|
+
if (!isAbsoluteLightness(regDef.lightness) && regDef.base === void 0) throw new Error(`glaze: color "${name}" must have either absolute "lightness" (root) or "base" (dependent).`);
|
|
780
|
+
if (regDef.contrast !== void 0 && regDef.opacity !== void 0) console.warn(`glaze: color "${name}" has both "contrast" and "opacity". Opacity makes perceived lightness unpredictable.`);
|
|
722
781
|
}
|
|
723
782
|
const visited = /* @__PURE__ */ new Set();
|
|
724
783
|
const inStack = /* @__PURE__ */ new Set();
|
|
@@ -727,7 +786,13 @@ function validateColorDefs(defs) {
|
|
|
727
786
|
if (visited.has(name)) return;
|
|
728
787
|
inStack.add(name);
|
|
729
788
|
const def = defs[name];
|
|
730
|
-
if (
|
|
789
|
+
if (isShadowDef(def)) {
|
|
790
|
+
dfs(def.bg);
|
|
791
|
+
if (def.fg) dfs(def.fg);
|
|
792
|
+
} else {
|
|
793
|
+
const regDef = def;
|
|
794
|
+
if (regDef.base && !isAbsoluteLightness(regDef.lightness)) dfs(regDef.base);
|
|
795
|
+
}
|
|
731
796
|
inStack.delete(name);
|
|
732
797
|
visited.add(name);
|
|
733
798
|
}
|
|
@@ -740,7 +805,13 @@ function topoSort(defs) {
|
|
|
740
805
|
if (visited.has(name)) return;
|
|
741
806
|
visited.add(name);
|
|
742
807
|
const def = defs[name];
|
|
743
|
-
if (
|
|
808
|
+
if (isShadowDef(def)) {
|
|
809
|
+
visit(def.bg);
|
|
810
|
+
if (def.fg) visit(def.fg);
|
|
811
|
+
} else {
|
|
812
|
+
const regDef = def;
|
|
813
|
+
if (regDef.base && !isAbsoluteLightness(regDef.lightness)) visit(regDef.base);
|
|
814
|
+
}
|
|
744
815
|
result.push(name);
|
|
745
816
|
}
|
|
746
817
|
for (const name of Object.keys(defs)) visit(name);
|
|
@@ -804,11 +875,8 @@ function resolveDependentColor(name, def, ctx, isHighContrast, isDark, effective
|
|
|
804
875
|
if (!baseResolved) throw new Error(`glaze: base "${baseName}" not yet resolved for "${name}".`);
|
|
805
876
|
const mode = def.mode ?? "auto";
|
|
806
877
|
const satFactor = clamp(def.saturation ?? 1, 0, 1);
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
else if (isDark) baseL = baseResolved.dark.l * 100;
|
|
810
|
-
else if (isHighContrast) baseL = baseResolved.lightContrast.l * 100;
|
|
811
|
-
else baseL = baseResolved.light.l * 100;
|
|
878
|
+
const baseVariant = getSchemeVariant(baseResolved, isDark, isHighContrast);
|
|
879
|
+
const baseL = baseVariant.l * 100;
|
|
812
880
|
let preferredL;
|
|
813
881
|
const rawLightness = def.lightness;
|
|
814
882
|
if (rawLightness === void 0) preferredL = baseL;
|
|
@@ -825,27 +893,7 @@ function resolveDependentColor(name, def, ctx, isHighContrast, isDark, effective
|
|
|
825
893
|
if (rawContrast !== void 0) {
|
|
826
894
|
const minCr = isHighContrast ? pairHC(rawContrast) : pairNormal(rawContrast);
|
|
827
895
|
const effectiveSat = isDark ? mapSaturationDark(satFactor * ctx.saturation / 100, mode) : satFactor * ctx.saturation / 100;
|
|
828
|
-
|
|
829
|
-
let baseS;
|
|
830
|
-
let baseLNorm;
|
|
831
|
-
if (isDark && isHighContrast) {
|
|
832
|
-
baseH = baseResolved.darkContrast.h;
|
|
833
|
-
baseS = baseResolved.darkContrast.s;
|
|
834
|
-
baseLNorm = baseResolved.darkContrast.l;
|
|
835
|
-
} else if (isDark) {
|
|
836
|
-
baseH = baseResolved.dark.h;
|
|
837
|
-
baseS = baseResolved.dark.s;
|
|
838
|
-
baseLNorm = baseResolved.dark.l;
|
|
839
|
-
} else if (isHighContrast) {
|
|
840
|
-
baseH = baseResolved.lightContrast.h;
|
|
841
|
-
baseS = baseResolved.lightContrast.s;
|
|
842
|
-
baseLNorm = baseResolved.lightContrast.l;
|
|
843
|
-
} else {
|
|
844
|
-
baseH = baseResolved.light.h;
|
|
845
|
-
baseS = baseResolved.light.s;
|
|
846
|
-
baseLNorm = baseResolved.light.l;
|
|
847
|
-
}
|
|
848
|
-
const baseLinearRgb = okhslToLinearSrgb(baseH, baseS, baseLNorm);
|
|
896
|
+
const baseLinearRgb = okhslToLinearSrgb(baseVariant.h, baseVariant.s, baseVariant.l);
|
|
849
897
|
return {
|
|
850
898
|
l: findLightnessForContrast({
|
|
851
899
|
hue: effectiveHue,
|
|
@@ -862,18 +910,26 @@ function resolveDependentColor(name, def, ctx, isHighContrast, isDark, effective
|
|
|
862
910
|
satFactor
|
|
863
911
|
};
|
|
864
912
|
}
|
|
913
|
+
function getSchemeVariant(color, isDark, isHighContrast) {
|
|
914
|
+
if (isDark && isHighContrast) return color.darkContrast;
|
|
915
|
+
if (isDark) return color.dark;
|
|
916
|
+
if (isHighContrast) return color.lightContrast;
|
|
917
|
+
return color.light;
|
|
918
|
+
}
|
|
865
919
|
function resolveColorForScheme(name, def, ctx, isDark, isHighContrast) {
|
|
866
|
-
|
|
867
|
-
const
|
|
868
|
-
const
|
|
920
|
+
if (isShadowDef(def)) return resolveShadowForScheme(def, ctx, isDark, isHighContrast);
|
|
921
|
+
const regDef = def;
|
|
922
|
+
const mode = regDef.mode ?? "auto";
|
|
923
|
+
const isRoot = isAbsoluteLightness(regDef.lightness) && !regDef.base;
|
|
924
|
+
const effectiveHue = resolveEffectiveHue(ctx.hue, regDef.hue);
|
|
869
925
|
let lightL;
|
|
870
926
|
let satFactor;
|
|
871
927
|
if (isRoot) {
|
|
872
|
-
const root = resolveRootColor(name,
|
|
928
|
+
const root = resolveRootColor(name, regDef, ctx, isHighContrast);
|
|
873
929
|
lightL = root.lightL;
|
|
874
930
|
satFactor = root.satFactor;
|
|
875
931
|
} else {
|
|
876
|
-
const dep = resolveDependentColor(name,
|
|
932
|
+
const dep = resolveDependentColor(name, regDef, ctx, isHighContrast, isDark, effectiveHue);
|
|
877
933
|
lightL = dep.l;
|
|
878
934
|
satFactor = dep.satFactor;
|
|
879
935
|
}
|
|
@@ -892,9 +948,18 @@ function resolveColorForScheme(name, def, ctx, isDark, isHighContrast) {
|
|
|
892
948
|
return {
|
|
893
949
|
h: effectiveHue,
|
|
894
950
|
s: clamp(finalSat, 0, 1),
|
|
895
|
-
l: clamp(finalL / 100, 0, 1)
|
|
951
|
+
l: clamp(finalL / 100, 0, 1),
|
|
952
|
+
alpha: regDef.opacity ?? 1
|
|
896
953
|
};
|
|
897
954
|
}
|
|
955
|
+
function resolveShadowForScheme(def, ctx, isDark, isHighContrast) {
|
|
956
|
+
const bgVariant = getSchemeVariant(ctx.resolved.get(def.bg), isDark, isHighContrast);
|
|
957
|
+
let fgVariant;
|
|
958
|
+
if (def.fg) fgVariant = getSchemeVariant(ctx.resolved.get(def.fg), isDark, isHighContrast);
|
|
959
|
+
const intensity = isHighContrast ? pairHC(def.intensity) : pairNormal(def.intensity);
|
|
960
|
+
const tuning = resolveShadowTuning(def.tuning);
|
|
961
|
+
return computeShadow(bgVariant, fgVariant, intensity, tuning);
|
|
962
|
+
}
|
|
898
963
|
function resolveAllColors(hue, saturation, defs) {
|
|
899
964
|
validateColorDefs(defs);
|
|
900
965
|
const order = topoSort(defs);
|
|
@@ -904,6 +969,9 @@ function resolveAllColors(hue, saturation, defs) {
|
|
|
904
969
|
defs,
|
|
905
970
|
resolved: /* @__PURE__ */ new Map()
|
|
906
971
|
};
|
|
972
|
+
function defMode(def) {
|
|
973
|
+
return isShadowDef(def) ? void 0 : def.mode ?? "auto";
|
|
974
|
+
}
|
|
907
975
|
const lightMap = /* @__PURE__ */ new Map();
|
|
908
976
|
for (const name of order) {
|
|
909
977
|
const variant = resolveColorForScheme(name, defs[name], ctx, false, false);
|
|
@@ -914,7 +982,7 @@ function resolveAllColors(hue, saturation, defs) {
|
|
|
914
982
|
dark: variant,
|
|
915
983
|
lightContrast: variant,
|
|
916
984
|
darkContrast: variant,
|
|
917
|
-
mode: defs[name]
|
|
985
|
+
mode: defMode(defs[name])
|
|
918
986
|
});
|
|
919
987
|
}
|
|
920
988
|
const lightHCMap = /* @__PURE__ */ new Map();
|
|
@@ -937,7 +1005,7 @@ function resolveAllColors(hue, saturation, defs) {
|
|
|
937
1005
|
dark: lightMap.get(name),
|
|
938
1006
|
lightContrast: lightHCMap.get(name),
|
|
939
1007
|
darkContrast: lightHCMap.get(name),
|
|
940
|
-
mode: defs[name]
|
|
1008
|
+
mode: defMode(defs[name])
|
|
941
1009
|
});
|
|
942
1010
|
for (const name of order) {
|
|
943
1011
|
const variant = resolveColorForScheme(name, defs[name], ctx, true, false);
|
|
@@ -967,7 +1035,7 @@ function resolveAllColors(hue, saturation, defs) {
|
|
|
967
1035
|
dark: darkMap.get(name),
|
|
968
1036
|
lightContrast: lightHCMap.get(name),
|
|
969
1037
|
darkContrast: darkHCMap.get(name),
|
|
970
|
-
mode: defs[name]
|
|
1038
|
+
mode: defMode(defs[name])
|
|
971
1039
|
});
|
|
972
1040
|
return result;
|
|
973
1041
|
}
|
|
@@ -977,8 +1045,14 @@ const formatters = {
|
|
|
977
1045
|
hsl: formatHsl,
|
|
978
1046
|
oklch: formatOklch
|
|
979
1047
|
};
|
|
1048
|
+
function fmt(value, decimals) {
|
|
1049
|
+
return parseFloat(value.toFixed(decimals)).toString();
|
|
1050
|
+
}
|
|
980
1051
|
function formatVariant(v, format = "okhsl") {
|
|
981
|
-
|
|
1052
|
+
const base = formatters[format](v.h, v.s * 100, v.l * 100);
|
|
1053
|
+
if (v.alpha >= 1) return base;
|
|
1054
|
+
const closing = base.lastIndexOf(")");
|
|
1055
|
+
return `${base.slice(0, closing)} / ${fmt(v.alpha, 4)})`;
|
|
982
1056
|
}
|
|
983
1057
|
function resolveModes(override) {
|
|
984
1058
|
return {
|
|
@@ -998,6 +1072,20 @@ function buildTokenMap(resolved, prefix, states, modes, format = "okhsl") {
|
|
|
998
1072
|
}
|
|
999
1073
|
return tokens;
|
|
1000
1074
|
}
|
|
1075
|
+
function buildFlatTokenMap(resolved, prefix, modes, format = "okhsl") {
|
|
1076
|
+
const result = { light: {} };
|
|
1077
|
+
if (modes.dark) result.dark = {};
|
|
1078
|
+
if (modes.highContrast) result.lightContrast = {};
|
|
1079
|
+
if (modes.dark && modes.highContrast) result.darkContrast = {};
|
|
1080
|
+
for (const [name, color] of resolved) {
|
|
1081
|
+
const key = `${prefix}${name}`;
|
|
1082
|
+
result.light[key] = formatVariant(color.light, format);
|
|
1083
|
+
if (modes.dark) result.dark[key] = formatVariant(color.dark, format);
|
|
1084
|
+
if (modes.highContrast) result.lightContrast[key] = formatVariant(color.lightContrast, format);
|
|
1085
|
+
if (modes.dark && modes.highContrast) result.darkContrast[key] = formatVariant(color.darkContrast, format);
|
|
1086
|
+
}
|
|
1087
|
+
return result;
|
|
1088
|
+
}
|
|
1001
1089
|
function buildJsonMap(resolved, modes, format = "okhsl") {
|
|
1002
1090
|
const result = {};
|
|
1003
1091
|
for (const [name, color] of resolved) {
|
|
@@ -1079,6 +1167,9 @@ function createTheme(hue, saturation, initialColors) {
|
|
|
1079
1167
|
return resolveAllColors(hue, saturation, colorDefs);
|
|
1080
1168
|
},
|
|
1081
1169
|
tokens(options) {
|
|
1170
|
+
return buildFlatTokenMap(resolveAllColors(hue, saturation, colorDefs), "", resolveModes(options?.modes), options?.format);
|
|
1171
|
+
},
|
|
1172
|
+
tasty(options) {
|
|
1082
1173
|
return buildTokenMap(resolveAllColors(hue, saturation, colorDefs), "", {
|
|
1083
1174
|
dark: options?.states?.dark ?? globalConfig.states.dark,
|
|
1084
1175
|
highContrast: options?.states?.highContrast ?? globalConfig.states.highContrast
|
|
@@ -1092,9 +1183,26 @@ function createTheme(hue, saturation, initialColors) {
|
|
|
1092
1183
|
}
|
|
1093
1184
|
};
|
|
1094
1185
|
}
|
|
1186
|
+
function resolvePrefix(options, themeName) {
|
|
1187
|
+
if (options?.prefix === true) return `${themeName}-`;
|
|
1188
|
+
if (typeof options?.prefix === "object" && options.prefix !== null) return options.prefix[themeName] ?? `${themeName}-`;
|
|
1189
|
+
return "";
|
|
1190
|
+
}
|
|
1095
1191
|
function createPalette(themes) {
|
|
1096
1192
|
return {
|
|
1097
1193
|
tokens(options) {
|
|
1194
|
+
const modes = resolveModes(options?.modes);
|
|
1195
|
+
const allTokens = {};
|
|
1196
|
+
for (const [themeName, theme] of Object.entries(themes)) {
|
|
1197
|
+
const tokens = buildFlatTokenMap(theme.resolve(), resolvePrefix(options, themeName), modes, options?.format);
|
|
1198
|
+
for (const variant of Object.keys(tokens)) {
|
|
1199
|
+
if (!allTokens[variant]) allTokens[variant] = {};
|
|
1200
|
+
Object.assign(allTokens[variant], tokens[variant]);
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
return allTokens;
|
|
1204
|
+
},
|
|
1205
|
+
tasty(options) {
|
|
1098
1206
|
const states = {
|
|
1099
1207
|
dark: options?.states?.dark ?? globalConfig.states.dark,
|
|
1100
1208
|
highContrast: options?.states?.highContrast ?? globalConfig.states.highContrast
|
|
@@ -1102,11 +1210,7 @@ function createPalette(themes) {
|
|
|
1102
1210
|
const modes = resolveModes(options?.modes);
|
|
1103
1211
|
const allTokens = {};
|
|
1104
1212
|
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);
|
|
1213
|
+
const tokens = buildTokenMap(theme.resolve(), resolvePrefix(options, themeName), states, modes, options?.format);
|
|
1110
1214
|
Object.assign(allTokens, tokens);
|
|
1111
1215
|
}
|
|
1112
1216
|
return allTokens;
|
|
@@ -1127,11 +1231,7 @@ function createPalette(themes) {
|
|
|
1127
1231
|
darkContrast: []
|
|
1128
1232
|
};
|
|
1129
1233
|
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);
|
|
1234
|
+
const css = buildCssMap(theme.resolve(), resolvePrefix(options, themeName), suffix, format);
|
|
1135
1235
|
for (const key of [
|
|
1136
1236
|
"light",
|
|
1137
1237
|
"dark",
|
|
@@ -1164,6 +1264,12 @@ function createColorToken(input) {
|
|
|
1164
1264
|
highContrast: options?.states?.highContrast ?? globalConfig.states.highContrast
|
|
1165
1265
|
}, resolveModes(options?.modes), options?.format)["#__color__"];
|
|
1166
1266
|
},
|
|
1267
|
+
tasty(options) {
|
|
1268
|
+
return buildTokenMap(resolveAllColors(input.hue, input.saturation, defs), "", {
|
|
1269
|
+
dark: options?.states?.dark ?? globalConfig.states.dark,
|
|
1270
|
+
highContrast: options?.states?.highContrast ?? globalConfig.states.highContrast
|
|
1271
|
+
}, resolveModes(options?.modes), options?.format)["#__color__"];
|
|
1272
|
+
},
|
|
1167
1273
|
json(options) {
|
|
1168
1274
|
return buildJsonMap(resolveAllColors(input.hue, input.saturation, defs), resolveModes(options?.modes), options?.format)["__color__"];
|
|
1169
1275
|
}
|
|
@@ -1197,7 +1303,8 @@ glaze.configure = function configure(config) {
|
|
|
1197
1303
|
modes: {
|
|
1198
1304
|
dark: config.modes?.dark ?? globalConfig.modes.dark,
|
|
1199
1305
|
highContrast: config.modes?.highContrast ?? globalConfig.modes.highContrast
|
|
1200
|
-
}
|
|
1306
|
+
},
|
|
1307
|
+
shadowTuning: config.shadowTuning ?? globalConfig.shadowTuning
|
|
1201
1308
|
};
|
|
1202
1309
|
};
|
|
1203
1310
|
/**
|
|
@@ -1219,6 +1326,40 @@ glaze.color = function color(input) {
|
|
|
1219
1326
|
return createColorToken(input);
|
|
1220
1327
|
};
|
|
1221
1328
|
/**
|
|
1329
|
+
* Compute a shadow color from a bg/fg pair and intensity.
|
|
1330
|
+
*/
|
|
1331
|
+
glaze.shadow = function shadow(input) {
|
|
1332
|
+
const bg = parseOkhslInput(input.bg);
|
|
1333
|
+
const fg = input.fg ? parseOkhslInput(input.fg) : void 0;
|
|
1334
|
+
const tuning = resolveShadowTuning(input.tuning);
|
|
1335
|
+
return computeShadow({
|
|
1336
|
+
...bg,
|
|
1337
|
+
alpha: 1
|
|
1338
|
+
}, fg ? {
|
|
1339
|
+
...fg,
|
|
1340
|
+
alpha: 1
|
|
1341
|
+
} : void 0, input.intensity, tuning);
|
|
1342
|
+
};
|
|
1343
|
+
/**
|
|
1344
|
+
* Format a resolved color variant as a CSS string.
|
|
1345
|
+
*/
|
|
1346
|
+
glaze.format = function format(variant, colorFormat) {
|
|
1347
|
+
return formatVariant(variant, colorFormat);
|
|
1348
|
+
};
|
|
1349
|
+
function parseOkhslInput(input) {
|
|
1350
|
+
if (typeof input === "string") {
|
|
1351
|
+
const rgb = parseHex(input);
|
|
1352
|
+
if (!rgb) throw new Error(`glaze: invalid hex color "${input}".`);
|
|
1353
|
+
const [h, s, l] = srgbToOkhsl(rgb);
|
|
1354
|
+
return {
|
|
1355
|
+
h,
|
|
1356
|
+
s,
|
|
1357
|
+
l
|
|
1358
|
+
};
|
|
1359
|
+
}
|
|
1360
|
+
return input;
|
|
1361
|
+
}
|
|
1362
|
+
/**
|
|
1222
1363
|
* Create a theme from a hex color string.
|
|
1223
1364
|
* Extracts hue and saturation from the color.
|
|
1224
1365
|
*/
|