@zag-js/color-picker 1.41.1 → 2.0.0-next.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/color-picker.anatomy.d.mts +2 -2
- package/dist/color-picker.anatomy.d.ts +2 -2
- package/dist/color-picker.anatomy.js +1 -0
- package/dist/color-picker.anatomy.mjs +1 -0
- package/dist/color-picker.connect.d.mts +1 -0
- package/dist/color-picker.connect.d.ts +1 -0
- package/dist/color-picker.connect.js +78 -42
- package/dist/color-picker.connect.mjs +79 -43
- package/dist/color-picker.dom.js +23 -22
- package/dist/color-picker.dom.mjs +23 -22
- package/dist/color-picker.machine.d.mts +1 -0
- package/dist/color-picker.machine.d.ts +1 -0
- package/dist/color-picker.machine.js +40 -17
- package/dist/color-picker.machine.mjs +40 -17
- package/dist/color-picker.props.d.mts +1 -0
- package/dist/color-picker.props.d.ts +1 -0
- package/dist/color-picker.types.d.mts +32 -1
- package/dist/color-picker.types.d.ts +32 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/utils/get-area-format.d.mts +6 -0
- package/dist/utils/get-area-format.d.ts +6 -0
- package/dist/utils/get-area-format.js +37 -0
- package/dist/utils/get-area-format.mjs +12 -0
- package/dist/utils/get-channel-display-color.js +7 -0
- package/dist/utils/get-channel-display-color.mjs +7 -0
- package/dist/utils/get-channel-input-value.d.mts +1 -0
- package/dist/utils/get-channel-input-value.d.ts +1 -0
- package/dist/utils/get-channel-input-value.js +39 -8
- package/dist/utils/get-channel-input-value.mjs +39 -8
- package/dist/utils/get-gamut-overlay-path.d.mts +33 -0
- package/dist/utils/get-gamut-overlay-path.d.ts +33 -0
- package/dist/utils/get-gamut-overlay-path.js +81 -0
- package/dist/utils/get-gamut-overlay-path.mjs +55 -0
- package/dist/utils/get-gamut-overlay-path.test.d.mts +2 -0
- package/dist/utils/get-gamut-overlay-path.test.d.ts +2 -0
- package/dist/utils/get-gamut-overlay-path.test.js +35 -0
- package/dist/utils/get-gamut-overlay-path.test.mjs +33 -0
- package/dist/utils/get-slider-background.d.mts +1 -0
- package/dist/utils/get-slider-background.d.ts +1 -0
- package/dist/utils/get-slider-background.js +16 -1
- package/dist/utils/get-slider-background.mjs +16 -1
- package/dist/utils/is-srgb-gamut.d.mts +6 -0
- package/dist/utils/is-srgb-gamut.d.ts +6 -0
- package/dist/utils/is-srgb-gamut.js +33 -0
- package/dist/utils/is-srgb-gamut.mjs +8 -0
- package/package.json +9 -9
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/color-picker.connect.ts
|
|
2
|
-
import { getColorAreaGradient, normalizeColor } from "@zag-js/color-utils";
|
|
2
|
+
import { getColorAreaGradient, isInSrgbGamut, normalizeColor } from "@zag-js/color-utils";
|
|
3
3
|
import { getEventKey, getEventPoint, getEventStep, isLeftClick, isModifierKey } from "@zag-js/dom-query";
|
|
4
4
|
import { dataAttr, query, visuallyHiddenStyle } from "@zag-js/dom-query";
|
|
5
5
|
import { getPlacementSide, getPlacementStyles } from "@zag-js/popper";
|
|
@@ -7,12 +7,14 @@ import { parts } from "./color-picker.anatomy.mjs";
|
|
|
7
7
|
import * as dom from "./color-picker.dom.mjs";
|
|
8
8
|
import { getChannelDisplayColor } from "./utils/get-channel-display-color.mjs";
|
|
9
9
|
import { getChannelRange, getChannelValue } from "./utils/get-channel-input-value.mjs";
|
|
10
|
+
import { getGamutOverlayData } from "./utils/get-gamut-overlay-path.mjs";
|
|
10
11
|
import { getSliderBackground } from "./utils/get-slider-background.mjs";
|
|
11
12
|
function connect(service, normalize) {
|
|
12
13
|
const { context, send, prop, computed, state, scope } = service;
|
|
13
14
|
const value = context.get("value");
|
|
14
15
|
const format = context.get("format");
|
|
15
16
|
const areaValue = computed("areaValue");
|
|
17
|
+
const stableAreaValue = context.get("areaBaseColor") ?? areaValue;
|
|
16
18
|
const valueAsString = computed("valueAsString");
|
|
17
19
|
const disabled = computed("disabled");
|
|
18
20
|
const readOnly = !!prop("readOnly");
|
|
@@ -29,11 +31,21 @@ function connect(service, normalize) {
|
|
|
29
31
|
yChannel: props.yChannel ?? channels[2]
|
|
30
32
|
};
|
|
31
33
|
};
|
|
34
|
+
function getDefaultDevicePixelRatio() {
|
|
35
|
+
if (typeof globalThis === "undefined") return 1;
|
|
36
|
+
const dpr = globalThis.devicePixelRatio;
|
|
37
|
+
return typeof dpr === "number" && Number.isFinite(dpr) ? dpr : 1;
|
|
38
|
+
}
|
|
39
|
+
function resolveGamutOverlay(props = {}) {
|
|
40
|
+
const pixelRatio = props.pixelRatio ?? getDefaultDevicePixelRatio();
|
|
41
|
+
return getGamutOverlayData(stableAreaValue, getAreaChannels(props), format, { pixelRatio });
|
|
42
|
+
}
|
|
32
43
|
const currentPlacement = context.get("currentPlacement");
|
|
33
44
|
const currentPlacementSide = currentPlacement ? getPlacementSide(currentPlacement) : void 0;
|
|
34
45
|
const popperStyles = getPlacementStyles({
|
|
35
46
|
...prop("positioning"),
|
|
36
|
-
placement: currentPlacement
|
|
47
|
+
placement: currentPlacement,
|
|
48
|
+
positioned: context.get("positioned")
|
|
37
49
|
});
|
|
38
50
|
function getSwatchTriggerState(props) {
|
|
39
51
|
const color = normalizeColor(props.value).toFormat(context.get("format"));
|
|
@@ -49,6 +61,10 @@ function connect(service, normalize) {
|
|
|
49
61
|
open,
|
|
50
62
|
valueAsString,
|
|
51
63
|
value,
|
|
64
|
+
isInSrgbGamut: isInSrgbGamut(value),
|
|
65
|
+
getGamutOverlay(props = {}) {
|
|
66
|
+
return resolveGamutOverlay(props);
|
|
67
|
+
},
|
|
52
68
|
inline: !!prop("inline"),
|
|
53
69
|
setOpen(nextOpen) {
|
|
54
70
|
if (prop("inline")) return;
|
|
@@ -70,9 +86,8 @@ function connect(service, normalize) {
|
|
|
70
86
|
send({ type: "VALUE.SET", value: color, src: "set-channel" });
|
|
71
87
|
},
|
|
72
88
|
format: context.get("format"),
|
|
73
|
-
setFormat(
|
|
74
|
-
|
|
75
|
-
send({ type: "VALUE.SET", value: formatValue, src: "set-format" });
|
|
89
|
+
setFormat(nextFormat) {
|
|
90
|
+
send({ type: "FORMAT.SET", format: nextFormat, src: "set-format" });
|
|
76
91
|
},
|
|
77
92
|
alpha: value.getChannelValue("alpha"),
|
|
78
93
|
setAlpha(alphaValue) {
|
|
@@ -81,9 +96,8 @@ function connect(service, normalize) {
|
|
|
81
96
|
},
|
|
82
97
|
getRootProps() {
|
|
83
98
|
return normalize.element({
|
|
84
|
-
...parts.root.attrs,
|
|
99
|
+
...parts.root.attrs(scope.id),
|
|
85
100
|
dir: prop("dir"),
|
|
86
|
-
id: dom.getRootId(scope),
|
|
87
101
|
"data-disabled": dataAttr(disabled),
|
|
88
102
|
"data-readonly": dataAttr(readOnly),
|
|
89
103
|
"data-invalid": dataAttr(invalid),
|
|
@@ -94,7 +108,7 @@ function connect(service, normalize) {
|
|
|
94
108
|
},
|
|
95
109
|
getLabelProps() {
|
|
96
110
|
return normalize.element({
|
|
97
|
-
...parts.label.attrs,
|
|
111
|
+
...parts.label.attrs(scope.id),
|
|
98
112
|
dir: prop("dir"),
|
|
99
113
|
id: dom.getLabelId(scope),
|
|
100
114
|
htmlFor: dom.getHiddenInputId(scope),
|
|
@@ -112,8 +126,7 @@ function connect(service, normalize) {
|
|
|
112
126
|
},
|
|
113
127
|
getControlProps() {
|
|
114
128
|
return normalize.element({
|
|
115
|
-
...parts.control.attrs,
|
|
116
|
-
id: dom.getControlId(scope),
|
|
129
|
+
...parts.control.attrs(scope.id),
|
|
117
130
|
dir: prop("dir"),
|
|
118
131
|
"data-disabled": dataAttr(disabled),
|
|
119
132
|
"data-readonly": dataAttr(readOnly),
|
|
@@ -124,7 +137,7 @@ function connect(service, normalize) {
|
|
|
124
137
|
},
|
|
125
138
|
getTriggerProps() {
|
|
126
139
|
return normalize.button({
|
|
127
|
-
...parts.trigger.attrs,
|
|
140
|
+
...parts.trigger.attrs(scope.id),
|
|
128
141
|
id: dom.getTriggerId(scope),
|
|
129
142
|
dir: prop("dir"),
|
|
130
143
|
disabled,
|
|
@@ -156,15 +169,14 @@ function connect(service, normalize) {
|
|
|
156
169
|
},
|
|
157
170
|
getPositionerProps() {
|
|
158
171
|
return normalize.element({
|
|
159
|
-
...parts.positioner.attrs,
|
|
160
|
-
id: dom.getPositionerId(scope),
|
|
172
|
+
...parts.positioner.attrs(scope.id),
|
|
161
173
|
dir: prop("dir"),
|
|
162
174
|
style: popperStyles.floating
|
|
163
175
|
});
|
|
164
176
|
},
|
|
165
177
|
getContentProps() {
|
|
166
178
|
return normalize.element({
|
|
167
|
-
...parts.content.attrs,
|
|
179
|
+
...parts.content.attrs(scope.id),
|
|
168
180
|
id: dom.getContentId(scope),
|
|
169
181
|
dir: prop("dir"),
|
|
170
182
|
role: prop("inline") ? void 0 : "dialog",
|
|
@@ -177,7 +189,7 @@ function connect(service, normalize) {
|
|
|
177
189
|
},
|
|
178
190
|
getValueTextProps() {
|
|
179
191
|
return normalize.element({
|
|
180
|
-
...parts.valueText.attrs,
|
|
192
|
+
...parts.valueText.attrs(scope.id),
|
|
181
193
|
dir: prop("dir"),
|
|
182
194
|
"data-disabled": dataAttr(disabled),
|
|
183
195
|
"data-focus": dataAttr(focused)
|
|
@@ -185,14 +197,13 @@ function connect(service, normalize) {
|
|
|
185
197
|
},
|
|
186
198
|
getAreaProps(props = {}) {
|
|
187
199
|
const { xChannel, yChannel } = getAreaChannels(props);
|
|
188
|
-
const { areaStyles } = getColorAreaGradient(
|
|
200
|
+
const { areaStyles } = getColorAreaGradient(stableAreaValue, {
|
|
189
201
|
xChannel,
|
|
190
202
|
yChannel,
|
|
191
203
|
dir: prop("dir")
|
|
192
204
|
});
|
|
193
205
|
return normalize.element({
|
|
194
|
-
...parts.area.attrs,
|
|
195
|
-
id: dom.getAreaId(scope),
|
|
206
|
+
...parts.area.attrs(scope.id),
|
|
196
207
|
role: "group",
|
|
197
208
|
"data-invalid": dataAttr(invalid),
|
|
198
209
|
"data-disabled": dataAttr(disabled),
|
|
@@ -216,14 +227,13 @@ function connect(service, normalize) {
|
|
|
216
227
|
},
|
|
217
228
|
getAreaBackgroundProps(props = {}) {
|
|
218
229
|
const { xChannel, yChannel } = getAreaChannels(props);
|
|
219
|
-
const { areaGradientStyles } = getColorAreaGradient(
|
|
230
|
+
const { areaGradientStyles } = getColorAreaGradient(stableAreaValue, {
|
|
220
231
|
xChannel,
|
|
221
232
|
yChannel,
|
|
222
233
|
dir: prop("dir")
|
|
223
234
|
});
|
|
224
235
|
return normalize.element({
|
|
225
|
-
...parts.areaBackground.attrs,
|
|
226
|
-
id: dom.getAreaGradientId(scope),
|
|
236
|
+
...parts.areaBackground.attrs(scope.id),
|
|
227
237
|
"data-invalid": dataAttr(invalid),
|
|
228
238
|
"data-disabled": dataAttr(disabled),
|
|
229
239
|
"data-readonly": dataAttr(readOnly),
|
|
@@ -235,18 +245,45 @@ function connect(service, normalize) {
|
|
|
235
245
|
}
|
|
236
246
|
});
|
|
237
247
|
},
|
|
248
|
+
getGamutOverlayProps(props = {}) {
|
|
249
|
+
const data = resolveGamutOverlay(props);
|
|
250
|
+
return normalize.element({
|
|
251
|
+
...parts.gamutOverlay.attrs(scope.id),
|
|
252
|
+
viewBox: "0 0 100 100",
|
|
253
|
+
preserveAspectRatio: "none",
|
|
254
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
255
|
+
"aria-hidden": true,
|
|
256
|
+
"data-state": data ? "visible" : "hidden",
|
|
257
|
+
style: {
|
|
258
|
+
position: "absolute",
|
|
259
|
+
inset: "0",
|
|
260
|
+
width: "100%",
|
|
261
|
+
height: "100%",
|
|
262
|
+
overflow: "hidden",
|
|
263
|
+
pointerEvents: "none"
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
},
|
|
238
267
|
getAreaThumbProps(props = {}) {
|
|
239
268
|
const { xChannel, yChannel } = getAreaChannels(props);
|
|
240
269
|
const channel = { xChannel, yChannel };
|
|
241
|
-
const
|
|
242
|
-
const yPercent = 1 - areaValue.getChannelValuePercent(yChannel);
|
|
270
|
+
const dragPos = context.get("areaDragPosition");
|
|
243
271
|
const isRtl = prop("dir") === "rtl";
|
|
272
|
+
let xPercent;
|
|
273
|
+
let yPercent;
|
|
274
|
+
if (dragPos) {
|
|
275
|
+
xPercent = dragPos.x;
|
|
276
|
+
yPercent = dragPos.y;
|
|
277
|
+
} else {
|
|
278
|
+
xPercent = areaValue.getChannelValuePercent(xChannel);
|
|
279
|
+
yPercent = 1 - areaValue.getChannelValuePercent(yChannel);
|
|
280
|
+
}
|
|
244
281
|
const finalXPercent = isRtl ? 1 - xPercent : xPercent;
|
|
245
282
|
const xValue = areaValue.getChannelValue(xChannel);
|
|
246
283
|
const yValue = areaValue.getChannelValue(yChannel);
|
|
247
284
|
const color = areaValue.withChannelValue("alpha", 1).toString("css");
|
|
248
285
|
return normalize.element({
|
|
249
|
-
...parts.areaThumb.attrs,
|
|
286
|
+
...parts.areaThumb.attrs(scope.id),
|
|
250
287
|
id: dom.getAreaThumbId(scope),
|
|
251
288
|
dir: prop("dir"),
|
|
252
289
|
tabIndex: disabled ? void 0 : 0,
|
|
@@ -314,7 +351,7 @@ function connect(service, normalize) {
|
|
|
314
351
|
getTransparencyGridProps(props = {}) {
|
|
315
352
|
const { size = "12px" } = props;
|
|
316
353
|
return normalize.element({
|
|
317
|
-
...parts.transparencyGrid.attrs,
|
|
354
|
+
...parts.transparencyGrid.attrs(scope.id),
|
|
318
355
|
style: {
|
|
319
356
|
"--size": size,
|
|
320
357
|
width: "100%",
|
|
@@ -332,7 +369,7 @@ function connect(service, normalize) {
|
|
|
332
369
|
getChannelSliderProps(props) {
|
|
333
370
|
const { orientation = "horizontal", channel, format: format2 } = props;
|
|
334
371
|
return normalize.element({
|
|
335
|
-
...parts.channelSlider.attrs,
|
|
372
|
+
...parts.channelSlider.attrs(scope.id),
|
|
336
373
|
"data-channel": channel,
|
|
337
374
|
"data-orientation": orientation,
|
|
338
375
|
role: "presentation",
|
|
@@ -352,10 +389,9 @@ function connect(service, normalize) {
|
|
|
352
389
|
},
|
|
353
390
|
getChannelSliderTrackProps(props) {
|
|
354
391
|
const { orientation = "horizontal", channel, format: format2 } = props;
|
|
355
|
-
const normalizedValue = format2 ? value.toFormat(format2) :
|
|
392
|
+
const normalizedValue = format2 ? value.toFormat(format2) : stableAreaValue;
|
|
356
393
|
return normalize.element({
|
|
357
|
-
...parts.channelSliderTrack.attrs,
|
|
358
|
-
id: dom.getChannelSliderTrackId(scope, channel),
|
|
394
|
+
...parts.channelSliderTrack.attrs(scope.id),
|
|
359
395
|
role: "group",
|
|
360
396
|
"data-channel": channel,
|
|
361
397
|
"data-orientation": orientation,
|
|
@@ -374,7 +410,7 @@ function connect(service, normalize) {
|
|
|
374
410
|
getChannelSliderLabelProps(props) {
|
|
375
411
|
const { channel } = props;
|
|
376
412
|
return normalize.element({
|
|
377
|
-
...parts.channelSliderLabel.attrs,
|
|
413
|
+
...parts.channelSliderLabel.attrs(scope.id),
|
|
378
414
|
"data-channel": channel,
|
|
379
415
|
onClick(event) {
|
|
380
416
|
if (!interactive) return;
|
|
@@ -390,13 +426,13 @@ function connect(service, normalize) {
|
|
|
390
426
|
},
|
|
391
427
|
getChannelSliderValueTextProps(props) {
|
|
392
428
|
return normalize.element({
|
|
393
|
-
...parts.channelSliderValueText.attrs,
|
|
429
|
+
...parts.channelSliderValueText.attrs(scope.id),
|
|
394
430
|
"data-channel": props.channel
|
|
395
431
|
});
|
|
396
432
|
},
|
|
397
433
|
getChannelSliderThumbProps(props) {
|
|
398
434
|
const { orientation = "horizontal", channel, format: format2 } = props;
|
|
399
|
-
const normalizedValue = format2 ? value.toFormat(format2) :
|
|
435
|
+
const normalizedValue = format2 ? value.toFormat(format2) : stableAreaValue;
|
|
400
436
|
const channelRange = normalizedValue.getChannelRange(channel);
|
|
401
437
|
const channelValue = normalizedValue.getChannelValue(channel);
|
|
402
438
|
const offset = (channelValue - channelRange.minValue) / (channelRange.maxValue - channelRange.minValue);
|
|
@@ -404,7 +440,7 @@ function connect(service, normalize) {
|
|
|
404
440
|
const finalOffset = orientation === "horizontal" && isRtl ? 1 - offset : offset;
|
|
405
441
|
const placementStyles = orientation === "horizontal" ? { left: `${finalOffset * 100}%`, top: "50%" } : { top: `${offset * 100}%`, left: "50%" };
|
|
406
442
|
return normalize.element({
|
|
407
|
-
...parts.channelSliderThumb.attrs,
|
|
443
|
+
...parts.channelSliderThumb.attrs(scope.id),
|
|
408
444
|
id: dom.getChannelSliderThumbId(scope, channel),
|
|
409
445
|
role: "slider",
|
|
410
446
|
"aria-label": channel,
|
|
@@ -421,7 +457,7 @@ function connect(service, normalize) {
|
|
|
421
457
|
style: {
|
|
422
458
|
forcedColorAdjust: "none",
|
|
423
459
|
position: "absolute",
|
|
424
|
-
background: getChannelDisplayColor(
|
|
460
|
+
background: getChannelDisplayColor(stableAreaValue, channel).toString("css"),
|
|
425
461
|
...placementStyles
|
|
426
462
|
},
|
|
427
463
|
onFocus() {
|
|
@@ -476,7 +512,7 @@ function connect(service, normalize) {
|
|
|
476
512
|
const isTextField = channel === "hex" || channel === "css";
|
|
477
513
|
const channelRange = getChannelRange(value, channel);
|
|
478
514
|
return normalize.input({
|
|
479
|
-
...parts.channelInput.attrs,
|
|
515
|
+
...parts.channelInput.attrs(scope.id),
|
|
480
516
|
dir: prop("dir"),
|
|
481
517
|
type: isTextField ? "text" : "number",
|
|
482
518
|
"data-channel": channel,
|
|
@@ -540,7 +576,7 @@ function connect(service, normalize) {
|
|
|
540
576
|
},
|
|
541
577
|
getEyeDropperTriggerProps() {
|
|
542
578
|
return normalize.button({
|
|
543
|
-
...parts.eyeDropperTrigger.attrs,
|
|
579
|
+
...parts.eyeDropperTrigger.attrs(scope.id),
|
|
544
580
|
type: "button",
|
|
545
581
|
dir: prop("dir"),
|
|
546
582
|
disabled,
|
|
@@ -556,7 +592,7 @@ function connect(service, normalize) {
|
|
|
556
592
|
},
|
|
557
593
|
getSwatchGroupProps() {
|
|
558
594
|
return normalize.element({
|
|
559
|
-
...parts.swatchGroup.attrs,
|
|
595
|
+
...parts.swatchGroup.attrs(scope.id),
|
|
560
596
|
role: "group"
|
|
561
597
|
});
|
|
562
598
|
},
|
|
@@ -564,7 +600,7 @@ function connect(service, normalize) {
|
|
|
564
600
|
getSwatchTriggerProps(props) {
|
|
565
601
|
const swatchState = getSwatchTriggerState(props);
|
|
566
602
|
return normalize.button({
|
|
567
|
-
...parts.swatchTrigger.attrs,
|
|
603
|
+
...parts.swatchTrigger.attrs(scope.id),
|
|
568
604
|
disabled: swatchState.disabled,
|
|
569
605
|
dir: prop("dir"),
|
|
570
606
|
type: "button",
|
|
@@ -585,7 +621,7 @@ function connect(service, normalize) {
|
|
|
585
621
|
getSwatchIndicatorProps(props) {
|
|
586
622
|
const swatchState = getSwatchTriggerState(props);
|
|
587
623
|
return normalize.element({
|
|
588
|
-
...parts.swatchIndicator.attrs,
|
|
624
|
+
...parts.swatchIndicator.attrs(scope.id),
|
|
589
625
|
dir: prop("dir"),
|
|
590
626
|
hidden: !swatchState.checked
|
|
591
627
|
});
|
|
@@ -595,7 +631,7 @@ function connect(service, normalize) {
|
|
|
595
631
|
const swatchState = getSwatchTriggerState(props);
|
|
596
632
|
const color = swatchState.value.toString(respectAlpha ? "css" : "hex");
|
|
597
633
|
return normalize.element({
|
|
598
|
-
...parts.swatch.attrs,
|
|
634
|
+
...parts.swatch.attrs(scope.id),
|
|
599
635
|
dir: prop("dir"),
|
|
600
636
|
"data-state": swatchState.checked ? "checked" : "unchecked",
|
|
601
637
|
"data-value": swatchState.valueAsString,
|
|
@@ -608,7 +644,7 @@ function connect(service, normalize) {
|
|
|
608
644
|
},
|
|
609
645
|
getFormatTriggerProps() {
|
|
610
646
|
return normalize.button({
|
|
611
|
-
...parts.formatTrigger.attrs,
|
|
647
|
+
...parts.formatTrigger.attrs(scope.id),
|
|
612
648
|
dir: prop("dir"),
|
|
613
649
|
type: "button",
|
|
614
650
|
"aria-label": `change color format to ${getNextFormat(format)}`,
|
|
@@ -621,7 +657,7 @@ function connect(service, normalize) {
|
|
|
621
657
|
},
|
|
622
658
|
getFormatSelectProps() {
|
|
623
659
|
return normalize.select({
|
|
624
|
-
...parts.formatSelect.attrs,
|
|
660
|
+
...parts.formatSelect.attrs(scope.id),
|
|
625
661
|
"aria-label": "change color format",
|
|
626
662
|
dir: prop("dir"),
|
|
627
663
|
defaultValue: prop("format"),
|
|
@@ -634,7 +670,7 @@ function connect(service, normalize) {
|
|
|
634
670
|
}
|
|
635
671
|
};
|
|
636
672
|
}
|
|
637
|
-
var formats = ["hsba", "hsla", "rgba"];
|
|
673
|
+
var formats = ["hsba", "hsla", "rgba", "oklab", "oklch"];
|
|
638
674
|
var formatRegex = new RegExp(`^(${formats.join("|")})$`);
|
|
639
675
|
function getNextFormat(format) {
|
|
640
676
|
const index = formats.indexOf(format);
|
package/dist/color-picker.dom.js
CHANGED
|
@@ -50,22 +50,23 @@ __export(color_picker_dom_exports, {
|
|
|
50
50
|
});
|
|
51
51
|
module.exports = __toCommonJS(color_picker_dom_exports);
|
|
52
52
|
var import_dom_query = require("@zag-js/dom-query");
|
|
53
|
-
var
|
|
54
|
-
var
|
|
55
|
-
var
|
|
56
|
-
var
|
|
57
|
-
var
|
|
58
|
-
var
|
|
59
|
-
var
|
|
60
|
-
var
|
|
61
|
-
var
|
|
62
|
-
var
|
|
63
|
-
var
|
|
64
|
-
var
|
|
65
|
-
var
|
|
66
|
-
var
|
|
67
|
-
var
|
|
68
|
-
var
|
|
53
|
+
var import_color_picker = require("./color-picker.anatomy.js");
|
|
54
|
+
var getRootId = (ctx) => ctx.ids?.root ?? `${ctx.id}`;
|
|
55
|
+
var getLabelId = (ctx) => ctx.ids?.label ?? `${ctx.id}:label`;
|
|
56
|
+
var getHiddenInputId = (ctx) => ctx.ids?.hiddenInput ?? `${ctx.id}:hidden-input`;
|
|
57
|
+
var getControlId = (ctx) => ctx.ids?.control ?? `${ctx.id}:control`;
|
|
58
|
+
var getTriggerId = (ctx) => ctx.ids?.trigger ?? `${ctx.id}:trigger`;
|
|
59
|
+
var getContentId = (ctx) => ctx.ids?.content ?? `${ctx.id}:content`;
|
|
60
|
+
var getPositionerId = (ctx) => ctx.ids?.positioner ?? `${ctx.id}:positioner`;
|
|
61
|
+
var getFormatSelectId = (ctx) => ctx.ids?.formatSelect ?? `${ctx.id}:format-select`;
|
|
62
|
+
var getAreaId = (ctx) => ctx.ids?.area ?? `${ctx.id}:area`;
|
|
63
|
+
var getAreaGradientId = (ctx) => ctx.ids?.areaGradient ?? `${ctx.id}:area-gradient`;
|
|
64
|
+
var getAreaThumbId = (ctx) => ctx.ids?.areaThumb ?? `${ctx.id}:area-thumb`;
|
|
65
|
+
var getChannelSliderTrackId = (ctx, channel) => ctx.ids?.channelSliderTrack?.(channel) ?? `${ctx.id}:slider-track:${channel}`;
|
|
66
|
+
var getChannelSliderThumbId = (ctx, channel) => ctx.ids?.channelSliderThumb?.(channel) ?? `${ctx.id}:slider-thumb:${channel}`;
|
|
67
|
+
var getContentEl = (ctx) => ctx.query(ctx.selector(import_color_picker.parts.content));
|
|
68
|
+
var getAreaThumbEl = (ctx) => ctx.query(ctx.selector(import_color_picker.parts.areaThumb));
|
|
69
|
+
var getChannelSliderThumbEl = (ctx, channel) => ctx.query(`${ctx.selector(import_color_picker.parts.channelSliderThumb)}[data-channel="${channel}"]`);
|
|
69
70
|
var getChannelInputEl = (ctx, channel) => {
|
|
70
71
|
const selector = `input[data-channel="${channel}"]`;
|
|
71
72
|
return [
|
|
@@ -73,9 +74,9 @@ var getChannelInputEl = (ctx, channel) => {
|
|
|
73
74
|
...(0, import_dom_query.queryAll)(getControlEl(ctx), selector)
|
|
74
75
|
];
|
|
75
76
|
};
|
|
76
|
-
var getFormatSelectEl = (ctx) => ctx.
|
|
77
|
+
var getFormatSelectEl = (ctx) => ctx.query(ctx.selector(import_color_picker.parts.formatSelect));
|
|
77
78
|
var getHiddenInputEl = (ctx) => ctx.getById(getHiddenInputId(ctx));
|
|
78
|
-
var getAreaEl = (ctx) => ctx.
|
|
79
|
+
var getAreaEl = (ctx) => ctx.query(ctx.selector(import_color_picker.parts.area));
|
|
79
80
|
var getAreaValueFromPoint = (ctx, point, dir) => {
|
|
80
81
|
const areaEl = getAreaEl(ctx);
|
|
81
82
|
if (!areaEl) return;
|
|
@@ -85,10 +86,10 @@ var getAreaValueFromPoint = (ctx, point, dir) => {
|
|
|
85
86
|
y: getPercentValue({ orientation: "vertical" })
|
|
86
87
|
};
|
|
87
88
|
};
|
|
88
|
-
var getControlEl = (ctx) => ctx.
|
|
89
|
-
var getTriggerEl = (ctx) => ctx.
|
|
90
|
-
var getPositionerEl = (ctx) => ctx.
|
|
91
|
-
var getChannelSliderTrackEl = (ctx, channel) => ctx.
|
|
89
|
+
var getControlEl = (ctx) => ctx.query(ctx.selector(import_color_picker.parts.control));
|
|
90
|
+
var getTriggerEl = (ctx) => ctx.query(ctx.selector(import_color_picker.parts.trigger));
|
|
91
|
+
var getPositionerEl = (ctx) => ctx.query(ctx.selector(import_color_picker.parts.positioner));
|
|
92
|
+
var getChannelSliderTrackEl = (ctx, channel) => ctx.query(`${ctx.selector(import_color_picker.parts.channelSliderTrack)}[data-channel="${channel}"]`);
|
|
92
93
|
var getChannelSliderValueFromPoint = (ctx, point, channel, dir) => {
|
|
93
94
|
const trackEl = getChannelSliderTrackEl(ctx, channel);
|
|
94
95
|
if (!trackEl) return;
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
// src/color-picker.dom.ts
|
|
2
2
|
import { getRelativePoint, queryAll } from "@zag-js/dom-query";
|
|
3
|
-
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var
|
|
10
|
-
var
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
var
|
|
15
|
-
var
|
|
16
|
-
var
|
|
17
|
-
var
|
|
18
|
-
var
|
|
3
|
+
import { parts } from "./color-picker.anatomy.mjs";
|
|
4
|
+
var getRootId = (ctx) => ctx.ids?.root ?? `${ctx.id}`;
|
|
5
|
+
var getLabelId = (ctx) => ctx.ids?.label ?? `${ctx.id}:label`;
|
|
6
|
+
var getHiddenInputId = (ctx) => ctx.ids?.hiddenInput ?? `${ctx.id}:hidden-input`;
|
|
7
|
+
var getControlId = (ctx) => ctx.ids?.control ?? `${ctx.id}:control`;
|
|
8
|
+
var getTriggerId = (ctx) => ctx.ids?.trigger ?? `${ctx.id}:trigger`;
|
|
9
|
+
var getContentId = (ctx) => ctx.ids?.content ?? `${ctx.id}:content`;
|
|
10
|
+
var getPositionerId = (ctx) => ctx.ids?.positioner ?? `${ctx.id}:positioner`;
|
|
11
|
+
var getFormatSelectId = (ctx) => ctx.ids?.formatSelect ?? `${ctx.id}:format-select`;
|
|
12
|
+
var getAreaId = (ctx) => ctx.ids?.area ?? `${ctx.id}:area`;
|
|
13
|
+
var getAreaGradientId = (ctx) => ctx.ids?.areaGradient ?? `${ctx.id}:area-gradient`;
|
|
14
|
+
var getAreaThumbId = (ctx) => ctx.ids?.areaThumb ?? `${ctx.id}:area-thumb`;
|
|
15
|
+
var getChannelSliderTrackId = (ctx, channel) => ctx.ids?.channelSliderTrack?.(channel) ?? `${ctx.id}:slider-track:${channel}`;
|
|
16
|
+
var getChannelSliderThumbId = (ctx, channel) => ctx.ids?.channelSliderThumb?.(channel) ?? `${ctx.id}:slider-thumb:${channel}`;
|
|
17
|
+
var getContentEl = (ctx) => ctx.query(ctx.selector(parts.content));
|
|
18
|
+
var getAreaThumbEl = (ctx) => ctx.query(ctx.selector(parts.areaThumb));
|
|
19
|
+
var getChannelSliderThumbEl = (ctx, channel) => ctx.query(`${ctx.selector(parts.channelSliderThumb)}[data-channel="${channel}"]`);
|
|
19
20
|
var getChannelInputEl = (ctx, channel) => {
|
|
20
21
|
const selector = `input[data-channel="${channel}"]`;
|
|
21
22
|
return [
|
|
@@ -23,9 +24,9 @@ var getChannelInputEl = (ctx, channel) => {
|
|
|
23
24
|
...queryAll(getControlEl(ctx), selector)
|
|
24
25
|
];
|
|
25
26
|
};
|
|
26
|
-
var getFormatSelectEl = (ctx) => ctx.
|
|
27
|
+
var getFormatSelectEl = (ctx) => ctx.query(ctx.selector(parts.formatSelect));
|
|
27
28
|
var getHiddenInputEl = (ctx) => ctx.getById(getHiddenInputId(ctx));
|
|
28
|
-
var getAreaEl = (ctx) => ctx.
|
|
29
|
+
var getAreaEl = (ctx) => ctx.query(ctx.selector(parts.area));
|
|
29
30
|
var getAreaValueFromPoint = (ctx, point, dir) => {
|
|
30
31
|
const areaEl = getAreaEl(ctx);
|
|
31
32
|
if (!areaEl) return;
|
|
@@ -35,10 +36,10 @@ var getAreaValueFromPoint = (ctx, point, dir) => {
|
|
|
35
36
|
y: getPercentValue({ orientation: "vertical" })
|
|
36
37
|
};
|
|
37
38
|
};
|
|
38
|
-
var getControlEl = (ctx) => ctx.
|
|
39
|
-
var getTriggerEl = (ctx) => ctx.
|
|
40
|
-
var getPositionerEl = (ctx) => ctx.
|
|
41
|
-
var getChannelSliderTrackEl = (ctx, channel) => ctx.
|
|
39
|
+
var getControlEl = (ctx) => ctx.query(ctx.selector(parts.control));
|
|
40
|
+
var getTriggerEl = (ctx) => ctx.query(ctx.selector(parts.trigger));
|
|
41
|
+
var getPositionerEl = (ctx) => ctx.query(ctx.selector(parts.positioner));
|
|
42
|
+
var getChannelSliderTrackEl = (ctx, channel) => ctx.query(`${ctx.selector(parts.channelSliderTrack)}[data-channel="${channel}"]`);
|
|
42
43
|
var getChannelSliderValueFromPoint = (ctx, point, channel, dir) => {
|
|
43
44
|
const trackEl = getChannelSliderTrackEl(ctx, channel);
|
|
44
45
|
if (!trackEl) return;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as _zag_js_core from '@zag-js/core';
|
|
2
2
|
import { ColorPickerSchema } from './color-picker.types.mjs';
|
|
3
3
|
import '@zag-js/color-utils';
|
|
4
|
+
import './utils/get-gamut-overlay-path.mjs';
|
|
4
5
|
import '@zag-js/dismissable';
|
|
5
6
|
import '@zag-js/popper';
|
|
6
7
|
import '@zag-js/types';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as _zag_js_core from '@zag-js/core';
|
|
2
2
|
import { ColorPickerSchema } from './color-picker.types.js';
|
|
3
3
|
import '@zag-js/color-utils';
|
|
4
|
+
import './utils/get-gamut-overlay-path.js';
|
|
4
5
|
import '@zag-js/dismissable';
|
|
5
6
|
import '@zag-js/popper';
|
|
6
7
|
import '@zag-js/types';
|
|
@@ -41,6 +41,7 @@ var import_popper = require("@zag-js/popper");
|
|
|
41
41
|
var import_utils = require("@zag-js/utils");
|
|
42
42
|
var dom = __toESM(require("./color-picker.dom.js"));
|
|
43
43
|
var import_color_picker = require("./color-picker.parse.js");
|
|
44
|
+
var import_get_area_format = require("./utils/get-area-format.js");
|
|
44
45
|
var import_get_channel_input_value = require("./utils/get-channel-input-value.js");
|
|
45
46
|
var import_is_valid_hex = require("./utils/is-valid-hex.js");
|
|
46
47
|
var { and } = (0, import_core.createGuards)();
|
|
@@ -96,11 +97,14 @@ var machine = (0, import_core.createMachine)({
|
|
|
96
97
|
activeId: bindable(() => ({ defaultValue: null })),
|
|
97
98
|
activeChannel: bindable(() => ({ defaultValue: null })),
|
|
98
99
|
activeOrientation: bindable(() => ({ defaultValue: null })),
|
|
100
|
+
areaBaseColor: bindable(() => ({ defaultValue: null })),
|
|
101
|
+
areaDragPosition: bindable(() => ({ defaultValue: null })),
|
|
99
102
|
fieldsetDisabled: bindable(() => ({ defaultValue: false })),
|
|
100
103
|
restoreFocus: bindable(() => ({ defaultValue: true })),
|
|
101
104
|
currentPlacement: bindable(() => ({
|
|
102
105
|
defaultValue: void 0
|
|
103
|
-
}))
|
|
106
|
+
})),
|
|
107
|
+
positioned: bindable(() => ({ defaultValue: false }))
|
|
104
108
|
};
|
|
105
109
|
},
|
|
106
110
|
computed: {
|
|
@@ -109,8 +113,7 @@ var machine = (0, import_core.createMachine)({
|
|
|
109
113
|
interactive: ({ prop }) => !(prop("disabled") || prop("readOnly")),
|
|
110
114
|
valueAsString: ({ context }) => context.get("value").toString(context.get("format")),
|
|
111
115
|
areaValue: ({ context }) => {
|
|
112
|
-
|
|
113
|
-
return context.get("value").toFormat(format);
|
|
116
|
+
return context.get("value").toFormat((0, import_get_area_format.getAreaFormat)(context.get("format")));
|
|
114
117
|
}
|
|
115
118
|
},
|
|
116
119
|
effects: ["trackFormControl"],
|
|
@@ -388,6 +391,7 @@ var machine = (0, import_core.createMachine)({
|
|
|
388
391
|
defer: true,
|
|
389
392
|
onComplete(data) {
|
|
390
393
|
context.set("currentPlacement", data.placement);
|
|
394
|
+
context.set("positioned", true);
|
|
391
395
|
}
|
|
392
396
|
});
|
|
393
397
|
},
|
|
@@ -458,36 +462,47 @@ var machine = (0, import_core.createMachine)({
|
|
|
458
462
|
});
|
|
459
463
|
}).catch(() => void 0);
|
|
460
464
|
},
|
|
461
|
-
setActiveChannel({ context, event }) {
|
|
465
|
+
setActiveChannel({ context, event, computed }) {
|
|
462
466
|
context.set("activeId", event.id);
|
|
463
467
|
if (event.channel) context.set("activeChannel", event.channel);
|
|
464
468
|
if (event.orientation) context.set("activeOrientation", event.orientation);
|
|
469
|
+
const areaFormat = (0, import_get_area_format.getAreaFormat)(context.get("format"));
|
|
470
|
+
if (areaFormat !== context.get("format")) {
|
|
471
|
+
context.set("areaBaseColor", computed("areaValue"));
|
|
472
|
+
}
|
|
465
473
|
},
|
|
466
474
|
clearActiveChannel({ context }) {
|
|
467
475
|
context.set("activeChannel", null);
|
|
468
476
|
context.set("activeId", null);
|
|
469
477
|
context.set("activeOrientation", null);
|
|
478
|
+
context.set("areaBaseColor", null);
|
|
479
|
+
context.set("areaDragPosition", null);
|
|
470
480
|
},
|
|
471
481
|
setAreaColorFromPoint({ context, event, computed, scope, prop }) {
|
|
472
|
-
const
|
|
482
|
+
const storeFormat = context.get("format");
|
|
483
|
+
const v = event.format ? context.get("value").toFormat(event.format) : context.get("areaBaseColor") ?? computed("areaValue");
|
|
473
484
|
const { xChannel, yChannel } = event.channel || context.get("activeChannel");
|
|
474
485
|
const percent = dom.getAreaValueFromPoint(scope, event.point, prop("dir"));
|
|
475
486
|
if (!percent) return;
|
|
487
|
+
context.set("areaDragPosition", { x: percent.x, y: percent.y });
|
|
476
488
|
const xValue = v.getChannelPercentValue(xChannel, percent.x);
|
|
477
489
|
const yValue = v.getChannelPercentValue(yChannel, 1 - percent.y);
|
|
478
|
-
const color = v.withChannelValue(xChannel, xValue).withChannelValue(yChannel, yValue);
|
|
490
|
+
const color = v.withChannelValue(xChannel, xValue).withChannelValue(yChannel, yValue).toFormat(storeFormat);
|
|
479
491
|
context.set("value", color);
|
|
480
492
|
},
|
|
481
493
|
setChannelColorFromPoint({ context, event, computed, scope, prop }) {
|
|
494
|
+
const storeFormat = context.get("format");
|
|
482
495
|
const channel = event.channel || context.get("activeId");
|
|
483
|
-
const
|
|
496
|
+
const baseColor = context.get("areaBaseColor");
|
|
497
|
+
const normalizedValue = event.format ? context.get("value").toFormat(event.format) : baseColor ?? computed("areaValue");
|
|
484
498
|
const percent = dom.getChannelSliderValueFromPoint(scope, event.point, channel, prop("dir"));
|
|
485
499
|
if (!percent) return;
|
|
486
500
|
const orientation = event.orientation || context.get("activeOrientation") || "horizontal";
|
|
487
501
|
const channelPercent = orientation === "horizontal" ? percent.x : percent.y;
|
|
488
502
|
const value = normalizedValue.getChannelPercentValue(channel, channelPercent);
|
|
489
|
-
const
|
|
490
|
-
context.set("
|
|
503
|
+
const updatedBase = normalizedValue.withChannelValue(channel, value);
|
|
504
|
+
context.set("areaBaseColor", updatedBase);
|
|
505
|
+
context.set("value", updatedBase.toFormat(storeFormat));
|
|
491
506
|
},
|
|
492
507
|
setValue({ context, event }) {
|
|
493
508
|
const format = context.get("format");
|
|
@@ -544,24 +559,32 @@ var machine = (0, import_core.createMachine)({
|
|
|
544
559
|
const color = context.get("value").decrementChannel(event.channel, event.step);
|
|
545
560
|
context.set("value", color);
|
|
546
561
|
},
|
|
547
|
-
incrementAreaXChannel({ context, event
|
|
562
|
+
incrementAreaXChannel({ context, event }) {
|
|
548
563
|
const { xChannel } = event.channel;
|
|
549
|
-
const
|
|
564
|
+
const storeFormat = context.get("format");
|
|
565
|
+
const v = context.get("value").toFormat((0, import_get_area_format.getAreaFormat)(storeFormat));
|
|
566
|
+
const color = v.incrementChannel(xChannel, event.step).toFormat(storeFormat);
|
|
550
567
|
context.set("value", color);
|
|
551
568
|
},
|
|
552
|
-
decrementAreaXChannel({ context, event
|
|
569
|
+
decrementAreaXChannel({ context, event }) {
|
|
553
570
|
const { xChannel } = event.channel;
|
|
554
|
-
const
|
|
571
|
+
const storeFormat = context.get("format");
|
|
572
|
+
const v = context.get("value").toFormat((0, import_get_area_format.getAreaFormat)(storeFormat));
|
|
573
|
+
const color = v.decrementChannel(xChannel, event.step).toFormat(storeFormat);
|
|
555
574
|
context.set("value", color);
|
|
556
575
|
},
|
|
557
|
-
incrementAreaYChannel({ context, event
|
|
576
|
+
incrementAreaYChannel({ context, event }) {
|
|
558
577
|
const { yChannel } = event.channel;
|
|
559
|
-
const
|
|
578
|
+
const storeFormat = context.get("format");
|
|
579
|
+
const v = context.get("value").toFormat((0, import_get_area_format.getAreaFormat)(storeFormat));
|
|
580
|
+
const color = v.incrementChannel(yChannel, event.step).toFormat(storeFormat);
|
|
560
581
|
context.set("value", color);
|
|
561
582
|
},
|
|
562
|
-
decrementAreaYChannel({ context, event
|
|
583
|
+
decrementAreaYChannel({ context, event }) {
|
|
563
584
|
const { yChannel } = event.channel;
|
|
564
|
-
const
|
|
585
|
+
const storeFormat = context.get("format");
|
|
586
|
+
const v = context.get("value").toFormat((0, import_get_area_format.getAreaFormat)(storeFormat));
|
|
587
|
+
const color = v.decrementChannel(yChannel, event.step).toFormat(storeFormat);
|
|
565
588
|
context.set("value", color);
|
|
566
589
|
},
|
|
567
590
|
setChannelToMax({ context, event }) {
|