@zag-js/slider 1.34.1 → 1.35.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.
@@ -0,0 +1,354 @@
1
+ // src/slider.machine.ts
2
+ import { createMachine, memo } from "@zag-js/core";
3
+ import { raf, resizeObserverBorderBox, setElementValue, trackFormControl, trackPointerMove } from "@zag-js/dom-query";
4
+ import {
5
+ callAll,
6
+ clampValue,
7
+ getValuePercent,
8
+ getValueRanges,
9
+ isEqual,
10
+ isValueWithinRange,
11
+ pick,
12
+ setValueAtIndex,
13
+ snapValueToStep
14
+ } from "@zag-js/utils";
15
+ import * as dom from "./slider.dom.mjs";
16
+ import {
17
+ constrainValue,
18
+ decrement,
19
+ getClosestIndex,
20
+ getRangeAtIndex,
21
+ increment,
22
+ normalizeValues,
23
+ resolveThumbCollision,
24
+ selectMovableThumb
25
+ } from "./slider.utils.mjs";
26
+ var isEqualSize = (a, b) => {
27
+ return a?.width === b?.width && a?.height === b?.height;
28
+ };
29
+ var normalize = (value, min, max, step, minStepsBetweenThumbs) => {
30
+ const ranges = getValueRanges(value, min, max, minStepsBetweenThumbs * step);
31
+ return ranges.map((range) => {
32
+ const snapValue = snapValueToStep(range.value, range.min, range.max, step);
33
+ const rangeValue = clampValue(snapValue, range.min, range.max);
34
+ if (!isValueWithinRange(rangeValue, min, max)) {
35
+ throw new Error(
36
+ "[zag-js/slider] The configured `min`, `max`, `step` or `minStepsBetweenThumbs` values are invalid"
37
+ );
38
+ }
39
+ return rangeValue;
40
+ });
41
+ };
42
+ var machine = createMachine({
43
+ props({ props }) {
44
+ const min = props.min ?? 0;
45
+ const max = props.max ?? 100;
46
+ const step = props.step ?? 1;
47
+ const defaultValue = props.defaultValue ?? [min];
48
+ const minStepsBetweenThumbs = props.minStepsBetweenThumbs ?? 0;
49
+ return {
50
+ dir: "ltr",
51
+ thumbAlignment: "contain",
52
+ origin: "start",
53
+ orientation: "horizontal",
54
+ thumbCollisionBehavior: "none",
55
+ minStepsBetweenThumbs,
56
+ ...props,
57
+ defaultValue: normalize(defaultValue, min, max, step, minStepsBetweenThumbs),
58
+ value: props.value ? normalize(props.value, min, max, step, minStepsBetweenThumbs) : void 0,
59
+ max,
60
+ step,
61
+ min
62
+ };
63
+ },
64
+ initialState() {
65
+ return "idle";
66
+ },
67
+ context({ prop, bindable, getContext }) {
68
+ return {
69
+ thumbSize: bindable(() => ({
70
+ defaultValue: prop("thumbSize") || null
71
+ })),
72
+ value: bindable(() => ({
73
+ defaultValue: prop("defaultValue"),
74
+ value: prop("value"),
75
+ isEqual,
76
+ hash(a) {
77
+ return a.join(",");
78
+ },
79
+ onChange(value) {
80
+ prop("onValueChange")?.({ value });
81
+ }
82
+ })),
83
+ focusedIndex: bindable(() => ({
84
+ defaultValue: -1,
85
+ onChange(value) {
86
+ const ctx = getContext();
87
+ prop("onFocusChange")?.({ focusedIndex: value, value: ctx.get("value") });
88
+ }
89
+ })),
90
+ fieldsetDisabled: bindable(() => ({
91
+ defaultValue: false
92
+ }))
93
+ };
94
+ },
95
+ refs() {
96
+ return {
97
+ thumbDragOffset: null,
98
+ thumbDragStartValue: null
99
+ };
100
+ },
101
+ computed: {
102
+ isHorizontal: ({ prop }) => prop("orientation") === "horizontal",
103
+ isVertical: ({ prop }) => prop("orientation") === "vertical",
104
+ isRtl: ({ prop }) => prop("orientation") === "horizontal" && prop("dir") === "rtl",
105
+ isDisabled: ({ context, prop }) => !!prop("disabled") || context.get("fieldsetDisabled"),
106
+ isInteractive: ({ prop, computed }) => !(prop("readOnly") || computed("isDisabled")),
107
+ hasMeasuredThumbSize: ({ context }) => context.get("thumbSize") != null,
108
+ valuePercent: memo(
109
+ ({ context, prop }) => [context.get("value"), prop("min"), prop("max")],
110
+ ([value, min, max]) => value.map((value2) => 100 * getValuePercent(value2, min, max))
111
+ )
112
+ },
113
+ watch({ track, action, context, computed, send }) {
114
+ track([() => context.hash("value")], () => {
115
+ action(["syncInputElements", "dispatchChangeEvent"]);
116
+ });
117
+ track([() => computed("isDisabled")], () => {
118
+ if (computed("isDisabled")) {
119
+ send({ type: "POINTER_CANCEL" });
120
+ }
121
+ });
122
+ },
123
+ effects: ["trackFormControlState", "trackThumbSize"],
124
+ on: {
125
+ SET_VALUE: [
126
+ {
127
+ guard: "hasIndex",
128
+ actions: ["setValueAtIndex", "invokeOnChangeEnd"]
129
+ },
130
+ {
131
+ actions: ["setValue", "invokeOnChangeEnd"]
132
+ }
133
+ ],
134
+ INCREMENT: {
135
+ actions: ["incrementThumbAtIndex", "invokeOnChangeEnd"]
136
+ },
137
+ DECREMENT: {
138
+ actions: ["decrementThumbAtIndex", "invokeOnChangeEnd"]
139
+ }
140
+ },
141
+ states: {
142
+ idle: {
143
+ on: {
144
+ POINTER_DOWN: {
145
+ target: "dragging",
146
+ actions: ["setClosestThumbIndex", "setThumbDragStartValue", "setPointerValue", "focusActiveThumb"]
147
+ },
148
+ FOCUS: {
149
+ target: "focus",
150
+ actions: ["setFocusedIndex"]
151
+ },
152
+ THUMB_POINTER_DOWN: {
153
+ target: "dragging",
154
+ actions: ["setFocusedIndex", "setThumbDragOffset", "setThumbDragStartValue", "focusActiveThumb"]
155
+ }
156
+ }
157
+ },
158
+ focus: {
159
+ entry: ["focusActiveThumb"],
160
+ on: {
161
+ POINTER_DOWN: {
162
+ target: "dragging",
163
+ actions: ["setClosestThumbIndex", "setThumbDragStartValue", "setPointerValue", "focusActiveThumb"]
164
+ },
165
+ THUMB_POINTER_DOWN: {
166
+ target: "dragging",
167
+ actions: ["setFocusedIndex", "setThumbDragOffset", "setThumbDragStartValue", "focusActiveThumb"]
168
+ },
169
+ ARROW_DEC: {
170
+ actions: ["decrementThumbAtIndex", "invokeOnChangeEnd"]
171
+ },
172
+ ARROW_INC: {
173
+ actions: ["incrementThumbAtIndex", "invokeOnChangeEnd"]
174
+ },
175
+ HOME: {
176
+ actions: ["setFocusedThumbToMin", "invokeOnChangeEnd"]
177
+ },
178
+ END: {
179
+ actions: ["setFocusedThumbToMax", "invokeOnChangeEnd"]
180
+ },
181
+ BLUR: {
182
+ target: "idle",
183
+ actions: ["clearFocusedIndex"]
184
+ }
185
+ }
186
+ },
187
+ dragging: {
188
+ entry: ["focusActiveThumb"],
189
+ effects: ["trackPointerMove"],
190
+ on: {
191
+ POINTER_UP: {
192
+ target: "focus",
193
+ actions: ["invokeOnChangeEnd", "clearThumbDragOffset", "clearThumbDragStartValue"]
194
+ },
195
+ POINTER_MOVE: {
196
+ actions: ["setPointerValue"]
197
+ },
198
+ POINTER_CANCEL: {
199
+ target: "idle",
200
+ actions: ["clearFocusedIndex", "clearThumbDragOffset", "clearThumbDragStartValue"]
201
+ }
202
+ }
203
+ }
204
+ },
205
+ implementations: {
206
+ guards: {
207
+ hasIndex: ({ event }) => event.index != null
208
+ },
209
+ effects: {
210
+ trackFormControlState({ context, scope }) {
211
+ return trackFormControl(dom.getRootEl(scope), {
212
+ onFieldsetDisabledChange(disabled) {
213
+ context.set("fieldsetDisabled", disabled);
214
+ },
215
+ onFormReset() {
216
+ context.set("value", context.initial("value"));
217
+ }
218
+ });
219
+ },
220
+ trackPointerMove({ scope, send }) {
221
+ return trackPointerMove(scope.getDoc(), {
222
+ onPointerMove(info) {
223
+ send({ type: "POINTER_MOVE", point: info.point });
224
+ },
225
+ onPointerUp() {
226
+ send({ type: "POINTER_UP" });
227
+ }
228
+ });
229
+ },
230
+ trackThumbSize({ context, scope, prop }) {
231
+ if (prop("thumbAlignment") !== "contain" || prop("thumbSize")) return;
232
+ const exec = (el) => {
233
+ const rect = dom.getOffsetRect(el);
234
+ const size = pick(rect, ["width", "height"]);
235
+ if (isEqualSize(context.get("thumbSize"), size)) return;
236
+ context.set("thumbSize", size);
237
+ };
238
+ const thumbEls = dom.getThumbEls(scope);
239
+ thumbEls.forEach(exec);
240
+ const cleanups = thumbEls.map((el) => resizeObserverBorderBox.observe(el, () => exec(el)));
241
+ return callAll(...cleanups);
242
+ }
243
+ },
244
+ actions: {
245
+ dispatchChangeEvent({ context, scope }) {
246
+ dom.dispatchChangeEvent(scope, context.get("value"));
247
+ },
248
+ syncInputElements({ context, scope }) {
249
+ context.get("value").forEach((value, index) => {
250
+ const inputEl = dom.getHiddenInputEl(scope, index);
251
+ setElementValue(inputEl, value.toString());
252
+ });
253
+ },
254
+ invokeOnChangeEnd({ prop, context }) {
255
+ queueMicrotask(() => {
256
+ prop("onValueChangeEnd")?.({ value: context.get("value") });
257
+ });
258
+ },
259
+ setClosestThumbIndex(params) {
260
+ const { context, event } = params;
261
+ const pointValue = dom.getPointValue(params, event.point);
262
+ if (pointValue == null) return;
263
+ const focusedIndex = getClosestIndex(params, pointValue);
264
+ context.set("focusedIndex", focusedIndex);
265
+ },
266
+ setFocusedIndex(params) {
267
+ const { context, event } = params;
268
+ const movableIndex = selectMovableThumb(params, event.index);
269
+ context.set("focusedIndex", movableIndex);
270
+ },
271
+ clearFocusedIndex({ context }) {
272
+ context.set("focusedIndex", -1);
273
+ },
274
+ setThumbDragOffset(params) {
275
+ const { refs, event } = params;
276
+ refs.set("thumbDragOffset", event.offset ?? null);
277
+ },
278
+ clearThumbDragOffset({ refs }) {
279
+ refs.set("thumbDragOffset", null);
280
+ },
281
+ setThumbDragStartValue({ refs, context }) {
282
+ refs.set("thumbDragStartValue", context.get("value").slice());
283
+ },
284
+ clearThumbDragStartValue({ refs }) {
285
+ refs.set("thumbDragStartValue", null);
286
+ },
287
+ setPointerValue(params) {
288
+ queueMicrotask(() => {
289
+ const { context, event, prop, refs } = params;
290
+ const pointValue = dom.getPointValue(params, event.point);
291
+ if (pointValue == null) return;
292
+ const focusedIndex = context.get("focusedIndex");
293
+ const startValues = refs.get("thumbDragStartValue");
294
+ const result = resolveThumbCollision(
295
+ prop("thumbCollisionBehavior"),
296
+ focusedIndex,
297
+ pointValue,
298
+ context.get("value"),
299
+ prop("min"),
300
+ prop("max"),
301
+ prop("step"),
302
+ prop("minStepsBetweenThumbs"),
303
+ startValues?.[focusedIndex]
304
+ );
305
+ if (result.swapped) {
306
+ context.set("focusedIndex", result.index);
307
+ }
308
+ context.set("value", result.values);
309
+ });
310
+ },
311
+ focusActiveThumb({ scope, context }) {
312
+ raf(() => {
313
+ const thumbEl = dom.getThumbEl(scope, context.get("focusedIndex"));
314
+ thumbEl?.focus({ preventScroll: true });
315
+ });
316
+ },
317
+ decrementThumbAtIndex(params) {
318
+ const { context, event } = params;
319
+ const value = decrement(params, event.index, event.step);
320
+ context.set("value", value);
321
+ },
322
+ incrementThumbAtIndex(params) {
323
+ const { context, event } = params;
324
+ const value = increment(params, event.index, event.step);
325
+ context.set("value", value);
326
+ },
327
+ setFocusedThumbToMin(params) {
328
+ const { context } = params;
329
+ const index = context.get("focusedIndex");
330
+ const { min } = getRangeAtIndex(params, index);
331
+ context.set("value", (prev) => setValueAtIndex(prev, index, min));
332
+ },
333
+ setFocusedThumbToMax(params) {
334
+ const { context } = params;
335
+ const index = context.get("focusedIndex");
336
+ const { max } = getRangeAtIndex(params, index);
337
+ context.set("value", (prev) => setValueAtIndex(prev, index, max));
338
+ },
339
+ setValueAtIndex(params) {
340
+ const { context, event } = params;
341
+ const value = constrainValue(params, event.value, event.index);
342
+ context.set("value", (prev) => setValueAtIndex(prev, event.index, value));
343
+ },
344
+ setValue(params) {
345
+ const { context, event } = params;
346
+ const value = normalizeValues(params, event.value);
347
+ context.set("value", value);
348
+ }
349
+ }
350
+ }
351
+ });
352
+ export {
353
+ machine
354
+ };
@@ -0,0 +1,12 @@
1
+ import { SliderProps, MarkerProps, ThumbProps } from './slider.types.mjs';
2
+ import '@zag-js/core';
3
+ import '@zag-js/types';
4
+
5
+ declare const props: (keyof SliderProps)[];
6
+ declare const splitProps: <Props extends Partial<SliderProps>>(props: Props) => [Partial<SliderProps>, Omit<Props, keyof SliderProps>];
7
+ declare const thumbProps: (keyof ThumbProps)[];
8
+ declare const splitThumbProps: <Props extends ThumbProps>(props: Props) => [ThumbProps, Omit<Props, keyof ThumbProps>];
9
+ declare const markerProps: "value"[];
10
+ declare const splitMarkerProps: <Props extends MarkerProps>(props: Props) => [MarkerProps, Omit<Props, "value">];
11
+
12
+ export { markerProps, props, splitMarkerProps, splitProps, splitThumbProps, thumbProps };
@@ -0,0 +1,12 @@
1
+ import { SliderProps, MarkerProps, ThumbProps } from './slider.types.js';
2
+ import '@zag-js/core';
3
+ import '@zag-js/types';
4
+
5
+ declare const props: (keyof SliderProps)[];
6
+ declare const splitProps: <Props extends Partial<SliderProps>>(props: Props) => [Partial<SliderProps>, Omit<Props, keyof SliderProps>];
7
+ declare const thumbProps: (keyof ThumbProps)[];
8
+ declare const splitThumbProps: <Props extends ThumbProps>(props: Props) => [ThumbProps, Omit<Props, keyof ThumbProps>];
9
+ declare const markerProps: "value"[];
10
+ declare const splitMarkerProps: <Props extends MarkerProps>(props: Props) => [MarkerProps, Omit<Props, "value">];
11
+
12
+ export { markerProps, props, splitMarkerProps, splitProps, splitThumbProps, thumbProps };
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/slider.props.ts
21
+ var slider_props_exports = {};
22
+ __export(slider_props_exports, {
23
+ markerProps: () => markerProps,
24
+ props: () => props,
25
+ splitMarkerProps: () => splitMarkerProps,
26
+ splitProps: () => splitProps,
27
+ splitThumbProps: () => splitThumbProps,
28
+ thumbProps: () => thumbProps
29
+ });
30
+ module.exports = __toCommonJS(slider_props_exports);
31
+ var import_types = require("@zag-js/types");
32
+ var import_utils = require("@zag-js/utils");
33
+ var props = (0, import_types.createProps)()([
34
+ "aria-label",
35
+ "aria-labelledby",
36
+ "dir",
37
+ "disabled",
38
+ "form",
39
+ "getAriaValueText",
40
+ "getRootNode",
41
+ "id",
42
+ "ids",
43
+ "invalid",
44
+ "max",
45
+ "min",
46
+ "minStepsBetweenThumbs",
47
+ "name",
48
+ "onFocusChange",
49
+ "onValueChange",
50
+ "onValueChangeEnd",
51
+ "orientation",
52
+ "origin",
53
+ "readOnly",
54
+ "step",
55
+ "thumbAlignment",
56
+ "thumbCollisionBehavior",
57
+ "thumbSize",
58
+ "value",
59
+ "defaultValue"
60
+ ]);
61
+ var splitProps = (0, import_utils.createSplitProps)(props);
62
+ var thumbProps = (0, import_types.createProps)()(["index", "name"]);
63
+ var splitThumbProps = (0, import_utils.createSplitProps)(thumbProps);
64
+ var markerProps = (0, import_types.createProps)()(["value"]);
65
+ var splitMarkerProps = (0, import_utils.createSplitProps)(markerProps);
66
+ // Annotate the CommonJS export names for ESM import in node:
67
+ 0 && (module.exports = {
68
+ markerProps,
69
+ props,
70
+ splitMarkerProps,
71
+ splitProps,
72
+ splitThumbProps,
73
+ thumbProps
74
+ });
@@ -0,0 +1,44 @@
1
+ // src/slider.props.ts
2
+ import { createProps } from "@zag-js/types";
3
+ import { createSplitProps } from "@zag-js/utils";
4
+ var props = createProps()([
5
+ "aria-label",
6
+ "aria-labelledby",
7
+ "dir",
8
+ "disabled",
9
+ "form",
10
+ "getAriaValueText",
11
+ "getRootNode",
12
+ "id",
13
+ "ids",
14
+ "invalid",
15
+ "max",
16
+ "min",
17
+ "minStepsBetweenThumbs",
18
+ "name",
19
+ "onFocusChange",
20
+ "onValueChange",
21
+ "onValueChangeEnd",
22
+ "orientation",
23
+ "origin",
24
+ "readOnly",
25
+ "step",
26
+ "thumbAlignment",
27
+ "thumbCollisionBehavior",
28
+ "thumbSize",
29
+ "value",
30
+ "defaultValue"
31
+ ]);
32
+ var splitProps = createSplitProps(props);
33
+ var thumbProps = createProps()(["index", "name"]);
34
+ var splitThumbProps = createSplitProps(thumbProps);
35
+ var markerProps = createProps()(["value"]);
36
+ var splitMarkerProps = createSplitProps(markerProps);
37
+ export {
38
+ markerProps,
39
+ props,
40
+ splitMarkerProps,
41
+ splitProps,
42
+ splitThumbProps,
43
+ thumbProps
44
+ };
@@ -0,0 +1,19 @@
1
+ import { Params } from '@zag-js/core';
2
+ import { Style } from '@zag-js/types';
3
+ import { SliderSchema } from './slider.types.mjs';
4
+
5
+ type Ctx = Params<SliderSchema>;
6
+ declare function getRangeOffsets(params: Pick<Ctx, "prop" | "computed">): {
7
+ start: string;
8
+ end: string;
9
+ };
10
+ declare function getRangeStyle(params: Pick<Ctx, "computed">): Style;
11
+ declare function getThumbOffset(params: Pick<Ctx, "computed" | "context" | "prop">, value: number): string;
12
+ declare function getVisibility(params: Pick<Ctx, "computed" | "prop">): "hidden" | "visible";
13
+ declare function getThumbStyle(params: Pick<Ctx, "computed" | "context" | "prop">, index: number): Style;
14
+ declare function getControlStyle(): Style;
15
+ declare function getRootStyle(params: Pick<Ctx, "context" | "computed" | "prop">): Style;
16
+ declare function getMarkerStyle(params: Pick<Ctx, "computed" | "context" | "prop">, value: number): Style;
17
+ declare function getMarkerGroupStyle(): Style;
18
+
19
+ export { getControlStyle, getMarkerGroupStyle, getMarkerStyle, getRangeOffsets, getRangeStyle, getRootStyle, getThumbOffset, getThumbStyle, getVisibility };
@@ -0,0 +1,19 @@
1
+ import { Params } from '@zag-js/core';
2
+ import { Style } from '@zag-js/types';
3
+ import { SliderSchema } from './slider.types.js';
4
+
5
+ type Ctx = Params<SliderSchema>;
6
+ declare function getRangeOffsets(params: Pick<Ctx, "prop" | "computed">): {
7
+ start: string;
8
+ end: string;
9
+ };
10
+ declare function getRangeStyle(params: Pick<Ctx, "computed">): Style;
11
+ declare function getThumbOffset(params: Pick<Ctx, "computed" | "context" | "prop">, value: number): string;
12
+ declare function getVisibility(params: Pick<Ctx, "computed" | "prop">): "hidden" | "visible";
13
+ declare function getThumbStyle(params: Pick<Ctx, "computed" | "context" | "prop">, index: number): Style;
14
+ declare function getControlStyle(): Style;
15
+ declare function getRootStyle(params: Pick<Ctx, "context" | "computed" | "prop">): Style;
16
+ declare function getMarkerStyle(params: Pick<Ctx, "computed" | "context" | "prop">, value: number): Style;
17
+ declare function getMarkerGroupStyle(): Style;
18
+
19
+ export { getControlStyle, getMarkerGroupStyle, getMarkerStyle, getRangeOffsets, getRangeStyle, getRootStyle, getThumbOffset, getThumbStyle, getVisibility };