color-map 2.2.0 → 2.3.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/.claude-plugin/plugin.json +12 -0
- package/.codex-plugin/plugin.json +12 -0
- package/.cursor-plugin/plugin.json +12 -0
- package/CHANGELOG.md +100 -0
- package/README.md +71 -8
- package/bin/cli-CELmx3Y9.js +6414 -0
- package/bin/color-map.js +9 -0
- package/bin/index.js +1 -0
- package/cjs/color/index.d.ts +5 -0
- package/cjs/color/index.js +52 -0
- package/cjs/color-wNrkrhC7.js +374 -0
- package/cjs/color-wNrkrhC7.js.map +1 -0
- package/cjs/contrast-XjF5Rwui.js +293 -0
- package/cjs/contrast-XjF5Rwui.js.map +1 -0
- package/cjs/gamut-CG1J2aat.d.ts +158 -0
- package/cjs/gamut-CG1J2aat.d.ts.map +1 -0
- package/cjs/index-BcEqCPHz.d.ts +137 -0
- package/cjs/index-BcEqCPHz.d.ts.map +1 -0
- package/cjs/index-CGKCqRqD.d.ts +111 -0
- package/cjs/index-CGKCqRqD.d.ts.map +1 -0
- package/cjs/index-Cv3iUUYE.d.ts +171 -0
- package/cjs/index-Cv3iUUYE.d.ts.map +1 -0
- package/cjs/index-Dw43Hj4v.d.ts +41 -0
- package/cjs/index-Dw43Hj4v.d.ts.map +1 -0
- package/cjs/index-Dy8UARqO.d.ts +72 -0
- package/cjs/index-Dy8UARqO.d.ts.map +1 -0
- package/cjs/index.d.ts +26 -36
- package/cjs/index.d.ts.map +1 -1
- package/cjs/index.js +83 -62
- package/cjs/index.js.map +1 -1
- package/cjs/legacy/index.d.ts +2 -0
- package/cjs/legacy/index.js +75 -0
- package/cjs/legacy/index.js.map +1 -0
- package/cjs/mix-Cs4owSbW.js +158 -0
- package/cjs/mix-Cs4owSbW.js.map +1 -0
- package/cjs/mix-DGlKoUw4.d.ts +31 -0
- package/cjs/mix-DGlKoUw4.d.ts.map +1 -0
- package/cjs/palette/index.d.ts +3 -0
- package/cjs/palette/index.js +8 -0
- package/cjs/palette-DyFV_KoJ.js +332 -0
- package/cjs/palette-DyFV_KoJ.js.map +1 -0
- package/cjs/parse-8mt2OMKf.js +1508 -0
- package/cjs/parse-8mt2OMKf.js.map +1 -0
- package/cjs/scale/index.d.ts +2 -0
- package/cjs/scale/index.js +11 -0
- package/cjs/scale-Cq9pXrc1.js +318 -0
- package/cjs/scale-Cq9pXrc1.js.map +1 -0
- package/cjs/semantic-CrEIo8tS.d.ts +52 -0
- package/cjs/semantic-CrEIo8tS.d.ts.map +1 -0
- package/cjs/serialize-C69DAmoE.d.ts +25 -0
- package/cjs/serialize-C69DAmoE.d.ts.map +1 -0
- package/cjs/serialize-Ci2X0cPN.js +103 -0
- package/cjs/serialize-Ci2X0cPN.js.map +1 -0
- package/cjs/tokens/index.d.ts +2 -0
- package/cjs/tokens/index.js +6 -0
- package/cjs/tokens-CzXxaMgM.js +168 -0
- package/cjs/tokens-CzXxaMgM.js.map +1 -0
- package/cjs/tone-BAhu-QzQ.js +118 -0
- package/cjs/tone-BAhu-QzQ.js.map +1 -0
- package/dist/color-map.es5.js.map +1 -1
- package/esm/color/a98-rgb.d.ts +7 -0
- package/esm/color/a98-rgb.d.ts.map +1 -0
- package/esm/color/a98-rgb.js +13 -0
- package/esm/color/a98-rgb.js.map +1 -0
- package/esm/color/argb.d.ts +6 -0
- package/esm/color/argb.d.ts.map +1 -0
- package/esm/color/argb.js +25 -0
- package/esm/color/argb.js.map +1 -0
- package/esm/color/calc.js +82 -0
- package/esm/color/calc.js.map +1 -0
- package/esm/color/compare.d.ts +20 -0
- package/esm/color/compare.d.ts.map +1 -0
- package/esm/color/compare.js +46 -0
- package/esm/color/compare.js.map +1 -0
- package/esm/color/contrast.d.ts +107 -0
- package/esm/color/contrast.d.ts.map +1 -0
- package/esm/color/contrast.js +242 -0
- package/esm/color/contrast.js.map +1 -0
- package/esm/color/convert.d.ts +9 -0
- package/esm/color/convert.d.ts.map +1 -0
- package/esm/color/convert.js +45 -0
- package/esm/color/convert.js.map +1 -0
- package/esm/color/display-p3-linear.d.ts +7 -0
- package/esm/color/display-p3-linear.d.ts.map +1 -0
- package/esm/color/display-p3-linear.js +12 -0
- package/esm/color/display-p3-linear.js.map +1 -0
- package/esm/color/display-p3.d.ts +7 -0
- package/esm/color/display-p3.d.ts.map +1 -0
- package/esm/color/display-p3.js +12 -0
- package/esm/color/display-p3.js.map +1 -0
- package/esm/color/expr.d.ts +43 -0
- package/esm/color/expr.d.ts.map +1 -0
- package/esm/color/expr.js +160 -0
- package/esm/color/expr.js.map +1 -0
- package/esm/color/gamut.d.ts +31 -0
- package/esm/color/gamut.d.ts.map +1 -0
- package/esm/color/gamut.js +210 -0
- package/esm/color/gamut.js.map +1 -0
- package/esm/color/hsl.d.ts +7 -0
- package/esm/color/hsl.d.ts.map +1 -0
- package/esm/color/hsl.js +67 -0
- package/esm/color/hsl.js.map +1 -0
- package/esm/color/hwb.d.ts +7 -0
- package/esm/color/hwb.d.ts.map +1 -0
- package/esm/color/hwb.js +40 -0
- package/esm/color/hwb.js.map +1 -0
- package/esm/color/index.d.ts +28 -0
- package/esm/color/index.js +27 -0
- package/esm/color/lab.d.ts +7 -0
- package/esm/color/lab.d.ts.map +1 -0
- package/esm/color/lab.js +33 -0
- package/esm/color/lab.js.map +1 -0
- package/esm/color/lch.d.ts +7 -0
- package/esm/color/lch.d.ts.map +1 -0
- package/esm/color/lch.js +11 -0
- package/esm/color/lch.js.map +1 -0
- package/esm/color/math.js +32 -0
- package/esm/color/math.js.map +1 -0
- package/esm/color/matrices.js +180 -0
- package/esm/color/matrices.js.map +1 -0
- package/esm/color/mix.d.ts +30 -0
- package/esm/color/mix.d.ts.map +1 -0
- package/esm/color/mix.js +152 -0
- package/esm/color/mix.js.map +1 -0
- package/esm/color/named.js +11 -0
- package/esm/color/named.js.map +1 -0
- package/esm/color/oklab.d.ts +7 -0
- package/esm/color/oklab.d.ts.map +1 -0
- package/esm/color/oklab.js +21 -0
- package/esm/color/oklab.js.map +1 -0
- package/esm/color/oklch.d.ts +7 -0
- package/esm/color/oklch.d.ts.map +1 -0
- package/esm/color/oklch.js +11 -0
- package/esm/color/oklch.js.map +1 -0
- package/esm/color/parse.d.ts +9 -0
- package/esm/color/parse.d.ts.map +1 -0
- package/esm/color/parse.js +452 -0
- package/esm/color/parse.js.map +1 -0
- package/esm/color/polar.js +27 -0
- package/esm/color/polar.js.map +1 -0
- package/esm/color/prophoto-rgb.d.ts +7 -0
- package/esm/color/prophoto-rgb.d.ts.map +1 -0
- package/esm/color/prophoto-rgb.js +18 -0
- package/esm/color/prophoto-rgb.js.map +1 -0
- package/esm/color/rec2020.d.ts +7 -0
- package/esm/color/rec2020.d.ts.map +1 -0
- package/esm/color/rec2020.js +13 -0
- package/esm/color/rec2020.js.map +1 -0
- package/esm/color/resolve.d.ts +18 -0
- package/esm/color/resolve.d.ts.map +1 -0
- package/esm/color/resolve.js +98 -0
- package/esm/color/resolve.js.map +1 -0
- package/esm/color/rgb.js +20 -0
- package/esm/color/rgb.js.map +1 -0
- package/esm/color/serialize.d.ts +24 -0
- package/esm/color/serialize.d.ts.map +1 -0
- package/esm/color/serialize.js +88 -0
- package/esm/color/serialize.js.map +1 -0
- package/esm/color/spaces.d.ts +6 -0
- package/esm/color/spaces.d.ts.map +1 -0
- package/esm/color/spaces.js +42 -0
- package/esm/color/spaces.js.map +1 -0
- package/esm/color/srgb-linear.d.ts +7 -0
- package/esm/color/srgb-linear.d.ts.map +1 -0
- package/esm/color/srgb-linear.js +12 -0
- package/esm/color/srgb-linear.js.map +1 -0
- package/esm/color/srgb.d.ts +7 -0
- package/esm/color/srgb.d.ts.map +1 -0
- package/esm/color/srgb.js +12 -0
- package/esm/color/srgb.js.map +1 -0
- package/esm/color/transfer.js +11 -0
- package/esm/color/transfer.js.map +1 -0
- package/esm/color/types.d.ts +23 -0
- package/esm/color/types.d.ts.map +1 -0
- package/esm/color/unknown-name.js +16 -0
- package/esm/color/unknown-name.js.map +1 -0
- package/esm/color/xyz-d50.d.ts +7 -0
- package/esm/color/xyz-d50.d.ts.map +1 -0
- package/esm/color/xyz-d50.js +15 -0
- package/esm/color/xyz-d50.js.map +1 -0
- package/esm/color/xyz-d65.d.ts +4 -0
- package/esm/color/xyz-d65.d.ts.map +1 -0
- package/esm/color/xyz-d65.js +10 -0
- package/esm/color/xyz-d65.js.map +1 -0
- package/esm/index.d.ts +63 -6
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +54 -5
- package/esm/index.js.map +1 -0
- package/esm/legacy/createColors.d.ts +9 -0
- package/esm/legacy/createColors.d.ts.map +1 -0
- package/esm/{createColors.js → legacy/createColors.js} +7 -2
- package/esm/legacy/createColors.js.map +1 -0
- package/esm/legacy/createColorsFromMap.d.ts +9 -0
- package/esm/legacy/createColorsFromMap.d.ts.map +1 -0
- package/esm/{createColorsFromMap.js → legacy/createColorsFromMap.js} +4 -2
- package/esm/legacy/createColorsFromMap.js.map +1 -0
- package/esm/legacy/index.d.ts +6 -0
- package/esm/legacy/index.js +5 -0
- package/esm/legacy/interfaces.d.ts +19 -0
- package/esm/legacy/interfaces.d.ts.map +1 -0
- package/esm/{rgbHex.d.ts → legacy/rgbHex.d.ts} +1 -4
- package/esm/legacy/rgbHex.d.ts.map +1 -0
- package/esm/{rgbHex.js → legacy/rgbHex.js} +1 -2
- package/esm/legacy/rgbHex.js.map +1 -0
- package/esm/legacy/rgbaString.d.ts +4 -0
- package/esm/{rgbaString.d.ts.map → legacy/rgbaString.d.ts.map} +1 -1
- package/esm/legacy/rgbaString.js +8 -0
- package/esm/legacy/rgbaString.js.map +1 -0
- package/esm/palette/dark.d.ts +23 -0
- package/esm/palette/dark.d.ts.map +1 -0
- package/esm/palette/dark.js +54 -0
- package/esm/palette/dark.js.map +1 -0
- package/esm/palette/harmony.d.ts +56 -0
- package/esm/palette/harmony.d.ts.map +1 -0
- package/esm/palette/harmony.js +115 -0
- package/esm/palette/harmony.js.map +1 -0
- package/esm/palette/index.d.ts +5 -0
- package/esm/palette/index.js +5 -0
- package/esm/palette/semantic.d.ts +53 -0
- package/esm/palette/semantic.d.ts.map +1 -0
- package/esm/palette/semantic.js +96 -0
- package/esm/palette/semantic.js.map +1 -0
- package/esm/palette/validate.d.ts +39 -0
- package/esm/palette/validate.d.ts.map +1 -0
- package/esm/palette/validate.js +56 -0
- package/esm/palette/validate.js.map +1 -0
- package/esm/scale/brand.d.ts +21 -0
- package/esm/scale/brand.d.ts.map +1 -0
- package/esm/scale/brand.js +63 -0
- package/esm/scale/brand.js.map +1 -0
- package/esm/scale/contrast-scale.d.ts +33 -0
- package/esm/scale/contrast-scale.d.ts.map +1 -0
- package/esm/scale/contrast-scale.js +26 -0
- package/esm/scale/contrast-scale.js.map +1 -0
- package/esm/scale/gradient.d.ts +38 -0
- package/esm/scale/gradient.d.ts.map +1 -0
- package/esm/scale/gradient.js +73 -0
- package/esm/scale/gradient.js.map +1 -0
- package/esm/scale/index.d.ts +6 -0
- package/esm/scale/index.js +6 -0
- package/esm/scale/scale.d.ts +31 -0
- package/esm/scale/scale.d.ts.map +1 -0
- package/esm/scale/scale.js +152 -0
- package/esm/scale/scale.js.map +1 -0
- package/esm/scale/tone.d.ts +25 -0
- package/esm/scale/tone.d.ts.map +1 -0
- package/esm/scale/tone.js +96 -0
- package/esm/scale/tone.js.map +1 -0
- package/esm/tokens/css.d.ts +18 -0
- package/esm/tokens/css.d.ts.map +1 -0
- package/esm/tokens/css.js +23 -0
- package/esm/tokens/css.js.map +1 -0
- package/esm/tokens/dtcg.d.ts +33 -0
- package/esm/tokens/dtcg.d.ts.map +1 -0
- package/esm/tokens/dtcg.js +42 -0
- package/esm/tokens/dtcg.js.map +1 -0
- package/esm/tokens/index.d.ts +5 -0
- package/esm/tokens/index.js +4 -0
- package/esm/tokens/tailwind.d.ts +19 -0
- package/esm/tokens/tailwind.d.ts.map +1 -0
- package/esm/tokens/tailwind.js +19 -0
- package/esm/tokens/tailwind.js.map +1 -0
- package/esm/tokens/tokens.d.ts +11 -0
- package/esm/tokens/tokens.d.ts.map +1 -0
- package/esm/tokens/tokens.js +77 -0
- package/esm/tokens/tokens.js.map +1 -0
- package/llms.txt +48 -0
- package/package.json +277 -64
- package/plugin.json +18 -0
- package/schemas/contrast.schema.json +24 -0
- package/schemas/convert.schema.json +60 -0
- package/schemas/export.schema.json +106 -0
- package/schemas/find-contrast.schema.json +51 -0
- package/schemas/harmony.schema.json +58 -0
- package/schemas/mix.schema.json +72 -0
- package/schemas/palette.schema.json +56 -0
- package/schemas/scale.schema.json +86 -0
- package/skills/color-map/SKILL.md +38 -0
- package/src/cli/bin.ts +11 -0
- package/src/cli/cli.ts +40 -0
- package/src/cli/commands/contrast.ts +36 -0
- package/src/cli/commands/convert.ts +37 -0
- package/src/cli/commands/export.ts +102 -0
- package/src/cli/commands/find-contrast.ts +37 -0
- package/src/cli/commands/harmony.ts +30 -0
- package/src/cli/commands/mix.ts +29 -0
- package/src/cli/commands/palette.ts +66 -0
- package/src/cli/commands/scale.ts +75 -0
- package/src/cli/index.ts +3 -0
- package/src/cli/schema-command.ts +31 -0
- package/src/cli/schemas.ts +86 -0
- package/src/cli/shared.ts +72 -0
- package/src/cli/testing.ts +27 -0
- package/src/color/a98-rgb.ts +11 -0
- package/src/color/argb.ts +21 -0
- package/src/color/calc.ts +84 -0
- package/src/color/compare.ts +53 -0
- package/src/color/contrast.ts +277 -0
- package/src/color/convert.ts +43 -0
- package/src/color/display-p3-linear.ts +9 -0
- package/src/color/display-p3.ts +9 -0
- package/src/color/expr.ts +158 -0
- package/src/color/gamut.ts +215 -0
- package/src/color/hsl.ts +57 -0
- package/src/color/hwb.ts +26 -0
- package/src/color/index.ts +43 -0
- package/src/color/lab.ts +29 -0
- package/src/color/lch.ts +8 -0
- package/src/color/math.ts +30 -0
- package/src/color/matrices.ts +91 -0
- package/src/color/mix.ts +158 -0
- package/src/color/named.ts +13 -0
- package/src/color/oklab.ts +19 -0
- package/src/color/oklch.ts +8 -0
- package/src/color/parse.ts +355 -0
- package/src/color/polar.ts +17 -0
- package/src/color/prophoto-rgb.ts +18 -0
- package/src/color/rec2020.ts +11 -0
- package/src/color/resolve.ts +87 -0
- package/src/color/rgb.ts +20 -0
- package/src/color/serialize.ts +96 -0
- package/src/color/spaces.ts +42 -0
- package/src/color/srgb-linear.ts +9 -0
- package/src/color/srgb.ts +9 -0
- package/src/color/test-utils.ts +10 -0
- package/src/color/transfer.ts +14 -0
- package/src/color/types.ts +41 -0
- package/src/color/unknown-name.ts +15 -0
- package/src/color/xyz-d50.ts +13 -0
- package/src/color/xyz-d65.ts +8 -0
- package/src/index.ts +37 -0
- package/{ts → src/legacy}/createColors.ts +6 -0
- package/{ts → src/legacy}/createColorsFromMap.ts +3 -0
- package/{ts → src/legacy}/interfaces.ts +4 -0
- package/{ts → src/legacy}/rgbaString.ts +1 -0
- package/src/palette/dark.ts +55 -0
- package/src/palette/harmony.ts +107 -0
- package/src/palette/index.ts +18 -0
- package/src/palette/semantic.ts +120 -0
- package/src/palette/validate.ts +82 -0
- package/src/scale/brand.ts +50 -0
- package/src/scale/contrast-scale.ts +48 -0
- package/src/scale/gradient.ts +91 -0
- package/src/scale/index.ts +5 -0
- package/src/scale/scale.ts +127 -0
- package/src/scale/tone.ts +69 -0
- package/src/tokens/css.ts +32 -0
- package/src/tokens/dtcg.ts +62 -0
- package/src/tokens/index.ts +11 -0
- package/src/tokens/tailwind.ts +24 -0
- package/src/tokens/tokens.ts +82 -0
- package/esm/createColors.d.ts +0 -6
- package/esm/createColors.d.ts.map +0 -1
- package/esm/createColors.js.map +0 -1
- package/esm/createColorsFromMap.d.ts +0 -9
- package/esm/createColorsFromMap.d.ts.map +0 -1
- package/esm/createColorsFromMap.js.map +0 -1
- package/esm/interfaces.d.ts +0 -18
- package/esm/interfaces.d.ts.map +0 -1
- package/esm/rgbHex.d.ts.map +0 -1
- package/esm/rgbHex.js.map +0 -1
- package/esm/rgbaString.d.ts +0 -6
- package/esm/rgbaString.js +0 -8
- package/esm/rgbaString.js.map +0 -1
- /package/{ts → src/legacy}/index.ts +0 -0
- /package/{ts → src/legacy}/rgbHex.ts +0 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
const require_parse = require("./parse-8mt2OMKf.js");
|
|
2
|
+
// src/color/serialize.ts
|
|
3
|
+
const POWERS = Array.from({ length: 23 }, (_, i) => Number(`1e${i}`));
|
|
4
|
+
/**
|
|
5
|
+
* `Number(n.toFixed(precision))`, without building the string. `toFixed` rounds
|
|
6
|
+
* the exact value of `n` half up (away from zero), and the number it then reads
|
|
7
|
+
* is `k / 10^precision` for that integer `k`, which one division gives exactly.
|
|
8
|
+
* `k` comes from `t = |n| * 10^precision`. The product is rounded, but a tie
|
|
9
|
+
* (`t` ending in .5) is a double, and rounding is monotonic, so any `t` that
|
|
10
|
+
* is not exactly a tie lies on the same side of it as the exact product: only
|
|
11
|
+
* `t` ending in .5 is left to `toFixed`. So are NaN, the infinities, products
|
|
12
|
+
* of 1e9 and up, and precisions that `POWERS` lacks.
|
|
13
|
+
*/
|
|
14
|
+
function roundTo(n, precision) {
|
|
15
|
+
const scale = POWERS[precision];
|
|
16
|
+
const t = Math.abs(n) * scale;
|
|
17
|
+
const whole = Math.floor(t);
|
|
18
|
+
const rest = t - whole;
|
|
19
|
+
if (t < 1e9 && rest !== .5) {
|
|
20
|
+
const r = (rest > .5 ? whole + 1 : whole) / scale;
|
|
21
|
+
return n < 0 ? -r : r;
|
|
22
|
+
}
|
|
23
|
+
return Number(n.toFixed(precision));
|
|
24
|
+
}
|
|
25
|
+
/** Prints a number with at most `precision` decimals, without `-0` or trailing zeros. */
|
|
26
|
+
function num(n, precision) {
|
|
27
|
+
return String(roundTo(n, precision) + 0);
|
|
28
|
+
}
|
|
29
|
+
const part = (c, precision, scale = 1, suffix = "") => c === null ? "none" : num(c * scale, precision) + suffix;
|
|
30
|
+
const RECTANGULAR = /* @__PURE__ */ new Set([
|
|
31
|
+
"hsl",
|
|
32
|
+
"hwb",
|
|
33
|
+
"lab",
|
|
34
|
+
"lch",
|
|
35
|
+
"oklab",
|
|
36
|
+
"oklch"
|
|
37
|
+
]);
|
|
38
|
+
/**
|
|
39
|
+
* Serializes a color as CSS. `srgb` and `hsl` print in the comma syntax
|
|
40
|
+
* (`rgb(255, 0, 0)`, `rgba(...)`) unless a component is `none`; the other
|
|
41
|
+
* spaces print in the space syntax (`oklch(0.7 0.1 200 / 0.5)`,
|
|
42
|
+
* `color(display-p3 1 0 0)`). Out-of-gamut values are kept, not clipped.
|
|
43
|
+
*/
|
|
44
|
+
function toCss(color, options = {}) {
|
|
45
|
+
const { precision = 5 } = options;
|
|
46
|
+
const id = color.colorSpace;
|
|
47
|
+
const [c0, c1, c2] = color.components;
|
|
48
|
+
const p = (c, scale, suffix) => part(c, precision, scale, suffix);
|
|
49
|
+
const a = color.alpha !== void 0 && color.alpha !== 1 ? p(color.alpha) : void 0;
|
|
50
|
+
const percent = id === "hsl" || id === "hwb" ? "%" : "";
|
|
51
|
+
const scale = id === "srgb" ? 255 : 1;
|
|
52
|
+
const args = [
|
|
53
|
+
p(c0, scale),
|
|
54
|
+
p(c1, scale, percent),
|
|
55
|
+
p(c2, scale, percent)
|
|
56
|
+
];
|
|
57
|
+
if ((id === "srgb" || id === "hsl") && color.alpha !== null && !color.components.includes(null)) {
|
|
58
|
+
const name = id === "srgb" ? "rgb" : "hsl";
|
|
59
|
+
return a === void 0 ? `${name}(${args.join(", ")})` : `${name}a(${args.join(", ")}, ${a})`;
|
|
60
|
+
}
|
|
61
|
+
return `${id === "srgb" ? "rgb(" : RECTANGULAR.has(id) ? `${id}(` : `color(${id} `}${args.join(" ")}${a === void 0 ? "" : ` / ${a}`})`;
|
|
62
|
+
}
|
|
63
|
+
const hexByte = (n) => Math.min(255, Math.max(0, Math.round(n * 255))).toString(16).padStart(2, "0");
|
|
64
|
+
/**
|
|
65
|
+
* The hex form of a color, `#rrggbb` or `#rrggbbaa` when it is not opaque.
|
|
66
|
+
* Colors outside sRGB are converted and clipped, so map them with `toGamut` first.
|
|
67
|
+
*/
|
|
68
|
+
function toHex(color) {
|
|
69
|
+
return hexWith(require_parse.componentsIn, color);
|
|
70
|
+
}
|
|
71
|
+
function hexWith(componentsIn, color) {
|
|
72
|
+
const [r, g, b] = componentsIn(color, "srgb");
|
|
73
|
+
const alpha = color.alpha ?? 1;
|
|
74
|
+
return `#${hexByte(r)}${hexByte(g)}${hexByte(b)}${alpha === 1 ? "" : hexByte(alpha)}`;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Builds {@link toHex} over the spaces given, plus `srgb`, so a bundle contains
|
|
78
|
+
* only those. A color in a space not given throws, naming that space.
|
|
79
|
+
*/
|
|
80
|
+
function createToHex(...spaces) {
|
|
81
|
+
const over = require_parse.componentsOver([require_parse.srgb, ...spaces]);
|
|
82
|
+
return (color) => hexWith(over, color);
|
|
83
|
+
}
|
|
84
|
+
Object.defineProperty(exports, "createToHex", {
|
|
85
|
+
enumerable: true,
|
|
86
|
+
get: function() {
|
|
87
|
+
return createToHex;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
Object.defineProperty(exports, "toCss", {
|
|
91
|
+
enumerable: true,
|
|
92
|
+
get: function() {
|
|
93
|
+
return toCss;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
Object.defineProperty(exports, "toHex", {
|
|
97
|
+
enumerable: true,
|
|
98
|
+
get: function() {
|
|
99
|
+
return toHex;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
//# sourceMappingURL=serialize-Ci2X0cPN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize-Ci2X0cPN.js","names":["componentsIn","componentsOver","srgb"],"sources":["../src/color/serialize.ts"],"sourcesContent":["import { type ComponentsIn, componentsOver } from './convert.js'\nimport { componentsIn } from './spaces.js'\nimport { srgb } from './srgb.js'\nimport type { Color, ColorSpaceId, Component, Space } from './types.js'\n\n/** Options for `toCss`. */\nexport interface ToCssOptions {\n\t/** Decimal places kept in every number. Default 5. */\n\tprecision?: number\n}\n\nconst POWERS = Array.from({ length: 23 }, (_, i) => Number(`1e${i}`))\n\n/**\n * `Number(n.toFixed(precision))`, without building the string. `toFixed` rounds\n * the exact value of `n` half up (away from zero), and the number it then reads\n * is `k / 10^precision` for that integer `k`, which one division gives exactly.\n * `k` comes from `t = |n| * 10^precision`. The product is rounded, but a tie\n * (`t` ending in .5) is a double, and rounding is monotonic, so any `t` that\n * is not exactly a tie lies on the same side of it as the exact product: only\n * `t` ending in .5 is left to `toFixed`. So are NaN, the infinities, products\n * of 1e9 and up, and precisions that `POWERS` lacks.\n */\nexport function roundTo(n: number, precision: number): number {\n\tconst scale = POWERS[precision]\n\tconst t = Math.abs(n) * scale\n\tconst whole = Math.floor(t)\n\tconst rest = t - whole\n\tif (t < 1e9 && rest !== 0.5) {\n\t\tconst r = (rest > 0.5 ? whole + 1 : whole) / scale\n\t\treturn n < 0 ? -r : r\n\t}\n\treturn Number(n.toFixed(precision))\n}\n\n/** Prints a number with at most `precision` decimals, without `-0` or trailing zeros. */\nfunction num(n: number, precision: number): string {\n\treturn String(roundTo(n, precision) + 0)\n}\n\nconst part = (c: Component, precision: number, scale = 1, suffix = ''): string =>\n\tc === null ? 'none' : num(c * scale, precision) + suffix\n\nconst RECTANGULAR = new Set<ColorSpaceId>(['hsl', 'hwb', 'lab', 'lch', 'oklab', 'oklch'])\n\n/**\n * Serializes a color as CSS. `srgb` and `hsl` print in the comma syntax\n * (`rgb(255, 0, 0)`, `rgba(...)`) unless a component is `none`; the other\n * spaces print in the space syntax (`oklch(0.7 0.1 200 / 0.5)`,\n * `color(display-p3 1 0 0)`). Out-of-gamut values are kept, not clipped.\n */\nexport function toCss(color: Color, options: ToCssOptions = {}): string {\n\tconst { precision = 5 } = options\n\tconst id = color.colorSpace\n\tconst [c0, c1, c2] = color.components\n\tconst p = (c: Component, scale?: number, suffix?: string): string => part(c, precision, scale, suffix)\n\tconst hasAlpha = color.alpha !== undefined && color.alpha !== 1\n\tconst a = hasAlpha ? p(color.alpha as Component) : undefined\n\tconst percent = id === 'hsl' || id === 'hwb' ? '%' : ''\n\tconst scale = id === 'srgb' ? 255 : 1\n\tconst args = [p(c0, scale), p(c1, scale, percent), p(c2, scale, percent)]\n\tif ((id === 'srgb' || id === 'hsl') && color.alpha !== null && !color.components.includes(null)) {\n\t\tconst name = id === 'srgb' ? 'rgb' : 'hsl'\n\t\treturn a === undefined ? `${name}(${args.join(', ')})` : `${name}a(${args.join(', ')}, ${a})`\n\t}\n\tconst head = id === 'srgb' ? 'rgb(' : RECTANGULAR.has(id) ? `${id}(` : `color(${id} `\n\treturn `${head}${args.join(' ')}${a === undefined ? '' : ` / ${a}`})`\n}\n\nconst hexByte = (n: number): string =>\n\tMath.min(255, Math.max(0, Math.round(n * 255)))\n\t\t.toString(16)\n\t\t.padStart(2, '0')\n\n/**\n * The hex form of a color, `#rrggbb` or `#rrggbbaa` when it is not opaque.\n * Colors outside sRGB are converted and clipped, so map them with `toGamut` first.\n */\nexport function toHex(color: Color): string {\n\treturn hexWith(componentsIn, color)\n}\n\nfunction hexWith(componentsIn: ComponentsIn, color: Color): string {\n\tconst [r, g, b] = componentsIn(color, 'srgb') as number[]\n\tconst alpha = color.alpha ?? 1\n\treturn `#${hexByte(r)}${hexByte(g)}${hexByte(b)}${alpha === 1 ? '' : hexByte(alpha)}`\n}\n\n/**\n * Builds {@link toHex} over the spaces given, plus `srgb`, so a bundle contains\n * only those. A color in a space not given throws, naming that space.\n */\nexport function createToHex(...spaces: Space[]): (color: Color) => string {\n\tconst over = componentsOver([srgb, ...spaces])\n\treturn (color) => hexWith(over, color)\n}\n"],"mappings":";;AAWA,MAAM,SAAS,MAAM,KAAK,EAAE,QAAQ,GAAG,IAAI,GAAG,MAAM,OAAO,KAAK,GAAG,CAAC;;;;;;;;;;;AAYpE,SAAgB,QAAQ,GAAW,WAA2B;CAC7D,MAAM,QAAQ,OAAO;CACrB,MAAM,IAAI,KAAK,IAAI,CAAC,IAAI;CACxB,MAAM,QAAQ,KAAK,MAAM,CAAC;CAC1B,MAAM,OAAO,IAAI;CACjB,IAAI,IAAI,OAAO,SAAS,IAAK;EAC5B,MAAM,KAAK,OAAO,KAAM,QAAQ,IAAI,SAAS;EAC7C,OAAO,IAAI,IAAI,CAAC,IAAI;CACrB;CACA,OAAO,OAAO,EAAE,QAAQ,SAAS,CAAC;AACnC;;AAGA,SAAS,IAAI,GAAW,WAA2B;CAClD,OAAO,OAAO,QAAQ,GAAG,SAAS,IAAI,CAAC;AACxC;AAEA,MAAM,QAAQ,GAAc,WAAmB,QAAQ,GAAG,SAAS,OAClE,MAAM,OAAO,SAAS,IAAI,IAAI,OAAO,SAAS,IAAI;AAEnD,MAAM,8BAAc,IAAI,IAAkB;CAAC;CAAO;CAAO;CAAO;CAAO;CAAS;AAAO,CAAC;;;;;;;AAQxF,SAAgB,MAAM,OAAc,UAAwB,CAAC,GAAW;CACvE,MAAM,EAAE,YAAY,MAAM;CAC1B,MAAM,KAAK,MAAM;CACjB,MAAM,CAAC,IAAI,IAAI,MAAM,MAAM;CAC3B,MAAM,KAAK,GAAc,OAAgB,WAA4B,KAAK,GAAG,WAAW,OAAO,MAAM;CAErG,MAAM,IADW,MAAM,UAAU,KAAA,KAAa,MAAM,UAAU,IACzC,EAAE,MAAM,KAAkB,IAAI,KAAA;CACnD,MAAM,UAAU,OAAO,SAAS,OAAO,QAAQ,MAAM;CACrD,MAAM,QAAQ,OAAO,SAAS,MAAM;CACpC,MAAM,OAAO;EAAC,EAAE,IAAI,KAAK;EAAG,EAAE,IAAI,OAAO,OAAO;EAAG,EAAE,IAAI,OAAO,OAAO;CAAC;CACxE,KAAK,OAAO,UAAU,OAAO,UAAU,MAAM,UAAU,QAAQ,CAAC,MAAM,WAAW,SAAS,IAAI,GAAG;EAChG,MAAM,OAAO,OAAO,SAAS,QAAQ;EACrC,OAAO,MAAM,KAAA,IAAY,GAAG,KAAK,GAAG,KAAK,KAAK,IAAI,EAAE,KAAK,GAAG,KAAK,IAAI,KAAK,KAAK,IAAI,EAAE,IAAI,EAAE;CAC5F;CAEA,OAAO,GADM,OAAO,SAAS,SAAS,YAAY,IAAI,EAAE,IAAI,GAAG,GAAG,KAAK,SAAS,GAAG,KAClE,KAAK,KAAK,GAAG,IAAI,MAAM,KAAA,IAAY,KAAK,MAAM,IAAI;AACpE;AAEA,MAAM,WAAW,MAChB,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAC7C,SAAS,EAAE,CAAC,CACZ,SAAS,GAAG,GAAG;;;;;AAMlB,SAAgB,MAAM,OAAsB;CAC3C,OAAO,QAAQA,cAAAA,cAAc,KAAK;AACnC;AAEA,SAAS,QAAQ,cAA4B,OAAsB;CAClE,MAAM,CAAC,GAAG,GAAG,KAAK,aAAa,OAAO,MAAM;CAC5C,MAAM,QAAQ,MAAM,SAAS;CAC7B,OAAO,IAAI,QAAQ,CAAC,IAAI,QAAQ,CAAC,IAAI,QAAQ,CAAC,IAAI,UAAU,IAAI,KAAK,QAAQ,KAAK;AACnF;;;;;AAMA,SAAgB,YAAY,GAAG,QAA2C;CACzE,MAAM,OAAOC,cAAAA,eAAe,CAACC,cAAAA,MAAM,GAAG,MAAM,CAAC;CAC7C,QAAQ,UAAU,QAAQ,MAAM,KAAK;AACtC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as DtcgOptions, c as toDtcgValue, d as TokenTree, i as DtcgGroup, l as CssVariablesOptions, n as toTailwindTheme, o as DtcgToken, r as DtcgColorValue, s as toDtcg, t as TailwindThemeOptions, u as toCssVariables } from "../index-Dy8UARqO.js";
|
|
2
|
+
export { type CssVariablesOptions, type DtcgColorValue, type DtcgGroup, type DtcgOptions, type DtcgToken, type TailwindThemeOptions, type TokenTree, toCssVariables, toDtcg, toDtcgValue, toTailwindTheme };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_tokens = require("../tokens-CzXxaMgM.js");
|
|
3
|
+
exports.toCssVariables = require_tokens.toCssVariables;
|
|
4
|
+
exports.toDtcg = require_tokens.toDtcg;
|
|
5
|
+
exports.toDtcgValue = require_tokens.toDtcgValue;
|
|
6
|
+
exports.toTailwindTheme = require_tokens.toTailwindTheme;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
const require_serialize = require("./serialize-Ci2X0cPN.js");
|
|
2
|
+
const require_parse = require("./parse-8mt2OMKf.js");
|
|
3
|
+
// src/tokens/tokens.ts
|
|
4
|
+
const TAILWIND_STEPS = [
|
|
5
|
+
50,
|
|
6
|
+
100,
|
|
7
|
+
200,
|
|
8
|
+
300,
|
|
9
|
+
400,
|
|
10
|
+
500,
|
|
11
|
+
600,
|
|
12
|
+
700,
|
|
13
|
+
800,
|
|
14
|
+
900,
|
|
15
|
+
950
|
|
16
|
+
];
|
|
17
|
+
const isColor = (v) => typeof v === "object" && v !== null && typeof v.colorSpace === "string" && Array.isArray(v.components);
|
|
18
|
+
function dropMeasures(tree) {
|
|
19
|
+
const { meta: _meta, scales, roles, ...rest } = tree;
|
|
20
|
+
const pairs = Object.fromEntries(Object.entries(roles).map(([name, p]) => [name, {
|
|
21
|
+
bg: p.bg,
|
|
22
|
+
fg: p.fg
|
|
23
|
+
}]));
|
|
24
|
+
return {
|
|
25
|
+
...rest,
|
|
26
|
+
...scales,
|
|
27
|
+
roles: pairs
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const isSemantic = (v) => "roles" in v && "scales" in v && "meta" in v;
|
|
31
|
+
/**
|
|
32
|
+
* Walks a token tree into a flat list. An array gets the Tailwind keys
|
|
33
|
+
* (50 to 950) when it has 11 colors and 1-based numbers otherwise; pass an
|
|
34
|
+
* object to choose the keys. A value that is not a color, a string, an array
|
|
35
|
+
* or an object throws with its path.
|
|
36
|
+
*/
|
|
37
|
+
function flatten(tree) {
|
|
38
|
+
const out = [];
|
|
39
|
+
const walk = (node, path) => {
|
|
40
|
+
if (typeof node === "string") return void out.push({
|
|
41
|
+
path,
|
|
42
|
+
color: require_parse.parse(node)
|
|
43
|
+
});
|
|
44
|
+
if (isColor(node)) return void out.push({
|
|
45
|
+
path,
|
|
46
|
+
color: node
|
|
47
|
+
});
|
|
48
|
+
if (Array.isArray(node)) {
|
|
49
|
+
node.forEach((v, i) => {
|
|
50
|
+
walk(v, [...path, String(node.length === TAILWIND_STEPS.length ? TAILWIND_STEPS[i] : i + 1)]);
|
|
51
|
+
});
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (typeof node === "object" && node !== null) {
|
|
55
|
+
const obj = isSemantic(node) ? dropMeasures(node) : node;
|
|
56
|
+
for (const [k, v] of Object.entries(obj)) walk(v, [...path, k]);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
throw new TypeError(`${path.join(".") || "(root)"} is not a color, a string, an array or an object`);
|
|
60
|
+
};
|
|
61
|
+
walk(tree, []);
|
|
62
|
+
return out;
|
|
63
|
+
}
|
|
64
|
+
/** `primaryContainer` and `Primary Container` both become `primary-container`. */
|
|
65
|
+
const kebab = (name) => name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase();
|
|
66
|
+
/** Names tokens for CSS: kebab-case segments joined by `-` after `prefix`. Two tokens with one name throw. */
|
|
67
|
+
function cssNames(tokens, prefix) {
|
|
68
|
+
const out = /* @__PURE__ */ new Map();
|
|
69
|
+
for (const { path, color } of tokens) {
|
|
70
|
+
const name = `--${[prefix, ...path].map(kebab).filter(Boolean).join("-")}`;
|
|
71
|
+
if (out.has(name)) throw new Error(`${name} is produced by more than one token`);
|
|
72
|
+
out.set(name, color);
|
|
73
|
+
}
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
// src/tokens/css.ts
|
|
77
|
+
/** Prints one `--name: value;` line per color. */
|
|
78
|
+
function declarations(tree, options) {
|
|
79
|
+
const { prefix, space, ...css } = options;
|
|
80
|
+
return [...cssNames(flatten(tree), prefix)].map(([name, color]) => `${name}: ${require_serialize.toCss(space ? require_parse.convert(color, space) : color, css)};`);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Exports colors as CSS custom properties in one rule:
|
|
84
|
+
* `:root {\n\t--color-primary-500: oklch(0.62 0.19 260);\n}`.
|
|
85
|
+
*/
|
|
86
|
+
function toCssVariables(tree, options = {}) {
|
|
87
|
+
const { selector = ":root", prefix = "color", ...rest } = options;
|
|
88
|
+
return `${selector} {\n${declarations(tree, {
|
|
89
|
+
...rest,
|
|
90
|
+
prefix
|
|
91
|
+
}).map((l) => `\t${l}\n`).join("")}}\n`;
|
|
92
|
+
}
|
|
93
|
+
// src/tokens/dtcg.ts
|
|
94
|
+
const none = (c) => c === null ? "none" : c;
|
|
95
|
+
/** One color as a DTCG color value. `display-p3-linear` is not a DTCG space, so it becomes `display-p3`. */
|
|
96
|
+
function toDtcgValue(color, options = {}) {
|
|
97
|
+
const c = color.colorSpace === "display-p3-linear" ? require_parse.convert(color, "display-p3") : color;
|
|
98
|
+
const value = {
|
|
99
|
+
colorSpace: c.colorSpace,
|
|
100
|
+
components: c.components.map(none)
|
|
101
|
+
};
|
|
102
|
+
if (c.alpha !== void 0 && c.alpha !== 1) value.alpha = none(c.alpha);
|
|
103
|
+
if (options.hex !== false) value.hex = require_serialize.toHex(require_parse.toGamut({
|
|
104
|
+
...c,
|
|
105
|
+
alpha: 1
|
|
106
|
+
}, { gamut: "srgb" }));
|
|
107
|
+
return value;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Exports colors as a DTCG 2025.10 token file: nested groups whose leaves are
|
|
111
|
+
* `{ "$type": "color", "$value": { colorSpace, components, alpha?, hex? } }`.
|
|
112
|
+
* `none` components print as `"none"`, as the format asks. The result is plain
|
|
113
|
+
* JSON, so `JSON.stringify` writes the file.
|
|
114
|
+
*/
|
|
115
|
+
function toDtcg(tree, options = {}) {
|
|
116
|
+
const root = Object.create(null);
|
|
117
|
+
for (const { path, color } of flatten(tree)) {
|
|
118
|
+
if (!path.length) throw new TypeError("A DTCG file needs a name for each token: pass an object, not a single color");
|
|
119
|
+
let group = root;
|
|
120
|
+
for (const name of path.slice(0, -1)) group = group[name] ??= Object.create(null);
|
|
121
|
+
group[path[path.length - 1]] = {
|
|
122
|
+
$type: "color",
|
|
123
|
+
$value: toDtcgValue(color, options)
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
return root;
|
|
127
|
+
}
|
|
128
|
+
// src/tokens/tailwind.ts
|
|
129
|
+
/**
|
|
130
|
+
* Exports colors as a Tailwind v4 `@theme` block. Paste it into the CSS file
|
|
131
|
+
* that has `@import "tailwindcss"`. An array of 11 colors gets the keys
|
|
132
|
+
* 50 to 950, so a `tailwind-11` scale reads like Tailwind's own.
|
|
133
|
+
*/
|
|
134
|
+
function toTailwindTheme(tree, options = {}) {
|
|
135
|
+
const { namespace = "color", inline = false, space = "oklch", ...rest } = options;
|
|
136
|
+
const lines = declarations(tree, {
|
|
137
|
+
...rest,
|
|
138
|
+
space,
|
|
139
|
+
prefix: namespace
|
|
140
|
+
});
|
|
141
|
+
return `@theme${inline ? " inline" : ""} {\n${lines.map((l) => `\t${l}\n`).join("")}}\n`;
|
|
142
|
+
}
|
|
143
|
+
Object.defineProperty(exports, "toCssVariables", {
|
|
144
|
+
enumerable: true,
|
|
145
|
+
get: function() {
|
|
146
|
+
return toCssVariables;
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
Object.defineProperty(exports, "toDtcg", {
|
|
150
|
+
enumerable: true,
|
|
151
|
+
get: function() {
|
|
152
|
+
return toDtcg;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
Object.defineProperty(exports, "toDtcgValue", {
|
|
156
|
+
enumerable: true,
|
|
157
|
+
get: function() {
|
|
158
|
+
return toDtcgValue;
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
Object.defineProperty(exports, "toTailwindTheme", {
|
|
162
|
+
enumerable: true,
|
|
163
|
+
get: function() {
|
|
164
|
+
return toTailwindTheme;
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
//# sourceMappingURL=tokens-CzXxaMgM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens-CzXxaMgM.js","names":["parse","toCss","convert","convert","toHex","toGamut"],"sources":["../src/tokens/tokens.ts","../src/tokens/css.ts","../src/tokens/dtcg.ts","../src/tokens/tailwind.ts"],"sourcesContent":["import { parse } from '../color/parse.js'\nimport type { Color } from '../color/types.js'\nimport type { SemanticPalette } from '../palette/semantic.js'\n\n/**\n * What the exporters accept: a color, a CSS color string, an array of them (a\n * scale), or an object of any of these nested to any depth. A `SemanticPalette`\n * works as is: its `scales` and its role pairs export, its `meta` and ratios do not.\n */\nexport type TokenTree = SemanticPalette | Color | string | readonly TokenTree[] | { readonly [name: string]: TokenTree }\n\n/** A color and the path of names that leads to it. */\nexport interface Token {\n\tpath: string[]\n\tcolor: Color\n}\n\nconst TAILWIND_STEPS = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950]\n\nconst isColor = (v: unknown): v is Color =>\n\ttypeof v === 'object' &&\n\tv !== null &&\n\ttypeof (v as Color).colorSpace === 'string' &&\n\tArray.isArray((v as Color).components)\n\n// A semantic palette carries numbers (`ratio`, `target`, `meta`) that are not colors.\nfunction dropMeasures(tree: Record<string, unknown>): Record<string, unknown> {\n\tconst { meta: _meta, scales, roles, ...rest } = tree\n\tconst pairs = Object.fromEntries(\n\t\tObject.entries(roles as Record<string, { bg: Color; fg: Color }>).map(([name, p]) => [name, { bg: p.bg, fg: p.fg }])\n\t)\n\treturn { ...rest, ...(scales as object), roles: pairs }\n}\n\nconst isSemantic = (v: object): boolean => 'roles' in v && 'scales' in v && 'meta' in v\n\n/**\n * Walks a token tree into a flat list. An array gets the Tailwind keys\n * (50 to 950) when it has 11 colors and 1-based numbers otherwise; pass an\n * object to choose the keys. A value that is not a color, a string, an array\n * or an object throws with its path.\n */\nexport function flatten(tree: TokenTree): Token[] {\n\tconst out: Token[] = []\n\tconst walk = (node: unknown, path: string[]): void => {\n\t\tif (typeof node === 'string') return void out.push({ path, color: parse(node) })\n\t\tif (isColor(node)) return void out.push({ path, color: node })\n\t\tif (Array.isArray(node)) {\n\t\t\tnode.forEach((v, i) => {\n\t\t\t\twalk(v, [...path, String(node.length === TAILWIND_STEPS.length ? TAILWIND_STEPS[i] : i + 1)])\n\t\t\t})\n\t\t\treturn\n\t\t}\n\t\tif (typeof node === 'object' && node !== null) {\n\t\t\tconst obj = isSemantic(node) ? dropMeasures(node as Record<string, unknown>) : (node as Record<string, unknown>)\n\t\t\tfor (const [k, v] of Object.entries(obj)) walk(v, [...path, k])\n\t\t\treturn\n\t\t}\n\t\tthrow new TypeError(`${path.join('.') || '(root)'} is not a color, a string, an array or an object`)\n\t}\n\twalk(tree, [])\n\treturn out\n}\n\n/** `primaryContainer` and `Primary Container` both become `primary-container`. */\nexport const kebab = (name: string): string =>\n\tname\n\t\t.replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n\t\t.replace(/[^a-zA-Z0-9]+/g, '-')\n\t\t.replace(/^-+|-+$/g, '')\n\t\t.toLowerCase()\n\n/** Names tokens for CSS: kebab-case segments joined by `-` after `prefix`. Two tokens with one name throw. */\nexport function cssNames(tokens: Token[], prefix: string): Map<string, Color> {\n\tconst out = new Map<string, Color>()\n\tfor (const { path, color } of tokens) {\n\t\tconst name = `--${[prefix, ...path].map(kebab).filter(Boolean).join('-')}`\n\t\tif (out.has(name)) throw new Error(`${name} is produced by more than one token`)\n\t\tout.set(name, color)\n\t}\n\treturn out\n}\n","import { type ToCssOptions, toCss } from '../color/serialize.js'\nimport { convert } from '../color/spaces.js'\nimport type { ColorSpaceId } from '../color/types.js'\nimport { cssNames, flatten, type TokenTree } from './tokens.js'\n\n/** Options for `toCssVariables`. It also takes the options of `toCss`. */\nexport interface CssVariablesOptions extends ToCssOptions {\n\t/** The first part of every name. Default `color`, so `primary.500` becomes `--color-primary-500`. */\n\tprefix?: string\n\t/** The rule's selector. Default `:root`. */\n\tselector?: string\n\t/** Convert every color to this space first. Default: print each in its own space. */\n\tspace?: ColorSpaceId\n}\n\n/** Prints one `--name: value;` line per color. */\nexport function declarations(tree: TokenTree, options: CssVariablesOptions & { prefix: string }): string[] {\n\tconst { prefix, space, ...css } = options\n\treturn [...cssNames(flatten(tree), prefix)].map(\n\t\t([name, color]) => `${name}: ${toCss(space ? convert(color, space) : color, css)};`\n\t)\n}\n\n/**\n * Exports colors as CSS custom properties in one rule:\n * `:root {\\n\\t--color-primary-500: oklch(0.62 0.19 260);\\n}`.\n */\nexport function toCssVariables(tree: TokenTree, options: CssVariablesOptions = {}): string {\n\tconst { selector = ':root', prefix = 'color', ...rest } = options\n\tconst lines = declarations(tree, { ...rest, prefix })\n\treturn `${selector} {\\n${lines.map((l) => `\\t${l}\\n`).join('')}}\\n`\n}\n","import { toGamut } from '../color/gamut.js'\nimport { toHex } from '../color/serialize.js'\nimport { convert } from '../color/spaces.js'\nimport type { Color, ColorSpaceId, Component } from '../color/types.js'\nimport { flatten, type TokenTree } from './tokens.js'\n\n/** Options for `toDtcg` and `toDtcgValue`. */\nexport interface DtcgOptions {\n\t/** Add the `hex` fallback (an sRGB `#rrggbb`, gamut-mapped when the color is outside sRGB). Default `true`. */\n\thex?: boolean\n}\n\n/** A color value as DTCG 2025.10 defines it. */\nexport interface DtcgColorValue {\n\tcolorSpace: Exclude<ColorSpaceId, 'display-p3-linear'>\n\tcomponents: (number | 'none')[]\n\talpha?: number | 'none'\n\thex?: string\n}\n\n/** A DTCG color token: a `$type` of `color` and its {@link DtcgColorValue}. */\nexport interface DtcgToken {\n\t$type: 'color'\n\t$value: DtcgColorValue\n}\n\n/** A DTCG group: named tokens and nested groups, as `toDtcg` returns for a token tree. */\nexport interface DtcgGroup {\n\t[name: string]: DtcgToken | DtcgGroup\n}\n\nconst none = (c: Component): number | 'none' => (c === null ? 'none' : c)\n\n/** One color as a DTCG color value. `display-p3-linear` is not a DTCG space, so it becomes `display-p3`. */\nexport function toDtcgValue(color: Color, options: DtcgOptions = {}): DtcgColorValue {\n\tconst c = color.colorSpace === 'display-p3-linear' ? convert(color, 'display-p3') : color\n\tconst value: DtcgColorValue = {\n\t\tcolorSpace: c.colorSpace as DtcgColorValue['colorSpace'],\n\t\tcomponents: c.components.map(none)\n\t}\n\tif (c.alpha !== undefined && c.alpha !== 1) value.alpha = none(c.alpha)\n\tif (options.hex !== false) value.hex = toHex(toGamut({ ...c, alpha: 1 }, { gamut: 'srgb' }))\n\treturn value\n}\n\n/**\n * Exports colors as a DTCG 2025.10 token file: nested groups whose leaves are\n * `{ \"$type\": \"color\", \"$value\": { colorSpace, components, alpha?, hex? } }`.\n * `none` components print as `\"none\"`, as the format asks. The result is plain\n * JSON, so `JSON.stringify` writes the file.\n */\nexport function toDtcg(tree: TokenTree, options: DtcgOptions = {}): DtcgGroup {\n\t// Groups have no prototype, so a token named `__proto__` or `constructor` is an ordinary key.\n\tconst root: DtcgGroup = Object.create(null)\n\tfor (const { path, color } of flatten(tree)) {\n\t\tif (!path.length) throw new TypeError('A DTCG file needs a name for each token: pass an object, not a single color')\n\t\tlet group = root\n\t\tfor (const name of path.slice(0, -1)) group = (group[name] ??= Object.create(null)) as DtcgGroup\n\t\tgroup[path[path.length - 1] as string] = { $type: 'color', $value: toDtcgValue(color, options) }\n\t}\n\treturn root\n}\n","import type { ColorSpaceId } from '../color/types.js'\nimport { type CssVariablesOptions, declarations } from './css.js'\nimport type { TokenTree } from './tokens.js'\n\n/** Options for `toTailwindTheme`. It also takes the options of `toCss`. */\nexport interface TailwindThemeOptions extends Omit<CssVariablesOptions, 'selector' | 'prefix'> {\n\t/** The theme variable namespace. Default `color`, which makes `bg-primary-500` and `text-primary-500` work. */\n\tnamespace?: string\n\t/** Write `@theme inline`, so utilities hold the value instead of a `var()` reference. */\n\tinline?: boolean\n\t/** Default `oklch`, the space Tailwind v4's own palette uses. */\n\tspace?: ColorSpaceId\n}\n\n/**\n * Exports colors as a Tailwind v4 `@theme` block. Paste it into the CSS file\n * that has `@import \"tailwindcss\"`. An array of 11 colors gets the keys\n * 50 to 950, so a `tailwind-11` scale reads like Tailwind's own.\n */\nexport function toTailwindTheme(tree: TokenTree, options: TailwindThemeOptions = {}): string {\n\tconst { namespace = 'color', inline = false, space = 'oklch', ...rest } = options\n\tconst lines = declarations(tree, { ...rest, space, prefix: namespace })\n\treturn `@theme${inline ? ' inline' : ''} {\\n${lines.map((l) => `\\t${l}\\n`).join('')}}\\n`\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
const require_parse = require("./parse-8mt2OMKf.js");
|
|
2
|
+
// src/scale/tone.ts
|
|
3
|
+
/** CIE L* (0 to 100) of a color: its relative luminance on the CIELAB lightness curve. */
|
|
4
|
+
function lstar(color) {
|
|
5
|
+
const y = Math.max(0, require_parse.componentsIn(color, "xyz-d65")[1]);
|
|
6
|
+
return y > 216 / 24389 ? 116 * Math.cbrt(y) - 16 : 24389 / 27 * y;
|
|
7
|
+
}
|
|
8
|
+
/** Material's tones: 0 is black, 100 is white. */
|
|
9
|
+
const MATERIAL_TONES = [
|
|
10
|
+
0,
|
|
11
|
+
10,
|
|
12
|
+
20,
|
|
13
|
+
30,
|
|
14
|
+
40,
|
|
15
|
+
50,
|
|
16
|
+
60,
|
|
17
|
+
70,
|
|
18
|
+
80,
|
|
19
|
+
90,
|
|
20
|
+
95,
|
|
21
|
+
99,
|
|
22
|
+
100
|
|
23
|
+
];
|
|
24
|
+
/**
|
|
25
|
+
* The color at CIE L* `tone` with the given OKLCH hue and chroma, mapped into
|
|
26
|
+
* the gamut. OKLCH lightness is searched until the *mapped* color lands on
|
|
27
|
+
* `tone`, so chroma tapers where the gamut narrows and the tone stays true.
|
|
28
|
+
*/
|
|
29
|
+
function toneColor(tone, chroma, hue, gamut = "srgb") {
|
|
30
|
+
if (tone <= 0) return {
|
|
31
|
+
colorSpace: "oklch",
|
|
32
|
+
components: [
|
|
33
|
+
0,
|
|
34
|
+
0,
|
|
35
|
+
hue
|
|
36
|
+
]
|
|
37
|
+
};
|
|
38
|
+
if (tone >= 100) return {
|
|
39
|
+
colorSpace: "oklch",
|
|
40
|
+
components: [
|
|
41
|
+
1,
|
|
42
|
+
0,
|
|
43
|
+
hue
|
|
44
|
+
]
|
|
45
|
+
};
|
|
46
|
+
const r = hue * Math.PI / 180;
|
|
47
|
+
const cos = Math.cos(r);
|
|
48
|
+
const sin = Math.sin(r);
|
|
49
|
+
const lab = (l, c) => ({
|
|
50
|
+
colorSpace: "oklab",
|
|
51
|
+
components: [
|
|
52
|
+
l,
|
|
53
|
+
c * cos,
|
|
54
|
+
c * sin
|
|
55
|
+
]
|
|
56
|
+
});
|
|
57
|
+
const chromaAt = (l) => {
|
|
58
|
+
if (require_parse.inGamut(lab(l, chroma), gamut)) return chroma;
|
|
59
|
+
let [lo, hi] = [0, chroma];
|
|
60
|
+
for (let i = 0; i < 24; i++) {
|
|
61
|
+
const mid = (lo + hi) / 2;
|
|
62
|
+
if (require_parse.inGamut(lab(l, mid), gamut)) lo = mid;
|
|
63
|
+
else hi = mid;
|
|
64
|
+
}
|
|
65
|
+
return lo;
|
|
66
|
+
};
|
|
67
|
+
let lo = 0;
|
|
68
|
+
let hi = 1;
|
|
69
|
+
for (let i = 0; i < 40; i++) {
|
|
70
|
+
const mid = (lo + hi) / 2;
|
|
71
|
+
if (lstar(lab(mid, chromaAt(mid))) < tone) lo = mid;
|
|
72
|
+
else hi = mid;
|
|
73
|
+
}
|
|
74
|
+
const l = (lo + hi) / 2;
|
|
75
|
+
return {
|
|
76
|
+
colorSpace: "oklch",
|
|
77
|
+
components: [
|
|
78
|
+
l,
|
|
79
|
+
chromaAt(l),
|
|
80
|
+
hue
|
|
81
|
+
]
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* A tonal palette, as in Material: one OKLCH hue and chroma held across L*
|
|
86
|
+
* tones. Two colors whose tones differ by 40 or more reach WCAG 2 contrast 3,
|
|
87
|
+
* and by 50 or more about 4.5 (4.48 at the worst pair, 100 against 50), so a
|
|
88
|
+
* pair can be picked by tone alone. Default tones are Material's 13.
|
|
89
|
+
*/
|
|
90
|
+
function tonalPalette(hue, chroma, tones = MATERIAL_TONES, options = {}) {
|
|
91
|
+
return tones.map((t) => toneColor(t, chroma, hue, options.gamut));
|
|
92
|
+
}
|
|
93
|
+
Object.defineProperty(exports, "MATERIAL_TONES", {
|
|
94
|
+
enumerable: true,
|
|
95
|
+
get: function() {
|
|
96
|
+
return MATERIAL_TONES;
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
Object.defineProperty(exports, "lstar", {
|
|
100
|
+
enumerable: true,
|
|
101
|
+
get: function() {
|
|
102
|
+
return lstar;
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
Object.defineProperty(exports, "tonalPalette", {
|
|
106
|
+
enumerable: true,
|
|
107
|
+
get: function() {
|
|
108
|
+
return tonalPalette;
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
Object.defineProperty(exports, "toneColor", {
|
|
112
|
+
enumerable: true,
|
|
113
|
+
get: function() {
|
|
114
|
+
return toneColor;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
//# sourceMappingURL=tone-BAhu-QzQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tone-BAhu-QzQ.js","names":["componentsIn","inGamut"],"sources":["../src/scale/tone.ts"],"sourcesContent":["import { type GamutId, inGamut } from '../color/gamut.js'\nimport { componentsIn } from '../color/spaces.js'\nimport type { Color } from '../color/types.js'\n\n/** CIE L* (0 to 100) of a color: its relative luminance on the CIELAB lightness curve. */\nexport function lstar(color: Color): number {\n\tconst y = Math.max(0, componentsIn(color, 'xyz-d65')[1] as number)\n\treturn y > 216 / 24389 ? 116 * Math.cbrt(y) - 16 : (24389 / 27) * y\n}\n\n/** Material's tones: 0 is black, 100 is white. */\nexport const MATERIAL_TONES: readonly number[] = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 95, 99, 100]\n\n/** Options for `tonalPalette`. */\nexport interface TonalPaletteOptions {\n\t/** The gamut the colors must fit. Default `srgb`. */\n\tgamut?: GamutId\n}\n\n/**\n * The color at CIE L* `tone` with the given OKLCH hue and chroma, mapped into\n * the gamut. OKLCH lightness is searched until the *mapped* color lands on\n * `tone`, so chroma tapers where the gamut narrows and the tone stays true.\n */\nexport function toneColor(tone: number, chroma: number, hue: number, gamut: GamutId = 'srgb'): Color {\n\tif (tone <= 0) return { colorSpace: 'oklch', components: [0, 0, hue] }\n\tif (tone >= 100) return { colorSpace: 'oklch', components: [1, 0, hue] }\n\t// The hue is fixed, so its cosine and sine are taken once: OKLCH converts by\n\t// way of OKLab with exactly these products, so the results are the same.\n\tconst r = (hue * Math.PI) / 180\n\tconst cos = Math.cos(r)\n\tconst sin = Math.sin(r)\n\tconst lab = (l: number, c: number): Color => ({ colorSpace: 'oklab', components: [l, c * cos, c * sin] })\n\t// The most chroma, up to `chroma`, that fits at this lightness; no clipping, so L* is monotone in L.\n\tconst chromaAt = (l: number): number => {\n\t\tif (inGamut(lab(l, chroma), gamut)) return chroma\n\t\tlet [lo, hi] = [0, chroma]\n\t\tfor (let i = 0; i < 24; i++) {\n\t\t\tconst mid = (lo + hi) / 2\n\t\t\tif (inGamut(lab(l, mid), gamut)) lo = mid\n\t\t\telse hi = mid\n\t\t}\n\t\treturn lo\n\t}\n\tlet lo = 0\n\tlet hi = 1\n\tfor (let i = 0; i < 40; i++) {\n\t\tconst mid = (lo + hi) / 2\n\t\tif (lstar(lab(mid, chromaAt(mid))) < tone) lo = mid\n\t\telse hi = mid\n\t}\n\tconst l = (lo + hi) / 2\n\treturn { colorSpace: 'oklch', components: [l, chromaAt(l), hue] }\n}\n\n/**\n * A tonal palette, as in Material: one OKLCH hue and chroma held across L*\n * tones. Two colors whose tones differ by 40 or more reach WCAG 2 contrast 3,\n * and by 50 or more about 4.5 (4.48 at the worst pair, 100 against 50), so a\n * pair can be picked by tone alone. Default tones are Material's 13.\n */\nexport function tonalPalette(\n\thue: number,\n\tchroma: number,\n\ttones: readonly number[] = MATERIAL_TONES,\n\toptions: TonalPaletteOptions = {}\n): Color[] {\n\treturn tones.map((t) => toneColor(t, chroma, hue, options.gamut))\n}\n"],"mappings":";;;AAKA,SAAgB,MAAM,OAAsB;CAC3C,MAAM,IAAI,KAAK,IAAI,GAAGA,cAAAA,aAAa,OAAO,SAAS,CAAC,CAAC,EAAY;CACjE,OAAO,IAAI,MAAM,QAAQ,MAAM,KAAK,KAAK,CAAC,IAAI,KAAM,QAAQ,KAAM;AACnE;;AAGA,MAAa,iBAAoC;CAAC;CAAG;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;AAAG;;;;;;AAapG,SAAgB,UAAU,MAAc,QAAgB,KAAa,QAAiB,QAAe;CACpG,IAAI,QAAQ,GAAG,OAAO;EAAE,YAAY;EAAS,YAAY;GAAC;GAAG;GAAG;EAAG;CAAE;CACrE,IAAI,QAAQ,KAAK,OAAO;EAAE,YAAY;EAAS,YAAY;GAAC;GAAG;GAAG;EAAG;CAAE;CAGvE,MAAM,IAAK,MAAM,KAAK,KAAM;CAC5B,MAAM,MAAM,KAAK,IAAI,CAAC;CACtB,MAAM,MAAM,KAAK,IAAI,CAAC;CACtB,MAAM,OAAO,GAAW,OAAsB;EAAE,YAAY;EAAS,YAAY;GAAC;GAAG,IAAI;GAAK,IAAI;EAAG;CAAE;CAEvG,MAAM,YAAY,MAAsB;EACvC,IAAIC,cAAAA,QAAQ,IAAI,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO;EAC3C,IAAI,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM;EACzB,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK;GAC5B,MAAM,OAAO,KAAK,MAAM;GACxB,IAAIA,cAAAA,QAAQ,IAAI,GAAG,GAAG,GAAG,KAAK,GAAG,KAAK;QACjC,KAAK;EACX;EACA,OAAO;CACR;CACA,IAAI,KAAK;CACT,IAAI,KAAK;CACT,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK;EAC5B,MAAM,OAAO,KAAK,MAAM;EACxB,IAAI,MAAM,IAAI,KAAK,SAAS,GAAG,CAAC,CAAC,IAAI,MAAM,KAAK;OAC3C,KAAK;CACX;CACA,MAAM,KAAK,KAAK,MAAM;CACtB,OAAO;EAAE,YAAY;EAAS,YAAY;GAAC;GAAG,SAAS,CAAC;GAAG;EAAG;CAAE;AACjE;;;;;;;AAQA,SAAgB,aACf,KACA,QACA,QAA2B,gBAC3B,UAA+B,CAAC,GACtB;CACV,OAAO,MAAM,KAAK,MAAM,UAAU,GAAG,QAAQ,KAAK,QAAQ,KAAK,CAAC;AACjE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"color-map.es5.js","names":[],"sources":["../
|
|
1
|
+
{"version":3,"file":"color-map.es5.js","names":["exports","createColors","from","to","start","diff","alpha","inc","shades","rgba","i","color","createColorsFromMap","colormap","result","steps","n","rgbaString","rgbHex","hex","d2h","rgb","s","d"],"sources":["../src/legacy/createColors.ts","../src/legacy/createColorsFromMap.ts","../src/legacy/rgbaString.ts","../src/legacy/rgbHex.ts"],"sourcesContent":["import type { Alpha, RGB, RGBA } from './interfaces.js'\n\n/**\n * Creates `shades` colors that step evenly from `from` to `to`. Red, green and\n * blue are rounded to whole numbers. Without `alpha`, the alpha of each end\n * comes from its own fourth value, then from the other end, then is 1.\n * Every result is an `RGBA`.\n */\nexport function createColors(\n\tfrom: RGB | RGBA,\n\tto: RGB | RGBA,\n\tshades: number,\n\talpha: Alpha = [\n\t\tfrom.length === 4 ? from[3] : to.length === 4 ? to[3] : 1,\n\t\tto.length === 4 ? to[3] : from.length === 4 ? from[3] : 1\n\t]\n): RGBA[] {\n\tconst start = [...from]\n\tconst diff = [to[0] - from[0], to[1] - from[1], to[2] - from[2], alpha[1] - alpha[0]]\n\n\tif (start.length === 3) start.push(alpha[0])\n\n\tconst inc = 1 / Math.max(shades - 1, 1)\n\n\tconst rgba: any[] = []\n\tfor (let i = 0; i < shades; i++) {\n\t\tconst color = [\n\t\t\tMath.round(start[0] + i * diff[0] * inc),\n\t\t\tMath.round(start[1] + i * diff[1] * inc),\n\t\t\tMath.round(start[2] + i * diff[2] * inc),\n\t\t\tstart[3] + i * diff[3] * inc\n\t\t]\n\t\trgba.push(color)\n\t}\n\treturn rgba\n}\n","import { createColors } from './createColors.js'\nimport type { Alpha, ColorMap, RGBA } from './interfaces.js'\n\n/**\n * Create colors with specified color map.\n *\n * @deprecated Use `createGradient` from `color-map`. Each of its stops\n * carries its own alpha, and `{ in: 'srgb' }` comes close to these results.\n */\nexport function createColorsFromMap(colormap: ColorMap, shades: number, alpha?: Alpha): RGBA[] {\n\tif (shades < colormap.length) {\n\t\tthrow new Error(`Requires at least ${colormap.length} shades.`)\n\t}\n\n\tconst result: RGBA[] = []\n\tconst steps: number[] = []\n\tfor (let i = 0; i < colormap.length; i++) {\n\t\tsteps.push(Math.round(colormap[i].index * shades))\n\t}\n\n\tfor (let i = 0; i < colormap.length - 1; i++) {\n\t\tconst n = steps[i + 1] - steps[i]\n\t\tconst from = colormap[i].rgb\n\t\tconst to = colormap[i + 1].rgb\n\t\tresult.push(...createColors(from, to, n, alpha))\n\t}\n\n\treturn result\n}\n","import type { RGBA } from './interfaces.js'\n\n/** Formats an `RGBA` as a CSS `rgba(r,g,b,a)` string, with no spaces. */\nexport function rgbaString(rgba: RGBA) {\n\treturn 'rgba(' + rgba.join(',') + ')'\n}\n","import type { RGB, RGBA } from './interfaces.js'\n\n/**\n * Convert `RGB` to `#rgb`\n * JavaScript note: no check for array length, use it properly.\n */\nexport function rgbHex(rgb: RGB | RGBA) {\n\tlet hex = '#'\n\tfor (let i = 0; i < 3; i++) {\n\t\thex += d2h(rgb[i])\n\t}\n\treturn hex\n}\n\nfunction d2h(d: number) {\n\tconst s = (+d).toString(16)\n\treturn s.length < 2 ? '0' + s : s\n}\n"],"mappings":"A,uFAQA,SAAgBC,EACf,EACA,EACA,EACA,EAAe,CACdC,EAAK,SAAW,EAAIA,EAAK,GAAKC,EAAG,SAAW,EAAIA,EAAG,GAAK,EACxDA,EAAG,SAAW,EAAIA,EAAG,GAAKD,EAAK,SAAW,EAAIA,EAAK,GAAK,CACzD,EACS,CACT,IAAME,EAAQ,CAAC,GAAGF,CAAI,EAChBG,EAAO,CAACF,EAAG,GAAKD,EAAK,GAAIC,EAAG,GAAKD,EAAK,GAAIC,EAAG,GAAKD,EAAK,GAAII,EAAM,GAAKA,EAAM,EAAE,EAEhFF,EAAM,SAAW,GAAGA,EAAM,KAAKE,EAAM,EAAE,EAE3C,IAAMC,EAAM,EAAI,KAAK,IAAIC,EAAS,EAAG,CAAC,EAEhCC,EAAc,CAAC,EACrB,IAAK,IAAIC,EAAI,EAAGA,EAAIF,EAAQ,IAAK,CAChC,IAAMG,EAAQ,CACb,KAAK,MAAMP,EAAM,GAAKM,EAAIL,EAAK,GAAKE,CAAG,EACvC,KAAK,MAAMH,EAAM,GAAKM,EAAIL,EAAK,GAAKE,CAAG,EACvC,KAAK,MAAMH,EAAM,GAAKM,EAAIL,EAAK,GAAKE,CAAG,EACvCH,EAAM,GAAKM,EAAIL,EAAK,GAAKE,CAC1B,EACAE,EAAK,KAAKE,CAAK,CAChB,CACA,OAAOF,CACR,CC1BA,SAAgBG,EAAoB,EAAoB,EAAgB,EAAuB,CAC9F,GAAIJ,EAASK,EAAS,OACrB,MAAU,MAAM,qBAAqBA,EAAS,OAAO,SAAS,EAG/D,IAAMC,EAAiB,CAAC,EAClBC,EAAkB,CAAC,EACzB,IAAK,IAAIL,EAAI,EAAGA,EAAIG,EAAS,OAAQ,IACpCE,EAAM,KAAK,KAAK,MAAMF,EAASH,EAAE,CAAC,MAAQF,CAAM,CAAC,EAGlD,IAAK,IAAIE,EAAI,EAAGA,EAAIG,EAAS,OAAS,EAAG,IAAK,CAC7C,IAAMG,EAAID,EAAML,EAAI,GAAKK,EAAML,GACzBR,EAAOW,EAASH,EAAE,CAAC,IACnBP,EAAKU,EAASH,EAAI,EAAE,CAAC,IAC3BI,EAAO,KAAK,GAAGb,EAAaC,EAAMC,EAAIa,EAAGV,CAAK,CAAC,CAChD,CAEA,OAAOQ,CACR,CCzBA,SAAgBG,EAAW,EAAY,CACtC,MAAO,QAAUR,EAAK,KAAK,GAAG,EAAI,GACnC,CCCA,SAAgBS,EAAO,EAAiB,CACvC,IAAIC,EAAM,IACV,IAAK,IAAIT,EAAI,EAAGA,EAAI,EAAG,IACtB,GAAOU,EAAIC,EAAIX,EAAE,EAElB,OAAOS,CACR,CAEA,SAASC,EAAI,EAAW,CACvB,IAAME,GAAK,CAACC,EAAA,CAAG,SAAS,EAAE,EAC1B,OAAOD,EAAE,OAAS,EAAI,IAAMA,EAAIA,CACjC,C"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Space } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The CSS `a98-rgb` space (Adobe RGB 1998). Components are red, green and blue in 0 to 1, with a 563/256 power transfer curve.
|
|
4
|
+
* Pass it to `createConverter` and to the narrow helpers such as `createMix` and `createToGamut`.
|
|
5
|
+
*/
|
|
6
|
+
export declare const a98Rgb: Space;
|
|
7
|
+
//# sourceMappingURL=a98-rgb.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a98-rgb.d.ts","names":["_$__types_js0.Space"],"sources":["../../src/color/a98-rgb.ts"],"mappings":";;;;;qBAUa,QAAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { a98ToXyz, xyzToA98 } from "./matrices.js";
|
|
2
|
+
import { rgbSpace } from "./rgb.js";
|
|
3
|
+
import { power } from "./transfer.js";
|
|
4
|
+
// src/color/a98-rgb.ts
|
|
5
|
+
const [toLinear, toGamma] = power(563 / 256);
|
|
6
|
+
/**
|
|
7
|
+
* The CSS `a98-rgb` space (Adobe RGB 1998). Components are red, green and blue in 0 to 1, with a 563/256 power transfer curve.
|
|
8
|
+
* Pass it to `createConverter` and to the narrow helpers such as `createMix` and `createToGamut`.
|
|
9
|
+
*/
|
|
10
|
+
const a98Rgb = rgbSpace("a98-rgb", toLinear, toGamma, a98ToXyz, xyzToA98);
|
|
11
|
+
export { a98Rgb };
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=a98-rgb.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a98-rgb.js","names":[],"sources":["../../src/color/a98-rgb.ts"],"sourcesContent":["import { a98ToXyz, xyzToA98 } from './matrices.js'\nimport { rgbSpace } from './rgb.js'\nimport { power } from './transfer.js'\n\nconst [toLinear, toGamma] = power(563 / 256)\n\n/**\n * The CSS `a98-rgb` space (Adobe RGB 1998). Components are red, green and blue in 0 to 1, with a 563/256 power transfer curve.\n * Pass it to `createConverter` and to the narrow helpers such as `createMix` and `createToGamut`.\n */\nexport const a98Rgb = rgbSpace('a98-rgb', toLinear, toGamma, a98ToXyz, xyzToA98)\n"],"mappings":";;;;AAIA,MAAM,CAAC,UAAU,WAAW,MAAM,MAAM,GAAG;;;;;AAM3C,MAAa,SAAS,SAAS,WAAW,UAAU,SAAS,UAAU,QAAQ"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Color } from "./types.js";
|
|
2
|
+
/** An sRGB color from a 32-bit ARGB integer, as Material Color Utilities uses. */
|
|
3
|
+
export declare function fromArgb(argb: number): Color;
|
|
4
|
+
/** The unsigned 32-bit ARGB integer for an sRGB color. Convert other spaces to `srgb` first. */
|
|
5
|
+
export declare function toArgb(color: Color): number;
|
|
6
|
+
//# sourceMappingURL=argb.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"argb.d.ts","names":[],"sources":["../../src/color/argb.ts"],"mappings":";;wBAKgB,SAAS,eAAe;;wBAUxB,OAAO,OAAO"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// src/color/argb.ts
|
|
2
|
+
const byte = (n) => Math.min(255, Math.max(0, Math.round(n * 255)));
|
|
3
|
+
/** An sRGB color from a 32-bit ARGB integer, as Material Color Utilities uses. */
|
|
4
|
+
function fromArgb(argb) {
|
|
5
|
+
const n = argb >>> 0;
|
|
6
|
+
return {
|
|
7
|
+
colorSpace: "srgb",
|
|
8
|
+
components: [
|
|
9
|
+
(n >>> 16 & 255) / 255,
|
|
10
|
+
(n >>> 8 & 255) / 255,
|
|
11
|
+
(n & 255) / 255
|
|
12
|
+
],
|
|
13
|
+
alpha: (n >>> 24) / 255
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/** The unsigned 32-bit ARGB integer for an sRGB color. Convert other spaces to `srgb` first. */
|
|
17
|
+
function toArgb(color) {
|
|
18
|
+
if (color.colorSpace !== "srgb") throw new Error(`color-map: toArgb needs an srgb color, got "${color.colorSpace}"`);
|
|
19
|
+
const [r, g, b] = color.components;
|
|
20
|
+
const a = color.alpha ?? 1;
|
|
21
|
+
return (byte(a) << 24 | byte(r ?? 0) << 16 | byte(g ?? 0) << 8 | byte(b ?? 0)) >>> 0;
|
|
22
|
+
}
|
|
23
|
+
export { fromArgb, toArgb };
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=argb.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"argb.js","names":[],"sources":["../../src/color/argb.ts"],"sourcesContent":["import type { Color } from './types.js'\n\nconst byte = (n: number): number => Math.min(255, Math.max(0, Math.round(n * 255)))\n\n/** An sRGB color from a 32-bit ARGB integer, as Material Color Utilities uses. */\nexport function fromArgb(argb: number): Color {\n\tconst n = argb >>> 0\n\treturn {\n\t\tcolorSpace: 'srgb',\n\t\tcomponents: [((n >>> 16) & 255) / 255, ((n >>> 8) & 255) / 255, (n & 255) / 255],\n\t\talpha: (n >>> 24) / 255\n\t}\n}\n\n/** The unsigned 32-bit ARGB integer for an sRGB color. Convert other spaces to `srgb` first. */\nexport function toArgb(color: Color): number {\n\tif (color.colorSpace !== 'srgb') throw new Error(`color-map: toArgb needs an srgb color, got \"${color.colorSpace}\"`)\n\tconst [r, g, b] = color.components\n\tconst a = color.alpha ?? 1\n\treturn ((byte(a) << 24) | (byte(r ?? 0) << 16) | (byte(g ?? 0) << 8) | byte(b ?? 0)) >>> 0\n}\n"],"mappings":";AAEA,MAAM,QAAQ,MAAsB,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,CAAC,CAAC;;AAGlF,SAAgB,SAAS,MAAqB;CAC7C,MAAM,IAAI,SAAS;CACnB,OAAO;EACN,YAAY;EACZ,YAAY;IAAG,MAAM,KAAM,OAAO;IAAO,MAAM,IAAK,OAAO;IAAM,IAAI,OAAO;EAAG;EAC/E,QAAQ,MAAM,MAAM;CACrB;AACD;;AAGA,SAAgB,OAAO,OAAsB;CAC5C,IAAI,MAAM,eAAe,QAAQ,MAAM,IAAI,MAAM,+CAA+C,MAAM,WAAW,EAAE;CACnH,MAAM,CAAC,GAAG,GAAG,KAAK,MAAM;CACxB,MAAM,IAAI,MAAM,SAAS;CACzB,QAAS,KAAK,CAAC,KAAK,KAAO,KAAK,KAAK,CAAC,KAAK,KAAO,KAAK,KAAK,CAAC,KAAK,IAAK,KAAK,KAAK,CAAC,OAAO;AAC1F"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { UNITS, fail } from "./parse.js";
|
|
2
|
+
// src/color/calc.ts
|
|
3
|
+
const TOKEN = /\s*(?:(\d*\.?\d+(?:e[+-]?\d+)?)([a-z%]*)|([a-z][a-z0-9-]*)|([-+*/(),]))/y;
|
|
4
|
+
/**
|
|
5
|
+
* Evaluates the `calc()` subset relative colors accept: numbers (angles become
|
|
6
|
+
* degrees), `+ - * /`, parentheses, `calc`, `min`, `max`, `clamp`, the
|
|
7
|
+
* constants `pi` and `e`, and the channel keywords in `vars`.
|
|
8
|
+
*/
|
|
9
|
+
function evaluate(text, vars) {
|
|
10
|
+
const tokens = [];
|
|
11
|
+
TOKEN.lastIndex = 0;
|
|
12
|
+
let end = 0;
|
|
13
|
+
for (let m = TOKEN.exec(text); m; m = TOKEN.exec(text)) {
|
|
14
|
+
end = TOKEN.lastIndex;
|
|
15
|
+
if (m[1] === void 0) tokens.push(m[3] ?? m[4]);
|
|
16
|
+
else {
|
|
17
|
+
const unit = UNITS[m[2]];
|
|
18
|
+
if (unit === void 0) return fail(text, "units other than angles are not supported in calc()", m[1] + m[2]);
|
|
19
|
+
tokens.push(String(Number(m[1]) * unit));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (end !== text.trimEnd().length) return fail(text, "invalid calc() expression");
|
|
23
|
+
let pos = 0;
|
|
24
|
+
const next = () => tokens[pos++];
|
|
25
|
+
const eat = (t) => tokens[pos] === t ? ++pos > 0 : false;
|
|
26
|
+
const need = (t) => {
|
|
27
|
+
if (!eat(t)) fail(text, `expected "${t}" in calc()`, tokens[pos]);
|
|
28
|
+
};
|
|
29
|
+
function sum() {
|
|
30
|
+
let v = product();
|
|
31
|
+
for (;;) if (eat("+")) v += product();
|
|
32
|
+
else if (eat("-")) v -= product();
|
|
33
|
+
else return v;
|
|
34
|
+
}
|
|
35
|
+
function product() {
|
|
36
|
+
let v = unary();
|
|
37
|
+
for (;;) if (eat("*")) v *= unary();
|
|
38
|
+
else if (eat("/")) v /= unary();
|
|
39
|
+
else return v;
|
|
40
|
+
}
|
|
41
|
+
function unary() {
|
|
42
|
+
if (eat("-")) return -unary();
|
|
43
|
+
if (eat("+")) return unary();
|
|
44
|
+
return atom();
|
|
45
|
+
}
|
|
46
|
+
function args() {
|
|
47
|
+
const list = [sum()];
|
|
48
|
+
while (eat(",")) list.push(sum());
|
|
49
|
+
need(")");
|
|
50
|
+
return list;
|
|
51
|
+
}
|
|
52
|
+
function atom() {
|
|
53
|
+
const t = next();
|
|
54
|
+
if (t === void 0) return fail(text, "unfinished calc() expression");
|
|
55
|
+
if (/^[\d.]/.test(t)) return Number(t);
|
|
56
|
+
if (t === "(") {
|
|
57
|
+
const v = sum();
|
|
58
|
+
need(")");
|
|
59
|
+
return v;
|
|
60
|
+
}
|
|
61
|
+
if (!/^[a-z]/.test(t)) return fail(text, "unexpected token", t);
|
|
62
|
+
if (eat("(")) {
|
|
63
|
+
const list = args();
|
|
64
|
+
if (t === "calc" && list.length === 1) return list[0];
|
|
65
|
+
if (t === "min") return Math.min(...list);
|
|
66
|
+
if (t === "max") return Math.max(...list);
|
|
67
|
+
if (t === "clamp" && list.length === 3) return Math.min(list[2], Math.max(list[0], list[1]));
|
|
68
|
+
return fail(text, "unknown function", t);
|
|
69
|
+
}
|
|
70
|
+
if (t === "pi") return Math.PI;
|
|
71
|
+
if (t === "e") return Math.E;
|
|
72
|
+
const v = vars[t];
|
|
73
|
+
if (typeof v === "number") return v;
|
|
74
|
+
return fail(text, "unknown keyword", t);
|
|
75
|
+
}
|
|
76
|
+
const value = sum();
|
|
77
|
+
if (pos < tokens.length) return fail(text, "unexpected token", tokens[pos]);
|
|
78
|
+
return value;
|
|
79
|
+
}
|
|
80
|
+
export { evaluate };
|
|
81
|
+
|
|
82
|
+
//# sourceMappingURL=calc.js.map
|