color-value-tools 1.2.0 → 1.2.2

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.
Files changed (49) hide show
  1. package/README.md +18 -0
  2. package/dist/cjs/a11y.d.ts +40 -0
  3. package/dist/cjs/a11y.js +253 -0
  4. package/dist/cjs/cache.d.ts +9 -0
  5. package/dist/cjs/cache.js +38 -0
  6. package/dist/cjs/convert/format.d.ts +3 -0
  7. package/dist/cjs/convert/format.js +42 -0
  8. package/dist/cjs/convert/index.d.ts +2 -0
  9. package/dist/cjs/convert/index.js +18 -0
  10. package/dist/cjs/convert/spaces.d.ts +189 -0
  11. package/dist/cjs/convert/spaces.js +556 -0
  12. package/dist/cjs/index.d.ts +6 -397
  13. package/dist/cjs/index.js +20 -1450
  14. package/dist/cjs/internal/named-colors.d.ts +1 -0
  15. package/dist/cjs/internal/named-colors.js +165 -0
  16. package/dist/cjs/internal/transfer.d.ts +2 -0
  17. package/dist/cjs/internal/transfer.js +12 -0
  18. package/dist/cjs/manipulate.d.ts +15 -0
  19. package/dist/cjs/manipulate.js +223 -0
  20. package/dist/cjs/palette.d.ts +40 -0
  21. package/dist/cjs/palette.js +164 -0
  22. package/dist/cjs/parse.d.ts +102 -0
  23. package/dist/cjs/parse.js +257 -0
  24. package/dist/cli/{bin/cli.js → cli.js} +28 -26
  25. package/dist/esm/a11y.d.ts +40 -0
  26. package/dist/esm/a11y.js +237 -0
  27. package/dist/esm/cache.d.ts +9 -0
  28. package/dist/esm/cache.js +31 -0
  29. package/dist/esm/convert/format.d.ts +3 -0
  30. package/dist/esm/convert/format.js +37 -0
  31. package/dist/esm/convert/index.d.ts +2 -0
  32. package/dist/esm/convert/index.js +2 -0
  33. package/dist/esm/convert/spaces.d.ts +189 -0
  34. package/dist/esm/convert/spaces.js +520 -0
  35. package/dist/esm/index.d.ts +6 -0
  36. package/dist/esm/index.js +6 -1352
  37. package/dist/esm/internal/named-colors.d.ts +1 -0
  38. package/dist/esm/internal/named-colors.js +162 -0
  39. package/dist/esm/internal/transfer.d.ts +2 -0
  40. package/dist/esm/internal/transfer.js +8 -0
  41. package/dist/esm/manipulate.d.ts +15 -0
  42. package/dist/esm/manipulate.js +210 -0
  43. package/dist/esm/package.json +3 -1
  44. package/dist/esm/palette.d.ts +40 -0
  45. package/dist/esm/palette.js +145 -0
  46. package/dist/esm/parse.d.ts +102 -0
  47. package/dist/esm/parse.js +241 -0
  48. package/package.json +100 -8
  49. package/dist/cli/src/index.js +0 -1452
@@ -0,0 +1 @@
1
+ export declare const NAMED_COLORS: Record<string, string>;
@@ -0,0 +1,162 @@
1
+ // CSS named colors (CSS Color Module Level 4).
2
+ export const NAMED_COLORS = {
3
+ aliceblue: '#f0f8ff',
4
+ antiquewhite: '#faebd7',
5
+ aqua: '#00ffff',
6
+ aquamarine: '#7fffd4',
7
+ azure: '#f0ffff',
8
+ beige: '#f5f5dc',
9
+ bisque: '#ffe4c4',
10
+ black: '#000000',
11
+ blanchedalmond: '#ffebcd',
12
+ blue: '#0000ff',
13
+ blueviolet: '#8a2be2',
14
+ brown: '#a52a2a',
15
+ burlywood: '#deb887',
16
+ cadetblue: '#5f9ea0',
17
+ chartreuse: '#7fff00',
18
+ chocolate: '#d2691e',
19
+ coral: '#ff7f50',
20
+ cornflowerblue: '#6495ed',
21
+ cornsilk: '#fff8dc',
22
+ crimson: '#dc143c',
23
+ cyan: '#00ffff',
24
+ darkblue: '#00008b',
25
+ darkcyan: '#008b8b',
26
+ darkgoldenrod: '#b8860b',
27
+ darkgray: '#a9a9a9',
28
+ darkgreen: '#006400',
29
+ darkgrey: '#a9a9a9',
30
+ darkkhaki: '#bdb76b',
31
+ darkmagenta: '#8b008b',
32
+ darkolivegreen: '#556b2f',
33
+ darkorange: '#ff8c00',
34
+ darkorchid: '#9932cc',
35
+ darkred: '#8b0000',
36
+ darksalmon: '#e9967a',
37
+ darkseagreen: '#8fbc8f',
38
+ darkslateblue: '#483d8b',
39
+ darkslategray: '#2f4f4f',
40
+ darkslategrey: '#2f4f4f',
41
+ darkturquoise: '#00ced1',
42
+ darkviolet: '#9400d3',
43
+ deeppink: '#ff1493',
44
+ deepskyblue: '#00bfff',
45
+ dimgray: '#696969',
46
+ dimgrey: '#696969',
47
+ dodgerblue: '#1e90ff',
48
+ firebrick: '#b22222',
49
+ floralwhite: '#fffaf0',
50
+ forestgreen: '#228b22',
51
+ fuchsia: '#ff00ff',
52
+ gainsboro: '#dcdcdc',
53
+ ghostwhite: '#f8f8ff',
54
+ gold: '#ffd700',
55
+ goldenrod: '#daa520',
56
+ gray: '#808080',
57
+ green: '#008000',
58
+ greenyellow: '#adff2f',
59
+ grey: '#808080',
60
+ honeydew: '#f0fff0',
61
+ hotpink: '#ff69b4',
62
+ indianred: '#cd5c5c',
63
+ indigo: '#4b0082',
64
+ ivory: '#fffff0',
65
+ khaki: '#f0e68c',
66
+ lavender: '#e6e6fa',
67
+ lavenderblush: '#fff0f5',
68
+ lawngreen: '#7cfc00',
69
+ lemonchiffon: '#fffacd',
70
+ lightblue: '#add8e6',
71
+ lightcoral: '#f08080',
72
+ lightcyan: '#e0ffff',
73
+ lightgoldenrodyellow: '#fafad2',
74
+ lightgray: '#d3d3d3',
75
+ lightgreen: '#90ee90',
76
+ lightgrey: '#d3d3d3',
77
+ lightpink: '#ffb6c1',
78
+ lightsalmon: '#ffa07a',
79
+ lightseagreen: '#20b2aa',
80
+ lightskyblue: '#87cefa',
81
+ lightslategray: '#778899',
82
+ lightslategrey: '#778899',
83
+ lightsteelblue: '#b0c4de',
84
+ lightyellow: '#ffffe0',
85
+ lime: '#00ff00',
86
+ limegreen: '#32cd32',
87
+ linen: '#faf0e6',
88
+ magenta: '#ff00ff',
89
+ maroon: '#800000',
90
+ mediumaquamarine: '#66cdaa',
91
+ mediumblue: '#0000cd',
92
+ mediumorchid: '#ba55d3',
93
+ mediumpurple: '#9370db',
94
+ mediumseagreen: '#3cb371',
95
+ mediumslateblue: '#7b68ee',
96
+ mediumspringgreen: '#00fa9a',
97
+ mediumturquoise: '#48d1cc',
98
+ mediumvioletred: '#c71585',
99
+ midnightblue: '#191970',
100
+ mintcream: '#f5fffa',
101
+ mistyrose: '#ffe4e1',
102
+ moccasin: '#ffe4b5',
103
+ navajowhite: '#ffdead',
104
+ navy: '#000080',
105
+ oldlace: '#fdf5e6',
106
+ olive: '#808000',
107
+ olivedrab: '#6b8e23',
108
+ orange: '#ffa500',
109
+ orangered: '#ff4500',
110
+ orchid: '#da70d6',
111
+ palegoldenrod: '#eee8aa',
112
+ palegreen: '#98fb98',
113
+ paleturquoise: '#afeeee',
114
+ palevioletred: '#db7093',
115
+ papayawhip: '#ffefd5',
116
+ peachpuff: '#ffdab9',
117
+ peru: '#cd853f',
118
+ pink: '#ffc0cb',
119
+ plum: '#dda0dd',
120
+ powderblue: '#b0e0e6',
121
+ purple: '#800080',
122
+ rebeccapurple: '#663399',
123
+ red: '#ff0000',
124
+ rosybrown: '#bc8f8f',
125
+ royalblue: '#4169e1',
126
+ saddlebrown: '#8b4513',
127
+ salmon: '#fa8072',
128
+ sandybrown: '#f4a460',
129
+ seagreen: '#2e8b57',
130
+ seashell: '#fff5ee',
131
+ sienna: '#a0522d',
132
+ silver: '#c0c0c0',
133
+ skyblue: '#87ceeb',
134
+ slateblue: '#6a5acd',
135
+ slategray: '#708090',
136
+ slategrey: '#708090',
137
+ snow: '#fffafa',
138
+ springgreen: '#00ff7f',
139
+ steelblue: '#4682b4',
140
+ tan: '#d2b48c',
141
+ teal: '#008080',
142
+ thistle: '#d8bfd8',
143
+ tomato: '#ff6347',
144
+ turquoise: '#40e0d0',
145
+ violet: '#ee82ee',
146
+ wheat: '#f5deb3',
147
+ white: '#ffffff',
148
+ whitesmoke: '#f5f5f5',
149
+ yellow: '#ffff00',
150
+ yellowgreen: '#9acd32',
151
+ // 'transparent' is the only CSS-wide keyword with an actual fixed color (fully
152
+ // transparent black) — normalizeColor() special-cases it before ever reaching
153
+ // this table (see the `str === 'transparent'` check), so this entry only
154
+ // matters for getColorType()/toNearestNamedColor(), which read the table
155
+ // directly. 'currentcolor'/'inherit'/'initial'/'unset' are deliberately NOT
156
+ // listed here: none of them has a color value of their own (they only resolve
157
+ // to one given surrounding DOM/CSSOM context this library never has access
158
+ // to), so treating them as resolvable named colors would mean fabricating an
159
+ // arbitrary RGB value with no way for a caller to tell it apart from a real
160
+ // one — see normalizeColor()'s `type: 'unknown'` fallback for these instead.
161
+ transparent: 'transparent',
162
+ };
@@ -0,0 +1,2 @@
1
+ export declare function srgbChanToLinear(v: number): number;
2
+ export declare function linearChanToSrgb(v: number): number;
@@ -0,0 +1,8 @@
1
+ // sRGB transfer functions (operate on 0-1 values)
2
+ export function srgbChanToLinear(v) {
3
+ return v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
4
+ }
5
+ export function linearChanToSrgb(v) {
6
+ const t = v <= 0.0031308 ? 12.92 * v : 1.055 * Math.pow(v, 1 / 2.4) - 0.055;
7
+ return Math.max(0, Math.min(1, t));
8
+ }
@@ -0,0 +1,15 @@
1
+ export declare function adjustHexBrightness(hex: string, offsetPercent: number): string;
2
+ export declare function rotateHue(hex: string, degrees: number): string;
3
+ export declare function lighten(color: string, amount: number): string;
4
+ export declare function darken(color: string, amount: number): string;
5
+ export declare function saturate(color: string, amount: number): string;
6
+ export declare function desaturate(color: string, amount: number): string;
7
+ export declare function setAlpha(color: string, alpha: number): string;
8
+ export declare function getAlpha(color: string): number;
9
+ export declare function invertColor(color: string): string;
10
+ export declare function grayscale(color: string): string;
11
+ export declare function mixColors(c1: string, c2: string, t: number, opts?: {
12
+ mode?: 'rgb' | 'hsl' | 'lab' | 'lch' | 'oklab' | 'oklch';
13
+ format?: 'hex' | 'rgb' | 'rgba' | 'hsl';
14
+ hueInterpolation?: 'shorter' | 'longer' | 'increasing' | 'decreasing';
15
+ }): string;
@@ -0,0 +1,210 @@
1
+ // Adjusting and mixing colors.
2
+ import { normalizeColor } from './parse.js';
3
+ import { hexToHsl, hslToHex, hslToRgb, labToRgb, lchToRgb, normalizeHex, oklabToRgb, oklchToRgb, rgbToHex, rgbToHsl, rgbToLab, rgbToLch, rgbToOklab, rgbToOklch, rgbToRgbaString, } from './convert/spaces.js';
4
+ export function adjustHexBrightness(hex, offsetPercent) {
5
+ const normalizedHex = normalizeHex(hex);
6
+ const p = Math.max(-100, Math.min(100, offsetPercent)) / 100;
7
+ const r = parseInt(normalizedHex.slice(1, 3), 16);
8
+ const g = parseInt(normalizedHex.slice(3, 5), 16);
9
+ const b = parseInt(normalizedHex.slice(5, 7), 16);
10
+ const adjustChannel = (channel) => {
11
+ if (p > 0)
12
+ return Math.min(255, Math.floor(channel + (255 - channel) * p));
13
+ else if (p < 0)
14
+ return Math.max(0, Math.floor(channel * (1 + p)));
15
+ return channel;
16
+ };
17
+ const newR = adjustChannel(r);
18
+ const newG = adjustChannel(g);
19
+ const newB = adjustChannel(b);
20
+ return `#${newR.toString(16).padStart(2, '0')}${newG.toString(16).padStart(2, '0')}${newB.toString(16).padStart(2, '0')}`;
21
+ }
22
+ export function rotateHue(hex, degrees) {
23
+ const [h, s, l] = hexToHsl(hex);
24
+ const newH = (((h + degrees) % 360) + 360) % 360;
25
+ return hslToHex(newH, s, l);
26
+ }
27
+ export function lighten(color, amount) {
28
+ var _a, _b, _c;
29
+ const n = normalizeColor(color);
30
+ const h = (_a = n.h) !== null && _a !== void 0 ? _a : 0;
31
+ const s = (_b = n.s) !== null && _b !== void 0 ? _b : 0;
32
+ const l = Math.min(100, ((_c = n.l) !== null && _c !== void 0 ? _c : 0) + amount);
33
+ return hslToHex(h, s, l);
34
+ }
35
+ export function darken(color, amount) {
36
+ var _a, _b, _c;
37
+ const n = normalizeColor(color);
38
+ const h = (_a = n.h) !== null && _a !== void 0 ? _a : 0;
39
+ const s = (_b = n.s) !== null && _b !== void 0 ? _b : 0;
40
+ const l = Math.max(0, ((_c = n.l) !== null && _c !== void 0 ? _c : 0) - amount);
41
+ return hslToHex(h, s, l);
42
+ }
43
+ export function saturate(color, amount) {
44
+ var _a, _b, _c;
45
+ const n = normalizeColor(color);
46
+ const h = (_a = n.h) !== null && _a !== void 0 ? _a : 0;
47
+ const s = Math.min(100, ((_b = n.s) !== null && _b !== void 0 ? _b : 0) + amount);
48
+ const l = (_c = n.l) !== null && _c !== void 0 ? _c : 0;
49
+ return hslToHex(h, s, l);
50
+ }
51
+ export function desaturate(color, amount) {
52
+ var _a, _b, _c;
53
+ const n = normalizeColor(color);
54
+ const h = (_a = n.h) !== null && _a !== void 0 ? _a : 0;
55
+ const s = Math.max(0, ((_b = n.s) !== null && _b !== void 0 ? _b : 0) - amount);
56
+ const l = (_c = n.l) !== null && _c !== void 0 ? _c : 0;
57
+ return hslToHex(h, s, l);
58
+ }
59
+ export function setAlpha(color, alpha) {
60
+ var _a, _b, _c;
61
+ const n = normalizeColor(color);
62
+ const r = (_a = n.r) !== null && _a !== void 0 ? _a : 0;
63
+ const g = (_b = n.g) !== null && _b !== void 0 ? _b : 0;
64
+ const b = (_c = n.b) !== null && _c !== void 0 ? _c : 0;
65
+ const a = Math.max(0, Math.min(1, alpha));
66
+ return `rgba(${r}, ${g}, ${b}, ${+a.toFixed(3)})`;
67
+ }
68
+ export function getAlpha(color) {
69
+ var _a;
70
+ const n = normalizeColor(color);
71
+ return (_a = n.a) !== null && _a !== void 0 ? _a : 1;
72
+ }
73
+ export function invertColor(color) {
74
+ var _a, _b, _c;
75
+ const n = normalizeColor(color);
76
+ const r = 255 - ((_a = n.r) !== null && _a !== void 0 ? _a : 0);
77
+ const g = 255 - ((_b = n.g) !== null && _b !== void 0 ? _b : 0);
78
+ const b = 255 - ((_c = n.b) !== null && _c !== void 0 ? _c : 0);
79
+ return rgbToHex({ r, g, b });
80
+ }
81
+ export function grayscale(color) {
82
+ var _a, _b, _c;
83
+ const n = normalizeColor(color);
84
+ const r = (_a = n.r) !== null && _a !== void 0 ? _a : 0;
85
+ const g = (_b = n.g) !== null && _b !== void 0 ? _b : 0;
86
+ const b = (_c = n.b) !== null && _c !== void 0 ? _c : 0;
87
+ // Perceptual luminance weights (ITU-R BT.709)
88
+ const gray = Math.round(0.2126 * r + 0.7152 * g + 0.0722 * b);
89
+ return rgbToHex({ r: gray, g: gray, b: gray });
90
+ }
91
+ function _lerpHue(h1, h2, t, mode = 'shorter') {
92
+ let d = h2 - h1;
93
+ if (mode === 'shorter') {
94
+ if (d > 180)
95
+ d -= 360;
96
+ else if (d < -180)
97
+ d += 360;
98
+ }
99
+ else if (mode === 'longer') {
100
+ if (d > 0 && d < 180)
101
+ d -= 360;
102
+ else if (d < 0 && d > -180)
103
+ d += 360;
104
+ }
105
+ else if (mode === 'increasing') {
106
+ if (d < 0)
107
+ d += 360;
108
+ }
109
+ else if (mode === 'decreasing') {
110
+ if (d > 0)
111
+ d -= 360;
112
+ }
113
+ return h1 + d * t;
114
+ }
115
+ function _formatMixResult(r, g, b, a, out) {
116
+ if (out === 'hex')
117
+ return rgbToHex({ r: Math.round(r), g: Math.round(g), b: Math.round(b) });
118
+ if (out === 'rgba')
119
+ return rgbToRgbaString({ r: Math.round(r), g: Math.round(g), b: Math.round(b) }, a);
120
+ if (out === 'rgb')
121
+ return `rgb(${Math.round(r)}, ${Math.round(g)}, ${Math.round(b)})`;
122
+ if (out === 'hsl') {
123
+ const [hh, ss, ll] = rgbToHsl({ r: Math.round(r), g: Math.round(g), b: Math.round(b) });
124
+ return `hsl(${hh}, ${ss}%, ${ll}%)`;
125
+ }
126
+ return rgbToHex({ r: Math.round(r), g: Math.round(g), b: Math.round(b) });
127
+ }
128
+ export function mixColors(c1, c2, t, opts) {
129
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35;
130
+ const o1 = normalizeColor(c1);
131
+ const o2 = normalizeColor(c2);
132
+ t = Math.max(0, Math.min(1, t));
133
+ const mode = (opts === null || opts === void 0 ? void 0 : opts.mode) || 'rgb';
134
+ const out = (opts === null || opts === void 0 ? void 0 : opts.format) || 'hex';
135
+ const hueMode = (_a = opts === null || opts === void 0 ? void 0 : opts.hueInterpolation) !== null && _a !== void 0 ? _a : 'shorter';
136
+ let r = 0, g = 0, b = 0, a = 1;
137
+ if (mode === 'hsl') {
138
+ const h1 = (_b = o1.h) !== null && _b !== void 0 ? _b : rgbToHsl({ r: (_c = o1.r) !== null && _c !== void 0 ? _c : 0, g: (_d = o1.g) !== null && _d !== void 0 ? _d : 0, b: (_e = o1.b) !== null && _e !== void 0 ? _e : 0 })[0];
139
+ const s1 = (_f = o1.s) !== null && _f !== void 0 ? _f : 0;
140
+ const l1 = (_g = o1.l) !== null && _g !== void 0 ? _g : 0;
141
+ const h2 = (_h = o2.h) !== null && _h !== void 0 ? _h : rgbToHsl({ r: (_j = o2.r) !== null && _j !== void 0 ? _j : 0, g: (_k = o2.g) !== null && _k !== void 0 ? _k : 0, b: (_l = o2.b) !== null && _l !== void 0 ? _l : 0 })[0];
142
+ const s2 = (_m = o2.s) !== null && _m !== void 0 ? _m : 0;
143
+ const l2 = (_o = o2.l) !== null && _o !== void 0 ? _o : 0;
144
+ const ih = _lerpHue(h1, h2, t, hueMode);
145
+ const rgb = hslToRgb(ih, s1 + (s2 - s1) * t, l1 + (l2 - l1) * t);
146
+ r = rgb.r;
147
+ g = rgb.g;
148
+ b = rgb.b;
149
+ a = ((_p = o1.a) !== null && _p !== void 0 ? _p : 1) + (((_q = o2.a) !== null && _q !== void 0 ? _q : 1) - ((_r = o1.a) !== null && _r !== void 0 ? _r : 1)) * t;
150
+ }
151
+ else if (mode === 'lab') {
152
+ const lab1 = rgbToLab({ r: (_s = o1.r) !== null && _s !== void 0 ? _s : 0, g: (_t = o1.g) !== null && _t !== void 0 ? _t : 0, b: (_u = o1.b) !== null && _u !== void 0 ? _u : 0 });
153
+ const lab2 = rgbToLab({ r: (_v = o2.r) !== null && _v !== void 0 ? _v : 0, g: (_w = o2.g) !== null && _w !== void 0 ? _w : 0, b: (_x = o2.b) !== null && _x !== void 0 ? _x : 0 });
154
+ const mixed = labToRgb({
155
+ L: lab1.L + (lab2.L - lab1.L) * t,
156
+ a: lab1.a + (lab2.a - lab1.a) * t,
157
+ b: lab1.b + (lab2.b - lab1.b) * t,
158
+ });
159
+ r = mixed.r;
160
+ g = mixed.g;
161
+ b = mixed.b;
162
+ a = ((_y = o1.a) !== null && _y !== void 0 ? _y : 1) + (((_z = o2.a) !== null && _z !== void 0 ? _z : 1) - ((_0 = o1.a) !== null && _0 !== void 0 ? _0 : 1)) * t;
163
+ }
164
+ else if (mode === 'lch') {
165
+ const lch1 = rgbToLch({ r: (_1 = o1.r) !== null && _1 !== void 0 ? _1 : 0, g: (_2 = o1.g) !== null && _2 !== void 0 ? _2 : 0, b: (_3 = o1.b) !== null && _3 !== void 0 ? _3 : 0 });
166
+ const lch2 = rgbToLch({ r: (_4 = o2.r) !== null && _4 !== void 0 ? _4 : 0, g: (_5 = o2.g) !== null && _5 !== void 0 ? _5 : 0, b: (_6 = o2.b) !== null && _6 !== void 0 ? _6 : 0 });
167
+ const mixed = lchToRgb({
168
+ L: lch1.L + (lch2.L - lch1.L) * t,
169
+ C: lch1.C + (lch2.C - lch1.C) * t,
170
+ H: _lerpHue(lch1.H, lch2.H, t, hueMode),
171
+ });
172
+ r = mixed.r;
173
+ g = mixed.g;
174
+ b = mixed.b;
175
+ a = ((_7 = o1.a) !== null && _7 !== void 0 ? _7 : 1) + (((_8 = o2.a) !== null && _8 !== void 0 ? _8 : 1) - ((_9 = o1.a) !== null && _9 !== void 0 ? _9 : 1)) * t;
176
+ }
177
+ else if (mode === 'oklab') {
178
+ const ok1 = rgbToOklab({ r: (_10 = o1.r) !== null && _10 !== void 0 ? _10 : 0, g: (_11 = o1.g) !== null && _11 !== void 0 ? _11 : 0, b: (_12 = o1.b) !== null && _12 !== void 0 ? _12 : 0 });
179
+ const ok2 = rgbToOklab({ r: (_13 = o2.r) !== null && _13 !== void 0 ? _13 : 0, g: (_14 = o2.g) !== null && _14 !== void 0 ? _14 : 0, b: (_15 = o2.b) !== null && _15 !== void 0 ? _15 : 0 });
180
+ const mixed = oklabToRgb({
181
+ L: ok1.L + (ok2.L - ok1.L) * t,
182
+ a: ok1.a + (ok2.a - ok1.a) * t,
183
+ b: ok1.b + (ok2.b - ok1.b) * t,
184
+ });
185
+ r = mixed.r;
186
+ g = mixed.g;
187
+ b = mixed.b;
188
+ a = ((_16 = o1.a) !== null && _16 !== void 0 ? _16 : 1) + (((_17 = o2.a) !== null && _17 !== void 0 ? _17 : 1) - ((_18 = o1.a) !== null && _18 !== void 0 ? _18 : 1)) * t;
189
+ }
190
+ else if (mode === 'oklch') {
191
+ const ok1 = rgbToOklch({ r: (_19 = o1.r) !== null && _19 !== void 0 ? _19 : 0, g: (_20 = o1.g) !== null && _20 !== void 0 ? _20 : 0, b: (_21 = o1.b) !== null && _21 !== void 0 ? _21 : 0 });
192
+ const ok2 = rgbToOklch({ r: (_22 = o2.r) !== null && _22 !== void 0 ? _22 : 0, g: (_23 = o2.g) !== null && _23 !== void 0 ? _23 : 0, b: (_24 = o2.b) !== null && _24 !== void 0 ? _24 : 0 });
193
+ const mixed = oklchToRgb({
194
+ L: ok1.L + (ok2.L - ok1.L) * t,
195
+ C: ok1.C + (ok2.C - ok1.C) * t,
196
+ H: _lerpHue(ok1.H, ok2.H, t, hueMode),
197
+ });
198
+ r = mixed.r;
199
+ g = mixed.g;
200
+ b = mixed.b;
201
+ a = ((_25 = o1.a) !== null && _25 !== void 0 ? _25 : 1) + (((_26 = o2.a) !== null && _26 !== void 0 ? _26 : 1) - ((_27 = o1.a) !== null && _27 !== void 0 ? _27 : 1)) * t;
202
+ }
203
+ else {
204
+ r = ((_28 = o1.r) !== null && _28 !== void 0 ? _28 : 0) * (1 - t) + ((_29 = o2.r) !== null && _29 !== void 0 ? _29 : 0) * t;
205
+ g = ((_30 = o1.g) !== null && _30 !== void 0 ? _30 : 0) * (1 - t) + ((_31 = o2.g) !== null && _31 !== void 0 ? _31 : 0) * t;
206
+ b = ((_32 = o1.b) !== null && _32 !== void 0 ? _32 : 0) * (1 - t) + ((_33 = o2.b) !== null && _33 !== void 0 ? _33 : 0) * t;
207
+ a = ((_34 = o1.a) !== null && _34 !== void 0 ? _34 : 1) * (1 - t) + ((_35 = o2.a) !== null && _35 !== void 0 ? _35 : 1) * t;
208
+ }
209
+ return _formatMixResult(r, g, b, a, out);
210
+ }
@@ -1 +1,3 @@
1
- {"type":"module"}
1
+ {
2
+ "type": "module"
3
+ }
@@ -0,0 +1,40 @@
1
+ export declare function complement(color: string): string;
2
+ export declare function triadic(color: string): [string, string, string];
3
+ export declare function analogous(color: string, angle?: number): [string, string, string];
4
+ export declare function splitComplementary(color: string): [string, string, string];
5
+ export declare function tetradic(color: string): [string, string, string, string];
6
+ export declare function colorShades(color: string, steps?: number): string[];
7
+ export declare function monochromatic(color: string, steps?: number): string[];
8
+ export declare function randomColor(options?: {
9
+ hRange?: [number, number];
10
+ sRange?: [number, number];
11
+ lRange?: [number, number];
12
+ }): string;
13
+ export declare function interpolateColors(color1: string, color2: string, steps: number, options?: {
14
+ space?: 'rgb' | 'hsl' | 'lab' | 'lch' | 'oklab' | 'oklch';
15
+ format?: 'hex' | 'rgb' | 'rgba' | 'hsl';
16
+ hueInterpolation?: 'shorter' | 'longer' | 'increasing' | 'decreasing';
17
+ }): string[];
18
+ export declare function createColorScale(anchors: string[] | Array<{
19
+ color: string;
20
+ position?: number;
21
+ }>, steps: number, options?: {
22
+ space?: 'rgb' | 'hsl' | 'oklab' | 'oklch';
23
+ format?: 'hex' | 'rgb' | 'hsl';
24
+ }): string[];
25
+ export declare function midpointColor(color1: string, color2: string, options?: {
26
+ space?: 'lab' | 'lch' | 'oklab' | 'oklch';
27
+ }): string;
28
+ export declare function tints(color: string, steps?: number): string[];
29
+ export declare function shades(color: string, steps?: number): string[];
30
+ export declare function tones(color: string, steps?: number, gray?: string): string[];
31
+ export declare function generateGradientColors(start: string, end: string, steps: number, options?: {
32
+ mode?: 'rgb' | 'hsl' | 'oklab' | 'oklch';
33
+ format?: 'hex' | 'rgb' | 'hsl';
34
+ }): Generator<string>;
35
+ export declare function generateTints(color: string, steps: number, options?: {
36
+ format?: 'hex' | 'rgb' | 'hsl';
37
+ }): Generator<string>;
38
+ export declare function generateShades(color: string, steps: number, options?: {
39
+ format?: 'hex' | 'rgb' | 'hsl';
40
+ }): Generator<string>;
@@ -0,0 +1,145 @@
1
+ // Harmonies, scales, tints/shades and color generators.
2
+ import { normalizeColor } from './parse.js';
3
+ import { hslToHex } from './convert/spaces.js';
4
+ import { mixColors, rotateHue } from './manipulate.js';
5
+ export function complement(color) {
6
+ var _a;
7
+ return rotateHue((_a = normalizeColor(color).hex) !== null && _a !== void 0 ? _a : '#000000', 180);
8
+ }
9
+ export function triadic(color) {
10
+ var _a;
11
+ const hex = (_a = normalizeColor(color).hex) !== null && _a !== void 0 ? _a : '#000000';
12
+ return [hex, rotateHue(hex, 120), rotateHue(hex, 240)];
13
+ }
14
+ export function analogous(color, angle = 30) {
15
+ var _a;
16
+ const hex = (_a = normalizeColor(color).hex) !== null && _a !== void 0 ? _a : '#000000';
17
+ return [rotateHue(hex, -angle), hex, rotateHue(hex, angle)];
18
+ }
19
+ export function splitComplementary(color) {
20
+ var _a;
21
+ const hex = (_a = normalizeColor(color).hex) !== null && _a !== void 0 ? _a : '#000000';
22
+ return [hex, rotateHue(hex, 150), rotateHue(hex, 210)];
23
+ }
24
+ export function tetradic(color) {
25
+ var _a;
26
+ const hex = (_a = normalizeColor(color).hex) !== null && _a !== void 0 ? _a : '#000000';
27
+ return [hex, rotateHue(hex, 90), rotateHue(hex, 180), rotateHue(hex, 270)];
28
+ }
29
+ export function colorShades(color, steps = 9) {
30
+ var _a, _b, _c;
31
+ const n = normalizeColor(color);
32
+ const h = (_a = n.h) !== null && _a !== void 0 ? _a : 0;
33
+ const s = (_b = n.s) !== null && _b !== void 0 ? _b : 0;
34
+ // steps - 1 === 0 below would otherwise divide by zero (NaN lightness, then
35
+ // a literal "#NaNNaNNaN" hex string) — a single shade is just the color's
36
+ // own lightness, same idea as interpolateColors() returning the midpoint
37
+ // for a 2-color, 1-step request.
38
+ if (steps <= 1)
39
+ return steps === 1 ? [hslToHex(h, s, (_c = n.l) !== null && _c !== void 0 ? _c : 50)] : [];
40
+ const result = [];
41
+ for (let i = 0; i < steps; i++) {
42
+ const l = Math.round(100 - (i / (steps - 1)) * 100);
43
+ result.push(hslToHex(h, s, l));
44
+ }
45
+ return result;
46
+ }
47
+ export function monochromatic(color, steps = 5) {
48
+ var _a, _b, _c;
49
+ const n = normalizeColor(color);
50
+ const h = (_a = n.h) !== null && _a !== void 0 ? _a : 0;
51
+ const l = (_b = n.l) !== null && _b !== void 0 ? _b : 50;
52
+ // Same steps === 1 divide-by-zero guard as colorShades() above.
53
+ if (steps <= 1)
54
+ return steps === 1 ? [hslToHex(h, (_c = n.s) !== null && _c !== void 0 ? _c : 0, l)] : [];
55
+ const result = [];
56
+ for (let i = 0; i < steps; i++) {
57
+ const s = Math.round((i / (steps - 1)) * 100);
58
+ result.push(hslToHex(h, s, l));
59
+ }
60
+ return result;
61
+ }
62
+ export function randomColor(options) {
63
+ var _a, _b, _c;
64
+ const [hMin, hMax] = (_a = options === null || options === void 0 ? void 0 : options.hRange) !== null && _a !== void 0 ? _a : [0, 360];
65
+ const [sMin, sMax] = (_b = options === null || options === void 0 ? void 0 : options.sRange) !== null && _b !== void 0 ? _b : [40, 90];
66
+ const [lMin, lMax] = (_c = options === null || options === void 0 ? void 0 : options.lRange) !== null && _c !== void 0 ? _c : [30, 70];
67
+ const h = Math.floor(Math.random() * (hMax - hMin)) + hMin;
68
+ const s = Math.floor(Math.random() * (sMax - sMin)) + sMin;
69
+ const l = Math.floor(Math.random() * (lMax - lMin)) + lMin;
70
+ return hslToHex(h, s, l);
71
+ }
72
+ // ─── Interpolation ─────────────────────────────────────────────────
73
+ export function interpolateColors(color1, color2, steps, options) {
74
+ if (steps < 2)
75
+ return steps === 1 ? [mixColors(color1, color2, 0.5, options)] : [];
76
+ const result = [];
77
+ for (let i = 0; i < steps; i++) {
78
+ result.push(mixColors(color1, color2, i / (steps - 1), options));
79
+ }
80
+ return result;
81
+ }
82
+ export function createColorScale(anchors, steps, options) {
83
+ const normalized = anchors.map((a, i, arr) => {
84
+ var _a;
85
+ return ({
86
+ color: typeof a === 'string' ? a : a.color,
87
+ position: typeof a === 'string'
88
+ ? i / Math.max(arr.length - 1, 1)
89
+ : ((_a = a.position) !== null && _a !== void 0 ? _a : i / Math.max(arr.length - 1, 1)),
90
+ });
91
+ });
92
+ normalized.sort((a, b) => a.position - b.position);
93
+ const result = [];
94
+ for (let i = 0; i < steps; i++) {
95
+ const t = steps === 1 ? 0 : i / (steps - 1);
96
+ let lo = normalized[0], hi = normalized[normalized.length - 1];
97
+ for (let j = 0; j < normalized.length - 1; j++) {
98
+ if (t >= normalized[j].position && t <= normalized[j + 1].position) {
99
+ lo = normalized[j];
100
+ hi = normalized[j + 1];
101
+ break;
102
+ }
103
+ }
104
+ const span = hi.position - lo.position;
105
+ const localT = span === 0 ? 0 : (t - lo.position) / span;
106
+ result.push(mixColors(lo.color, hi.color, localT, options));
107
+ }
108
+ return result;
109
+ }
110
+ export function midpointColor(color1, color2, options) {
111
+ var _a;
112
+ return mixColors(color1, color2, 0.5, { mode: (_a = options === null || options === void 0 ? void 0 : options.space) !== null && _a !== void 0 ? _a : 'oklab' });
113
+ }
114
+ // ─── Tints / Shades / Tones ───────────────────────────────────────
115
+ export function tints(color, steps = 5) {
116
+ return interpolateColors(color, '#ffffff', steps, { space: 'oklab' });
117
+ }
118
+ export function shades(color, steps = 5) {
119
+ return interpolateColors(color, '#000000', steps, { space: 'oklab' });
120
+ }
121
+ export function tones(color, steps = 5, gray = '#808080') {
122
+ return interpolateColors(color, gray, steps, { space: 'oklab' });
123
+ }
124
+ // ─── Generator functions ────────────────────────────────────────
125
+ export function* generateGradientColors(start, end, steps, options) {
126
+ for (let i = 0; i < steps; i++) {
127
+ yield mixColors(start, end, steps === 1 ? 0 : i / (steps - 1), options);
128
+ }
129
+ }
130
+ export function* generateTints(color, steps, options) {
131
+ for (let i = 0; i < steps; i++) {
132
+ yield mixColors(color, '#ffffff', steps === 1 ? 0 : i / (steps - 1), {
133
+ mode: 'oklab',
134
+ ...options,
135
+ });
136
+ }
137
+ }
138
+ export function* generateShades(color, steps, options) {
139
+ for (let i = 0; i < steps; i++) {
140
+ yield mixColors(color, '#000000', steps === 1 ? 0 : i / (steps - 1), {
141
+ mode: 'oklab',
142
+ ...options,
143
+ });
144
+ }
145
+ }