color-value-tools 1.2.1 → 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 -1466
  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 -1368
  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 -1468
@@ -0,0 +1,102 @@
1
+ export type ColorType = 'hex' | 'css-var' | 'rgb' | 'hsl' | 'named' | 'oklch' | 'color' | 'unknown';
2
+ export declare function isCssVariable(value: string): boolean;
3
+ export declare function isHexColor(value: string): boolean;
4
+ export declare function isOklchColor(value: string): boolean;
5
+ export declare function isColorFunction(value: string): boolean;
6
+ export declare function isRgbColor(value: string): boolean;
7
+ export declare function isHslColor(value: string): boolean;
8
+ export declare function getColorType(value: string): ColorType;
9
+ export declare function extractCssVariableName(value: string): string;
10
+ export declare function parseCssVar(value: string): {
11
+ variableName: string;
12
+ fallback?: string;
13
+ } | null;
14
+ export declare function parseOklchString(str: string): {
15
+ L: number;
16
+ C: number;
17
+ H: number;
18
+ alpha: number;
19
+ } | null;
20
+ export declare function parseColorFn(str: string): {
21
+ space: string;
22
+ r: number;
23
+ g: number;
24
+ b: number;
25
+ alpha: number;
26
+ } | null;
27
+ export declare function normalizeColor(input: string | {
28
+ r: number;
29
+ g: number;
30
+ b: number;
31
+ } | {
32
+ h: number;
33
+ s: number;
34
+ l: number;
35
+ }): {
36
+ type: string;
37
+ hex: string;
38
+ r: any;
39
+ g: any;
40
+ b: any;
41
+ a: number;
42
+ h: number;
43
+ s: number;
44
+ l: number;
45
+ v: number;
46
+ raw?: undefined;
47
+ } | {
48
+ type: string;
49
+ hex: string;
50
+ r: number;
51
+ g: number;
52
+ b: number;
53
+ a: number;
54
+ h: any;
55
+ s: any;
56
+ l: any;
57
+ v: number;
58
+ raw?: undefined;
59
+ } | {
60
+ type: string;
61
+ hex?: undefined;
62
+ r?: undefined;
63
+ g?: undefined;
64
+ b?: undefined;
65
+ a?: undefined;
66
+ h?: undefined;
67
+ s?: undefined;
68
+ l?: undefined;
69
+ v?: undefined;
70
+ raw?: undefined;
71
+ } | {
72
+ type: string;
73
+ raw: string;
74
+ hex?: undefined;
75
+ r?: undefined;
76
+ g?: undefined;
77
+ b?: undefined;
78
+ a?: undefined;
79
+ h?: undefined;
80
+ s?: undefined;
81
+ l?: undefined;
82
+ v?: undefined;
83
+ } | {
84
+ type: string;
85
+ hex: string;
86
+ r: number;
87
+ g: number;
88
+ b: number;
89
+ a: number;
90
+ h?: undefined;
91
+ s?: undefined;
92
+ l?: undefined;
93
+ v?: undefined;
94
+ raw?: undefined;
95
+ };
96
+ export declare function parseHwbString(str: string): {
97
+ H: number;
98
+ W: number;
99
+ B: number;
100
+ alpha: number;
101
+ } | null;
102
+ export declare function toNearestNamedColor(color: string): string;
@@ -0,0 +1,257 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isCssVariable = isCssVariable;
4
+ exports.isHexColor = isHexColor;
5
+ exports.isOklchColor = isOklchColor;
6
+ exports.isColorFunction = isColorFunction;
7
+ exports.isRgbColor = isRgbColor;
8
+ exports.isHslColor = isHslColor;
9
+ exports.getColorType = getColorType;
10
+ exports.extractCssVariableName = extractCssVariableName;
11
+ exports.parseCssVar = parseCssVar;
12
+ exports.parseOklchString = parseOklchString;
13
+ exports.parseColorFn = parseColorFn;
14
+ exports.normalizeColor = normalizeColor;
15
+ exports.parseHwbString = parseHwbString;
16
+ exports.toNearestNamedColor = toNearestNamedColor;
17
+ // Detecting, parsing and normalizing CSS color strings.
18
+ const named_colors_js_1 = require("./internal/named-colors.js");
19
+ const transfer_js_1 = require("./internal/transfer.js");
20
+ const spaces_js_1 = require("./convert/spaces.js");
21
+ function isCssVariable(value) {
22
+ return value.trim().startsWith('var(--');
23
+ }
24
+ function isHexColor(value) {
25
+ const trimmed = value.trim();
26
+ return /^#?([0-9A-Fa-f]{3}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(trimmed);
27
+ }
28
+ function isOklchColor(value) {
29
+ return /^\s*oklcha?\s*\(/i.test(value.trim());
30
+ }
31
+ function isColorFunction(value) {
32
+ return /^\s*color\s*\(\s*(display-p3|srgb|srgb-linear)\s/i.test(value.trim());
33
+ }
34
+ function isRgbColor(value) {
35
+ const trimmed = value.trim().toLowerCase();
36
+ return trimmed.startsWith('rgb(') || trimmed.startsWith('rgba(');
37
+ }
38
+ function isHslColor(value) {
39
+ const trimmed = value.trim().toLowerCase();
40
+ return trimmed.startsWith('hsl(') || trimmed.startsWith('hsla(');
41
+ }
42
+ function getColorType(value) {
43
+ const trimmed = value.trim();
44
+ const lower = trimmed.toLowerCase();
45
+ if (isCssVariable(trimmed))
46
+ return 'css-var';
47
+ if (isHexColor(trimmed))
48
+ return 'hex';
49
+ if (isRgbColor(trimmed))
50
+ return 'rgb';
51
+ if (isHslColor(trimmed))
52
+ return 'hsl';
53
+ if (isOklchColor(trimmed))
54
+ return 'oklch';
55
+ if (isColorFunction(trimmed))
56
+ return 'color';
57
+ if (lower in named_colors_js_1.NAMED_COLORS)
58
+ return 'named';
59
+ return 'unknown';
60
+ }
61
+ function extractCssVariableName(value) {
62
+ var _a;
63
+ const match = value.match(/var\(\s*(--[^,)]+)/);
64
+ return ((_a = match === null || match === void 0 ? void 0 : match[1]) === null || _a === void 0 ? void 0 : _a.trim()) || value;
65
+ }
66
+ function parseCssVar(value) {
67
+ var _a;
68
+ const m = value.trim().match(/^var\(\s*(--[^,)]+)(?:,\s*([\s\S]+?))?\s*\)$/);
69
+ if (!m)
70
+ return null;
71
+ return { variableName: m[1].trim(), fallback: (_a = m[2]) === null || _a === void 0 ? void 0 : _a.trim() };
72
+ }
73
+ // ─── OKLCH / color() CSS string parsing ────────────────────────
74
+ function parseOklchString(str) {
75
+ const m = str
76
+ .trim()
77
+ .match(/oklcha?\(\s*([\d.]+%?)\s+([\d.]+)\s+([\d.]+)(?:\s*\/\s*([\d.]+))?\s*\)/i);
78
+ if (!m)
79
+ return null;
80
+ let L = parseFloat(m[1]);
81
+ if (m[1].endsWith('%'))
82
+ L = L / 100;
83
+ const C = parseFloat(m[2]);
84
+ const H = parseFloat(m[3]);
85
+ const alpha = m[4] !== undefined ? parseFloat(m[4]) : 1;
86
+ return { L, C, H, alpha };
87
+ }
88
+ function parseColorFn(str) {
89
+ const m = str
90
+ .trim()
91
+ .match(/color\(\s*([\w-]+)\s+([\d.]+%?)\s+([\d.]+%?)\s+([\d.]+%?)(?:\s*\/\s*([\d.]+))?\s*\)/i);
92
+ if (!m)
93
+ return null;
94
+ const space = m[1].toLowerCase();
95
+ const parseVal = (v) => (v.endsWith('%') ? parseFloat(v) / 100 : parseFloat(v));
96
+ const r = parseVal(m[2]);
97
+ const g = parseVal(m[3]);
98
+ const b = parseVal(m[4]);
99
+ const alpha = m[5] !== undefined ? parseFloat(m[5]) : 1;
100
+ return { space, r, g, b, alpha };
101
+ }
102
+ function normalizeColor(input) {
103
+ if (typeof input !== 'string') {
104
+ if ('r' in input && 'g' in input && 'b' in input) {
105
+ const { r, g, b } = input;
106
+ const hex = (0, spaces_js_1.rgbToHex)({ r, g, b });
107
+ const [h, s, l] = (0, spaces_js_1.rgbToHsl)({ r, g, b });
108
+ const [hh, ss, vv] = (0, spaces_js_1.rgbToHsv)({ r, g, b });
109
+ return { type: 'rgb', hex, r, g, b, a: 1, h, s, l, v: vv };
110
+ }
111
+ if ('h' in input && 's' in input && 'l' in input) {
112
+ const { h, s, l } = input;
113
+ const { r, g, b } = (0, spaces_js_1.hslToRgb)(h, s, l);
114
+ const hex = (0, spaces_js_1.rgbToHex)({ r, g, b });
115
+ const [hh, ss, vv] = (0, spaces_js_1.rgbToHsv)({ r, g, b });
116
+ return { type: 'hsl', hex, r, g, b, a: 1, h, s, l, v: vv };
117
+ }
118
+ return { type: 'unknown' };
119
+ }
120
+ const str = input.trim();
121
+ if (isCssVariable(str))
122
+ return { type: 'css-var', raw: str };
123
+ // 8-digit (#rrggbbaa) or 4-digit (#rgba) — check before isHexColor
124
+ const hex8 = str.match(/^#([0-9a-f]{8}|[0-9a-f]{4})$/i);
125
+ if (hex8) {
126
+ const rgba = (0, spaces_js_1.hex8ToRgba)(str);
127
+ if (rgba) {
128
+ const { r, g, b, a } = rgba;
129
+ const hex = (0, spaces_js_1.rgbToHex)({ r, g, b });
130
+ const [h, s, l] = (0, spaces_js_1.rgbToHsl)({ r, g, b });
131
+ const [hh, ss, vv] = (0, spaces_js_1.rgbToHsv)({ r, g, b });
132
+ return { type: 'hex', hex, r, g, b, a, h, s, l, v: vv };
133
+ }
134
+ }
135
+ if (isHexColor(str)) {
136
+ const hex = (0, spaces_js_1.normalizeHex)(str);
137
+ const [r, g, b] = (0, spaces_js_1.hexToRgb)(hex);
138
+ const [h, s, l] = (0, spaces_js_1.hexToHsl)(hex);
139
+ const [hh, ss, vv] = (0, spaces_js_1.rgbToHsv)({ r, g, b });
140
+ return { type: 'hex', hex, r, g, b, a: 1, h, s, l, v: vv };
141
+ }
142
+ if (isRgbColor(str)) {
143
+ const rgba = (0, spaces_js_1.rgbaStringToRgba)(str);
144
+ if (rgba) {
145
+ const { r, g, b, a } = rgba;
146
+ const hex = (0, spaces_js_1.rgbToHex)({ r, g, b });
147
+ const [h, s, l] = (0, spaces_js_1.rgbToHsl)({ r, g, b });
148
+ const [hh, ss, vv] = (0, spaces_js_1.rgbToHsv)({ r, g, b });
149
+ return { type: 'rgb', hex, r, g, b, a, h, s, l, v: vv };
150
+ }
151
+ }
152
+ if (isHslColor(str)) {
153
+ const m = str.match(/hsla?\(([^)]+)\)/i);
154
+ if (m) {
155
+ const parts = m[1].split(/,\s*/);
156
+ const h = parseFloat(parts[0]);
157
+ const s = parseFloat(parts[1]);
158
+ const l = parseFloat(parts[2]);
159
+ const a = parts[3] ? parseFloat(parts[3]) : 1;
160
+ const { r, g, b } = (0, spaces_js_1.hslToRgb)(h, s, l);
161
+ const hex = (0, spaces_js_1.rgbToHex)({ r, g, b });
162
+ const [hh, ss, vv] = (0, spaces_js_1.rgbToHsv)({ r, g, b });
163
+ return { type: 'hsl', hex, r, g, b, a, h, s, l, v: vv };
164
+ }
165
+ }
166
+ if (str === 'transparent')
167
+ return { type: 'named', hex: '#000000', r: 0, g: 0, b: 0, a: 0 };
168
+ const lowerStr = str.toLowerCase();
169
+ if (lowerStr in named_colors_js_1.NAMED_COLORS) {
170
+ const hex = named_colors_js_1.NAMED_COLORS[lowerStr];
171
+ const [r, g, b] = (0, spaces_js_1.hexToRgb)(hex);
172
+ const [h, s, l] = (0, spaces_js_1.hexToHsl)(hex);
173
+ const [, , vv] = (0, spaces_js_1.rgbToHsv)({ r, g, b });
174
+ return { type: 'named', hex, r, g, b, a: 1, h, s, l, v: vv };
175
+ }
176
+ // oklch / oklcha
177
+ if (isOklchColor(str)) {
178
+ const parsed = parseOklchString(str);
179
+ if (parsed) {
180
+ const { r, g, b } = (0, spaces_js_1.oklchToRgb)({ L: parsed.L, C: parsed.C, H: parsed.H });
181
+ const hex = (0, spaces_js_1.rgbToHex)({ r, g, b });
182
+ const [h, s, l] = (0, spaces_js_1.rgbToHsl)({ r, g, b });
183
+ const [, , vv] = (0, spaces_js_1.rgbToHsv)({ r, g, b });
184
+ return { type: 'oklch', hex, r, g, b, a: parsed.alpha, h, s, l, v: vv };
185
+ }
186
+ }
187
+ // color(display-p3 ...) / color(srgb ...)
188
+ if (isColorFunction(str)) {
189
+ const parsed = parseColorFn(str);
190
+ if (parsed) {
191
+ const { r: p3r, g: p3g, b: p3b, alpha } = parsed;
192
+ // Convert from p3/srgb (0-1) to sRGB 0-255
193
+ let r, g, b;
194
+ if (parsed.space === 'display-p3') {
195
+ const srgb = (0, spaces_js_1.displayP3ToRgb)({ r: p3r, g: p3g, b: p3b });
196
+ r = srgb.r;
197
+ g = srgb.g;
198
+ b = srgb.b;
199
+ }
200
+ else if (parsed.space === 'srgb-linear') {
201
+ // srgb-linear components are linear-light, not gamma-encoded — unlike
202
+ // plain srgb below, they need the linear-to-sRGB transfer function
203
+ // applied before scaling to a 0-255 byte. Without this, only the 0/1
204
+ // extremes happened to come out correct; any mid-range value (e.g. 0.5)
205
+ // converted as if it were already gamma-encoded, which is wrong.
206
+ r = Math.round((0, transfer_js_1.linearChanToSrgb)(p3r) * 255);
207
+ g = Math.round((0, transfer_js_1.linearChanToSrgb)(p3g) * 255);
208
+ b = Math.round((0, transfer_js_1.linearChanToSrgb)(p3b) * 255);
209
+ }
210
+ else {
211
+ r = Math.round(Math.max(0, Math.min(255, p3r * 255)));
212
+ g = Math.round(Math.max(0, Math.min(255, p3g * 255)));
213
+ b = Math.round(Math.max(0, Math.min(255, p3b * 255)));
214
+ }
215
+ const hex = (0, spaces_js_1.rgbToHex)({ r, g, b });
216
+ const [h, s, l] = (0, spaces_js_1.rgbToHsl)({ r, g, b });
217
+ const [, , vv] = (0, spaces_js_1.rgbToHsv)({ r, g, b });
218
+ return { type: 'color', hex, r, g, b, a: alpha, h, s, l, v: vv };
219
+ }
220
+ }
221
+ return { type: 'unknown' };
222
+ }
223
+ function parseHwbString(str) {
224
+ const m = str
225
+ .trim()
226
+ .match(/hwb\(\s*([\d.+-]+)\s+([\d.]+)%\s+([\d.]+)%(?:\s*\/\s*([\d.]+))?\s*\)/i);
227
+ if (!m)
228
+ return null;
229
+ return {
230
+ H: parseFloat(m[1]),
231
+ W: parseFloat(m[2]),
232
+ B: parseFloat(m[3]),
233
+ alpha: m[4] !== undefined ? parseFloat(m[4]) : 1,
234
+ };
235
+ }
236
+ function toNearestNamedColor(color) {
237
+ var _a, _b, _c;
238
+ const n = normalizeColor(color);
239
+ const r = (_a = n.r) !== null && _a !== void 0 ? _a : 0, g = (_b = n.g) !== null && _b !== void 0 ? _b : 0, b = (_c = n.b) !== null && _c !== void 0 ? _c : 0;
240
+ let bestName = 'black';
241
+ let bestDist = Infinity;
242
+ for (const [name, hex] of Object.entries(named_colors_js_1.NAMED_COLORS)) {
243
+ // Skip any non-hex entry (currently just a defensive guard — 'transparent'
244
+ // is the only such value left in the table, and it has no real RGB to
245
+ // compare against; hexToRgb() would otherwise silently fall back to
246
+ // normalizeHex()'s placeholder color for it).
247
+ if (hex[0] !== '#')
248
+ continue;
249
+ const [nr, ng, nb] = (0, spaces_js_1.hexToRgb)(hex);
250
+ const dist = Math.sqrt(Math.pow(r - nr, 2) + Math.pow(g - ng, 2) + Math.pow(b - nb, 2));
251
+ if (dist < bestDist) {
252
+ bestDist = dist;
253
+ bestName = name;
254
+ }
255
+ }
256
+ return bestName;
257
+ }
@@ -14,7 +14,7 @@
14
14
  */
15
15
  var _a, _b, _c, _d, _e, _f, _g, _h;
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- const index_1 = require("../src/index");
17
+ const color_value_tools_1 = require("color-value-tools");
18
18
  const args = process.argv.slice(2);
19
19
  function printUsage() {
20
20
  console.log(`
@@ -42,7 +42,7 @@ if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
42
42
  }
43
43
  const colorInput = args[0];
44
44
  const command = (_a = args[1]) !== null && _a !== void 0 ? _a : 'info';
45
- const normalized = (0, index_1.normalizeColor)(colorInput);
45
+ const normalized = (0, color_value_tools_1.normalizeColor)(colorInput);
46
46
  if (normalized.type === 'unknown' || normalized.type === 'css-var') {
47
47
  console.error(`Error: Cannot resolve color "${colorInput}"`);
48
48
  if (normalized.type === 'css-var') {
@@ -64,11 +64,11 @@ function line(label, value) {
64
64
  }
65
65
  switch (command) {
66
66
  case 'info': {
67
- const type = (0, index_1.getColorType)(colorInput);
68
- const [h, s, l] = (0, index_1.rgbToHsl)({ r, g, b });
69
- const [hv, sv, v] = (0, index_1.rgbToHsv)({ r, g, b });
70
- const nearest = (0, index_1.toNearestNamedColor)(hex);
71
- const textColor = (0, index_1.bestTextColor)(hex);
67
+ const type = (0, color_value_tools_1.getColorType)(colorInput);
68
+ const [h, s, l] = (0, color_value_tools_1.rgbToHsl)({ r, g, b });
69
+ const [hv, sv, v] = (0, color_value_tools_1.rgbToHsv)({ r, g, b });
70
+ const nearest = (0, color_value_tools_1.toNearestNamedColor)(hex);
71
+ const textColor = (0, color_value_tools_1.bestTextColor)(hex);
72
72
  console.log(`\nColor: ${colorInput}`);
73
73
  console.log('─'.repeat(40));
74
74
  line('Type:', type);
@@ -84,18 +84,20 @@ switch (command) {
84
84
  break;
85
85
  }
86
86
  case 'convert': {
87
- const [h, s, l] = (0, index_1.rgbToHsl)({ r, g, b });
88
- const [hv, sv, v] = (0, index_1.rgbToHsv)({ r, g, b });
89
- const [hw, w, bw] = (0, index_1.rgbToHwb)({ r, g, b });
90
- const lab = (0, index_1.rgbToLab)({ r, g, b });
91
- const lch = (0, index_1.rgbToLch)({ r, g, b });
92
- const oklab = (0, index_1.rgbToOklab)({ r, g, b });
93
- const oklch = (0, index_1.rgbToOklch)({ r, g, b });
94
- const cmyk = (0, index_1.rgbToCmyk)({ r, g, b });
87
+ const [h, s, l] = (0, color_value_tools_1.rgbToHsl)({ r, g, b });
88
+ const [hv, sv, v] = (0, color_value_tools_1.rgbToHsv)({ r, g, b });
89
+ const [hw, w, bw] = (0, color_value_tools_1.rgbToHwb)({ r, g, b });
90
+ const lab = (0, color_value_tools_1.rgbToLab)({ r, g, b });
91
+ const lch = (0, color_value_tools_1.rgbToLch)({ r, g, b });
92
+ const oklab = (0, color_value_tools_1.rgbToOklab)({ r, g, b });
93
+ const oklch = (0, color_value_tools_1.rgbToOklch)({ r, g, b });
94
+ const cmyk = (0, color_value_tools_1.rgbToCmyk)({ r, g, b });
95
95
  console.log(`\nConversions for: ${colorInput}`);
96
96
  console.log('─'.repeat(40));
97
97
  line('Hex:', hex);
98
- line('Hex8:', `${hex}${Math.round(a * 255).toString(16).padStart(2, '0')}`);
98
+ line('Hex8:', `${hex}${Math.round(a * 255)
99
+ .toString(16)
100
+ .padStart(2, '0')}`);
99
101
  line('RGB:', `rgb(${r}, ${g}, ${b})`);
100
102
  line('RGBA:', `rgba(${r}, ${g}, ${b}, ${fmt2(a)})`);
101
103
  line('HSL:', `hsl(${h}, ${s}%, ${l}%)`);
@@ -115,14 +117,14 @@ switch (command) {
115
117
  console.error('Error: Please provide a background color. Usage: cvt <color> contrast <bg>');
116
118
  process.exit(1);
117
119
  }
118
- const bg = (0, index_1.normalizeColor)(bgInput);
120
+ const bg = (0, color_value_tools_1.normalizeColor)(bgInput);
119
121
  if (bg.type === 'unknown' || bg.type === 'css-var') {
120
122
  console.error(`Error: Cannot resolve background color "${bgInput}"`);
121
123
  process.exit(1);
122
124
  }
123
125
  const bgHex = (_g = bg.hex) !== null && _g !== void 0 ? _g : '#000000';
124
- const ratio = (0, index_1.contrastRatio)(hex, bgHex);
125
- const level = (0, index_1.wcagLevel)(hex, bgHex);
126
+ const ratio = (0, color_value_tools_1.contrastRatio)(hex, bgHex);
127
+ const level = (0, color_value_tools_1.wcagLevel)(hex, bgHex);
126
128
  console.log(`\nContrast: ${colorInput} on ${bgInput}`);
127
129
  console.log('─'.repeat(40));
128
130
  line('Ratio:', `${fmt2(ratio)}:1`);
@@ -139,7 +141,7 @@ switch (command) {
139
141
  console.error('Error: steps must be a number >= 2');
140
142
  process.exit(1);
141
143
  }
142
- const shades = (0, index_1.colorShades)(hex, steps);
144
+ const shades = (0, color_value_tools_1.colorShades)(hex, steps);
143
145
  console.log(`\nShades of ${colorInput} (${steps} steps):`);
144
146
  console.log('─'.repeat(40));
145
147
  shades.forEach((shade, i) => {
@@ -149,11 +151,11 @@ switch (command) {
149
151
  break;
150
152
  }
151
153
  case 'harmonies': {
152
- const comp = (0, index_1.complement)(hex);
153
- const tri = (0, index_1.triadic)(hex);
154
- const ana = (0, index_1.analogous)(hex);
155
- const split = (0, index_1.splitComplementary)(hex);
156
- const tet = (0, index_1.tetradic)(hex);
154
+ const comp = (0, color_value_tools_1.complement)(hex);
155
+ const tri = (0, color_value_tools_1.triadic)(hex);
156
+ const ana = (0, color_value_tools_1.analogous)(hex);
157
+ const split = (0, color_value_tools_1.splitComplementary)(hex);
158
+ const tet = (0, color_value_tools_1.tetradic)(hex);
157
159
  console.log(`\nHarmonies for: ${colorInput}`);
158
160
  console.log('─'.repeat(40));
159
161
  line('Complement:', comp);
@@ -165,7 +167,7 @@ switch (command) {
165
167
  break;
166
168
  }
167
169
  case 'nearest': {
168
- const name = (0, index_1.toNearestNamedColor)(hex);
170
+ const name = (0, color_value_tools_1.toNearestNamedColor)(hex);
169
171
  console.log(`\nNearest CSS named color for ${colorInput}:`);
170
172
  console.log('─'.repeat(40));
171
173
  line('Name:', name);
@@ -0,0 +1,40 @@
1
+ export declare function relativeLuminance(color: string): number;
2
+ export declare function contrastRatio(a: string, b: string): number;
3
+ export declare function isDark(color: string, threshold?: number): boolean;
4
+ export declare function isLight(color: string, threshold?: number): boolean;
5
+ export type WcagLevel = 'AAA' | 'AA' | 'AA-large' | 'fail';
6
+ export declare function wcagLevel(foreground: string, background: string): WcagLevel;
7
+ export declare function bestTextColor(background: string): '#000000' | '#ffffff';
8
+ export declare function bestContrastColor(background: string, candidates: string[]): string;
9
+ export declare function colorDeltaE(c1: string, c2: string): number;
10
+ export type ColorBlindnessType = 'protanopia' | 'deuteranopia' | 'tritanopia';
11
+ export declare function simulateProtanopia(color: string): string;
12
+ export declare function simulateDeuteranopia(color: string): string;
13
+ export declare function simulateTritanopia(color: string): string;
14
+ export declare function simulateColorBlindness(color: string, type: ColorBlindnessType): string;
15
+ export type BackgroundSpec = string | {
16
+ type: 'semi-transparent';
17
+ color: string;
18
+ underlay?: string;
19
+ } | {
20
+ type: 'gradient';
21
+ stops: string[];
22
+ };
23
+ export declare function isReadableOnBackground(textColor: string, background: BackgroundSpec, options?: {
24
+ level?: 'AA' | 'AAA';
25
+ largeText?: boolean;
26
+ }): {
27
+ readable: boolean;
28
+ minContrastRatio: number;
29
+ wcagLevel: WcagLevel;
30
+ };
31
+ export interface PaletteScore {
32
+ palette: string[];
33
+ minContrastRatio: number;
34
+ avgContrastRatio: number;
35
+ }
36
+ export declare function bestContrastPalette(background: string, palettes: string[][], options?: {
37
+ weights?: number[];
38
+ }): PaletteScore & {
39
+ paletteIndex: number;
40
+ };