color-value-tools 1.1.0 → 1.1.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.
- package/README.md +182 -18
- package/dist/cjs/index.d.ts +116 -2
- package/dist/cjs/index.js +466 -32
- package/dist/cli/bin/cli.js +179 -0
- package/dist/cli/src/index.js +1410 -0
- package/dist/esm/index.js +435 -32
- package/package.json +6 -2
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* color-value-tools CLI
|
|
5
|
+
* Usage: cvt <color> [command]
|
|
6
|
+
*
|
|
7
|
+
* Commands:
|
|
8
|
+
* info Show full parsed info (default)
|
|
9
|
+
* convert Show all format conversions
|
|
10
|
+
* contrast <bg> Contrast ratio and WCAG level against a background
|
|
11
|
+
* shades [n] Generate n light-to-dark shades (default 9)
|
|
12
|
+
* harmonies Show all color harmonies
|
|
13
|
+
* nearest Show nearest CSS named color
|
|
14
|
+
*/
|
|
15
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
const index_1 = require("../src/index");
|
|
18
|
+
const args = process.argv.slice(2);
|
|
19
|
+
function printUsage() {
|
|
20
|
+
console.log(`
|
|
21
|
+
color-value-tools CLI (cvt)
|
|
22
|
+
|
|
23
|
+
Usage:
|
|
24
|
+
cvt <color> Full color info
|
|
25
|
+
cvt <color> convert All format conversions
|
|
26
|
+
cvt <color> contrast <bg> Contrast ratio vs background
|
|
27
|
+
cvt <color> shades [n] Generate shades (default 9)
|
|
28
|
+
cvt <color> harmonies All color harmonies
|
|
29
|
+
cvt <color> nearest Nearest CSS named color
|
|
30
|
+
|
|
31
|
+
Examples:
|
|
32
|
+
cvt "#3498db"
|
|
33
|
+
cvt "rgb(52,152,219)" convert
|
|
34
|
+
cvt "#3498db" contrast "#ffffff"
|
|
35
|
+
cvt "#3498db" shades 7
|
|
36
|
+
cvt "cornflowerblue" harmonies
|
|
37
|
+
`.trim());
|
|
38
|
+
}
|
|
39
|
+
if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
|
|
40
|
+
printUsage();
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}
|
|
43
|
+
const colorInput = args[0];
|
|
44
|
+
const command = (_a = args[1]) !== null && _a !== void 0 ? _a : 'info';
|
|
45
|
+
const normalized = (0, index_1.normalizeColor)(colorInput);
|
|
46
|
+
if (normalized.type === 'unknown' || normalized.type === 'css-var') {
|
|
47
|
+
console.error(`Error: Cannot resolve color "${colorInput}"`);
|
|
48
|
+
if (normalized.type === 'css-var') {
|
|
49
|
+
console.error('CSS variables cannot be resolved in the CLI (no DOM context).');
|
|
50
|
+
}
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
const r = (_b = normalized.r) !== null && _b !== void 0 ? _b : 0;
|
|
54
|
+
const g = (_c = normalized.g) !== null && _c !== void 0 ? _c : 0;
|
|
55
|
+
const b = (_d = normalized.b) !== null && _d !== void 0 ? _d : 0;
|
|
56
|
+
const a = (_e = normalized.a) !== null && _e !== void 0 ? _e : 1;
|
|
57
|
+
const hex = (_f = normalized.hex) !== null && _f !== void 0 ? _f : '#000000';
|
|
58
|
+
function fmt2(n, dec = 2) {
|
|
59
|
+
return n.toFixed(dec);
|
|
60
|
+
}
|
|
61
|
+
function line(label, value) {
|
|
62
|
+
const pad = 18;
|
|
63
|
+
console.log(` ${label.padEnd(pad)} ${value}`);
|
|
64
|
+
}
|
|
65
|
+
switch (command) {
|
|
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);
|
|
72
|
+
console.log(`\nColor: ${colorInput}`);
|
|
73
|
+
console.log('─'.repeat(40));
|
|
74
|
+
line('Type:', type);
|
|
75
|
+
line('Hex:', hex);
|
|
76
|
+
line('RGB:', `rgb(${r}, ${g}, ${b})`);
|
|
77
|
+
if (a < 1)
|
|
78
|
+
line('Alpha:', fmt2(a));
|
|
79
|
+
line('HSL:', `hsl(${h}, ${s}%, ${l}%)`);
|
|
80
|
+
line('HSV:', `hsv(${hv}, ${sv}%, ${v}%)`);
|
|
81
|
+
line('Nearest named:', nearest);
|
|
82
|
+
line('Best text on it:', textColor);
|
|
83
|
+
console.log('');
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
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 });
|
|
95
|
+
console.log(`\nConversions for: ${colorInput}`);
|
|
96
|
+
console.log('─'.repeat(40));
|
|
97
|
+
line('Hex:', hex);
|
|
98
|
+
line('Hex8:', `${hex}${Math.round(a * 255).toString(16).padStart(2, '0')}`);
|
|
99
|
+
line('RGB:', `rgb(${r}, ${g}, ${b})`);
|
|
100
|
+
line('RGBA:', `rgba(${r}, ${g}, ${b}, ${fmt2(a)})`);
|
|
101
|
+
line('HSL:', `hsl(${h}, ${s}%, ${l}%)`);
|
|
102
|
+
line('HSV:', `hsv(${hv}, ${sv}%, ${v}%)`);
|
|
103
|
+
line('HWB:', `hwb(${hw} ${w}% ${bw}%)`);
|
|
104
|
+
line('Lab:', `lab(${fmt2(lab.L)} ${fmt2(lab.a)} ${fmt2(lab.b)})`);
|
|
105
|
+
line('LCH:', `lch(${fmt2(lch.L)} ${fmt2(lch.C)} ${fmt2(lch.H)})`);
|
|
106
|
+
line('Oklab:', `oklab(${fmt2(oklab.L, 4)} ${fmt2(oklab.a, 4)} ${fmt2(oklab.b, 4)})`);
|
|
107
|
+
line('Oklch:', `oklch(${fmt2(oklch.L, 4)} ${fmt2(oklch.C, 4)} ${fmt2(oklch.H, 2)})`);
|
|
108
|
+
line('CMYK:', `cmyk(${fmt2(cmyk.c * 100)}%, ${fmt2(cmyk.m * 100)}%, ${fmt2(cmyk.y * 100)}%, ${fmt2(cmyk.k * 100)}%)`);
|
|
109
|
+
console.log('');
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
case 'contrast': {
|
|
113
|
+
const bgInput = args[2];
|
|
114
|
+
if (!bgInput) {
|
|
115
|
+
console.error('Error: Please provide a background color. Usage: cvt <color> contrast <bg>');
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
const bg = (0, index_1.normalizeColor)(bgInput);
|
|
119
|
+
if (bg.type === 'unknown' || bg.type === 'css-var') {
|
|
120
|
+
console.error(`Error: Cannot resolve background color "${bgInput}"`);
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
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
|
+
console.log(`\nContrast: ${colorInput} on ${bgInput}`);
|
|
127
|
+
console.log('─'.repeat(40));
|
|
128
|
+
line('Ratio:', `${fmt2(ratio)}:1`);
|
|
129
|
+
line('WCAG level:', level);
|
|
130
|
+
line('AA (text):', ratio >= 4.5 ? 'pass' : 'fail');
|
|
131
|
+
line('AAA (text):', ratio >= 7 ? 'pass' : 'fail');
|
|
132
|
+
line('AA-large:', ratio >= 3 ? 'pass' : 'fail');
|
|
133
|
+
console.log('');
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
case 'shades': {
|
|
137
|
+
const steps = parseInt((_h = args[2]) !== null && _h !== void 0 ? _h : '9', 10);
|
|
138
|
+
if (isNaN(steps) || steps < 2) {
|
|
139
|
+
console.error('Error: steps must be a number >= 2');
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
const shades = (0, index_1.colorShades)(hex, steps);
|
|
143
|
+
console.log(`\nShades of ${colorInput} (${steps} steps):`);
|
|
144
|
+
console.log('─'.repeat(40));
|
|
145
|
+
shades.forEach((shade, i) => {
|
|
146
|
+
console.log(` ${String(i + 1).padStart(2)}. ${shade}`);
|
|
147
|
+
});
|
|
148
|
+
console.log('');
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
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);
|
|
157
|
+
console.log(`\nHarmonies for: ${colorInput}`);
|
|
158
|
+
console.log('─'.repeat(40));
|
|
159
|
+
line('Complement:', comp);
|
|
160
|
+
line('Triadic:', tri.join(', '));
|
|
161
|
+
line('Analogous:', ana.join(', '));
|
|
162
|
+
line('Split-comp:', split.join(', '));
|
|
163
|
+
line('Tetradic:', tet.join(', '));
|
|
164
|
+
console.log('');
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
case 'nearest': {
|
|
168
|
+
const name = (0, index_1.toNearestNamedColor)(hex);
|
|
169
|
+
console.log(`\nNearest CSS named color for ${colorInput}:`);
|
|
170
|
+
console.log('─'.repeat(40));
|
|
171
|
+
line('Name:', name);
|
|
172
|
+
console.log('');
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
default:
|
|
176
|
+
console.error(`Unknown command: "${command}"`);
|
|
177
|
+
printUsage();
|
|
178
|
+
process.exit(1);
|
|
179
|
+
}
|