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.
@@ -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
+ }