@pixpilot/shadcn 0.5.0 → 0.6.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 (84) hide show
  1. package/dist/components/index.cjs +6 -4
  2. package/dist/components/index.d.cts +6 -4
  3. package/dist/components/index.d.ts +6 -4
  4. package/dist/components/index.js +7 -5
  5. package/dist/components/ui/OrContinueWithSeparator.d.cts +2 -2
  6. package/dist/components/ui/OrContinueWithSeparator.d.ts +2 -2
  7. package/dist/components/ui/alert-dialog.d.cts +12 -12
  8. package/dist/components/ui/alert.d.cts +4 -4
  9. package/dist/components/ui/avatar.d.cts +4 -4
  10. package/dist/components/ui/badge.d.cts +2 -2
  11. package/dist/components/ui/button.cjs +3 -1
  12. package/dist/components/ui/button.d.cts +2 -2
  13. package/dist/components/ui/button.js +3 -1
  14. package/dist/components/ui/calendar.d.cts +3 -3
  15. package/dist/components/ui/card.d.cts +8 -8
  16. package/dist/components/ui/checkbox.d.cts +2 -2
  17. package/dist/components/ui/color-picker.cjs +1171 -0
  18. package/dist/components/ui/color-picker.d.cts +94 -0
  19. package/dist/components/ui/color-picker.d.ts +94 -0
  20. package/dist/components/ui/color-picker.js +1152 -0
  21. package/dist/components/ui/command.d.cts +10 -10
  22. package/dist/components/ui/command.d.ts +10 -10
  23. package/dist/components/ui/dialog.d.cts +11 -11
  24. package/dist/components/ui/dialog.d.ts +11 -11
  25. package/dist/components/ui/dropdown-menu.d.cts +16 -16
  26. package/dist/components/ui/dropdown-menu.d.ts +16 -16
  27. package/dist/components/ui/file-upload.d.cts +11 -11
  28. package/dist/components/ui/file-upload.d.ts +11 -11
  29. package/dist/components/ui/form.d.cts +7 -7
  30. package/dist/components/ui/form.d.ts +7 -7
  31. package/dist/components/ui/index.cjs +6 -4
  32. package/dist/components/ui/index.d.cts +6 -4
  33. package/dist/components/ui/index.d.ts +6 -4
  34. package/dist/components/ui/index.js +7 -5
  35. package/dist/components/ui/input-group.cjs +90 -0
  36. package/dist/components/ui/input-group.d.cts +43 -0
  37. package/dist/components/ui/input-group.d.ts +43 -0
  38. package/dist/components/ui/input-group.js +81 -0
  39. package/dist/components/ui/input.d.cts +2 -2
  40. package/dist/components/ui/input.d.ts +2 -2
  41. package/dist/components/ui/label.d.cts +2 -2
  42. package/dist/components/ui/label.d.ts +2 -2
  43. package/dist/components/ui/pagination.d.cts +8 -8
  44. package/dist/components/ui/pagination.d.ts +8 -8
  45. package/dist/components/ui/popover.d.cts +5 -5
  46. package/dist/components/ui/popover.d.ts +5 -5
  47. package/dist/components/ui/radio-group.d.cts +3 -3
  48. package/dist/components/ui/radio-group.d.ts +3 -3
  49. package/dist/components/ui/select.d.cts +11 -11
  50. package/dist/components/ui/select.d.ts +11 -11
  51. package/dist/components/ui/separator.d.cts +2 -2
  52. package/dist/components/ui/separator.d.ts +2 -2
  53. package/dist/components/ui/shadcn-io/tags/index.cjs +1 -1
  54. package/dist/components/ui/shadcn-io/tags/index.d.cts +10 -10
  55. package/dist/components/ui/shadcn-io/tags/index.d.ts +10 -10
  56. package/dist/components/ui/shadcn-io/tags/index.js +1 -1
  57. package/dist/components/ui/shadcn-io/tags-input-inline/index.d.cts +7 -7
  58. package/dist/components/ui/shadcn-io/tags-input-inline/index.d.ts +7 -7
  59. package/dist/components/ui/sheet.d.cts +9 -9
  60. package/dist/components/ui/sheet.d.ts +9 -9
  61. package/dist/components/ui/slider.d.cts +2 -2
  62. package/dist/components/ui/slider.d.ts +2 -2
  63. package/dist/components/ui/switch.d.cts +2 -2
  64. package/dist/components/ui/switch.d.ts +2 -2
  65. package/dist/components/ui/tabs.d.cts +8 -8
  66. package/dist/components/ui/tabs.d.ts +8 -8
  67. package/dist/components/ui/textarea.d.cts +2 -2
  68. package/dist/components/ui/textarea.d.ts +2 -2
  69. package/dist/components/ui/tooltip.d.cts +5 -5
  70. package/dist/components/visually-hidden-input.cjs +116 -0
  71. package/dist/components/visually-hidden-input.js +113 -0
  72. package/dist/hooks/use-as-ref.cjs +16 -0
  73. package/dist/hooks/use-as-ref.js +14 -0
  74. package/dist/hooks/use-isomorphic-layout-effect.cjs +9 -0
  75. package/dist/hooks/use-isomorphic-layout-effect.js +7 -0
  76. package/dist/hooks/use-lazy-ref.cjs +13 -0
  77. package/dist/hooks/use-lazy-ref.js +11 -0
  78. package/dist/index.cjs +24 -4
  79. package/dist/index.d.cts +7 -5
  80. package/dist/index.d.ts +7 -5
  81. package/dist/index.js +8 -6
  82. package/dist/lib/compose-refs.cjs +44 -0
  83. package/dist/lib/compose-refs.js +42 -0
  84. package/package.json +1 -1
@@ -0,0 +1,1171 @@
1
+ 'use client';
2
+
3
+
4
+ const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
5
+ const require_utils = require('../../lib/utils.cjs');
6
+ require('../../lib/index.cjs');
7
+ const require_button = require('./button.cjs');
8
+ const require_input = require('./input.cjs');
9
+ const require_popover = require('./popover.cjs');
10
+ const require_select = require('./select.cjs');
11
+ const require_compose_refs = require('../../lib/compose-refs.cjs');
12
+ const require_visually_hidden_input = require('../visually-hidden-input.cjs');
13
+ const require_use_isomorphic_layout_effect = require('../../hooks/use-isomorphic-layout-effect.cjs');
14
+ const require_use_as_ref = require('../../hooks/use-as-ref.cjs');
15
+ const require_use_lazy_ref = require('../../hooks/use-lazy-ref.cjs');
16
+ let class_variance_authority = require("class-variance-authority");
17
+ class_variance_authority = require_rolldown_runtime.__toESM(class_variance_authority);
18
+ let react = require("react");
19
+ react = require_rolldown_runtime.__toESM(react);
20
+ let react_jsx_runtime = require("react/jsx-runtime");
21
+ react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
22
+ let __radix_ui_react_slot = require("@radix-ui/react-slot");
23
+ __radix_ui_react_slot = require_rolldown_runtime.__toESM(__radix_ui_react_slot);
24
+ let lucide_react = require("lucide-react");
25
+ lucide_react = require_rolldown_runtime.__toESM(lucide_react);
26
+ let __radix_ui_react_direction = require("@radix-ui/react-direction");
27
+ __radix_ui_react_direction = require_rolldown_runtime.__toESM(__radix_ui_react_direction);
28
+ let __radix_ui_react_slider = require("@radix-ui/react-slider");
29
+ __radix_ui_react_slider = require_rolldown_runtime.__toESM(__radix_ui_react_slider);
30
+
31
+ //#region src/components/ui/color-picker.tsx
32
+ const ROOT_NAME = "ColorPicker";
33
+ const ROOT_IMPL_NAME = "ColorPickerImpl";
34
+ const TRIGGER_NAME = "ColorPickerTrigger";
35
+ const CONTENT_NAME = "ColorPickerContent";
36
+ const AREA_NAME = "ColorPickerArea";
37
+ const HUE_SLIDER_NAME = "ColorPickerHueSlider";
38
+ const ALPHA_SLIDER_NAME = "ColorPickerAlphaSlider";
39
+ const SWATCH_NAME = "ColorPickerSwatch";
40
+ const EYE_DROPPER_NAME = "ColorPickerEyeDropper";
41
+ const FORMAT_SELECT_NAME = "ColorPickerFormatSelect";
42
+ const INPUT_NAME = "ColorPickerInput";
43
+ const colorFormats = [
44
+ "hex",
45
+ "rgb",
46
+ "hsl",
47
+ "hsb"
48
+ ];
49
+ function hexToRgb(hex, alpha) {
50
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
51
+ return result ? {
52
+ r: Number.parseInt(result[1] ?? "0", 16),
53
+ g: Number.parseInt(result[2] ?? "0", 16),
54
+ b: Number.parseInt(result[3] ?? "0", 16),
55
+ a: alpha ?? 1
56
+ } : {
57
+ r: 0,
58
+ g: 0,
59
+ b: 0,
60
+ a: alpha ?? 1
61
+ };
62
+ }
63
+ function rgbToHex(color) {
64
+ const toHex = (n) => {
65
+ const hex = Math.round(n).toString(16);
66
+ return hex.length === 1 ? `0${hex}` : hex;
67
+ };
68
+ return `#${toHex(color.r)}${toHex(color.g)}${toHex(color.b)}`;
69
+ }
70
+ function rgbToHexWithAlpha(color) {
71
+ const toHex = (n) => {
72
+ const hex = Math.round(n).toString(16);
73
+ return hex.length === 1 ? `0${hex}` : hex;
74
+ };
75
+ const alphaByte = Math.min(255, Math.max(0, Math.round((color.a ?? 1) * 255)));
76
+ return `#${toHex(color.r)}${toHex(color.g)}${toHex(color.b)}${toHex(alphaByte)}`;
77
+ }
78
+ function rgbToHsv(color) {
79
+ const r = color.r / 255;
80
+ const g = color.g / 255;
81
+ const b = color.b / 255;
82
+ const max = Math.max(r, g, b);
83
+ const diff = max - Math.min(r, g, b);
84
+ let h = 0;
85
+ if (diff !== 0) switch (max) {
86
+ case r:
87
+ h = (g - b) / diff % 6;
88
+ break;
89
+ case g:
90
+ h = (b - r) / diff + 2;
91
+ break;
92
+ case b:
93
+ h = (r - g) / diff + 4;
94
+ break;
95
+ }
96
+ h = Math.round(h * 60);
97
+ if (h < 0) h += 360;
98
+ const s = max === 0 ? 0 : diff / max;
99
+ const v = max;
100
+ return {
101
+ h,
102
+ s: Math.round(s * 100),
103
+ v: Math.round(v * 100),
104
+ a: color.a
105
+ };
106
+ }
107
+ function hsvToRgb(hsv) {
108
+ const h = hsv.h / 360;
109
+ const s = hsv.s / 100;
110
+ const v = hsv.v / 100;
111
+ const i = Math.floor(h * 6);
112
+ const f = h * 6 - i;
113
+ const p = v * (1 - s);
114
+ const q = v * (1 - f * s);
115
+ const t = v * (1 - (1 - f) * s);
116
+ let r;
117
+ let g;
118
+ let b;
119
+ switch (i % 6) {
120
+ case 0:
121
+ r = v;
122
+ g = t;
123
+ b = p;
124
+ break;
125
+ case 1:
126
+ r = q;
127
+ g = v;
128
+ b = p;
129
+ break;
130
+ case 2:
131
+ r = p;
132
+ g = v;
133
+ b = t;
134
+ break;
135
+ case 3:
136
+ r = p;
137
+ g = q;
138
+ b = v;
139
+ break;
140
+ case 4:
141
+ r = t;
142
+ g = p;
143
+ b = v;
144
+ break;
145
+ case 5:
146
+ r = v;
147
+ g = p;
148
+ b = q;
149
+ break;
150
+ default:
151
+ r = 0;
152
+ g = 0;
153
+ b = 0;
154
+ }
155
+ return {
156
+ r: Math.round(r * 255),
157
+ g: Math.round(g * 255),
158
+ b: Math.round(b * 255),
159
+ a: hsv.a
160
+ };
161
+ }
162
+ function colorToString(color, format = "hex") {
163
+ switch (format) {
164
+ case "hex": return color.a < 1 ? rgbToHexWithAlpha(color) : rgbToHex(color);
165
+ case "rgb": return color.a < 1 ? `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})` : `rgb(${color.r}, ${color.g}, ${color.b})`;
166
+ case "hsl": {
167
+ const hsl = rgbToHsl(color);
168
+ return color.a < 1 ? `hsla(${hsl.h}, ${hsl.s}%, ${hsl.l}%, ${color.a})` : `hsl(${hsl.h}, ${hsl.s}%, ${hsl.l}%)`;
169
+ }
170
+ case "hsb": {
171
+ const hsv = rgbToHsv(color);
172
+ return color.a < 1 ? `hsba(${hsv.h}, ${hsv.s}%, ${hsv.v}%, ${color.a})` : `hsb(${hsv.h}, ${hsv.s}%, ${hsv.v}%)`;
173
+ }
174
+ default: return rgbToHex(color);
175
+ }
176
+ }
177
+ function rgbToHsl(color) {
178
+ const r = color.r / 255;
179
+ const g = color.g / 255;
180
+ const b = color.b / 255;
181
+ const max = Math.max(r, g, b);
182
+ const min = Math.min(r, g, b);
183
+ const diff = max - min;
184
+ const sum = max + min;
185
+ const l = sum / 2;
186
+ let h = 0;
187
+ let s = 0;
188
+ if (diff !== 0) {
189
+ s = l > .5 ? diff / (2 - sum) : diff / sum;
190
+ if (max === r) h = (g - b) / diff + (g < b ? 6 : 0);
191
+ else if (max === g) h = (b - r) / diff + 2;
192
+ else if (max === b) h = (r - g) / diff + 4;
193
+ h /= 6;
194
+ }
195
+ return {
196
+ h: Math.round(h * 360),
197
+ s: Math.round(s * 100),
198
+ l: Math.round(l * 100)
199
+ };
200
+ }
201
+ function hslToRgb(hsl, alpha = 1) {
202
+ const h = hsl.h / 360;
203
+ const s = hsl.s / 100;
204
+ const l = hsl.l / 100;
205
+ const c = (1 - Math.abs(2 * l - 1)) * s;
206
+ const x = c * (1 - Math.abs(h * 6 % 2 - 1));
207
+ const m = l - c / 2;
208
+ let r = 0;
209
+ let g = 0;
210
+ let b = 0;
211
+ if (h >= 0 && h < 1 / 6) {
212
+ r = c;
213
+ g = x;
214
+ b = 0;
215
+ } else if (h >= 1 / 6 && h < 2 / 6) {
216
+ r = x;
217
+ g = c;
218
+ b = 0;
219
+ } else if (h >= 2 / 6 && h < 3 / 6) {
220
+ r = 0;
221
+ g = c;
222
+ b = x;
223
+ } else if (h >= 3 / 6 && h < 4 / 6) {
224
+ r = 0;
225
+ g = x;
226
+ b = c;
227
+ } else if (h >= 4 / 6 && h < 5 / 6) {
228
+ r = x;
229
+ g = 0;
230
+ b = c;
231
+ } else if (h >= 5 / 6 && h < 1) {
232
+ r = c;
233
+ g = 0;
234
+ b = x;
235
+ }
236
+ return {
237
+ r: Math.round((r + m) * 255),
238
+ g: Math.round((g + m) * 255),
239
+ b: Math.round((b + m) * 255),
240
+ a: alpha
241
+ };
242
+ }
243
+ function parseColorString(value) {
244
+ const trimmed = value.trim();
245
+ if (trimmed.startsWith("#")) {
246
+ const hexMatch = trimmed.match(/^#([a-f0-9]{3}|[a-f0-9]{4}|[a-f0-9]{6}|[a-f0-9]{8})$/i);
247
+ if (hexMatch) {
248
+ const hex = (hexMatch[1] ?? "").toLowerCase();
249
+ if (hex.length === 3 || hex.length === 4) return {
250
+ r: Number.parseInt(hex[0] ? `${hex[0]}${hex[0]}` : "00", 16),
251
+ g: Number.parseInt(hex[1] ? `${hex[1]}${hex[1]}` : "00", 16),
252
+ b: Number.parseInt(hex[2] ? `${hex[2]}${hex[2]}` : "00", 16),
253
+ a: hex.length === 4 ? Number.parseInt(hex[3] ? `${hex[3]}${hex[3]}` : "ff", 16) / 255 : 1
254
+ };
255
+ if (hex.length === 6 || hex.length === 8) return {
256
+ r: Number.parseInt(hex.slice(0, 2) || "00", 16),
257
+ g: Number.parseInt(hex.slice(2, 4) || "00", 16),
258
+ b: Number.parseInt(hex.slice(4, 6) || "00", 16),
259
+ a: hex.length === 8 ? Number.parseInt(hex.slice(6, 8) || "ff", 16) / 255 : 1
260
+ };
261
+ }
262
+ }
263
+ const rgbMatch = trimmed.match(/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+)\s*)?\)$/);
264
+ if (rgbMatch) return {
265
+ r: Number.parseInt(rgbMatch[1] ?? "0", 10),
266
+ g: Number.parseInt(rgbMatch[2] ?? "0", 10),
267
+ b: Number.parseInt(rgbMatch[3] ?? "0", 10),
268
+ a: rgbMatch[4] ? Number.parseFloat(rgbMatch[4]) : 1
269
+ };
270
+ const hslMatch = trimmed.match(/^hsla?\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(?:,\s*([\d.]+)\s*)?\)$/);
271
+ if (hslMatch) {
272
+ const h = Number.parseInt(hslMatch[1] ?? "0", 10);
273
+ const s = Number.parseInt(hslMatch[2] ?? "0", 10) / 100;
274
+ const l = Number.parseInt(hslMatch[3] ?? "0", 10) / 100;
275
+ const a = hslMatch[4] ? Number.parseFloat(hslMatch[4]) : 1;
276
+ const c = (1 - Math.abs(2 * l - 1)) * s;
277
+ const x = c * (1 - Math.abs(h / 60 % 2 - 1));
278
+ const m = l - c / 2;
279
+ let r = 0;
280
+ let g = 0;
281
+ let b = 0;
282
+ if (h >= 0 && h < 60) {
283
+ r = c;
284
+ g = x;
285
+ b = 0;
286
+ } else if (h >= 60 && h < 120) {
287
+ r = x;
288
+ g = c;
289
+ b = 0;
290
+ } else if (h >= 120 && h < 180) {
291
+ r = 0;
292
+ g = c;
293
+ b = x;
294
+ } else if (h >= 180 && h < 240) {
295
+ r = 0;
296
+ g = x;
297
+ b = c;
298
+ } else if (h >= 240 && h < 300) {
299
+ r = x;
300
+ g = 0;
301
+ b = c;
302
+ } else if (h >= 300 && h < 360) {
303
+ r = c;
304
+ g = 0;
305
+ b = x;
306
+ }
307
+ return {
308
+ r: Math.round((r + m) * 255),
309
+ g: Math.round((g + m) * 255),
310
+ b: Math.round((b + m) * 255),
311
+ a
312
+ };
313
+ }
314
+ const hsbMatch = trimmed.match(/^hsba?\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(?:,\s*([\d.]+)\s*)?\)$/);
315
+ if (hsbMatch) return hsvToRgb({
316
+ h: Number.parseInt(hsbMatch[1] ?? "0", 10),
317
+ s: Number.parseInt(hsbMatch[2] ?? "0", 10),
318
+ v: Number.parseInt(hsbMatch[3] ?? "0", 10),
319
+ a: hsbMatch[4] ? Number.parseFloat(hsbMatch[4]) : 1
320
+ });
321
+ return null;
322
+ }
323
+ function areColorsEqual(a, b) {
324
+ return a.r === b.r && a.g === b.g && a.b === b.b && a.a === b.a;
325
+ }
326
+ function areHsvEqual(a, b) {
327
+ return a.h === b.h && a.s === b.s && a.v === b.v && a.a === b.a;
328
+ }
329
+ const StoreContext = react.createContext(null);
330
+ function useStoreContext(consumerName) {
331
+ const context = react.use(StoreContext);
332
+ if (!context) throw new Error(`\`${consumerName}\` must be used within \`ColorPickerRoot\``);
333
+ return context;
334
+ }
335
+ function useStore(selector) {
336
+ const store = useStoreContext("useStore");
337
+ const getSnapshot = react.useCallback(() => selector(store.getState()), [store, selector]);
338
+ return react.useSyncExternalStore(store.subscribe, getSnapshot, getSnapshot);
339
+ }
340
+ const ColorPickerContext = react.createContext(null);
341
+ function useColorPickerContext(consumerName) {
342
+ const context = react.use(ColorPickerContext);
343
+ if (!context) throw new Error(`\`${consumerName}\` must be used within \`${ROOT_NAME}\``);
344
+ return context;
345
+ }
346
+ function ColorPicker(props) {
347
+ const { value: valueProp, defaultValue = "#000000", onValueChange, format: formatProp, defaultFormat = "hex", onFormatChange, defaultOpen, open: openProp, onOpenChange, name, disabled, inline, readOnly, required,...rootProps } = props;
348
+ const listenersRef = require_use_lazy_ref.useLazyRef(() => /* @__PURE__ */ new Set());
349
+ const stateRef = require_use_lazy_ref.useLazyRef(() => {
350
+ const color = hexToRgb(valueProp ?? defaultValue);
351
+ return {
352
+ color,
353
+ hsv: rgbToHsv(color),
354
+ open: openProp ?? defaultOpen ?? false,
355
+ format: formatProp ?? defaultFormat
356
+ };
357
+ });
358
+ const propsRef = require_use_as_ref.useAsRef({
359
+ onValueChange,
360
+ onOpenChange,
361
+ onFormatChange
362
+ });
363
+ const store = react.useMemo(() => {
364
+ return {
365
+ subscribe: (cb) => {
366
+ listenersRef.current.add(cb);
367
+ return () => listenersRef.current.delete(cb);
368
+ },
369
+ getState: () => stateRef.current,
370
+ setColor: (value) => {
371
+ if (areColorsEqual(stateRef.current.color, value)) return;
372
+ const prevState = { ...stateRef.current };
373
+ stateRef.current.color = value;
374
+ if (propsRef.current.onValueChange) {
375
+ const colorString = colorToString(value, prevState.format);
376
+ propsRef.current.onValueChange(colorString);
377
+ }
378
+ store.notify();
379
+ },
380
+ setHsv: (value) => {
381
+ if (areHsvEqual(stateRef.current.hsv, value)) return;
382
+ const prevState = { ...stateRef.current };
383
+ stateRef.current.hsv = value;
384
+ if (propsRef.current.onValueChange) {
385
+ const colorString = colorToString(hsvToRgb(value), prevState.format);
386
+ propsRef.current.onValueChange(colorString);
387
+ }
388
+ store.notify();
389
+ },
390
+ syncFromValueProp: (value) => {
391
+ const currentState = stateRef.current;
392
+ const parsed = parseColorString(value);
393
+ let color = parsed || {
394
+ r: 0,
395
+ g: 0,
396
+ b: 0,
397
+ a: currentState.color.a
398
+ };
399
+ if (parsed && typeof currentState.color.a === "number") {
400
+ const trimmed = value.trim().toLowerCase();
401
+ if (trimmed.startsWith("#") && (trimmed.length === 4 || trimmed.length === 7) && parsed.a === 1 && currentState.color.a !== 1) color = {
402
+ ...parsed,
403
+ a: currentState.color.a
404
+ };
405
+ }
406
+ const nextColor = color;
407
+ const nextHsv = rgbToHsv(nextColor);
408
+ const didChangeColor = !areColorsEqual(currentState.color, nextColor);
409
+ const didChangeHsv = !areHsvEqual(currentState.hsv, nextHsv);
410
+ if (!didChangeColor && !didChangeHsv) return;
411
+ if (didChangeColor) currentState.color = nextColor;
412
+ if (didChangeHsv) currentState.hsv = nextHsv;
413
+ store.notify();
414
+ },
415
+ setOpen: (value) => {
416
+ if (Object.is(stateRef.current.open, value)) return;
417
+ stateRef.current.open = value;
418
+ if (propsRef.current.onOpenChange) propsRef.current.onOpenChange(value);
419
+ store.notify();
420
+ },
421
+ setFormat: (value) => {
422
+ if (Object.is(stateRef.current.format, value)) return;
423
+ stateRef.current.format = value;
424
+ if (propsRef.current.onFormatChange) propsRef.current.onFormatChange(value);
425
+ store.notify();
426
+ },
427
+ notify: () => {
428
+ for (const cb of listenersRef.current) cb();
429
+ }
430
+ };
431
+ }, [
432
+ listenersRef,
433
+ stateRef,
434
+ propsRef
435
+ ]);
436
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StoreContext.Provider, {
437
+ value: store,
438
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ColorPickerImpl, {
439
+ ...rootProps,
440
+ value: valueProp,
441
+ defaultOpen,
442
+ open: openProp,
443
+ name,
444
+ disabled,
445
+ inline,
446
+ readOnly,
447
+ required
448
+ })
449
+ });
450
+ }
451
+ function ColorPickerImpl(props) {
452
+ const { value: valueProp, dir: dirProp, defaultOpen, open: openProp, name, ref, asChild, disabled, inline, modal, readOnly, required,...rootProps } = props;
453
+ const store = useStoreContext(ROOT_IMPL_NAME);
454
+ const dir = (0, __radix_ui_react_direction.useDirection)(dirProp);
455
+ const [formTrigger, setFormTrigger] = react.useState(null);
456
+ const composedRef = require_compose_refs.useComposedRefs(ref, (node) => setFormTrigger(node));
457
+ const isFormControl = formTrigger ? Boolean(formTrigger.closest("form")) : true;
458
+ require_use_isomorphic_layout_effect.useIsomorphicLayoutEffect(() => {
459
+ if (valueProp !== void 0) store.syncFromValueProp(valueProp);
460
+ }, [valueProp]);
461
+ require_use_isomorphic_layout_effect.useIsomorphicLayoutEffect(() => {
462
+ if (openProp !== void 0) store.setOpen(openProp);
463
+ }, [openProp]);
464
+ const contextValue = react.useMemo(() => ({
465
+ dir,
466
+ disabled,
467
+ inline,
468
+ readOnly,
469
+ required
470
+ }), [
471
+ dir,
472
+ disabled,
473
+ inline,
474
+ readOnly,
475
+ required
476
+ ]);
477
+ const value = useStore((state) => rgbToHex(state.color));
478
+ const open = useStore((state) => state.open);
479
+ const RootPrimitive = asChild ? __radix_ui_react_slot.Slot : "div";
480
+ if (inline) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ColorPickerContext.Provider, {
481
+ value: contextValue,
482
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(RootPrimitive, {
483
+ ...rootProps,
484
+ ref: composedRef
485
+ }), isFormControl && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_visually_hidden_input.VisuallyHiddenInput, {
486
+ type: "hidden",
487
+ control: formTrigger,
488
+ name,
489
+ value,
490
+ disabled,
491
+ readOnly,
492
+ required
493
+ })]
494
+ });
495
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ColorPickerContext.Provider, {
496
+ value: contextValue,
497
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_popover.Popover, {
498
+ defaultOpen,
499
+ open,
500
+ onOpenChange: store.setOpen,
501
+ modal,
502
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(RootPrimitive, {
503
+ ...rootProps,
504
+ ref: composedRef
505
+ }), isFormControl && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_visually_hidden_input.VisuallyHiddenInput, {
506
+ type: "hidden",
507
+ control: formTrigger,
508
+ name,
509
+ value,
510
+ disabled,
511
+ readOnly,
512
+ required
513
+ })]
514
+ })
515
+ });
516
+ }
517
+ function ColorPickerTrigger({ variant,...props }) {
518
+ const { asChild, disabled,...triggerProps } = props;
519
+ const context = useColorPickerContext(TRIGGER_NAME);
520
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_popover.PopoverTrigger, {
521
+ asChild: true,
522
+ disabled: disabled || context.disabled,
523
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(asChild ? __radix_ui_react_slot.Slot : require_button.Button, {
524
+ "data-slot": "color-picker-trigger",
525
+ ...asChild ? {} : { variant },
526
+ ...triggerProps
527
+ })
528
+ });
529
+ }
530
+ function ColorPickerContent(props) {
531
+ const { asChild, className, children,...popoverContentProps } = props;
532
+ if (useColorPickerContext(CONTENT_NAME).inline) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(asChild ? __radix_ui_react_slot.Slot : "div", {
533
+ "data-slot": "color-picker-content",
534
+ ...popoverContentProps,
535
+ className: require_utils.cn("flex w-[340px] flex-col gap-4 p-4", className),
536
+ children
537
+ });
538
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_popover.PopoverContent, {
539
+ "data-slot": "color-picker-content",
540
+ asChild,
541
+ ...popoverContentProps,
542
+ className: require_utils.cn("flex w-[340px] flex-col gap-4 p-4", className),
543
+ children
544
+ });
545
+ }
546
+ function ColorPickerArea(props) {
547
+ const { asChild, onPointerDown: onPointerDownProp, onPointerMove: onPointerMoveProp, onPointerUp: onPointerUpProp, className, ref,...areaProps } = props;
548
+ const propsRef = require_use_as_ref.useAsRef({
549
+ onPointerDown: onPointerDownProp,
550
+ onPointerMove: onPointerMoveProp,
551
+ onPointerUp: onPointerUpProp
552
+ });
553
+ const context = useColorPickerContext(AREA_NAME);
554
+ const store = useStoreContext(AREA_NAME);
555
+ const hsv = useStore((state) => state.hsv);
556
+ const isDraggingRef = react.useRef(false);
557
+ const areaRef = react.useRef(null);
558
+ const composedRef = require_compose_refs.useComposedRefs(ref, areaRef);
559
+ const updateColorFromPosition = react.useCallback((clientX, clientY) => {
560
+ if (!areaRef.current) return;
561
+ const rect = areaRef.current.getBoundingClientRect();
562
+ const x = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
563
+ const y = Math.max(0, Math.min(1, 1 - (clientY - rect.top) / rect.height));
564
+ const newHsv = {
565
+ h: hsv?.h ?? 0,
566
+ s: Math.round(x * 100),
567
+ v: Math.round(y * 100),
568
+ a: hsv?.a ?? 1
569
+ };
570
+ store.setHsv(newHsv);
571
+ store.setColor(hsvToRgb(newHsv));
572
+ }, [hsv, store]);
573
+ const onPointerDown = react.useCallback((event) => {
574
+ if (context.disabled) return;
575
+ propsRef.current.onPointerDown?.(event);
576
+ if (event.defaultPrevented) return;
577
+ isDraggingRef.current = true;
578
+ areaRef.current?.setPointerCapture(event.pointerId);
579
+ updateColorFromPosition(event.clientX, event.clientY);
580
+ }, [
581
+ context.disabled,
582
+ updateColorFromPosition,
583
+ propsRef
584
+ ]);
585
+ const onPointerMove = react.useCallback((event) => {
586
+ propsRef.current.onPointerMove?.(event);
587
+ if (event.defaultPrevented) return;
588
+ if (isDraggingRef.current) updateColorFromPosition(event.clientX, event.clientY);
589
+ }, [updateColorFromPosition, propsRef]);
590
+ const onPointerUp = react.useCallback((event) => {
591
+ propsRef.current.onPointerUp?.(event);
592
+ if (event.defaultPrevented) return;
593
+ isDraggingRef.current = false;
594
+ areaRef.current?.releasePointerCapture(event.pointerId);
595
+ }, [propsRef]);
596
+ const backgroundHue = hsvToRgb({
597
+ h: hsv?.h ?? 0,
598
+ s: 100,
599
+ v: 100,
600
+ a: 1
601
+ });
602
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(asChild ? __radix_ui_react_slot.Slot : "div", {
603
+ "data-slot": "color-picker-area",
604
+ ...areaProps,
605
+ className: require_utils.cn("relative h-40 w-full cursor-crosshair touch-none rounded-sm border", context.disabled && "pointer-events-none opacity-50", className),
606
+ ref: composedRef,
607
+ onPointerDown,
608
+ onPointerMove,
609
+ onPointerUp,
610
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
611
+ className: "absolute inset-0 overflow-hidden rounded-sm",
612
+ children: [
613
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
614
+ className: "absolute inset-0",
615
+ style: { backgroundColor: `rgb(${backgroundHue.r}, ${backgroundHue.g}, ${backgroundHue.b})` }
616
+ }),
617
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
618
+ className: "absolute inset-0",
619
+ style: { background: "linear-gradient(to right, #fff, transparent)" }
620
+ }),
621
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
622
+ className: "absolute inset-0",
623
+ style: { background: "linear-gradient(to bottom, transparent, #000)" }
624
+ })
625
+ ]
626
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
627
+ className: "absolute size-3 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white shadow-sm",
628
+ style: {
629
+ left: `${hsv?.s ?? 0}%`,
630
+ top: `${100 - (hsv?.v ?? 0)}%`
631
+ }
632
+ })]
633
+ });
634
+ }
635
+ function ColorPickerHueSlider(props) {
636
+ const { className,...sliderProps } = props;
637
+ const context = useColorPickerContext(HUE_SLIDER_NAME);
638
+ const store = useStoreContext(HUE_SLIDER_NAME);
639
+ const hsv = useStore((state) => state.hsv);
640
+ const onValueChange = react.useCallback((values) => {
641
+ const newHsv = {
642
+ h: values[0] ?? 0,
643
+ s: hsv?.s ?? 0,
644
+ v: hsv?.v ?? 0,
645
+ a: hsv?.a ?? 1
646
+ };
647
+ store.setHsv(newHsv);
648
+ store.setColor(hsvToRgb(newHsv));
649
+ }, [hsv, store]);
650
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__radix_ui_react_slider.Root, {
651
+ "data-slot": "color-picker-hue-slider",
652
+ ...sliderProps,
653
+ max: 360,
654
+ step: 1,
655
+ className: require_utils.cn("relative flex w-full touch-none select-none items-center", className),
656
+ value: [hsv?.h ?? 0],
657
+ onValueChange,
658
+ disabled: context.disabled,
659
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__radix_ui_react_slider.Track, {
660
+ className: "relative h-3 w-full grow overflow-hidden rounded-full bg-[linear-gradient(to_right,#ff0000_0%,#ffff00_16.66%,#00ff00_33.33%,#00ffff_50%,#0000ff_66.66%,#ff00ff_83.33%,#ff0000_100%)]",
661
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__radix_ui_react_slider.Range, { className: "absolute h-full" })
662
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__radix_ui_react_slider.Thumb, { className: "block size-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" })]
663
+ });
664
+ }
665
+ function ColorPickerAlphaSlider(props) {
666
+ const { className,...sliderProps } = props;
667
+ const context = useColorPickerContext(ALPHA_SLIDER_NAME);
668
+ const store = useStoreContext(ALPHA_SLIDER_NAME);
669
+ const color = useStore((state) => state.color);
670
+ const hsv = useStore((state) => state.hsv);
671
+ const onValueChange = react.useCallback((values) => {
672
+ const alpha = (values[0] ?? 0) / 100;
673
+ const newColor = {
674
+ ...color,
675
+ a: alpha
676
+ };
677
+ const newHsv = {
678
+ ...hsv,
679
+ a: alpha
680
+ };
681
+ store.setColor(newColor);
682
+ store.setHsv(newHsv);
683
+ }, [
684
+ color,
685
+ hsv,
686
+ store
687
+ ]);
688
+ const gradientColor = `rgb(${color?.r ?? 0}, ${color?.g ?? 0}, ${color?.b ?? 0})`;
689
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__radix_ui_react_slider.Root, {
690
+ "data-slot": "color-picker-alpha-slider",
691
+ ...sliderProps,
692
+ max: 100,
693
+ step: 1,
694
+ disabled: context.disabled,
695
+ className: require_utils.cn("relative flex w-full touch-none select-none items-center", className),
696
+ value: [Math.round((color?.a ?? 1) * 100)],
697
+ onValueChange,
698
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__radix_ui_react_slider.Track, {
699
+ className: "relative h-3 w-full grow overflow-hidden rounded-full",
700
+ style: {
701
+ background: "linear-gradient(45deg, #ccc 25%, transparent 25%), linear-gradient(-45deg, #ccc 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #ccc 75%), linear-gradient(-45deg, transparent 75%, #ccc 75%)",
702
+ backgroundSize: "8px 8px",
703
+ backgroundPosition: "0 0, 0 4px, 4px -4px, -4px 0px"
704
+ },
705
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
706
+ className: "absolute inset-0 rounded-full",
707
+ style: { background: `linear-gradient(to right, transparent, ${gradientColor})` }
708
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__radix_ui_react_slider.Range, { className: "absolute h-full" })]
709
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__radix_ui_react_slider.Thumb, { className: "block size-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" })]
710
+ });
711
+ }
712
+ function ColorPickerSwatch(props) {
713
+ const { asChild, className,...swatchProps } = props;
714
+ const context = useColorPickerContext(SWATCH_NAME);
715
+ const color = useStore((state) => state.color);
716
+ const format = useStore((state) => state.format);
717
+ const backgroundStyle = react.useMemo(() => {
718
+ if (!color) return { background: "linear-gradient(to bottom right, transparent calc(50% - 1px), hsl(var(--destructive)) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) no-repeat" };
719
+ const colorString = `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`;
720
+ if (color.a < 1) return { background: `linear-gradient(${colorString}, ${colorString}), repeating-conic-gradient(#ccc 0% 25%, #fff 0% 50%) 0% 50% / 8px 8px` };
721
+ return { backgroundColor: colorString };
722
+ }, [color]);
723
+ const ariaLabel = !color ? "No color selected" : `Current color: ${colorToString(color, format)}`;
724
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(asChild ? __radix_ui_react_slot.Slot : "div", {
725
+ role: "img",
726
+ "aria-label": ariaLabel,
727
+ "data-slot": "color-picker-swatch",
728
+ ...swatchProps,
729
+ className: require_utils.cn("box-border size-8 rounded-sm border shadow-sm", context.disabled && "opacity-50", className),
730
+ style: {
731
+ ...backgroundStyle,
732
+ forcedColorAdjust: "none"
733
+ }
734
+ });
735
+ }
736
+ function ColorPickerEyeDropper(props) {
737
+ const { size: sizeProp, children, disabled,...buttonProps } = props;
738
+ const context = useColorPickerContext(EYE_DROPPER_NAME);
739
+ const store = useStoreContext(EYE_DROPPER_NAME);
740
+ const color = useStore((state) => state.color);
741
+ const isDisabled = disabled || context.disabled;
742
+ const onEyeDropper = react.useCallback(async () => {
743
+ if (!window.EyeDropper) return;
744
+ try {
745
+ const result = await new window.EyeDropper().open();
746
+ if (result.sRGBHex) {
747
+ const currentAlpha = color?.a ?? 1;
748
+ const newColor = hexToRgb(result.sRGBHex, currentAlpha);
749
+ const newHsv = rgbToHsv(newColor);
750
+ store.setColor(newColor);
751
+ store.setHsv(newHsv);
752
+ }
753
+ } catch (error) {
754
+ console.warn("EyeDropper error:", error);
755
+ }
756
+ }, [color, store]);
757
+ if (!(typeof window !== "undefined" && Boolean(window.EyeDropper))) return null;
758
+ const size = sizeProp ?? (children ? "default" : "icon");
759
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_button.Button, {
760
+ "data-slot": "color-picker-eye-dropper",
761
+ ...buttonProps,
762
+ variant: "outline",
763
+ size,
764
+ onClick: onEyeDropper,
765
+ disabled: isDisabled,
766
+ children: children ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.PipetteIcon, {})
767
+ });
768
+ }
769
+ function ColorPickerFormatSelect(props) {
770
+ const { size, disabled, className,...selectProps } = props;
771
+ const context = useColorPickerContext(FORMAT_SELECT_NAME);
772
+ const store = useStoreContext(FORMAT_SELECT_NAME);
773
+ const isDisabled = disabled || context.disabled;
774
+ const format = useStore((state) => state.format);
775
+ const onFormatChange = react.useCallback((value) => {
776
+ store.setFormat(value);
777
+ }, [store]);
778
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_select.Select, {
779
+ "data-slot": "color-picker-format-select",
780
+ ...selectProps,
781
+ value: format,
782
+ onValueChange: onFormatChange,
783
+ disabled: isDisabled,
784
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_select.SelectTrigger, {
785
+ "data-slot": "color-picker-format-select-trigger",
786
+ size: size ?? "sm",
787
+ className: require_utils.cn(className),
788
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_select.SelectValue, {})
789
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_select.SelectContent, { children: colorFormats.map((format$1) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_select.SelectItem, {
790
+ value: format$1,
791
+ children: format$1.toUpperCase()
792
+ }, format$1)) })]
793
+ });
794
+ }
795
+ function ColorPickerInput(props) {
796
+ const store = useStoreContext(INPUT_NAME);
797
+ const context = useColorPickerContext(INPUT_NAME);
798
+ const color = useStore((state) => state.color);
799
+ const format = useStore((state) => state.format);
800
+ const hsv = useStore((state) => state.hsv);
801
+ const onColorChange = react.useCallback((newColor) => {
802
+ const newHsv = rgbToHsv(newColor);
803
+ store.setColor(newColor);
804
+ store.setHsv(newHsv);
805
+ }, [store]);
806
+ if (format === "hex") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HexInput, {
807
+ color,
808
+ onColorChange,
809
+ context,
810
+ ...props
811
+ });
812
+ if (format === "rgb") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RgbInput, {
813
+ color,
814
+ onColorChange,
815
+ context,
816
+ ...props
817
+ });
818
+ if (format === "hsl") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HslInput, {
819
+ color,
820
+ onColorChange,
821
+ context,
822
+ ...props
823
+ });
824
+ if (format === "hsb") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HsbInput, {
825
+ hsv,
826
+ onColorChange,
827
+ context,
828
+ ...props
829
+ });
830
+ }
831
+ const inputGroupItemVariants = (0, class_variance_authority.cva)("h-8 [-moz-appearance:textfield] focus-visible:z-10 focus-visible:ring-1 [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:appearance-none", {
832
+ variants: { position: {
833
+ first: "rounded-e-none",
834
+ middle: "-ms-px rounded-none border-l-0",
835
+ last: "-ms-px rounded-s-none border-l-0",
836
+ isolated: ""
837
+ } },
838
+ defaultVariants: { position: "isolated" }
839
+ });
840
+ function InputGroupItem({ className, position,...props }) {
841
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_input.Input, {
842
+ "data-slot": "color-picker-input",
843
+ className: require_utils.cn(inputGroupItemVariants({
844
+ position,
845
+ className
846
+ })),
847
+ ...props
848
+ });
849
+ }
850
+ function HexInput(props) {
851
+ const { color, onColorChange, context, withoutAlpha, className,...inputProps } = props;
852
+ const hexValue = rgbToHex(color);
853
+ const alphaValue = Math.round((color?.a ?? 1) * 100);
854
+ const onHexChange = react.useCallback((event) => {
855
+ const { value } = event.target;
856
+ const parsedColor = parseColorString(value);
857
+ if (parsedColor) {
858
+ const trimmed = value.trim().toLowerCase();
859
+ onColorChange(trimmed.startsWith("#") && (trimmed.length === 4 || trimmed.length === 7) ? {
860
+ ...parsedColor,
861
+ a: color?.a ?? 1
862
+ } : parsedColor);
863
+ }
864
+ }, [color, onColorChange]);
865
+ const onAlphaChange = react.useCallback((event) => {
866
+ const value = Number.parseInt(event.target.value, 10);
867
+ if (!Number.isNaN(value) && value >= 0 && value <= 100) onColorChange({
868
+ ...color,
869
+ a: value / 100
870
+ });
871
+ }, [color, onColorChange]);
872
+ if (withoutAlpha) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InputGroupItem, {
873
+ "aria-label": "Hex color value",
874
+ position: "isolated",
875
+ ...inputProps,
876
+ placeholder: "#000000",
877
+ className: require_utils.cn("font-mono", className),
878
+ value: hexValue,
879
+ onChange: onHexChange,
880
+ disabled: context.disabled
881
+ });
882
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
883
+ "data-slot": "color-picker-input-wrapper",
884
+ className: require_utils.cn("flex items-center", className),
885
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(InputGroupItem, {
886
+ "aria-label": "Hex color value",
887
+ position: "first",
888
+ ...inputProps,
889
+ placeholder: "#000000",
890
+ className: "flex-1 font-mono",
891
+ value: hexValue,
892
+ onChange: onHexChange,
893
+ disabled: context.disabled
894
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InputGroupItem, {
895
+ "aria-label": "Alpha transparency percentage",
896
+ position: "last",
897
+ ...inputProps,
898
+ placeholder: "100",
899
+ inputMode: "numeric",
900
+ pattern: "[0-9]*",
901
+ min: "0",
902
+ max: "100",
903
+ className: "w-14",
904
+ value: alphaValue,
905
+ onChange: onAlphaChange,
906
+ disabled: context.disabled
907
+ })]
908
+ });
909
+ }
910
+ function RgbInput(props) {
911
+ const { color, onColorChange, context, withoutAlpha, className,...inputProps } = props;
912
+ const rValue = Math.round(color?.r ?? 0);
913
+ const gValue = Math.round(color?.g ?? 0);
914
+ const bValue = Math.round(color?.b ?? 0);
915
+ const alphaValue = Math.round((color?.a ?? 1) * 100);
916
+ const onChannelChange = react.useCallback((channel, max, isAlpha = false) => (event) => {
917
+ const value = Number.parseInt(event.target.value, 10);
918
+ if (!Number.isNaN(value) && value >= 0 && value <= max) {
919
+ const newValue = isAlpha ? value / 100 : value;
920
+ onColorChange({
921
+ ...color,
922
+ [channel]: newValue
923
+ });
924
+ }
925
+ }, [color, onColorChange]);
926
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
927
+ "data-slot": "color-picker-input-wrapper",
928
+ className: require_utils.cn("flex items-center", className),
929
+ children: [
930
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InputGroupItem, {
931
+ "aria-label": "Red color component (0-255)",
932
+ position: "first",
933
+ ...inputProps,
934
+ placeholder: "0",
935
+ inputMode: "numeric",
936
+ pattern: "[0-9]*",
937
+ min: "0",
938
+ max: "255",
939
+ className: "w-14",
940
+ value: rValue,
941
+ onChange: onChannelChange("r", 255),
942
+ disabled: context.disabled
943
+ }),
944
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InputGroupItem, {
945
+ "aria-label": "Green color component (0-255)",
946
+ position: "middle",
947
+ ...inputProps,
948
+ placeholder: "0",
949
+ inputMode: "numeric",
950
+ pattern: "[0-9]*",
951
+ min: "0",
952
+ max: "255",
953
+ className: "w-14",
954
+ value: gValue,
955
+ onChange: onChannelChange("g", 255),
956
+ disabled: context.disabled
957
+ }),
958
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InputGroupItem, {
959
+ "aria-label": "Blue color component (0-255)",
960
+ position: withoutAlpha ? "last" : "middle",
961
+ ...inputProps,
962
+ placeholder: "0",
963
+ inputMode: "numeric",
964
+ pattern: "[0-9]*",
965
+ min: "0",
966
+ max: "255",
967
+ className: "w-14",
968
+ value: bValue,
969
+ onChange: onChannelChange("b", 255),
970
+ disabled: context.disabled
971
+ }),
972
+ !withoutAlpha && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InputGroupItem, {
973
+ "aria-label": "Alpha transparency percentage",
974
+ position: "last",
975
+ ...inputProps,
976
+ placeholder: "100",
977
+ inputMode: "numeric",
978
+ pattern: "[0-9]*",
979
+ min: "0",
980
+ max: "100",
981
+ className: "w-14",
982
+ value: alphaValue,
983
+ onChange: onChannelChange("a", 100, true),
984
+ disabled: context.disabled
985
+ })
986
+ ]
987
+ });
988
+ }
989
+ function HslInput(props) {
990
+ const { color, onColorChange, context, withoutAlpha, className,...inputProps } = props;
991
+ const hsl = react.useMemo(() => rgbToHsl(color), [color]);
992
+ const alphaValue = Math.round((color?.a ?? 1) * 100);
993
+ const onHslChannelChange = react.useCallback((channel, max) => (event) => {
994
+ const value = Number.parseInt(event.target.value, 10);
995
+ if (!Number.isNaN(value) && value >= 0 && value <= max) onColorChange(hslToRgb({
996
+ ...hsl,
997
+ [channel]: value
998
+ }, color?.a ?? 1));
999
+ }, [
1000
+ hsl,
1001
+ color,
1002
+ onColorChange
1003
+ ]);
1004
+ const onAlphaChange = react.useCallback((event) => {
1005
+ const value = Number.parseInt(event.target.value, 10);
1006
+ if (!Number.isNaN(value) && value >= 0 && value <= 100) onColorChange({
1007
+ ...color,
1008
+ a: value / 100
1009
+ });
1010
+ }, [color, onColorChange]);
1011
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1012
+ "data-slot": "color-picker-input-wrapper",
1013
+ className: require_utils.cn("flex items-center", className),
1014
+ children: [
1015
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InputGroupItem, {
1016
+ "aria-label": "Hue degree (0-360)",
1017
+ position: "first",
1018
+ ...inputProps,
1019
+ placeholder: "0",
1020
+ inputMode: "numeric",
1021
+ pattern: "[0-9]*",
1022
+ min: "0",
1023
+ max: "360",
1024
+ className: "w-14",
1025
+ value: hsl.h,
1026
+ onChange: onHslChannelChange("h", 360),
1027
+ disabled: context.disabled
1028
+ }),
1029
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InputGroupItem, {
1030
+ "aria-label": "Saturation percentage (0-100)",
1031
+ position: "middle",
1032
+ ...inputProps,
1033
+ placeholder: "0",
1034
+ inputMode: "numeric",
1035
+ pattern: "[0-9]*",
1036
+ min: "0",
1037
+ max: "100",
1038
+ className: "w-14",
1039
+ value: hsl.s,
1040
+ onChange: onHslChannelChange("s", 100),
1041
+ disabled: context.disabled
1042
+ }),
1043
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InputGroupItem, {
1044
+ "aria-label": "Lightness percentage (0-100)",
1045
+ position: withoutAlpha ? "last" : "middle",
1046
+ ...inputProps,
1047
+ placeholder: "0",
1048
+ inputMode: "numeric",
1049
+ pattern: "[0-9]*",
1050
+ min: "0",
1051
+ max: "100",
1052
+ className: "w-14",
1053
+ value: hsl.l,
1054
+ onChange: onHslChannelChange("l", 100),
1055
+ disabled: context.disabled
1056
+ }),
1057
+ !withoutAlpha && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InputGroupItem, {
1058
+ "aria-label": "Alpha transparency percentage",
1059
+ position: "last",
1060
+ ...inputProps,
1061
+ placeholder: "100",
1062
+ inputMode: "numeric",
1063
+ pattern: "[0-9]*",
1064
+ min: "0",
1065
+ max: "100",
1066
+ className: "w-14",
1067
+ value: alphaValue,
1068
+ onChange: onAlphaChange,
1069
+ disabled: context.disabled
1070
+ })
1071
+ ]
1072
+ });
1073
+ }
1074
+ function HsbInput(props) {
1075
+ const { hsv, onColorChange, context, withoutAlpha, className,...inputProps } = props;
1076
+ const alphaValue = Math.round((hsv?.a ?? 1) * 100);
1077
+ const onHsvChannelChange = react.useCallback((channel, max) => (event) => {
1078
+ const value = Number.parseInt(event.target.value, 10);
1079
+ if (!Number.isNaN(value) && value >= 0 && value <= max) onColorChange(hsvToRgb({
1080
+ ...hsv,
1081
+ [channel]: value
1082
+ }));
1083
+ }, [hsv, onColorChange]);
1084
+ const onAlphaChange = react.useCallback((event) => {
1085
+ const value = Number.parseInt(event.target.value, 10);
1086
+ if (!Number.isNaN(value) && value >= 0 && value <= 100) onColorChange({
1087
+ ...hsvToRgb(hsv),
1088
+ a: value / 100
1089
+ });
1090
+ }, [hsv, onColorChange]);
1091
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1092
+ "data-slot": "color-picker-input-wrapper",
1093
+ className: require_utils.cn("flex items-center", className),
1094
+ children: [
1095
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InputGroupItem, {
1096
+ "aria-label": "Hue degree (0-360)",
1097
+ position: "first",
1098
+ ...inputProps,
1099
+ placeholder: "0",
1100
+ inputMode: "numeric",
1101
+ pattern: "[0-9]*",
1102
+ min: "0",
1103
+ max: "360",
1104
+ className: "w-14",
1105
+ value: hsv?.h ?? 0,
1106
+ onChange: onHsvChannelChange("h", 360),
1107
+ disabled: context.disabled
1108
+ }),
1109
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InputGroupItem, {
1110
+ "aria-label": "Saturation percentage (0-100)",
1111
+ position: "middle",
1112
+ ...inputProps,
1113
+ placeholder: "0",
1114
+ inputMode: "numeric",
1115
+ pattern: "[0-9]*",
1116
+ min: "0",
1117
+ max: "100",
1118
+ className: "w-14",
1119
+ value: hsv?.s ?? 0,
1120
+ onChange: onHsvChannelChange("s", 100),
1121
+ disabled: context.disabled
1122
+ }),
1123
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InputGroupItem, {
1124
+ "aria-label": "Brightness percentage (0-100)",
1125
+ position: withoutAlpha ? "last" : "middle",
1126
+ ...inputProps,
1127
+ placeholder: "0",
1128
+ inputMode: "numeric",
1129
+ pattern: "[0-9]*",
1130
+ min: "0",
1131
+ max: "100",
1132
+ className: "w-14",
1133
+ value: hsv?.v ?? 0,
1134
+ onChange: onHsvChannelChange("v", 100),
1135
+ disabled: context.disabled
1136
+ }),
1137
+ !withoutAlpha && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InputGroupItem, {
1138
+ "aria-label": "Alpha transparency percentage",
1139
+ position: "last",
1140
+ ...inputProps,
1141
+ placeholder: "100",
1142
+ inputMode: "numeric",
1143
+ pattern: "[0-9]*",
1144
+ min: "0",
1145
+ max: "100",
1146
+ className: "w-14",
1147
+ value: alphaValue,
1148
+ onChange: onAlphaChange,
1149
+ disabled: context.disabled
1150
+ })
1151
+ ]
1152
+ });
1153
+ }
1154
+ const colorUtils = {
1155
+ colorToString,
1156
+ parseColorString
1157
+ };
1158
+
1159
+ //#endregion
1160
+ exports.ColorPicker = ColorPicker;
1161
+ exports.ColorPickerAlphaSlider = ColorPickerAlphaSlider;
1162
+ exports.ColorPickerArea = ColorPickerArea;
1163
+ exports.ColorPickerContent = ColorPickerContent;
1164
+ exports.ColorPickerEyeDropper = ColorPickerEyeDropper;
1165
+ exports.ColorPickerFormatSelect = ColorPickerFormatSelect;
1166
+ exports.ColorPickerHueSlider = ColorPickerHueSlider;
1167
+ exports.ColorPickerInput = ColorPickerInput;
1168
+ exports.ColorPickerSwatch = ColorPickerSwatch;
1169
+ exports.ColorPickerTrigger = ColorPickerTrigger;
1170
+ exports.colorUtils = colorUtils;
1171
+ exports.useStore = useStore;