@zag-js/slider 2.0.0-next.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
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,44 +146,48 @@ function connect(service, normalize) {
119
146
  });
120
147
  },
121
148
  getRootProps() {
149
+ const rootState = getRootState();
122
150
  return normalize.element({
123
151
  ...import_slider.parts.root.attrs(scope.id),
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),
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),
129
157
  dir: prop("dir"),
130
158
  style: (0, import_slider2.getRootStyle)(service)
131
159
  });
132
160
  },
133
161
  getValueTextProps() {
162
+ const rootState = getRootState();
134
163
  return normalize.element({
135
164
  ...import_slider.parts.valueText.attrs(scope.id),
136
165
  dir: prop("dir"),
137
- "data-disabled": (0, import_dom_query.dataAttr)(disabled),
138
- "data-orientation": prop("orientation"),
139
- "data-invalid": (0, import_dom_query.dataAttr)(invalid),
140
- "data-focus": (0, import_dom_query.dataAttr)(focused)
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)
141
170
  });
142
171
  },
143
172
  getTrackProps() {
173
+ const rootState = getRootState();
144
174
  return normalize.element({
145
175
  ...import_slider.parts.track.attrs(scope.id),
146
176
  dir: prop("dir"),
147
- "data-disabled": (0, import_dom_query.dataAttr)(disabled),
148
- "data-invalid": (0, import_dom_query.dataAttr)(invalid),
149
- "data-dragging": (0, import_dom_query.dataAttr)(dragging),
150
- "data-orientation": prop("orientation"),
151
- "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),
152
182
  style: { position: "relative" }
153
183
  });
154
184
  },
185
+ getThumbState,
155
186
  getThumbProps(props) {
156
187
  const { index = 0, name } = props;
157
- const value = sliderValue[index];
188
+ const thumbState = getThumbState({ index, name });
158
189
  const range = (0, import_slider3.getRangeAtIndex)(service, index);
159
- const valueText = prop("getAriaValueText")?.({ value, index });
190
+ const valueText = prop("getAriaValueText")?.({ value: thumbState.value, index });
160
191
  const _ariaLabel = Array.isArray(ariaLabel) ? ariaLabel[index] : ariaLabel;
161
192
  const _ariaLabelledBy = Array.isArray(ariaLabelledBy) ? ariaLabelledBy[index] : ariaLabelledBy;
162
193
  return normalize.element({
@@ -164,21 +195,21 @@ function connect(service, normalize) {
164
195
  dir: prop("dir"),
165
196
  "data-index": index,
166
197
  "data-name": name,
167
- "data-disabled": (0, import_dom_query.dataAttr)(disabled),
198
+ "data-disabled": (0, import_dom_query.dataAttr)(thumbState.disabled),
168
199
  "data-orientation": prop("orientation"),
169
- "data-focus": (0, import_dom_query.dataAttr)(focused && focusedIndex === index),
170
- "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),
171
202
  draggable: false,
172
- "aria-disabled": (0, import_dom_query.ariaAttr)(disabled),
203
+ "aria-disabled": (0, import_dom_query.ariaAttr)(thumbState.disabled),
173
204
  "aria-label": _ariaLabel,
174
205
  "aria-labelledby": _ariaLabelledBy ?? dom.getLabelId(scope),
175
206
  "aria-orientation": prop("orientation"),
176
207
  "aria-valuemax": range.max,
177
208
  "aria-valuemin": range.min,
178
- "aria-valuenow": sliderValue[index],
209
+ "aria-valuenow": thumbState.value,
179
210
  "aria-valuetext": valueText,
180
211
  role: "slider",
181
- tabIndex: disabled ? void 0 : 0,
212
+ tabIndex: thumbState.disabled ? void 0 : 0,
182
213
  style: (0, import_slider2.getThumbStyle)(service, index),
183
214
  onPointerDown(event) {
184
215
  if (!interactive) return;
@@ -207,7 +238,7 @@ function connect(service, normalize) {
207
238
  onKeyDown(event) {
208
239
  if (event.defaultPrevented) return;
209
240
  if (!interactive) return;
210
- const step = (0, import_dom_query.getEventStep)(event) * prop("step");
241
+ const step = (0, import_dom_query.getEventStepValue)(event, { step: prop("step"), largeStep: prop("largeStep") });
211
242
  const keyMap = {
212
243
  ArrowUp() {
213
244
  if (isHorizontal) return;
@@ -253,36 +284,39 @@ function connect(service, normalize) {
253
284
  },
254
285
  getHiddenInputProps(props) {
255
286
  const { index = 0, name } = props;
287
+ const thumbState = getThumbState({ index, name });
256
288
  return normalize.input({
257
289
  name: name ?? (prop("name") ? prop("name") + (sliderValue.length > 1 ? "[]" : "") : void 0),
258
290
  form: prop("form"),
259
291
  type: "text",
260
292
  hidden: true,
261
- defaultValue: sliderValue[index],
293
+ defaultValue: thumbState.value,
262
294
  id: dom.getHiddenInputId(scope, index)
263
295
  });
264
296
  },
265
297
  getRangeProps() {
298
+ const rootState = getRootState();
266
299
  return normalize.element({
267
300
  ...import_slider.parts.range.attrs(scope.id),
268
301
  dir: prop("dir"),
269
- "data-dragging": (0, import_dom_query.dataAttr)(dragging),
270
- "data-focus": (0, import_dom_query.dataAttr)(focused),
271
- "data-invalid": (0, import_dom_query.dataAttr)(invalid),
272
- "data-disabled": (0, import_dom_query.dataAttr)(disabled),
273
- "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,
274
307
  style: (0, import_slider2.getRangeStyle)(service)
275
308
  });
276
309
  },
277
310
  getControlProps() {
311
+ const rootState = getRootState();
278
312
  return normalize.element({
279
313
  ...import_slider.parts.control.attrs(scope.id),
280
314
  dir: prop("dir"),
281
- "data-dragging": (0, import_dom_query.dataAttr)(dragging),
282
- "data-disabled": (0, import_dom_query.dataAttr)(disabled),
283
- "data-orientation": prop("orientation"),
284
- "data-invalid": (0, import_dom_query.dataAttr)(invalid),
285
- "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),
286
320
  style: (0, import_slider2.getControlStyle)(),
287
321
  onPointerDown(event) {
288
322
  if (!interactive) return;
@@ -305,37 +339,31 @@ function connect(service, normalize) {
305
339
  style: (0, import_slider2.getMarkerGroupStyle)()
306
340
  });
307
341
  },
342
+ getMarkerState,
308
343
  getMarkerProps(props) {
309
344
  const style = (0, import_slider2.getMarkerStyle)(service, props.value);
310
- let markerState;
311
- if (props.value < (0, import_utils.first)(sliderValue)) {
312
- markerState = "under-value";
313
- } else if (props.value > (0, import_utils.last)(sliderValue)) {
314
- markerState = "over-value";
315
- } else {
316
- markerState = "at-value";
317
- }
345
+ const markerState = getMarkerState(props);
318
346
  return normalize.element({
319
347
  ...import_slider.parts.marker.attrs(scope.id),
320
348
  role: "presentation",
321
349
  dir: prop("dir"),
322
350
  "data-orientation": prop("orientation"),
323
- "data-value": props.value,
324
- "data-disabled": (0, import_dom_query.dataAttr)(disabled),
325
- "data-state": markerState,
351
+ "data-value": markerState.value,
352
+ "data-disabled": (0, import_dom_query.dataAttr)(markerState.disabled),
353
+ "data-state": markerState.state,
326
354
  style
327
355
  });
328
356
  },
329
357
  getDraggingIndicatorProps(props) {
330
358
  const { index = 0 } = props;
331
- const isDragging = index === focusedIndex && dragging;
359
+ const thumbState = getThumbState({ index });
332
360
  return normalize.element({
333
361
  ...import_slider.parts.draggingIndicator.attrs(scope.id),
334
362
  role: "presentation",
335
363
  dir: prop("dir"),
336
- hidden: !isDragging,
364
+ hidden: !thumbState.dragging,
337
365
  "data-orientation": prop("orientation"),
338
- "data-state": isDragging ? "open" : "closed",
366
+ "data-state": thumbState.dragging ? "open" : "closed",
339
367
  style: (0, import_slider2.getThumbStyle)(service, index)
340
368
  });
341
369
  }
@@ -4,7 +4,7 @@ import {
4
4
  dataAttr,
5
5
  getEventKey,
6
6
  getEventPoint,
7
- getEventStep,
7
+ getEventStepValue,
8
8
  isLeftClick,
9
9
  isModifierKey
10
10
  } from "@zag-js/dom-query";
@@ -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
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,44 +127,48 @@ function connect(service, normalize) {
100
127
  });
101
128
  },
102
129
  getRootProps() {
130
+ const rootState = getRootState();
103
131
  return normalize.element({
104
132
  ...parts.root.attrs(scope.id),
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),
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),
110
138
  dir: prop("dir"),
111
139
  style: getRootStyle(service)
112
140
  });
113
141
  },
114
142
  getValueTextProps() {
143
+ const rootState = getRootState();
115
144
  return normalize.element({
116
145
  ...parts.valueText.attrs(scope.id),
117
146
  dir: prop("dir"),
118
- "data-disabled": dataAttr(disabled),
119
- "data-orientation": prop("orientation"),
120
- "data-invalid": dataAttr(invalid),
121
- "data-focus": dataAttr(focused)
147
+ "data-disabled": dataAttr(rootState.disabled),
148
+ "data-orientation": rootState.orientation,
149
+ "data-invalid": dataAttr(rootState.invalid),
150
+ "data-focus": dataAttr(rootState.focused)
122
151
  });
123
152
  },
124
153
  getTrackProps() {
154
+ const rootState = getRootState();
125
155
  return normalize.element({
126
156
  ...parts.track.attrs(scope.id),
127
157
  dir: prop("dir"),
128
- "data-disabled": dataAttr(disabled),
129
- "data-invalid": dataAttr(invalid),
130
- "data-dragging": dataAttr(dragging),
131
- "data-orientation": prop("orientation"),
132
- "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),
133
163
  style: { position: "relative" }
134
164
  });
135
165
  },
166
+ getThumbState,
136
167
  getThumbProps(props) {
137
168
  const { index = 0, name } = props;
138
- const value = sliderValue[index];
169
+ const thumbState = getThumbState({ index, name });
139
170
  const range = getRangeAtIndex(service, index);
140
- const valueText = prop("getAriaValueText")?.({ value, index });
171
+ const valueText = prop("getAriaValueText")?.({ value: thumbState.value, index });
141
172
  const _ariaLabel = Array.isArray(ariaLabel) ? ariaLabel[index] : ariaLabel;
142
173
  const _ariaLabelledBy = Array.isArray(ariaLabelledBy) ? ariaLabelledBy[index] : ariaLabelledBy;
143
174
  return normalize.element({
@@ -145,21 +176,21 @@ function connect(service, normalize) {
145
176
  dir: prop("dir"),
146
177
  "data-index": index,
147
178
  "data-name": name,
148
- "data-disabled": dataAttr(disabled),
179
+ "data-disabled": dataAttr(thumbState.disabled),
149
180
  "data-orientation": prop("orientation"),
150
- "data-focus": dataAttr(focused && focusedIndex === index),
151
- "data-dragging": dataAttr(dragging && focusedIndex === index),
181
+ "data-focus": dataAttr(thumbState.focused),
182
+ "data-dragging": dataAttr(thumbState.dragging),
152
183
  draggable: false,
153
- "aria-disabled": ariaAttr(disabled),
184
+ "aria-disabled": ariaAttr(thumbState.disabled),
154
185
  "aria-label": _ariaLabel,
155
186
  "aria-labelledby": _ariaLabelledBy ?? dom.getLabelId(scope),
156
187
  "aria-orientation": prop("orientation"),
157
188
  "aria-valuemax": range.max,
158
189
  "aria-valuemin": range.min,
159
- "aria-valuenow": sliderValue[index],
190
+ "aria-valuenow": thumbState.value,
160
191
  "aria-valuetext": valueText,
161
192
  role: "slider",
162
- tabIndex: disabled ? void 0 : 0,
193
+ tabIndex: thumbState.disabled ? void 0 : 0,
163
194
  style: getThumbStyle(service, index),
164
195
  onPointerDown(event) {
165
196
  if (!interactive) return;
@@ -188,7 +219,7 @@ function connect(service, normalize) {
188
219
  onKeyDown(event) {
189
220
  if (event.defaultPrevented) return;
190
221
  if (!interactive) return;
191
- const step = getEventStep(event) * prop("step");
222
+ const step = getEventStepValue(event, { step: prop("step"), largeStep: prop("largeStep") });
192
223
  const keyMap = {
193
224
  ArrowUp() {
194
225
  if (isHorizontal) return;
@@ -234,36 +265,39 @@ function connect(service, normalize) {
234
265
  },
235
266
  getHiddenInputProps(props) {
236
267
  const { index = 0, name } = props;
268
+ const thumbState = getThumbState({ index, name });
237
269
  return normalize.input({
238
270
  name: name ?? (prop("name") ? prop("name") + (sliderValue.length > 1 ? "[]" : "") : void 0),
239
271
  form: prop("form"),
240
272
  type: "text",
241
273
  hidden: true,
242
- defaultValue: sliderValue[index],
274
+ defaultValue: thumbState.value,
243
275
  id: dom.getHiddenInputId(scope, index)
244
276
  });
245
277
  },
246
278
  getRangeProps() {
279
+ const rootState = getRootState();
247
280
  return normalize.element({
248
281
  ...parts.range.attrs(scope.id),
249
282
  dir: prop("dir"),
250
- "data-dragging": dataAttr(dragging),
251
- "data-focus": dataAttr(focused),
252
- "data-invalid": dataAttr(invalid),
253
- "data-disabled": dataAttr(disabled),
254
- "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,
255
288
  style: getRangeStyle(service)
256
289
  });
257
290
  },
258
291
  getControlProps() {
292
+ const rootState = getRootState();
259
293
  return normalize.element({
260
294
  ...parts.control.attrs(scope.id),
261
295
  dir: prop("dir"),
262
- "data-dragging": dataAttr(dragging),
263
- "data-disabled": dataAttr(disabled),
264
- "data-orientation": prop("orientation"),
265
- "data-invalid": dataAttr(invalid),
266
- "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),
267
301
  style: getControlStyle(),
268
302
  onPointerDown(event) {
269
303
  if (!interactive) return;
@@ -286,37 +320,31 @@ function connect(service, normalize) {
286
320
  style: getMarkerGroupStyle()
287
321
  });
288
322
  },
323
+ getMarkerState,
289
324
  getMarkerProps(props) {
290
325
  const style = getMarkerStyle(service, props.value);
291
- let markerState;
292
- if (props.value < first(sliderValue)) {
293
- markerState = "under-value";
294
- } else if (props.value > last(sliderValue)) {
295
- markerState = "over-value";
296
- } else {
297
- markerState = "at-value";
298
- }
326
+ const markerState = getMarkerState(props);
299
327
  return normalize.element({
300
328
  ...parts.marker.attrs(scope.id),
301
329
  role: "presentation",
302
330
  dir: prop("dir"),
303
331
  "data-orientation": prop("orientation"),
304
- "data-value": props.value,
305
- "data-disabled": dataAttr(disabled),
306
- "data-state": markerState,
332
+ "data-value": markerState.value,
333
+ "data-disabled": dataAttr(markerState.disabled),
334
+ "data-state": markerState.state,
307
335
  style
308
336
  });
309
337
  },
310
338
  getDraggingIndicatorProps(props) {
311
339
  const { index = 0 } = props;
312
- const isDragging = index === focusedIndex && dragging;
340
+ const thumbState = getThumbState({ index });
313
341
  return normalize.element({
314
342
  ...parts.draggingIndicator.attrs(scope.id),
315
343
  role: "presentation",
316
344
  dir: prop("dir"),
317
- hidden: !isDragging,
345
+ hidden: !thumbState.dragging,
318
346
  "data-orientation": prop("orientation"),
319
- "data-state": isDragging ? "open" : "closed",
347
+ "data-state": thumbState.dragging ? "open" : "closed",
320
348
  style: getThumbStyle(service, index)
321
349
  });
322
350
  }
@@ -69,6 +69,7 @@ var machine = (0, import_core.createMachine)({
69
69
  thumbCollisionBehavior: "none",
70
70
  minStepsBetweenThumbs,
71
71
  ...props,
72
+ largeStep: props.largeStep ?? 10 * step,
72
73
  defaultValue: normalize(defaultValue, min, max, step, minStepsBetweenThumbs),
73
74
  value: props.value ? normalize(props.value, min, max, step, minStepsBetweenThumbs) : void 0,
74
75
  max,
@@ -54,6 +54,7 @@ var machine = createMachine({
54
54
  thumbCollisionBehavior: "none",
55
55
  minStepsBetweenThumbs,
56
56
  ...props,
57
+ largeStep: props.largeStep ?? 10 * step,
57
58
  defaultValue: normalize(defaultValue, min, max, step, minStepsBetweenThumbs),
58
59
  value: props.value ? normalize(props.value, min, max, step, minStepsBetweenThumbs) : void 0,
59
60
  max,
@@ -41,6 +41,7 @@ var props = (0, import_types.createProps)()([
41
41
  "id",
42
42
  "ids",
43
43
  "invalid",
44
+ "largeStep",
44
45
  "max",
45
46
  "min",
46
47
  "minStepsBetweenThumbs",
@@ -12,6 +12,7 @@ var props = createProps()([
12
12
  "id",
13
13
  "ids",
14
14
  "invalid",
15
+ "largeStep",
15
16
  "max",
16
17
  "min",
17
18
  "minStepsBetweenThumbs",
@@ -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
  }
@@ -98,6 +99,12 @@ interface SliderProps extends DirectionProperty, CommonProperties {
98
99
  * @default 1
99
100
  */
100
101
  step?: number | undefined;
102
+ /**
103
+ * The step value of the slider when the `Shift` key is held, or the
104
+ * `PageUp`/`PageDown` keys are used.
105
+ * @default 10 * step
106
+ */
107
+ largeStep?: number | undefined;
101
108
  /**
102
109
  * The minimum permitted steps between multiple thumbs.
103
110
  *
@@ -115,15 +122,14 @@ interface SliderProps extends DirectionProperty, CommonProperties {
115
122
  */
116
123
  orientation?: "vertical" | "horizontal" | undefined;
117
124
  /**
118
- * The origin of the slider range. The track is filled from the origin
119
- * to the thumb for single values.
120
- * - "start": Useful when the value represents an absolute value
121
- * - "center": Useful when the value represents an offset (relative)
122
- * - "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
123
129
  *
124
130
  * @default "start"
125
131
  */
126
- origin?: "start" | "center" | "end" | undefined;
132
+ origin?: SliderOrigin | undefined;
127
133
  /**
128
134
  * The alignment of the slider thumb relative to the track
129
135
  * - `center`: the thumb will extend beyond the bounds of the slider track.
@@ -149,7 +155,7 @@ interface SliderProps extends DirectionProperty, CommonProperties {
149
155
  */
150
156
  thumbCollisionBehavior?: "none" | "push" | "swap" | undefined;
151
157
  }
152
- type PropsWithDefault = "dir" | "min" | "max" | "step" | "orientation" | "defaultValue" | "origin" | "thumbAlignment" | "minStepsBetweenThumbs" | "thumbCollisionBehavior";
158
+ type PropsWithDefault = "dir" | "min" | "max" | "step" | "largeStep" | "orientation" | "defaultValue" | "origin" | "thumbAlignment" | "minStepsBetweenThumbs" | "thumbCollisionBehavior";
153
159
  type Computed = Readonly<{
154
160
  /**
155
161
  * @computed
@@ -236,13 +242,71 @@ interface Size {
236
242
  interface MarkerProps {
237
243
  value: number;
238
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
+ }
239
259
  interface ThumbProps {
240
260
  index: number;
241
261
  name?: string | undefined;
242
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
+ }
243
285
  interface DraggingIndicatorProps {
244
286
  index: number;
245
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
+ }
246
310
  interface SliderApi<T extends PropTypes = PropTypes> {
247
311
  /**
248
312
  * The value of the slider.
@@ -304,17 +368,29 @@ interface SliderApi<T extends PropTypes = PropTypes> {
304
368
  * Function to focus the slider. This focuses the first thumb.
305
369
  */
306
370
  focus: VoidFunction;
371
+ /**
372
+ * Returns the state of the slider
373
+ */
374
+ getRootState: () => RootState;
307
375
  getLabelProps: () => T["label"];
308
376
  getRootProps: () => T["element"];
309
377
  getValueTextProps: () => T["element"];
310
378
  getTrackProps: () => T["element"];
379
+ /**
380
+ * Returns the state of a specific thumb
381
+ */
382
+ getThumbState: (props: ThumbProps) => ThumbState;
311
383
  getThumbProps: (props: ThumbProps) => T["element"];
312
384
  getHiddenInputProps: (props: ThumbProps) => T["input"];
313
385
  getRangeProps: () => T["element"];
314
386
  getControlProps: () => T["element"];
315
387
  getMarkerGroupProps: () => T["element"];
388
+ /**
389
+ * Returns the state of a specific marker
390
+ */
391
+ getMarkerState: (props: MarkerProps) => MarkerState;
316
392
  getMarkerProps: (props: MarkerProps) => T["element"];
317
393
  getDraggingIndicatorProps: (props: DraggingIndicatorProps) => T["element"];
318
394
  }
319
395
 
320
- 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
  }
@@ -98,6 +99,12 @@ interface SliderProps extends DirectionProperty, CommonProperties {
98
99
  * @default 1
99
100
  */
100
101
  step?: number | undefined;
102
+ /**
103
+ * The step value of the slider when the `Shift` key is held, or the
104
+ * `PageUp`/`PageDown` keys are used.
105
+ * @default 10 * step
106
+ */
107
+ largeStep?: number | undefined;
101
108
  /**
102
109
  * The minimum permitted steps between multiple thumbs.
103
110
  *
@@ -115,15 +122,14 @@ interface SliderProps extends DirectionProperty, CommonProperties {
115
122
  */
116
123
  orientation?: "vertical" | "horizontal" | undefined;
117
124
  /**
118
- * The origin of the slider range. The track is filled from the origin
119
- * to the thumb for single values.
120
- * - "start": Useful when the value represents an absolute value
121
- * - "center": Useful when the value represents an offset (relative)
122
- * - "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
123
129
  *
124
130
  * @default "start"
125
131
  */
126
- origin?: "start" | "center" | "end" | undefined;
132
+ origin?: SliderOrigin | undefined;
127
133
  /**
128
134
  * The alignment of the slider thumb relative to the track
129
135
  * - `center`: the thumb will extend beyond the bounds of the slider track.
@@ -149,7 +155,7 @@ interface SliderProps extends DirectionProperty, CommonProperties {
149
155
  */
150
156
  thumbCollisionBehavior?: "none" | "push" | "swap" | undefined;
151
157
  }
152
- type PropsWithDefault = "dir" | "min" | "max" | "step" | "orientation" | "defaultValue" | "origin" | "thumbAlignment" | "minStepsBetweenThumbs" | "thumbCollisionBehavior";
158
+ type PropsWithDefault = "dir" | "min" | "max" | "step" | "largeStep" | "orientation" | "defaultValue" | "origin" | "thumbAlignment" | "minStepsBetweenThumbs" | "thumbCollisionBehavior";
153
159
  type Computed = Readonly<{
154
160
  /**
155
161
  * @computed
@@ -236,13 +242,71 @@ interface Size {
236
242
  interface MarkerProps {
237
243
  value: number;
238
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
+ }
239
259
  interface ThumbProps {
240
260
  index: number;
241
261
  name?: string | undefined;
242
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
+ }
243
285
  interface DraggingIndicatorProps {
244
286
  index: number;
245
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
+ }
246
310
  interface SliderApi<T extends PropTypes = PropTypes> {
247
311
  /**
248
312
  * The value of the slider.
@@ -304,17 +368,29 @@ interface SliderApi<T extends PropTypes = PropTypes> {
304
368
  * Function to focus the slider. This focuses the first thumb.
305
369
  */
306
370
  focus: VoidFunction;
371
+ /**
372
+ * Returns the state of the slider
373
+ */
374
+ getRootState: () => RootState;
307
375
  getLabelProps: () => T["label"];
308
376
  getRootProps: () => T["element"];
309
377
  getValueTextProps: () => T["element"];
310
378
  getTrackProps: () => T["element"];
379
+ /**
380
+ * Returns the state of a specific thumb
381
+ */
382
+ getThumbState: (props: ThumbProps) => ThumbState;
311
383
  getThumbProps: (props: ThumbProps) => T["element"];
312
384
  getHiddenInputProps: (props: ThumbProps) => T["input"];
313
385
  getRangeProps: () => T["element"];
314
386
  getControlProps: () => T["element"];
315
387
  getMarkerGroupProps: () => T["element"];
388
+ /**
389
+ * Returns the state of a specific marker
390
+ */
391
+ getMarkerState: (props: MarkerProps) => MarkerState;
316
392
  getMarkerProps: (props: MarkerProps) => T["element"];
317
393
  getDraggingIndicatorProps: (props: DraggingIndicatorProps) => T["element"];
318
394
  }
319
395
 
320
- 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": "2.0.0-next.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",
@@ -15,7 +15,10 @@
15
15
  "author": "Segun Adebayo <sage@adebayosegun.com>",
16
16
  "homepage": "https://github.com/chakra-ui/zag#readme",
17
17
  "license": "MIT",
18
- "repository": "https://github.com/chakra-ui/zag/tree/main/packages/slider",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/chakra-ui/zag/tree/main/packages/slider"
21
+ },
19
22
  "sideEffects": false,
20
23
  "files": [
21
24
  "dist"
@@ -27,11 +30,11 @@
27
30
  "url": "https://github.com/chakra-ui/zag/issues"
28
31
  },
29
32
  "dependencies": {
30
- "@zag-js/anatomy": "2.0.0-next.0",
31
- "@zag-js/core": "2.0.0-next.0",
32
- "@zag-js/dom-query": "2.0.0-next.0",
33
- "@zag-js/utils": "2.0.0-next.0",
34
- "@zag-js/types": "2.0.0-next.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"
35
38
  },
36
39
  "devDependencies": {
37
40
  "clean-package": "2.2.0"