@zag-js/color-picker 0.29.0 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +46 -9
- package/dist/index.d.ts +46 -9
- package/dist/index.js +220 -89
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +220 -89
- package/dist/index.mjs.map +1 -1
- package/package.json +14 -14
- package/src/color-picker.anatomy.ts +3 -0
- package/src/color-picker.connect.ts +134 -28
- package/src/color-picker.dom.ts +3 -2
- package/src/color-picker.machine.ts +90 -49
- package/src/color-picker.parse.ts +2 -10
- package/src/color-picker.types.ts +48 -7
- package/src/index.ts +1 -0
- package/src/utils/get-channel-input-value.ts +5 -5
package/dist/index.js
CHANGED
|
@@ -46,8 +46,11 @@ var anatomy = (0, import_anatomy.createAnatomy)("color-picker", [
|
|
|
46
46
|
"transparencyGrid",
|
|
47
47
|
"swatchGroup",
|
|
48
48
|
"swatchTrigger",
|
|
49
|
+
"swatchIndicator",
|
|
49
50
|
"swatch",
|
|
50
|
-
"eyeDropperTrigger"
|
|
51
|
+
"eyeDropperTrigger",
|
|
52
|
+
"formatTrigger",
|
|
53
|
+
"formatSelect"
|
|
51
54
|
]);
|
|
52
55
|
var parts = anatomy.build();
|
|
53
56
|
|
|
@@ -71,6 +74,7 @@ var dom = (0, import_dom_query.createScope)({
|
|
|
71
74
|
getTriggerId: (ctx) => ctx.ids?.trigger ?? `color-picker:${ctx.id}:trigger`,
|
|
72
75
|
getContentId: (ctx) => ctx.ids?.content ?? `color-picker:${ctx.id}:content`,
|
|
73
76
|
getPositionerId: (ctx) => `color-picker:${ctx.id}:positioner`,
|
|
77
|
+
getFormatSelectId: (ctx) => `color-picker:${ctx.id}:format-select`,
|
|
74
78
|
getAreaId: (ctx) => ctx.ids?.area ?? `color-picker:${ctx.id}:area`,
|
|
75
79
|
getAreaGradientId: (ctx) => ctx.ids?.areaGradient ?? `color-picker:${ctx.id}:area-gradient`,
|
|
76
80
|
getAreaThumbId: (ctx) => ctx.ids?.areaThumb ?? `color-picker:${ctx.id}:area-thumb`,
|
|
@@ -85,6 +89,7 @@ var dom = (0, import_dom_query.createScope)({
|
|
|
85
89
|
...(0, import_dom_query.queryAll)(dom.getControlEl(ctx), `input[data-channel="${channel}"]`)
|
|
86
90
|
];
|
|
87
91
|
},
|
|
92
|
+
getFormatSelectEl: (ctx) => dom.getById(ctx, dom.getFormatSelectId(ctx)),
|
|
88
93
|
getHiddenInputEl: (ctx) => dom.getById(ctx, dom.getHiddenInputId(ctx)),
|
|
89
94
|
getAreaEl: (ctx) => dom.getById(ctx, dom.getAreaId(ctx)),
|
|
90
95
|
getAreaValueFromPoint(ctx, point) {
|
|
@@ -116,10 +121,7 @@ var dom = (0, import_dom_query.createScope)({
|
|
|
116
121
|
getFirstFocusableEl: (ctx) => (0, import_tabbable.getFirstFocusable)(dom.getContentEl(ctx), "if-empty"),
|
|
117
122
|
getInitialFocusEl: (ctx) => {
|
|
118
123
|
let el = (0, import_utils.runIfFn)(ctx.initialFocusEl);
|
|
119
|
-
|
|
120
|
-
el = dom.getFirstFocusableEl(ctx);
|
|
121
|
-
if (!el)
|
|
122
|
-
el = dom.getContentEl(ctx);
|
|
124
|
+
el = dom.getFirstFocusableEl(ctx) ?? dom.getContentEl(ctx);
|
|
123
125
|
return el;
|
|
124
126
|
}
|
|
125
127
|
});
|
|
@@ -164,7 +166,7 @@ function getChannelValue(color, channel) {
|
|
|
164
166
|
case "hue":
|
|
165
167
|
return isHSL ? color.toFormat("hsla").getChannelValue("hue").toString() : color.toFormat("hsba").getChannelValue("hue").toString();
|
|
166
168
|
case "saturation":
|
|
167
|
-
return isHSL ? color.toFormat("
|
|
169
|
+
return isHSL ? color.toFormat("hsla").getChannelValue("saturation").toString() : color.toFormat("hsba").getChannelValue("saturation").toString();
|
|
168
170
|
case "lightness":
|
|
169
171
|
return color.toFormat("hsla").getChannelValue("lightness").toString();
|
|
170
172
|
case "brightness":
|
|
@@ -193,13 +195,13 @@ function getChannelRange(color, channel) {
|
|
|
193
195
|
case "hue":
|
|
194
196
|
case "saturation":
|
|
195
197
|
case "lightness":
|
|
196
|
-
return color.toFormat("
|
|
198
|
+
return color.toFormat("hsla").getChannelRange(channel);
|
|
197
199
|
case "brightness":
|
|
198
|
-
return color.toFormat("
|
|
200
|
+
return color.toFormat("hsba").getChannelRange(channel);
|
|
199
201
|
case "red":
|
|
200
202
|
case "green":
|
|
201
203
|
case "blue":
|
|
202
|
-
return color.toFormat("
|
|
204
|
+
return color.toFormat("rgba").getChannelRange(channel);
|
|
203
205
|
default:
|
|
204
206
|
return color.getChannelRange(channel);
|
|
205
207
|
}
|
|
@@ -246,13 +248,15 @@ var getSliderBackground = (props) => {
|
|
|
246
248
|
// src/color-picker.connect.ts
|
|
247
249
|
function connect(state, send, normalize) {
|
|
248
250
|
const value = state.context.value;
|
|
251
|
+
const areaValue = state.context.areaValue;
|
|
249
252
|
const valueAsString = state.context.valueAsString;
|
|
250
253
|
const isDisabled = state.context.isDisabled;
|
|
251
254
|
const isInteractive = state.context.isInteractive;
|
|
252
255
|
const isDragging = state.hasTag("dragging");
|
|
253
256
|
const isOpen = state.hasTag("open");
|
|
257
|
+
const isFocused = state.hasTag("focused");
|
|
254
258
|
const getAreaChannels = (props) => {
|
|
255
|
-
const channels =
|
|
259
|
+
const channels = areaValue.getChannels();
|
|
256
260
|
return {
|
|
257
261
|
xChannel: props.xChannel ?? channels[1],
|
|
258
262
|
yChannel: props.yChannel ?? channels[2]
|
|
@@ -263,11 +267,26 @@ function connect(state, send, normalize) {
|
|
|
263
267
|
...state.context.positioning,
|
|
264
268
|
placement: currentPlacement
|
|
265
269
|
});
|
|
270
|
+
function getSwatchTriggerState(props) {
|
|
271
|
+
const color = (0, import_color_utils3.normalizeColor)(props.value).toFormat(state.context.format);
|
|
272
|
+
return {
|
|
273
|
+
value: color,
|
|
274
|
+
valueAsString: color.toString("hex"),
|
|
275
|
+
isChecked: color.isEqual(value),
|
|
276
|
+
isDisabled: props.disabled || !isInteractive
|
|
277
|
+
};
|
|
278
|
+
}
|
|
266
279
|
return {
|
|
267
280
|
isDragging,
|
|
268
281
|
isOpen,
|
|
269
282
|
valueAsString,
|
|
270
283
|
value,
|
|
284
|
+
open() {
|
|
285
|
+
send({ type: "OPEN" });
|
|
286
|
+
},
|
|
287
|
+
close() {
|
|
288
|
+
send({ type: "CLOSE" });
|
|
289
|
+
},
|
|
271
290
|
setValue(value2) {
|
|
272
291
|
send({ type: "VALUE.SET", value: (0, import_color_utils3.normalizeColor)(value2), src: "set-color" });
|
|
273
292
|
},
|
|
@@ -278,7 +297,7 @@ function connect(state, send, normalize) {
|
|
|
278
297
|
const color = value.withChannelValue(channel, channelValue);
|
|
279
298
|
send({ type: "VALUE.SET", value: color, src: "set-channel" });
|
|
280
299
|
},
|
|
281
|
-
format:
|
|
300
|
+
format: state.context.format,
|
|
282
301
|
setFormat(format) {
|
|
283
302
|
const formatValue = value.toFormat(format);
|
|
284
303
|
send({ type: "VALUE.SET", value: formatValue, src: "set-format" });
|
|
@@ -305,6 +324,7 @@ function connect(state, send, normalize) {
|
|
|
305
324
|
htmlFor: dom.getHiddenInputId(state.context),
|
|
306
325
|
"data-disabled": (0, import_dom_query2.dataAttr)(isDisabled),
|
|
307
326
|
"data-readonly": (0, import_dom_query2.dataAttr)(state.context.readOnly),
|
|
327
|
+
"data-focus": (0, import_dom_query2.dataAttr)(isFocused),
|
|
308
328
|
onClick(event) {
|
|
309
329
|
event.preventDefault();
|
|
310
330
|
const inputEl = (0, import_dom_query2.query)(dom.getControlEl(state.context), "[data-channel=hex]");
|
|
@@ -316,21 +336,35 @@ function connect(state, send, normalize) {
|
|
|
316
336
|
id: dom.getControlId(state.context),
|
|
317
337
|
dir: state.context.dir,
|
|
318
338
|
"data-disabled": (0, import_dom_query2.dataAttr)(isDisabled),
|
|
319
|
-
"data-readonly": (0, import_dom_query2.dataAttr)(state.context.readOnly)
|
|
339
|
+
"data-readonly": (0, import_dom_query2.dataAttr)(state.context.readOnly),
|
|
340
|
+
"data-state": isOpen ? "open" : "closed",
|
|
341
|
+
"data-focus": (0, import_dom_query2.dataAttr)(isFocused)
|
|
320
342
|
}),
|
|
321
343
|
triggerProps: normalize.button({
|
|
322
344
|
...parts.trigger.attrs,
|
|
323
345
|
id: dom.getTriggerId(state.context),
|
|
324
346
|
dir: state.context.dir,
|
|
347
|
+
disabled: isDisabled,
|
|
348
|
+
"aria-label": `select color. current color is ${valueAsString}`,
|
|
325
349
|
"aria-controls": dom.getContentId(state.context),
|
|
326
350
|
"aria-labelledby": dom.getLabelId(state.context),
|
|
327
351
|
"data-disabled": (0, import_dom_query2.dataAttr)(isDisabled),
|
|
328
352
|
"data-readonly": (0, import_dom_query2.dataAttr)(state.context.readOnly),
|
|
329
353
|
"data-placement": currentPlacement,
|
|
354
|
+
"aria-expanded": (0, import_dom_query2.dataAttr)(isOpen),
|
|
355
|
+
"data-state": isOpen ? "open" : "closed",
|
|
356
|
+
"data-focus": (0, import_dom_query2.dataAttr)(isFocused),
|
|
330
357
|
type: "button",
|
|
331
358
|
onClick() {
|
|
359
|
+
if (!isInteractive)
|
|
360
|
+
return;
|
|
332
361
|
send({ type: "TRIGGER.CLICK" });
|
|
333
362
|
},
|
|
363
|
+
onBlur() {
|
|
364
|
+
if (!isInteractive)
|
|
365
|
+
return;
|
|
366
|
+
send({ type: "TRIGGER.BLUR" });
|
|
367
|
+
},
|
|
334
368
|
style: {
|
|
335
369
|
position: "relative"
|
|
336
370
|
}
|
|
@@ -346,11 +380,12 @@ function connect(state, send, normalize) {
|
|
|
346
380
|
id: dom.getContentId(state.context),
|
|
347
381
|
dir: state.context.dir,
|
|
348
382
|
"data-placement": currentPlacement,
|
|
383
|
+
"data-state": isOpen ? "open" : "closed",
|
|
349
384
|
hidden: !isOpen
|
|
350
385
|
}),
|
|
351
386
|
getAreaProps(props = {}) {
|
|
352
387
|
const { xChannel, yChannel } = getAreaChannels(props);
|
|
353
|
-
const { areaStyles } = (0, import_color_utils3.getColorAreaGradient)(
|
|
388
|
+
const { areaStyles } = (0, import_color_utils3.getColorAreaGradient)(areaValue, {
|
|
354
389
|
xChannel,
|
|
355
390
|
yChannel,
|
|
356
391
|
dir: state.context.dir
|
|
@@ -380,7 +415,7 @@ function connect(state, send, normalize) {
|
|
|
380
415
|
},
|
|
381
416
|
getAreaBackgroundProps(props = {}) {
|
|
382
417
|
const { xChannel, yChannel } = getAreaChannels(props);
|
|
383
|
-
const { areaGradientStyles } = (0, import_color_utils3.getColorAreaGradient)(
|
|
418
|
+
const { areaGradientStyles } = (0, import_color_utils3.getColorAreaGradient)(areaValue, {
|
|
384
419
|
xChannel,
|
|
385
420
|
yChannel,
|
|
386
421
|
dir: state.context.dir
|
|
@@ -399,25 +434,35 @@ function connect(state, send, normalize) {
|
|
|
399
434
|
getAreaThumbProps(props = {}) {
|
|
400
435
|
const { xChannel, yChannel } = getAreaChannels(props);
|
|
401
436
|
const channel = { xChannel, yChannel };
|
|
402
|
-
const
|
|
403
|
-
const
|
|
437
|
+
const xPercent = areaValue.getChannelValuePercent(xChannel);
|
|
438
|
+
const yPercent = 1 - areaValue.getChannelValuePercent(yChannel);
|
|
439
|
+
const xValue = areaValue.getChannelValue(xChannel);
|
|
440
|
+
const yValue = areaValue.getChannelValue(yChannel);
|
|
404
441
|
return normalize.element({
|
|
405
442
|
...parts.areaThumb.attrs,
|
|
406
443
|
id: dom.getAreaThumbId(state.context),
|
|
407
444
|
dir: state.context.dir,
|
|
408
445
|
tabIndex: isDisabled ? void 0 : 0,
|
|
409
446
|
"data-disabled": (0, import_dom_query2.dataAttr)(isDisabled),
|
|
410
|
-
role: "
|
|
447
|
+
role: "slider",
|
|
448
|
+
"aria-valuemin": 0,
|
|
449
|
+
"aria-valuemax": 100,
|
|
450
|
+
"aria-valuenow": xValue,
|
|
451
|
+
"aria-label": `${xChannel} and ${yChannel}`,
|
|
452
|
+
"aria-roledescription": "2d slider",
|
|
453
|
+
"aria-valuetext": `${xChannel} ${xValue}, ${yChannel} ${yValue}`,
|
|
411
454
|
style: {
|
|
412
455
|
position: "absolute",
|
|
413
|
-
left: `${
|
|
414
|
-
top: `${
|
|
456
|
+
left: `${xPercent * 100}%`,
|
|
457
|
+
top: `${yPercent * 100}%`,
|
|
415
458
|
transform: "translate(-50%, -50%)",
|
|
416
459
|
touchAction: "none",
|
|
417
460
|
forcedColorAdjust: "none",
|
|
418
|
-
background:
|
|
461
|
+
background: areaValue.withChannelValue("alpha", 1).toString("css")
|
|
419
462
|
},
|
|
420
463
|
onFocus() {
|
|
464
|
+
if (!isInteractive)
|
|
465
|
+
return;
|
|
421
466
|
send({ type: "AREA.FOCUS", id: "area", channel });
|
|
422
467
|
},
|
|
423
468
|
onKeyDown(event) {
|
|
@@ -511,15 +556,15 @@ function connect(state, send, normalize) {
|
|
|
511
556
|
orientation,
|
|
512
557
|
channel,
|
|
513
558
|
dir: state.context.dir,
|
|
514
|
-
value
|
|
559
|
+
value: areaValue
|
|
515
560
|
})
|
|
516
561
|
}
|
|
517
562
|
});
|
|
518
563
|
},
|
|
519
564
|
getChannelSliderThumbProps(props) {
|
|
520
565
|
const { orientation = "horizontal", channel } = props;
|
|
521
|
-
const { minValue, maxValue, step: stepValue } =
|
|
522
|
-
const channelValue =
|
|
566
|
+
const { minValue, maxValue, step: stepValue } = areaValue.getChannelRange(channel);
|
|
567
|
+
const channelValue = areaValue.getChannelValue(channel);
|
|
523
568
|
const offset = (channelValue - minValue) / (maxValue - minValue);
|
|
524
569
|
const placementStyles = orientation === "horizontal" ? { left: `${offset * 100}%`, top: "50%" } : { top: `${offset * 100}%`, left: "50%" };
|
|
525
570
|
return normalize.element({
|
|
@@ -536,10 +581,11 @@ function connect(state, send, normalize) {
|
|
|
536
581
|
"aria-valuemax": maxValue,
|
|
537
582
|
"aria-valuemin": minValue,
|
|
538
583
|
"aria-valuenow": channelValue,
|
|
584
|
+
"aria-valuetext": `${channel} ${channelValue}`,
|
|
539
585
|
style: {
|
|
540
586
|
forcedColorAdjust: "none",
|
|
541
587
|
position: "absolute",
|
|
542
|
-
background: getChannelDisplayColor(
|
|
588
|
+
background: getChannelDisplayColor(areaValue, channel).toString("css"),
|
|
543
589
|
...placementStyles
|
|
544
590
|
},
|
|
545
591
|
onFocus() {
|
|
@@ -598,6 +644,8 @@ function connect(state, send, normalize) {
|
|
|
598
644
|
type: isTextField ? "text" : "number",
|
|
599
645
|
"data-channel": channel,
|
|
600
646
|
"aria-label": channel,
|
|
647
|
+
spellCheck: false,
|
|
648
|
+
autoComplete: "off",
|
|
601
649
|
disabled: isDisabled,
|
|
602
650
|
"data-disabled": (0, import_dom_query2.dataAttr)(isDisabled),
|
|
603
651
|
readOnly: state.context.readOnly,
|
|
@@ -606,7 +654,7 @@ function connect(state, send, normalize) {
|
|
|
606
654
|
max: range?.maxValue,
|
|
607
655
|
step: range?.step,
|
|
608
656
|
onBeforeInput(event) {
|
|
609
|
-
if (isTextField)
|
|
657
|
+
if (isTextField || !isInteractive)
|
|
610
658
|
return;
|
|
611
659
|
const value2 = event.currentTarget.value;
|
|
612
660
|
if (value2.match(/[^0-9.]/g)) {
|
|
@@ -614,14 +662,20 @@ function connect(state, send, normalize) {
|
|
|
614
662
|
}
|
|
615
663
|
},
|
|
616
664
|
onFocus(event) {
|
|
665
|
+
if (!isInteractive)
|
|
666
|
+
return;
|
|
617
667
|
send({ type: "CHANNEL_INPUT.FOCUS", channel });
|
|
618
668
|
event.target.select();
|
|
619
669
|
},
|
|
620
670
|
onBlur(event) {
|
|
671
|
+
if (!isInteractive)
|
|
672
|
+
return;
|
|
621
673
|
const value2 = isTextField ? event.currentTarget.value : event.currentTarget.valueAsNumber;
|
|
622
674
|
send({ type: "CHANNEL_INPUT.BLUR", channel, value: value2, isTextField });
|
|
623
675
|
},
|
|
624
676
|
onKeyDown(event) {
|
|
677
|
+
if (!isInteractive)
|
|
678
|
+
return;
|
|
625
679
|
if (event.key === "Enter") {
|
|
626
680
|
const value2 = isTextField ? event.currentTarget.value : event.currentTarget.valueAsNumber;
|
|
627
681
|
send({ type: "CHANNEL_INPUT.CHANGE", channel, value: value2, isTextField });
|
|
@@ -660,42 +714,87 @@ function connect(state, send, normalize) {
|
|
|
660
714
|
...parts.swatchGroup.attrs,
|
|
661
715
|
role: "group"
|
|
662
716
|
}),
|
|
717
|
+
getSwatchTriggerState,
|
|
663
718
|
getSwatchTriggerProps(props) {
|
|
664
|
-
const
|
|
665
|
-
const color = (0, import_color_utils3.normalizeColor)(valueProp).toFormat(value.getFormat());
|
|
719
|
+
const triggerState = getSwatchTriggerState(props);
|
|
666
720
|
return normalize.button({
|
|
667
721
|
...parts.swatchTrigger.attrs,
|
|
668
|
-
disabled: isDisabled,
|
|
722
|
+
disabled: triggerState.isDisabled,
|
|
669
723
|
dir: state.context.dir,
|
|
670
724
|
type: "button",
|
|
671
|
-
"
|
|
725
|
+
"aria-label": `select ${triggerState.valueAsString} as the color`,
|
|
726
|
+
"data-state": triggerState.isChecked ? "checked" : "unchecked",
|
|
727
|
+
"data-value": triggerState.valueAsString,
|
|
728
|
+
"data-disabled": (0, import_dom_query2.dataAttr)(triggerState.isDisabled),
|
|
672
729
|
onClick() {
|
|
673
|
-
if (
|
|
730
|
+
if (triggerState.isDisabled)
|
|
674
731
|
return;
|
|
675
|
-
send({ type: "
|
|
732
|
+
send({ type: "SWATCH_TRIGGER.CLICK", value: triggerState.value });
|
|
676
733
|
},
|
|
677
734
|
style: {
|
|
678
735
|
position: "relative"
|
|
679
736
|
}
|
|
680
737
|
});
|
|
681
738
|
},
|
|
739
|
+
getSwatchIndicatorProps(props) {
|
|
740
|
+
const triggerState = getSwatchTriggerState(props);
|
|
741
|
+
return normalize.element({
|
|
742
|
+
...parts.swatchIndicator.attrs,
|
|
743
|
+
dir: state.context.dir,
|
|
744
|
+
"aria-hidden": true,
|
|
745
|
+
"data-state": triggerState.isChecked ? "open" : "closed"
|
|
746
|
+
});
|
|
747
|
+
},
|
|
682
748
|
getSwatchProps(props) {
|
|
683
|
-
const {
|
|
684
|
-
const
|
|
685
|
-
const color = colorValue.toFormat(value.getFormat());
|
|
749
|
+
const { respectAlpha = true } = props;
|
|
750
|
+
const triggerState = getSwatchTriggerState(props);
|
|
686
751
|
return normalize.element({
|
|
687
752
|
...parts.swatch.attrs,
|
|
688
753
|
dir: state.context.dir,
|
|
689
|
-
"data-state":
|
|
690
|
-
"data-value":
|
|
754
|
+
"data-state": triggerState.isChecked ? "checked" : "unchecked",
|
|
755
|
+
"data-value": triggerState.valueAsString,
|
|
691
756
|
style: {
|
|
692
757
|
position: "relative",
|
|
693
|
-
background:
|
|
758
|
+
background: triggerState.value.toString(respectAlpha ? "css" : "hex")
|
|
694
759
|
}
|
|
695
760
|
});
|
|
696
|
-
}
|
|
761
|
+
},
|
|
762
|
+
formatTriggerProps: normalize.button({
|
|
763
|
+
...parts.formatTrigger.attrs,
|
|
764
|
+
dir: state.context.dir,
|
|
765
|
+
type: "button",
|
|
766
|
+
"aria-label": `change color format to ${getNextFormat(state.context.format)}`,
|
|
767
|
+
onClick(event) {
|
|
768
|
+
if (event.currentTarget.disabled)
|
|
769
|
+
return;
|
|
770
|
+
const nextFormat = getNextFormat(state.context.format);
|
|
771
|
+
send({ type: "FORMAT.SET", format: nextFormat, src: "format-trigger" });
|
|
772
|
+
}
|
|
773
|
+
}),
|
|
774
|
+
formatSelectProps: normalize.select({
|
|
775
|
+
...parts.formatSelect.attrs,
|
|
776
|
+
"aria-label": "change color format",
|
|
777
|
+
dir: state.context.dir,
|
|
778
|
+
defaultValue: state.context.format,
|
|
779
|
+
disabled: isDisabled,
|
|
780
|
+
onChange(event) {
|
|
781
|
+
const format = assertFormat(event.currentTarget.value);
|
|
782
|
+
send({ type: "FORMAT.SET", format, src: "format-select" });
|
|
783
|
+
}
|
|
784
|
+
})
|
|
697
785
|
};
|
|
698
786
|
}
|
|
787
|
+
var formats = ["hsba", "hsla", "rgba"];
|
|
788
|
+
var formatRegex = new RegExp(`^(${formats.join("|")})$`);
|
|
789
|
+
function getNextFormat(format) {
|
|
790
|
+
const index = formats.indexOf(format);
|
|
791
|
+
return formats[index + 1] ?? formats[0];
|
|
792
|
+
}
|
|
793
|
+
function assertFormat(format) {
|
|
794
|
+
if (formatRegex.test(format))
|
|
795
|
+
return format;
|
|
796
|
+
throw new Error(`Unsupported color format: ${format}`);
|
|
797
|
+
}
|
|
699
798
|
|
|
700
799
|
// src/color-picker.machine.ts
|
|
701
800
|
var import_color_utils5 = require("@zag-js/color-utils");
|
|
@@ -710,13 +809,8 @@ var import_utils2 = require("@zag-js/utils");
|
|
|
710
809
|
|
|
711
810
|
// src/color-picker.parse.ts
|
|
712
811
|
var import_color_utils4 = require("@zag-js/color-utils");
|
|
713
|
-
var parse = (
|
|
714
|
-
|
|
715
|
-
const colorFormat = value.getFormat();
|
|
716
|
-
const lockedFormat = colorFormat === "hsla" ? "hsla" : "hsba";
|
|
717
|
-
const result = value.toFormat(lockedFormat);
|
|
718
|
-
result.outputFormat = colorFormat;
|
|
719
|
-
return result;
|
|
812
|
+
var parse = (colorString) => {
|
|
813
|
+
return (0, import_color_utils4.parseColor)(colorString);
|
|
720
814
|
};
|
|
721
815
|
|
|
722
816
|
// src/color-picker.machine.ts
|
|
@@ -729,13 +823,14 @@ function machine(userContext) {
|
|
|
729
823
|
context: {
|
|
730
824
|
dir: "ltr",
|
|
731
825
|
value: parse("#000000"),
|
|
826
|
+
format: "rgba",
|
|
732
827
|
disabled: false,
|
|
828
|
+
closeOnSelect: false,
|
|
733
829
|
...ctx,
|
|
734
830
|
activeId: null,
|
|
735
831
|
activeChannel: null,
|
|
736
832
|
activeOrientation: null,
|
|
737
833
|
fieldsetDisabled: false,
|
|
738
|
-
autoFocus: true,
|
|
739
834
|
positioning: {
|
|
740
835
|
...ctx.positioning,
|
|
741
836
|
placement: "bottom"
|
|
@@ -745,22 +840,30 @@ function machine(userContext) {
|
|
|
745
840
|
isRtl: (ctx2) => ctx2.dir === "rtl",
|
|
746
841
|
isDisabled: (ctx2) => !!ctx2.disabled || ctx2.fieldsetDisabled,
|
|
747
842
|
isInteractive: (ctx2) => !(ctx2.isDisabled || ctx2.readOnly),
|
|
748
|
-
valueAsString: (ctx2) =>
|
|
749
|
-
|
|
750
|
-
|
|
843
|
+
valueAsString: (ctx2) => ctx2.value.toString(ctx2.format),
|
|
844
|
+
areaValue: (ctx2) => {
|
|
845
|
+
const format = ctx2.format.startsWith("hsl") ? "hsla" : "hsba";
|
|
846
|
+
return ctx2.value.toFormat(format);
|
|
751
847
|
}
|
|
752
848
|
},
|
|
753
849
|
activities: ["trackFormControl"],
|
|
754
850
|
watch: {
|
|
755
851
|
value: ["syncInputElements"],
|
|
852
|
+
format: ["syncFormatSelectElement"],
|
|
756
853
|
open: ["toggleVisibility"]
|
|
757
854
|
},
|
|
758
855
|
on: {
|
|
759
856
|
"VALUE.SET": {
|
|
760
857
|
actions: ["setValue"]
|
|
761
858
|
},
|
|
859
|
+
"FORMAT.SET": {
|
|
860
|
+
actions: ["setFormat"]
|
|
861
|
+
},
|
|
762
862
|
"CHANNEL_INPUT.CHANGE": {
|
|
763
863
|
actions: ["setChannelColorFromInput"]
|
|
864
|
+
},
|
|
865
|
+
"EYEDROPPER.CLICK": {
|
|
866
|
+
actions: ["openEyeDropper"]
|
|
764
867
|
}
|
|
765
868
|
},
|
|
766
869
|
states: {
|
|
@@ -798,6 +901,9 @@ function machine(userContext) {
|
|
|
798
901
|
"CHANNEL_INPUT.BLUR": {
|
|
799
902
|
target: "idle",
|
|
800
903
|
actions: ["setChannelColorFromInput"]
|
|
904
|
+
},
|
|
905
|
+
"TRIGGER.BLUR": {
|
|
906
|
+
target: "idle"
|
|
801
907
|
}
|
|
802
908
|
}
|
|
803
909
|
},
|
|
@@ -809,9 +915,6 @@ function machine(userContext) {
|
|
|
809
915
|
target: "idle",
|
|
810
916
|
actions: ["invokeOnClose"]
|
|
811
917
|
},
|
|
812
|
-
"EYEDROPPER.CLICK": {
|
|
813
|
-
actions: ["openEyeDropper"]
|
|
814
|
-
},
|
|
815
918
|
"AREA.POINTER_DOWN": {
|
|
816
919
|
target: "open:dragging",
|
|
817
920
|
actions: ["setActiveChannel", "setAreaColorFromPoint", "focusAreaThumb"]
|
|
@@ -885,7 +988,17 @@ function machine(userContext) {
|
|
|
885
988
|
CLOSE: {
|
|
886
989
|
target: "idle",
|
|
887
990
|
actions: ["invokeOnClose"]
|
|
888
|
-
}
|
|
991
|
+
},
|
|
992
|
+
"SWATCH_TRIGGER.CLICK": [
|
|
993
|
+
{
|
|
994
|
+
guard: "closeOnSelect",
|
|
995
|
+
target: "focused",
|
|
996
|
+
actions: ["setValue", "setReturnFocus", "invokeOnClose"]
|
|
997
|
+
},
|
|
998
|
+
{
|
|
999
|
+
actions: ["setValue"]
|
|
1000
|
+
}
|
|
1001
|
+
]
|
|
889
1002
|
}
|
|
890
1003
|
},
|
|
891
1004
|
"open:dragging": {
|
|
@@ -928,7 +1041,8 @@ function machine(userContext) {
|
|
|
928
1041
|
},
|
|
929
1042
|
{
|
|
930
1043
|
guards: {
|
|
931
|
-
isTargetFocusable: (_ctx, evt) => evt.restoreFocus
|
|
1044
|
+
isTargetFocusable: (_ctx, evt) => evt.restoreFocus,
|
|
1045
|
+
closeOnSelect: (ctx2) => !!ctx2.closeOnSelect
|
|
932
1046
|
},
|
|
933
1047
|
activities: {
|
|
934
1048
|
trackPositioning(ctx2) {
|
|
@@ -1023,9 +1137,9 @@ function machine(userContext) {
|
|
|
1023
1137
|
const percent = dom.getAreaValueFromPoint(ctx2, evt.point);
|
|
1024
1138
|
if (!percent)
|
|
1025
1139
|
return;
|
|
1026
|
-
const xValue = ctx2.
|
|
1027
|
-
const yValue = ctx2.
|
|
1028
|
-
const color = ctx2.
|
|
1140
|
+
const xValue = ctx2.areaValue.getChannelPercentValue(xChannel, percent.x);
|
|
1141
|
+
const yValue = ctx2.areaValue.getChannelPercentValue(yChannel, 1 - percent.y);
|
|
1142
|
+
const color = ctx2.areaValue.withChannelValue(xChannel, xValue).withChannelValue(yChannel, yValue);
|
|
1029
1143
|
set.value(ctx2, color);
|
|
1030
1144
|
},
|
|
1031
1145
|
setChannelColorFromPoint(ctx2, evt) {
|
|
@@ -1035,13 +1149,16 @@ function machine(userContext) {
|
|
|
1035
1149
|
return;
|
|
1036
1150
|
const orientation = ctx2.activeOrientation || "horizontal";
|
|
1037
1151
|
const channelPercent = orientation === "horizontal" ? percent.x : percent.y;
|
|
1038
|
-
const value = ctx2.
|
|
1039
|
-
const color = ctx2.
|
|
1152
|
+
const value = ctx2.areaValue.getChannelPercentValue(channel, channelPercent);
|
|
1153
|
+
const color = ctx2.areaValue.withChannelValue(channel, value);
|
|
1040
1154
|
set.value(ctx2, color);
|
|
1041
1155
|
},
|
|
1042
1156
|
setValue(ctx2, evt) {
|
|
1043
1157
|
set.value(ctx2, evt.value);
|
|
1044
1158
|
},
|
|
1159
|
+
setFormat(ctx2, evt) {
|
|
1160
|
+
set.format(ctx2, evt.format);
|
|
1161
|
+
},
|
|
1045
1162
|
syncInputElements(ctx2) {
|
|
1046
1163
|
sync.inputs(ctx2);
|
|
1047
1164
|
},
|
|
@@ -1051,26 +1168,22 @@ function machine(userContext) {
|
|
|
1051
1168
|
setChannelColorFromInput(ctx2, evt) {
|
|
1052
1169
|
const { channel, isTextField, value } = evt;
|
|
1053
1170
|
const currentAlpha = ctx2.value.getChannelValue("alpha");
|
|
1171
|
+
let color;
|
|
1054
1172
|
if (channel === "alpha") {
|
|
1055
1173
|
let valueAsNumber = parseFloat(value);
|
|
1056
1174
|
valueAsNumber = Number.isNaN(valueAsNumber) ? currentAlpha : valueAsNumber;
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
}
|
|
1061
|
-
if (isTextField) {
|
|
1062
|
-
const color2 = (0, import_utils2.tryCatch)(
|
|
1175
|
+
color = ctx2.value.withChannelValue("alpha", valueAsNumber);
|
|
1176
|
+
} else if (isTextField) {
|
|
1177
|
+
color = (0, import_utils2.tryCatch)(
|
|
1063
1178
|
() => parse(value).withChannelValue("alpha", currentAlpha),
|
|
1064
1179
|
() => ctx2.value
|
|
1065
1180
|
);
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
set.value(ctx2, color2);
|
|
1071
|
-
return;
|
|
1181
|
+
} else {
|
|
1182
|
+
const current = ctx2.value.toFormat(ctx2.format);
|
|
1183
|
+
const valueAsNumber = Number.isNaN(value) ? current.getChannelValue(channel) : value;
|
|
1184
|
+
color = current.withChannelValue(channel, valueAsNumber);
|
|
1072
1185
|
}
|
|
1073
|
-
|
|
1186
|
+
sync.inputs(ctx2, color);
|
|
1074
1187
|
set.value(ctx2, color);
|
|
1075
1188
|
},
|
|
1076
1189
|
incrementChannel(ctx2, evt) {
|
|
@@ -1083,22 +1196,22 @@ function machine(userContext) {
|
|
|
1083
1196
|
},
|
|
1084
1197
|
incrementXChannel(ctx2, evt) {
|
|
1085
1198
|
const { xChannel } = evt.channel;
|
|
1086
|
-
const color = ctx2.
|
|
1199
|
+
const color = ctx2.areaValue.incrementChannel(xChannel, evt.step);
|
|
1087
1200
|
set.value(ctx2, color);
|
|
1088
1201
|
},
|
|
1089
1202
|
decrementXChannel(ctx2, evt) {
|
|
1090
1203
|
const { xChannel } = evt.channel;
|
|
1091
|
-
const color = ctx2.
|
|
1204
|
+
const color = ctx2.areaValue.decrementChannel(xChannel, evt.step);
|
|
1092
1205
|
set.value(ctx2, color);
|
|
1093
1206
|
},
|
|
1094
1207
|
incrementYChannel(ctx2, evt) {
|
|
1095
1208
|
const { yChannel } = evt.channel;
|
|
1096
|
-
const color = ctx2.
|
|
1209
|
+
const color = ctx2.areaValue.incrementChannel(yChannel, evt.step);
|
|
1097
1210
|
set.value(ctx2, color);
|
|
1098
1211
|
},
|
|
1099
1212
|
decrementYChannel(ctx2, evt) {
|
|
1100
1213
|
const { yChannel } = evt.channel;
|
|
1101
|
-
const color = ctx2.
|
|
1214
|
+
const color = ctx2.areaValue.decrementChannel(yChannel, evt.step);
|
|
1102
1215
|
set.value(ctx2, color);
|
|
1103
1216
|
},
|
|
1104
1217
|
setChannelToMax(ctx2, evt) {
|
|
@@ -1131,6 +1244,9 @@ function machine(userContext) {
|
|
|
1131
1244
|
dom?.focus(ctx2, dom.getTriggerEl(ctx2));
|
|
1132
1245
|
});
|
|
1133
1246
|
},
|
|
1247
|
+
syncFormatSelectElement(ctx2) {
|
|
1248
|
+
sync.formatSelect(ctx2);
|
|
1249
|
+
},
|
|
1134
1250
|
invokeOnOpen(ctx2) {
|
|
1135
1251
|
ctx2.onOpenChange?.({ open: true });
|
|
1136
1252
|
},
|
|
@@ -1148,41 +1264,56 @@ function machine(userContext) {
|
|
|
1148
1264
|
);
|
|
1149
1265
|
}
|
|
1150
1266
|
var sync = {
|
|
1151
|
-
inputs
|
|
1267
|
+
// sync channel inputs
|
|
1268
|
+
inputs(ctx, color) {
|
|
1152
1269
|
const channelInputs = dom.getChannelInputEls(ctx);
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1270
|
+
(0, import_dom_query3.raf)(() => {
|
|
1271
|
+
channelInputs.forEach((inputEl) => {
|
|
1272
|
+
const channel = inputEl.dataset.channel;
|
|
1273
|
+
dom.setValue(inputEl, getChannelValue(color || ctx.value, channel));
|
|
1274
|
+
});
|
|
1275
|
+
});
|
|
1276
|
+
},
|
|
1277
|
+
// sync format select
|
|
1278
|
+
formatSelect(ctx) {
|
|
1279
|
+
const selectEl = dom.getFormatSelectEl(ctx);
|
|
1280
|
+
(0, import_dom_query3.raf)(() => {
|
|
1281
|
+
dom.setValue(selectEl, ctx.format);
|
|
1156
1282
|
});
|
|
1157
1283
|
}
|
|
1158
1284
|
};
|
|
1159
1285
|
var invoke = {
|
|
1160
1286
|
changeEnd(ctx) {
|
|
1287
|
+
const value = ctx.value.toFormat(ctx.format);
|
|
1161
1288
|
ctx.onValueChangeEnd?.({
|
|
1162
|
-
value
|
|
1289
|
+
value,
|
|
1163
1290
|
valueAsString: ctx.valueAsString
|
|
1164
1291
|
});
|
|
1165
1292
|
},
|
|
1166
1293
|
change(ctx) {
|
|
1294
|
+
const value = ctx.value.toFormat(ctx.format);
|
|
1167
1295
|
ctx.onValueChange?.({
|
|
1168
|
-
value
|
|
1296
|
+
value,
|
|
1169
1297
|
valueAsString: ctx.valueAsString
|
|
1170
1298
|
});
|
|
1171
1299
|
(0, import_form_utils.dispatchInputValueEvent)(dom.getHiddenInputEl(ctx), { value: ctx.valueAsString });
|
|
1300
|
+
},
|
|
1301
|
+
formatChange(ctx) {
|
|
1302
|
+
ctx.onFormatChange?.({ format: ctx.format });
|
|
1172
1303
|
}
|
|
1173
1304
|
};
|
|
1174
1305
|
var set = {
|
|
1175
1306
|
value(ctx, color) {
|
|
1176
1307
|
if (!color || ctx.value.isEqual(color))
|
|
1177
1308
|
return;
|
|
1178
|
-
|
|
1179
|
-
const outputColor = color.toFormat(currentFormat);
|
|
1180
|
-
try {
|
|
1181
|
-
outputColor.outputFormat = ctx.value.outputFormat;
|
|
1182
|
-
} catch {
|
|
1183
|
-
}
|
|
1184
|
-
ctx.value = outputColor;
|
|
1309
|
+
ctx.value = color;
|
|
1185
1310
|
invoke.change(ctx);
|
|
1311
|
+
},
|
|
1312
|
+
format(ctx, format) {
|
|
1313
|
+
if (ctx.format === format)
|
|
1314
|
+
return;
|
|
1315
|
+
ctx.format = format;
|
|
1316
|
+
invoke.formatChange(ctx);
|
|
1186
1317
|
}
|
|
1187
1318
|
};
|
|
1188
1319
|
// Annotate the CommonJS export names for ESM import in node:
|