color-map 2.1.0 → 2.3.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/.claude-plugin/plugin.json +12 -0
- package/.codex-plugin/plugin.json +12 -0
- package/.cursor-plugin/plugin.json +12 -0
- package/CHANGELOG.md +94 -0
- package/README.md +71 -11
- package/bin/cli-CNBftDBE.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 +27 -5
- package/cjs/index.d.ts.map +1 -0
- package/cjs/index.js +89 -20
- 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/package.json +1 -1
- 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 +1 -1
- 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 -5
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +53 -4
- package/esm/index.js.map +1 -1
- package/esm/legacy/createColors.d.ts +9 -0
- package/esm/legacy/createColors.d.ts.map +1 -0
- package/esm/legacy/createColors.js +32 -0
- 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/legacy/createColorsFromMap.js +24 -0
- 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} +2 -1
- package/esm/legacy/rgbHex.d.ts.map +1 -0
- package/esm/legacy/rgbHex.js +17 -0
- package/esm/legacy/rgbHex.js.map +1 -0
- package/esm/legacy/rgbaString.d.ts +4 -0
- package/esm/legacy/rgbaString.d.ts.map +1 -0
- 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 +29 -0
- package/package.json +240 -56
- 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 +2 -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/src/legacy/createColors.ts +36 -0
- package/src/legacy/createColorsFromMap.ts +29 -0
- package/src/legacy/interfaces.ts +19 -0
- package/{ts → src/legacy}/rgbHex.ts +7 -7
- package/src/legacy/rgbaString.ts +6 -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/cjs/createColors.d.ts +0 -2
- package/cjs/createColors.js +0 -40
- package/cjs/createColors.js.map +0 -1
- package/cjs/createColors.spec.d.ts +0 -1
- package/cjs/createColors.spec.js +0 -176
- package/cjs/createColors.spec.js.map +0 -1
- package/cjs/createColorsFromMap.d.ts +0 -5
- package/cjs/createColorsFromMap.js +0 -25
- package/cjs/createColorsFromMap.js.map +0 -1
- package/cjs/createColorsFromMap.spec.d.ts +0 -1
- package/cjs/createColorsFromMap.spec.js +0 -11
- package/cjs/createColorsFromMap.spec.js.map +0 -1
- package/cjs/interfaces.d.ts +0 -14
- package/cjs/interfaces.js +0 -3
- package/cjs/interfaces.js.map +0 -1
- package/cjs/rgbHex.d.ts +0 -6
- package/cjs/rgbHex.js +0 -19
- package/cjs/rgbHex.js.map +0 -1
- package/cjs/rgbHex.spec.d.ts +0 -1
- package/cjs/rgbHex.spec.js +0 -16
- package/cjs/rgbHex.spec.js.map +0 -1
- package/cjs/rgbaString.d.ts +0 -2
- package/cjs/rgbaString.js +0 -7
- package/cjs/rgbaString.js.map +0 -1
- package/cjs/rgbaString.spec.d.ts +0 -1
- package/cjs/rgbaString.spec.js +0 -10
- package/cjs/rgbaString.spec.js.map +0 -1
- package/esm/createColors.d.ts +0 -2
- package/esm/createColors.js +0 -27
- package/esm/createColors.js.map +0 -1
- package/esm/createColors.spec.d.ts +0 -1
- package/esm/createColors.spec.js +0 -171
- package/esm/createColors.spec.js.map +0 -1
- package/esm/createColorsFromMap.d.ts +0 -5
- package/esm/createColorsFromMap.js +0 -22
- package/esm/createColorsFromMap.js.map +0 -1
- package/esm/createColorsFromMap.spec.d.ts +0 -1
- package/esm/createColorsFromMap.spec.js +0 -9
- package/esm/createColorsFromMap.spec.js.map +0 -1
- package/esm/interfaces.d.ts +0 -14
- package/esm/interfaces.js +0 -2
- package/esm/interfaces.js.map +0 -1
- package/esm/rgbHex.js +0 -16
- package/esm/rgbHex.js.map +0 -1
- package/esm/rgbHex.spec.d.ts +0 -1
- package/esm/rgbHex.spec.js +0 -14
- package/esm/rgbHex.spec.js.map +0 -1
- package/esm/rgbaString.d.ts +0 -2
- package/esm/rgbaString.js +0 -4
- package/esm/rgbaString.js.map +0 -1
- package/esm/rgbaString.spec.d.ts +0 -1
- package/esm/rgbaString.spec.js +0 -8
- package/esm/rgbaString.spec.js.map +0 -1
- package/ts/createColors.ts +0 -35
- package/ts/createColorsFromMap.ts +0 -26
- package/ts/interfaces.ts +0 -15
- package/ts/rgbaString.ts +0 -5
- package/{ts → src/legacy}/index.ts +1 -1
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
// src/legacy/createColors.ts
|
|
3
|
+
/**
|
|
4
|
+
* Creates `shades` colors that step evenly from `from` to `to`. Red, green and
|
|
5
|
+
* blue are rounded to whole numbers. Without `alpha`, the alpha of each end
|
|
6
|
+
* comes from its own fourth value, then from the other end, then is 1.
|
|
7
|
+
* Every result is an `RGBA`.
|
|
8
|
+
*/
|
|
9
|
+
function createColors(from, to, shades, alpha = [from.length === 4 ? from[3] : to.length === 4 ? to[3] : 1, to.length === 4 ? to[3] : from.length === 4 ? from[3] : 1]) {
|
|
10
|
+
const start = [...from];
|
|
11
|
+
const diff = [
|
|
12
|
+
to[0] - from[0],
|
|
13
|
+
to[1] - from[1],
|
|
14
|
+
to[2] - from[2],
|
|
15
|
+
alpha[1] - alpha[0]
|
|
16
|
+
];
|
|
17
|
+
if (start.length === 3) start.push(alpha[0]);
|
|
18
|
+
const inc = 1 / Math.max(shades - 1, 1);
|
|
19
|
+
const rgba = [];
|
|
20
|
+
for (let i = 0; i < shades; i++) {
|
|
21
|
+
const color = [
|
|
22
|
+
Math.round(start[0] + i * diff[0] * inc),
|
|
23
|
+
Math.round(start[1] + i * diff[1] * inc),
|
|
24
|
+
Math.round(start[2] + i * diff[2] * inc),
|
|
25
|
+
start[3] + i * diff[3] * inc
|
|
26
|
+
];
|
|
27
|
+
rgba.push(color);
|
|
28
|
+
}
|
|
29
|
+
return rgba;
|
|
30
|
+
}
|
|
31
|
+
// src/legacy/createColorsFromMap.ts
|
|
32
|
+
/**
|
|
33
|
+
* Create colors with specified color map.
|
|
34
|
+
*
|
|
35
|
+
* @deprecated Use `createGradient` from `color-map`. Each of its stops
|
|
36
|
+
* carries its own alpha, and `{ in: 'srgb' }` comes close to these results.
|
|
37
|
+
*/
|
|
38
|
+
function createColorsFromMap(colormap, shades, alpha) {
|
|
39
|
+
if (shades < colormap.length) throw new Error(`Requires at least ${colormap.length} shades.`);
|
|
40
|
+
const result = [];
|
|
41
|
+
const steps = [];
|
|
42
|
+
for (let i = 0; i < colormap.length; i++) steps.push(Math.round(colormap[i].index * shades));
|
|
43
|
+
for (let i = 0; i < colormap.length - 1; i++) {
|
|
44
|
+
const n = steps[i + 1] - steps[i];
|
|
45
|
+
const from = colormap[i].rgb;
|
|
46
|
+
const to = colormap[i + 1].rgb;
|
|
47
|
+
result.push(...createColors(from, to, n, alpha));
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
// src/legacy/rgbaString.ts
|
|
52
|
+
/** Formats an `RGBA` as a CSS `rgba(r,g,b,a)` string, with no spaces. */
|
|
53
|
+
function rgbaString(rgba) {
|
|
54
|
+
return "rgba(" + rgba.join(",") + ")";
|
|
55
|
+
}
|
|
56
|
+
// src/legacy/rgbHex.ts
|
|
57
|
+
/**
|
|
58
|
+
* Convert `RGB` to `#rgb`
|
|
59
|
+
* JavaScript note: no check for array length, use it properly.
|
|
60
|
+
*/
|
|
61
|
+
function rgbHex(rgb) {
|
|
62
|
+
let hex = "#";
|
|
63
|
+
for (let i = 0; i < 3; i++) hex += d2h(rgb[i]);
|
|
64
|
+
return hex;
|
|
65
|
+
}
|
|
66
|
+
function d2h(d) {
|
|
67
|
+
const s = (+d).toString(16);
|
|
68
|
+
return s.length < 2 ? "0" + s : s;
|
|
69
|
+
}
|
|
70
|
+
exports.createColors = createColors;
|
|
71
|
+
exports.createColorsFromMap = createColorsFromMap;
|
|
72
|
+
exports.rgbHex = rgbHex;
|
|
73
|
+
exports.rgbaString = rgbaString;
|
|
74
|
+
|
|
75
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"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":";;;;;;;;AAQA,SAAgB,aACf,MACA,IACA,QACA,QAAe,CACd,KAAK,WAAW,IAAI,KAAK,KAAK,GAAG,WAAW,IAAI,GAAG,KAAK,GACxD,GAAG,WAAW,IAAI,GAAG,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,CACzD,GACS;CACT,MAAM,QAAQ,CAAC,GAAG,IAAI;CACtB,MAAM,OAAO;EAAC,GAAG,KAAK,KAAK;EAAI,GAAG,KAAK,KAAK;EAAI,GAAG,KAAK,KAAK;EAAI,MAAM,KAAK,MAAM;CAAE;CAEpF,IAAI,MAAM,WAAW,GAAG,MAAM,KAAK,MAAM,EAAE;CAE3C,MAAM,MAAM,IAAI,KAAK,IAAI,SAAS,GAAG,CAAC;CAEtC,MAAM,OAAc,CAAC;CACrB,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK;EAChC,MAAM,QAAQ;GACb,KAAK,MAAM,MAAM,KAAK,IAAI,KAAK,KAAK,GAAG;GACvC,KAAK,MAAM,MAAM,KAAK,IAAI,KAAK,KAAK,GAAG;GACvC,KAAK,MAAM,MAAM,KAAK,IAAI,KAAK,KAAK,GAAG;GACvC,MAAM,KAAK,IAAI,KAAK,KAAK;EAC1B;EACA,KAAK,KAAK,KAAK;CAChB;CACA,OAAO;AACR;;;;;;;;AC1BA,SAAgB,oBAAoB,UAAoB,QAAgB,OAAuB;CAC9F,IAAI,SAAS,SAAS,QACrB,MAAM,IAAI,MAAM,qBAAqB,SAAS,OAAO,SAAS;CAG/D,MAAM,SAAiB,CAAC;CACxB,MAAM,QAAkB,CAAC;CACzB,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KACpC,MAAM,KAAK,KAAK,MAAM,SAAS,EAAE,CAAC,QAAQ,MAAM,CAAC;CAGlD,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,SAAS,GAAG,KAAK;EAC7C,MAAM,IAAI,MAAM,IAAI,KAAK,MAAM;EAC/B,MAAM,OAAO,SAAS,EAAE,CAAC;EACzB,MAAM,KAAK,SAAS,IAAI,EAAE,CAAC;EAC3B,OAAO,KAAK,GAAG,aAAa,MAAM,IAAI,GAAG,KAAK,CAAC;CAChD;CAEA,OAAO;AACR;;;ACzBA,SAAgB,WAAW,MAAY;CACtC,OAAO,UAAU,KAAK,KAAK,GAAG,IAAI;AACnC;;;;;;ACCA,SAAgB,OAAO,KAAiB;CACvC,IAAI,MAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACtB,OAAO,IAAI,IAAI,EAAE;CAElB,OAAO;AACR;AAEA,SAAS,IAAI,GAAW;CACvB,MAAM,KAAK,CAAC,EAAA,CAAG,SAAS,EAAE;CAC1B,OAAO,EAAE,SAAS,IAAI,MAAM,IAAI;AACjC"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
const require_parse = require("./parse-8mt2OMKf.js");
|
|
2
|
+
// src/color/mix.ts
|
|
3
|
+
/** Index of the hue component, for the polar spaces. */
|
|
4
|
+
const HUE_AT = {
|
|
5
|
+
__proto__: null,
|
|
6
|
+
hsl: 0,
|
|
7
|
+
hwb: 0,
|
|
8
|
+
lch: 2,
|
|
9
|
+
oklch: 2
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Which components are "analogous" (CSS Color 4 section 4.4): a `none` in one
|
|
13
|
+
* space carries to the analogous component of another. One letter per
|
|
14
|
+
* component; the RGB spaces share `RGB` and the XYZ ones `XYZ`.
|
|
15
|
+
*/
|
|
16
|
+
const ANALOGOUS = {
|
|
17
|
+
__proto__: null,
|
|
18
|
+
hsl: "hcl",
|
|
19
|
+
hwb: "hwk",
|
|
20
|
+
lab: "lab",
|
|
21
|
+
lch: "lch",
|
|
22
|
+
oklab: "lab",
|
|
23
|
+
oklch: "lch",
|
|
24
|
+
"xyz-d50": "XYZ",
|
|
25
|
+
"xyz-d65": "XYZ"
|
|
26
|
+
};
|
|
27
|
+
const analogous = (id) => ANALOGOUS[id] ?? "RGB";
|
|
28
|
+
/** Converts, keeping `none` on components that have an analogous one in the source. */
|
|
29
|
+
function convertKeepingNone(componentsIn, color, space) {
|
|
30
|
+
const out = require_parse.convertWith(componentsIn, color, space);
|
|
31
|
+
if (color.colorSpace !== space && color.components.includes(null)) {
|
|
32
|
+
const from = analogous(color.colorSpace);
|
|
33
|
+
const to = analogous(space);
|
|
34
|
+
out.components = out.components.map((c, i) => color.components[from.indexOf(to[i])] === null ? null : c);
|
|
35
|
+
}
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Chroma below which a converted hue is powerless and so `none`, per polar
|
|
40
|
+
* space. Follows colorjs.io, which treats a hue as powerless when both Lab
|
|
41
|
+
* axes are under 1/100000 of their reference extent: 0.8 for Oklab (a, b in
|
|
42
|
+
* -0.4 to 0.4) gives 8e-6, 250 for Lab (-125 to 125) gives 0.0025.
|
|
43
|
+
*/
|
|
44
|
+
const POWERLESS = {
|
|
45
|
+
__proto__: null,
|
|
46
|
+
oklch: 8e-6,
|
|
47
|
+
lch: .0025,
|
|
48
|
+
hsl: 1e-4
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Converts for interpolation. A hue that conversion produced for a gray
|
|
52
|
+
* becomes `none`, so it takes the other color's hue; a hue the author wrote
|
|
53
|
+
* (the color already in `space`) stays as written.
|
|
54
|
+
*/
|
|
55
|
+
function prepare(componentsIn, color, space) {
|
|
56
|
+
const out = convertKeepingNone(componentsIn, color, space);
|
|
57
|
+
if (color.colorSpace === space || space !== "hwb" && POWERLESS[space] === void 0) return out;
|
|
58
|
+
const [, x, y] = out.components;
|
|
59
|
+
const epsilon = POWERLESS[space];
|
|
60
|
+
if (typeof x === "number" && (space === "hwb" ? typeof y === "number" && x + y > 99.9999 : epsilon !== void 0 && x < epsilon)) out.components[HUE_AT[space]] = null;
|
|
61
|
+
return out;
|
|
62
|
+
}
|
|
63
|
+
const HUE_METHODS = [
|
|
64
|
+
"shorter",
|
|
65
|
+
"longer",
|
|
66
|
+
"increasing",
|
|
67
|
+
"decreasing"
|
|
68
|
+
];
|
|
69
|
+
/** Fixes up two hues so they interpolate by `method` (section 12.4). */
|
|
70
|
+
function fixHues(h1, h2, method) {
|
|
71
|
+
let a = require_parse.normalizeHue(h1);
|
|
72
|
+
let b = require_parse.normalizeHue(h2);
|
|
73
|
+
const d = b - a;
|
|
74
|
+
if (method === "shorter") {
|
|
75
|
+
if (d > 180) a += 360;
|
|
76
|
+
else if (d < -180) b += 360;
|
|
77
|
+
} else if (method === "longer") {
|
|
78
|
+
if (d > 0 && d < 180) a += 360;
|
|
79
|
+
else if (d > -180 && d <= 0) b += 360;
|
|
80
|
+
} else if (method === "increasing") {
|
|
81
|
+
if (b < a) b += 360;
|
|
82
|
+
} else if (method !== "decreasing") throw require_parse.unknownName("hue method", method, HUE_METHODS);
|
|
83
|
+
else if (a < b) a += 360;
|
|
84
|
+
return [a, b];
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Interpolates two colors the way CSS does (Color 4 section 13): in the space
|
|
88
|
+
* `in`, with premultiplied alpha, `none` taking the other color's value, and
|
|
89
|
+
* the chosen hue method. `t` is the weight of `b`, 0 to 1 (outside it
|
|
90
|
+
* extrapolates). Strings are parsed with `parse`.
|
|
91
|
+
*
|
|
92
|
+
* A hue that conversion makes powerless (chroma under 8e-6 in `oklch`, 0.0025
|
|
93
|
+
* in `lch`, saturation under 1e-4 in `hsl`, whiteness plus blackness filling `hwb`; for example white) becomes `none`, so it takes the other color's
|
|
94
|
+
* hue. A hue you wrote in the target space stays as written.
|
|
95
|
+
*/
|
|
96
|
+
function mix(a, b, t = .5, options = {}) {
|
|
97
|
+
return mixWith(require_parse.componentsIn, require_parse.toColor(a), require_parse.toColor(b), t, options);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Builds {@link mix} over the spaces given, plus `oklab`, the default `in`, so
|
|
101
|
+
* a bundle contains only those. Give the `in` space too when it is not
|
|
102
|
+
* `oklab`. It takes color objects, not strings, so it does not carry `parse`;
|
|
103
|
+
* pass strings through `parse` first. A color in a space not given throws,
|
|
104
|
+
* naming that space.
|
|
105
|
+
*/
|
|
106
|
+
function createMix(...spaces) {
|
|
107
|
+
const over = require_parse.componentsOver([require_parse.oklab, ...spaces]);
|
|
108
|
+
return (a, b, t = .5, options = {}) => mixWith(over, a, b, t, options);
|
|
109
|
+
}
|
|
110
|
+
/** {@link mix} of two colors over the spaces `componentsIn` knows. */
|
|
111
|
+
function mixWith(componentsIn, a, b, t, options) {
|
|
112
|
+
const space = options.in ?? "oklab";
|
|
113
|
+
const c1 = prepare(componentsIn, a, space);
|
|
114
|
+
const c2 = prepare(componentsIn, b, space);
|
|
115
|
+
const alpha1 = c1.alpha === void 0 ? 1 : c1.alpha;
|
|
116
|
+
const alpha2 = c2.alpha === void 0 ? 1 : c2.alpha;
|
|
117
|
+
const a1 = alpha1 ?? alpha2;
|
|
118
|
+
const p1 = a1 ?? 1;
|
|
119
|
+
const p2 = alpha2 ?? alpha1 ?? 1;
|
|
120
|
+
const alpha = p1 * (1 - t) + p2 * t;
|
|
121
|
+
const hueAt = HUE_AT[space];
|
|
122
|
+
const method = options.hue ?? "shorter";
|
|
123
|
+
const components = [];
|
|
124
|
+
for (let i = 0; i < c1.components.length; i++) {
|
|
125
|
+
const x = c1.components[i];
|
|
126
|
+
const y = c2.components[i];
|
|
127
|
+
const u = x ?? y;
|
|
128
|
+
const v = y ?? x;
|
|
129
|
+
if (u === null || v === null) components.push(null);
|
|
130
|
+
else if (i === hueAt) {
|
|
131
|
+
const [h1, h2] = fixHues(u, v, method);
|
|
132
|
+
components.push(require_parse.normalizeHue(h1 * (1 - t) + h2 * t));
|
|
133
|
+
} else {
|
|
134
|
+
const premultiplied = u * p1 * (1 - t) + v * p2 * t;
|
|
135
|
+
components.push(alpha === 0 ? premultiplied : premultiplied / alpha);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const result = {
|
|
139
|
+
colorSpace: space,
|
|
140
|
+
components
|
|
141
|
+
};
|
|
142
|
+
if (a1 === null || alpha !== 1) result.alpha = a1 === null ? null : alpha;
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
Object.defineProperty(exports, "createMix", {
|
|
146
|
+
enumerable: true,
|
|
147
|
+
get: function() {
|
|
148
|
+
return createMix;
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
Object.defineProperty(exports, "mix", {
|
|
152
|
+
enumerable: true,
|
|
153
|
+
get: function() {
|
|
154
|
+
return mix;
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
//# sourceMappingURL=mix-Cs4owSbW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mix-Cs4owSbW.js","names":["convertWith","normalizeHue","unknownName","componentsIn","toColor","componentsOver","oklab"],"sources":["../src/color/mix.ts"],"sourcesContent":["import { type ComponentsIn, componentsOver, convertWith } from './convert.js'\nimport { normalizeHue } from './math.js'\nimport { oklab } from './oklab.js'\nimport { toColor } from './parse.js'\nimport { componentsIn } from './spaces.js'\nimport type { Color, ColorSpaceId, Component, Space } from './types.js'\nimport { unknownName } from './unknown-name.js'\n\n/** How `mix` travels around the hue circle (CSS Color 4 section 12.4). */\nexport type HueMethod = 'shorter' | 'longer' | 'increasing' | 'decreasing'\n\n/** Options for `mix` and the function `createMix` returns. */\nexport interface MixOptions {\n\t/** The space to interpolate in. Default `oklab`, which is what `color-mix()` uses. */\n\tin?: ColorSpaceId\n\t/** How hues are interpolated, in the polar spaces. Default `shorter`. */\n\thue?: HueMethod\n}\n\n/** Index of the hue component, for the polar spaces. */\nconst HUE_AT: Record<string, number> = { __proto__: null as never, hsl: 0, hwb: 0, lch: 2, oklch: 2 }\n\n/**\n * Which components are \"analogous\" (CSS Color 4 section 4.4): a `none` in one\n * space carries to the analogous component of another. One letter per\n * component; the RGB spaces share `RGB` and the XYZ ones `XYZ`.\n */\nconst ANALOGOUS: Record<string, string> = {\n\t__proto__: null as never,\n\thsl: 'hcl',\n\thwb: 'hwk',\n\tlab: 'lab',\n\tlch: 'lch',\n\toklab: 'lab',\n\toklch: 'lch',\n\t'xyz-d50': 'XYZ',\n\t'xyz-d65': 'XYZ'\n}\nconst analogous = (id: ColorSpaceId): string => ANALOGOUS[id] ?? 'RGB'\n\n/** Converts, keeping `none` on components that have an analogous one in the source. */\nfunction convertKeepingNone(componentsIn: ComponentsIn, color: Color, space: ColorSpaceId): Color {\n\tconst out = convertWith(componentsIn, color, space)\n\t// Nothing to carry when no component is `none`, the common case.\n\tif (color.colorSpace !== space && color.components.includes(null)) {\n\t\tconst from = analogous(color.colorSpace)\n\t\tconst to = analogous(space)\n\t\tout.components = out.components.map((c, i) => (color.components[from.indexOf(to[i])] === null ? null : c))\n\t}\n\treturn out\n}\n\n/**\n * Chroma below which a converted hue is powerless and so `none`, per polar\n * space. Follows colorjs.io, which treats a hue as powerless when both Lab\n * axes are under 1/100000 of their reference extent: 0.8 for Oklab (a, b in\n * -0.4 to 0.4) gives 8e-6, 250 for Lab (-125 to 125) gives 0.0025.\n */\nconst POWERLESS: Record<string, number> = { __proto__: null as never, oklch: 8e-6, lch: 0.0025, hsl: 1e-4 }\n\n/**\n * Converts for interpolation. A hue that conversion produced for a gray\n * becomes `none`, so it takes the other color's hue; a hue the author wrote\n * (the color already in `space`) stays as written.\n */\nfunction prepare(componentsIn: ComponentsIn, color: Color, space: ColorSpaceId): Color {\n\tconst out = convertKeepingNone(componentsIn, color, space)\n\t// A space with no powerless entry (and not `hwb`) has no hue to lose.\n\tif (color.colorSpace === space || (space !== 'hwb' && POWERLESS[space] === undefined)) return out\n\tconst [, x, y] = out.components\n\tconst epsilon = POWERLESS[space]\n\tconst gray =\n\t\ttypeof x === 'number' &&\n\t\t(space === 'hwb' ? typeof y === 'number' && x + y > 100 - 1e-4 : epsilon !== undefined && x < epsilon)\n\tif (gray) out.components[HUE_AT[space] as number] = null\n\treturn out\n}\n\nconst HUE_METHODS = ['shorter', 'longer', 'increasing', 'decreasing']\n\n/** Fixes up two hues so they interpolate by `method` (section 12.4). */\nfunction fixHues(h1: number, h2: number, method: HueMethod): [number, number] {\n\tlet a = normalizeHue(h1)\n\tlet b = normalizeHue(h2)\n\tconst d = b - a\n\tif (method === 'shorter') {\n\t\tif (d > 180) a += 360\n\t\telse if (d < -180) b += 360\n\t} else if (method === 'longer') {\n\t\tif (d > 0 && d < 180) a += 360\n\t\telse if (d > -180 && d <= 0) b += 360\n\t} else if (method === 'increasing') {\n\t\tif (b < a) b += 360\n\t} else if (method !== 'decreasing') throw unknownName('hue method', method, HUE_METHODS)\n\telse if (a < b) a += 360\n\treturn [a, b]\n}\n\n/**\n * Interpolates two colors the way CSS does (Color 4 section 13): in the space\n * `in`, with premultiplied alpha, `none` taking the other color's value, and\n * the chosen hue method. `t` is the weight of `b`, 0 to 1 (outside it\n * extrapolates). Strings are parsed with `parse`.\n *\n * A hue that conversion makes powerless (chroma under 8e-6 in `oklch`, 0.0025\n * in `lch`, saturation under 1e-4 in `hsl`, whiteness plus blackness filling `hwb`; for example white) becomes `none`, so it takes the other color's\n * hue. A hue you wrote in the target space stays as written.\n */\nexport function mix(a: Color | string, b: Color | string, t = 0.5, options: MixOptions = {}): Color {\n\treturn mixWith(componentsIn, toColor(a), toColor(b), t, options)\n}\n\n/**\n * Builds {@link mix} over the spaces given, plus `oklab`, the default `in`, so\n * a bundle contains only those. Give the `in` space too when it is not\n * `oklab`. It takes color objects, not strings, so it does not carry `parse`;\n * pass strings through `parse` first. A color in a space not given throws,\n * naming that space.\n */\nexport function createMix(...spaces: Space[]): (a: Color, b: Color, t?: number, options?: MixOptions) => Color {\n\tconst over = componentsOver([oklab, ...spaces])\n\treturn (a, b, t = 0.5, options = {}) => mixWith(over, a, b, t, options)\n}\n\n/** {@link mix} of two colors over the spaces `componentsIn` knows. */\nfunction mixWith(componentsIn: ComponentsIn, a: Color, b: Color, t: number, options: MixOptions): Color {\n\tconst space = options.in ?? 'oklab'\n\tconst c1 = prepare(componentsIn, a, space)\n\tconst c2 = prepare(componentsIn, b, space)\n\t// A `none` takes the other side's value; both `none` stays `none`.\n\tconst alpha1 = c1.alpha === undefined ? 1 : c1.alpha\n\tconst alpha2 = c2.alpha === undefined ? 1 : c2.alpha\n\tconst a1 = alpha1 ?? alpha2\n\tconst p1 = a1 ?? 1\n\tconst p2 = alpha2 ?? alpha1 ?? 1\n\tconst alpha = p1 * (1 - t) + p2 * t\n\tconst hueAt = HUE_AT[space]\n\tconst method = options.hue ?? 'shorter'\n\tconst components: Component[] = []\n\tfor (let i = 0; i < c1.components.length; i++) {\n\t\tconst x = c1.components[i] as Component\n\t\tconst y = c2.components[i] as Component\n\t\tconst u = x ?? y\n\t\tconst v = y ?? x\n\t\tif (u === null || v === null) {\n\t\t\tcomponents.push(null)\n\t\t} else if (i === hueAt) {\n\t\t\tconst [h1, h2] = fixHues(u, v, method)\n\t\t\tcomponents.push(normalizeHue(h1 * (1 - t) + h2 * t))\n\t\t} else {\n\t\t\tconst premultiplied = u * p1 * (1 - t) + v * p2 * t\n\t\t\tcomponents.push(alpha === 0 ? premultiplied : premultiplied / alpha)\n\t\t}\n\t}\n\tconst result: Color = { colorSpace: space, components }\n\tif (a1 === null || alpha !== 1) result.alpha = a1 === null ? null : alpha\n\treturn result\n}\n"],"mappings":";;;AAoBA,MAAM,SAAiC;CAAE,WAAW;CAAe,KAAK;CAAG,KAAK;CAAG,KAAK;CAAG,OAAO;AAAE;;;;;;AAOpG,MAAM,YAAoC;CACzC,WAAW;CACX,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,OAAO;CACP,OAAO;CACP,WAAW;CACX,WAAW;AACZ;AACA,MAAM,aAAa,OAA6B,UAAU,OAAO;;AAGjE,SAAS,mBAAmB,cAA4B,OAAc,OAA4B;CACjG,MAAM,MAAMA,cAAAA,YAAY,cAAc,OAAO,KAAK;CAElD,IAAI,MAAM,eAAe,SAAS,MAAM,WAAW,SAAS,IAAI,GAAG;EAClE,MAAM,OAAO,UAAU,MAAM,UAAU;EACvC,MAAM,KAAK,UAAU,KAAK;EAC1B,IAAI,aAAa,IAAI,WAAW,KAAK,GAAG,MAAO,MAAM,WAAW,KAAK,QAAQ,GAAG,EAAE,OAAO,OAAO,OAAO,CAAE;CAC1G;CACA,OAAO;AACR;;;;;;;AAQA,MAAM,YAAoC;CAAE,WAAW;CAAe,OAAO;CAAM,KAAK;CAAQ,KAAK;AAAK;;;;;;AAO1G,SAAS,QAAQ,cAA4B,OAAc,OAA4B;CACtF,MAAM,MAAM,mBAAmB,cAAc,OAAO,KAAK;CAEzD,IAAI,MAAM,eAAe,SAAU,UAAU,SAAS,UAAU,WAAW,KAAA,GAAY,OAAO;CAC9F,MAAM,GAAG,GAAG,KAAK,IAAI;CACrB,MAAM,UAAU,UAAU;CAI1B,IAFC,OAAO,MAAM,aACZ,UAAU,QAAQ,OAAO,MAAM,YAAY,IAAI,IAAI,UAAa,YAAY,KAAA,KAAa,IAAI,UACrF,IAAI,WAAW,OAAO,UAAoB;CACpD,OAAO;AACR;AAEA,MAAM,cAAc;CAAC;CAAW;CAAU;CAAc;AAAY;;AAGpE,SAAS,QAAQ,IAAY,IAAY,QAAqC;CAC7E,IAAI,IAAIC,cAAAA,aAAa,EAAE;CACvB,IAAI,IAAIA,cAAAA,aAAa,EAAE;CACvB,MAAM,IAAI,IAAI;CACd,IAAI,WAAW,WAAW;EACzB,IAAI,IAAI,KAAK,KAAK;OACb,IAAI,IAAI,MAAM,KAAK;CACzB,OAAO,IAAI,WAAW,UAAU;EAC/B,IAAI,IAAI,KAAK,IAAI,KAAK,KAAK;OACtB,IAAI,IAAI,QAAQ,KAAK,GAAG,KAAK;CACnC,OAAO,IAAI,WAAW,cACjB;MAAA,IAAI,GAAG,KAAK;CAAA,OACV,IAAI,WAAW,cAAc,MAAMC,cAAAA,YAAY,cAAc,QAAQ,WAAW;MAClF,IAAI,IAAI,GAAG,KAAK;CACrB,OAAO,CAAC,GAAG,CAAC;AACb;;;;;;;;;;;AAYA,SAAgB,IAAI,GAAmB,GAAmB,IAAI,IAAK,UAAsB,CAAC,GAAU;CACnG,OAAO,QAAQC,cAAAA,cAAcC,cAAAA,QAAQ,CAAC,GAAGA,cAAAA,QAAQ,CAAC,GAAG,GAAG,OAAO;AAChE;;;;;;;;AASA,SAAgB,UAAU,GAAG,QAAkF;CAC9G,MAAM,OAAOC,cAAAA,eAAe,CAACC,cAAAA,OAAO,GAAG,MAAM,CAAC;CAC9C,QAAQ,GAAG,GAAG,IAAI,IAAK,UAAU,CAAC,MAAM,QAAQ,MAAM,GAAG,GAAG,GAAG,OAAO;AACvE;;AAGA,SAAS,QAAQ,cAA4B,GAAU,GAAU,GAAW,SAA4B;CACvG,MAAM,QAAQ,QAAQ,MAAM;CAC5B,MAAM,KAAK,QAAQ,cAAc,GAAG,KAAK;CACzC,MAAM,KAAK,QAAQ,cAAc,GAAG,KAAK;CAEzC,MAAM,SAAS,GAAG,UAAU,KAAA,IAAY,IAAI,GAAG;CAC/C,MAAM,SAAS,GAAG,UAAU,KAAA,IAAY,IAAI,GAAG;CAC/C,MAAM,KAAK,UAAU;CACrB,MAAM,KAAK,MAAM;CACjB,MAAM,KAAK,UAAU,UAAU;CAC/B,MAAM,QAAQ,MAAM,IAAI,KAAK,KAAK;CAClC,MAAM,QAAQ,OAAO;CACrB,MAAM,SAAS,QAAQ,OAAO;CAC9B,MAAM,aAA0B,CAAC;CACjC,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,WAAW,QAAQ,KAAK;EAC9C,MAAM,IAAI,GAAG,WAAW;EACxB,MAAM,IAAI,GAAG,WAAW;EACxB,MAAM,IAAI,KAAK;EACf,MAAM,IAAI,KAAK;EACf,IAAI,MAAM,QAAQ,MAAM,MACvB,WAAW,KAAK,IAAI;OACd,IAAI,MAAM,OAAO;GACvB,MAAM,CAAC,IAAI,MAAM,QAAQ,GAAG,GAAG,MAAM;GACrC,WAAW,KAAKL,cAAAA,aAAa,MAAM,IAAI,KAAK,KAAK,CAAC,CAAC;EACpD,OAAO;GACN,MAAM,gBAAgB,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK;GAClD,WAAW,KAAK,UAAU,IAAI,gBAAgB,gBAAgB,KAAK;EACpE;CACD;CACA,MAAM,SAAgB;EAAE,YAAY;EAAO;CAAW;CACtD,IAAI,OAAO,QAAQ,UAAU,GAAG,OAAO,QAAQ,OAAO,OAAO,OAAO;CACpE,OAAO;AACR"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { C as ColorSpaceId, S as Color, T as Space } from "./gamut-CG1J2aat.js";
|
|
2
|
+
/** How `mix` travels around the hue circle (CSS Color 4 section 12.4). */
|
|
3
|
+
type HueMethod = 'shorter' | 'longer' | 'increasing' | 'decreasing';
|
|
4
|
+
/** Options for `mix` and the function `createMix` returns. */
|
|
5
|
+
interface MixOptions {
|
|
6
|
+
/** The space to interpolate in. Default `oklab`, which is what `color-mix()` uses. */
|
|
7
|
+
in?: ColorSpaceId;
|
|
8
|
+
/** How hues are interpolated, in the polar spaces. Default `shorter`. */
|
|
9
|
+
hue?: HueMethod;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Interpolates two colors the way CSS does (Color 4 section 13): in the space
|
|
13
|
+
* `in`, with premultiplied alpha, `none` taking the other color's value, and
|
|
14
|
+
* the chosen hue method. `t` is the weight of `b`, 0 to 1 (outside it
|
|
15
|
+
* extrapolates). Strings are parsed with `parse`.
|
|
16
|
+
*
|
|
17
|
+
* A hue that conversion makes powerless (chroma under 8e-6 in `oklch`, 0.0025
|
|
18
|
+
* in `lch`, saturation under 1e-4 in `hsl`, whiteness plus blackness filling `hwb`; for example white) becomes `none`, so it takes the other color's
|
|
19
|
+
* hue. A hue you wrote in the target space stays as written.
|
|
20
|
+
*/
|
|
21
|
+
declare function mix(a: Color | string, b: Color | string, t?: number, options?: MixOptions): Color;
|
|
22
|
+
/**
|
|
23
|
+
* Builds {@link mix} over the spaces given, plus `oklab`, the default `in`, so
|
|
24
|
+
* a bundle contains only those. Give the `in` space too when it is not
|
|
25
|
+
* `oklab`. It takes color objects, not strings, so it does not carry `parse`;
|
|
26
|
+
* pass strings through `parse` first. A color in a space not given throws,
|
|
27
|
+
* naming that space.
|
|
28
|
+
*/
|
|
29
|
+
declare function createMix(...spaces: Space[]): (a: Color, b: Color, t?: number, options?: MixOptions) => Color;
|
|
30
|
+
export { mix as i, MixOptions as n, createMix as r, HueMethod as t };
|
|
31
|
+
//# sourceMappingURL=mix-DGlKoUw4.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mix-DGlKoUw4.d.ts","names":[],"sources":["../src/color/mix.ts"],"mappings":";;KASY;;UAGK;;EAEhB,KAAK;;EAEL,MAAM;;;;;;;;;;;;iBA4FS,IAAI,GAAG,gBAAgB,GAAG,gBAAgB,YAAS,UAAS,aAAkB;;;;;;;;iBAW9E,aAAa,QAAQ,WAAW,GAAG,OAAO,GAAG,OAAO,YAAY,UAAU,eAAe"}
|
package/cjs/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"type":"commonjs"}
|
|
1
|
+
{ "type": "commonjs" }
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { a as validate, c as HarmonyScheme, d as harmony, f as inverse, h as darkVariant, i as ValidateResult, l as HarmonySpace, m as DarkVariantOptions, n as PaletteLike, o as HarmonizeOptions, p as DarkStrategy, r as ValidateOptions, s as HarmonyOptions, t as PaletteIssue, u as harmonize } from "../index-CGKCqRqD.js";
|
|
2
|
+
import { a as semanticPalette, i as SemanticRole, n as SemanticPalette, r as SemanticPaletteOptions, t as RolePair } from "../semantic-CrEIo8tS.js";
|
|
3
|
+
export { type DarkStrategy, type DarkVariantOptions, type HarmonizeOptions, type HarmonyOptions, type HarmonyScheme, type HarmonySpace, type PaletteIssue, type PaletteLike, type RolePair, type SemanticPalette, type SemanticPaletteOptions, type SemanticRole, type ValidateOptions, type ValidateResult, darkVariant, harmonize, harmony, inverse, semanticPalette, validate };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_palette = require("../palette-DyFV_KoJ.js");
|
|
3
|
+
exports.darkVariant = require_palette.darkVariant;
|
|
4
|
+
exports.harmonize = require_palette.harmonize;
|
|
5
|
+
exports.harmony = require_palette.harmony;
|
|
6
|
+
exports.inverse = require_palette.inverse;
|
|
7
|
+
exports.semanticPalette = require_palette.semanticPalette;
|
|
8
|
+
exports.validate = require_palette.validate;
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
const require_parse = require("./parse-8mt2OMKf.js");
|
|
2
|
+
const require_tone = require("./tone-BAhu-QzQ.js");
|
|
3
|
+
const require_contrast = require("./contrast-XjF5Rwui.js");
|
|
4
|
+
// src/palette/dark.ts
|
|
5
|
+
const STRATEGIES = [
|
|
6
|
+
"mirror",
|
|
7
|
+
"tone-swap",
|
|
8
|
+
"lightness-invert"
|
|
9
|
+
];
|
|
10
|
+
/**
|
|
11
|
+
* A dark version of a light scale (ordered light to dark), with the same
|
|
12
|
+
* number of steps.
|
|
13
|
+
* - `mirror`: step n takes the color of step N+1-n, so the scale runs dark to
|
|
14
|
+
* light and step 1 is the old last step. Colors are unchanged.
|
|
15
|
+
* - `tone-swap`: each color keeps its OKLCH hue and chroma and takes the CIE
|
|
16
|
+
* L* tone 100 minus its own, as Material swaps tone 40 for 80. Contrast
|
|
17
|
+
* between two steps is kept roughly the same.
|
|
18
|
+
* - `lightness-invert`: OKLCH lightness is reflected within the scale's own
|
|
19
|
+
* range, keeping step order, with chroma eased by 10% to curb vibration on
|
|
20
|
+
* dark backgrounds.
|
|
21
|
+
*/
|
|
22
|
+
function darkVariant(scale, strategy = "tone-swap", options = {}) {
|
|
23
|
+
const { gamut = "srgb" } = options;
|
|
24
|
+
if (!STRATEGIES.includes(strategy)) throw require_parse.unknownName("dark variant strategy", strategy, STRATEGIES);
|
|
25
|
+
if (strategy === "mirror") return [...scale].reverse();
|
|
26
|
+
if (strategy === "tone-swap") return scale.map((c) => {
|
|
27
|
+
const [, chroma, hue] = require_parse.componentsIn(c, "oklch");
|
|
28
|
+
return withAlpha(require_tone.toneColor(100 - require_tone.lstar(c), chroma, hue ?? 0, gamut), c);
|
|
29
|
+
});
|
|
30
|
+
const oklch = scale.map((c) => require_parse.componentsIn(c, "oklch"));
|
|
31
|
+
const ls = oklch.map((c) => c[0]);
|
|
32
|
+
const sum = Math.min(...ls) + Math.max(...ls);
|
|
33
|
+
return scale.map((c, i) => {
|
|
34
|
+
const [l, chroma, hue] = oklch[i];
|
|
35
|
+
return withAlpha(require_parse.toGamut({
|
|
36
|
+
colorSpace: "oklch",
|
|
37
|
+
components: [
|
|
38
|
+
sum - l,
|
|
39
|
+
chroma * .9,
|
|
40
|
+
hue
|
|
41
|
+
]
|
|
42
|
+
}, { gamut }), c);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function withAlpha(color, from) {
|
|
46
|
+
return from.alpha === void 0 ? color : {
|
|
47
|
+
...color,
|
|
48
|
+
alpha: from.alpha
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// src/palette/harmony.ts
|
|
52
|
+
/** The hue rotations, in degrees, that each scheme adds to the base color. */
|
|
53
|
+
const SCHEMES = {
|
|
54
|
+
__proto__: null,
|
|
55
|
+
complementary: [0, 180],
|
|
56
|
+
split: [
|
|
57
|
+
0,
|
|
58
|
+
150,
|
|
59
|
+
210
|
|
60
|
+
],
|
|
61
|
+
analogous: [
|
|
62
|
+
-30,
|
|
63
|
+
0,
|
|
64
|
+
30
|
|
65
|
+
],
|
|
66
|
+
triadic: [
|
|
67
|
+
0,
|
|
68
|
+
120,
|
|
69
|
+
240
|
|
70
|
+
],
|
|
71
|
+
tetradic: [
|
|
72
|
+
0,
|
|
73
|
+
90,
|
|
74
|
+
180,
|
|
75
|
+
270
|
|
76
|
+
]
|
|
77
|
+
};
|
|
78
|
+
const HUE_SPACES = [
|
|
79
|
+
"oklch",
|
|
80
|
+
"lch",
|
|
81
|
+
"hsl",
|
|
82
|
+
"hwb"
|
|
83
|
+
];
|
|
84
|
+
const hueIndex = (space) => space === "hsl" || space === "hwb" ? 0 : 2;
|
|
85
|
+
/**
|
|
86
|
+
* The colors of a harmony: `color` rotated around the hue wheel of `space`,
|
|
87
|
+
* with lightness and chroma held, in the order of the scheme's angles
|
|
88
|
+
* (`complementary` 0 and 180; `split` 0, 150, 210; `analogous` -30, 0, 30;
|
|
89
|
+
* `triadic` 0, 120, 240; `tetradic` 0, 90, 180, 270). The color itself is the
|
|
90
|
+
* entry at angle 0, returned as given. Rotated colors are mapped into `gamut`.
|
|
91
|
+
* The same angle looks different in `hsl` and `oklch`, so name the space.
|
|
92
|
+
*/
|
|
93
|
+
function harmony(color, scheme, options = {}) {
|
|
94
|
+
const { space = "oklch", gamut = "srgb" } = options;
|
|
95
|
+
const angles = SCHEMES[scheme];
|
|
96
|
+
if (!angles) throw require_parse.unknownName("harmony scheme", scheme, Object.keys(SCHEMES));
|
|
97
|
+
if (!HUE_SPACES.includes(space)) throw require_parse.unknownName("harmony space", space, HUE_SPACES);
|
|
98
|
+
const base = require_parse.toColor(color);
|
|
99
|
+
const inSpace = require_parse.convert(base, space);
|
|
100
|
+
const at = hueIndex(space);
|
|
101
|
+
const hue = inSpace.components[at] ?? 0;
|
|
102
|
+
return angles.map((angle) => {
|
|
103
|
+
if (angle === 0) return base;
|
|
104
|
+
const components = [...inSpace.components];
|
|
105
|
+
components[at] = require_parse.normalizeHue(hue + angle);
|
|
106
|
+
return require_parse.toGamut({
|
|
107
|
+
...inSpace,
|
|
108
|
+
components
|
|
109
|
+
}, { gamut });
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Nudges `color`'s hue toward `toward`, as Material's `Blend.harmonize` does:
|
|
114
|
+
* by half the hue difference, but at most 15 degrees, in OKLCH, keeping
|
|
115
|
+
* lightness and chroma. Use it to make a status color feel at home with a
|
|
116
|
+
* brand color without changing its meaning.
|
|
117
|
+
*/
|
|
118
|
+
function harmonize(color, toward, options = {}) {
|
|
119
|
+
const { max = 15, factor = .5, gamut = "srgb" } = options;
|
|
120
|
+
const from = require_parse.convert(require_parse.toColor(color), "oklch");
|
|
121
|
+
const to = require_parse.convert(require_parse.toColor(toward), "oklch");
|
|
122
|
+
const h0 = from.components[2] ?? 0;
|
|
123
|
+
const h1 = to.components[2] ?? h0;
|
|
124
|
+
const diff = require_parse.normalizeHue(h1 - h0 + 180) - 180;
|
|
125
|
+
const rotation = Math.min(Math.abs(diff) * factor, max) * Math.sign(diff);
|
|
126
|
+
const components = [...from.components];
|
|
127
|
+
components[2] = require_parse.normalizeHue(h0 + rotation);
|
|
128
|
+
return require_parse.toGamut({
|
|
129
|
+
...from,
|
|
130
|
+
components
|
|
131
|
+
}, { gamut });
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* The opposite of a color. `lightness` flips OKLCH lightness (L becomes 1 - L)
|
|
135
|
+
* and keeps hue and chroma, so light turns dark without changing its hue;
|
|
136
|
+
* `rgb` inverts each sRGB channel, which also turns the hue to its complement.
|
|
137
|
+
* Alpha is kept. The result is mapped into sRGB.
|
|
138
|
+
*/
|
|
139
|
+
function inverse(color, mode = "lightness") {
|
|
140
|
+
const base = require_parse.toColor(color);
|
|
141
|
+
if (mode === "rgb") {
|
|
142
|
+
const c = require_parse.convert(base, "srgb");
|
|
143
|
+
return require_parse.toGamut({
|
|
144
|
+
...c,
|
|
145
|
+
components: c.components.map((x) => 1 - x)
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
const c = require_parse.convert(base, "oklch");
|
|
149
|
+
return require_parse.toGamut({
|
|
150
|
+
...c,
|
|
151
|
+
components: [
|
|
152
|
+
1 - c.components[0],
|
|
153
|
+
c.components[1],
|
|
154
|
+
c.components[2]
|
|
155
|
+
]
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
// src/palette/semantic.ts
|
|
159
|
+
const BG_TONE = {
|
|
160
|
+
primary: [40, 80],
|
|
161
|
+
primaryContainer: [90, 30],
|
|
162
|
+
surface: [98, 6],
|
|
163
|
+
surfaceVariant: [90, 30]
|
|
164
|
+
};
|
|
165
|
+
const FG_TONE = {
|
|
166
|
+
primary: [100, 20],
|
|
167
|
+
primaryContainer: [10, 90],
|
|
168
|
+
surface: [10, 90],
|
|
169
|
+
surfaceVariant: [30, 80]
|
|
170
|
+
};
|
|
171
|
+
const STATUS = {
|
|
172
|
+
success: 145,
|
|
173
|
+
warning: 85,
|
|
174
|
+
danger: 25,
|
|
175
|
+
info: 240
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* A role-based palette from one brand color: primary and its container, four
|
|
179
|
+
* status colors (success, warning, danger, info) harmonized toward the brand's
|
|
180
|
+
* hue, a surface and a variant tinted by the brand hue, and an outline. Every
|
|
181
|
+
* pair is built from L* tones, so a 50-tone gap or more reaches about 4.5 on
|
|
182
|
+
* WCAG 2 (the worst pair, 100 on 50, gives 4.48). Each pair records the ratio
|
|
183
|
+
* it reached; a foreground that falls short of `target` is replaced by the
|
|
184
|
+
* closest one that meets it, and `validate` reports any that cannot.
|
|
185
|
+
*/
|
|
186
|
+
function semanticPalette(options) {
|
|
187
|
+
const { mode = "light", contrast = "wcag2", target = 4.5, gamut = "srgb" } = options;
|
|
188
|
+
const fn = require_contrast.pick(contrast);
|
|
189
|
+
const dark = require_parse.checkMode(mode) === "dark";
|
|
190
|
+
const i = dark ? 1 : 0;
|
|
191
|
+
const brand = require_parse.toColor(options.brand);
|
|
192
|
+
const [, c, h] = require_parse.componentsIn(brand, "oklch");
|
|
193
|
+
const hue = h ?? 0;
|
|
194
|
+
const chroma = Math.max(c, .04);
|
|
195
|
+
const tint = .015;
|
|
196
|
+
const pair = (bg, fgTone, fgChroma, need = target) => {
|
|
197
|
+
let fg = require_tone.toneColor(fgTone, fgChroma, hue, gamut);
|
|
198
|
+
let ratio = Math.abs(fn(fg, bg));
|
|
199
|
+
if (ratio < need) {
|
|
200
|
+
const found = require_contrast.findContrast(bg, need, {
|
|
201
|
+
contrast: fn,
|
|
202
|
+
chroma: fgChroma,
|
|
203
|
+
hue
|
|
204
|
+
});
|
|
205
|
+
fg = found.color;
|
|
206
|
+
ratio = Math.abs(found.contrast);
|
|
207
|
+
}
|
|
208
|
+
return {
|
|
209
|
+
bg,
|
|
210
|
+
fg,
|
|
211
|
+
ratio,
|
|
212
|
+
target: need
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
const status = (name) => {
|
|
216
|
+
const base = require_tone.toneColor(BG_TONE.primary[i], .14, STATUS[name], gamut);
|
|
217
|
+
return pair(harmonize(base, brand, { gamut }), FG_TONE.primary[i], .02);
|
|
218
|
+
};
|
|
219
|
+
const surface = require_tone.toneColor(BG_TONE.surface[i], tint, hue, gamut);
|
|
220
|
+
const outline = pair(surface, dark ? 60 : 50, tint, 3);
|
|
221
|
+
return {
|
|
222
|
+
meta: {
|
|
223
|
+
mode,
|
|
224
|
+
contrast: fn.algorithm ?? "custom",
|
|
225
|
+
target,
|
|
226
|
+
gamut
|
|
227
|
+
},
|
|
228
|
+
scales: {
|
|
229
|
+
primary: require_tone.tonalPalette(hue, chroma, void 0, { gamut }),
|
|
230
|
+
neutral: require_tone.tonalPalette(hue, tint, void 0, { gamut })
|
|
231
|
+
},
|
|
232
|
+
roles: {
|
|
233
|
+
primary: pair(require_tone.toneColor(BG_TONE.primary[i], chroma, hue, gamut), FG_TONE.primary[i], .02),
|
|
234
|
+
primaryContainer: pair(require_tone.toneColor(BG_TONE.primaryContainer[i], chroma, hue, gamut), FG_TONE.primaryContainer[i], .02),
|
|
235
|
+
success: status("success"),
|
|
236
|
+
warning: status("warning"),
|
|
237
|
+
danger: status("danger"),
|
|
238
|
+
info: status("info"),
|
|
239
|
+
surface: pair(surface, FG_TONE.surface[i], tint),
|
|
240
|
+
surfaceVariant: pair(require_tone.toneColor(BG_TONE.surfaceVariant[i], tint, hue, gamut), FG_TONE.surfaceVariant[i], tint),
|
|
241
|
+
outline
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
// src/palette/validate.ts
|
|
246
|
+
/**
|
|
247
|
+
* Checks a palette and lists what is wrong, so an agent can fix it:
|
|
248
|
+
* - `contrast`: a role pair whose measured contrast is under its target;
|
|
249
|
+
* - `lightness`: a scale whose OKLCH lightness does not change steadily in one
|
|
250
|
+
* direction from one step to the next;
|
|
251
|
+
* - `gamut`: a color outside the gamut (it would be clipped on display).
|
|
252
|
+
*/
|
|
253
|
+
function validate(palette, options = {}) {
|
|
254
|
+
const { contrast = "wcag2", target = 4.5, gamut = "srgb" } = options;
|
|
255
|
+
const fn = require_contrast.pick(contrast);
|
|
256
|
+
const issues = [];
|
|
257
|
+
const outside = (path, color) => {
|
|
258
|
+
if (!require_parse.inGamut(color, gamut)) issues.push({
|
|
259
|
+
kind: "gamut",
|
|
260
|
+
path,
|
|
261
|
+
message: `${path} is outside ${gamut}`
|
|
262
|
+
});
|
|
263
|
+
};
|
|
264
|
+
for (const [name, p] of Object.entries(palette.roles ?? {})) {
|
|
265
|
+
const need = p.target ?? target;
|
|
266
|
+
const ratio = Math.abs(fn(p.fg, p.bg));
|
|
267
|
+
if (ratio < need) issues.push({
|
|
268
|
+
kind: "contrast",
|
|
269
|
+
path: `roles.${name}`,
|
|
270
|
+
message: `roles.${name} reaches ${ratio.toFixed(2)}, needs ${need}`
|
|
271
|
+
});
|
|
272
|
+
outside(`roles.${name}.bg`, p.bg);
|
|
273
|
+
outside(`roles.${name}.fg`, p.fg);
|
|
274
|
+
}
|
|
275
|
+
for (const [name, scale] of Object.entries(palette.scales ?? {})) {
|
|
276
|
+
const ls = scale.map((c) => require_parse.componentsIn(c, "oklch")[0]);
|
|
277
|
+
const steps = ls.slice(1).map((l, k) => l - ls[k]);
|
|
278
|
+
const direction = Math.sign(steps.find((d) => d !== 0) ?? 0);
|
|
279
|
+
steps.forEach((d, k) => {
|
|
280
|
+
if (Math.sign(d) !== direction || Math.abs(d) < 1e-9) issues.push({
|
|
281
|
+
kind: "lightness",
|
|
282
|
+
path: `scales.${name}[${k + 1}]`,
|
|
283
|
+
message: `scales.${name} lightness does not change steadily at step ${k + 1}`
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
scale.forEach((c, k) => {
|
|
287
|
+
outside(`scales.${name}[${k}]`, c);
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
return {
|
|
291
|
+
ok: issues.length === 0,
|
|
292
|
+
issues
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
Object.defineProperty(exports, "darkVariant", {
|
|
296
|
+
enumerable: true,
|
|
297
|
+
get: function() {
|
|
298
|
+
return darkVariant;
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
Object.defineProperty(exports, "harmonize", {
|
|
302
|
+
enumerable: true,
|
|
303
|
+
get: function() {
|
|
304
|
+
return harmonize;
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
Object.defineProperty(exports, "harmony", {
|
|
308
|
+
enumerable: true,
|
|
309
|
+
get: function() {
|
|
310
|
+
return harmony;
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
Object.defineProperty(exports, "inverse", {
|
|
314
|
+
enumerable: true,
|
|
315
|
+
get: function() {
|
|
316
|
+
return inverse;
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
Object.defineProperty(exports, "semanticPalette", {
|
|
320
|
+
enumerable: true,
|
|
321
|
+
get: function() {
|
|
322
|
+
return semanticPalette;
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
Object.defineProperty(exports, "validate", {
|
|
326
|
+
enumerable: true,
|
|
327
|
+
get: function() {
|
|
328
|
+
return validate;
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
//# sourceMappingURL=palette-DyFV_KoJ.js.map
|