@zag-js/slider 1.43.0 → 2.0.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -2,7 +2,7 @@ export { anatomy } from './slider.anatomy.mjs';
2
2
  export { connect } from './slider.connect.mjs';
3
3
  export { machine } from './slider.machine.mjs';
4
4
  export { markerProps, props, splitMarkerProps, splitProps, splitThumbProps, thumbProps } from './slider.props.mjs';
5
- export { SliderApi as Api, DraggingIndicatorProps, ElementIds, FocusChangeDetails, SliderMachine as Machine, MarkerProps, SliderProps as Props, SliderService as Service, ThumbAlignment, ThumbCollisionBehavior, ThumbProps, ValueChangeDetails, ValueTextDetails } from './slider.types.mjs';
5
+ export { SliderApi as Api, DraggingIndicatorProps, ElementIds, FocusChangeDetails, SliderMachine as Machine, MarkerProps, MarkerState, SliderProps as Props, RootState, SliderService as Service, SliderOrigin, ThumbAlignment, ThumbCollisionBehavior, ThumbProps, ThumbState, ValueChangeDetails, ValueTextDetails } from './slider.types.mjs';
6
6
  import '@zag-js/anatomy';
7
7
  import '@zag-js/types';
8
8
  import '@zag-js/core';
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export { anatomy } from './slider.anatomy.js';
2
2
  export { connect } from './slider.connect.js';
3
3
  export { machine } from './slider.machine.js';
4
4
  export { markerProps, props, splitMarkerProps, splitProps, splitThumbProps, thumbProps } from './slider.props.js';
5
- export { SliderApi as Api, DraggingIndicatorProps, ElementIds, FocusChangeDetails, SliderMachine as Machine, MarkerProps, SliderProps as Props, SliderService as Service, ThumbAlignment, ThumbCollisionBehavior, ThumbProps, ValueChangeDetails, ValueTextDetails } from './slider.types.js';
5
+ export { SliderApi as Api, DraggingIndicatorProps, ElementIds, FocusChangeDetails, SliderMachine as Machine, MarkerProps, MarkerState, SliderProps as Props, RootState, SliderService as Service, SliderOrigin, ThumbAlignment, ThumbCollisionBehavior, ThumbProps, ThumbState, ValueChangeDetails, ValueTextDetails } from './slider.types.js';
6
6
  import '@zag-js/anatomy';
7
7
  import '@zag-js/types';
8
8
  import '@zag-js/core';
@@ -48,7 +48,7 @@ function connect(service, normalize) {
48
48
  const focused = state.matches("focus");
49
49
  const dragging = state.matches("dragging");
50
50
  const disabled = computed("isDisabled");
51
- const invalid = prop("invalid");
51
+ const invalid = !!prop("invalid");
52
52
  const interactive = computed("isInteractive");
53
53
  const isHorizontal = prop("orientation") === "horizontal";
54
54
  const isVertical = prop("orientation") === "vertical";
@@ -58,6 +58,31 @@ function connect(service, normalize) {
58
58
  function getPercentValueFn(percent) {
59
59
  return (0, import_utils.getPercentValue)(percent, prop("min"), prop("max"), prop("step"));
60
60
  }
61
+ function getRootState() {
62
+ return { disabled, invalid, dragging, focused, orientation: prop("orientation") };
63
+ }
64
+ function getThumbState(props) {
65
+ const { index } = props;
66
+ return {
67
+ index,
68
+ value: sliderValue[index],
69
+ disabled,
70
+ focused: focused && focusedIndex === index,
71
+ dragging: dragging && focusedIndex === index
72
+ };
73
+ }
74
+ function getMarkerState(props) {
75
+ const { value } = props;
76
+ let markerState;
77
+ if (value < (0, import_utils.first)(sliderValue)) {
78
+ markerState = "under-value";
79
+ } else if (value > (0, import_utils.last)(sliderValue)) {
80
+ markerState = "over-value";
81
+ } else {
82
+ markerState = "at-value";
83
+ }
84
+ return { value, disabled, state: markerState };
85
+ }
61
86
  return {
62
87
  value: sliderValue,
63
88
  dragging,
@@ -96,15 +121,17 @@ function connect(service, normalize) {
96
121
  if (!interactive) return;
97
122
  send({ type: "FOCUS", index: 0 });
98
123
  },
124
+ getRootState,
99
125
  getLabelProps() {
126
+ const rootState = getRootState();
100
127
  return normalize.label({
101
- ...import_slider.parts.label.attrs,
128
+ ...import_slider.parts.label.attrs(scope.id),
102
129
  dir: prop("dir"),
103
- "data-disabled": (0, import_dom_query.dataAttr)(disabled),
104
- "data-orientation": prop("orientation"),
105
- "data-invalid": (0, import_dom_query.dataAttr)(invalid),
106
- "data-dragging": (0, import_dom_query.dataAttr)(dragging),
107
- "data-focus": (0, import_dom_query.dataAttr)(focused),
130
+ "data-disabled": (0, import_dom_query.dataAttr)(rootState.disabled),
131
+ "data-orientation": rootState.orientation,
132
+ "data-invalid": (0, import_dom_query.dataAttr)(rootState.invalid),
133
+ "data-dragging": (0, import_dom_query.dataAttr)(rootState.dragging),
134
+ "data-focus": (0, import_dom_query.dataAttr)(rootState.focused),
108
135
  id: dom.getLabelId(scope),
109
136
  htmlFor: dom.getHiddenInputId(scope, 0),
110
137
  onClick(event) {
@@ -119,70 +146,70 @@ function connect(service, normalize) {
119
146
  });
120
147
  },
121
148
  getRootProps() {
149
+ const rootState = getRootState();
122
150
  return normalize.element({
123
- ...import_slider.parts.root.attrs,
124
- "data-disabled": (0, import_dom_query.dataAttr)(disabled),
125
- "data-orientation": prop("orientation"),
126
- "data-dragging": (0, import_dom_query.dataAttr)(dragging),
127
- "data-invalid": (0, import_dom_query.dataAttr)(invalid),
128
- "data-focus": (0, import_dom_query.dataAttr)(focused),
129
- id: dom.getRootId(scope),
151
+ ...import_slider.parts.root.attrs(scope.id),
152
+ "data-disabled": (0, import_dom_query.dataAttr)(rootState.disabled),
153
+ "data-orientation": rootState.orientation,
154
+ "data-dragging": (0, import_dom_query.dataAttr)(rootState.dragging),
155
+ "data-invalid": (0, import_dom_query.dataAttr)(rootState.invalid),
156
+ "data-focus": (0, import_dom_query.dataAttr)(rootState.focused),
130
157
  dir: prop("dir"),
131
158
  style: (0, import_slider2.getRootStyle)(service)
132
159
  });
133
160
  },
134
161
  getValueTextProps() {
162
+ const rootState = getRootState();
135
163
  return normalize.element({
136
- ...import_slider.parts.valueText.attrs,
164
+ ...import_slider.parts.valueText.attrs(scope.id),
137
165
  dir: prop("dir"),
138
- "data-disabled": (0, import_dom_query.dataAttr)(disabled),
139
- "data-orientation": prop("orientation"),
140
- "data-invalid": (0, import_dom_query.dataAttr)(invalid),
141
- "data-focus": (0, import_dom_query.dataAttr)(focused),
142
- id: dom.getValueTextId(scope)
166
+ "data-disabled": (0, import_dom_query.dataAttr)(rootState.disabled),
167
+ "data-orientation": rootState.orientation,
168
+ "data-invalid": (0, import_dom_query.dataAttr)(rootState.invalid),
169
+ "data-focus": (0, import_dom_query.dataAttr)(rootState.focused)
143
170
  });
144
171
  },
145
172
  getTrackProps() {
173
+ const rootState = getRootState();
146
174
  return normalize.element({
147
- ...import_slider.parts.track.attrs,
175
+ ...import_slider.parts.track.attrs(scope.id),
148
176
  dir: prop("dir"),
149
- id: dom.getTrackId(scope),
150
- "data-disabled": (0, import_dom_query.dataAttr)(disabled),
151
- "data-invalid": (0, import_dom_query.dataAttr)(invalid),
152
- "data-dragging": (0, import_dom_query.dataAttr)(dragging),
153
- "data-orientation": prop("orientation"),
154
- "data-focus": (0, import_dom_query.dataAttr)(focused),
177
+ "data-disabled": (0, import_dom_query.dataAttr)(rootState.disabled),
178
+ "data-invalid": (0, import_dom_query.dataAttr)(rootState.invalid),
179
+ "data-dragging": (0, import_dom_query.dataAttr)(rootState.dragging),
180
+ "data-orientation": rootState.orientation,
181
+ "data-focus": (0, import_dom_query.dataAttr)(rootState.focused),
155
182
  style: { position: "relative" }
156
183
  });
157
184
  },
185
+ getThumbState,
158
186
  getThumbProps(props) {
159
187
  const { index = 0, name } = props;
160
- const value = sliderValue[index];
188
+ const thumbState = getThumbState({ index, name });
161
189
  const range = (0, import_slider3.getRangeAtIndex)(service, index);
162
- const valueText = prop("getAriaValueText")?.({ value, index });
190
+ const valueText = prop("getAriaValueText")?.({ value: thumbState.value, index });
163
191
  const _ariaLabel = Array.isArray(ariaLabel) ? ariaLabel[index] : ariaLabel;
164
192
  const _ariaLabelledBy = Array.isArray(ariaLabelledBy) ? ariaLabelledBy[index] : ariaLabelledBy;
165
193
  return normalize.element({
166
- ...import_slider.parts.thumb.attrs,
194
+ ...import_slider.parts.thumb.attrs(scope.id),
167
195
  dir: prop("dir"),
168
196
  "data-index": index,
169
197
  "data-name": name,
170
- id: dom.getThumbId(scope, index),
171
- "data-disabled": (0, import_dom_query.dataAttr)(disabled),
198
+ "data-disabled": (0, import_dom_query.dataAttr)(thumbState.disabled),
172
199
  "data-orientation": prop("orientation"),
173
- "data-focus": (0, import_dom_query.dataAttr)(focused && focusedIndex === index),
174
- "data-dragging": (0, import_dom_query.dataAttr)(dragging && focusedIndex === index),
200
+ "data-focus": (0, import_dom_query.dataAttr)(thumbState.focused),
201
+ "data-dragging": (0, import_dom_query.dataAttr)(thumbState.dragging),
175
202
  draggable: false,
176
- "aria-disabled": (0, import_dom_query.ariaAttr)(disabled),
203
+ "aria-disabled": (0, import_dom_query.ariaAttr)(thumbState.disabled),
177
204
  "aria-label": _ariaLabel,
178
205
  "aria-labelledby": _ariaLabelledBy ?? dom.getLabelId(scope),
179
206
  "aria-orientation": prop("orientation"),
180
207
  "aria-valuemax": range.max,
181
208
  "aria-valuemin": range.min,
182
- "aria-valuenow": sliderValue[index],
209
+ "aria-valuenow": thumbState.value,
183
210
  "aria-valuetext": valueText,
184
211
  role: "slider",
185
- tabIndex: disabled ? void 0 : 0,
212
+ tabIndex: thumbState.disabled ? void 0 : 0,
186
213
  style: (0, import_slider2.getThumbStyle)(service, index),
187
214
  onPointerDown(event) {
188
215
  if (!interactive) return;
@@ -257,38 +284,39 @@ function connect(service, normalize) {
257
284
  },
258
285
  getHiddenInputProps(props) {
259
286
  const { index = 0, name } = props;
287
+ const thumbState = getThumbState({ index, name });
260
288
  return normalize.input({
261
289
  name: name ?? (prop("name") ? prop("name") + (sliderValue.length > 1 ? "[]" : "") : void 0),
262
290
  form: prop("form"),
263
291
  type: "text",
264
292
  hidden: true,
265
- defaultValue: sliderValue[index],
293
+ defaultValue: thumbState.value,
266
294
  id: dom.getHiddenInputId(scope, index)
267
295
  });
268
296
  },
269
297
  getRangeProps() {
298
+ const rootState = getRootState();
270
299
  return normalize.element({
271
- id: dom.getRangeId(scope),
272
- ...import_slider.parts.range.attrs,
300
+ ...import_slider.parts.range.attrs(scope.id),
273
301
  dir: prop("dir"),
274
- "data-dragging": (0, import_dom_query.dataAttr)(dragging),
275
- "data-focus": (0, import_dom_query.dataAttr)(focused),
276
- "data-invalid": (0, import_dom_query.dataAttr)(invalid),
277
- "data-disabled": (0, import_dom_query.dataAttr)(disabled),
278
- "data-orientation": prop("orientation"),
302
+ "data-dragging": (0, import_dom_query.dataAttr)(rootState.dragging),
303
+ "data-focus": (0, import_dom_query.dataAttr)(rootState.focused),
304
+ "data-invalid": (0, import_dom_query.dataAttr)(rootState.invalid),
305
+ "data-disabled": (0, import_dom_query.dataAttr)(rootState.disabled),
306
+ "data-orientation": rootState.orientation,
279
307
  style: (0, import_slider2.getRangeStyle)(service)
280
308
  });
281
309
  },
282
310
  getControlProps() {
311
+ const rootState = getRootState();
283
312
  return normalize.element({
284
- ...import_slider.parts.control.attrs,
313
+ ...import_slider.parts.control.attrs(scope.id),
285
314
  dir: prop("dir"),
286
- id: dom.getControlId(scope),
287
- "data-dragging": (0, import_dom_query.dataAttr)(dragging),
288
- "data-disabled": (0, import_dom_query.dataAttr)(disabled),
289
- "data-orientation": prop("orientation"),
290
- "data-invalid": (0, import_dom_query.dataAttr)(invalid),
291
- "data-focus": (0, import_dom_query.dataAttr)(focused),
315
+ "data-dragging": (0, import_dom_query.dataAttr)(rootState.dragging),
316
+ "data-disabled": (0, import_dom_query.dataAttr)(rootState.disabled),
317
+ "data-orientation": rootState.orientation,
318
+ "data-invalid": (0, import_dom_query.dataAttr)(rootState.invalid),
319
+ "data-focus": (0, import_dom_query.dataAttr)(rootState.focused),
292
320
  style: (0, import_slider2.getControlStyle)(),
293
321
  onPointerDown(event) {
294
322
  if (!interactive) return;
@@ -303,7 +331,7 @@ function connect(service, normalize) {
303
331
  },
304
332
  getMarkerGroupProps() {
305
333
  return normalize.element({
306
- ...import_slider.parts.markerGroup.attrs,
334
+ ...import_slider.parts.markerGroup.attrs(scope.id),
307
335
  role: "presentation",
308
336
  dir: prop("dir"),
309
337
  "aria-hidden": true,
@@ -311,38 +339,31 @@ function connect(service, normalize) {
311
339
  style: (0, import_slider2.getMarkerGroupStyle)()
312
340
  });
313
341
  },
342
+ getMarkerState,
314
343
  getMarkerProps(props) {
315
344
  const style = (0, import_slider2.getMarkerStyle)(service, props.value);
316
- let markerState;
317
- if (props.value < (0, import_utils.first)(sliderValue)) {
318
- markerState = "under-value";
319
- } else if (props.value > (0, import_utils.last)(sliderValue)) {
320
- markerState = "over-value";
321
- } else {
322
- markerState = "at-value";
323
- }
345
+ const markerState = getMarkerState(props);
324
346
  return normalize.element({
325
- ...import_slider.parts.marker.attrs,
326
- id: dom.getMarkerId(scope, props.value),
347
+ ...import_slider.parts.marker.attrs(scope.id),
327
348
  role: "presentation",
328
349
  dir: prop("dir"),
329
350
  "data-orientation": prop("orientation"),
330
- "data-value": props.value,
331
- "data-disabled": (0, import_dom_query.dataAttr)(disabled),
332
- "data-state": markerState,
351
+ "data-value": markerState.value,
352
+ "data-disabled": (0, import_dom_query.dataAttr)(markerState.disabled),
353
+ "data-state": markerState.state,
333
354
  style
334
355
  });
335
356
  },
336
357
  getDraggingIndicatorProps(props) {
337
358
  const { index = 0 } = props;
338
- const isDragging = index === focusedIndex && dragging;
359
+ const thumbState = getThumbState({ index });
339
360
  return normalize.element({
340
- ...import_slider.parts.draggingIndicator.attrs,
361
+ ...import_slider.parts.draggingIndicator.attrs(scope.id),
341
362
  role: "presentation",
342
363
  dir: prop("dir"),
343
- hidden: !isDragging,
364
+ hidden: !thumbState.dragging,
344
365
  "data-orientation": prop("orientation"),
345
- "data-state": isDragging ? "open" : "closed",
366
+ "data-state": thumbState.dragging ? "open" : "closed",
346
367
  style: (0, import_slider2.getThumbStyle)(service, index)
347
368
  });
348
369
  }
@@ -29,7 +29,7 @@ function connect(service, normalize) {
29
29
  const focused = state.matches("focus");
30
30
  const dragging = state.matches("dragging");
31
31
  const disabled = computed("isDisabled");
32
- const invalid = prop("invalid");
32
+ const invalid = !!prop("invalid");
33
33
  const interactive = computed("isInteractive");
34
34
  const isHorizontal = prop("orientation") === "horizontal";
35
35
  const isVertical = prop("orientation") === "vertical";
@@ -39,6 +39,31 @@ function connect(service, normalize) {
39
39
  function getPercentValueFn(percent) {
40
40
  return getPercentValue(percent, prop("min"), prop("max"), prop("step"));
41
41
  }
42
+ function getRootState() {
43
+ return { disabled, invalid, dragging, focused, orientation: prop("orientation") };
44
+ }
45
+ function getThumbState(props) {
46
+ const { index } = props;
47
+ return {
48
+ index,
49
+ value: sliderValue[index],
50
+ disabled,
51
+ focused: focused && focusedIndex === index,
52
+ dragging: dragging && focusedIndex === index
53
+ };
54
+ }
55
+ function getMarkerState(props) {
56
+ const { value } = props;
57
+ let markerState;
58
+ if (value < first(sliderValue)) {
59
+ markerState = "under-value";
60
+ } else if (value > last(sliderValue)) {
61
+ markerState = "over-value";
62
+ } else {
63
+ markerState = "at-value";
64
+ }
65
+ return { value, disabled, state: markerState };
66
+ }
42
67
  return {
43
68
  value: sliderValue,
44
69
  dragging,
@@ -77,15 +102,17 @@ function connect(service, normalize) {
77
102
  if (!interactive) return;
78
103
  send({ type: "FOCUS", index: 0 });
79
104
  },
105
+ getRootState,
80
106
  getLabelProps() {
107
+ const rootState = getRootState();
81
108
  return normalize.label({
82
- ...parts.label.attrs,
109
+ ...parts.label.attrs(scope.id),
83
110
  dir: prop("dir"),
84
- "data-disabled": dataAttr(disabled),
85
- "data-orientation": prop("orientation"),
86
- "data-invalid": dataAttr(invalid),
87
- "data-dragging": dataAttr(dragging),
88
- "data-focus": dataAttr(focused),
111
+ "data-disabled": dataAttr(rootState.disabled),
112
+ "data-orientation": rootState.orientation,
113
+ "data-invalid": dataAttr(rootState.invalid),
114
+ "data-dragging": dataAttr(rootState.dragging),
115
+ "data-focus": dataAttr(rootState.focused),
89
116
  id: dom.getLabelId(scope),
90
117
  htmlFor: dom.getHiddenInputId(scope, 0),
91
118
  onClick(event) {
@@ -100,70 +127,70 @@ function connect(service, normalize) {
100
127
  });
101
128
  },
102
129
  getRootProps() {
130
+ const rootState = getRootState();
103
131
  return normalize.element({
104
- ...parts.root.attrs,
105
- "data-disabled": dataAttr(disabled),
106
- "data-orientation": prop("orientation"),
107
- "data-dragging": dataAttr(dragging),
108
- "data-invalid": dataAttr(invalid),
109
- "data-focus": dataAttr(focused),
110
- id: dom.getRootId(scope),
132
+ ...parts.root.attrs(scope.id),
133
+ "data-disabled": dataAttr(rootState.disabled),
134
+ "data-orientation": rootState.orientation,
135
+ "data-dragging": dataAttr(rootState.dragging),
136
+ "data-invalid": dataAttr(rootState.invalid),
137
+ "data-focus": dataAttr(rootState.focused),
111
138
  dir: prop("dir"),
112
139
  style: getRootStyle(service)
113
140
  });
114
141
  },
115
142
  getValueTextProps() {
143
+ const rootState = getRootState();
116
144
  return normalize.element({
117
- ...parts.valueText.attrs,
145
+ ...parts.valueText.attrs(scope.id),
118
146
  dir: prop("dir"),
119
- "data-disabled": dataAttr(disabled),
120
- "data-orientation": prop("orientation"),
121
- "data-invalid": dataAttr(invalid),
122
- "data-focus": dataAttr(focused),
123
- id: dom.getValueTextId(scope)
147
+ "data-disabled": dataAttr(rootState.disabled),
148
+ "data-orientation": rootState.orientation,
149
+ "data-invalid": dataAttr(rootState.invalid),
150
+ "data-focus": dataAttr(rootState.focused)
124
151
  });
125
152
  },
126
153
  getTrackProps() {
154
+ const rootState = getRootState();
127
155
  return normalize.element({
128
- ...parts.track.attrs,
156
+ ...parts.track.attrs(scope.id),
129
157
  dir: prop("dir"),
130
- id: dom.getTrackId(scope),
131
- "data-disabled": dataAttr(disabled),
132
- "data-invalid": dataAttr(invalid),
133
- "data-dragging": dataAttr(dragging),
134
- "data-orientation": prop("orientation"),
135
- "data-focus": dataAttr(focused),
158
+ "data-disabled": dataAttr(rootState.disabled),
159
+ "data-invalid": dataAttr(rootState.invalid),
160
+ "data-dragging": dataAttr(rootState.dragging),
161
+ "data-orientation": rootState.orientation,
162
+ "data-focus": dataAttr(rootState.focused),
136
163
  style: { position: "relative" }
137
164
  });
138
165
  },
166
+ getThumbState,
139
167
  getThumbProps(props) {
140
168
  const { index = 0, name } = props;
141
- const value = sliderValue[index];
169
+ const thumbState = getThumbState({ index, name });
142
170
  const range = getRangeAtIndex(service, index);
143
- const valueText = prop("getAriaValueText")?.({ value, index });
171
+ const valueText = prop("getAriaValueText")?.({ value: thumbState.value, index });
144
172
  const _ariaLabel = Array.isArray(ariaLabel) ? ariaLabel[index] : ariaLabel;
145
173
  const _ariaLabelledBy = Array.isArray(ariaLabelledBy) ? ariaLabelledBy[index] : ariaLabelledBy;
146
174
  return normalize.element({
147
- ...parts.thumb.attrs,
175
+ ...parts.thumb.attrs(scope.id),
148
176
  dir: prop("dir"),
149
177
  "data-index": index,
150
178
  "data-name": name,
151
- id: dom.getThumbId(scope, index),
152
- "data-disabled": dataAttr(disabled),
179
+ "data-disabled": dataAttr(thumbState.disabled),
153
180
  "data-orientation": prop("orientation"),
154
- "data-focus": dataAttr(focused && focusedIndex === index),
155
- "data-dragging": dataAttr(dragging && focusedIndex === index),
181
+ "data-focus": dataAttr(thumbState.focused),
182
+ "data-dragging": dataAttr(thumbState.dragging),
156
183
  draggable: false,
157
- "aria-disabled": ariaAttr(disabled),
184
+ "aria-disabled": ariaAttr(thumbState.disabled),
158
185
  "aria-label": _ariaLabel,
159
186
  "aria-labelledby": _ariaLabelledBy ?? dom.getLabelId(scope),
160
187
  "aria-orientation": prop("orientation"),
161
188
  "aria-valuemax": range.max,
162
189
  "aria-valuemin": range.min,
163
- "aria-valuenow": sliderValue[index],
190
+ "aria-valuenow": thumbState.value,
164
191
  "aria-valuetext": valueText,
165
192
  role: "slider",
166
- tabIndex: disabled ? void 0 : 0,
193
+ tabIndex: thumbState.disabled ? void 0 : 0,
167
194
  style: getThumbStyle(service, index),
168
195
  onPointerDown(event) {
169
196
  if (!interactive) return;
@@ -238,38 +265,39 @@ function connect(service, normalize) {
238
265
  },
239
266
  getHiddenInputProps(props) {
240
267
  const { index = 0, name } = props;
268
+ const thumbState = getThumbState({ index, name });
241
269
  return normalize.input({
242
270
  name: name ?? (prop("name") ? prop("name") + (sliderValue.length > 1 ? "[]" : "") : void 0),
243
271
  form: prop("form"),
244
272
  type: "text",
245
273
  hidden: true,
246
- defaultValue: sliderValue[index],
274
+ defaultValue: thumbState.value,
247
275
  id: dom.getHiddenInputId(scope, index)
248
276
  });
249
277
  },
250
278
  getRangeProps() {
279
+ const rootState = getRootState();
251
280
  return normalize.element({
252
- id: dom.getRangeId(scope),
253
- ...parts.range.attrs,
281
+ ...parts.range.attrs(scope.id),
254
282
  dir: prop("dir"),
255
- "data-dragging": dataAttr(dragging),
256
- "data-focus": dataAttr(focused),
257
- "data-invalid": dataAttr(invalid),
258
- "data-disabled": dataAttr(disabled),
259
- "data-orientation": prop("orientation"),
283
+ "data-dragging": dataAttr(rootState.dragging),
284
+ "data-focus": dataAttr(rootState.focused),
285
+ "data-invalid": dataAttr(rootState.invalid),
286
+ "data-disabled": dataAttr(rootState.disabled),
287
+ "data-orientation": rootState.orientation,
260
288
  style: getRangeStyle(service)
261
289
  });
262
290
  },
263
291
  getControlProps() {
292
+ const rootState = getRootState();
264
293
  return normalize.element({
265
- ...parts.control.attrs,
294
+ ...parts.control.attrs(scope.id),
266
295
  dir: prop("dir"),
267
- id: dom.getControlId(scope),
268
- "data-dragging": dataAttr(dragging),
269
- "data-disabled": dataAttr(disabled),
270
- "data-orientation": prop("orientation"),
271
- "data-invalid": dataAttr(invalid),
272
- "data-focus": dataAttr(focused),
296
+ "data-dragging": dataAttr(rootState.dragging),
297
+ "data-disabled": dataAttr(rootState.disabled),
298
+ "data-orientation": rootState.orientation,
299
+ "data-invalid": dataAttr(rootState.invalid),
300
+ "data-focus": dataAttr(rootState.focused),
273
301
  style: getControlStyle(),
274
302
  onPointerDown(event) {
275
303
  if (!interactive) return;
@@ -284,7 +312,7 @@ function connect(service, normalize) {
284
312
  },
285
313
  getMarkerGroupProps() {
286
314
  return normalize.element({
287
- ...parts.markerGroup.attrs,
315
+ ...parts.markerGroup.attrs(scope.id),
288
316
  role: "presentation",
289
317
  dir: prop("dir"),
290
318
  "aria-hidden": true,
@@ -292,38 +320,31 @@ function connect(service, normalize) {
292
320
  style: getMarkerGroupStyle()
293
321
  });
294
322
  },
323
+ getMarkerState,
295
324
  getMarkerProps(props) {
296
325
  const style = getMarkerStyle(service, props.value);
297
- let markerState;
298
- if (props.value < first(sliderValue)) {
299
- markerState = "under-value";
300
- } else if (props.value > last(sliderValue)) {
301
- markerState = "over-value";
302
- } else {
303
- markerState = "at-value";
304
- }
326
+ const markerState = getMarkerState(props);
305
327
  return normalize.element({
306
- ...parts.marker.attrs,
307
- id: dom.getMarkerId(scope, props.value),
328
+ ...parts.marker.attrs(scope.id),
308
329
  role: "presentation",
309
330
  dir: prop("dir"),
310
331
  "data-orientation": prop("orientation"),
311
- "data-value": props.value,
312
- "data-disabled": dataAttr(disabled),
313
- "data-state": markerState,
332
+ "data-value": markerState.value,
333
+ "data-disabled": dataAttr(markerState.disabled),
334
+ "data-state": markerState.state,
314
335
  style
315
336
  });
316
337
  },
317
338
  getDraggingIndicatorProps(props) {
318
339
  const { index = 0 } = props;
319
- const isDragging = index === focusedIndex && dragging;
340
+ const thumbState = getThumbState({ index });
320
341
  return normalize.element({
321
- ...parts.draggingIndicator.attrs,
342
+ ...parts.draggingIndicator.attrs(scope.id),
322
343
  role: "presentation",
323
344
  dir: prop("dir"),
324
- hidden: !isDragging,
345
+ hidden: !thumbState.dragging,
325
346
  "data-orientation": prop("orientation"),
326
- "data-state": isDragging ? "open" : "closed",
347
+ "data-state": thumbState.dragging ? "open" : "closed",
327
348
  style: getThumbStyle(service, index)
328
349
  });
329
350
  }
@@ -43,22 +43,23 @@ __export(slider_dom_exports, {
43
43
  module.exports = __toCommonJS(slider_dom_exports);
44
44
  var import_dom_query = require("@zag-js/dom-query");
45
45
  var import_utils = require("@zag-js/utils");
46
- var getRootId = (ctx) => ctx.ids?.root ?? `slider:${ctx.id}`;
47
- var getThumbId = (ctx, index) => ctx.ids?.thumb?.(index) ?? `slider:${ctx.id}:thumb:${index}`;
48
- var getHiddenInputId = (ctx, index) => ctx.ids?.hiddenInput?.(index) ?? `slider:${ctx.id}:input:${index}`;
49
- var getControlId = (ctx) => ctx.ids?.control ?? `slider:${ctx.id}:control`;
50
- var getTrackId = (ctx) => ctx.ids?.track ?? `slider:${ctx.id}:track`;
51
- var getRangeId = (ctx) => ctx.ids?.range ?? `slider:${ctx.id}:range`;
52
- var getLabelId = (ctx) => ctx.ids?.label ?? `slider:${ctx.id}:label`;
53
- var getValueTextId = (ctx) => ctx.ids?.valueText ?? `slider:${ctx.id}:value-text`;
54
- var getMarkerId = (ctx, value) => ctx.ids?.marker?.(value) ?? `slider:${ctx.id}:marker:${value}`;
55
- var getRootEl = (ctx) => ctx.getById(getRootId(ctx));
56
- var getThumbEl = (ctx, index) => ctx.getById(getThumbId(ctx, index));
57
- var getThumbEls = (ctx) => (0, import_dom_query.queryAll)(getControlEl(ctx), "[role=slider]");
46
+ var import_slider = require("./slider.anatomy.js");
47
+ var getRootId = (ctx) => ctx.ids?.root ?? `${ctx.id}`;
48
+ var getThumbId = (ctx, index) => ctx.ids?.thumb?.(index) ?? `${ctx.id}:thumb:${index}`;
49
+ var getHiddenInputId = (ctx, index) => ctx.ids?.hiddenInput?.(index) ?? `${ctx.id}:input:${index}`;
50
+ var getControlId = (ctx) => ctx.ids?.control ?? `${ctx.id}:control`;
51
+ var getTrackId = (ctx) => ctx.ids?.track ?? `${ctx.id}:track`;
52
+ var getRangeId = (ctx) => ctx.ids?.range ?? `${ctx.id}:range`;
53
+ var getLabelId = (ctx) => ctx.ids?.label ?? `${ctx.id}:label`;
54
+ var getValueTextId = (ctx) => ctx.ids?.valueText ?? `${ctx.id}:value-text`;
55
+ var getMarkerId = (ctx, value) => ctx.ids?.marker?.(value) ?? `${ctx.id}:marker:${value}`;
56
+ var getRootEl = (ctx) => ctx.query(ctx.selector(import_slider.parts.root));
57
+ var getThumbEl = (ctx, index) => ctx.query(`${ctx.selector(import_slider.parts.thumb)}[data-index="${index}"]`);
58
+ var getThumbEls = (ctx) => ctx.queryAll(ctx.selector(import_slider.parts.thumb));
58
59
  var getFirstThumbEl = (ctx) => getThumbEls(ctx)[0];
59
60
  var getHiddenInputEl = (ctx, index) => ctx.getById(getHiddenInputId(ctx, index));
60
- var getControlEl = (ctx) => ctx.getById(getControlId(ctx));
61
- var getRangeEl = (ctx) => ctx.getById(getRangeId(ctx));
61
+ var getControlEl = (ctx) => ctx.query(ctx.selector(import_slider.parts.control));
62
+ var getRangeEl = (ctx) => ctx.query(ctx.selector(import_slider.parts.range));
62
63
  var getThumbInset = (thumbSize, thumbAlignment, orientation) => {
63
64
  const isContain = thumbAlignment === "contain";
64
65
  const isVertical = orientation === "vertical";
@@ -1,22 +1,23 @@
1
1
  // src/slider.dom.ts
2
- import { dispatchInputValueEvent, queryAll } from "@zag-js/dom-query";
2
+ import { dispatchInputValueEvent } from "@zag-js/dom-query";
3
3
  import { clampPercent, getPercentValue } from "@zag-js/utils";
4
- var getRootId = (ctx) => ctx.ids?.root ?? `slider:${ctx.id}`;
5
- var getThumbId = (ctx, index) => ctx.ids?.thumb?.(index) ?? `slider:${ctx.id}:thumb:${index}`;
6
- var getHiddenInputId = (ctx, index) => ctx.ids?.hiddenInput?.(index) ?? `slider:${ctx.id}:input:${index}`;
7
- var getControlId = (ctx) => ctx.ids?.control ?? `slider:${ctx.id}:control`;
8
- var getTrackId = (ctx) => ctx.ids?.track ?? `slider:${ctx.id}:track`;
9
- var getRangeId = (ctx) => ctx.ids?.range ?? `slider:${ctx.id}:range`;
10
- var getLabelId = (ctx) => ctx.ids?.label ?? `slider:${ctx.id}:label`;
11
- var getValueTextId = (ctx) => ctx.ids?.valueText ?? `slider:${ctx.id}:value-text`;
12
- var getMarkerId = (ctx, value) => ctx.ids?.marker?.(value) ?? `slider:${ctx.id}:marker:${value}`;
13
- var getRootEl = (ctx) => ctx.getById(getRootId(ctx));
14
- var getThumbEl = (ctx, index) => ctx.getById(getThumbId(ctx, index));
15
- var getThumbEls = (ctx) => queryAll(getControlEl(ctx), "[role=slider]");
4
+ import { parts } from "./slider.anatomy.mjs";
5
+ var getRootId = (ctx) => ctx.ids?.root ?? `${ctx.id}`;
6
+ var getThumbId = (ctx, index) => ctx.ids?.thumb?.(index) ?? `${ctx.id}:thumb:${index}`;
7
+ var getHiddenInputId = (ctx, index) => ctx.ids?.hiddenInput?.(index) ?? `${ctx.id}:input:${index}`;
8
+ var getControlId = (ctx) => ctx.ids?.control ?? `${ctx.id}:control`;
9
+ var getTrackId = (ctx) => ctx.ids?.track ?? `${ctx.id}:track`;
10
+ var getRangeId = (ctx) => ctx.ids?.range ?? `${ctx.id}:range`;
11
+ var getLabelId = (ctx) => ctx.ids?.label ?? `${ctx.id}:label`;
12
+ var getValueTextId = (ctx) => ctx.ids?.valueText ?? `${ctx.id}:value-text`;
13
+ var getMarkerId = (ctx, value) => ctx.ids?.marker?.(value) ?? `${ctx.id}:marker:${value}`;
14
+ var getRootEl = (ctx) => ctx.query(ctx.selector(parts.root));
15
+ var getThumbEl = (ctx, index) => ctx.query(`${ctx.selector(parts.thumb)}[data-index="${index}"]`);
16
+ var getThumbEls = (ctx) => ctx.queryAll(ctx.selector(parts.thumb));
16
17
  var getFirstThumbEl = (ctx) => getThumbEls(ctx)[0];
17
18
  var getHiddenInputEl = (ctx, index) => ctx.getById(getHiddenInputId(ctx, index));
18
- var getControlEl = (ctx) => ctx.getById(getControlId(ctx));
19
- var getRangeEl = (ctx) => ctx.getById(getRangeId(ctx));
19
+ var getControlEl = (ctx) => ctx.query(ctx.selector(parts.control));
20
+ var getRangeEl = (ctx) => ctx.query(ctx.selector(parts.range));
20
21
  var getThumbInset = (thumbSize, thumbAlignment, orientation) => {
21
22
  const isContain = thumbAlignment === "contain";
22
23
  const isVertical = orientation === "vertical";
@@ -32,6 +32,7 @@ __export(slider_style_exports, {
32
32
  });
33
33
  module.exports = __toCommonJS(slider_style_exports);
34
34
  var import_utils = require("@zag-js/utils");
35
+ var import_slider = require("./slider.utils.js");
35
36
  function getBounds(value) {
36
37
  const firstValue = value[0];
37
38
  const lastThumb = value[value.length - 1];
@@ -42,16 +43,9 @@ function getRangeOffsets(params) {
42
43
  const valuePercent = computed("valuePercent");
43
44
  const [firstPercent, lastPercent] = getBounds(valuePercent);
44
45
  if (valuePercent.length === 1) {
45
- if (prop("origin") === "center") {
46
- const isNegative = valuePercent[0] < 50;
47
- const start = isNegative ? `${valuePercent[0]}%` : "50%";
48
- const end = isNegative ? "50%" : `${100 - valuePercent[0]}%`;
49
- return { start, end };
50
- }
51
- if (prop("origin") === "end") {
52
- return { start: `${lastPercent}%`, end: "0%" };
53
- }
54
- return { start: "0%", end: `${100 - lastPercent}%` };
46
+ const originPercent = (0, import_slider.getOriginPercent)(prop("origin"), prop("min"), prop("max"));
47
+ const { start, end } = (0, import_slider.getFillRange)(valuePercent[0], originPercent);
48
+ return { start: `${start}%`, end: `${end}%` };
55
49
  }
56
50
  return { start: `${firstPercent}%`, end: `${100 - lastPercent}%` };
57
51
  }
@@ -1,5 +1,6 @@
1
1
  // src/slider.style.ts
2
2
  import { getValuePercent, getValueTransformer, toPx } from "@zag-js/utils";
3
+ import { getFillRange, getOriginPercent } from "./slider.utils.mjs";
3
4
  function getBounds(value) {
4
5
  const firstValue = value[0];
5
6
  const lastThumb = value[value.length - 1];
@@ -10,16 +11,9 @@ function getRangeOffsets(params) {
10
11
  const valuePercent = computed("valuePercent");
11
12
  const [firstPercent, lastPercent] = getBounds(valuePercent);
12
13
  if (valuePercent.length === 1) {
13
- if (prop("origin") === "center") {
14
- const isNegative = valuePercent[0] < 50;
15
- const start = isNegative ? `${valuePercent[0]}%` : "50%";
16
- const end = isNegative ? "50%" : `${100 - valuePercent[0]}%`;
17
- return { start, end };
18
- }
19
- if (prop("origin") === "end") {
20
- return { start: `${lastPercent}%`, end: "0%" };
21
- }
22
- return { start: "0%", end: `${100 - lastPercent}%` };
14
+ const originPercent = getOriginPercent(prop("origin"), prop("min"), prop("max"));
15
+ const { start, end } = getFillRange(valuePercent[0], originPercent);
16
+ return { start: `${start}%`, end: `${end}%` };
23
17
  }
24
18
  return { start: `${firstPercent}%`, end: `${100 - lastPercent}%` };
25
19
  }
@@ -3,6 +3,7 @@ import { PropTypes, RequiredBy, DirectionProperty, CommonProperties } from '@zag
3
3
 
4
4
  type ThumbCollisionBehavior = "none" | "push" | "swap";
5
5
  type ThumbAlignment = "contain" | "center";
6
+ type SliderOrigin = "start" | "center" | "end" | number;
6
7
  interface ValueChangeDetails {
7
8
  value: number[];
8
9
  }
@@ -121,15 +122,14 @@ interface SliderProps extends DirectionProperty, CommonProperties {
121
122
  */
122
123
  orientation?: "vertical" | "horizontal" | undefined;
123
124
  /**
124
- * The origin of the slider range. The track is filled from the origin
125
- * to the thumb for single values.
126
- * - "start": Useful when the value represents an absolute value
127
- * - "center": Useful when the value represents an offset (relative)
128
- * - "end": Useful when the value represents an offset from the end
125
+ * The origin of the slider range. The track is filled from the origin to the thumb.
126
+ * - `"start"` / `"end"`: fill from `min` / `max`
127
+ * - `"center"`: fill from the midpoint of `min`/`max`
128
+ * - a `number`: fill from that value instead, for when the neutral point isn't the midpoint
129
129
  *
130
130
  * @default "start"
131
131
  */
132
- origin?: "start" | "center" | "end" | undefined;
132
+ origin?: SliderOrigin | undefined;
133
133
  /**
134
134
  * The alignment of the slider thumb relative to the track
135
135
  * - `center`: the thumb will extend beyond the bounds of the slider track.
@@ -242,13 +242,71 @@ interface Size {
242
242
  interface MarkerProps {
243
243
  value: number;
244
244
  }
245
+ interface MarkerState {
246
+ /**
247
+ * The value of the marker
248
+ */
249
+ value: number;
250
+ /**
251
+ * Whether the marker is disabled
252
+ */
253
+ disabled: boolean;
254
+ /**
255
+ * The state of the marker relative to the slider value
256
+ */
257
+ state: "under-value" | "over-value" | "at-value";
258
+ }
245
259
  interface ThumbProps {
246
260
  index: number;
247
261
  name?: string | undefined;
248
262
  }
263
+ interface ThumbState {
264
+ /**
265
+ * The index of the thumb
266
+ */
267
+ index: number;
268
+ /**
269
+ * The value of the thumb
270
+ */
271
+ value: number;
272
+ /**
273
+ * Whether the thumb is disabled
274
+ */
275
+ disabled: boolean;
276
+ /**
277
+ * Whether the thumb is focused
278
+ */
279
+ focused: boolean;
280
+ /**
281
+ * Whether the thumb is being dragged
282
+ */
283
+ dragging: boolean;
284
+ }
249
285
  interface DraggingIndicatorProps {
250
286
  index: number;
251
287
  }
288
+ interface RootState {
289
+ /**
290
+ * Whether the slider is disabled
291
+ */
292
+ disabled: boolean;
293
+ /**
294
+ * Whether the slider is invalid
295
+ */
296
+ invalid: boolean;
297
+ /**
298
+ * Whether the slider is being dragged
299
+ */
300
+ dragging: boolean;
301
+ /**
302
+ * Whether the slider is focused
303
+ */
304
+ focused: boolean;
305
+ /**
306
+ * The orientation of the slider
307
+ */
308
+ orientation: "vertical" | "horizontal";
309
+ }
252
310
  interface SliderApi<T extends PropTypes = PropTypes> {
253
311
  /**
254
312
  * The value of the slider.
@@ -310,17 +368,29 @@ interface SliderApi<T extends PropTypes = PropTypes> {
310
368
  * Function to focus the slider. This focuses the first thumb.
311
369
  */
312
370
  focus: VoidFunction;
371
+ /**
372
+ * Returns the state of the slider
373
+ */
374
+ getRootState: () => RootState;
313
375
  getLabelProps: () => T["label"];
314
376
  getRootProps: () => T["element"];
315
377
  getValueTextProps: () => T["element"];
316
378
  getTrackProps: () => T["element"];
379
+ /**
380
+ * Returns the state of a specific thumb
381
+ */
382
+ getThumbState: (props: ThumbProps) => ThumbState;
317
383
  getThumbProps: (props: ThumbProps) => T["element"];
318
384
  getHiddenInputProps: (props: ThumbProps) => T["input"];
319
385
  getRangeProps: () => T["element"];
320
386
  getControlProps: () => T["element"];
321
387
  getMarkerGroupProps: () => T["element"];
388
+ /**
389
+ * Returns the state of a specific marker
390
+ */
391
+ getMarkerState: (props: MarkerProps) => MarkerState;
322
392
  getMarkerProps: (props: MarkerProps) => T["element"];
323
393
  getDraggingIndicatorProps: (props: DraggingIndicatorProps) => T["element"];
324
394
  }
325
395
 
326
- export type { DraggingIndicatorProps, ElementIds, FocusChangeDetails, MarkerProps, SliderApi, SliderMachine, SliderProps, SliderSchema, SliderService, ThumbAlignment, ThumbCollisionBehavior, ThumbProps, ValueChangeDetails, ValueTextDetails };
396
+ export type { DraggingIndicatorProps, ElementIds, FocusChangeDetails, MarkerProps, MarkerState, RootState, SliderApi, SliderMachine, SliderOrigin, SliderProps, SliderSchema, SliderService, ThumbAlignment, ThumbCollisionBehavior, ThumbProps, ThumbState, ValueChangeDetails, ValueTextDetails };
@@ -3,6 +3,7 @@ import { PropTypes, RequiredBy, DirectionProperty, CommonProperties } from '@zag
3
3
 
4
4
  type ThumbCollisionBehavior = "none" | "push" | "swap";
5
5
  type ThumbAlignment = "contain" | "center";
6
+ type SliderOrigin = "start" | "center" | "end" | number;
6
7
  interface ValueChangeDetails {
7
8
  value: number[];
8
9
  }
@@ -121,15 +122,14 @@ interface SliderProps extends DirectionProperty, CommonProperties {
121
122
  */
122
123
  orientation?: "vertical" | "horizontal" | undefined;
123
124
  /**
124
- * The origin of the slider range. The track is filled from the origin
125
- * to the thumb for single values.
126
- * - "start": Useful when the value represents an absolute value
127
- * - "center": Useful when the value represents an offset (relative)
128
- * - "end": Useful when the value represents an offset from the end
125
+ * The origin of the slider range. The track is filled from the origin to the thumb.
126
+ * - `"start"` / `"end"`: fill from `min` / `max`
127
+ * - `"center"`: fill from the midpoint of `min`/`max`
128
+ * - a `number`: fill from that value instead, for when the neutral point isn't the midpoint
129
129
  *
130
130
  * @default "start"
131
131
  */
132
- origin?: "start" | "center" | "end" | undefined;
132
+ origin?: SliderOrigin | undefined;
133
133
  /**
134
134
  * The alignment of the slider thumb relative to the track
135
135
  * - `center`: the thumb will extend beyond the bounds of the slider track.
@@ -242,13 +242,71 @@ interface Size {
242
242
  interface MarkerProps {
243
243
  value: number;
244
244
  }
245
+ interface MarkerState {
246
+ /**
247
+ * The value of the marker
248
+ */
249
+ value: number;
250
+ /**
251
+ * Whether the marker is disabled
252
+ */
253
+ disabled: boolean;
254
+ /**
255
+ * The state of the marker relative to the slider value
256
+ */
257
+ state: "under-value" | "over-value" | "at-value";
258
+ }
245
259
  interface ThumbProps {
246
260
  index: number;
247
261
  name?: string | undefined;
248
262
  }
263
+ interface ThumbState {
264
+ /**
265
+ * The index of the thumb
266
+ */
267
+ index: number;
268
+ /**
269
+ * The value of the thumb
270
+ */
271
+ value: number;
272
+ /**
273
+ * Whether the thumb is disabled
274
+ */
275
+ disabled: boolean;
276
+ /**
277
+ * Whether the thumb is focused
278
+ */
279
+ focused: boolean;
280
+ /**
281
+ * Whether the thumb is being dragged
282
+ */
283
+ dragging: boolean;
284
+ }
249
285
  interface DraggingIndicatorProps {
250
286
  index: number;
251
287
  }
288
+ interface RootState {
289
+ /**
290
+ * Whether the slider is disabled
291
+ */
292
+ disabled: boolean;
293
+ /**
294
+ * Whether the slider is invalid
295
+ */
296
+ invalid: boolean;
297
+ /**
298
+ * Whether the slider is being dragged
299
+ */
300
+ dragging: boolean;
301
+ /**
302
+ * Whether the slider is focused
303
+ */
304
+ focused: boolean;
305
+ /**
306
+ * The orientation of the slider
307
+ */
308
+ orientation: "vertical" | "horizontal";
309
+ }
252
310
  interface SliderApi<T extends PropTypes = PropTypes> {
253
311
  /**
254
312
  * The value of the slider.
@@ -310,17 +368,29 @@ interface SliderApi<T extends PropTypes = PropTypes> {
310
368
  * Function to focus the slider. This focuses the first thumb.
311
369
  */
312
370
  focus: VoidFunction;
371
+ /**
372
+ * Returns the state of the slider
373
+ */
374
+ getRootState: () => RootState;
313
375
  getLabelProps: () => T["label"];
314
376
  getRootProps: () => T["element"];
315
377
  getValueTextProps: () => T["element"];
316
378
  getTrackProps: () => T["element"];
379
+ /**
380
+ * Returns the state of a specific thumb
381
+ */
382
+ getThumbState: (props: ThumbProps) => ThumbState;
317
383
  getThumbProps: (props: ThumbProps) => T["element"];
318
384
  getHiddenInputProps: (props: ThumbProps) => T["input"];
319
385
  getRangeProps: () => T["element"];
320
386
  getControlProps: () => T["element"];
321
387
  getMarkerGroupProps: () => T["element"];
388
+ /**
389
+ * Returns the state of a specific marker
390
+ */
391
+ getMarkerState: (props: MarkerProps) => MarkerState;
322
392
  getMarkerProps: (props: MarkerProps) => T["element"];
323
393
  getDraggingIndicatorProps: (props: DraggingIndicatorProps) => T["element"];
324
394
  }
325
395
 
326
- export type { DraggingIndicatorProps, ElementIds, FocusChangeDetails, MarkerProps, SliderApi, SliderMachine, SliderProps, SliderSchema, SliderService, ThumbAlignment, ThumbCollisionBehavior, ThumbProps, ValueChangeDetails, ValueTextDetails };
396
+ export type { DraggingIndicatorProps, ElementIds, FocusChangeDetails, MarkerProps, MarkerState, RootState, SliderApi, SliderMachine, SliderOrigin, SliderProps, SliderSchema, SliderService, ThumbAlignment, ThumbCollisionBehavior, ThumbProps, ThumbState, ValueChangeDetails, ValueTextDetails };
@@ -1,5 +1,5 @@
1
1
  import { Params } from '@zag-js/core';
2
- import { SliderSchema, ThumbCollisionBehavior } from './slider.types.mjs';
2
+ import { SliderSchema, SliderOrigin, ThumbCollisionBehavior } from './slider.types.mjs';
3
3
  import '@zag-js/types';
4
4
 
5
5
  type Ctx = Params<SliderSchema>;
@@ -21,5 +21,12 @@ declare function increment(params: Pick<Ctx, "context" | "prop">, index?: number
21
21
  declare function getClosestIndex(params: Pick<Ctx, "context" | "prop">, pointValue: number): number;
22
22
  declare function selectMovableThumb(params: Pick<Ctx, "context" | "prop">, index: number): number;
23
23
  declare function assignArray(current: number[], next: number[]): void;
24
+ /** Resolves the `origin` prop to a percent position (0-100) within `min`-`max`. */
25
+ declare function getOriginPercent(origin: SliderOrigin, min: number, max: number): number;
26
+ /** Track-fill insets (from the left/right edges) needed to fill between origin and value. */
27
+ declare function getFillRange(valuePercent: number, originPercent: number): {
28
+ start: number;
29
+ end: number;
30
+ };
24
31
 
25
- export { assignArray, constrainValue, decrement, getClosestIndex, getRangeAtIndex, increment, normalizeValues, resolveThumbCollision, selectMovableThumb };
32
+ export { assignArray, constrainValue, decrement, getClosestIndex, getFillRange, getOriginPercent, getRangeAtIndex, increment, normalizeValues, resolveThumbCollision, selectMovableThumb };
@@ -1,5 +1,5 @@
1
1
  import { Params } from '@zag-js/core';
2
- import { SliderSchema, ThumbCollisionBehavior } from './slider.types.js';
2
+ import { SliderSchema, SliderOrigin, ThumbCollisionBehavior } from './slider.types.js';
3
3
  import '@zag-js/types';
4
4
 
5
5
  type Ctx = Params<SliderSchema>;
@@ -21,5 +21,12 @@ declare function increment(params: Pick<Ctx, "context" | "prop">, index?: number
21
21
  declare function getClosestIndex(params: Pick<Ctx, "context" | "prop">, pointValue: number): number;
22
22
  declare function selectMovableThumb(params: Pick<Ctx, "context" | "prop">, index: number): number;
23
23
  declare function assignArray(current: number[], next: number[]): void;
24
+ /** Resolves the `origin` prop to a percent position (0-100) within `min`-`max`. */
25
+ declare function getOriginPercent(origin: SliderOrigin, min: number, max: number): number;
26
+ /** Track-fill insets (from the left/right edges) needed to fill between origin and value. */
27
+ declare function getFillRange(valuePercent: number, originPercent: number): {
28
+ start: number;
29
+ end: number;
30
+ };
24
31
 
25
- export { assignArray, constrainValue, decrement, getClosestIndex, getRangeAtIndex, increment, normalizeValues, resolveThumbCollision, selectMovableThumb };
32
+ export { assignArray, constrainValue, decrement, getClosestIndex, getFillRange, getOriginPercent, getRangeAtIndex, increment, normalizeValues, resolveThumbCollision, selectMovableThumb };
@@ -24,6 +24,8 @@ __export(slider_utils_exports, {
24
24
  constrainValue: () => constrainValue,
25
25
  decrement: () => decrement,
26
26
  getClosestIndex: () => getClosestIndex,
27
+ getFillRange: () => getFillRange,
28
+ getOriginPercent: () => getOriginPercent,
27
29
  getRangeAtIndex: () => getRangeAtIndex,
28
30
  increment: () => increment,
29
31
  normalizeValues: () => normalizeValues,
@@ -183,12 +185,35 @@ function assignArray(current, next) {
183
185
  current[i] = value;
184
186
  }
185
187
  }
188
+ function getOriginPercent(origin, min, max) {
189
+ if (typeof origin === "number") {
190
+ return (0, import_utils.clampValue)(100 * (0, import_utils.getValuePercent)(origin, min, max), 0, 100);
191
+ }
192
+ switch (origin) {
193
+ case "end":
194
+ return 100;
195
+ case "center":
196
+ return 50;
197
+ case "start":
198
+ default:
199
+ return 0;
200
+ }
201
+ }
202
+ function getFillRange(valuePercent, originPercent) {
203
+ const isBeforeOrigin = valuePercent < originPercent;
204
+ return {
205
+ start: isBeforeOrigin ? valuePercent : originPercent,
206
+ end: isBeforeOrigin ? 100 - originPercent : 100 - valuePercent
207
+ };
208
+ }
186
209
  // Annotate the CommonJS export names for ESM import in node:
187
210
  0 && (module.exports = {
188
211
  assignArray,
189
212
  constrainValue,
190
213
  decrement,
191
214
  getClosestIndex,
215
+ getFillRange,
216
+ getOriginPercent,
192
217
  getRangeAtIndex,
193
218
  increment,
194
219
  normalizeValues,
@@ -1,5 +1,12 @@
1
1
  // src/slider.utils.ts
2
- import { clampValue, getNextStepValue, getPreviousStepValue, getValueRanges, snapValueToStep } from "@zag-js/utils";
2
+ import {
3
+ clampValue,
4
+ getNextStepValue,
5
+ getPreviousStepValue,
6
+ getValuePercent,
7
+ getValueRanges,
8
+ snapValueToStep
9
+ } from "@zag-js/utils";
3
10
  function getThumbBounds(ctx) {
4
11
  const { index, values, min, max, gap } = ctx;
5
12
  const prevThumb = values[index - 1];
@@ -151,11 +158,34 @@ function assignArray(current, next) {
151
158
  current[i] = value;
152
159
  }
153
160
  }
161
+ function getOriginPercent(origin, min, max) {
162
+ if (typeof origin === "number") {
163
+ return clampValue(100 * getValuePercent(origin, min, max), 0, 100);
164
+ }
165
+ switch (origin) {
166
+ case "end":
167
+ return 100;
168
+ case "center":
169
+ return 50;
170
+ case "start":
171
+ default:
172
+ return 0;
173
+ }
174
+ }
175
+ function getFillRange(valuePercent, originPercent) {
176
+ const isBeforeOrigin = valuePercent < originPercent;
177
+ return {
178
+ start: isBeforeOrigin ? valuePercent : originPercent,
179
+ end: isBeforeOrigin ? 100 - originPercent : 100 - valuePercent
180
+ };
181
+ }
154
182
  export {
155
183
  assignArray,
156
184
  constrainValue,
157
185
  decrement,
158
186
  getClosestIndex,
187
+ getFillRange,
188
+ getOriginPercent,
159
189
  getRangeAtIndex,
160
190
  increment,
161
191
  normalizeValues,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zag-js/slider",
3
- "version": "1.43.0",
3
+ "version": "2.0.0-next.1",
4
4
  "description": "Core logic for the slider widget implemented as a state machine",
5
5
  "keywords": [
6
6
  "js",
@@ -30,11 +30,11 @@
30
30
  "url": "https://github.com/chakra-ui/zag/issues"
31
31
  },
32
32
  "dependencies": {
33
- "@zag-js/anatomy": "1.43.0",
34
- "@zag-js/core": "1.43.0",
35
- "@zag-js/dom-query": "1.43.0",
36
- "@zag-js/utils": "1.43.0",
37
- "@zag-js/types": "1.43.0"
33
+ "@zag-js/anatomy": "2.0.0-next.1",
34
+ "@zag-js/core": "2.0.0-next.1",
35
+ "@zag-js/dom-query": "2.0.0-next.1",
36
+ "@zag-js/types": "2.0.0-next.1",
37
+ "@zag-js/utils": "2.0.0-next.1"
38
38
  },
39
39
  "devDependencies": {
40
40
  "clean-package": "2.2.0"