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