@tenphi/glaze 1.5.0 → 2.0.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 +49 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -6
- package/dist/index.d.mts +11 -6
- package/dist/index.mjs +49 -18
- package/dist/index.mjs.map +1 -1
- package/docs/api.md +38 -9
- package/docs/migration.md +36 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -372,6 +372,7 @@ const sRGBGammaToLinear = (val) => {
|
|
|
372
372
|
};
|
|
373
373
|
/**
|
|
374
374
|
* Convert OKHSL to gamma-encoded sRGB (clamped to 0–1).
|
|
375
|
+
* h: 0–360, s: 0–1, l: 0–1. Returns [r, g, b] with each channel 0–1.
|
|
375
376
|
*/
|
|
376
377
|
function okhslToSrgb(h, s, l, pastel = false) {
|
|
377
378
|
const lin = okhslToLinearSrgb(h, s, l, pastel);
|
|
@@ -581,47 +582,72 @@ function fmt$1(value, decimals) {
|
|
|
581
582
|
return parseFloat(value.toFixed(decimals)).toString();
|
|
582
583
|
}
|
|
583
584
|
/**
|
|
585
|
+
* Every `format*` writer takes `s` / `l` / `t` on the **0–1 factor scale** —
|
|
586
|
+
* the same scale every producer in the library hands back (`resolve()`,
|
|
587
|
+
* `variantToOkhsl`, `srgbToOkhsl`, `oklabToOkhsl`, `okhslToOklab`,
|
|
588
|
+
* `okhslToSrgb`). The percentages are an output detail: the writers multiply
|
|
589
|
+
* by 100 themselves when the CSS syntax asks for a percentage.
|
|
590
|
+
*
|
|
591
|
+
* Before 2.0 the writers took 0–100 while everything producing those values
|
|
592
|
+
* returned 0–1, so the obvious composition was off by 100x and failed
|
|
593
|
+
* silently — `0.7` is a legal percentage, so the result was a valid CSS string
|
|
594
|
+
* naming a near-black color. A value above 1 can only be that old
|
|
595
|
+
* percentage-scale input, so warn about it loudly rather than emit a wrong
|
|
596
|
+
* color quietly.
|
|
597
|
+
*/
|
|
598
|
+
const scaleWarnCache = /* @__PURE__ */ new Set();
|
|
599
|
+
function warnPercentScale(fn, ...values) {
|
|
600
|
+
if (!values.some((v) => v > 1.000001)) return;
|
|
601
|
+
if (!scaleWarnCache.has(fn)) {
|
|
602
|
+
scaleWarnCache.add(fn);
|
|
603
|
+
console.warn(`glaze: ${fn}() got a value above 1 — it takes the 0-1 factors every Glaze producer returns (resolve(), variantToOkhsl, srgbToOkhsl), not 0-100 percentages. Divide by 100, or drop the "* 100" left over from the pre-2.0 signature.`);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
584
607
|
* Format OKHSL values as a CSS `okhsl(H S% L%)` string.
|
|
585
|
-
* h: 0–360, s: 0–
|
|
608
|
+
* h: 0–360, s: 0–1, l: 0–1 (factor scale, as returned by every converter).
|
|
586
609
|
*/
|
|
587
610
|
function formatOkhsl(h, s, l, pastel = false) {
|
|
611
|
+
warnPercentScale("formatOkhsl", s, l);
|
|
588
612
|
let outS = s;
|
|
589
|
-
if (pastel) outS = oklabToOkhsl(okhslToOklab(h, s
|
|
590
|
-
return `okhsl(${fmt$1(h, 2)} ${fmt$1(outS, 2)}% ${fmt$1(l, 2)}%)`;
|
|
613
|
+
if (pastel) outS = oklabToOkhsl(okhslToOklab(h, s, l, true), false)[1];
|
|
614
|
+
return `okhsl(${fmt$1(h, 2)} ${fmt$1(outS * 100, 2)}% ${fmt$1(l * 100, 2)}%)`;
|
|
591
615
|
}
|
|
592
616
|
/**
|
|
593
617
|
* Format OKHST values as a CSS `okhst(H S% T%)` string.
|
|
594
|
-
* h: 0–360, s: 0–
|
|
618
|
+
* h: 0–360, s: 0–1, t: 0–1 (factor scale, matching `ResolvedColorVariant`).
|
|
595
619
|
*
|
|
596
620
|
* Pastel recompute matches `formatOkhsl`: convert via OKLab so external
|
|
597
621
|
* parsers that only understand non-pastel OKHST render identically.
|
|
598
622
|
*/
|
|
599
623
|
function formatOkhst(h, s, t, pastel = false) {
|
|
624
|
+
warnPercentScale("formatOkhst", s, t);
|
|
600
625
|
let outS = s;
|
|
601
626
|
if (pastel) {
|
|
602
627
|
const REF_EPS = .05;
|
|
603
628
|
const den = Math.log(1 + REF_EPS) - Math.log(REF_EPS);
|
|
604
|
-
const y = Math.exp(t
|
|
605
|
-
|
|
606
|
-
outS = oklabToOkhsl(okhslToOklab(h, s / 100, l, true), false)[1] * 100;
|
|
629
|
+
const y = Math.exp(t * den + Math.log(REF_EPS)) - REF_EPS;
|
|
630
|
+
outS = oklabToOkhsl(okhslToOklab(h, s, toe(Math.cbrt(Math.max(0, y))), true), false)[1];
|
|
607
631
|
}
|
|
608
|
-
return `okhst(${fmt$1(h, 2)} ${fmt$1(outS, 2)}% ${fmt$1(t, 2)}%)`;
|
|
632
|
+
return `okhst(${fmt$1(h, 2)} ${fmt$1(outS * 100, 2)}% ${fmt$1(t * 100, 2)}%)`;
|
|
609
633
|
}
|
|
610
634
|
/**
|
|
611
635
|
* Format OKHSL values as a CSS `rgb(R G B)` string.
|
|
612
636
|
* Uses 2 decimal places to avoid 8-bit quantization contrast loss.
|
|
613
|
-
* h: 0–360, s: 0–
|
|
637
|
+
* h: 0–360, s: 0–1, l: 0–1 (factor scale, as returned by every converter).
|
|
614
638
|
*/
|
|
615
639
|
function formatRgb(h, s, l, pastel = false) {
|
|
616
|
-
|
|
640
|
+
warnPercentScale("formatRgb", s, l);
|
|
641
|
+
const [r, g, b] = okhslToSrgb(h, s, l, pastel);
|
|
617
642
|
return `rgb(${parseFloat((r * 255).toFixed(2))} ${parseFloat((g * 255).toFixed(2))} ${parseFloat((b * 255).toFixed(2))})`;
|
|
618
643
|
}
|
|
619
644
|
/**
|
|
620
645
|
* Format OKHSL values as a CSS `hsl(H S% L%)` string.
|
|
621
|
-
* h: 0–360, s: 0–
|
|
646
|
+
* h: 0–360, s: 0–1, l: 0–1 (factor scale, as returned by every converter).
|
|
622
647
|
*/
|
|
623
648
|
function formatHsl(h, s, l, pastel = false) {
|
|
624
|
-
|
|
649
|
+
warnPercentScale("formatHsl", s, l);
|
|
650
|
+
const [r, g, b] = okhslToSrgb(h, s, l, pastel);
|
|
625
651
|
const max = Math.max(r, g, b);
|
|
626
652
|
const min = Math.min(r, g, b);
|
|
627
653
|
const delta = max - min;
|
|
@@ -638,10 +664,11 @@ function formatHsl(h, s, l, pastel = false) {
|
|
|
638
664
|
}
|
|
639
665
|
/**
|
|
640
666
|
* Format OKHSL values as a CSS `oklch(L C H)` string.
|
|
641
|
-
* h: 0–360, s: 0–
|
|
667
|
+
* h: 0–360, s: 0–1, l: 0–1 (factor scale, as returned by every converter).
|
|
642
668
|
*/
|
|
643
669
|
function formatOklch(h, s, l, pastel = false) {
|
|
644
|
-
|
|
670
|
+
warnPercentScale("formatOklch", s, l);
|
|
671
|
+
const [L, C, hh] = okhslToOklch(h, s, l, pastel);
|
|
645
672
|
return `oklch(${fmt$1(L, 4)} ${fmt$1(C, 4)} ${fmt$1(hh, 2)})`;
|
|
646
673
|
}
|
|
647
674
|
/**
|
|
@@ -1119,7 +1146,11 @@ function okhslToOkhst(c) {
|
|
|
1119
1146
|
}
|
|
1120
1147
|
/**
|
|
1121
1148
|
* Edge adapter: a resolved variant stores canonical tone `t` (0–1). Convert
|
|
1122
|
-
* it to the OKHSL `{ h, s, l }` the formatters and luminance pipeline expect
|
|
1149
|
+
* it to the OKHSL `{ h, s, l }` the formatters and luminance pipeline expect —
|
|
1150
|
+
* `s` and `l` on the same 0–1 factor scale, so `const { h, s, l } =
|
|
1151
|
+
* variantToOkhsl(v)` destructures straight into `formatOkhsl` / `formatRgb` /
|
|
1152
|
+
* `okhslToLinearSrgb` with no rescaling. `alpha` stays on the variant; use
|
|
1153
|
+
* `glaze.format(v, format)` for a string that carries it.
|
|
1123
1154
|
*/
|
|
1124
1155
|
function variantToOkhsl(v) {
|
|
1125
1156
|
return {
|
|
@@ -3026,10 +3057,10 @@ function fmt(value, decimals) {
|
|
|
3026
3057
|
function formatVariant(v, format = "oklch", pastel = false) {
|
|
3027
3058
|
const effectivePastel = v.pastel ?? pastel;
|
|
3028
3059
|
let base;
|
|
3029
|
-
if (format === "okhst") base = formatOkhst(v.h, v.s
|
|
3060
|
+
if (format === "okhst") base = formatOkhst(v.h, v.s, v.t, effectivePastel);
|
|
3030
3061
|
else {
|
|
3031
3062
|
const { l } = variantToOkhsl(v);
|
|
3032
|
-
base = formatters[format](v.h, v.s
|
|
3063
|
+
base = formatters[format](v.h, v.s, l, effectivePastel);
|
|
3033
3064
|
}
|
|
3034
3065
|
if (v.alpha >= 1) return base;
|
|
3035
3066
|
const closing = base.lastIndexOf(")");
|
|
@@ -3045,7 +3076,7 @@ function formatVariantHue(v, plan, pastel = false) {
|
|
|
3045
3076
|
const [L, C] = okhslToOklch(v.h, v.s, l, effectivePastel);
|
|
3046
3077
|
let base;
|
|
3047
3078
|
if (plan.inline) if (v.s <= 1e-6) base = `oklch(${fmt(L, 4)} 0 0)`;
|
|
3048
|
-
else base = formatOklch(v.h, v.s
|
|
3079
|
+
else base = formatOklch(v.h, v.s, l, effectivePastel);
|
|
3049
3080
|
else base = `oklch(${fmt(L, 4)} ${fmt(C, 4)} ${plan.hueVar})`;
|
|
3050
3081
|
if (v.alpha >= 1) return base;
|
|
3051
3082
|
const closing = base.lastIndexOf(")");
|