chroma-panel 0.2.0 → 1.0.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/README.md +46 -8
- package/dist/a11y/contrast.cjs +94 -0
- package/dist/a11y/contrast.d.cts +8 -0
- package/dist/a11y/contrast.d.ts +8 -0
- package/dist/a11y/contrast.js +93 -2
- package/dist/color/css4.cjs +397 -0
- package/dist/color/css4.d.cts +10 -0
- package/dist/color/css4.d.ts +10 -0
- package/dist/color/css4.js +392 -0
- package/dist/color/parse.cjs +3 -1
- package/dist/color/parse.js +3 -1
- package/dist/color/types.d.cts +16 -0
- package/dist/color/types.d.ts +16 -0
- package/dist/color/value.cjs +11 -0
- package/dist/color/value.d.cts +4 -0
- package/dist/color/value.d.ts +4 -0
- package/dist/color/value.js +12 -0
- package/dist/color.cjs +43 -0
- package/dist/color.d.cts +9 -0
- package/dist/color.d.ts +9 -0
- package/dist/color.js +8 -0
- package/dist/components/ChromaPanel.cjs +16 -6
- package/dist/components/ChromaPanel.d.cts +4 -2
- package/dist/components/ChromaPanel.d.ts +4 -2
- package/dist/components/ChromaPanel.js +16 -6
- package/dist/components/ColorInput.cjs +1 -1
- package/dist/components/ColorInput.js +1 -1
- package/dist/components/PanelFooter.cjs +4 -4
- package/dist/components/PanelFooter.js +4 -4
- package/dist/contrast.cjs +3 -0
- package/dist/contrast.d.cts +2 -2
- package/dist/contrast.d.ts +2 -2
- package/dist/contrast.js +2 -2
- package/dist/core/store.cjs +17 -9
- package/dist/core/store.d.cts +6 -6
- package/dist/core/store.d.ts +6 -6
- package/dist/core/store.js +17 -9
- package/dist/core.cjs +10 -0
- package/dist/core.d.cts +4 -2
- package/dist/core.d.ts +4 -2
- package/dist/core.js +3 -1
- package/dist/export/tokens.cjs +39 -0
- package/dist/export/tokens.d.cts +16 -0
- package/dist/export/tokens.d.ts +16 -0
- package/dist/export/tokens.js +37 -0
- package/dist/export.cjs +6 -0
- package/dist/export.d.cts +2 -0
- package/dist/export.d.ts +2 -0
- package/dist/export.js +2 -0
- package/dist/gradient/GradientEditor.cjs +196 -0
- package/dist/gradient/GradientEditor.d.cts +17 -0
- package/dist/gradient/GradientEditor.d.ts +17 -0
- package/dist/gradient/GradientEditor.js +195 -0
- package/dist/gradient/model.cjs +63 -0
- package/dist/gradient/model.d.cts +23 -0
- package/dist/gradient/model.d.ts +23 -0
- package/dist/gradient/model.js +60 -0
- package/dist/gradient.cjs +9 -0
- package/dist/gradient.d.cts +3 -0
- package/dist/gradient.d.ts +3 -0
- package/dist/gradient.js +3 -0
- package/dist/index.cjs +13 -0
- package/dist/index.d.cts +5 -3
- package/dist/index.d.ts +5 -3
- package/dist/index.js +4 -2
- package/dist/modes/image/index.cjs +65 -4
- package/dist/modes/image/index.d.cts +1 -0
- package/dist/modes/image/index.d.ts +1 -0
- package/dist/modes/image/index.js +65 -4
- package/dist/modes/registry.d.cts +1 -1
- package/dist/modes/registry.d.ts +1 -1
- package/dist/modes.cjs +30 -0
- package/dist/modes.d.cts +10 -0
- package/dist/modes.d.ts +10 -0
- package/dist/modes.js +17 -0
- package/dist/panel.cjs +10 -0
- package/dist/panel.d.cts +4 -2
- package/dist/panel.d.ts +4 -2
- package/dist/panel.js +3 -1
- package/dist/primitives/ChannelSlider.cjs +4 -4
- package/dist/primitives/ChannelSlider.js +4 -4
- package/dist/primitives/ColorArea.cjs +6 -6
- package/dist/primitives/ColorArea.js +6 -6
- package/dist/primitives/ColorDisc.cjs +6 -6
- package/dist/primitives/ColorDisc.js +6 -6
- package/dist/primitives/ColorField.cjs +2 -2
- package/dist/primitives/ColorField.js +2 -2
- package/dist/primitives/NumberField.cjs +2 -2
- package/dist/primitives/NumberField.js +2 -2
- package/dist/primitives/SwatchGrid.cjs +2 -2
- package/dist/primitives/SwatchGrid.js +2 -2
- package/package.json +46 -2
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
import { clamp, hsvaToRgba, rgbaToHsva } from "./convert.js";
|
|
2
|
+
//#region src/color/css4.ts
|
|
3
|
+
const D50 = [
|
|
4
|
+
.96422,
|
|
5
|
+
1,
|
|
6
|
+
.82521
|
|
7
|
+
];
|
|
8
|
+
const D65_TO_D50 = [
|
|
9
|
+
[
|
|
10
|
+
1.0479298,
|
|
11
|
+
.0229468,
|
|
12
|
+
-.0501922
|
|
13
|
+
],
|
|
14
|
+
[
|
|
15
|
+
.0296278,
|
|
16
|
+
.9904345,
|
|
17
|
+
-.0170738
|
|
18
|
+
],
|
|
19
|
+
[
|
|
20
|
+
-.009243,
|
|
21
|
+
.0150552,
|
|
22
|
+
.7518743
|
|
23
|
+
]
|
|
24
|
+
];
|
|
25
|
+
const D50_TO_D65 = [
|
|
26
|
+
[
|
|
27
|
+
.9554734,
|
|
28
|
+
-.0230985,
|
|
29
|
+
.0632593
|
|
30
|
+
],
|
|
31
|
+
[
|
|
32
|
+
-.0283697,
|
|
33
|
+
1.0099955,
|
|
34
|
+
.0210414
|
|
35
|
+
],
|
|
36
|
+
[
|
|
37
|
+
.012314,
|
|
38
|
+
-.0205077,
|
|
39
|
+
1.3303659
|
|
40
|
+
]
|
|
41
|
+
];
|
|
42
|
+
function mul(matrix, value) {
|
|
43
|
+
return matrix.map((row) => row[0] * value[0] + row[1] * value[1] + row[2] * value[2]);
|
|
44
|
+
}
|
|
45
|
+
function linear(value) {
|
|
46
|
+
const sign = value < 0 ? -1 : 1;
|
|
47
|
+
const abs = Math.abs(value);
|
|
48
|
+
return sign * (abs <= .04045 ? abs / 12.92 : ((abs + .055) / 1.055) ** 2.4);
|
|
49
|
+
}
|
|
50
|
+
function gamma(value) {
|
|
51
|
+
const sign = value < 0 ? -1 : 1;
|
|
52
|
+
const abs = Math.abs(value);
|
|
53
|
+
return sign * (abs <= .0031308 ? 12.92 * abs : 1.055 * abs ** (1 / 2.4) - .055);
|
|
54
|
+
}
|
|
55
|
+
function rgbToXyz(rgb, space) {
|
|
56
|
+
return mul(space === "srgb" ? [
|
|
57
|
+
[
|
|
58
|
+
.4123908,
|
|
59
|
+
.3575843,
|
|
60
|
+
.1804808
|
|
61
|
+
],
|
|
62
|
+
[
|
|
63
|
+
.212639,
|
|
64
|
+
.7151687,
|
|
65
|
+
.0721923
|
|
66
|
+
],
|
|
67
|
+
[
|
|
68
|
+
.0193308,
|
|
69
|
+
.1191948,
|
|
70
|
+
.9505322
|
|
71
|
+
]
|
|
72
|
+
] : [
|
|
73
|
+
[
|
|
74
|
+
.4865709,
|
|
75
|
+
.2656677,
|
|
76
|
+
.1982173
|
|
77
|
+
],
|
|
78
|
+
[
|
|
79
|
+
.2289746,
|
|
80
|
+
.6917385,
|
|
81
|
+
.0792869
|
|
82
|
+
],
|
|
83
|
+
[
|
|
84
|
+
0,
|
|
85
|
+
.0451134,
|
|
86
|
+
1.0439444
|
|
87
|
+
]
|
|
88
|
+
], rgb.map(linear));
|
|
89
|
+
}
|
|
90
|
+
function xyzToRgb(xyz, space) {
|
|
91
|
+
return mul(space === "srgb" ? [
|
|
92
|
+
[
|
|
93
|
+
3.2409699,
|
|
94
|
+
-1.5373832,
|
|
95
|
+
-.4986108
|
|
96
|
+
],
|
|
97
|
+
[
|
|
98
|
+
-.9692436,
|
|
99
|
+
1.8759675,
|
|
100
|
+
.0415551
|
|
101
|
+
],
|
|
102
|
+
[
|
|
103
|
+
.0556301,
|
|
104
|
+
-.203977,
|
|
105
|
+
1.0569715
|
|
106
|
+
]
|
|
107
|
+
] : [
|
|
108
|
+
[
|
|
109
|
+
2.4934969,
|
|
110
|
+
-.9313836,
|
|
111
|
+
-.4027108
|
|
112
|
+
],
|
|
113
|
+
[
|
|
114
|
+
-.829489,
|
|
115
|
+
1.762664,
|
|
116
|
+
.0236247
|
|
117
|
+
],
|
|
118
|
+
[
|
|
119
|
+
.0358458,
|
|
120
|
+
-.0761724,
|
|
121
|
+
.9568845
|
|
122
|
+
]
|
|
123
|
+
], xyz).map(gamma);
|
|
124
|
+
}
|
|
125
|
+
function xyzToOklab(xyz) {
|
|
126
|
+
return mul([
|
|
127
|
+
[
|
|
128
|
+
.2104543,
|
|
129
|
+
.7936178,
|
|
130
|
+
-.004072
|
|
131
|
+
],
|
|
132
|
+
[
|
|
133
|
+
1.9779985,
|
|
134
|
+
-2.4285922,
|
|
135
|
+
.4505937
|
|
136
|
+
],
|
|
137
|
+
[
|
|
138
|
+
.025904,
|
|
139
|
+
.7827718,
|
|
140
|
+
-.8086758
|
|
141
|
+
]
|
|
142
|
+
], mul([
|
|
143
|
+
[
|
|
144
|
+
.8190224,
|
|
145
|
+
.3619063,
|
|
146
|
+
-.1288738
|
|
147
|
+
],
|
|
148
|
+
[
|
|
149
|
+
.0329837,
|
|
150
|
+
.9292868,
|
|
151
|
+
.0361447
|
|
152
|
+
],
|
|
153
|
+
[
|
|
154
|
+
.0481772,
|
|
155
|
+
.2642395,
|
|
156
|
+
.6335478
|
|
157
|
+
]
|
|
158
|
+
], xyz).map(Math.cbrt));
|
|
159
|
+
}
|
|
160
|
+
function oklabToXyz(lab) {
|
|
161
|
+
return mul([
|
|
162
|
+
[
|
|
163
|
+
1.2268798758,
|
|
164
|
+
-.5578149945,
|
|
165
|
+
.2813910457
|
|
166
|
+
],
|
|
167
|
+
[
|
|
168
|
+
-.0405757452,
|
|
169
|
+
1.1122868033,
|
|
170
|
+
-.0717110581
|
|
171
|
+
],
|
|
172
|
+
[
|
|
173
|
+
-.0763729367,
|
|
174
|
+
-.4214933324,
|
|
175
|
+
1.5869240198
|
|
176
|
+
]
|
|
177
|
+
], mul([
|
|
178
|
+
[
|
|
179
|
+
1,
|
|
180
|
+
.3963378,
|
|
181
|
+
.2158038
|
|
182
|
+
],
|
|
183
|
+
[
|
|
184
|
+
1,
|
|
185
|
+
-.1055613,
|
|
186
|
+
-.0638542
|
|
187
|
+
],
|
|
188
|
+
[
|
|
189
|
+
1,
|
|
190
|
+
-.0894842,
|
|
191
|
+
-1.2914855
|
|
192
|
+
]
|
|
193
|
+
], lab).map((v) => v ** 3));
|
|
194
|
+
}
|
|
195
|
+
function xyzD50ToLab(xyz) {
|
|
196
|
+
const e = 216 / 24389;
|
|
197
|
+
const k = 24389 / 27;
|
|
198
|
+
const f = xyz.map((v, i) => {
|
|
199
|
+
const n = v / D50[i];
|
|
200
|
+
return n > e ? Math.cbrt(n) : (k * n + 16) / 116;
|
|
201
|
+
});
|
|
202
|
+
return [
|
|
203
|
+
116 * f[1] - 16,
|
|
204
|
+
500 * (f[0] - f[1]),
|
|
205
|
+
200 * (f[1] - f[2])
|
|
206
|
+
];
|
|
207
|
+
}
|
|
208
|
+
function labToXyzD50(lab) {
|
|
209
|
+
const f = [
|
|
210
|
+
lab[1] / 500 + (lab[0] + 16) / 116,
|
|
211
|
+
(lab[0] + 16) / 116,
|
|
212
|
+
(lab[0] + 16) / 116 - lab[2] / 200
|
|
213
|
+
];
|
|
214
|
+
const e = 216 / 24389;
|
|
215
|
+
const k = 24389 / 27;
|
|
216
|
+
return f.map((v, i) => D50[i] * (v ** 3 > e ? v ** 3 : (116 * v - 16) / k));
|
|
217
|
+
}
|
|
218
|
+
function polar(value) {
|
|
219
|
+
const r = value[2] * Math.PI / 180;
|
|
220
|
+
return [
|
|
221
|
+
value[0],
|
|
222
|
+
value[1] * Math.cos(r),
|
|
223
|
+
value[1] * Math.sin(r)
|
|
224
|
+
];
|
|
225
|
+
}
|
|
226
|
+
function cylindrical(value) {
|
|
227
|
+
const c = Math.hypot(value[1], value[2]);
|
|
228
|
+
return [
|
|
229
|
+
value[0],
|
|
230
|
+
c,
|
|
231
|
+
c < 1e-7 ? 0 : (Math.atan2(value[2], value[1]) * 180 / Math.PI + 360) % 360
|
|
232
|
+
];
|
|
233
|
+
}
|
|
234
|
+
function toXyz(color) {
|
|
235
|
+
switch (color.space) {
|
|
236
|
+
case "srgb":
|
|
237
|
+
case "display-p3": return rgbToXyz([...color.channels], color.space);
|
|
238
|
+
case "oklab": return oklabToXyz([...color.channels]);
|
|
239
|
+
case "oklch": return oklabToXyz(polar([...color.channels]));
|
|
240
|
+
case "lab": return mul(D50_TO_D65, labToXyzD50([...color.channels]));
|
|
241
|
+
case "lch": return mul(D50_TO_D65, labToXyzD50(polar([...color.channels])));
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function convertColor(color, space) {
|
|
245
|
+
if (color.space === space) return {
|
|
246
|
+
...color,
|
|
247
|
+
channels: [...color.channels]
|
|
248
|
+
};
|
|
249
|
+
const xyz = toXyz(color);
|
|
250
|
+
let channels;
|
|
251
|
+
switch (space) {
|
|
252
|
+
case "srgb":
|
|
253
|
+
case "display-p3":
|
|
254
|
+
channels = xyzToRgb(xyz, space);
|
|
255
|
+
break;
|
|
256
|
+
case "oklab":
|
|
257
|
+
channels = xyzToOklab(xyz);
|
|
258
|
+
break;
|
|
259
|
+
case "oklch":
|
|
260
|
+
channels = cylindrical(xyzToOklab(xyz));
|
|
261
|
+
break;
|
|
262
|
+
case "lab":
|
|
263
|
+
channels = xyzD50ToLab(mul(D65_TO_D50, xyz));
|
|
264
|
+
break;
|
|
265
|
+
case "lch": channels = cylindrical(xyzD50ToLab(mul(D65_TO_D50, xyz)));
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
space,
|
|
269
|
+
channels,
|
|
270
|
+
alpha: color.alpha
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
function isInGamut(color, gamut = "srgb") {
|
|
274
|
+
return convertColor(color, gamut).channels.every((v) => v >= -1e-7 && v <= 1 + 1e-7);
|
|
275
|
+
}
|
|
276
|
+
function mapToGamut(color, gamut = "srgb") {
|
|
277
|
+
if (isInGamut(color, gamut)) return convertColor(color, gamut);
|
|
278
|
+
const source = convertColor(color, "oklch");
|
|
279
|
+
let low = 0;
|
|
280
|
+
let high = Math.max(0, source.channels[1]);
|
|
281
|
+
for (let i = 0; i < 24; i++) {
|
|
282
|
+
const c = (low + high) / 2;
|
|
283
|
+
if (isInGamut({
|
|
284
|
+
...source,
|
|
285
|
+
channels: [
|
|
286
|
+
source.channels[0],
|
|
287
|
+
c,
|
|
288
|
+
source.channels[2]
|
|
289
|
+
]
|
|
290
|
+
}, gamut)) low = c;
|
|
291
|
+
else high = c;
|
|
292
|
+
}
|
|
293
|
+
const mapped = convertColor({
|
|
294
|
+
...source,
|
|
295
|
+
channels: [
|
|
296
|
+
source.channels[0],
|
|
297
|
+
low,
|
|
298
|
+
source.channels[2]
|
|
299
|
+
]
|
|
300
|
+
}, gamut);
|
|
301
|
+
return {
|
|
302
|
+
...mapped,
|
|
303
|
+
channels: mapped.channels.map((channel) => clamp(channel, 0, 1))
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
function num(token, percentScale = 1) {
|
|
307
|
+
if (token.toLowerCase() === "none") return 0;
|
|
308
|
+
const percent = token.endsWith("%");
|
|
309
|
+
const value = Number(percent ? token.slice(0, -1) : token);
|
|
310
|
+
return Number.isFinite(value) ? value * (percent ? percentScale / 100 : 1) : null;
|
|
311
|
+
}
|
|
312
|
+
function hue(token) {
|
|
313
|
+
if (token.toLowerCase() === "none") return 0;
|
|
314
|
+
const m = token.match(/^([-+]?(?:\d*\.)?\d+)(deg|grad|rad|turn)?$/i);
|
|
315
|
+
if (m === null) return null;
|
|
316
|
+
const value = Number(m[1]);
|
|
317
|
+
return m[2] === "grad" ? value * .9 : m[2] === "rad" ? value * 180 / Math.PI : m[2] === "turn" ? value * 360 : value;
|
|
318
|
+
}
|
|
319
|
+
function lightness(token, ok) {
|
|
320
|
+
if (token.toLowerCase() === "none") return 0;
|
|
321
|
+
const percent = token.endsWith("%");
|
|
322
|
+
const value = Number(percent ? token.slice(0, -1) : token);
|
|
323
|
+
if (!Number.isFinite(value)) return null;
|
|
324
|
+
return ok && percent ? value / 100 : value;
|
|
325
|
+
}
|
|
326
|
+
function parseCss4Color(input) {
|
|
327
|
+
const rgb = input.trim().match(/^color\((srgb|display-p3)\s+([^/]+?)(?:\s*\/\s*([^\s]+))?\)$/i);
|
|
328
|
+
if (rgb !== null) {
|
|
329
|
+
const values = rgb[2].trim().split(/\s+/).map((v) => num(v, 1));
|
|
330
|
+
const alpha = rgb[3] === void 0 ? 1 : num(rgb[3], 1);
|
|
331
|
+
return values.length === 3 && values.every((v) => v !== null) && alpha !== null ? {
|
|
332
|
+
space: rgb[1].toLowerCase(),
|
|
333
|
+
channels: values,
|
|
334
|
+
alpha: clamp(alpha, 0, 1)
|
|
335
|
+
} : null;
|
|
336
|
+
}
|
|
337
|
+
const match = input.trim().match(/^(oklab|oklch|lab|lch)\((.*)\)$/i);
|
|
338
|
+
if (match === null) return null;
|
|
339
|
+
const sections = match[2].split("/");
|
|
340
|
+
const parts = sections[0].trim().split(/\s+/);
|
|
341
|
+
const space = match[1].toLowerCase();
|
|
342
|
+
if (parts.length !== 3 || sections.length > 2) return null;
|
|
343
|
+
const l = lightness(parts[0], space.startsWith("ok"));
|
|
344
|
+
const second = num(parts[1], space.startsWith("ok") ? .4 : space === "lch" ? 150 : 125);
|
|
345
|
+
const third = space.endsWith("ch") ? hue(parts[2]) : num(parts[2], space === "oklab" ? .4 : 125);
|
|
346
|
+
const alpha = sections[1] === void 0 ? 1 : num(sections[1].trim(), 1);
|
|
347
|
+
if (l === null || second === null || third === null || alpha === null) return null;
|
|
348
|
+
return {
|
|
349
|
+
space,
|
|
350
|
+
channels: [
|
|
351
|
+
l,
|
|
352
|
+
space.endsWith("ch") ? Math.max(0, second) : second,
|
|
353
|
+
space.endsWith("ch") ? (third % 360 + 360) % 360 : third
|
|
354
|
+
],
|
|
355
|
+
alpha: clamp(alpha, 0, 1)
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
function colorValueToHsva(color) {
|
|
359
|
+
const rgb = mapToGamut(color, "srgb");
|
|
360
|
+
return rgbaToHsva({
|
|
361
|
+
r: clamp(rgb.channels[0], 0, 1) * 255,
|
|
362
|
+
g: clamp(rgb.channels[1], 0, 1) * 255,
|
|
363
|
+
b: clamp(rgb.channels[2], 0, 1) * 255,
|
|
364
|
+
a: color.alpha
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
function hsvaToColorValue(color) {
|
|
368
|
+
const rgb = hsvaToRgba(color);
|
|
369
|
+
return {
|
|
370
|
+
space: "srgb",
|
|
371
|
+
channels: [
|
|
372
|
+
rgb.r / 255,
|
|
373
|
+
rgb.g / 255,
|
|
374
|
+
rgb.b / 255
|
|
375
|
+
],
|
|
376
|
+
alpha: rgb.a
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
const out = (value, precision) => String(Number(value.toFixed(precision)));
|
|
380
|
+
function serializeColor(color, options = {}) {
|
|
381
|
+
const format = options.format ?? color.space;
|
|
382
|
+
const precision = Math.min(8, Math.max(0, options.precision ?? 4));
|
|
383
|
+
const converted = convertColor(options.gamut === void 0 || options.gamut === "preserve" ? color : mapToGamut(color, options.gamut), format);
|
|
384
|
+
const [x, y, z] = converted.channels;
|
|
385
|
+
const alpha = converted.alpha < 1 ? ` / ${out(converted.alpha, precision)}` : "";
|
|
386
|
+
if (format === "srgb" || format === "display-p3") return `color(${format} ${out(x, precision)} ${out(y, precision)} ${out(z, precision)}${alpha})`;
|
|
387
|
+
const lightness = format.startsWith("ok") ? x * 100 : x;
|
|
388
|
+
return `${format}(${out(lightness, precision)}% ${out(y, precision)} ${out(z, precision)}${alpha})`;
|
|
389
|
+
}
|
|
390
|
+
//#endregion
|
|
391
|
+
export { colorValueToHsva, convertColor, hsvaToColorValue, isInGamut, mapToGamut, parseCss4Color, serializeColor };
|
|
392
|
+
|
package/dist/color/parse.cjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const require_convert = require("./convert.cjs");
|
|
2
|
+
const require_css4 = require("./css4.cjs");
|
|
2
3
|
//#region src/color/parse.ts
|
|
3
4
|
let namedTable = null;
|
|
4
5
|
function registerNamedColors(table) {
|
|
@@ -141,7 +142,8 @@ function parse(input) {
|
|
|
141
142
|
a: alpha
|
|
142
143
|
});
|
|
143
144
|
}
|
|
144
|
-
|
|
145
|
+
const modern = require_css4.parseCss4Color(raw);
|
|
146
|
+
return modern === null ? null : require_css4.colorValueToHsva(modern);
|
|
145
147
|
}
|
|
146
148
|
function isValidColor(input) {
|
|
147
149
|
return parse(input) !== null;
|
package/dist/color/parse.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { clamp, hslaToHsva, hwbaToHsva, rgbaToHsva } from "./convert.js";
|
|
2
|
+
import { colorValueToHsva, parseCss4Color } from "./css4.js";
|
|
2
3
|
//#region src/color/parse.ts
|
|
3
4
|
let namedTable = null;
|
|
4
5
|
function registerNamedColors(table) {
|
|
@@ -141,7 +142,8 @@ function parse(input) {
|
|
|
141
142
|
a: alpha
|
|
142
143
|
});
|
|
143
144
|
}
|
|
144
|
-
|
|
145
|
+
const modern = parseCss4Color(raw);
|
|
146
|
+
return modern === null ? null : colorValueToHsva(modern);
|
|
145
147
|
}
|
|
146
148
|
function isValidColor(input) {
|
|
147
149
|
return parse(input) !== null;
|
package/dist/color/types.d.cts
CHANGED
|
@@ -40,4 +40,20 @@ export interface ColorChangeResult {
|
|
|
40
40
|
hsva: Hsva;
|
|
41
41
|
css: string;
|
|
42
42
|
}
|
|
43
|
+
export type ColorChangeSource = "pointer" | "keyboard" | "field" | "swatch" | "eyedropper" | "image" | "recent" | "programmatic" | "unknown";
|
|
44
|
+
export interface ColorChangeMeta {
|
|
45
|
+
phase: "change" | "commit";
|
|
46
|
+
source: ColorChangeSource;
|
|
47
|
+
}
|
|
48
|
+
export type ModernColorSpace = "srgb" | "display-p3" | "oklab" | "oklch" | "lab" | "lch";
|
|
49
|
+
export interface ColorValue {
|
|
50
|
+
space: ModernColorSpace;
|
|
51
|
+
channels: readonly [number, number, number];
|
|
52
|
+
alpha: number;
|
|
53
|
+
}
|
|
54
|
+
export interface SerializeColorOptions {
|
|
55
|
+
format?: ModernColorSpace;
|
|
56
|
+
precision?: number;
|
|
57
|
+
gamut?: "preserve" | "srgb" | "display-p3";
|
|
58
|
+
}
|
|
43
59
|
//#endregion
|
package/dist/color/types.d.ts
CHANGED
|
@@ -40,4 +40,20 @@ export interface ColorChangeResult {
|
|
|
40
40
|
hsva: Hsva;
|
|
41
41
|
css: string;
|
|
42
42
|
}
|
|
43
|
+
export type ColorChangeSource = "pointer" | "keyboard" | "field" | "swatch" | "eyedropper" | "image" | "recent" | "programmatic" | "unknown";
|
|
44
|
+
export interface ColorChangeMeta {
|
|
45
|
+
phase: "change" | "commit";
|
|
46
|
+
source: ColorChangeSource;
|
|
47
|
+
}
|
|
48
|
+
export type ModernColorSpace = "srgb" | "display-p3" | "oklab" | "oklch" | "lab" | "lch";
|
|
49
|
+
export interface ColorValue {
|
|
50
|
+
space: ModernColorSpace;
|
|
51
|
+
channels: readonly [number, number, number];
|
|
52
|
+
alpha: number;
|
|
53
|
+
}
|
|
54
|
+
export interface SerializeColorOptions {
|
|
55
|
+
format?: ModernColorSpace;
|
|
56
|
+
precision?: number;
|
|
57
|
+
gamut?: "preserve" | "srgb" | "display-p3";
|
|
58
|
+
}
|
|
43
59
|
//#endregion
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const require_css4 = require("./css4.cjs");
|
|
2
|
+
const require_parse = require("./parse.cjs");
|
|
3
|
+
//#region src/color/value.ts
|
|
4
|
+
function parseColor(input) {
|
|
5
|
+
const modern = require_css4.parseCss4Color(input);
|
|
6
|
+
if (modern !== null) return modern;
|
|
7
|
+
const legacy = require_parse.parse(input);
|
|
8
|
+
return legacy === null ? null : require_css4.hsvaToColorValue(legacy);
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
exports.parseColor = parseColor;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { hsvaToColorValue, parseCss4Color } from "./css4.js";
|
|
2
|
+
import { parse } from "./parse.js";
|
|
3
|
+
//#region src/color/value.ts
|
|
4
|
+
function parseColor(input) {
|
|
5
|
+
const modern = parseCss4Color(input);
|
|
6
|
+
if (modern !== null) return modern;
|
|
7
|
+
const legacy = parse(input);
|
|
8
|
+
return legacy === null ? null : hsvaToColorValue(legacy);
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { parseColor };
|
|
12
|
+
|
package/dist/color.cjs
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_convert = require("./color/convert.cjs");
|
|
3
|
+
const require_css4 = require("./color/css4.cjs");
|
|
4
|
+
const require_parse = require("./color/parse.cjs");
|
|
5
|
+
const require_serialize = require("./color/serialize.cjs");
|
|
6
|
+
const require_sticky = require("./color/sticky.cjs");
|
|
7
|
+
const require_store = require("./core/store.cjs");
|
|
8
|
+
const require_value = require("./color/value.cjs");
|
|
9
|
+
exports.clamp = require_convert.clamp;
|
|
10
|
+
exports.clearNamedColors = require_parse.clearNamedColors;
|
|
11
|
+
exports.colorValueToHsva = require_css4.colorValueToHsva;
|
|
12
|
+
exports.convertColor = require_css4.convertColor;
|
|
13
|
+
exports.createColorStore = require_store.createColorStore;
|
|
14
|
+
exports.hslaToHsva = require_convert.hslaToHsva;
|
|
15
|
+
exports.hsvaToColorValue = require_css4.hsvaToColorValue;
|
|
16
|
+
exports.hsvaToHsl = require_convert.hsvaToHsl;
|
|
17
|
+
exports.hsvaToHsla = require_convert.hsvaToHsla;
|
|
18
|
+
exports.hsvaToHwba = require_convert.hsvaToHwba;
|
|
19
|
+
exports.hsvaToRgb = require_convert.hsvaToRgb;
|
|
20
|
+
exports.hsvaToRgba = require_convert.hsvaToRgba;
|
|
21
|
+
exports.hwbaToHsva = require_convert.hwbaToHsva;
|
|
22
|
+
exports.ingest = require_sticky.ingest;
|
|
23
|
+
exports.isInGamut = require_css4.isInGamut;
|
|
24
|
+
exports.isValidColor = require_parse.isValidColor;
|
|
25
|
+
exports.mapToGamut = require_css4.mapToGamut;
|
|
26
|
+
exports.normalizeHue = require_convert.normalizeHue;
|
|
27
|
+
exports.parse = require_parse.parse;
|
|
28
|
+
exports.parseColor = require_value.parseColor;
|
|
29
|
+
exports.parseCss4Color = require_css4.parseCss4Color;
|
|
30
|
+
exports.registerNamedColors = require_parse.registerNamedColors;
|
|
31
|
+
exports.rgbaToHsva = require_convert.rgbaToHsva;
|
|
32
|
+
exports.roundRgba = require_convert.roundRgba;
|
|
33
|
+
exports.sameHsva = require_sticky.sameHsva;
|
|
34
|
+
exports.sameRendered = require_sticky.sameRendered;
|
|
35
|
+
exports.serializeColor = require_css4.serializeColor;
|
|
36
|
+
exports.toFormat = require_serialize.toFormat;
|
|
37
|
+
exports.toHex = require_serialize.toHex;
|
|
38
|
+
exports.toHexa = require_serialize.toHexa;
|
|
39
|
+
exports.toHslString = require_serialize.toHslString;
|
|
40
|
+
exports.toHslaString = require_serialize.toHslaString;
|
|
41
|
+
exports.toResult = require_serialize.toResult;
|
|
42
|
+
exports.toRgbString = require_serialize.toRgbString;
|
|
43
|
+
exports.toRgbaString = require_serialize.toRgbaString;
|
package/dist/color.d.cts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ColorChangeMeta, ColorChangeResult, ColorChangeSource, ColorFormat, ColorValue, Hsl, Hsla, Hsva, Hwb, Hwba, ModernColorSpace, Rgb, Rgba, SerializeColorOptions } from "./color/types.cjs";
|
|
2
|
+
import { clamp, hslaToHsva, hsvaToHsl, hsvaToHsla, hsvaToHwba, hsvaToRgb, hsvaToRgba, hwbaToHsva, normalizeHue, rgbaToHsva, roundRgba } from "./color/convert.cjs";
|
|
3
|
+
import { clearNamedColors, isValidColor, parse, registerNamedColors } from "./color/parse.cjs";
|
|
4
|
+
import { parseColor } from "./color/value.cjs";
|
|
5
|
+
import { colorValueToHsva, convertColor, hsvaToColorValue, isInGamut, mapToGamut, parseCss4Color, serializeColor } from "./color/css4.cjs";
|
|
6
|
+
import { toFormat, toHex, toHexa, toHslString, toHslaString, toResult, toRgbString, toRgbaString } from "./color/serialize.cjs";
|
|
7
|
+
import { ingest, sameHsva, sameRendered } from "./color/sticky.cjs";
|
|
8
|
+
import { ColorListener, ColorStore, Unsubscribe, createColorStore } from "./core/store.cjs";
|
|
9
|
+
export { ColorChangeMeta, ColorChangeResult, ColorChangeSource, ColorFormat, type ColorListener, type ColorStore, ColorValue, Hsl, Hsla, Hsva, Hwb, Hwba, ModernColorSpace, Rgb, Rgba, SerializeColorOptions, type Unsubscribe, clamp, clearNamedColors, colorValueToHsva, convertColor, createColorStore, hslaToHsva, hsvaToColorValue, hsvaToHsl, hsvaToHsla, hsvaToHwba, hsvaToRgb, hsvaToRgba, hwbaToHsva, ingest, isInGamut, isValidColor, mapToGamut, normalizeHue, parse, parseColor, parseCss4Color, registerNamedColors, rgbaToHsva, roundRgba, sameHsva, sameRendered, serializeColor, toFormat, toHex, toHexa, toHslString, toHslaString, toResult, toRgbString, toRgbaString };
|
package/dist/color.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ColorChangeMeta, ColorChangeResult, ColorChangeSource, ColorFormat, ColorValue, Hsl, Hsla, Hsva, Hwb, Hwba, ModernColorSpace, Rgb, Rgba, SerializeColorOptions } from "./color/types.js";
|
|
2
|
+
import { clamp, hslaToHsva, hsvaToHsl, hsvaToHsla, hsvaToHwba, hsvaToRgb, hsvaToRgba, hwbaToHsva, normalizeHue, rgbaToHsva, roundRgba } from "./color/convert.js";
|
|
3
|
+
import { clearNamedColors, isValidColor, parse, registerNamedColors } from "./color/parse.js";
|
|
4
|
+
import { parseColor } from "./color/value.js";
|
|
5
|
+
import { colorValueToHsva, convertColor, hsvaToColorValue, isInGamut, mapToGamut, parseCss4Color, serializeColor } from "./color/css4.js";
|
|
6
|
+
import { toFormat, toHex, toHexa, toHslString, toHslaString, toResult, toRgbString, toRgbaString } from "./color/serialize.js";
|
|
7
|
+
import { ingest, sameHsva, sameRendered } from "./color/sticky.js";
|
|
8
|
+
import { ColorListener, ColorStore, Unsubscribe, createColorStore } from "./core/store.js";
|
|
9
|
+
export { ColorChangeMeta, ColorChangeResult, ColorChangeSource, ColorFormat, type ColorListener, type ColorStore, ColorValue, Hsl, Hsla, Hsva, Hwb, Hwba, ModernColorSpace, Rgb, Rgba, SerializeColorOptions, type Unsubscribe, clamp, clearNamedColors, colorValueToHsva, convertColor, createColorStore, hslaToHsva, hsvaToColorValue, hsvaToHsl, hsvaToHsla, hsvaToHwba, hsvaToRgb, hsvaToRgba, hwbaToHsva, ingest, isInGamut, isValidColor, mapToGamut, normalizeHue, parse, parseColor, parseCss4Color, registerNamedColors, rgbaToHsva, roundRgba, sameHsva, sameRendered, serializeColor, toFormat, toHex, toHexa, toHslString, toHslaString, toResult, toRgbString, toRgbaString };
|
package/dist/color.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { clamp, hslaToHsva, hsvaToHsl, hsvaToHsla, hsvaToHwba, hsvaToRgb, hsvaToRgba, hwbaToHsva, normalizeHue, rgbaToHsva, roundRgba } from "./color/convert.js";
|
|
2
|
+
import { colorValueToHsva, convertColor, hsvaToColorValue, isInGamut, mapToGamut, parseCss4Color, serializeColor } from "./color/css4.js";
|
|
3
|
+
import { clearNamedColors, isValidColor, parse, registerNamedColors } from "./color/parse.js";
|
|
4
|
+
import { toFormat, toHex, toHexa, toHslString, toHslaString, toResult, toRgbString, toRgbaString } from "./color/serialize.js";
|
|
5
|
+
import { ingest, sameHsva, sameRendered } from "./color/sticky.js";
|
|
6
|
+
import { createColorStore } from "./core/store.js";
|
|
7
|
+
import { parseColor } from "./color/value.js";
|
|
8
|
+
export { clamp, clearNamedColors, colorValueToHsva, convertColor, createColorStore, hslaToHsva, hsvaToColorValue, hsvaToHsl, hsvaToHsla, hsvaToHwba, hsvaToRgb, hsvaToRgba, hwbaToHsva, ingest, isInGamut, isValidColor, mapToGamut, normalizeHue, parse, parseColor, parseCss4Color, registerNamedColors, rgbaToHsva, roundRgba, sameHsva, sameRendered, serializeColor, toFormat, toHex, toHexa, toHslString, toHslaString, toResult, toRgbString, toRgbaString };
|
|
@@ -26,7 +26,7 @@ const FALLBACK = {
|
|
|
26
26
|
a: 1
|
|
27
27
|
};
|
|
28
28
|
function ChromaPanel(props) {
|
|
29
|
-
const { value, defaultValue = DEFAULT_COLOR, onChange, onChangeComplete, modes = [
|
|
29
|
+
const { value, defaultValue = DEFAULT_COLOR, onChange, onChangeComplete, onValueChange, onValueCommit, modes = [
|
|
30
30
|
"wheel",
|
|
31
31
|
"sliders",
|
|
32
32
|
"palettes",
|
|
@@ -64,13 +64,15 @@ function ChromaPanel(props) {
|
|
|
64
64
|
return;
|
|
65
65
|
}
|
|
66
66
|
if (require_sticky.sameRendered(parsed, store.get())) return;
|
|
67
|
-
store.ingest(parsed);
|
|
67
|
+
store.ingest(parsed, "programmatic");
|
|
68
68
|
}, [value, store]);
|
|
69
69
|
const [internalRecents, setInternalRecents] = react.useState(() => defaultRecentColors ?? []);
|
|
70
70
|
const activeRecents = recentColors ?? internalRecents;
|
|
71
71
|
const callbacks = react.useRef({
|
|
72
72
|
onChange,
|
|
73
73
|
onChangeComplete,
|
|
74
|
+
onValueChange,
|
|
75
|
+
onValueCommit,
|
|
74
76
|
format,
|
|
75
77
|
activeRecents,
|
|
76
78
|
onRecentColorsChange,
|
|
@@ -80,16 +82,24 @@ function ChromaPanel(props) {
|
|
|
80
82
|
callbacks.current = {
|
|
81
83
|
onChange,
|
|
82
84
|
onChangeComplete,
|
|
85
|
+
onValueChange,
|
|
86
|
+
onValueCommit,
|
|
83
87
|
format,
|
|
84
88
|
activeRecents,
|
|
85
89
|
onRecentColorsChange,
|
|
86
90
|
controlled: recentColors !== void 0
|
|
87
91
|
};
|
|
88
92
|
});
|
|
89
|
-
react.useEffect(() => store.subscribe((c) =>
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
+
react.useEffect(() => store.subscribe((c, meta) => {
|
|
94
|
+
const result = require_serialize.toResult(c, callbacks.current.format);
|
|
95
|
+
callbacks.current.onChange?.(result);
|
|
96
|
+
callbacks.current.onValueChange?.(result, meta);
|
|
97
|
+
}), [store]);
|
|
98
|
+
react.useEffect(() => store.subscribeCommit((c, meta) => {
|
|
99
|
+
const { onChangeComplete: done, format: fmt, activeRecents: recents, onValueCommit: commit, onRecentColorsChange: notify, controlled } = callbacks.current;
|
|
100
|
+
const result = require_serialize.toResult(c, fmt);
|
|
101
|
+
done?.(result);
|
|
102
|
+
commit?.(result, meta);
|
|
93
103
|
const next = require_PanelFooter.pushRecent(recents, require_serialize.toHex(c));
|
|
94
104
|
if (!controlled) setInternalRecents(next);
|
|
95
105
|
notify?.(next);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ColorChangeResult, ColorFormat, Hsva } from "../color/types.cjs";
|
|
1
|
+
import { ColorChangeMeta, ColorChangeResult, ColorFormat, Hsva } from "../color/types.cjs";
|
|
2
2
|
import { ColorStore } from "../core/store.cjs";
|
|
3
3
|
import { ExtractOptions } from "../image/extract.cjs";
|
|
4
4
|
import { ModeId, PickerMode } from "../modes/registry.cjs";
|
|
@@ -11,7 +11,9 @@ export interface ChromaPanelProps {
|
|
|
11
11
|
defaultValue?: string | Hsva;
|
|
12
12
|
onChange?: (color: ColorChangeResult) => void;
|
|
13
13
|
onChangeComplete?: (color: ColorChangeResult) => void;
|
|
14
|
-
|
|
14
|
+
onValueChange?: (color: ColorChangeResult, meta: ColorChangeMeta) => void;
|
|
15
|
+
onValueCommit?: (color: ColorChangeResult, meta: ColorChangeMeta) => void;
|
|
16
|
+
modes?: readonly (ModeId | string | PickerMode)[];
|
|
15
17
|
mode?: string;
|
|
16
18
|
defaultMode?: string;
|
|
17
19
|
onModeChange?: (mode: string) => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ColorChangeResult, ColorFormat, Hsva } from "../color/types.js";
|
|
1
|
+
import { ColorChangeMeta, ColorChangeResult, ColorFormat, Hsva } from "../color/types.js";
|
|
2
2
|
import { ColorStore } from "../core/store.js";
|
|
3
3
|
import { ExtractOptions } from "../image/extract.js";
|
|
4
4
|
import { ModeId, PickerMode } from "../modes/registry.js";
|
|
@@ -11,7 +11,9 @@ export interface ChromaPanelProps {
|
|
|
11
11
|
defaultValue?: string | Hsva;
|
|
12
12
|
onChange?: (color: ColorChangeResult) => void;
|
|
13
13
|
onChangeComplete?: (color: ColorChangeResult) => void;
|
|
14
|
-
|
|
14
|
+
onValueChange?: (color: ColorChangeResult, meta: ColorChangeMeta) => void;
|
|
15
|
+
onValueCommit?: (color: ColorChangeResult, meta: ColorChangeMeta) => void;
|
|
16
|
+
modes?: readonly (ModeId | string | PickerMode)[];
|
|
15
17
|
mode?: string;
|
|
16
18
|
defaultMode?: string;
|
|
17
19
|
onModeChange?: (mode: string) => void;
|