@zag-js/color-picker 2.0.0-next.0 → 2.0.0-next.2

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.
@@ -34,6 +34,7 @@ __export(color_picker_connect_exports, {
34
34
  });
35
35
  module.exports = __toCommonJS(color_picker_connect_exports);
36
36
  var import_color_utils = require("@zag-js/color-utils");
37
+ var import_dismissable = require("@zag-js/dismissable");
37
38
  var import_dom_query = require("@zag-js/dom-query");
38
39
  var import_dom_query2 = require("@zag-js/dom-query");
39
40
  var import_popper = require("@zag-js/popper");
@@ -43,8 +44,14 @@ var import_get_channel_display_color = require("./utils/get-channel-display-colo
43
44
  var import_get_channel_input_value = require("./utils/get-channel-input-value.js");
44
45
  var import_get_gamut_overlay_path = require("./utils/get-gamut-overlay-path.js");
45
46
  var import_get_slider_background = require("./utils/get-slider-background.js");
47
+ function getDefaultDevicePixelRatio() {
48
+ if (typeof globalThis === "undefined") return 1;
49
+ const dpr = globalThis.devicePixelRatio;
50
+ return typeof dpr === "number" && Number.isFinite(dpr) ? dpr : 1;
51
+ }
46
52
  function connect(service, normalize) {
47
53
  const { context, send, prop, computed, state, scope } = service;
54
+ const layer = context.get("layer");
48
55
  const value = context.get("value");
49
56
  const format = context.get("format");
50
57
  const areaValue = computed("areaValue");
@@ -65,11 +72,6 @@ function connect(service, normalize) {
65
72
  yChannel: props.yChannel ?? channels[2]
66
73
  };
67
74
  };
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
75
  function resolveGamutOverlay(props = {}) {
74
76
  const pixelRatio = props.pixelRatio ?? getDefaultDevicePixelRatio();
75
77
  return (0, import_get_gamut_overlay_path.getGamutOverlayData)(stableAreaValue, getAreaChannels(props), format, { pixelRatio });
@@ -78,8 +80,7 @@ function connect(service, normalize) {
78
80
  const currentPlacementSide = currentPlacement ? (0, import_popper.getPlacementSide)(currentPlacement) : void 0;
79
81
  const popperStyles = (0, import_popper.getPlacementStyles)({
80
82
  ...prop("positioning"),
81
- placement: currentPlacement,
82
- positioned: context.get("positioned")
83
+ placement: currentPlacement
83
84
  });
84
85
  function getSwatchTriggerState(props) {
85
86
  const color = (0, import_color_utils.normalizeColor)(props.value).toFormat(context.get("format"));
@@ -90,6 +91,29 @@ function connect(service, normalize) {
90
91
  disabled: props.disabled || !interactive
91
92
  };
92
93
  }
94
+ function getRootState() {
95
+ return { disabled, readOnly, invalid };
96
+ }
97
+ function getTriggerState() {
98
+ return {
99
+ open,
100
+ focused,
101
+ disabled,
102
+ invalid,
103
+ readOnly,
104
+ placement: currentPlacement,
105
+ side: currentPlacementSide
106
+ };
107
+ }
108
+ function getContentState() {
109
+ return {
110
+ open,
111
+ nested: !!layer?.nested,
112
+ hasNested: !!layer?.hasNested,
113
+ placement: currentPlacement,
114
+ side: currentPlacementSide
115
+ };
116
+ }
93
117
  return {
94
118
  dragging,
95
119
  open,
@@ -128,13 +152,15 @@ function connect(service, normalize) {
128
152
  const color = value.withChannelValue("alpha", alphaValue);
129
153
  send({ type: "VALUE.SET", value: color, src: "set-alpha" });
130
154
  },
155
+ getRootState,
131
156
  getRootProps() {
157
+ const rootState = getRootState();
132
158
  return normalize.element({
133
159
  ...import_color_picker.parts.root.attrs(scope.id),
134
160
  dir: prop("dir"),
135
- "data-disabled": (0, import_dom_query2.dataAttr)(disabled),
136
- "data-readonly": (0, import_dom_query2.dataAttr)(readOnly),
137
- "data-invalid": (0, import_dom_query2.dataAttr)(invalid),
161
+ "data-disabled": (0, import_dom_query2.dataAttr)(rootState.disabled),
162
+ "data-readonly": (0, import_dom_query2.dataAttr)(rootState.readOnly),
163
+ "data-invalid": (0, import_dom_query2.dataAttr)(rootState.invalid),
138
164
  style: {
139
165
  "--value": value.toString("css")
140
166
  }
@@ -169,24 +195,26 @@ function connect(service, normalize) {
169
195
  "data-focus": (0, import_dom_query2.dataAttr)(focused)
170
196
  });
171
197
  },
198
+ getTriggerState,
172
199
  getTriggerProps() {
200
+ const triggerState = getTriggerState();
173
201
  return normalize.button({
174
202
  ...import_color_picker.parts.trigger.attrs(scope.id),
175
203
  id: dom.getTriggerId(scope),
176
204
  dir: prop("dir"),
177
- disabled,
205
+ disabled: triggerState.disabled,
178
206
  "aria-label": `select color. current color is ${valueAsString}`,
179
207
  "aria-controls": dom.getContentId(scope),
180
208
  "aria-labelledby": dom.getLabelId(scope),
181
209
  "aria-haspopup": prop("inline") ? void 0 : "dialog",
182
- "data-disabled": (0, import_dom_query2.dataAttr)(disabled),
183
- "data-readonly": (0, import_dom_query2.dataAttr)(readOnly),
184
- "data-invalid": (0, import_dom_query2.dataAttr)(invalid),
185
- "data-placement": currentPlacement,
186
- "data-side": currentPlacementSide,
187
- "aria-expanded": open,
188
- "data-state": open ? "open" : "closed",
189
- "data-focus": (0, import_dom_query2.dataAttr)(focused),
210
+ "data-disabled": (0, import_dom_query2.dataAttr)(triggerState.disabled),
211
+ "data-readonly": (0, import_dom_query2.dataAttr)(triggerState.readOnly),
212
+ "data-invalid": (0, import_dom_query2.dataAttr)(triggerState.invalid),
213
+ "data-placement": triggerState.placement,
214
+ "data-side": triggerState.side,
215
+ "aria-expanded": triggerState.open,
216
+ "data-state": triggerState.open ? "open" : "closed",
217
+ "data-focus": (0, import_dom_query2.dataAttr)(triggerState.focused),
190
218
  type: "button",
191
219
  onClick() {
192
220
  if (!interactive) return;
@@ -205,20 +233,28 @@ function connect(service, normalize) {
205
233
  return normalize.element({
206
234
  ...import_color_picker.parts.positioner.attrs(scope.id),
207
235
  dir: prop("dir"),
208
- style: popperStyles.floating
236
+ ...(0, import_dismissable.getDismissableLayerAttrs)(layer),
237
+ style: {
238
+ ...popperStyles.floating,
239
+ ...(0, import_dismissable.getDismissableLayerStyle)(layer, { zIndex: true })
240
+ }
209
241
  });
210
242
  },
243
+ getContentState,
211
244
  getContentProps() {
245
+ const contentState = getContentState();
212
246
  return normalize.element({
213
247
  ...import_color_picker.parts.content.attrs(scope.id),
214
248
  id: dom.getContentId(scope),
215
249
  dir: prop("dir"),
216
250
  role: prop("inline") ? void 0 : "dialog",
217
251
  tabIndex: -1,
218
- "data-placement": currentPlacement,
219
- "data-side": currentPlacementSide,
220
- "data-state": open ? "open" : "closed",
221
- hidden: !open
252
+ "data-placement": contentState.placement,
253
+ "data-side": contentState.side,
254
+ "data-state": contentState.open ? "open" : "closed",
255
+ hidden: !contentState.open,
256
+ ...(0, import_dismissable.getDismissableLayerAttrs)(layer),
257
+ style: (0, import_dismissable.getDismissableLayerStyle)(layer, { pointerEvents: true })
222
258
  });
223
259
  },
224
260
  getValueTextProps() {
@@ -582,6 +618,7 @@ function connect(service, normalize) {
582
618
  onKeyDown(event) {
583
619
  if (event.defaultPrevented) return;
584
620
  if (!interactive) return;
621
+ if ((0, import_dom_query.isComposingEvent)(event)) return;
585
622
  if (event.key === "Enter") {
586
623
  const value2 = isTextField ? event.currentTarget.value : event.currentTarget.valueAsNumber;
587
624
  send({ type: "CHANNEL_INPUT.CHANGE", channel, value: value2, isTextField });
@@ -1,6 +1,14 @@
1
1
  // src/color-picker.connect.ts
2
2
  import { getColorAreaGradient, isInSrgbGamut, normalizeColor } from "@zag-js/color-utils";
3
- import { getEventKey, getEventPoint, getEventStep, isLeftClick, isModifierKey } from "@zag-js/dom-query";
3
+ import { getDismissableLayerAttrs, getDismissableLayerStyle } from "@zag-js/dismissable";
4
+ import {
5
+ getEventKey,
6
+ getEventPoint,
7
+ getEventStep,
8
+ isComposingEvent,
9
+ isLeftClick,
10
+ isModifierKey
11
+ } from "@zag-js/dom-query";
4
12
  import { dataAttr, query, visuallyHiddenStyle } from "@zag-js/dom-query";
5
13
  import { getPlacementSide, getPlacementStyles } from "@zag-js/popper";
6
14
  import { parts } from "./color-picker.anatomy.mjs";
@@ -9,8 +17,14 @@ import { getChannelDisplayColor } from "./utils/get-channel-display-color.mjs";
9
17
  import { getChannelRange, getChannelValue } from "./utils/get-channel-input-value.mjs";
10
18
  import { getGamutOverlayData } from "./utils/get-gamut-overlay-path.mjs";
11
19
  import { getSliderBackground } from "./utils/get-slider-background.mjs";
20
+ function getDefaultDevicePixelRatio() {
21
+ if (typeof globalThis === "undefined") return 1;
22
+ const dpr = globalThis.devicePixelRatio;
23
+ return typeof dpr === "number" && Number.isFinite(dpr) ? dpr : 1;
24
+ }
12
25
  function connect(service, normalize) {
13
26
  const { context, send, prop, computed, state, scope } = service;
27
+ const layer = context.get("layer");
14
28
  const value = context.get("value");
15
29
  const format = context.get("format");
16
30
  const areaValue = computed("areaValue");
@@ -31,11 +45,6 @@ function connect(service, normalize) {
31
45
  yChannel: props.yChannel ?? channels[2]
32
46
  };
33
47
  };
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
48
  function resolveGamutOverlay(props = {}) {
40
49
  const pixelRatio = props.pixelRatio ?? getDefaultDevicePixelRatio();
41
50
  return getGamutOverlayData(stableAreaValue, getAreaChannels(props), format, { pixelRatio });
@@ -44,8 +53,7 @@ function connect(service, normalize) {
44
53
  const currentPlacementSide = currentPlacement ? getPlacementSide(currentPlacement) : void 0;
45
54
  const popperStyles = getPlacementStyles({
46
55
  ...prop("positioning"),
47
- placement: currentPlacement,
48
- positioned: context.get("positioned")
56
+ placement: currentPlacement
49
57
  });
50
58
  function getSwatchTriggerState(props) {
51
59
  const color = normalizeColor(props.value).toFormat(context.get("format"));
@@ -56,6 +64,29 @@ function connect(service, normalize) {
56
64
  disabled: props.disabled || !interactive
57
65
  };
58
66
  }
67
+ function getRootState() {
68
+ return { disabled, readOnly, invalid };
69
+ }
70
+ function getTriggerState() {
71
+ return {
72
+ open,
73
+ focused,
74
+ disabled,
75
+ invalid,
76
+ readOnly,
77
+ placement: currentPlacement,
78
+ side: currentPlacementSide
79
+ };
80
+ }
81
+ function getContentState() {
82
+ return {
83
+ open,
84
+ nested: !!layer?.nested,
85
+ hasNested: !!layer?.hasNested,
86
+ placement: currentPlacement,
87
+ side: currentPlacementSide
88
+ };
89
+ }
59
90
  return {
60
91
  dragging,
61
92
  open,
@@ -94,13 +125,15 @@ function connect(service, normalize) {
94
125
  const color = value.withChannelValue("alpha", alphaValue);
95
126
  send({ type: "VALUE.SET", value: color, src: "set-alpha" });
96
127
  },
128
+ getRootState,
97
129
  getRootProps() {
130
+ const rootState = getRootState();
98
131
  return normalize.element({
99
132
  ...parts.root.attrs(scope.id),
100
133
  dir: prop("dir"),
101
- "data-disabled": dataAttr(disabled),
102
- "data-readonly": dataAttr(readOnly),
103
- "data-invalid": dataAttr(invalid),
134
+ "data-disabled": dataAttr(rootState.disabled),
135
+ "data-readonly": dataAttr(rootState.readOnly),
136
+ "data-invalid": dataAttr(rootState.invalid),
104
137
  style: {
105
138
  "--value": value.toString("css")
106
139
  }
@@ -135,24 +168,26 @@ function connect(service, normalize) {
135
168
  "data-focus": dataAttr(focused)
136
169
  });
137
170
  },
171
+ getTriggerState,
138
172
  getTriggerProps() {
173
+ const triggerState = getTriggerState();
139
174
  return normalize.button({
140
175
  ...parts.trigger.attrs(scope.id),
141
176
  id: dom.getTriggerId(scope),
142
177
  dir: prop("dir"),
143
- disabled,
178
+ disabled: triggerState.disabled,
144
179
  "aria-label": `select color. current color is ${valueAsString}`,
145
180
  "aria-controls": dom.getContentId(scope),
146
181
  "aria-labelledby": dom.getLabelId(scope),
147
182
  "aria-haspopup": prop("inline") ? void 0 : "dialog",
148
- "data-disabled": dataAttr(disabled),
149
- "data-readonly": dataAttr(readOnly),
150
- "data-invalid": dataAttr(invalid),
151
- "data-placement": currentPlacement,
152
- "data-side": currentPlacementSide,
153
- "aria-expanded": open,
154
- "data-state": open ? "open" : "closed",
155
- "data-focus": dataAttr(focused),
183
+ "data-disabled": dataAttr(triggerState.disabled),
184
+ "data-readonly": dataAttr(triggerState.readOnly),
185
+ "data-invalid": dataAttr(triggerState.invalid),
186
+ "data-placement": triggerState.placement,
187
+ "data-side": triggerState.side,
188
+ "aria-expanded": triggerState.open,
189
+ "data-state": triggerState.open ? "open" : "closed",
190
+ "data-focus": dataAttr(triggerState.focused),
156
191
  type: "button",
157
192
  onClick() {
158
193
  if (!interactive) return;
@@ -171,20 +206,28 @@ function connect(service, normalize) {
171
206
  return normalize.element({
172
207
  ...parts.positioner.attrs(scope.id),
173
208
  dir: prop("dir"),
174
- style: popperStyles.floating
209
+ ...getDismissableLayerAttrs(layer),
210
+ style: {
211
+ ...popperStyles.floating,
212
+ ...getDismissableLayerStyle(layer, { zIndex: true })
213
+ }
175
214
  });
176
215
  },
216
+ getContentState,
177
217
  getContentProps() {
218
+ const contentState = getContentState();
178
219
  return normalize.element({
179
220
  ...parts.content.attrs(scope.id),
180
221
  id: dom.getContentId(scope),
181
222
  dir: prop("dir"),
182
223
  role: prop("inline") ? void 0 : "dialog",
183
224
  tabIndex: -1,
184
- "data-placement": currentPlacement,
185
- "data-side": currentPlacementSide,
186
- "data-state": open ? "open" : "closed",
187
- hidden: !open
225
+ "data-placement": contentState.placement,
226
+ "data-side": contentState.side,
227
+ "data-state": contentState.open ? "open" : "closed",
228
+ hidden: !contentState.open,
229
+ ...getDismissableLayerAttrs(layer),
230
+ style: getDismissableLayerStyle(layer, { pointerEvents: true })
188
231
  });
189
232
  },
190
233
  getValueTextProps() {
@@ -548,6 +591,7 @@ function connect(service, normalize) {
548
591
  onKeyDown(event) {
549
592
  if (event.defaultPrevented) return;
550
593
  if (!interactive) return;
594
+ if (isComposingEvent(event)) return;
551
595
  if (event.key === "Enter") {
552
596
  const value2 = isTextField ? event.currentTarget.value : event.currentTarget.valueAsNumber;
553
597
  send({ type: "CHANNEL_INPUT.CHANGE", channel, value: value2, isTextField });
@@ -72,6 +72,9 @@ var machine = (0, import_core.createMachine)({
72
72
  },
73
73
  context({ prop, bindable, getContext }) {
74
74
  return {
75
+ layer: bindable(() => ({
76
+ defaultValue: null
77
+ })),
75
78
  value: bindable(() => ({
76
79
  defaultValue: prop("defaultValue").toFormat(prop("format") ?? prop("defaultFormat")),
77
80
  value: prop("value")?.toFormat(prop("format") ?? prop("defaultFormat")),
@@ -103,8 +106,7 @@ var machine = (0, import_core.createMachine)({
103
106
  restoreFocus: bindable(() => ({ defaultValue: true })),
104
107
  currentPlacement: bindable(() => ({
105
108
  defaultValue: void 0
106
- })),
107
- positioned: bindable(() => ({ defaultValue: false }))
109
+ }))
108
110
  };
109
111
  },
110
112
  computed: {
@@ -391,7 +393,6 @@ var machine = (0, import_core.createMachine)({
391
393
  defer: true,
392
394
  onComplete(data) {
393
395
  context.set("currentPlacement", data.placement);
394
- context.set("positioned", true);
395
396
  }
396
397
  });
397
398
  },
@@ -400,6 +401,9 @@ var machine = (0, import_core.createMachine)({
400
401
  const getContentEl2 = () => dom.getContentEl(scope);
401
402
  return (0, import_dismissable.trackDismissableElement)(getContentEl2, {
402
403
  type: "popover",
404
+ onLayerChange(layer) {
405
+ context.set("layer", layer);
406
+ },
403
407
  exclude: dom.getTriggerEl(scope),
404
408
  defer: true,
405
409
  onInteractOutside(event) {
@@ -46,6 +46,9 @@ var machine = createMachine({
46
46
  },
47
47
  context({ prop, bindable, getContext }) {
48
48
  return {
49
+ layer: bindable(() => ({
50
+ defaultValue: null
51
+ })),
49
52
  value: bindable(() => ({
50
53
  defaultValue: prop("defaultValue").toFormat(prop("format") ?? prop("defaultFormat")),
51
54
  value: prop("value")?.toFormat(prop("format") ?? prop("defaultFormat")),
@@ -77,8 +80,7 @@ var machine = createMachine({
77
80
  restoreFocus: bindable(() => ({ defaultValue: true })),
78
81
  currentPlacement: bindable(() => ({
79
82
  defaultValue: void 0
80
- })),
81
- positioned: bindable(() => ({ defaultValue: false }))
83
+ }))
82
84
  };
83
85
  },
84
86
  computed: {
@@ -365,7 +367,6 @@ var machine = createMachine({
365
367
  defer: true,
366
368
  onComplete(data) {
367
369
  context.set("currentPlacement", data.placement);
368
- context.set("positioned", true);
369
370
  }
370
371
  });
371
372
  },
@@ -374,6 +375,9 @@ var machine = createMachine({
374
375
  const getContentEl2 = () => dom.getContentEl(scope);
375
376
  return trackDismissableElement(getContentEl2, {
376
377
  type: "popover",
378
+ onLayerChange(layer) {
379
+ context.set("layer", layer);
380
+ },
377
381
  exclude: dom.getTriggerEl(scope),
378
382
  defer: true,
379
383
  onInteractOutside(event) {
@@ -2,10 +2,10 @@ import { ColorChannel, Color, ColorFormat, ColorAxes } from '@zag-js/color-utils
2
2
  export { Color, ColorAxes, ColorChannel, ColorFormat, ColorType } from '@zag-js/color-utils';
3
3
  import { GamutOverlayData } from './utils/get-gamut-overlay-path.mjs';
4
4
  import { Service, EventObject, Machine } from '@zag-js/core';
5
- import { InteractOutsideHandlers } from '@zag-js/dismissable';
6
- import { PositioningOptions } from '@zag-js/popper';
5
+ import { InteractOutsideHandlers, LayerSnapshot } from '@zag-js/dismissable';
6
+ import { PositioningOptions, Placement, PlacementSide } from '@zag-js/popper';
7
7
  export { PositioningOptions } from '@zag-js/popper';
8
- import { RequiredBy, CommonProperties, DirectionProperty, Orientation, PropTypes } from '@zag-js/types';
8
+ import { CommonProperties, DirectionProperty, Orientation, PropTypes } from '@zag-js/types';
9
9
 
10
10
  type ExtendedColorChannel = ColorChannel | "hex" | "css";
11
11
  interface EyeDropper {
@@ -33,23 +33,23 @@ interface OpenChangeDetails {
33
33
  interface FormatChangeDetails {
34
34
  format: ColorFormat;
35
35
  }
36
- type ElementIds = Partial<{
37
- root: string;
38
- control: string;
39
- trigger: string;
40
- label: string;
41
- input: string;
42
- hiddenInput: string;
43
- content: string;
44
- area: string;
45
- areaGradient: string;
46
- positioner: string;
47
- formatSelect: string;
48
- areaThumb: string;
49
- channelInput: (id: string) => string;
50
- channelSliderTrack: (id: ColorChannel) => string;
51
- channelSliderThumb: (id: ColorChannel) => string;
52
- }>;
36
+ interface ElementIds {
37
+ root?: string | undefined;
38
+ control?: string | undefined;
39
+ trigger?: string | undefined;
40
+ label?: string | undefined;
41
+ input?: string | undefined;
42
+ hiddenInput?: string | undefined;
43
+ content?: string | undefined;
44
+ area?: string | undefined;
45
+ areaGradient?: string | undefined;
46
+ positioner?: string | undefined;
47
+ formatSelect?: string | undefined;
48
+ areaThumb?: string | undefined;
49
+ channelInput?: ((id: string) => string) | undefined;
50
+ channelSliderTrack?: ((id: ColorChannel) => string) | undefined;
51
+ channelSliderThumb?: ((id: ColorChannel) => string) | undefined;
52
+ }
53
53
  interface ColorPickerProps extends CommonProperties, DirectionProperty, InteractOutsideHandlers {
54
54
  /**
55
55
  * The ids of the elements in the color picker. Useful for composition.
@@ -104,7 +104,7 @@ interface ColorPickerProps extends CommonProperties, DirectionProperty, Interact
104
104
  /**
105
105
  * The initial focus element when the color picker is opened.
106
106
  */
107
- initialFocusEl?: (() => HTMLElement | null) | undefined;
107
+ initialFocusEl?: (() => HTMLElement | null) | null | undefined;
108
108
  /**
109
109
  * The controlled open state of the color picker
110
110
  */
@@ -147,7 +147,8 @@ type PropsWithDefault = "defaultFormat" | "defaultValue" | "openAutoFocus" | "di
147
147
  type ColorPickerSchema = {
148
148
  tag: "open" | "closed" | "dragging" | "focused";
149
149
  state: "idle" | "focused" | "open" | "open.idle" | "open.dragging";
150
- props: RequiredBy<ColorPickerProps, PropsWithDefault>;
150
+ props: ColorPickerProps;
151
+ defaultPropKey: PropsWithDefault;
151
152
  computed: {
152
153
  disabled: boolean;
153
154
  rtl: boolean;
@@ -156,6 +157,10 @@ type ColorPickerSchema = {
156
157
  areaValue: Color;
157
158
  };
158
159
  context: {
160
+ /**
161
+ * The computed layer stack state used for declarative styles and attributes.
162
+ */
163
+ layer: LayerSnapshot | null;
159
164
  format: ColorFormat;
160
165
  value: Color;
161
166
  activeId: string | null;
@@ -168,7 +173,6 @@ type ColorPickerSchema = {
168
173
  } | null;
169
174
  fieldsetDisabled: boolean;
170
175
  currentPlacement: PositioningOptions["placement"] | undefined;
171
- positioned: boolean;
172
176
  restoreFocus: boolean;
173
177
  };
174
178
  event: EventObject;
@@ -219,6 +223,72 @@ interface SwatchTriggerState {
219
223
  checked: boolean;
220
224
  disabled: boolean;
221
225
  }
226
+ interface RootState {
227
+ /**
228
+ * Whether the color picker is disabled
229
+ */
230
+ disabled: boolean;
231
+ /**
232
+ * Whether the color picker is read-only
233
+ */
234
+ readOnly: boolean;
235
+ /**
236
+ * Whether the color picker is invalid
237
+ */
238
+ invalid: boolean;
239
+ }
240
+ interface TriggerState {
241
+ /**
242
+ * Whether the color picker is open
243
+ */
244
+ open: boolean;
245
+ /**
246
+ * Whether the trigger is focused
247
+ */
248
+ focused: boolean;
249
+ /**
250
+ * Whether the trigger is disabled
251
+ */
252
+ disabled: boolean;
253
+ /**
254
+ * Whether the color picker is invalid
255
+ */
256
+ invalid: boolean;
257
+ /**
258
+ * Whether the color picker is read-only
259
+ */
260
+ readOnly: boolean;
261
+ /**
262
+ * The current placement of the content relative to the trigger
263
+ */
264
+ placement: Placement | undefined;
265
+ /**
266
+ * The side of the trigger the content is placed on
267
+ */
268
+ side: PlacementSide | undefined;
269
+ }
270
+ interface ContentState {
271
+ /**
272
+ * Whether the color picker is open
273
+ */
274
+ open: boolean;
275
+ /**
276
+ * Whether the content is nested within another layered element
277
+ */
278
+ nested: boolean;
279
+ /**
280
+ * Whether the content has nested layered elements within it
281
+ */
282
+ hasNested: boolean;
283
+ /**
284
+ * The current placement of the content relative to the trigger
285
+ */
286
+ placement: Placement | undefined;
287
+ /**
288
+ * The side of the trigger the content is placed on
289
+ */
290
+ side: PlacementSide | undefined;
291
+ }
222
292
  interface SwatchProps {
223
293
  /**
224
294
  * The color value
@@ -294,11 +364,23 @@ interface ColorPickerApi<T extends PropTypes = PropTypes> {
294
364
  * Function to open or close the color picker
295
365
  */
296
366
  setOpen: (open: boolean) => void;
367
+ /**
368
+ * Returns the state of the root
369
+ */
370
+ getRootState: () => RootState;
297
371
  getRootProps: () => T["element"];
298
372
  getLabelProps: () => T["element"];
299
373
  getControlProps: () => T["element"];
374
+ /**
375
+ * Returns the state of the trigger
376
+ */
377
+ getTriggerState: () => TriggerState;
300
378
  getTriggerProps: () => T["button"];
301
379
  getPositionerProps: () => T["element"];
380
+ /**
381
+ * Returns the state of the content
382
+ */
383
+ getContentState: () => ContentState;
302
384
  getContentProps: () => T["element"];
303
385
  getHiddenInputProps: () => T["input"];
304
386
  getValueTextProps: () => T["element"];
@@ -331,4 +413,4 @@ interface ColorPickerApi<T extends PropTypes = PropTypes> {
331
413
  getFormatTriggerProps: () => T["button"];
332
414
  }
333
415
 
334
- export { type AreaProps, type ChannelInputProps, type ChannelProps, type ChannelSliderProps, type ColorPickerApi, type ColorPickerMachine, type ColorPickerProps, type ColorPickerSchema, type ColorPickerService, type ElementIds, type ExtendedColorChannel, type FormatChangeDetails, GamutOverlayData, type GamutOverlayProps, type OpenChangeDetails, type SwatchProps, type SwatchTriggerProps, type SwatchTriggerState, type TransparencyGridProps, type ValueChangeDetails };
416
+ export { type AreaProps, type ChannelInputProps, type ChannelProps, type ChannelSliderProps, type ColorPickerApi, type ColorPickerMachine, type ColorPickerProps, type ColorPickerSchema, type ColorPickerService, type ContentState, type ElementIds, type ExtendedColorChannel, type FormatChangeDetails, GamutOverlayData, type GamutOverlayProps, type OpenChangeDetails, type RootState, type SwatchProps, type SwatchTriggerProps, type SwatchTriggerState, type TransparencyGridProps, type TriggerState, type ValueChangeDetails };
@@ -2,10 +2,10 @@ import { ColorChannel, Color, ColorFormat, ColorAxes } from '@zag-js/color-utils
2
2
  export { Color, ColorAxes, ColorChannel, ColorFormat, ColorType } from '@zag-js/color-utils';
3
3
  import { GamutOverlayData } from './utils/get-gamut-overlay-path.js';
4
4
  import { Service, EventObject, Machine } from '@zag-js/core';
5
- import { InteractOutsideHandlers } from '@zag-js/dismissable';
6
- import { PositioningOptions } from '@zag-js/popper';
5
+ import { InteractOutsideHandlers, LayerSnapshot } from '@zag-js/dismissable';
6
+ import { PositioningOptions, Placement, PlacementSide } from '@zag-js/popper';
7
7
  export { PositioningOptions } from '@zag-js/popper';
8
- import { RequiredBy, CommonProperties, DirectionProperty, Orientation, PropTypes } from '@zag-js/types';
8
+ import { CommonProperties, DirectionProperty, Orientation, PropTypes } from '@zag-js/types';
9
9
 
10
10
  type ExtendedColorChannel = ColorChannel | "hex" | "css";
11
11
  interface EyeDropper {
@@ -33,23 +33,23 @@ interface OpenChangeDetails {
33
33
  interface FormatChangeDetails {
34
34
  format: ColorFormat;
35
35
  }
36
- type ElementIds = Partial<{
37
- root: string;
38
- control: string;
39
- trigger: string;
40
- label: string;
41
- input: string;
42
- hiddenInput: string;
43
- content: string;
44
- area: string;
45
- areaGradient: string;
46
- positioner: string;
47
- formatSelect: string;
48
- areaThumb: string;
49
- channelInput: (id: string) => string;
50
- channelSliderTrack: (id: ColorChannel) => string;
51
- channelSliderThumb: (id: ColorChannel) => string;
52
- }>;
36
+ interface ElementIds {
37
+ root?: string | undefined;
38
+ control?: string | undefined;
39
+ trigger?: string | undefined;
40
+ label?: string | undefined;
41
+ input?: string | undefined;
42
+ hiddenInput?: string | undefined;
43
+ content?: string | undefined;
44
+ area?: string | undefined;
45
+ areaGradient?: string | undefined;
46
+ positioner?: string | undefined;
47
+ formatSelect?: string | undefined;
48
+ areaThumb?: string | undefined;
49
+ channelInput?: ((id: string) => string) | undefined;
50
+ channelSliderTrack?: ((id: ColorChannel) => string) | undefined;
51
+ channelSliderThumb?: ((id: ColorChannel) => string) | undefined;
52
+ }
53
53
  interface ColorPickerProps extends CommonProperties, DirectionProperty, InteractOutsideHandlers {
54
54
  /**
55
55
  * The ids of the elements in the color picker. Useful for composition.
@@ -104,7 +104,7 @@ interface ColorPickerProps extends CommonProperties, DirectionProperty, Interact
104
104
  /**
105
105
  * The initial focus element when the color picker is opened.
106
106
  */
107
- initialFocusEl?: (() => HTMLElement | null) | undefined;
107
+ initialFocusEl?: (() => HTMLElement | null) | null | undefined;
108
108
  /**
109
109
  * The controlled open state of the color picker
110
110
  */
@@ -147,7 +147,8 @@ type PropsWithDefault = "defaultFormat" | "defaultValue" | "openAutoFocus" | "di
147
147
  type ColorPickerSchema = {
148
148
  tag: "open" | "closed" | "dragging" | "focused";
149
149
  state: "idle" | "focused" | "open" | "open.idle" | "open.dragging";
150
- props: RequiredBy<ColorPickerProps, PropsWithDefault>;
150
+ props: ColorPickerProps;
151
+ defaultPropKey: PropsWithDefault;
151
152
  computed: {
152
153
  disabled: boolean;
153
154
  rtl: boolean;
@@ -156,6 +157,10 @@ type ColorPickerSchema = {
156
157
  areaValue: Color;
157
158
  };
158
159
  context: {
160
+ /**
161
+ * The computed layer stack state used for declarative styles and attributes.
162
+ */
163
+ layer: LayerSnapshot | null;
159
164
  format: ColorFormat;
160
165
  value: Color;
161
166
  activeId: string | null;
@@ -168,7 +173,6 @@ type ColorPickerSchema = {
168
173
  } | null;
169
174
  fieldsetDisabled: boolean;
170
175
  currentPlacement: PositioningOptions["placement"] | undefined;
171
- positioned: boolean;
172
176
  restoreFocus: boolean;
173
177
  };
174
178
  event: EventObject;
@@ -219,6 +223,72 @@ interface SwatchTriggerState {
219
223
  checked: boolean;
220
224
  disabled: boolean;
221
225
  }
226
+ interface RootState {
227
+ /**
228
+ * Whether the color picker is disabled
229
+ */
230
+ disabled: boolean;
231
+ /**
232
+ * Whether the color picker is read-only
233
+ */
234
+ readOnly: boolean;
235
+ /**
236
+ * Whether the color picker is invalid
237
+ */
238
+ invalid: boolean;
239
+ }
240
+ interface TriggerState {
241
+ /**
242
+ * Whether the color picker is open
243
+ */
244
+ open: boolean;
245
+ /**
246
+ * Whether the trigger is focused
247
+ */
248
+ focused: boolean;
249
+ /**
250
+ * Whether the trigger is disabled
251
+ */
252
+ disabled: boolean;
253
+ /**
254
+ * Whether the color picker is invalid
255
+ */
256
+ invalid: boolean;
257
+ /**
258
+ * Whether the color picker is read-only
259
+ */
260
+ readOnly: boolean;
261
+ /**
262
+ * The current placement of the content relative to the trigger
263
+ */
264
+ placement: Placement | undefined;
265
+ /**
266
+ * The side of the trigger the content is placed on
267
+ */
268
+ side: PlacementSide | undefined;
269
+ }
270
+ interface ContentState {
271
+ /**
272
+ * Whether the color picker is open
273
+ */
274
+ open: boolean;
275
+ /**
276
+ * Whether the content is nested within another layered element
277
+ */
278
+ nested: boolean;
279
+ /**
280
+ * Whether the content has nested layered elements within it
281
+ */
282
+ hasNested: boolean;
283
+ /**
284
+ * The current placement of the content relative to the trigger
285
+ */
286
+ placement: Placement | undefined;
287
+ /**
288
+ * The side of the trigger the content is placed on
289
+ */
290
+ side: PlacementSide | undefined;
291
+ }
222
292
  interface SwatchProps {
223
293
  /**
224
294
  * The color value
@@ -294,11 +364,23 @@ interface ColorPickerApi<T extends PropTypes = PropTypes> {
294
364
  * Function to open or close the color picker
295
365
  */
296
366
  setOpen: (open: boolean) => void;
367
+ /**
368
+ * Returns the state of the root
369
+ */
370
+ getRootState: () => RootState;
297
371
  getRootProps: () => T["element"];
298
372
  getLabelProps: () => T["element"];
299
373
  getControlProps: () => T["element"];
374
+ /**
375
+ * Returns the state of the trigger
376
+ */
377
+ getTriggerState: () => TriggerState;
300
378
  getTriggerProps: () => T["button"];
301
379
  getPositionerProps: () => T["element"];
380
+ /**
381
+ * Returns the state of the content
382
+ */
383
+ getContentState: () => ContentState;
302
384
  getContentProps: () => T["element"];
303
385
  getHiddenInputProps: () => T["input"];
304
386
  getValueTextProps: () => T["element"];
@@ -331,4 +413,4 @@ interface ColorPickerApi<T extends PropTypes = PropTypes> {
331
413
  getFormatTriggerProps: () => T["button"];
332
414
  }
333
415
 
334
- export { type AreaProps, type ChannelInputProps, type ChannelProps, type ChannelSliderProps, type ColorPickerApi, type ColorPickerMachine, type ColorPickerProps, type ColorPickerSchema, type ColorPickerService, type ElementIds, type ExtendedColorChannel, type FormatChangeDetails, GamutOverlayData, type GamutOverlayProps, type OpenChangeDetails, type SwatchProps, type SwatchTriggerProps, type SwatchTriggerState, type TransparencyGridProps, type ValueChangeDetails };
416
+ export { type AreaProps, type ChannelInputProps, type ChannelProps, type ChannelSliderProps, type ColorPickerApi, type ColorPickerMachine, type ColorPickerProps, type ColorPickerSchema, type ColorPickerService, type ContentState, type ElementIds, type ExtendedColorChannel, type FormatChangeDetails, GamutOverlayData, type GamutOverlayProps, type OpenChangeDetails, type RootState, type SwatchProps, type SwatchTriggerProps, type SwatchTriggerState, type TransparencyGridProps, type TriggerState, type ValueChangeDetails };
package/dist/index.d.mts CHANGED
@@ -4,7 +4,7 @@ export { connect } from './color-picker.connect.mjs';
4
4
  export { machine } from './color-picker.machine.mjs';
5
5
  export { parse } from './color-picker.parse.mjs';
6
6
  export { areaProps, channelProps, props, splitAreaProps, splitChannelProps, splitProps, splitSwatchProps, splitSwatchTriggerProps, splitTransparencyGridProps, swatchProps, swatchTriggerProps, transparencyGridProps } from './color-picker.props.mjs';
7
- export { ColorPickerApi as Api, AreaProps, ChannelInputProps, ChannelProps, ChannelSliderProps, ElementIds, ExtendedColorChannel, FormatChangeDetails, GamutOverlayProps, ColorPickerMachine as Machine, OpenChangeDetails, ColorPickerProps as Props, ColorPickerService as Service, SwatchProps, SwatchTriggerProps, SwatchTriggerState, TransparencyGridProps, ValueChangeDetails } from './color-picker.types.mjs';
7
+ export { ColorPickerApi as Api, AreaProps, ChannelInputProps, ChannelProps, ChannelSliderProps, ContentState, ElementIds, ExtendedColorChannel, FormatChangeDetails, GamutOverlayProps, ColorPickerMachine as Machine, OpenChangeDetails, ColorPickerProps as Props, RootState, ColorPickerService as Service, SwatchProps, SwatchTriggerProps, SwatchTriggerState, TransparencyGridProps, TriggerState, ValueChangeDetails } from './color-picker.types.mjs';
8
8
  export { Color, ColorAxes, ColorChannel, ColorFormat, ColorType } from '@zag-js/color-utils';
9
9
  export { GamutOverlayData } from './utils/get-gamut-overlay-path.mjs';
10
10
  export { PositioningOptions } from '@zag-js/popper';
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ export { connect } from './color-picker.connect.js';
4
4
  export { machine } from './color-picker.machine.js';
5
5
  export { parse } from './color-picker.parse.js';
6
6
  export { areaProps, channelProps, props, splitAreaProps, splitChannelProps, splitProps, splitSwatchProps, splitSwatchTriggerProps, splitTransparencyGridProps, swatchProps, swatchTriggerProps, transparencyGridProps } from './color-picker.props.js';
7
- export { ColorPickerApi as Api, AreaProps, ChannelInputProps, ChannelProps, ChannelSliderProps, ElementIds, ExtendedColorChannel, FormatChangeDetails, GamutOverlayProps, ColorPickerMachine as Machine, OpenChangeDetails, ColorPickerProps as Props, ColorPickerService as Service, SwatchProps, SwatchTriggerProps, SwatchTriggerState, TransparencyGridProps, ValueChangeDetails } from './color-picker.types.js';
7
+ export { ColorPickerApi as Api, AreaProps, ChannelInputProps, ChannelProps, ChannelSliderProps, ContentState, ElementIds, ExtendedColorChannel, FormatChangeDetails, GamutOverlayProps, ColorPickerMachine as Machine, OpenChangeDetails, ColorPickerProps as Props, RootState, ColorPickerService as Service, SwatchProps, SwatchTriggerProps, SwatchTriggerState, TransparencyGridProps, TriggerState, ValueChangeDetails } from './color-picker.types.js';
8
8
  export { Color, ColorAxes, ColorChannel, ColorFormat, ColorType } from '@zag-js/color-utils';
9
9
  export { GamutOverlayData } from './utils/get-gamut-overlay-path.js';
10
10
  export { PositioningOptions } from '@zag-js/popper';
@@ -1,5 +1,6 @@
1
+ import * as _zag_js_color_utils from '@zag-js/color-utils';
1
2
  import { Color, ColorChannel } from '@zag-js/color-utils';
2
3
 
3
- declare function getChannelDisplayColor(color: Color, channel: ColorChannel): Color;
4
+ declare function getChannelDisplayColor(color: Color, channel: ColorChannel): _zag_js_color_utils.ColorType;
4
5
 
5
6
  export { getChannelDisplayColor };
@@ -1,5 +1,6 @@
1
+ import * as _zag_js_color_utils from '@zag-js/color-utils';
1
2
  import { Color, ColorChannel } from '@zag-js/color-utils';
2
3
 
3
- declare function getChannelDisplayColor(color: Color, channel: ColorChannel): Color;
4
+ declare function getChannelDisplayColor(color: Color, channel: ColorChannel): _zag_js_color_utils.ColorType;
4
5
 
5
6
  export { getChannelDisplayColor };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zag-js/color-picker",
3
- "version": "2.0.0-next.0",
3
+ "version": "2.0.0-next.2",
4
4
  "description": "Core logic for the color-picker widget implemented as a state machine",
5
5
  "keywords": [
6
6
  "js",
@@ -15,7 +15,10 @@
15
15
  "homepage": "https://github.com/chakra-ui/zag#readme",
16
16
  "license": "MIT",
17
17
  "main": "dist/index.js",
18
- "repository": "https://github.com/chakra-ui/zag/tree/main/packages/color-picker",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/chakra-ui/zag/tree/main/packages/color-picker"
21
+ },
19
22
  "sideEffects": false,
20
23
  "files": [
21
24
  "dist"
@@ -27,14 +30,14 @@
27
30
  "url": "https://github.com/chakra-ui/zag/issues"
28
31
  },
29
32
  "dependencies": {
30
- "@zag-js/core": "2.0.0-next.0",
31
- "@zag-js/anatomy": "2.0.0-next.0",
32
- "@zag-js/dom-query": "2.0.0-next.0",
33
- "@zag-js/dismissable": "2.0.0-next.0",
34
- "@zag-js/utils": "2.0.0-next.0",
35
- "@zag-js/color-utils": "2.0.0-next.0",
36
- "@zag-js/popper": "2.0.0-next.0",
37
- "@zag-js/types": "2.0.0-next.0"
33
+ "@zag-js/core": "2.0.0-next.2",
34
+ "@zag-js/anatomy": "2.0.0-next.2",
35
+ "@zag-js/dom-query": "2.0.0-next.2",
36
+ "@zag-js/dismissable": "2.0.0-next.2",
37
+ "@zag-js/utils": "2.0.0-next.2",
38
+ "@zag-js/color-utils": "2.0.0-next.2",
39
+ "@zag-js/popper": "2.0.0-next.2",
40
+ "@zag-js/types": "2.0.0-next.2"
38
41
  },
39
42
  "devDependencies": {
40
43
  "clean-package": "2.2.0"
@@ -67,7 +70,7 @@
67
70
  },
68
71
  "scripts": {
69
72
  "build": "tsup",
70
- "lint": "eslint src",
73
+ "lint": "oxlint src",
71
74
  "typecheck": "tsc --noEmit"
72
75
  }
73
76
  }