@tamagui/slider 2.7.7 → 3.0.0-beta.643.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.
Files changed (96) hide show
  1. package/dist/cjs/Slider.cjs +455 -512
  2. package/dist/cjs/Slider.native.cjs +469 -0
  3. package/dist/cjs/Slider.native.js +424 -498
  4. package/dist/cjs/Slider.native.js.map +1 -1
  5. package/dist/cjs/SliderImpl.cjs +111 -128
  6. package/dist/cjs/SliderImpl.native.cjs +154 -0
  7. package/dist/cjs/SliderImpl.native.js +127 -143
  8. package/dist/cjs/SliderImpl.native.js.map +1 -1
  9. package/dist/cjs/constants.cjs +59 -45
  10. package/dist/cjs/constants.native.cjs +79 -0
  11. package/dist/cjs/constants.native.js +59 -44
  12. package/dist/cjs/constants.native.js.map +1 -1
  13. package/dist/cjs/helpers.cjs +59 -60
  14. package/dist/cjs/helpers.native.cjs +99 -0
  15. package/dist/cjs/helpers.native.js +66 -68
  16. package/dist/cjs/helpers.native.js.map +1 -1
  17. package/dist/cjs/index.cjs +16 -17
  18. package/dist/cjs/index.native.cjs +33 -0
  19. package/dist/cjs/index.native.js +16 -16
  20. package/dist/cjs/index.native.js.map +1 -1
  21. package/dist/cjs/types.cjs +10 -11
  22. package/dist/cjs/types.native.cjs +19 -0
  23. package/dist/cjs/types.native.js +10 -10
  24. package/dist/cjs/types.native.js.map +1 -1
  25. package/dist/esm/Slider.mjs +427 -474
  26. package/dist/esm/Slider.mjs.map +1 -1
  27. package/dist/esm/Slider.native.js +396 -463
  28. package/dist/esm/Slider.native.js.map +1 -1
  29. package/dist/esm/SliderImpl.mjs +92 -102
  30. package/dist/esm/SliderImpl.mjs.map +1 -1
  31. package/dist/esm/SliderImpl.native.js +109 -119
  32. package/dist/esm/SliderImpl.native.js.map +1 -1
  33. package/dist/esm/constants.mjs +38 -21
  34. package/dist/esm/constants.mjs.map +1 -1
  35. package/dist/esm/constants.native.js +38 -21
  36. package/dist/esm/constants.native.js.map +1 -1
  37. package/dist/esm/helpers.mjs +37 -36
  38. package/dist/esm/helpers.mjs.map +1 -1
  39. package/dist/esm/helpers.native.js +44 -45
  40. package/dist/esm/helpers.native.js.map +1 -1
  41. package/dist/esm/index.js +4 -3
  42. package/dist/esm/index.mjs +4 -3
  43. package/dist/esm/index.native.js +4 -3
  44. package/dist/esm/types.mjs +0 -2
  45. package/dist/esm/types.native.js +0 -2
  46. package/dist/jsx/Slider.mjs +427 -474
  47. package/dist/jsx/Slider.mjs.map +1 -1
  48. package/dist/jsx/Slider.native.cjs +469 -0
  49. package/dist/jsx/Slider.native.js +424 -498
  50. package/dist/jsx/Slider.native.js.map +1 -1
  51. package/dist/jsx/SliderImpl.mjs +92 -102
  52. package/dist/jsx/SliderImpl.mjs.map +1 -1
  53. package/dist/jsx/SliderImpl.native.cjs +154 -0
  54. package/dist/jsx/SliderImpl.native.js +127 -143
  55. package/dist/jsx/SliderImpl.native.js.map +1 -1
  56. package/dist/jsx/constants.mjs +38 -21
  57. package/dist/jsx/constants.mjs.map +1 -1
  58. package/dist/jsx/constants.native.cjs +79 -0
  59. package/dist/jsx/constants.native.js +59 -44
  60. package/dist/jsx/constants.native.js.map +1 -1
  61. package/dist/jsx/helpers.mjs +37 -36
  62. package/dist/jsx/helpers.mjs.map +1 -1
  63. package/dist/jsx/helpers.native.cjs +99 -0
  64. package/dist/jsx/helpers.native.js +66 -68
  65. package/dist/jsx/helpers.native.js.map +1 -1
  66. package/dist/jsx/index.js +4 -3
  67. package/dist/jsx/index.mjs +4 -3
  68. package/dist/jsx/index.native.cjs +33 -0
  69. package/dist/jsx/index.native.js +16 -16
  70. package/dist/jsx/index.native.js.map +1 -1
  71. package/dist/jsx/types.mjs +0 -2
  72. package/dist/jsx/types.native.cjs +19 -0
  73. package/dist/jsx/types.native.js +10 -10
  74. package/dist/jsx/types.native.js.map +1 -1
  75. package/package.json +15 -14
  76. package/src/Slider.tsx +126 -171
  77. package/src/SliderImpl.tsx +3 -2
  78. package/src/constants.tsx +16 -6
  79. package/src/types.ts +6 -4
  80. package/types/Slider.d.ts +218 -200
  81. package/types/Slider.d.ts.map +1 -1
  82. package/types/SliderImpl.d.ts +16 -5
  83. package/types/SliderImpl.d.ts.map +1 -1
  84. package/types/constants.d.ts +10 -10
  85. package/types/constants.d.ts.map +1 -1
  86. package/types/helpers.d.ts.map +1 -1
  87. package/types/types.d.ts +6 -4
  88. package/types/types.d.ts.map +1 -1
  89. package/dist/esm/index.js.map +0 -1
  90. package/dist/esm/index.mjs.map +0 -1
  91. package/dist/esm/index.native.js.map +0 -1
  92. package/dist/esm/types.mjs.map +0 -1
  93. package/dist/esm/types.native.js.map +0 -1
  94. package/dist/jsx/index.js.map +0 -1
  95. package/dist/jsx/index.mjs.map +0 -1
  96. package/dist/jsx/types.mjs.map +0 -1
@@ -1,505 +1,458 @@
1
1
  import { composeRefs, useComposedRefs } from "@tamagui/compose-refs";
2
2
  import { isIos, isWeb } from "@tamagui/constants";
3
- import { getTokens, getVariableValue, styled, useConfiguration, useCreateShallowSetState } from "@tamagui/core";
4
- import { getSize } from "@tamagui/get-token";
3
+ import { createRefComponent, createStyledHOC, getTokens, getVariableValue, resolveSizeToken, styled, useConfiguration, useCreateShallowSetState } from "@tamagui/core";
5
4
  import { clamp, composeEventHandlers, withStaticProperties } from "@tamagui/helpers";
6
- import { ThemeableStack } from "@tamagui/stacks";
5
+ import { YStack } from "@tamagui/stacks";
7
6
  import { useControllableState } from "@tamagui/use-controllable-state";
8
7
  import { useDirection } from "@tamagui/use-direction";
9
8
  import * as React from "react";
10
9
  import { ARROW_KEYS, BACK_KEYS, PAGE_KEYS, SLIDER_NAME, SliderOrientationProvider, SliderProvider, useSliderContext, useSliderOrientationContext } from "./constants.mjs";
11
10
  import { convertValueToPercentage, getClosestValueIndex, getDecimalCount, getLabel, getNextSortedValues, getThumbInBoundsOffset, hasMinStepsBetweenValues, linearScale, roundValue } from "./helpers.mjs";
12
11
  import { SliderFrame, SliderImpl } from "./SliderImpl.mjs";
13
- import { jsx } from "react/jsx-runtime";
14
- const activeSliderMeasureListeners = /* @__PURE__ */new Set();
15
- if (!process.env.TAMAGUI_DISABLE_SLIDER_INTERVAL) setInterval?.(() => {
16
- activeSliderMeasureListeners.forEach(cb => cb());
17
- }, 1e3);
18
- const SliderHorizontal = React.forwardRef((props, forwardedRef) => {
19
- const {
20
- min,
21
- max,
22
- dir,
23
- onSlideStart,
24
- onSlideMove,
25
- onStepKeyDown,
26
- onSlideEnd,
27
- ...sliderProps
28
- } = props;
29
- const direction = useDirection(dir);
30
- const isDirectionLTR = direction === "ltr";
31
- const sliderRef = React.useRef(null);
32
- const [state, setState_] = React.useState(() => ({
33
- size: 0,
34
- offset: 0
35
- }));
36
- const setState = useCreateShallowSetState(setState_);
37
- function getValueFromPointer(pointerPosition) {
38
- return linearScale([0, state.size], isDirectionLTR ? [min, max] : [max, min])(pointerPosition);
39
- }
40
- const measure = () => {
41
- sliderRef.current?.measure((_x, _y, width, _height, pageX, _pageY) => {
42
- setState({
43
- size: width,
44
- offset: pageX
45
- });
46
- });
47
- };
48
- useSliderMeasure(sliderRef, measure);
49
- return /* @__PURE__ */jsx(SliderOrientationProvider, {
50
- scope: props.__scopeSlider,
51
- startEdge: isDirectionLTR ? "left" : "right",
52
- endEdge: isDirectionLTR ? "right" : "left",
53
- direction: isDirectionLTR ? 1 : -1,
54
- sizeProp: "width",
55
- size: state.size,
56
- children: /* @__PURE__ */jsx(SliderImpl, {
57
- ref: composeRefs(forwardedRef, sliderRef),
58
- dir: direction,
59
- ...sliderProps,
60
- orientation: "horizontal",
61
- onLayout: measure,
62
- onSlideStart: (event, target) => {
63
- const value = getValueFromPointer(event.nativeEvent.locationX);
64
- if (value) onSlideStart?.(value, target, event);
65
- },
66
- onSlideMove: event => {
67
- const value = getValueFromPointer(event.nativeEvent.pageX - state.offset);
68
- if (value) onSlideMove?.(value, event);
69
- },
70
- onSlideEnd: event => {
71
- const value = getValueFromPointer(event.nativeEvent.pageX - state.offset);
72
- if (value) onSlideEnd?.(event, value);
73
- },
74
- onStepKeyDown: event => {
75
- const isBackKey = BACK_KEYS[direction].includes(event.key);
76
- onStepKeyDown?.({
77
- event,
78
- direction: isBackKey ? -1 : 1
79
- });
80
- }
81
- })
82
- });
12
+ import { jsx, jsxs } from "react/jsx-runtime";
13
+
14
+ const activeSliderMeasureListeners = /* @__PURE__ */ new Set();
15
+ let activeSliderMeasureInterval;
16
+ function startSliderMeasureInterval() {
17
+ if (activeSliderMeasureInterval !== void 0 || process.env.TAMAGUI_DISABLE_SLIDER_INTERVAL) return;
18
+ activeSliderMeasureInterval = setInterval(() => {
19
+ activeSliderMeasureListeners.forEach((cb) => cb());
20
+ }, 1e3);
21
+ }
22
+ function addActiveSliderMeasureListener(listener) {
23
+ activeSliderMeasureListeners.add(listener);
24
+ startSliderMeasureInterval();
25
+ }
26
+ function removeActiveSliderMeasureListener(listener) {
27
+ activeSliderMeasureListeners.delete(listener);
28
+ if (!activeSliderMeasureListeners.size && activeSliderMeasureInterval !== void 0) {
29
+ clearInterval(activeSliderMeasureInterval);
30
+ activeSliderMeasureInterval = void 0;
31
+ }
32
+ }
33
+ const SliderHorizontal = createRefComponent((props, forwardedRef) => {
34
+ const { min, max, dir, onSlideStart, onSlideMove, onStepKeyDown, onSlideEnd, ...sliderProps } = props;
35
+ const direction = useDirection(dir);
36
+ const isDirectionLTR = direction === "ltr";
37
+ const sliderRef = React.useRef(null);
38
+ const [state, setState_] = React.useState(() => ({
39
+ size: 0,
40
+ offset: 0
41
+ }));
42
+ const setState = useCreateShallowSetState(setState_);
43
+ function getValueFromPointer(pointerPosition) {
44
+ return linearScale([0, state.size], isDirectionLTR ? [min, max] : [max, min])(pointerPosition);
45
+ }
46
+ const measure = () => {
47
+ sliderRef.current?.measure((_x, _y, width, _height, pageX, _pageY) => {
48
+ setState({
49
+ size: width,
50
+ offset: pageX
51
+ });
52
+ });
53
+ };
54
+ useSliderMeasure(sliderRef, measure);
55
+ return /* @__PURE__ */ jsx(SliderOrientationProvider, {
56
+ scope: props.__scopeSlider,
57
+ startEdge: isDirectionLTR ? "left" : "right",
58
+ endEdge: isDirectionLTR ? "right" : "left",
59
+ direction: isDirectionLTR ? 1 : -1,
60
+ sizeProp: "width",
61
+ size: state.size,
62
+ children: /* @__PURE__ */ jsx(SliderImpl, {
63
+ ref: composeRefs(forwardedRef, sliderRef),
64
+ dir: direction,
65
+ ...sliderProps,
66
+ orientation: "horizontal",
67
+ onLayout: measure,
68
+ onSlideStart: (event, target) => {
69
+ const value = getValueFromPointer(event.nativeEvent.locationX);
70
+ if (value) onSlideStart?.(value, target, event);
71
+ },
72
+ onSlideMove: (event) => {
73
+ const value = getValueFromPointer(event.nativeEvent.pageX - state.offset);
74
+ if (value) onSlideMove?.(value, event);
75
+ },
76
+ onSlideEnd: (event) => {
77
+ const value = getValueFromPointer(event.nativeEvent.pageX - state.offset);
78
+ if (value) onSlideEnd?.(event, value);
79
+ },
80
+ onStepKeyDown: (event) => {
81
+ const isBackKey = BACK_KEYS[direction].includes(event.key);
82
+ onStepKeyDown?.({
83
+ event,
84
+ direction: isBackKey ? -1 : 1
85
+ });
86
+ }
87
+ })
88
+ });
83
89
  });
84
90
  function useOnDebouncedWindowResize(callback, amt = 200) {
85
- React.useEffect(() => {
86
- let last;
87
- const onResize = () => {
88
- clearTimeout(last);
89
- last = setTimeout(callback, amt);
90
- };
91
- window.addEventListener("resize", onResize);
92
- return () => {
93
- clearTimeout(last);
94
- window.removeEventListener("resize", onResize);
95
- };
96
- }, []);
91
+ React.useEffect(() => {
92
+ let last;
93
+ const onResize = () => {
94
+ clearTimeout(last);
95
+ last = setTimeout(callback, amt);
96
+ };
97
+ window.addEventListener("resize", onResize);
98
+ return () => {
99
+ clearTimeout(last);
100
+ window.removeEventListener("resize", onResize);
101
+ };
102
+ }, []);
97
103
  }
98
104
  function useSliderMeasure(sliderRef, measure) {
99
- useOnDebouncedWindowResize(measure);
100
- React.useEffect(() => {
101
- const node = sliderRef.current;
102
- if (!node) return;
103
- let measureTm;
104
- const debouncedMeasure = () => {
105
- clearTimeout(measureTm);
106
- measureTm = setTimeout(() => {
107
- measure();
108
- }, 200);
109
- };
110
- const io = new IntersectionObserver(entries => {
111
- debouncedMeasure();
112
- if (entries?.[0].isIntersecting) activeSliderMeasureListeners.add(debouncedMeasure);else activeSliderMeasureListeners.delete(debouncedMeasure);
113
- }, {
114
- root: null,
115
- rootMargin: "0px",
116
- threshold: [0, .5, 1]
117
- });
118
- io.observe(node);
119
- return () => {
120
- activeSliderMeasureListeners.delete(debouncedMeasure);
121
- io.disconnect();
122
- };
123
- }, []);
105
+ useOnDebouncedWindowResize(measure);
106
+ React.useEffect(() => {
107
+ const node = sliderRef.current;
108
+ if (!node) return;
109
+ let measureTm;
110
+ const debouncedMeasure = () => {
111
+ clearTimeout(measureTm);
112
+ measureTm = setTimeout(() => {
113
+ measure();
114
+ }, 200);
115
+ };
116
+ const io = new IntersectionObserver((entries) => {
117
+ debouncedMeasure();
118
+ if (entries?.[0].isIntersecting) addActiveSliderMeasureListener(debouncedMeasure);
119
+ else removeActiveSliderMeasureListener(debouncedMeasure);
120
+ }, {
121
+ root: null,
122
+ rootMargin: "0px",
123
+ threshold: [
124
+ 0,
125
+ .5,
126
+ 1
127
+ ]
128
+ });
129
+ io.observe(node);
130
+ return () => {
131
+ removeActiveSliderMeasureListener(debouncedMeasure);
132
+ io.disconnect();
133
+ };
134
+ }, []);
124
135
  }
125
- const SliderVertical = React.forwardRef((props, forwardedRef) => {
126
- const {
127
- min,
128
- max,
129
- onSlideStart,
130
- onSlideMove,
131
- onStepKeyDown,
132
- onSlideEnd,
133
- ...sliderProps
134
- } = props;
135
- const [state, setState_] = React.useState(() => ({
136
- size: 0,
137
- offset: 0
138
- }));
139
- const setState = useCreateShallowSetState(setState_);
140
- const sliderRef = React.useRef(null);
141
- const configuration = useConfiguration();
142
- const insets = isIos && configuration.insets ? configuration.insets : {
143
- top: 0,
144
- bottom: 0
145
- };
146
- function getValueFromPointer(pointerPosition) {
147
- return linearScale([0, state.size], [max, min])(pointerPosition);
148
- }
149
- const measure = () => {
150
- sliderRef.current?.measure((_x, _y, _width, height, _pageX, pageY) => {
151
- setState({
152
- size: height,
153
- offset: pageY + (isIos ? insets.top : 0)
154
- });
155
- });
156
- };
157
- useSliderMeasure(sliderRef, measure);
158
- return /* @__PURE__ */jsx(SliderOrientationProvider, {
159
- scope: props.__scopeSlider,
160
- startEdge: "bottom",
161
- endEdge: "top",
162
- sizeProp: "height",
163
- size: state.size,
164
- direction: 1,
165
- children: /* @__PURE__ */jsx(SliderImpl, {
166
- ref: composeRefs(forwardedRef, sliderRef),
167
- ...sliderProps,
168
- orientation: "vertical",
169
- onLayout: measure,
170
- onSlideStart: (event, target) => {
171
- const value = getValueFromPointer(event.nativeEvent.locationY);
172
- if (value) onSlideStart?.(value, target, event);
173
- },
174
- onSlideMove: event => {
175
- const value = getValueFromPointer(event.nativeEvent.pageY - state.offset);
176
- if (value) onSlideMove?.(value, event);
177
- },
178
- onSlideEnd: event => {
179
- const value = getValueFromPointer(event.nativeEvent.pageY - state.offset);
180
- onSlideEnd?.(event, value);
181
- },
182
- onStepKeyDown: event => {
183
- const isBackKey = BACK_KEYS.ltr.includes(event.key);
184
- onStepKeyDown?.({
185
- event,
186
- direction: isBackKey ? -1 : 1
187
- });
188
- }
189
- })
190
- });
136
+ const SliderVertical = createRefComponent((props, forwardedRef) => {
137
+ const { min, max, onSlideStart, onSlideMove, onStepKeyDown, onSlideEnd, ...sliderProps } = props;
138
+ const [state, setState_] = React.useState(() => ({
139
+ size: 0,
140
+ offset: 0
141
+ }));
142
+ const setState = useCreateShallowSetState(setState_);
143
+ const sliderRef = React.useRef(null);
144
+ const configuration = useConfiguration();
145
+ const insets = isIos && configuration.insets ? configuration.insets : {
146
+ top: 0,
147
+ bottom: 0
148
+ };
149
+ function getValueFromPointer(pointerPosition) {
150
+ return linearScale([0, state.size], [max, min])(pointerPosition);
151
+ }
152
+ const measure = () => {
153
+ sliderRef.current?.measure((_x, _y, _width, height, _pageX, pageY) => {
154
+ setState({
155
+ size: height,
156
+ offset: pageY + (isIos ? insets.top : 0)
157
+ });
158
+ });
159
+ };
160
+ useSliderMeasure(sliderRef, measure);
161
+ return /* @__PURE__ */ jsx(SliderOrientationProvider, {
162
+ scope: props.__scopeSlider,
163
+ startEdge: "bottom",
164
+ endEdge: "top",
165
+ sizeProp: "height",
166
+ size: state.size,
167
+ direction: 1,
168
+ children: /* @__PURE__ */ jsx(SliderImpl, {
169
+ ref: composeRefs(forwardedRef, sliderRef),
170
+ ...sliderProps,
171
+ orientation: "vertical",
172
+ onLayout: measure,
173
+ onSlideStart: (event, target) => {
174
+ const value = getValueFromPointer(event.nativeEvent.locationY);
175
+ if (value) onSlideStart?.(value, target, event);
176
+ },
177
+ onSlideMove: (event) => {
178
+ const value = getValueFromPointer(event.nativeEvent.pageY - state.offset);
179
+ if (value) onSlideMove?.(value, event);
180
+ },
181
+ onSlideEnd: (event) => {
182
+ const value = getValueFromPointer(event.nativeEvent.pageY - state.offset);
183
+ onSlideEnd?.(event, value);
184
+ },
185
+ onStepKeyDown: (event) => {
186
+ const isBackKey = BACK_KEYS.ltr.includes(event.key);
187
+ onStepKeyDown?.({
188
+ event,
189
+ direction: isBackKey ? -1 : 1
190
+ });
191
+ }
192
+ })
193
+ });
191
194
  });
192
195
  const SliderTrackFrame = styled(SliderFrame, {
193
- name: "Slider",
194
- variants: {
195
- unstyled: {
196
- false: {
197
- height: "100%",
198
- width: "100%",
199
- backgroundColor: "$background",
200
- position: "relative",
201
- borderRadius: 1e5,
202
- overflow: "hidden"
203
- }
204
- }
205
- },
206
- defaultVariants: {
207
- unstyled: process.env.TAMAGUI_HEADLESS === "1"
208
- }
196
+ displayName: "Slider",
197
+ height: "100%",
198
+ width: "100%",
199
+ position: "relative",
200
+ overflow: "hidden"
209
201
  });
210
- const SliderTrack = React.forwardRef(function SliderTrack2(props, forwardedRef) {
211
- const {
212
- __scopeSlider,
213
- ...trackProps
214
- } = props;
215
- const context = useSliderContext(__scopeSlider);
216
- return /* @__PURE__ */jsx(SliderTrackFrame, {
217
- "data-disabled": context.disabled ? "" : void 0,
218
- "data-orientation": context.orientation,
219
- orientation: context.orientation,
220
- size: context.size,
221
- ...trackProps,
222
- ref: forwardedRef
223
- });
202
+ const SliderTrack = createStyledHOC(SliderTrackFrame, function SliderTrack2(props, forwardedRef) {
203
+ const { __scopeSlider, ...trackProps } = props;
204
+ const context = useSliderContext(__scopeSlider);
205
+ return /* @__PURE__ */ jsx(SliderTrackFrame, {
206
+ "data-disabled": context.disabled ? "" : void 0,
207
+ "data-orientation": context.orientation,
208
+ orientation: context.orientation,
209
+ size: context.size,
210
+ ...trackProps,
211
+ ref: forwardedRef
212
+ });
224
213
  });
225
214
  const SliderActiveFrame = styled(SliderFrame, {
226
- name: "SliderActive",
227
- position: "absolute",
228
- pointerEvents: "box-none",
229
- variants: {
230
- unstyled: {
231
- false: {
232
- backgroundColor: "$background",
233
- borderRadius: 1e5
234
- }
235
- }
236
- },
237
- defaultVariants: {
238
- unstyled: process.env.TAMAGUI_HEADLESS === "1"
239
- }
215
+ displayName: "SliderActive",
216
+ position: "absolute",
217
+ pointerEvents: "box-none"
240
218
  });
241
- const SliderActive = React.forwardRef(function SliderActive2(props, forwardedRef) {
242
- const {
243
- __scopeSlider,
244
- ...rangeProps
245
- } = props;
246
- const context = useSliderContext(__scopeSlider);
247
- const orientation = useSliderOrientationContext(__scopeSlider);
248
- const composedRefs = useComposedRefs(forwardedRef, React.useRef(null));
249
- const valuesCount = context.values.length;
250
- const percentages = context.values.map(value => convertValueToPercentage(value, context.min, context.max));
251
- const offsetStart = valuesCount > 1 ? Math.min(...percentages) : 0;
252
- const offsetEnd = 100 - Math.max(...percentages);
253
- return /* @__PURE__ */jsx(SliderActiveFrame, {
254
- orientation: context.orientation,
255
- "data-orientation": context.orientation,
256
- "data-disabled": context.disabled ? "" : void 0,
257
- size: context.size,
258
- animateOnly: ["left", "top", "right", "bottom"],
259
- ...rangeProps,
260
- ref: composedRefs,
261
- [orientation.startEdge]: `${offsetStart}%`,
262
- [orientation.endEdge]: `${offsetEnd}%`,
263
- ...(orientation.sizeProp === "width" ? {
264
- height: "100%"
265
- } : {
266
- left: 0,
267
- right: 0
268
- })
269
- });
219
+ const SliderActive = createStyledHOC(SliderActiveFrame, function SliderActive2(props, forwardedRef) {
220
+ const { __scopeSlider, ...rangeProps } = props;
221
+ const context = useSliderContext(__scopeSlider);
222
+ const orientation = useSliderOrientationContext(__scopeSlider);
223
+ const composedRefs = useComposedRefs(forwardedRef, React.useRef(null));
224
+ const valuesCount = context.values.length;
225
+ const percentages = context.values.map((value) => convertValueToPercentage(value, context.min, context.max));
226
+ const offsetStart = valuesCount > 1 ? Math.min(...percentages) : 0;
227
+ const offsetEnd = 100 - Math.max(...percentages);
228
+ return /* @__PURE__ */ jsx(SliderActiveFrame, {
229
+ orientation: context.orientation,
230
+ "data-orientation": context.orientation,
231
+ "data-disabled": context.disabled ? "" : void 0,
232
+ size: context.size,
233
+ animateOnly: [
234
+ "left",
235
+ "top",
236
+ "right",
237
+ "bottom"
238
+ ],
239
+ ...rangeProps,
240
+ ref: composedRefs,
241
+ [orientation.startEdge]: `${offsetStart}%`,
242
+ [orientation.endEdge]: `${offsetEnd}%`,
243
+ ...orientation.sizeProp === "width" ? { height: "100%" } : {
244
+ left: 0,
245
+ right: 0
246
+ }
247
+ });
270
248
  });
271
- const getThumbSize = val => {
272
- const tokens = getTokens();
273
- const size = typeof val === "number" ? val : getSize(tokens.size[val], {
274
- shift: -1
275
- });
276
- return {
277
- width: size,
278
- height: size,
279
- minWidth: size,
280
- minHeight: size
281
- };
249
+ const getThumbSize = (val) => {
250
+ const tokens = getTokens();
251
+ const sizeToken = resolveSizeToken(val ?? true, "size");
252
+ const resolved = typeof sizeToken === "number" ? sizeToken : tokens.size[sizeToken];
253
+ const size = typeof val === "number" ? val : getVariableValue(resolved) * .86;
254
+ return {
255
+ width: size,
256
+ height: size,
257
+ minWidth: size,
258
+ minHeight: size
259
+ };
282
260
  };
283
- const SliderThumbFrame = styled(ThemeableStack, {
284
- name: "SliderThumb",
285
- variants: {
286
- size: {
287
- "...size": getThumbSize,
288
- ":number": getThumbSize
289
- },
290
- unstyled: {
291
- false: {
292
- position: "absolute",
293
- borderWidth: 2,
294
- borderColor: "$borderColor",
295
- backgroundColor: "$background",
296
- pressStyle: {
297
- backgroundColor: "$backgroundPress",
298
- borderColor: "$borderColorPress"
299
- },
300
- hoverStyle: {
301
- backgroundColor: "$backgroundHover",
302
- borderColor: "$borderColorHover"
303
- },
304
- focusVisibleStyle: {
305
- outlineStyle: "solid",
306
- outlineWidth: 2,
307
- outlineColor: "$outlineColor"
308
- }
309
- }
310
- }
311
- },
312
- defaultVariants: {
313
- unstyled: process.env.TAMAGUI_HEADLESS === "1"
314
- }
315
- });
316
- const SliderThumb = SliderThumbFrame.styleable(function SliderThumb2(props, forwardedRef) {
317
- const {
318
- __scopeSlider,
319
- index = 0,
320
- circular,
321
- size: sizeProp,
322
- ...thumbProps
323
- } = props;
324
- const context = useSliderContext(__scopeSlider);
325
- const orientation = useSliderOrientationContext(__scopeSlider);
326
- const [thumb, setThumb] = React.useState(null);
327
- const composedRefs = useComposedRefs(forwardedRef, setThumb);
328
- const value = context.values[index];
329
- const percent = value === void 0 ? 0 : convertValueToPercentage(value, context.min, context.max);
330
- const label = getLabel(index, context.values.length);
331
- const sizeIn = sizeProp ?? context.size ?? "$true";
332
- const [size, setSize] = React.useState(() => {
333
- return getVariableValue(getThumbSize(sizeIn).width);
334
- });
335
- const thumbInBoundsOffset = size ? getThumbInBoundsOffset(size, percent, orientation.direction) : 0;
336
- React.useEffect(() => {
337
- if (thumb) {
338
- context.thumbs.set(thumb, index);
339
- return () => {
340
- context.thumbs.delete(thumb);
341
- };
342
- }
343
- }, [thumb, context.thumbs, index]);
344
- const positionalStyles = context.orientation === "horizontal" ? {
345
- x: (thumbInBoundsOffset - size / 2) * orientation.direction,
346
- y: -size / 2,
347
- top: "50%",
348
- ...(size === 0 && {
349
- top: "auto",
350
- bottom: "auto"
351
- })
352
- } : {
353
- x: -size / 2,
354
- y: size / 2,
355
- left: "50%",
356
- ...(size === 0 && {
357
- left: "auto",
358
- right: "auto"
359
- })
360
- };
361
- return /* @__PURE__ */jsx(SliderThumbFrame, {
362
- ref: composedRefs,
363
- role: "slider",
364
- "aria-label": props["aria-label"] || label,
365
- "aria-valuemin": context.min,
366
- "aria-valuenow": value,
367
- "aria-valuemax": context.max,
368
- "aria-orientation": context.orientation,
369
- "data-orientation": context.orientation,
370
- "data-disabled": context.disabled ? "" : void 0,
371
- tabIndex: context.disabled ? void 0 : 0,
372
- animateOnly: ["transform", "left", "top", "right", "bottom"],
373
- ...positionalStyles,
374
- [orientation.startEdge]: `${percent}%`,
375
- size: sizeIn,
376
- circular,
377
- ...thumbProps,
378
- onLayout: e => {
379
- setSize(e.nativeEvent.layout[orientation.sizeProp]);
380
- },
381
- onFocus: composeEventHandlers(props.onFocus, () => {
382
- context.valueIndexToChangeRef.current = index;
383
- })
384
- });
385
- }, {
386
- staticConfig: {
387
- memo: true
388
- }
261
+ const SliderThumbFrame = styled(YStack, {
262
+ displayName: "SliderThumb",
263
+ position: "absolute",
264
+ variants: {
265
+ size: {
266
+ number: getThumbSize,
267
+ Size: getThumbSize
268
+ },
269
+ circular: { true: {
270
+ borderRadius: 1e5,
271
+ padding: 0
272
+ } },
273
+ elevate: { true: {
274
+ shadowColor: "shadow-color",
275
+ shadowRadius: 4,
276
+ shadowOffset: {
277
+ width: 0,
278
+ height: 2
279
+ }
280
+ } }
281
+ }
389
282
  });
390
- const Slider = withStaticProperties(React.forwardRef((props, forwardedRef) => {
391
- const {
392
- name,
393
- min = 0,
394
- max = 100,
395
- step = 1,
396
- orientation = "horizontal",
397
- disabled = false,
398
- minStepsBetweenThumbs = 0,
399
- defaultValue = [min],
400
- value,
401
- onValueChange = () => {},
402
- size: sizeProp,
403
- onSlideEnd,
404
- onSlideMove,
405
- onSlideStart,
406
- ...sliderProps
407
- } = props;
408
- const sliderRef = React.useRef(null);
409
- const composedRefs = useComposedRefs(sliderRef, forwardedRef);
410
- const thumbRefs = React.useRef(/* @__PURE__ */new Map());
411
- const valueIndexToChangeRef = React.useRef(0);
412
- const isHorizontal = orientation === "horizontal";
413
- const [values = [], setValues] = useControllableState({
414
- prop: value,
415
- defaultProp: defaultValue,
416
- transition: true,
417
- onChange: value2 => {
418
- updateThumbFocus(valueIndexToChangeRef.current);
419
- onValueChange(value2);
420
- }
421
- });
422
- if (isWeb) React.useEffect(() => {
423
- const node = sliderRef.current;
424
- if (!node) return;
425
- const preventDefault = e => {
426
- e.preventDefault();
427
- };
428
- node.addEventListener("touchstart", preventDefault);
429
- return () => {
430
- node.removeEventListener("touchstart", preventDefault);
431
- };
432
- }, []);
433
- function updateThumbFocus(focusIndex) {
434
- if (!isWeb) return;
435
- for (const [node, index] of thumbRefs.current.entries()) if (index === focusIndex) {
436
- node.focus();
437
- return;
438
- }
439
- }
440
- function handleSlideMove(value2, event) {
441
- updateValues(value2, valueIndexToChangeRef.current);
442
- onSlideMove?.(event, value2);
443
- }
444
- function updateValues(value2, atIndex) {
445
- const decimalCount = getDecimalCount(step);
446
- const nextValue = clamp(roundValue(Math.round((value2 - min) / step) * step + min, decimalCount), [min, max]);
447
- setValues((prevValues = []) => {
448
- const nextValues = getNextSortedValues(prevValues, nextValue, atIndex);
449
- if (hasMinStepsBetweenValues(nextValues, minStepsBetweenThumbs * step)) {
450
- valueIndexToChangeRef.current = nextValues.indexOf(nextValue);
451
- return String(nextValues) === String(prevValues) ? prevValues : nextValues;
452
- }
453
- return prevValues;
454
- });
455
- }
456
- const SliderOriented = isHorizontal ? SliderHorizontal : SliderVertical;
457
- return /* @__PURE__ */jsx(SliderProvider, {
458
- scope: props.__scopeSlider,
459
- disabled,
460
- min,
461
- max,
462
- valueIndexToChangeRef,
463
- thumbs: thumbRefs.current,
464
- values,
465
- orientation,
466
- size: sizeProp,
467
- children: /* @__PURE__ */jsx(SliderOriented, {
468
- "aria-disabled": disabled,
469
- "data-disabled": disabled ? "" : void 0,
470
- ...sliderProps,
471
- ref: composedRefs,
472
- min,
473
- max,
474
- onSlideEnd,
475
- onSlideStart: disabled ? void 0 : (value2, target, event) => {
476
- if (target !== "thumb") updateValues(value2, getClosestValueIndex(values, value2));
477
- onSlideStart?.(event, value2, target);
478
- },
479
- onSlideMove: disabled ? void 0 : handleSlideMove,
480
- onHomeKeyDown: () => !disabled && updateValues(min, 0),
481
- onEndKeyDown: () => !disabled && updateValues(max, values.length - 1),
482
- onStepKeyDown: ({
483
- event,
484
- direction: stepDirection
485
- }) => {
486
- if (!disabled) {
487
- const multiplier = PAGE_KEYS.includes(event.key) || event.shiftKey && ARROW_KEYS.includes(event.key) ? 10 : 1;
488
- const atIndex = valueIndexToChangeRef.current;
489
- const value2 = values[atIndex];
490
- updateValues(value2 + step * multiplier * stepDirection, atIndex);
491
- }
492
- }
493
- })
494
- });
283
+ const SliderThumb = createStyledHOC(SliderThumbFrame, function SliderThumb2(props, forwardedRef) {
284
+ const { __scopeSlider, index = 0, circular, size: sizeProp, ...thumbProps } = props;
285
+ const context = useSliderContext(__scopeSlider);
286
+ const orientation = useSliderOrientationContext(__scopeSlider);
287
+ const [thumb, setThumb] = React.useState(null);
288
+ const composedRefs = useComposedRefs(forwardedRef, setThumb);
289
+ const value = context.values[index];
290
+ const percent = value === void 0 ? 0 : convertValueToPercentage(value, context.min, context.max);
291
+ const label = getLabel(index, context.values.length);
292
+ const sizeIn = sizeProp ?? context.size ?? true;
293
+ const [size, setSize] = React.useState(() => {
294
+ return getVariableValue(getThumbSize(sizeIn).width);
295
+ });
296
+ const thumbInBoundsOffset = size ? getThumbInBoundsOffset(size, percent, orientation.direction) : 0;
297
+ React.useEffect(() => {
298
+ if (thumb) {
299
+ context.thumbs.set(thumb, index);
300
+ return () => {
301
+ context.thumbs.delete(thumb);
302
+ };
303
+ }
304
+ }, [
305
+ thumb,
306
+ context.thumbs,
307
+ index
308
+ ]);
309
+ const positionalStyles = context.orientation === "horizontal" ? {
310
+ x: (thumbInBoundsOffset - size / 2) * orientation.direction,
311
+ y: -size / 2,
312
+ top: "50%",
313
+ ...size === 0 && {
314
+ top: "auto",
315
+ bottom: "auto"
316
+ }
317
+ } : {
318
+ x: -size / 2,
319
+ y: size / 2,
320
+ left: "50%",
321
+ ...size === 0 && {
322
+ left: "auto",
323
+ right: "auto"
324
+ }
325
+ };
326
+ return /* @__PURE__ */ jsx(SliderThumbFrame, {
327
+ ref: composedRefs,
328
+ role: "slider",
329
+ "aria-label": props["aria-label"] || label,
330
+ "aria-valuemin": context.min,
331
+ "aria-valuenow": value,
332
+ "aria-valuemax": context.max,
333
+ "aria-orientation": context.orientation,
334
+ "data-orientation": context.orientation,
335
+ "data-disabled": context.disabled ? "" : void 0,
336
+ tabIndex: context.disabled ? void 0 : 0,
337
+ animateOnly: [
338
+ "transform",
339
+ "left",
340
+ "top",
341
+ "right",
342
+ "bottom"
343
+ ],
344
+ ...positionalStyles,
345
+ [orientation.startEdge]: `${percent}%`,
346
+ size: sizeIn,
347
+ circular,
348
+ ...thumbProps,
349
+ onLayout: (e) => {
350
+ setSize(e.nativeEvent.layout[orientation.sizeProp]);
351
+ },
352
+ onFocus: composeEventHandlers(props.onFocus, () => {
353
+ context.valueIndexToChangeRef.current = index;
354
+ })
355
+ });
356
+ }, { staticConfig: { memo: true } });
357
+ const Slider = withStaticProperties(createRefComponent((props, forwardedRef) => {
358
+ const { name, min = 0, max = 100, step = 1, orientation = "horizontal", disabled = false, minStepsBetweenThumbs = 0, defaultValue = [min], value, onValueChange = () => {}, size: sizeProp, onSlideEnd, onSlideMove, onSlideStart, ...sliderProps } = props;
359
+ const sliderRef = React.useRef(null);
360
+ const composedRefs = useComposedRefs(sliderRef, forwardedRef);
361
+ const thumbRefs = React.useRef(/* @__PURE__ */ new Map());
362
+ const valueIndexToChangeRef = React.useRef(0);
363
+ const isHorizontal = orientation === "horizontal";
364
+ const [values = [], setValues] = useControllableState({
365
+ prop: value,
366
+ defaultProp: defaultValue,
367
+ transition: true,
368
+ onChange: (value2) => {
369
+ updateThumbFocus(valueIndexToChangeRef.current);
370
+ onValueChange(value2);
371
+ }
372
+ });
373
+ if (isWeb) React.useEffect(() => {
374
+ const node = sliderRef.current;
375
+ if (!node) return;
376
+ const preventDefault = (e) => {
377
+ e.preventDefault();
378
+ };
379
+ node.addEventListener("touchstart", preventDefault);
380
+ return () => {
381
+ node.removeEventListener("touchstart", preventDefault);
382
+ };
383
+ }, []);
384
+ function updateThumbFocus(focusIndex) {
385
+ if (!isWeb) return;
386
+ for (const [node, index] of thumbRefs.current.entries()) if (index === focusIndex) {
387
+ node.focus();
388
+ return;
389
+ }
390
+ }
391
+ function handleSlideMove(value2, event) {
392
+ updateValues(value2, valueIndexToChangeRef.current);
393
+ onSlideMove?.(event, value2);
394
+ }
395
+ function updateValues(value2, atIndex) {
396
+ const decimalCount = getDecimalCount(step);
397
+ const nextValue = clamp(roundValue(Math.round((value2 - min) / step) * step + min, decimalCount), [min, max]);
398
+ setValues((prevValues = []) => {
399
+ const nextValues = getNextSortedValues(prevValues, nextValue, atIndex);
400
+ if (hasMinStepsBetweenValues(nextValues, minStepsBetweenThumbs * step)) {
401
+ valueIndexToChangeRef.current = nextValues.indexOf(nextValue);
402
+ return String(nextValues) === String(prevValues) ? prevValues : nextValues;
403
+ }
404
+ return prevValues;
405
+ });
406
+ }
407
+ const SliderOriented = isHorizontal ? SliderHorizontal : SliderVertical;
408
+ return /* @__PURE__ */ jsxs(SliderProvider, {
409
+ scope: props.__scopeSlider,
410
+ disabled,
411
+ min,
412
+ max,
413
+ valueIndexToChangeRef,
414
+ thumbs: thumbRefs.current,
415
+ values,
416
+ orientation,
417
+ size: sizeProp,
418
+ children: [/* @__PURE__ */ jsx(SliderOriented, {
419
+ "aria-disabled": disabled,
420
+ "data-disabled": disabled ? "" : void 0,
421
+ ...sliderProps,
422
+ ref: composedRefs,
423
+ min,
424
+ max,
425
+ onSlideEnd,
426
+ onSlideStart: disabled ? void 0 : (value2, target, event) => {
427
+ if (target !== "thumb") updateValues(value2, getClosestValueIndex(values, value2));
428
+ onSlideStart?.(event, value2, target);
429
+ },
430
+ onSlideMove: disabled ? void 0 : handleSlideMove,
431
+ onHomeKeyDown: () => !disabled && updateValues(min, 0),
432
+ onEndKeyDown: () => !disabled && updateValues(max, values.length - 1),
433
+ onStepKeyDown: ({ event, direction: stepDirection }) => {
434
+ if (!disabled) {
435
+ const multiplier = PAGE_KEYS.includes(event.key) || event.shiftKey && ARROW_KEYS.includes(event.key) ? 10 : 1;
436
+ const atIndex = valueIndexToChangeRef.current;
437
+ const value2 = values[atIndex];
438
+ updateValues(value2 + step * multiplier * stepDirection, atIndex);
439
+ }
440
+ }
441
+ }), isWeb && name && values.map((value2, index) => /* @__PURE__ */ jsx("input", {
442
+ type: "hidden",
443
+ name,
444
+ value: value2
445
+ }, index))]
446
+ });
495
447
  }), {
496
- Track: SliderTrack,
497
- TrackActive: SliderActive,
498
- Thumb: SliderThumb
448
+ Track: SliderTrack,
449
+ TrackActive: SliderActive,
450
+ Thumb: SliderThumb
499
451
  });
500
452
  Slider.displayName = SLIDER_NAME;
501
453
  const Track = SliderTrack;
502
454
  const Range = SliderActive;
503
455
  const Thumb = SliderThumb;
456
+
504
457
  export { Range, Slider, SliderActive, SliderActiveFrame, SliderThumb, SliderThumbFrame, SliderTrack, SliderTrackFrame, Thumb, Track };
505
458
  //# sourceMappingURL=Slider.mjs.map