@zag-js/color-picker 0.29.0 → 0.31.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 +219 -89
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +219 -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 +133 -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,86 @@ 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
|
+
hidden: !triggerState.isChecked
|
|
745
|
+
});
|
|
746
|
+
},
|
|
682
747
|
getSwatchProps(props) {
|
|
683
|
-
const {
|
|
684
|
-
const
|
|
685
|
-
const color = colorValue.toFormat(value.getFormat());
|
|
748
|
+
const { respectAlpha = true } = props;
|
|
749
|
+
const triggerState = getSwatchTriggerState(props);
|
|
686
750
|
return normalize.element({
|
|
687
751
|
...parts.swatch.attrs,
|
|
688
752
|
dir: state.context.dir,
|
|
689
|
-
"data-state":
|
|
690
|
-
"data-value":
|
|
753
|
+
"data-state": triggerState.isChecked ? "checked" : "unchecked",
|
|
754
|
+
"data-value": triggerState.valueAsString,
|
|
691
755
|
style: {
|
|
692
756
|
position: "relative",
|
|
693
|
-
background:
|
|
757
|
+
background: triggerState.value.toString(respectAlpha ? "css" : "hex")
|
|
694
758
|
}
|
|
695
759
|
});
|
|
696
|
-
}
|
|
760
|
+
},
|
|
761
|
+
formatTriggerProps: normalize.button({
|
|
762
|
+
...parts.formatTrigger.attrs,
|
|
763
|
+
dir: state.context.dir,
|
|
764
|
+
type: "button",
|
|
765
|
+
"aria-label": `change color format to ${getNextFormat(state.context.format)}`,
|
|
766
|
+
onClick(event) {
|
|
767
|
+
if (event.currentTarget.disabled)
|
|
768
|
+
return;
|
|
769
|
+
const nextFormat = getNextFormat(state.context.format);
|
|
770
|
+
send({ type: "FORMAT.SET", format: nextFormat, src: "format-trigger" });
|
|
771
|
+
}
|
|
772
|
+
}),
|
|
773
|
+
formatSelectProps: normalize.select({
|
|
774
|
+
...parts.formatSelect.attrs,
|
|
775
|
+
"aria-label": "change color format",
|
|
776
|
+
dir: state.context.dir,
|
|
777
|
+
defaultValue: state.context.format,
|
|
778
|
+
disabled: isDisabled,
|
|
779
|
+
onChange(event) {
|
|
780
|
+
const format = assertFormat(event.currentTarget.value);
|
|
781
|
+
send({ type: "FORMAT.SET", format, src: "format-select" });
|
|
782
|
+
}
|
|
783
|
+
})
|
|
697
784
|
};
|
|
698
785
|
}
|
|
786
|
+
var formats = ["hsba", "hsla", "rgba"];
|
|
787
|
+
var formatRegex = new RegExp(`^(${formats.join("|")})$`);
|
|
788
|
+
function getNextFormat(format) {
|
|
789
|
+
const index = formats.indexOf(format);
|
|
790
|
+
return formats[index + 1] ?? formats[0];
|
|
791
|
+
}
|
|
792
|
+
function assertFormat(format) {
|
|
793
|
+
if (formatRegex.test(format))
|
|
794
|
+
return format;
|
|
795
|
+
throw new Error(`Unsupported color format: ${format}`);
|
|
796
|
+
}
|
|
699
797
|
|
|
700
798
|
// src/color-picker.machine.ts
|
|
701
799
|
var import_color_utils5 = require("@zag-js/color-utils");
|
|
@@ -710,13 +808,8 @@ var import_utils2 = require("@zag-js/utils");
|
|
|
710
808
|
|
|
711
809
|
// src/color-picker.parse.ts
|
|
712
810
|
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;
|
|
811
|
+
var parse = (colorString) => {
|
|
812
|
+
return (0, import_color_utils4.parseColor)(colorString);
|
|
720
813
|
};
|
|
721
814
|
|
|
722
815
|
// src/color-picker.machine.ts
|
|
@@ -729,13 +822,14 @@ function machine(userContext) {
|
|
|
729
822
|
context: {
|
|
730
823
|
dir: "ltr",
|
|
731
824
|
value: parse("#000000"),
|
|
825
|
+
format: "rgba",
|
|
732
826
|
disabled: false,
|
|
827
|
+
closeOnSelect: false,
|
|
733
828
|
...ctx,
|
|
734
829
|
activeId: null,
|
|
735
830
|
activeChannel: null,
|
|
736
831
|
activeOrientation: null,
|
|
737
832
|
fieldsetDisabled: false,
|
|
738
|
-
autoFocus: true,
|
|
739
833
|
positioning: {
|
|
740
834
|
...ctx.positioning,
|
|
741
835
|
placement: "bottom"
|
|
@@ -745,22 +839,30 @@ function machine(userContext) {
|
|
|
745
839
|
isRtl: (ctx2) => ctx2.dir === "rtl",
|
|
746
840
|
isDisabled: (ctx2) => !!ctx2.disabled || ctx2.fieldsetDisabled,
|
|
747
841
|
isInteractive: (ctx2) => !(ctx2.isDisabled || ctx2.readOnly),
|
|
748
|
-
valueAsString: (ctx2) =>
|
|
749
|
-
|
|
750
|
-
|
|
842
|
+
valueAsString: (ctx2) => ctx2.value.toString(ctx2.format),
|
|
843
|
+
areaValue: (ctx2) => {
|
|
844
|
+
const format = ctx2.format.startsWith("hsl") ? "hsla" : "hsba";
|
|
845
|
+
return ctx2.value.toFormat(format);
|
|
751
846
|
}
|
|
752
847
|
},
|
|
753
848
|
activities: ["trackFormControl"],
|
|
754
849
|
watch: {
|
|
755
850
|
value: ["syncInputElements"],
|
|
851
|
+
format: ["syncFormatSelectElement"],
|
|
756
852
|
open: ["toggleVisibility"]
|
|
757
853
|
},
|
|
758
854
|
on: {
|
|
759
855
|
"VALUE.SET": {
|
|
760
856
|
actions: ["setValue"]
|
|
761
857
|
},
|
|
858
|
+
"FORMAT.SET": {
|
|
859
|
+
actions: ["setFormat"]
|
|
860
|
+
},
|
|
762
861
|
"CHANNEL_INPUT.CHANGE": {
|
|
763
862
|
actions: ["setChannelColorFromInput"]
|
|
863
|
+
},
|
|
864
|
+
"EYEDROPPER.CLICK": {
|
|
865
|
+
actions: ["openEyeDropper"]
|
|
764
866
|
}
|
|
765
867
|
},
|
|
766
868
|
states: {
|
|
@@ -798,6 +900,9 @@ function machine(userContext) {
|
|
|
798
900
|
"CHANNEL_INPUT.BLUR": {
|
|
799
901
|
target: "idle",
|
|
800
902
|
actions: ["setChannelColorFromInput"]
|
|
903
|
+
},
|
|
904
|
+
"TRIGGER.BLUR": {
|
|
905
|
+
target: "idle"
|
|
801
906
|
}
|
|
802
907
|
}
|
|
803
908
|
},
|
|
@@ -809,9 +914,6 @@ function machine(userContext) {
|
|
|
809
914
|
target: "idle",
|
|
810
915
|
actions: ["invokeOnClose"]
|
|
811
916
|
},
|
|
812
|
-
"EYEDROPPER.CLICK": {
|
|
813
|
-
actions: ["openEyeDropper"]
|
|
814
|
-
},
|
|
815
917
|
"AREA.POINTER_DOWN": {
|
|
816
918
|
target: "open:dragging",
|
|
817
919
|
actions: ["setActiveChannel", "setAreaColorFromPoint", "focusAreaThumb"]
|
|
@@ -885,7 +987,17 @@ function machine(userContext) {
|
|
|
885
987
|
CLOSE: {
|
|
886
988
|
target: "idle",
|
|
887
989
|
actions: ["invokeOnClose"]
|
|
888
|
-
}
|
|
990
|
+
},
|
|
991
|
+
"SWATCH_TRIGGER.CLICK": [
|
|
992
|
+
{
|
|
993
|
+
guard: "closeOnSelect",
|
|
994
|
+
target: "focused",
|
|
995
|
+
actions: ["setValue", "setReturnFocus", "invokeOnClose"]
|
|
996
|
+
},
|
|
997
|
+
{
|
|
998
|
+
actions: ["setValue"]
|
|
999
|
+
}
|
|
1000
|
+
]
|
|
889
1001
|
}
|
|
890
1002
|
},
|
|
891
1003
|
"open:dragging": {
|
|
@@ -928,7 +1040,8 @@ function machine(userContext) {
|
|
|
928
1040
|
},
|
|
929
1041
|
{
|
|
930
1042
|
guards: {
|
|
931
|
-
isTargetFocusable: (_ctx, evt) => evt.restoreFocus
|
|
1043
|
+
isTargetFocusable: (_ctx, evt) => evt.restoreFocus,
|
|
1044
|
+
closeOnSelect: (ctx2) => !!ctx2.closeOnSelect
|
|
932
1045
|
},
|
|
933
1046
|
activities: {
|
|
934
1047
|
trackPositioning(ctx2) {
|
|
@@ -1023,9 +1136,9 @@ function machine(userContext) {
|
|
|
1023
1136
|
const percent = dom.getAreaValueFromPoint(ctx2, evt.point);
|
|
1024
1137
|
if (!percent)
|
|
1025
1138
|
return;
|
|
1026
|
-
const xValue = ctx2.
|
|
1027
|
-
const yValue = ctx2.
|
|
1028
|
-
const color = ctx2.
|
|
1139
|
+
const xValue = ctx2.areaValue.getChannelPercentValue(xChannel, percent.x);
|
|
1140
|
+
const yValue = ctx2.areaValue.getChannelPercentValue(yChannel, 1 - percent.y);
|
|
1141
|
+
const color = ctx2.areaValue.withChannelValue(xChannel, xValue).withChannelValue(yChannel, yValue);
|
|
1029
1142
|
set.value(ctx2, color);
|
|
1030
1143
|
},
|
|
1031
1144
|
setChannelColorFromPoint(ctx2, evt) {
|
|
@@ -1035,13 +1148,16 @@ function machine(userContext) {
|
|
|
1035
1148
|
return;
|
|
1036
1149
|
const orientation = ctx2.activeOrientation || "horizontal";
|
|
1037
1150
|
const channelPercent = orientation === "horizontal" ? percent.x : percent.y;
|
|
1038
|
-
const value = ctx2.
|
|
1039
|
-
const color = ctx2.
|
|
1151
|
+
const value = ctx2.areaValue.getChannelPercentValue(channel, channelPercent);
|
|
1152
|
+
const color = ctx2.areaValue.withChannelValue(channel, value);
|
|
1040
1153
|
set.value(ctx2, color);
|
|
1041
1154
|
},
|
|
1042
1155
|
setValue(ctx2, evt) {
|
|
1043
1156
|
set.value(ctx2, evt.value);
|
|
1044
1157
|
},
|
|
1158
|
+
setFormat(ctx2, evt) {
|
|
1159
|
+
set.format(ctx2, evt.format);
|
|
1160
|
+
},
|
|
1045
1161
|
syncInputElements(ctx2) {
|
|
1046
1162
|
sync.inputs(ctx2);
|
|
1047
1163
|
},
|
|
@@ -1051,26 +1167,22 @@ function machine(userContext) {
|
|
|
1051
1167
|
setChannelColorFromInput(ctx2, evt) {
|
|
1052
1168
|
const { channel, isTextField, value } = evt;
|
|
1053
1169
|
const currentAlpha = ctx2.value.getChannelValue("alpha");
|
|
1170
|
+
let color;
|
|
1054
1171
|
if (channel === "alpha") {
|
|
1055
1172
|
let valueAsNumber = parseFloat(value);
|
|
1056
1173
|
valueAsNumber = Number.isNaN(valueAsNumber) ? currentAlpha : valueAsNumber;
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
}
|
|
1061
|
-
if (isTextField) {
|
|
1062
|
-
const color2 = (0, import_utils2.tryCatch)(
|
|
1174
|
+
color = ctx2.value.withChannelValue("alpha", valueAsNumber);
|
|
1175
|
+
} else if (isTextField) {
|
|
1176
|
+
color = (0, import_utils2.tryCatch)(
|
|
1063
1177
|
() => parse(value).withChannelValue("alpha", currentAlpha),
|
|
1064
1178
|
() => ctx2.value
|
|
1065
1179
|
);
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
set.value(ctx2, color2);
|
|
1071
|
-
return;
|
|
1180
|
+
} else {
|
|
1181
|
+
const current = ctx2.value.toFormat(ctx2.format);
|
|
1182
|
+
const valueAsNumber = Number.isNaN(value) ? current.getChannelValue(channel) : value;
|
|
1183
|
+
color = current.withChannelValue(channel, valueAsNumber);
|
|
1072
1184
|
}
|
|
1073
|
-
|
|
1185
|
+
sync.inputs(ctx2, color);
|
|
1074
1186
|
set.value(ctx2, color);
|
|
1075
1187
|
},
|
|
1076
1188
|
incrementChannel(ctx2, evt) {
|
|
@@ -1083,22 +1195,22 @@ function machine(userContext) {
|
|
|
1083
1195
|
},
|
|
1084
1196
|
incrementXChannel(ctx2, evt) {
|
|
1085
1197
|
const { xChannel } = evt.channel;
|
|
1086
|
-
const color = ctx2.
|
|
1198
|
+
const color = ctx2.areaValue.incrementChannel(xChannel, evt.step);
|
|
1087
1199
|
set.value(ctx2, color);
|
|
1088
1200
|
},
|
|
1089
1201
|
decrementXChannel(ctx2, evt) {
|
|
1090
1202
|
const { xChannel } = evt.channel;
|
|
1091
|
-
const color = ctx2.
|
|
1203
|
+
const color = ctx2.areaValue.decrementChannel(xChannel, evt.step);
|
|
1092
1204
|
set.value(ctx2, color);
|
|
1093
1205
|
},
|
|
1094
1206
|
incrementYChannel(ctx2, evt) {
|
|
1095
1207
|
const { yChannel } = evt.channel;
|
|
1096
|
-
const color = ctx2.
|
|
1208
|
+
const color = ctx2.areaValue.incrementChannel(yChannel, evt.step);
|
|
1097
1209
|
set.value(ctx2, color);
|
|
1098
1210
|
},
|
|
1099
1211
|
decrementYChannel(ctx2, evt) {
|
|
1100
1212
|
const { yChannel } = evt.channel;
|
|
1101
|
-
const color = ctx2.
|
|
1213
|
+
const color = ctx2.areaValue.decrementChannel(yChannel, evt.step);
|
|
1102
1214
|
set.value(ctx2, color);
|
|
1103
1215
|
},
|
|
1104
1216
|
setChannelToMax(ctx2, evt) {
|
|
@@ -1131,6 +1243,9 @@ function machine(userContext) {
|
|
|
1131
1243
|
dom?.focus(ctx2, dom.getTriggerEl(ctx2));
|
|
1132
1244
|
});
|
|
1133
1245
|
},
|
|
1246
|
+
syncFormatSelectElement(ctx2) {
|
|
1247
|
+
sync.formatSelect(ctx2);
|
|
1248
|
+
},
|
|
1134
1249
|
invokeOnOpen(ctx2) {
|
|
1135
1250
|
ctx2.onOpenChange?.({ open: true });
|
|
1136
1251
|
},
|
|
@@ -1148,41 +1263,56 @@ function machine(userContext) {
|
|
|
1148
1263
|
);
|
|
1149
1264
|
}
|
|
1150
1265
|
var sync = {
|
|
1151
|
-
inputs
|
|
1266
|
+
// sync channel inputs
|
|
1267
|
+
inputs(ctx, color) {
|
|
1152
1268
|
const channelInputs = dom.getChannelInputEls(ctx);
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1269
|
+
(0, import_dom_query3.raf)(() => {
|
|
1270
|
+
channelInputs.forEach((inputEl) => {
|
|
1271
|
+
const channel = inputEl.dataset.channel;
|
|
1272
|
+
dom.setValue(inputEl, getChannelValue(color || ctx.value, channel));
|
|
1273
|
+
});
|
|
1274
|
+
});
|
|
1275
|
+
},
|
|
1276
|
+
// sync format select
|
|
1277
|
+
formatSelect(ctx) {
|
|
1278
|
+
const selectEl = dom.getFormatSelectEl(ctx);
|
|
1279
|
+
(0, import_dom_query3.raf)(() => {
|
|
1280
|
+
dom.setValue(selectEl, ctx.format);
|
|
1156
1281
|
});
|
|
1157
1282
|
}
|
|
1158
1283
|
};
|
|
1159
1284
|
var invoke = {
|
|
1160
1285
|
changeEnd(ctx) {
|
|
1286
|
+
const value = ctx.value.toFormat(ctx.format);
|
|
1161
1287
|
ctx.onValueChangeEnd?.({
|
|
1162
|
-
value
|
|
1288
|
+
value,
|
|
1163
1289
|
valueAsString: ctx.valueAsString
|
|
1164
1290
|
});
|
|
1165
1291
|
},
|
|
1166
1292
|
change(ctx) {
|
|
1293
|
+
const value = ctx.value.toFormat(ctx.format);
|
|
1167
1294
|
ctx.onValueChange?.({
|
|
1168
|
-
value
|
|
1295
|
+
value,
|
|
1169
1296
|
valueAsString: ctx.valueAsString
|
|
1170
1297
|
});
|
|
1171
1298
|
(0, import_form_utils.dispatchInputValueEvent)(dom.getHiddenInputEl(ctx), { value: ctx.valueAsString });
|
|
1299
|
+
},
|
|
1300
|
+
formatChange(ctx) {
|
|
1301
|
+
ctx.onFormatChange?.({ format: ctx.format });
|
|
1172
1302
|
}
|
|
1173
1303
|
};
|
|
1174
1304
|
var set = {
|
|
1175
1305
|
value(ctx, color) {
|
|
1176
1306
|
if (!color || ctx.value.isEqual(color))
|
|
1177
1307
|
return;
|
|
1178
|
-
|
|
1179
|
-
const outputColor = color.toFormat(currentFormat);
|
|
1180
|
-
try {
|
|
1181
|
-
outputColor.outputFormat = ctx.value.outputFormat;
|
|
1182
|
-
} catch {
|
|
1183
|
-
}
|
|
1184
|
-
ctx.value = outputColor;
|
|
1308
|
+
ctx.value = color;
|
|
1185
1309
|
invoke.change(ctx);
|
|
1310
|
+
},
|
|
1311
|
+
format(ctx, format) {
|
|
1312
|
+
if (ctx.format === format)
|
|
1313
|
+
return;
|
|
1314
|
+
ctx.format = format;
|
|
1315
|
+
invoke.formatChange(ctx);
|
|
1186
1316
|
}
|
|
1187
1317
|
};
|
|
1188
1318
|
// Annotate the CommonJS export names for ESM import in node:
|