@zag-js/color-picker 1.34.1 → 1.35.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 (49) hide show
  1. package/dist/color-picker.anatomy.d.mts +6 -0
  2. package/dist/color-picker.anatomy.d.ts +6 -0
  3. package/dist/color-picker.anatomy.js +59 -0
  4. package/dist/color-picker.anatomy.mjs +33 -0
  5. package/dist/color-picker.connect.d.mts +10 -0
  6. package/dist/color-picker.connect.d.ts +10 -0
  7. package/dist/color-picker.connect.js +681 -0
  8. package/dist/color-picker.connect.mjs +646 -0
  9. package/dist/color-picker.dom.d.mts +39 -0
  10. package/dist/color-picker.dom.d.ts +39 -0
  11. package/dist/color-picker.dom.js +136 -0
  12. package/dist/color-picker.dom.mjs +85 -0
  13. package/dist/color-picker.machine.d.mts +10 -0
  14. package/dist/color-picker.machine.d.ts +10 -0
  15. package/dist/color-picker.machine.js +636 -0
  16. package/dist/color-picker.machine.mjs +609 -0
  17. package/dist/color-picker.parse.d.mts +5 -0
  18. package/dist/color-picker.parse.d.ts +5 -0
  19. package/dist/color-picker.parse.js +33 -0
  20. package/dist/color-picker.parse.mjs +8 -0
  21. package/dist/color-picker.props.d.mts +21 -0
  22. package/dist/color-picker.props.d.ts +21 -0
  23. package/dist/color-picker.props.js +94 -0
  24. package/dist/color-picker.props.mjs +58 -0
  25. package/dist/color-picker.types.d.mts +303 -0
  26. package/dist/color-picker.types.d.ts +303 -0
  27. package/dist/color-picker.types.js +18 -0
  28. package/dist/color-picker.types.mjs +0 -0
  29. package/dist/index.d.mts +9 -324
  30. package/dist/index.d.ts +9 -324
  31. package/dist/index.js +37 -1517
  32. package/dist/index.mjs +11 -1504
  33. package/dist/utils/get-channel-display-color.d.mts +5 -0
  34. package/dist/utils/get-channel-display-color.d.ts +5 -0
  35. package/dist/utils/get-channel-display-color.js +48 -0
  36. package/dist/utils/get-channel-display-color.mjs +23 -0
  37. package/dist/utils/get-channel-input-value.d.mts +11 -0
  38. package/dist/utils/get-channel-input-value.d.ts +11 -0
  39. package/dist/utils/get-channel-input-value.js +88 -0
  40. package/dist/utils/get-channel-input-value.mjs +62 -0
  41. package/dist/utils/get-slider-background.d.mts +14 -0
  42. package/dist/utils/get-slider-background.d.ts +14 -0
  43. package/dist/utils/get-slider-background.js +65 -0
  44. package/dist/utils/get-slider-background.mjs +40 -0
  45. package/dist/utils/is-valid-hex.d.mts +4 -0
  46. package/dist/utils/is-valid-hex.d.ts +4 -0
  47. package/dist/utils/is-valid-hex.js +40 -0
  48. package/dist/utils/is-valid-hex.mjs +14 -0
  49. package/package.json +20 -10
@@ -0,0 +1,609 @@
1
+ // src/color-picker.machine.ts
2
+ import { parseColor } from "@zag-js/color-utils";
3
+ import { createGuards, createMachine } from "@zag-js/core";
4
+ import { trackDismissableElement } from "@zag-js/dismissable";
5
+ import {
6
+ disableTextSelection,
7
+ dispatchInputValueEvent,
8
+ getInitialFocus,
9
+ raf,
10
+ setElementValue,
11
+ trackFormControl,
12
+ trackPointerMove
13
+ } from "@zag-js/dom-query";
14
+ import { getPlacement } from "@zag-js/popper";
15
+ import { tryCatch } from "@zag-js/utils";
16
+ import * as dom from "./color-picker.dom.mjs";
17
+ import { parse } from "./color-picker.parse.mjs";
18
+ import { getChannelValue } from "./utils/get-channel-input-value.mjs";
19
+ import { prefixHex } from "./utils/is-valid-hex.mjs";
20
+ var { and } = createGuards();
21
+ var hashObject = (obj) => {
22
+ let hash = "";
23
+ for (const key in obj) hash += `${key}:${obj[key] ?? ""};`;
24
+ return hash;
25
+ };
26
+ var DEFAULT_COLOR = parse("#000000");
27
+ var machine = createMachine({
28
+ props({ props }) {
29
+ const color = props.value ?? props.defaultValue ?? DEFAULT_COLOR;
30
+ return {
31
+ dir: "ltr",
32
+ defaultValue: DEFAULT_COLOR,
33
+ defaultFormat: color.getFormat(),
34
+ openAutoFocus: true,
35
+ ...props,
36
+ positioning: {
37
+ placement: "bottom",
38
+ ...props.positioning
39
+ }
40
+ };
41
+ },
42
+ initialState({ prop }) {
43
+ const open = prop("open") || prop("defaultOpen") || prop("inline");
44
+ return open ? "open" : "idle";
45
+ },
46
+ context({ prop, bindable, getContext }) {
47
+ return {
48
+ value: bindable(() => ({
49
+ defaultValue: prop("defaultValue"),
50
+ value: prop("value"),
51
+ isEqual(a, b) {
52
+ return b != null && a.isEqual(b);
53
+ },
54
+ hash(a) {
55
+ return hashObject(a.toJSON());
56
+ },
57
+ onChange(value) {
58
+ const ctx = getContext();
59
+ const format = ctx.get("format");
60
+ prop("onValueChange")?.({ value, valueAsString: value.toString(format) });
61
+ }
62
+ })),
63
+ format: bindable(() => ({
64
+ defaultValue: prop("defaultFormat"),
65
+ value: prop("format"),
66
+ onChange(format) {
67
+ prop("onFormatChange")?.({ format });
68
+ }
69
+ })),
70
+ activeId: bindable(() => ({ defaultValue: null })),
71
+ activeChannel: bindable(() => ({ defaultValue: null })),
72
+ activeOrientation: bindable(() => ({ defaultValue: null })),
73
+ fieldsetDisabled: bindable(() => ({ defaultValue: false })),
74
+ restoreFocus: bindable(() => ({ defaultValue: true })),
75
+ currentPlacement: bindable(() => ({
76
+ defaultValue: void 0
77
+ }))
78
+ };
79
+ },
80
+ computed: {
81
+ rtl: ({ prop }) => prop("dir") === "rtl",
82
+ disabled: ({ prop, context }) => !!prop("disabled") || context.get("fieldsetDisabled"),
83
+ interactive: ({ prop }) => !(prop("disabled") || prop("readOnly")),
84
+ valueAsString: ({ context }) => context.get("value").toString(context.get("format")),
85
+ areaValue: ({ context }) => {
86
+ const format = context.get("format").startsWith("hsl") ? "hsla" : "hsba";
87
+ return context.get("value").toFormat(format);
88
+ }
89
+ },
90
+ effects: ["trackFormControl"],
91
+ watch({ prop, context, action, track }) {
92
+ track([() => context.hash("value")], () => {
93
+ action(["syncInputElements", "dispatchChangeEvent"]);
94
+ });
95
+ track([() => context.get("format")], () => {
96
+ action(["syncFormatSelectElement", "syncValueWithFormat"]);
97
+ });
98
+ track([() => prop("open")], () => {
99
+ action(["toggleVisibility"]);
100
+ });
101
+ },
102
+ on: {
103
+ "VALUE.SET": {
104
+ actions: ["setValue"]
105
+ },
106
+ "FORMAT.SET": {
107
+ actions: ["setFormat"]
108
+ },
109
+ "CHANNEL_INPUT.CHANGE": {
110
+ actions: ["setChannelColorFromInput"]
111
+ },
112
+ "EYEDROPPER.CLICK": {
113
+ actions: ["openEyeDropper"]
114
+ },
115
+ "SWATCH_TRIGGER.CLICK": {
116
+ actions: ["setValue"]
117
+ }
118
+ },
119
+ states: {
120
+ idle: {
121
+ tags: ["closed"],
122
+ on: {
123
+ "CONTROLLED.OPEN": {
124
+ target: "open",
125
+ actions: ["setInitialFocus"]
126
+ },
127
+ OPEN: [
128
+ {
129
+ guard: "isOpenControlled",
130
+ actions: ["invokeOnOpen"]
131
+ },
132
+ {
133
+ target: "open",
134
+ actions: ["invokeOnOpen", "setInitialFocus"]
135
+ }
136
+ ],
137
+ "TRIGGER.CLICK": [
138
+ {
139
+ guard: "isOpenControlled",
140
+ actions: ["invokeOnOpen"]
141
+ },
142
+ {
143
+ target: "open",
144
+ actions: ["invokeOnOpen", "setInitialFocus"]
145
+ }
146
+ ],
147
+ "CHANNEL_INPUT.FOCUS": {
148
+ target: "focused",
149
+ actions: ["setActiveChannel"]
150
+ }
151
+ }
152
+ },
153
+ focused: {
154
+ tags: ["closed", "focused"],
155
+ on: {
156
+ "CONTROLLED.OPEN": {
157
+ target: "open",
158
+ actions: ["setInitialFocus"]
159
+ },
160
+ OPEN: [
161
+ {
162
+ guard: "isOpenControlled",
163
+ actions: ["invokeOnOpen"]
164
+ },
165
+ {
166
+ target: "open",
167
+ actions: ["invokeOnOpen", "setInitialFocus"]
168
+ }
169
+ ],
170
+ "TRIGGER.CLICK": [
171
+ {
172
+ guard: "isOpenControlled",
173
+ actions: ["invokeOnOpen"]
174
+ },
175
+ {
176
+ target: "open",
177
+ actions: ["invokeOnOpen", "setInitialFocus"]
178
+ }
179
+ ],
180
+ "CHANNEL_INPUT.FOCUS": {
181
+ actions: ["setActiveChannel"]
182
+ },
183
+ "CHANNEL_INPUT.BLUR": {
184
+ target: "idle",
185
+ actions: ["setChannelColorFromInput"]
186
+ },
187
+ "TRIGGER.BLUR": {
188
+ target: "idle"
189
+ }
190
+ }
191
+ },
192
+ open: {
193
+ tags: ["open"],
194
+ effects: ["trackPositioning", "trackDismissableElement"],
195
+ initial: "idle",
196
+ on: {
197
+ "CONTROLLED.CLOSE": [
198
+ {
199
+ guard: "shouldRestoreFocus",
200
+ target: "focused",
201
+ actions: ["setReturnFocus"]
202
+ },
203
+ {
204
+ target: "idle"
205
+ }
206
+ ],
207
+ INTERACT_OUTSIDE: [
208
+ {
209
+ guard: "isOpenControlled",
210
+ actions: ["invokeOnClose"]
211
+ },
212
+ {
213
+ guard: "shouldRestoreFocus",
214
+ target: "focused",
215
+ actions: ["invokeOnClose", "setReturnFocus"]
216
+ },
217
+ {
218
+ target: "idle",
219
+ actions: ["invokeOnClose"]
220
+ }
221
+ ],
222
+ CLOSE: [
223
+ {
224
+ guard: "isOpenControlled",
225
+ actions: ["invokeOnClose"]
226
+ },
227
+ {
228
+ target: "idle",
229
+ actions: ["invokeOnClose"]
230
+ }
231
+ ]
232
+ },
233
+ states: {
234
+ idle: {
235
+ on: {
236
+ "TRIGGER.CLICK": [
237
+ {
238
+ guard: "isOpenControlled",
239
+ actions: ["invokeOnClose"]
240
+ },
241
+ {
242
+ target: "idle",
243
+ actions: ["invokeOnClose"]
244
+ }
245
+ ],
246
+ "AREA.POINTER_DOWN": {
247
+ target: "dragging",
248
+ actions: ["setActiveChannel", "setAreaColorFromPoint", "focusAreaThumb"]
249
+ },
250
+ "AREA.FOCUS": {
251
+ actions: ["setActiveChannel"]
252
+ },
253
+ "CHANNEL_SLIDER.POINTER_DOWN": {
254
+ target: "dragging",
255
+ actions: ["setActiveChannel", "setChannelColorFromPoint", "focusChannelThumb"]
256
+ },
257
+ "CHANNEL_SLIDER.FOCUS": {
258
+ actions: ["setActiveChannel"]
259
+ },
260
+ "AREA.ARROW_LEFT": {
261
+ actions: ["decrementAreaXChannel"]
262
+ },
263
+ "AREA.ARROW_RIGHT": {
264
+ actions: ["incrementAreaXChannel"]
265
+ },
266
+ "AREA.ARROW_UP": {
267
+ actions: ["incrementAreaYChannel"]
268
+ },
269
+ "AREA.ARROW_DOWN": {
270
+ actions: ["decrementAreaYChannel"]
271
+ },
272
+ "AREA.PAGE_UP": {
273
+ actions: ["incrementAreaXChannel"]
274
+ },
275
+ "AREA.PAGE_DOWN": {
276
+ actions: ["decrementAreaXChannel"]
277
+ },
278
+ "CHANNEL_SLIDER.ARROW_LEFT": {
279
+ actions: ["decrementChannel"]
280
+ },
281
+ "CHANNEL_SLIDER.ARROW_RIGHT": {
282
+ actions: ["incrementChannel"]
283
+ },
284
+ "CHANNEL_SLIDER.ARROW_UP": {
285
+ actions: ["incrementChannel"]
286
+ },
287
+ "CHANNEL_SLIDER.ARROW_DOWN": {
288
+ actions: ["decrementChannel"]
289
+ },
290
+ "CHANNEL_SLIDER.PAGE_UP": {
291
+ actions: ["incrementChannel"]
292
+ },
293
+ "CHANNEL_SLIDER.PAGE_DOWN": {
294
+ actions: ["decrementChannel"]
295
+ },
296
+ "CHANNEL_SLIDER.HOME": {
297
+ actions: ["setChannelToMin"]
298
+ },
299
+ "CHANNEL_SLIDER.END": {
300
+ actions: ["setChannelToMax"]
301
+ },
302
+ "CHANNEL_INPUT.BLUR": {
303
+ actions: ["setChannelColorFromInput"]
304
+ },
305
+ "SWATCH_TRIGGER.CLICK": [
306
+ {
307
+ guard: and("isOpenControlled", "closeOnSelect"),
308
+ actions: ["setValue", "invokeOnClose"]
309
+ },
310
+ {
311
+ guard: "closeOnSelect",
312
+ target: "focused",
313
+ actions: ["setValue", "invokeOnClose", "setReturnFocus"]
314
+ },
315
+ {
316
+ actions: ["setValue"]
317
+ }
318
+ ]
319
+ }
320
+ },
321
+ dragging: {
322
+ tags: ["dragging"],
323
+ exit: ["clearActiveChannel"],
324
+ effects: ["trackPointerMove", "disableTextSelection"],
325
+ on: {
326
+ "AREA.POINTER_MOVE": {
327
+ actions: ["setAreaColorFromPoint", "focusAreaThumb"]
328
+ },
329
+ "AREA.POINTER_UP": {
330
+ target: "idle",
331
+ actions: ["invokeOnChangeEnd"]
332
+ },
333
+ "CHANNEL_SLIDER.POINTER_MOVE": {
334
+ actions: ["setChannelColorFromPoint", "focusChannelThumb"]
335
+ },
336
+ "CHANNEL_SLIDER.POINTER_UP": {
337
+ target: "idle",
338
+ actions: ["invokeOnChangeEnd"]
339
+ }
340
+ }
341
+ }
342
+ }
343
+ }
344
+ },
345
+ implementations: {
346
+ guards: {
347
+ closeOnSelect: ({ prop }) => !!prop("closeOnSelect"),
348
+ isOpenControlled: ({ prop }) => prop("open") != null || !!prop("inline"),
349
+ shouldRestoreFocus: ({ context }) => !!context.get("restoreFocus")
350
+ },
351
+ effects: {
352
+ trackPositioning({ context, prop, scope }) {
353
+ if (prop("inline")) return;
354
+ if (!context.get("currentPlacement")) {
355
+ context.set("currentPlacement", prop("positioning")?.placement);
356
+ }
357
+ const anchorEl = dom.getTriggerEl(scope);
358
+ const getPositionerEl2 = () => dom.getPositionerEl(scope);
359
+ return getPlacement(anchorEl, getPositionerEl2, {
360
+ ...prop("positioning"),
361
+ defer: true,
362
+ onComplete(data) {
363
+ context.set("currentPlacement", data.placement);
364
+ }
365
+ });
366
+ },
367
+ trackDismissableElement({ context, scope, prop, send }) {
368
+ if (prop("inline")) return;
369
+ const getContentEl2 = () => dom.getContentEl(scope);
370
+ return trackDismissableElement(getContentEl2, {
371
+ type: "popover",
372
+ exclude: dom.getTriggerEl(scope),
373
+ defer: true,
374
+ onInteractOutside(event) {
375
+ prop("onInteractOutside")?.(event);
376
+ if (event.defaultPrevented) return;
377
+ context.set("restoreFocus", !(event.detail.focusable || event.detail.contextmenu));
378
+ },
379
+ onPointerDownOutside: prop("onPointerDownOutside"),
380
+ onFocusOutside: prop("onFocusOutside"),
381
+ onDismiss() {
382
+ send({ type: "INTERACT_OUTSIDE" });
383
+ }
384
+ });
385
+ },
386
+ trackFormControl({ context, scope, send }) {
387
+ const inputEl = dom.getHiddenInputEl(scope);
388
+ return trackFormControl(inputEl, {
389
+ onFieldsetDisabledChange(disabled) {
390
+ context.set("fieldsetDisabled", disabled);
391
+ },
392
+ onFormReset() {
393
+ send({ type: "VALUE.SET", value: context.initial("value"), src: "form.reset" });
394
+ }
395
+ });
396
+ },
397
+ trackPointerMove({ context, scope, event, send }) {
398
+ return trackPointerMove(scope.getDoc(), {
399
+ onPointerMove({ point }) {
400
+ const type = context.get("activeId") === "area" ? "AREA.POINTER_MOVE" : "CHANNEL_SLIDER.POINTER_MOVE";
401
+ send({ type, point, format: event.format });
402
+ },
403
+ onPointerUp() {
404
+ const type = context.get("activeId") === "area" ? "AREA.POINTER_UP" : "CHANNEL_SLIDER.POINTER_UP";
405
+ send({ type });
406
+ }
407
+ });
408
+ },
409
+ disableTextSelection({ scope }) {
410
+ return disableTextSelection({
411
+ doc: scope.getDoc(),
412
+ target: dom.getContentEl(scope)
413
+ });
414
+ }
415
+ },
416
+ actions: {
417
+ openEyeDropper({ scope, context }) {
418
+ const win = scope.getWin();
419
+ const isSupported = "EyeDropper" in win;
420
+ if (!isSupported) return;
421
+ const picker = new win.EyeDropper();
422
+ picker.open().then(({ sRGBHex }) => {
423
+ const format = context.get("value").getFormat();
424
+ const color = parseColor(sRGBHex).toFormat(format);
425
+ context.set("value", color);
426
+ }).catch(() => void 0);
427
+ },
428
+ setActiveChannel({ context, event }) {
429
+ context.set("activeId", event.id);
430
+ if (event.channel) context.set("activeChannel", event.channel);
431
+ if (event.orientation) context.set("activeOrientation", event.orientation);
432
+ },
433
+ clearActiveChannel({ context }) {
434
+ context.set("activeChannel", null);
435
+ context.set("activeId", null);
436
+ context.set("activeOrientation", null);
437
+ },
438
+ setAreaColorFromPoint({ context, event, computed, scope, prop }) {
439
+ const v = event.format ? context.get("value").toFormat(event.format) : computed("areaValue");
440
+ const { xChannel, yChannel } = event.channel || context.get("activeChannel");
441
+ const percent = dom.getAreaValueFromPoint(scope, event.point, prop("dir"));
442
+ if (!percent) return;
443
+ const xValue = v.getChannelPercentValue(xChannel, percent.x);
444
+ const yValue = v.getChannelPercentValue(yChannel, 1 - percent.y);
445
+ const color = v.withChannelValue(xChannel, xValue).withChannelValue(yChannel, yValue);
446
+ context.set("value", color);
447
+ },
448
+ setChannelColorFromPoint({ context, event, computed, scope, prop }) {
449
+ const channel = event.channel || context.get("activeId");
450
+ const normalizedValue = event.format ? context.get("value").toFormat(event.format) : computed("areaValue");
451
+ const percent = dom.getChannelSliderValueFromPoint(scope, event.point, channel, prop("dir"));
452
+ if (!percent) return;
453
+ const orientation = context.get("activeOrientation") || "horizontal";
454
+ const channelPercent = orientation === "horizontal" ? percent.x : percent.y;
455
+ const value = normalizedValue.getChannelPercentValue(channel, channelPercent);
456
+ const color = normalizedValue.withChannelValue(channel, value);
457
+ context.set("value", color);
458
+ },
459
+ setValue({ context, event }) {
460
+ context.set("value", event.value);
461
+ },
462
+ setFormat({ context, event }) {
463
+ context.set("format", event.format);
464
+ },
465
+ dispatchChangeEvent({ scope, computed }) {
466
+ dispatchInputValueEvent(dom.getHiddenInputEl(scope), { value: computed("valueAsString") });
467
+ },
468
+ syncInputElements({ context, scope }) {
469
+ syncChannelInputs(scope, context.get("value"));
470
+ },
471
+ invokeOnChangeEnd({ context, prop, computed }) {
472
+ prop("onValueChangeEnd")?.({
473
+ value: context.get("value"),
474
+ valueAsString: computed("valueAsString")
475
+ });
476
+ },
477
+ setChannelColorFromInput({ context, event, scope, prop }) {
478
+ const { channel, isTextField, value } = event;
479
+ const currentAlpha = context.get("value").getChannelValue("alpha");
480
+ let color;
481
+ if (channel === "alpha") {
482
+ let valueAsNumber = parseFloat(value);
483
+ valueAsNumber = Number.isNaN(valueAsNumber) ? currentAlpha : valueAsNumber;
484
+ color = context.get("value").withChannelValue("alpha", valueAsNumber);
485
+ } else if (isTextField) {
486
+ color = tryCatch(
487
+ () => {
488
+ const parseValue = channel === "hex" ? prefixHex(value) : value;
489
+ return parse(parseValue).withChannelValue("alpha", currentAlpha);
490
+ },
491
+ () => context.get("value")
492
+ );
493
+ } else {
494
+ const current = context.get("value").toFormat(context.get("format"));
495
+ const valueAsNumber = Number.isNaN(value) ? current.getChannelValue(channel) : value;
496
+ color = current.withChannelValue(channel, valueAsNumber);
497
+ }
498
+ syncChannelInputs(scope, context.get("value"), color);
499
+ context.set("value", color);
500
+ prop("onValueChangeEnd")?.({
501
+ value: color,
502
+ valueAsString: color.toString(context.get("format"))
503
+ });
504
+ },
505
+ incrementChannel({ context, event }) {
506
+ const color = context.get("value").incrementChannel(event.channel, event.step);
507
+ context.set("value", color);
508
+ },
509
+ decrementChannel({ context, event }) {
510
+ const color = context.get("value").decrementChannel(event.channel, event.step);
511
+ context.set("value", color);
512
+ },
513
+ incrementAreaXChannel({ context, event, computed }) {
514
+ const { xChannel } = event.channel;
515
+ const color = computed("areaValue").incrementChannel(xChannel, event.step);
516
+ context.set("value", color);
517
+ },
518
+ decrementAreaXChannel({ context, event, computed }) {
519
+ const { xChannel } = event.channel;
520
+ const color = computed("areaValue").decrementChannel(xChannel, event.step);
521
+ context.set("value", color);
522
+ },
523
+ incrementAreaYChannel({ context, event, computed }) {
524
+ const { yChannel } = event.channel;
525
+ const color = computed("areaValue").incrementChannel(yChannel, event.step);
526
+ context.set("value", color);
527
+ },
528
+ decrementAreaYChannel({ context, event, computed }) {
529
+ const { yChannel } = event.channel;
530
+ const color = computed("areaValue").decrementChannel(yChannel, event.step);
531
+ context.set("value", color);
532
+ },
533
+ setChannelToMax({ context, event }) {
534
+ const value = context.get("value");
535
+ const range = value.getChannelRange(event.channel);
536
+ const color = value.withChannelValue(event.channel, range.maxValue);
537
+ context.set("value", color);
538
+ },
539
+ setChannelToMin({ context, event }) {
540
+ const value = context.get("value");
541
+ const range = value.getChannelRange(event.channel);
542
+ const color = value.withChannelValue(event.channel, range.minValue);
543
+ context.set("value", color);
544
+ },
545
+ focusAreaThumb({ scope }) {
546
+ raf(() => {
547
+ dom.getAreaThumbEl(scope)?.focus({ preventScroll: true });
548
+ });
549
+ },
550
+ focusChannelThumb({ event, scope }) {
551
+ raf(() => {
552
+ dom.getChannelSliderThumbEl(scope, event.channel)?.focus({ preventScroll: true });
553
+ });
554
+ },
555
+ setInitialFocus({ prop, scope }) {
556
+ if (!prop("openAutoFocus")) return;
557
+ raf(() => {
558
+ const element = getInitialFocus({
559
+ root: dom.getContentEl(scope),
560
+ getInitialEl: prop("initialFocusEl")
561
+ });
562
+ element?.focus({ preventScroll: true });
563
+ });
564
+ },
565
+ setReturnFocus({ scope }) {
566
+ raf(() => {
567
+ dom.getTriggerEl(scope)?.focus({ preventScroll: true });
568
+ });
569
+ },
570
+ syncFormatSelectElement({ context, scope }) {
571
+ syncFormatSelect(scope, context.get("format"));
572
+ },
573
+ syncValueWithFormat({ context }) {
574
+ const value = context.get("value");
575
+ const newValue = value.toFormat(context.get("format"));
576
+ if (newValue.isEqual(value)) return;
577
+ context.set("value", newValue);
578
+ },
579
+ invokeOnOpen({ prop, context }) {
580
+ if (prop("inline")) return;
581
+ prop("onOpenChange")?.({ open: true, value: context.get("value") });
582
+ },
583
+ invokeOnClose({ prop, context }) {
584
+ if (prop("inline")) return;
585
+ prop("onOpenChange")?.({ open: false, value: context.get("value") });
586
+ },
587
+ toggleVisibility({ prop, event, send }) {
588
+ send({ type: prop("open") ? "CONTROLLED.OPEN" : "CONTROLLED.CLOSE", previousEvent: event });
589
+ }
590
+ }
591
+ }
592
+ });
593
+ function syncChannelInputs(scope, currentValue, nextValue) {
594
+ const channelInputEls = dom.getChannelInputEls(scope);
595
+ raf(() => {
596
+ channelInputEls.forEach((inputEl) => {
597
+ const channel = inputEl.dataset.channel;
598
+ setElementValue(inputEl, getChannelValue(nextValue || currentValue, channel));
599
+ });
600
+ });
601
+ }
602
+ function syncFormatSelect(scope, format) {
603
+ const selectEl = dom.getFormatSelectEl(scope);
604
+ if (!selectEl) return;
605
+ raf(() => setElementValue(selectEl, format));
606
+ }
607
+ export {
608
+ machine
609
+ };
@@ -0,0 +1,5 @@
1
+ import { Color } from '@zag-js/color-utils';
2
+
3
+ declare const parse: (colorString: string) => Color;
4
+
5
+ export { parse };
@@ -0,0 +1,5 @@
1
+ import { Color } from '@zag-js/color-utils';
2
+
3
+ declare const parse: (colorString: string) => Color;
4
+
5
+ export { parse };
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/color-picker.parse.ts
21
+ var color_picker_parse_exports = {};
22
+ __export(color_picker_parse_exports, {
23
+ parse: () => parse
24
+ });
25
+ module.exports = __toCommonJS(color_picker_parse_exports);
26
+ var import_color_utils = require("@zag-js/color-utils");
27
+ var parse = (colorString) => {
28
+ return (0, import_color_utils.parseColor)(colorString);
29
+ };
30
+ // Annotate the CommonJS export names for ESM import in node:
31
+ 0 && (module.exports = {
32
+ parse
33
+ });
@@ -0,0 +1,8 @@
1
+ // src/color-picker.parse.ts
2
+ import { parseColor } from "@zag-js/color-utils";
3
+ var parse = (colorString) => {
4
+ return parseColor(colorString);
5
+ };
6
+ export {
7
+ parse
8
+ };
@@ -0,0 +1,21 @@
1
+ import { AreaProps, ChannelProps, ColorPickerProps, SwatchProps, SwatchTriggerProps, TransparencyGridProps } from './color-picker.types.mjs';
2
+ import '@zag-js/color-utils';
3
+ import '@zag-js/core';
4
+ import '@zag-js/dismissable';
5
+ import '@zag-js/popper';
6
+ import '@zag-js/types';
7
+
8
+ declare const props: (keyof ColorPickerProps)[];
9
+ declare const splitProps: <Props extends Partial<ColorPickerProps>>(props: Props) => [Partial<ColorPickerProps>, Omit<Props, keyof ColorPickerProps>];
10
+ declare const areaProps: (keyof AreaProps)[];
11
+ declare const splitAreaProps: <Props extends AreaProps>(props: Props) => [AreaProps, Omit<Props, keyof AreaProps>];
12
+ declare const channelProps: (keyof ChannelProps)[];
13
+ declare const splitChannelProps: <Props extends ChannelProps>(props: Props) => [ChannelProps, Omit<Props, keyof ChannelProps>];
14
+ declare const swatchTriggerProps: (keyof SwatchTriggerProps)[];
15
+ declare const splitSwatchTriggerProps: <Props extends SwatchTriggerProps>(props: Props) => [SwatchTriggerProps, Omit<Props, keyof SwatchTriggerProps>];
16
+ declare const swatchProps: (keyof SwatchProps)[];
17
+ declare const splitSwatchProps: <Props extends SwatchProps>(props: Props) => [SwatchProps, Omit<Props, keyof SwatchProps>];
18
+ declare const transparencyGridProps: "size"[];
19
+ declare const splitTransparencyGridProps: <Props extends TransparencyGridProps>(props: Props) => [TransparencyGridProps, Omit<Props, "size">];
20
+
21
+ export { areaProps, channelProps, props, splitAreaProps, splitChannelProps, splitProps, splitSwatchProps, splitSwatchTriggerProps, splitTransparencyGridProps, swatchProps, swatchTriggerProps, transparencyGridProps };