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.
Files changed (92) hide show
  1. package/README.md +46 -8
  2. package/dist/a11y/contrast.cjs +94 -0
  3. package/dist/a11y/contrast.d.cts +8 -0
  4. package/dist/a11y/contrast.d.ts +8 -0
  5. package/dist/a11y/contrast.js +93 -2
  6. package/dist/color/css4.cjs +397 -0
  7. package/dist/color/css4.d.cts +10 -0
  8. package/dist/color/css4.d.ts +10 -0
  9. package/dist/color/css4.js +392 -0
  10. package/dist/color/parse.cjs +3 -1
  11. package/dist/color/parse.js +3 -1
  12. package/dist/color/types.d.cts +16 -0
  13. package/dist/color/types.d.ts +16 -0
  14. package/dist/color/value.cjs +11 -0
  15. package/dist/color/value.d.cts +4 -0
  16. package/dist/color/value.d.ts +4 -0
  17. package/dist/color/value.js +12 -0
  18. package/dist/color.cjs +43 -0
  19. package/dist/color.d.cts +9 -0
  20. package/dist/color.d.ts +9 -0
  21. package/dist/color.js +8 -0
  22. package/dist/components/ChromaPanel.cjs +16 -6
  23. package/dist/components/ChromaPanel.d.cts +4 -2
  24. package/dist/components/ChromaPanel.d.ts +4 -2
  25. package/dist/components/ChromaPanel.js +16 -6
  26. package/dist/components/ColorInput.cjs +1 -1
  27. package/dist/components/ColorInput.js +1 -1
  28. package/dist/components/PanelFooter.cjs +4 -4
  29. package/dist/components/PanelFooter.js +4 -4
  30. package/dist/contrast.cjs +3 -0
  31. package/dist/contrast.d.cts +2 -2
  32. package/dist/contrast.d.ts +2 -2
  33. package/dist/contrast.js +2 -2
  34. package/dist/core/store.cjs +17 -9
  35. package/dist/core/store.d.cts +6 -6
  36. package/dist/core/store.d.ts +6 -6
  37. package/dist/core/store.js +17 -9
  38. package/dist/core.cjs +10 -0
  39. package/dist/core.d.cts +4 -2
  40. package/dist/core.d.ts +4 -2
  41. package/dist/core.js +3 -1
  42. package/dist/export/tokens.cjs +39 -0
  43. package/dist/export/tokens.d.cts +16 -0
  44. package/dist/export/tokens.d.ts +16 -0
  45. package/dist/export/tokens.js +37 -0
  46. package/dist/export.cjs +6 -0
  47. package/dist/export.d.cts +2 -0
  48. package/dist/export.d.ts +2 -0
  49. package/dist/export.js +2 -0
  50. package/dist/gradient/GradientEditor.cjs +196 -0
  51. package/dist/gradient/GradientEditor.d.cts +17 -0
  52. package/dist/gradient/GradientEditor.d.ts +17 -0
  53. package/dist/gradient/GradientEditor.js +195 -0
  54. package/dist/gradient/model.cjs +63 -0
  55. package/dist/gradient/model.d.cts +23 -0
  56. package/dist/gradient/model.d.ts +23 -0
  57. package/dist/gradient/model.js +60 -0
  58. package/dist/gradient.cjs +9 -0
  59. package/dist/gradient.d.cts +3 -0
  60. package/dist/gradient.d.ts +3 -0
  61. package/dist/gradient.js +3 -0
  62. package/dist/index.cjs +13 -0
  63. package/dist/index.d.cts +5 -3
  64. package/dist/index.d.ts +5 -3
  65. package/dist/index.js +4 -2
  66. package/dist/modes/image/index.cjs +65 -4
  67. package/dist/modes/image/index.d.cts +1 -0
  68. package/dist/modes/image/index.d.ts +1 -0
  69. package/dist/modes/image/index.js +65 -4
  70. package/dist/modes/registry.d.cts +1 -1
  71. package/dist/modes/registry.d.ts +1 -1
  72. package/dist/modes.cjs +30 -0
  73. package/dist/modes.d.cts +10 -0
  74. package/dist/modes.d.ts +10 -0
  75. package/dist/modes.js +17 -0
  76. package/dist/panel.cjs +10 -0
  77. package/dist/panel.d.cts +4 -2
  78. package/dist/panel.d.ts +4 -2
  79. package/dist/panel.js +3 -1
  80. package/dist/primitives/ChannelSlider.cjs +4 -4
  81. package/dist/primitives/ChannelSlider.js +4 -4
  82. package/dist/primitives/ColorArea.cjs +6 -6
  83. package/dist/primitives/ColorArea.js +6 -6
  84. package/dist/primitives/ColorDisc.cjs +6 -6
  85. package/dist/primitives/ColorDisc.js +6 -6
  86. package/dist/primitives/ColorField.cjs +2 -2
  87. package/dist/primitives/ColorField.js +2 -2
  88. package/dist/primitives/NumberField.cjs +2 -2
  89. package/dist/primitives/NumberField.js +2 -2
  90. package/dist/primitives/SwatchGrid.cjs +2 -2
  91. package/dist/primitives/SwatchGrid.js +2 -2
  92. 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
+
@@ -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
- return null;
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;
@@ -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
- return null;
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;
@@ -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
@@ -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,4 @@
1
+ import { ColorValue } from "./types.cjs";
2
+ //#region src/color/value.d.ts
3
+ export declare function parseColor(input: string): ColorValue | null;
4
+ //#endregion
@@ -0,0 +1,4 @@
1
+ import { ColorValue } from "./types.js";
2
+ //#region src/color/value.d.ts
3
+ export declare function parseColor(input: string): ColorValue | null;
4
+ //#endregion
@@ -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;
@@ -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 };
@@ -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) => callbacks.current.onChange?.(require_serialize.toResult(c, callbacks.current.format))), [store]);
90
- react.useEffect(() => store.subscribeCommit((c) => {
91
- const { onChangeComplete: done, format: fmt, activeRecents: recents, onRecentColorsChange: notify, controlled } = callbacks.current;
92
- done?.(require_serialize.toResult(c, fmt));
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
- modes?: (ModeId | string | PickerMode)[];
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
- modes?: (ModeId | string | PickerMode)[];
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;