@zag-js/color-picker 1.41.0 → 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.
Files changed (47) hide show
  1. package/dist/color-picker.anatomy.d.mts +2 -2
  2. package/dist/color-picker.anatomy.d.ts +2 -2
  3. package/dist/color-picker.anatomy.js +1 -0
  4. package/dist/color-picker.anatomy.mjs +1 -0
  5. package/dist/color-picker.connect.d.mts +1 -0
  6. package/dist/color-picker.connect.d.ts +1 -0
  7. package/dist/color-picker.connect.js +78 -42
  8. package/dist/color-picker.connect.mjs +79 -43
  9. package/dist/color-picker.dom.js +23 -22
  10. package/dist/color-picker.dom.mjs +23 -22
  11. package/dist/color-picker.machine.d.mts +1 -0
  12. package/dist/color-picker.machine.d.ts +1 -0
  13. package/dist/color-picker.machine.js +40 -17
  14. package/dist/color-picker.machine.mjs +40 -17
  15. package/dist/color-picker.props.d.mts +1 -0
  16. package/dist/color-picker.props.d.ts +1 -0
  17. package/dist/color-picker.types.d.mts +32 -1
  18. package/dist/color-picker.types.d.ts +32 -1
  19. package/dist/index.d.mts +2 -1
  20. package/dist/index.d.ts +2 -1
  21. package/dist/utils/get-area-format.d.mts +6 -0
  22. package/dist/utils/get-area-format.d.ts +6 -0
  23. package/dist/utils/get-area-format.js +37 -0
  24. package/dist/utils/get-area-format.mjs +12 -0
  25. package/dist/utils/get-channel-display-color.js +7 -0
  26. package/dist/utils/get-channel-display-color.mjs +7 -0
  27. package/dist/utils/get-channel-input-value.d.mts +1 -0
  28. package/dist/utils/get-channel-input-value.d.ts +1 -0
  29. package/dist/utils/get-channel-input-value.js +39 -8
  30. package/dist/utils/get-channel-input-value.mjs +39 -8
  31. package/dist/utils/get-gamut-overlay-path.d.mts +33 -0
  32. package/dist/utils/get-gamut-overlay-path.d.ts +33 -0
  33. package/dist/utils/get-gamut-overlay-path.js +81 -0
  34. package/dist/utils/get-gamut-overlay-path.mjs +55 -0
  35. package/dist/utils/get-gamut-overlay-path.test.d.mts +2 -0
  36. package/dist/utils/get-gamut-overlay-path.test.d.ts +2 -0
  37. package/dist/utils/get-gamut-overlay-path.test.js +35 -0
  38. package/dist/utils/get-gamut-overlay-path.test.mjs +33 -0
  39. package/dist/utils/get-slider-background.d.mts +1 -0
  40. package/dist/utils/get-slider-background.d.ts +1 -0
  41. package/dist/utils/get-slider-background.js +16 -1
  42. package/dist/utils/get-slider-background.mjs +16 -1
  43. package/dist/utils/is-srgb-gamut.d.mts +6 -0
  44. package/dist/utils/is-srgb-gamut.d.ts +6 -0
  45. package/dist/utils/is-srgb-gamut.js +33 -0
  46. package/dist/utils/is-srgb-gamut.mjs +8 -0
  47. package/package.json +9 -9
@@ -1,6 +1,6 @@
1
1
  import * as _zag_js_anatomy from '@zag-js/anatomy';
2
2
 
3
- declare const anatomy: _zag_js_anatomy.Anatomy<"root" | "label" | "control" | "trigger" | "positioner" | "content" | "area" | "areaThumb" | "valueText" | "areaBackground" | "channelSlider" | "channelSliderLabel" | "channelSliderTrack" | "channelSliderThumb" | "channelSliderValueText" | "channelInput" | "transparencyGrid" | "swatchGroup" | "swatchTrigger" | "swatchIndicator" | "swatch" | "eyeDropperTrigger" | "formatTrigger" | "formatSelect">;
4
- declare const parts: Record<"root" | "label" | "control" | "trigger" | "positioner" | "content" | "area" | "areaThumb" | "valueText" | "areaBackground" | "channelSlider" | "channelSliderLabel" | "channelSliderTrack" | "channelSliderThumb" | "channelSliderValueText" | "channelInput" | "transparencyGrid" | "swatchGroup" | "swatchTrigger" | "swatchIndicator" | "swatch" | "eyeDropperTrigger" | "formatTrigger" | "formatSelect", _zag_js_anatomy.AnatomyPart>;
3
+ declare const anatomy: _zag_js_anatomy.Anatomy<"root" | "label" | "control" | "trigger" | "positioner" | "content" | "area" | "areaThumb" | "gamutOverlay" | "valueText" | "areaBackground" | "channelSlider" | "channelSliderLabel" | "channelSliderTrack" | "channelSliderThumb" | "channelSliderValueText" | "channelInput" | "transparencyGrid" | "swatchGroup" | "swatchTrigger" | "swatchIndicator" | "swatch" | "eyeDropperTrigger" | "formatTrigger" | "formatSelect">;
4
+ declare const parts: Record<"root" | "label" | "control" | "trigger" | "positioner" | "content" | "area" | "areaThumb" | "gamutOverlay" | "valueText" | "areaBackground" | "channelSlider" | "channelSliderLabel" | "channelSliderTrack" | "channelSliderThumb" | "channelSliderValueText" | "channelInput" | "transparencyGrid" | "swatchGroup" | "swatchTrigger" | "swatchIndicator" | "swatch" | "eyeDropperTrigger" | "formatTrigger" | "formatSelect", _zag_js_anatomy.AnatomyPart>;
5
5
 
6
6
  export { anatomy, parts };
@@ -1,6 +1,6 @@
1
1
  import * as _zag_js_anatomy from '@zag-js/anatomy';
2
2
 
3
- declare const anatomy: _zag_js_anatomy.Anatomy<"root" | "label" | "control" | "trigger" | "positioner" | "content" | "area" | "areaThumb" | "valueText" | "areaBackground" | "channelSlider" | "channelSliderLabel" | "channelSliderTrack" | "channelSliderThumb" | "channelSliderValueText" | "channelInput" | "transparencyGrid" | "swatchGroup" | "swatchTrigger" | "swatchIndicator" | "swatch" | "eyeDropperTrigger" | "formatTrigger" | "formatSelect">;
4
- declare const parts: Record<"root" | "label" | "control" | "trigger" | "positioner" | "content" | "area" | "areaThumb" | "valueText" | "areaBackground" | "channelSlider" | "channelSliderLabel" | "channelSliderTrack" | "channelSliderThumb" | "channelSliderValueText" | "channelInput" | "transparencyGrid" | "swatchGroup" | "swatchTrigger" | "swatchIndicator" | "swatch" | "eyeDropperTrigger" | "formatTrigger" | "formatSelect", _zag_js_anatomy.AnatomyPart>;
3
+ declare const anatomy: _zag_js_anatomy.Anatomy<"root" | "label" | "control" | "trigger" | "positioner" | "content" | "area" | "areaThumb" | "gamutOverlay" | "valueText" | "areaBackground" | "channelSlider" | "channelSliderLabel" | "channelSliderTrack" | "channelSliderThumb" | "channelSliderValueText" | "channelInput" | "transparencyGrid" | "swatchGroup" | "swatchTrigger" | "swatchIndicator" | "swatch" | "eyeDropperTrigger" | "formatTrigger" | "formatSelect">;
4
+ declare const parts: Record<"root" | "label" | "control" | "trigger" | "positioner" | "content" | "area" | "areaThumb" | "gamutOverlay" | "valueText" | "areaBackground" | "channelSlider" | "channelSliderLabel" | "channelSliderTrack" | "channelSliderThumb" | "channelSliderValueText" | "channelInput" | "transparencyGrid" | "swatchGroup" | "swatchTrigger" | "swatchIndicator" | "swatch" | "eyeDropperTrigger" | "formatTrigger" | "formatSelect", _zag_js_anatomy.AnatomyPart>;
5
5
 
6
6
  export { anatomy, parts };
@@ -34,6 +34,7 @@ var anatomy = (0, import_anatomy.createAnatomy)("color-picker", [
34
34
  "content",
35
35
  "area",
36
36
  "areaThumb",
37
+ "gamutOverlay",
37
38
  "valueText",
38
39
  "areaBackground",
39
40
  "channelSlider",
@@ -9,6 +9,7 @@ var anatomy = createAnatomy("color-picker", [
9
9
  "content",
10
10
  "area",
11
11
  "areaThumb",
12
+ "gamutOverlay",
12
13
  "valueText",
13
14
  "areaBackground",
14
15
  "channelSlider",
@@ -1,6 +1,7 @@
1
1
  import { PropTypes, NormalizeProps } from '@zag-js/types';
2
2
  import { ColorPickerService, ColorPickerApi } 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/core';
5
6
  import '@zag-js/dismissable';
6
7
  import '@zag-js/popper';
@@ -1,6 +1,7 @@
1
1
  import { PropTypes, NormalizeProps } from '@zag-js/types';
2
2
  import { ColorPickerService, ColorPickerApi } 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/core';
5
6
  import '@zag-js/dismissable';
6
7
  import '@zag-js/popper';
@@ -41,12 +41,14 @@ var import_color_picker = require("./color-picker.anatomy.js");
41
41
  var dom = __toESM(require("./color-picker.dom.js"));
42
42
  var import_get_channel_display_color = require("./utils/get-channel-display-color.js");
43
43
  var import_get_channel_input_value = require("./utils/get-channel-input-value.js");
44
+ var import_get_gamut_overlay_path = require("./utils/get-gamut-overlay-path.js");
44
45
  var import_get_slider_background = require("./utils/get-slider-background.js");
45
46
  function connect(service, normalize) {
46
47
  const { context, send, prop, computed, state, scope } = service;
47
48
  const value = context.get("value");
48
49
  const format = context.get("format");
49
50
  const areaValue = computed("areaValue");
51
+ const stableAreaValue = context.get("areaBaseColor") ?? areaValue;
50
52
  const valueAsString = computed("valueAsString");
51
53
  const disabled = computed("disabled");
52
54
  const readOnly = !!prop("readOnly");
@@ -63,11 +65,21 @@ function connect(service, normalize) {
63
65
  yChannel: props.yChannel ?? channels[2]
64
66
  };
65
67
  };
68
+ function getDefaultDevicePixelRatio() {
69
+ if (typeof globalThis === "undefined") return 1;
70
+ const dpr = globalThis.devicePixelRatio;
71
+ return typeof dpr === "number" && Number.isFinite(dpr) ? dpr : 1;
72
+ }
73
+ function resolveGamutOverlay(props = {}) {
74
+ const pixelRatio = props.pixelRatio ?? getDefaultDevicePixelRatio();
75
+ return (0, import_get_gamut_overlay_path.getGamutOverlayData)(stableAreaValue, getAreaChannels(props), format, { pixelRatio });
76
+ }
66
77
  const currentPlacement = context.get("currentPlacement");
67
78
  const currentPlacementSide = currentPlacement ? (0, import_popper.getPlacementSide)(currentPlacement) : void 0;
68
79
  const popperStyles = (0, import_popper.getPlacementStyles)({
69
80
  ...prop("positioning"),
70
- placement: currentPlacement
81
+ placement: currentPlacement,
82
+ positioned: context.get("positioned")
71
83
  });
72
84
  function getSwatchTriggerState(props) {
73
85
  const color = (0, import_color_utils.normalizeColor)(props.value).toFormat(context.get("format"));
@@ -83,6 +95,10 @@ function connect(service, normalize) {
83
95
  open,
84
96
  valueAsString,
85
97
  value,
98
+ isInSrgbGamut: (0, import_color_utils.isInSrgbGamut)(value),
99
+ getGamutOverlay(props = {}) {
100
+ return resolveGamutOverlay(props);
101
+ },
86
102
  inline: !!prop("inline"),
87
103
  setOpen(nextOpen) {
88
104
  if (prop("inline")) return;
@@ -104,9 +120,8 @@ function connect(service, normalize) {
104
120
  send({ type: "VALUE.SET", value: color, src: "set-channel" });
105
121
  },
106
122
  format: context.get("format"),
107
- setFormat(format2) {
108
- const formatValue = value.toFormat(format2);
109
- send({ type: "VALUE.SET", value: formatValue, src: "set-format" });
123
+ setFormat(nextFormat) {
124
+ send({ type: "FORMAT.SET", format: nextFormat, src: "set-format" });
110
125
  },
111
126
  alpha: value.getChannelValue("alpha"),
112
127
  setAlpha(alphaValue) {
@@ -115,9 +130,8 @@ function connect(service, normalize) {
115
130
  },
116
131
  getRootProps() {
117
132
  return normalize.element({
118
- ...import_color_picker.parts.root.attrs,
133
+ ...import_color_picker.parts.root.attrs(scope.id),
119
134
  dir: prop("dir"),
120
- id: dom.getRootId(scope),
121
135
  "data-disabled": (0, import_dom_query2.dataAttr)(disabled),
122
136
  "data-readonly": (0, import_dom_query2.dataAttr)(readOnly),
123
137
  "data-invalid": (0, import_dom_query2.dataAttr)(invalid),
@@ -128,7 +142,7 @@ function connect(service, normalize) {
128
142
  },
129
143
  getLabelProps() {
130
144
  return normalize.element({
131
- ...import_color_picker.parts.label.attrs,
145
+ ...import_color_picker.parts.label.attrs(scope.id),
132
146
  dir: prop("dir"),
133
147
  id: dom.getLabelId(scope),
134
148
  htmlFor: dom.getHiddenInputId(scope),
@@ -146,8 +160,7 @@ function connect(service, normalize) {
146
160
  },
147
161
  getControlProps() {
148
162
  return normalize.element({
149
- ...import_color_picker.parts.control.attrs,
150
- id: dom.getControlId(scope),
163
+ ...import_color_picker.parts.control.attrs(scope.id),
151
164
  dir: prop("dir"),
152
165
  "data-disabled": (0, import_dom_query2.dataAttr)(disabled),
153
166
  "data-readonly": (0, import_dom_query2.dataAttr)(readOnly),
@@ -158,7 +171,7 @@ function connect(service, normalize) {
158
171
  },
159
172
  getTriggerProps() {
160
173
  return normalize.button({
161
- ...import_color_picker.parts.trigger.attrs,
174
+ ...import_color_picker.parts.trigger.attrs(scope.id),
162
175
  id: dom.getTriggerId(scope),
163
176
  dir: prop("dir"),
164
177
  disabled,
@@ -190,15 +203,14 @@ function connect(service, normalize) {
190
203
  },
191
204
  getPositionerProps() {
192
205
  return normalize.element({
193
- ...import_color_picker.parts.positioner.attrs,
194
- id: dom.getPositionerId(scope),
206
+ ...import_color_picker.parts.positioner.attrs(scope.id),
195
207
  dir: prop("dir"),
196
208
  style: popperStyles.floating
197
209
  });
198
210
  },
199
211
  getContentProps() {
200
212
  return normalize.element({
201
- ...import_color_picker.parts.content.attrs,
213
+ ...import_color_picker.parts.content.attrs(scope.id),
202
214
  id: dom.getContentId(scope),
203
215
  dir: prop("dir"),
204
216
  role: prop("inline") ? void 0 : "dialog",
@@ -211,7 +223,7 @@ function connect(service, normalize) {
211
223
  },
212
224
  getValueTextProps() {
213
225
  return normalize.element({
214
- ...import_color_picker.parts.valueText.attrs,
226
+ ...import_color_picker.parts.valueText.attrs(scope.id),
215
227
  dir: prop("dir"),
216
228
  "data-disabled": (0, import_dom_query2.dataAttr)(disabled),
217
229
  "data-focus": (0, import_dom_query2.dataAttr)(focused)
@@ -219,14 +231,13 @@ function connect(service, normalize) {
219
231
  },
220
232
  getAreaProps(props = {}) {
221
233
  const { xChannel, yChannel } = getAreaChannels(props);
222
- const { areaStyles } = (0, import_color_utils.getColorAreaGradient)(areaValue, {
234
+ const { areaStyles } = (0, import_color_utils.getColorAreaGradient)(stableAreaValue, {
223
235
  xChannel,
224
236
  yChannel,
225
237
  dir: prop("dir")
226
238
  });
227
239
  return normalize.element({
228
- ...import_color_picker.parts.area.attrs,
229
- id: dom.getAreaId(scope),
240
+ ...import_color_picker.parts.area.attrs(scope.id),
230
241
  role: "group",
231
242
  "data-invalid": (0, import_dom_query2.dataAttr)(invalid),
232
243
  "data-disabled": (0, import_dom_query2.dataAttr)(disabled),
@@ -250,14 +261,13 @@ function connect(service, normalize) {
250
261
  },
251
262
  getAreaBackgroundProps(props = {}) {
252
263
  const { xChannel, yChannel } = getAreaChannels(props);
253
- const { areaGradientStyles } = (0, import_color_utils.getColorAreaGradient)(areaValue, {
264
+ const { areaGradientStyles } = (0, import_color_utils.getColorAreaGradient)(stableAreaValue, {
254
265
  xChannel,
255
266
  yChannel,
256
267
  dir: prop("dir")
257
268
  });
258
269
  return normalize.element({
259
- ...import_color_picker.parts.areaBackground.attrs,
260
- id: dom.getAreaGradientId(scope),
270
+ ...import_color_picker.parts.areaBackground.attrs(scope.id),
261
271
  "data-invalid": (0, import_dom_query2.dataAttr)(invalid),
262
272
  "data-disabled": (0, import_dom_query2.dataAttr)(disabled),
263
273
  "data-readonly": (0, import_dom_query2.dataAttr)(readOnly),
@@ -269,18 +279,45 @@ function connect(service, normalize) {
269
279
  }
270
280
  });
271
281
  },
282
+ getGamutOverlayProps(props = {}) {
283
+ const data = resolveGamutOverlay(props);
284
+ return normalize.element({
285
+ ...import_color_picker.parts.gamutOverlay.attrs(scope.id),
286
+ viewBox: "0 0 100 100",
287
+ preserveAspectRatio: "none",
288
+ xmlns: "http://www.w3.org/2000/svg",
289
+ "aria-hidden": true,
290
+ "data-state": data ? "visible" : "hidden",
291
+ style: {
292
+ position: "absolute",
293
+ inset: "0",
294
+ width: "100%",
295
+ height: "100%",
296
+ overflow: "hidden",
297
+ pointerEvents: "none"
298
+ }
299
+ });
300
+ },
272
301
  getAreaThumbProps(props = {}) {
273
302
  const { xChannel, yChannel } = getAreaChannels(props);
274
303
  const channel = { xChannel, yChannel };
275
- const xPercent = areaValue.getChannelValuePercent(xChannel);
276
- const yPercent = 1 - areaValue.getChannelValuePercent(yChannel);
304
+ const dragPos = context.get("areaDragPosition");
277
305
  const isRtl = prop("dir") === "rtl";
306
+ let xPercent;
307
+ let yPercent;
308
+ if (dragPos) {
309
+ xPercent = dragPos.x;
310
+ yPercent = dragPos.y;
311
+ } else {
312
+ xPercent = areaValue.getChannelValuePercent(xChannel);
313
+ yPercent = 1 - areaValue.getChannelValuePercent(yChannel);
314
+ }
278
315
  const finalXPercent = isRtl ? 1 - xPercent : xPercent;
279
316
  const xValue = areaValue.getChannelValue(xChannel);
280
317
  const yValue = areaValue.getChannelValue(yChannel);
281
318
  const color = areaValue.withChannelValue("alpha", 1).toString("css");
282
319
  return normalize.element({
283
- ...import_color_picker.parts.areaThumb.attrs,
320
+ ...import_color_picker.parts.areaThumb.attrs(scope.id),
284
321
  id: dom.getAreaThumbId(scope),
285
322
  dir: prop("dir"),
286
323
  tabIndex: disabled ? void 0 : 0,
@@ -348,7 +385,7 @@ function connect(service, normalize) {
348
385
  getTransparencyGridProps(props = {}) {
349
386
  const { size = "12px" } = props;
350
387
  return normalize.element({
351
- ...import_color_picker.parts.transparencyGrid.attrs,
388
+ ...import_color_picker.parts.transparencyGrid.attrs(scope.id),
352
389
  style: {
353
390
  "--size": size,
354
391
  width: "100%",
@@ -366,7 +403,7 @@ function connect(service, normalize) {
366
403
  getChannelSliderProps(props) {
367
404
  const { orientation = "horizontal", channel, format: format2 } = props;
368
405
  return normalize.element({
369
- ...import_color_picker.parts.channelSlider.attrs,
406
+ ...import_color_picker.parts.channelSlider.attrs(scope.id),
370
407
  "data-channel": channel,
371
408
  "data-orientation": orientation,
372
409
  role: "presentation",
@@ -386,10 +423,9 @@ function connect(service, normalize) {
386
423
  },
387
424
  getChannelSliderTrackProps(props) {
388
425
  const { orientation = "horizontal", channel, format: format2 } = props;
389
- const normalizedValue = format2 ? value.toFormat(format2) : areaValue;
426
+ const normalizedValue = format2 ? value.toFormat(format2) : stableAreaValue;
390
427
  return normalize.element({
391
- ...import_color_picker.parts.channelSliderTrack.attrs,
392
- id: dom.getChannelSliderTrackId(scope, channel),
428
+ ...import_color_picker.parts.channelSliderTrack.attrs(scope.id),
393
429
  role: "group",
394
430
  "data-channel": channel,
395
431
  "data-orientation": orientation,
@@ -408,7 +444,7 @@ function connect(service, normalize) {
408
444
  getChannelSliderLabelProps(props) {
409
445
  const { channel } = props;
410
446
  return normalize.element({
411
- ...import_color_picker.parts.channelSliderLabel.attrs,
447
+ ...import_color_picker.parts.channelSliderLabel.attrs(scope.id),
412
448
  "data-channel": channel,
413
449
  onClick(event) {
414
450
  if (!interactive) return;
@@ -424,13 +460,13 @@ function connect(service, normalize) {
424
460
  },
425
461
  getChannelSliderValueTextProps(props) {
426
462
  return normalize.element({
427
- ...import_color_picker.parts.channelSliderValueText.attrs,
463
+ ...import_color_picker.parts.channelSliderValueText.attrs(scope.id),
428
464
  "data-channel": props.channel
429
465
  });
430
466
  },
431
467
  getChannelSliderThumbProps(props) {
432
468
  const { orientation = "horizontal", channel, format: format2 } = props;
433
- const normalizedValue = format2 ? value.toFormat(format2) : areaValue;
469
+ const normalizedValue = format2 ? value.toFormat(format2) : stableAreaValue;
434
470
  const channelRange = normalizedValue.getChannelRange(channel);
435
471
  const channelValue = normalizedValue.getChannelValue(channel);
436
472
  const offset = (channelValue - channelRange.minValue) / (channelRange.maxValue - channelRange.minValue);
@@ -438,7 +474,7 @@ function connect(service, normalize) {
438
474
  const finalOffset = orientation === "horizontal" && isRtl ? 1 - offset : offset;
439
475
  const placementStyles = orientation === "horizontal" ? { left: `${finalOffset * 100}%`, top: "50%" } : { top: `${offset * 100}%`, left: "50%" };
440
476
  return normalize.element({
441
- ...import_color_picker.parts.channelSliderThumb.attrs,
477
+ ...import_color_picker.parts.channelSliderThumb.attrs(scope.id),
442
478
  id: dom.getChannelSliderThumbId(scope, channel),
443
479
  role: "slider",
444
480
  "aria-label": channel,
@@ -455,7 +491,7 @@ function connect(service, normalize) {
455
491
  style: {
456
492
  forcedColorAdjust: "none",
457
493
  position: "absolute",
458
- background: (0, import_get_channel_display_color.getChannelDisplayColor)(areaValue, channel).toString("css"),
494
+ background: (0, import_get_channel_display_color.getChannelDisplayColor)(stableAreaValue, channel).toString("css"),
459
495
  ...placementStyles
460
496
  },
461
497
  onFocus() {
@@ -510,7 +546,7 @@ function connect(service, normalize) {
510
546
  const isTextField = channel === "hex" || channel === "css";
511
547
  const channelRange = (0, import_get_channel_input_value.getChannelRange)(value, channel);
512
548
  return normalize.input({
513
- ...import_color_picker.parts.channelInput.attrs,
549
+ ...import_color_picker.parts.channelInput.attrs(scope.id),
514
550
  dir: prop("dir"),
515
551
  type: isTextField ? "text" : "number",
516
552
  "data-channel": channel,
@@ -574,7 +610,7 @@ function connect(service, normalize) {
574
610
  },
575
611
  getEyeDropperTriggerProps() {
576
612
  return normalize.button({
577
- ...import_color_picker.parts.eyeDropperTrigger.attrs,
613
+ ...import_color_picker.parts.eyeDropperTrigger.attrs(scope.id),
578
614
  type: "button",
579
615
  dir: prop("dir"),
580
616
  disabled,
@@ -590,7 +626,7 @@ function connect(service, normalize) {
590
626
  },
591
627
  getSwatchGroupProps() {
592
628
  return normalize.element({
593
- ...import_color_picker.parts.swatchGroup.attrs,
629
+ ...import_color_picker.parts.swatchGroup.attrs(scope.id),
594
630
  role: "group"
595
631
  });
596
632
  },
@@ -598,7 +634,7 @@ function connect(service, normalize) {
598
634
  getSwatchTriggerProps(props) {
599
635
  const swatchState = getSwatchTriggerState(props);
600
636
  return normalize.button({
601
- ...import_color_picker.parts.swatchTrigger.attrs,
637
+ ...import_color_picker.parts.swatchTrigger.attrs(scope.id),
602
638
  disabled: swatchState.disabled,
603
639
  dir: prop("dir"),
604
640
  type: "button",
@@ -619,7 +655,7 @@ function connect(service, normalize) {
619
655
  getSwatchIndicatorProps(props) {
620
656
  const swatchState = getSwatchTriggerState(props);
621
657
  return normalize.element({
622
- ...import_color_picker.parts.swatchIndicator.attrs,
658
+ ...import_color_picker.parts.swatchIndicator.attrs(scope.id),
623
659
  dir: prop("dir"),
624
660
  hidden: !swatchState.checked
625
661
  });
@@ -629,7 +665,7 @@ function connect(service, normalize) {
629
665
  const swatchState = getSwatchTriggerState(props);
630
666
  const color = swatchState.value.toString(respectAlpha ? "css" : "hex");
631
667
  return normalize.element({
632
- ...import_color_picker.parts.swatch.attrs,
668
+ ...import_color_picker.parts.swatch.attrs(scope.id),
633
669
  dir: prop("dir"),
634
670
  "data-state": swatchState.checked ? "checked" : "unchecked",
635
671
  "data-value": swatchState.valueAsString,
@@ -642,7 +678,7 @@ function connect(service, normalize) {
642
678
  },
643
679
  getFormatTriggerProps() {
644
680
  return normalize.button({
645
- ...import_color_picker.parts.formatTrigger.attrs,
681
+ ...import_color_picker.parts.formatTrigger.attrs(scope.id),
646
682
  dir: prop("dir"),
647
683
  type: "button",
648
684
  "aria-label": `change color format to ${getNextFormat(format)}`,
@@ -655,7 +691,7 @@ function connect(service, normalize) {
655
691
  },
656
692
  getFormatSelectProps() {
657
693
  return normalize.select({
658
- ...import_color_picker.parts.formatSelect.attrs,
694
+ ...import_color_picker.parts.formatSelect.attrs(scope.id),
659
695
  "aria-label": "change color format",
660
696
  dir: prop("dir"),
661
697
  defaultValue: prop("format"),
@@ -668,7 +704,7 @@ function connect(service, normalize) {
668
704
  }
669
705
  };
670
706
  }
671
- var formats = ["hsba", "hsla", "rgba"];
707
+ var formats = ["hsba", "hsla", "rgba", "oklab", "oklch"];
672
708
  var formatRegex = new RegExp(`^(${formats.join("|")})$`);
673
709
  function getNextFormat(format) {
674
710
  const index = formats.indexOf(format);