@webority-technologies/mobile 0.0.23 → 0.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/components/Accordion/Accordion.js +5 -5
- package/lib/commonjs/components/AnimatePresence/AnimatePresence.js +69 -0
- package/lib/commonjs/components/AnimatePresence/index.js +13 -0
- package/lib/commonjs/components/AppBar/AppBar.js +9 -6
- package/lib/commonjs/components/Banner/Banner.js +12 -2
- package/lib/commonjs/components/Card/Card.js +3 -3
- package/lib/commonjs/components/Checkbox/Checkbox.js +3 -2
- package/lib/commonjs/components/Chip/Chip.js +4 -2
- package/lib/commonjs/components/DatePicker/DatePicker.js +23 -18
- package/lib/commonjs/components/DateRangePicker/DateRangePicker.js +11 -9
- package/lib/commonjs/components/Dialog/Dialog.js +4 -2
- package/lib/commonjs/components/Drawer/Drawer.js +4 -2
- package/lib/commonjs/components/FloatingActionButton/FloatingActionButton.js +10 -8
- package/lib/commonjs/components/ImageGallery/ImageGallery.js +17 -15
- package/lib/commonjs/components/ListItem/ListItem.js +4 -3
- package/lib/commonjs/components/Modal/Modal.js +4 -3
- package/lib/commonjs/components/NumberInput/NumberInput.js +7 -5
- package/lib/commonjs/components/OTPInput/OTPInput.js +7 -7
- package/lib/commonjs/components/Radio/Radio.js +2 -3
- package/lib/commonjs/components/Rating/Rating.js +4 -3
- package/lib/commonjs/components/SearchBar/SearchBar.js +7 -4
- package/lib/commonjs/components/SegmentedControl/SegmentedControl.js +4 -3
- package/lib/commonjs/components/Select/Select.js +7 -4
- package/lib/commonjs/components/Slider/Slider.js +228 -228
- package/lib/commonjs/components/Stepper/Stepper.js +6 -5
- package/lib/commonjs/components/Swipeable/Swipeable.js +8 -9
- package/lib/commonjs/components/Tabs/Tabs.js +4 -3
- package/lib/commonjs/components/TimePicker/TimePicker.js +14 -9
- package/lib/commonjs/components/index.js +121 -114
- package/lib/commonjs/utils/hapticUtils.js +11 -1
- package/lib/commonjs/utils/index.js +6 -0
- package/lib/module/components/Accordion/Accordion.js +6 -6
- package/lib/module/components/AnimatePresence/AnimatePresence.js +63 -0
- package/lib/module/components/AnimatePresence/index.js +4 -0
- package/lib/module/components/AppBar/AppBar.js +10 -7
- package/lib/module/components/Banner/Banner.js +12 -2
- package/lib/module/components/Card/Card.js +4 -4
- package/lib/module/components/Checkbox/Checkbox.js +4 -3
- package/lib/module/components/Chip/Chip.js +5 -3
- package/lib/module/components/DatePicker/DatePicker.js +24 -19
- package/lib/module/components/DateRangePicker/DateRangePicker.js +12 -10
- package/lib/module/components/Dialog/Dialog.js +5 -3
- package/lib/module/components/Drawer/Drawer.js +5 -3
- package/lib/module/components/FloatingActionButton/FloatingActionButton.js +11 -9
- package/lib/module/components/ImageGallery/ImageGallery.js +18 -16
- package/lib/module/components/ListItem/ListItem.js +5 -4
- package/lib/module/components/Modal/Modal.js +5 -4
- package/lib/module/components/NumberInput/NumberInput.js +8 -6
- package/lib/module/components/OTPInput/OTPInput.js +8 -8
- package/lib/module/components/Radio/Radio.js +3 -4
- package/lib/module/components/Rating/Rating.js +5 -4
- package/lib/module/components/SearchBar/SearchBar.js +8 -5
- package/lib/module/components/SegmentedControl/SegmentedControl.js +5 -4
- package/lib/module/components/Select/Select.js +8 -5
- package/lib/module/components/Slider/Slider.js +231 -231
- package/lib/module/components/Stepper/Stepper.js +7 -6
- package/lib/module/components/Swipeable/Swipeable.js +9 -10
- package/lib/module/components/Tabs/Tabs.js +5 -4
- package/lib/module/components/TimePicker/TimePicker.js +15 -10
- package/lib/module/components/index.js +1 -0
- package/lib/module/utils/hapticUtils.js +9 -0
- package/lib/module/utils/index.js +1 -1
- package/lib/typescript/commonjs/components/Accordion/Accordion.d.ts +3 -0
- package/lib/typescript/commonjs/components/AnimatePresence/AnimatePresence.d.ts +30 -0
- package/lib/typescript/commonjs/components/AnimatePresence/index.d.ts +3 -0
- package/lib/typescript/commonjs/components/AppBar/AppBar.d.ts +6 -0
- package/lib/typescript/commonjs/components/Banner/Banner.d.ts +3 -0
- package/lib/typescript/commonjs/components/Card/Card.d.ts +3 -0
- package/lib/typescript/commonjs/components/Checkbox/Checkbox.d.ts +1 -0
- package/lib/typescript/commonjs/components/Chip/Chip.d.ts +3 -0
- package/lib/typescript/commonjs/components/DatePicker/DatePicker.d.ts +3 -0
- package/lib/typescript/commonjs/components/DateRangePicker/DateRangePicker.d.ts +6 -0
- package/lib/typescript/commonjs/components/Dialog/Dialog.d.ts +3 -0
- package/lib/typescript/commonjs/components/Drawer/Drawer.d.ts +3 -0
- package/lib/typescript/commonjs/components/FloatingActionButton/FloatingActionButton.d.ts +5 -0
- package/lib/typescript/commonjs/components/ImageGallery/ImageGallery.d.ts +6 -0
- package/lib/typescript/commonjs/components/ListItem/ListItem.d.ts +3 -0
- package/lib/typescript/commonjs/components/Modal/Modal.d.ts +6 -0
- package/lib/typescript/commonjs/components/NumberInput/NumberInput.d.ts +3 -0
- package/lib/typescript/commonjs/components/OTPInput/OTPInput.d.ts +6 -0
- package/lib/typescript/commonjs/components/Rating/Rating.d.ts +6 -0
- package/lib/typescript/commonjs/components/SearchBar/SearchBar.d.ts +3 -0
- package/lib/typescript/commonjs/components/SegmentedControl/SegmentedControl.d.ts +3 -0
- package/lib/typescript/commonjs/components/Select/Select.d.ts +6 -0
- package/lib/typescript/commonjs/components/Slider/Slider.d.ts +3 -0
- package/lib/typescript/commonjs/components/Stepper/Stepper.d.ts +6 -0
- package/lib/typescript/commonjs/components/Swipeable/Swipeable.d.ts +3 -0
- package/lib/typescript/commonjs/components/Tabs/Tabs.d.ts +3 -0
- package/lib/typescript/commonjs/components/TimePicker/TimePicker.d.ts +3 -0
- package/lib/typescript/commonjs/components/index.d.ts +2 -0
- package/lib/typescript/commonjs/theme/types.d.ts +2 -67
- package/lib/typescript/commonjs/utils/hapticUtils.d.ts +8 -0
- package/lib/typescript/commonjs/utils/index.d.ts +1 -1
- package/lib/typescript/module/components/Accordion/Accordion.d.ts +3 -0
- package/lib/typescript/module/components/AnimatePresence/AnimatePresence.d.ts +30 -0
- package/lib/typescript/module/components/AnimatePresence/index.d.ts +3 -0
- package/lib/typescript/module/components/AppBar/AppBar.d.ts +6 -0
- package/lib/typescript/module/components/Banner/Banner.d.ts +3 -0
- package/lib/typescript/module/components/Card/Card.d.ts +3 -0
- package/lib/typescript/module/components/Checkbox/Checkbox.d.ts +1 -0
- package/lib/typescript/module/components/Chip/Chip.d.ts +3 -0
- package/lib/typescript/module/components/DatePicker/DatePicker.d.ts +3 -0
- package/lib/typescript/module/components/DateRangePicker/DateRangePicker.d.ts +6 -0
- package/lib/typescript/module/components/Dialog/Dialog.d.ts +3 -0
- package/lib/typescript/module/components/Drawer/Drawer.d.ts +3 -0
- package/lib/typescript/module/components/FloatingActionButton/FloatingActionButton.d.ts +5 -0
- package/lib/typescript/module/components/ImageGallery/ImageGallery.d.ts +6 -0
- package/lib/typescript/module/components/ListItem/ListItem.d.ts +3 -0
- package/lib/typescript/module/components/Modal/Modal.d.ts +6 -0
- package/lib/typescript/module/components/NumberInput/NumberInput.d.ts +3 -0
- package/lib/typescript/module/components/OTPInput/OTPInput.d.ts +6 -0
- package/lib/typescript/module/components/Rating/Rating.d.ts +6 -0
- package/lib/typescript/module/components/SearchBar/SearchBar.d.ts +3 -0
- package/lib/typescript/module/components/SegmentedControl/SegmentedControl.d.ts +3 -0
- package/lib/typescript/module/components/Select/Select.d.ts +6 -0
- package/lib/typescript/module/components/Slider/Slider.d.ts +3 -0
- package/lib/typescript/module/components/Stepper/Stepper.d.ts +6 -0
- package/lib/typescript/module/components/Swipeable/Swipeable.d.ts +3 -0
- package/lib/typescript/module/components/Tabs/Tabs.d.ts +3 -0
- package/lib/typescript/module/components/TimePicker/TimePicker.d.ts +3 -0
- package/lib/typescript/module/components/index.d.ts +2 -0
- package/lib/typescript/module/theme/types.d.ts +2 -67
- package/lib/typescript/module/utils/hapticUtils.d.ts +8 -0
- package/lib/typescript/module/utils/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = exports.Slider = void 0;
|
|
7
7
|
var _react = _interopRequireWildcard(require("react"));
|
|
8
8
|
var _reactNative = require("react-native");
|
|
9
|
+
var _reactNativeGestureHandler = require("react-native-gesture-handler");
|
|
10
|
+
var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
|
|
9
11
|
var _index = require("../../theme/index.js");
|
|
10
12
|
var _index2 = require("../../utils/index.js");
|
|
11
13
|
var _index3 = require("../../hooks/index.js");
|
|
@@ -35,7 +37,6 @@ const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
|
|
|
35
37
|
const snapToStep = (value, min, max, step) => {
|
|
36
38
|
if (step <= 0) return clamp(value, min, max);
|
|
37
39
|
const stepped = Math.round((value - min) / step) * step + min;
|
|
38
|
-
// Guard against floating-point drift.
|
|
39
40
|
const decimals = String(step).split('.')[1]?.length ?? 0;
|
|
40
41
|
const fixed = decimals > 0 ? Number(stepped.toFixed(decimals)) : stepped;
|
|
41
42
|
return clamp(fixed, min, max);
|
|
@@ -52,6 +53,7 @@ const Slider = exports.Slider = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
|
|
|
52
53
|
showLabel = false,
|
|
53
54
|
formatLabel = defaultFormatLabel,
|
|
54
55
|
accessibilityLabel,
|
|
56
|
+
haptic,
|
|
55
57
|
style,
|
|
56
58
|
containerStyle,
|
|
57
59
|
trackStyle,
|
|
@@ -66,17 +68,20 @@ const Slider = exports.Slider = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
|
|
|
66
68
|
const theme = (0, _index.useTheme)();
|
|
67
69
|
const sliderTheme = theme.components.slider;
|
|
68
70
|
const sliderSizeTheme = sliderTheme?.[size];
|
|
69
|
-
const sizeCfg = {
|
|
71
|
+
const sizeCfg = (0, _react.useMemo)(() => ({
|
|
70
72
|
trackHeight: sliderSizeTheme?.trackHeight ?? SIZE_MAP[size].trackHeight,
|
|
71
73
|
thumbDiameter: sliderSizeTheme?.thumbDiameter ?? SIZE_MAP[size].thumbDiameter
|
|
72
|
-
};
|
|
74
|
+
}), [sliderSizeTheme, size]);
|
|
73
75
|
const thumbPressAnimationEnabled = sliderTheme?.thumbPressAnimation ?? false;
|
|
74
76
|
const resolvedPressScale = thumbPressScale ?? sliderTheme?.thumbPressScale ?? 1.1;
|
|
75
77
|
const resolvedLabelDuration = labelShowDuration ?? sliderTheme?.labelShowDuration ?? theme.motion.duration.fast;
|
|
76
78
|
const resolvedLabelOpacity = labelOpacityProp ?? sliderTheme?.labelOpacity ?? 1;
|
|
77
79
|
const styles = (0, _react.useMemo)(() => buildStyles(theme, sizeCfg), [theme, sizeCfg]);
|
|
78
|
-
|
|
79
|
-
|
|
80
|
+
const springCfg = (0, _react.useMemo)(() => ({
|
|
81
|
+
damping: theme.motion.spring.snappy.damping,
|
|
82
|
+
stiffness: theme.motion.spring.snappy.stiffness,
|
|
83
|
+
mass: theme.motion.spring.snappy.mass
|
|
84
|
+
}), [theme.motion.spring.snappy]);
|
|
80
85
|
const [trackWidth, setTrackWidth] = (0, _react.useState)(0);
|
|
81
86
|
const fillColor = theme.colors[TONE_TO_COLOR_KEY[tone]];
|
|
82
87
|
const isRange = props.range === true;
|
|
@@ -86,217 +91,218 @@ const Slider = exports.Slider = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
|
|
|
86
91
|
onChange: props.onChange
|
|
87
92
|
});
|
|
88
93
|
|
|
89
|
-
//
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
// Label opacity per thumb.
|
|
104
|
-
const lowLabelOpacity = (0, _react.useRef)((0, _index.createAnimatedValue)(0)).current;
|
|
105
|
-
const highLabelOpacity = (0, _react.useRef)((0, _index.createAnimatedValue)(0)).current;
|
|
94
|
+
// ───────── Shared values (UI thread) ─────────
|
|
95
|
+
// lowX/highX: thumb px positions. lowVal/highVal: their snapped numeric values
|
|
96
|
+
// (mirrored on the UI thread so worklets can clamp the range + detect changes).
|
|
97
|
+
const lowX = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
98
|
+
const highX = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
99
|
+
const lowVal = (0, _reactNativeReanimated.useSharedValue)(isRange ? currentValue[0] : currentValue);
|
|
100
|
+
const highVal = (0, _reactNativeReanimated.useSharedValue)(isRange ? currentValue[1] : currentValue);
|
|
101
|
+
const dragStartX = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
102
|
+
const trackW = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
103
|
+
const lowScale = (0, _reactNativeReanimated.useSharedValue)(1);
|
|
104
|
+
const highScale = (0, _reactNativeReanimated.useSharedValue)(1);
|
|
105
|
+
const lowLabelOpacity = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
106
|
+
const highLabelOpacity = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
106
107
|
|
|
107
|
-
//
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
108
|
+
// Float-drift guard precision for step snapping (e.g. step 0.1 -> precision 10).
|
|
109
|
+
const precision = (0, _react.useMemo)(() => {
|
|
110
|
+
const decimals = String(step).split('.')[1]?.length ?? 0;
|
|
111
|
+
return Math.pow(10, decimals);
|
|
112
|
+
}, [step]);
|
|
113
|
+
(0, _react.useEffect)(() => {
|
|
114
|
+
return () => {
|
|
115
|
+
(0, _reactNativeReanimated.cancelAnimation)(lowX);
|
|
116
|
+
(0, _reactNativeReanimated.cancelAnimation)(highX);
|
|
117
|
+
(0, _reactNativeReanimated.cancelAnimation)(lowScale);
|
|
118
|
+
(0, _reactNativeReanimated.cancelAnimation)(highScale);
|
|
119
|
+
(0, _reactNativeReanimated.cancelAnimation)(lowLabelOpacity);
|
|
120
|
+
(0, _reactNativeReanimated.cancelAnimation)(highLabelOpacity);
|
|
121
|
+
};
|
|
122
|
+
}, [lowX, highX, lowScale, highScale, lowLabelOpacity, highLabelOpacity]);
|
|
111
123
|
const valueToPx = (0, _react.useCallback)((value, width) => {
|
|
112
124
|
if (max === min || width <= 0) return 0;
|
|
113
|
-
|
|
114
|
-
return ratio * width;
|
|
125
|
+
return (value - min) / (max - min) * width;
|
|
115
126
|
}, [min, max]);
|
|
116
|
-
|
|
117
|
-
// Derived helper: convert px -> snapped value.
|
|
118
127
|
const pxToValue = (0, _react.useCallback)((px, width) => {
|
|
119
128
|
if (width <= 0) return min;
|
|
120
129
|
const ratio = clamp(px / width, 0, 1);
|
|
121
|
-
|
|
122
|
-
return snapToStep(raw, min, max, step);
|
|
130
|
+
return snapToStep(min + ratio * (max - min), min, max, step);
|
|
123
131
|
}, [min, max, step]);
|
|
124
132
|
|
|
125
|
-
// Sync external value ->
|
|
133
|
+
// Sync external value -> shared values (controlled updates, value prop changes).
|
|
126
134
|
(0, _react.useEffect)(() => {
|
|
127
135
|
if (trackWidth <= 0) return;
|
|
128
136
|
if (isRange) {
|
|
129
137
|
const [v0, v1] = currentValue;
|
|
130
138
|
const lo = Math.min(v0, v1);
|
|
131
139
|
const hi = Math.max(v0, v1);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
(0, _index.setNativeValue)(lowX, valueToPx(lo, trackWidth));
|
|
137
|
-
(0, _index.setNativeValue)(highX, valueToPx(hi, trackWidth));
|
|
140
|
+
lowVal.value = lo;
|
|
141
|
+
highVal.value = hi;
|
|
142
|
+
lowX.value = valueToPx(lo, trackWidth);
|
|
143
|
+
highX.value = valueToPx(hi, trackWidth);
|
|
138
144
|
} else {
|
|
139
145
|
const v = currentValue;
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
(0, _index.setNativeValue)(lowX, valueToPx(v, trackWidth));
|
|
146
|
+
lowVal.value = v;
|
|
147
|
+
highVal.value = v;
|
|
148
|
+
lowX.value = valueToPx(v, trackWidth);
|
|
144
149
|
}
|
|
145
|
-
// We intentionally listen to the value across both shapes via JSON; ESLint is fine.
|
|
146
150
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
147
151
|
}, [JSON.stringify(currentValue), trackWidth, isRange, valueToPx]);
|
|
148
152
|
const onTrackLayout = (0, _react.useCallback)(e => {
|
|
149
153
|
const w = e.nativeEvent.layout.width;
|
|
154
|
+
trackW.value = w;
|
|
150
155
|
setTrackWidth(w);
|
|
151
|
-
|
|
152
|
-
if (isRange) {
|
|
153
|
-
const [v0, v1] = currentValue;
|
|
154
|
-
const lo = Math.min(v0, v1);
|
|
155
|
-
const hi = Math.max(v0, v1);
|
|
156
|
-
(0, _index.setNativeValue)(lowX, valueToPx(lo, w));
|
|
157
|
-
(0, _index.setNativeValue)(highX, valueToPx(hi, w));
|
|
158
|
-
} else {
|
|
159
|
-
(0, _index.setNativeValue)(lowX, valueToPx(currentValue, w));
|
|
160
|
-
}
|
|
161
|
-
},
|
|
162
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
163
|
-
[isRange, valueToPx]);
|
|
156
|
+
}, [trackW]);
|
|
164
157
|
const fireChange = (0, _react.useCallback)((lo, hi) => {
|
|
165
158
|
setCurrentValue(isRange ? [lo, hi] : lo);
|
|
166
159
|
}, [isRange, setCurrentValue]);
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
damping: theme.motion.spring.snappy.damping,
|
|
172
|
-
stiffness: theme.motion.spring.snappy.stiffness,
|
|
173
|
-
mass: theme.motion.spring.snappy.mass,
|
|
174
|
-
useNativeDriver: true
|
|
175
|
-
}).start();
|
|
176
|
-
}
|
|
177
|
-
if (showLabel) {
|
|
178
|
-
_reactNative.Animated.timing(opacity, {
|
|
179
|
-
toValue: pressed ? resolvedLabelOpacity : 0,
|
|
180
|
-
duration: resolvedLabelDuration,
|
|
181
|
-
easing: _reactNative.Easing.out(_reactNative.Easing.cubic),
|
|
182
|
-
useNativeDriver: true
|
|
183
|
-
}).start();
|
|
184
|
-
}
|
|
185
|
-
}, [showLabel, theme.motion, thumbPressAnimationEnabled, resolvedPressScale, resolvedLabelDuration, resolvedLabelOpacity]);
|
|
160
|
+
const fireHaptic = (0, _react.useCallback)(() => {
|
|
161
|
+
const h = (0, _index2.resolveHaptic)(haptic, 'selection');
|
|
162
|
+
if (h) (0, _index2.triggerHaptic)(h);
|
|
163
|
+
}, [haptic]);
|
|
186
164
|
|
|
187
|
-
//
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
165
|
+
// ───────── Pan gesture per thumb (UI thread) ─────────
|
|
166
|
+
const buildPan = (0, _react.useCallback)(which => {
|
|
167
|
+
const xSV = which === 'low' ? lowX : highX;
|
|
168
|
+
const valSV = which === 'low' ? lowVal : highVal;
|
|
169
|
+
const otherSV = which === 'low' ? highVal : lowVal;
|
|
170
|
+
const scaleSV = which === 'low' ? lowScale : highScale;
|
|
171
|
+
const labelSV = which === 'low' ? lowLabelOpacity : highLabelOpacity;
|
|
172
|
+
const isLow = which === 'low';
|
|
173
|
+
const _min = min;
|
|
174
|
+
const _max = max;
|
|
175
|
+
const _step = step;
|
|
176
|
+
const _precision = precision;
|
|
177
|
+
const _range = isRange;
|
|
178
|
+
const _pressScale = resolvedPressScale;
|
|
179
|
+
const _pressAnim = thumbPressAnimationEnabled;
|
|
180
|
+
const _showLabel = showLabel;
|
|
181
|
+
const _labelOpacity = resolvedLabelOpacity;
|
|
182
|
+
const _labelDur = resolvedLabelDuration;
|
|
183
|
+
const _spring = springCfg;
|
|
184
|
+
return _reactNativeGestureHandler.Gesture.Pan().enabled(!disabled).minDistance(0).onStart(() => {
|
|
185
|
+
'worklet';
|
|
201
186
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
if (sliderTheme?.stepHaptic ?? false) (0, _index2.triggerHaptic)('selection');
|
|
210
|
-
lastReportedLow.current = nextValue;
|
|
211
|
-
lowRef.current = nextValue;
|
|
212
|
-
(0, _index.setNativeValue)(lowX, valueToPx(nextValue, trackWidth));
|
|
213
|
-
fireChange(nextValue, highRef.current);
|
|
214
|
-
}
|
|
215
|
-
} else {
|
|
216
|
-
if (isRange && nextValue < lowRef.current) nextValue = lowRef.current;
|
|
217
|
-
if (nextValue !== lastReportedHigh.current) {
|
|
218
|
-
if (sliderTheme?.stepHaptic ?? false) (0, _index2.triggerHaptic)('selection');
|
|
219
|
-
lastReportedHigh.current = nextValue;
|
|
220
|
-
highRef.current = nextValue;
|
|
221
|
-
(0, _index.setNativeValue)(highX, valueToPx(nextValue, trackWidth));
|
|
222
|
-
fireChange(lowRef.current, nextValue);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
},
|
|
226
|
-
onPanResponderRelease: () => {
|
|
227
|
-
animateThumbPress(which === 'low' ? lowScale : highScale, which === 'low' ? lowLabelOpacity : highLabelOpacity, false);
|
|
228
|
-
},
|
|
229
|
-
onPanResponderTerminate: () => {
|
|
230
|
-
animateThumbPress(which === 'low' ? lowScale : highScale, which === 'low' ? lowLabelOpacity : highLabelOpacity, false);
|
|
187
|
+
dragStartX.value = xSV.value;
|
|
188
|
+
if (_pressAnim) scaleSV.value = (0, _reactNativeReanimated.withSpring)(_pressScale, _spring);
|
|
189
|
+
if (_showLabel) {
|
|
190
|
+
labelSV.value = (0, _reactNativeReanimated.withTiming)(_labelOpacity, {
|
|
191
|
+
duration: _labelDur,
|
|
192
|
+
easing: _reactNativeReanimated.Easing.out(_reactNativeReanimated.Easing.cubic)
|
|
193
|
+
});
|
|
231
194
|
}
|
|
232
|
-
|
|
233
|
-
|
|
195
|
+
(0, _reactNativeReanimated.runOnJS)(fireHaptic)();
|
|
196
|
+
}).onUpdate(event => {
|
|
197
|
+
'worklet';
|
|
234
198
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
199
|
+
if (trackW.value <= 0) return;
|
|
200
|
+
const px = Math.min(Math.max(dragStartX.value + event.translationX, 0), trackW.value);
|
|
201
|
+
const ratio = px / trackW.value;
|
|
202
|
+
let v = _min + ratio * (_max - _min);
|
|
203
|
+
if (_step > 0) {
|
|
204
|
+
v = Math.round((v - _min) / _step) * _step + _min;
|
|
205
|
+
v = Math.round(v * _precision) / _precision;
|
|
206
|
+
}
|
|
207
|
+
v = Math.min(Math.max(v, _min), _max);
|
|
208
|
+
if (_range) {
|
|
209
|
+
if (isLow && v > otherSV.value) v = otherSV.value;
|
|
210
|
+
if (!isLow && v < otherSV.value) v = otherSV.value;
|
|
211
|
+
}
|
|
212
|
+
// Thumb sits at the snapped value's position.
|
|
213
|
+
xSV.value = _max === _min ? 0 : (v - _min) / (_max - _min) * trackW.value;
|
|
214
|
+
if (v !== valSV.value) {
|
|
215
|
+
valSV.value = v;
|
|
216
|
+
(0, _reactNativeReanimated.runOnJS)(fireHaptic)();
|
|
217
|
+
(0, _reactNativeReanimated.runOnJS)(fireChange)(lowVal.value, highVal.value);
|
|
218
|
+
}
|
|
219
|
+
}).onEnd(() => {
|
|
220
|
+
'worklet';
|
|
221
|
+
|
|
222
|
+
if (_pressAnim) scaleSV.value = (0, _reactNativeReanimated.withSpring)(1, _spring);
|
|
223
|
+
if (_showLabel) {
|
|
224
|
+
labelSV.value = (0, _reactNativeReanimated.withTiming)(0, {
|
|
225
|
+
duration: _labelDur,
|
|
226
|
+
easing: _reactNativeReanimated.Easing.out(_reactNativeReanimated.Easing.cubic)
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
}, [disabled, min, max, step, precision, isRange, resolvedPressScale, thumbPressAnimationEnabled, showLabel, resolvedLabelOpacity, resolvedLabelDuration, springCfg, fireChange, fireHaptic, lowX, highX, lowVal, highVal, lowScale, highScale, lowLabelOpacity, highLabelOpacity, dragStartX, trackW]);
|
|
231
|
+
const lowPan = (0, _react.useMemo)(() => buildPan('low'), [buildPan]);
|
|
232
|
+
const highPan = (0, _react.useMemo)(() => buildPan('high'), [buildPan]);
|
|
238
233
|
|
|
239
234
|
// Tap on track jumps to position (single mode only).
|
|
240
235
|
const handleTrackPress = (0, _react.useCallback)(e => {
|
|
241
236
|
if (disabled || isRange || trackWidth <= 0) return;
|
|
242
237
|
const px = clamp(e.nativeEvent.locationX, 0, trackWidth);
|
|
243
238
|
const next = pxToValue(px, trackWidth);
|
|
244
|
-
if (next !==
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
_reactNative.Animated.timing(lowX, {
|
|
249
|
-
toValue: valueToPx(next, trackWidth),
|
|
239
|
+
if (next !== lowVal.value) {
|
|
240
|
+
fireHaptic();
|
|
241
|
+
lowVal.value = next;
|
|
242
|
+
lowX.value = (0, _reactNativeReanimated.withTiming)(valueToPx(next, trackWidth), {
|
|
250
243
|
duration: theme.motion.duration.fast,
|
|
251
|
-
easing:
|
|
252
|
-
|
|
253
|
-
}).start();
|
|
244
|
+
easing: _reactNativeReanimated.Easing.out(_reactNativeReanimated.Easing.cubic)
|
|
245
|
+
});
|
|
254
246
|
fireChange(next, next);
|
|
255
247
|
}
|
|
256
|
-
}, [disabled, isRange, trackWidth, pxToValue, valueToPx, fireChange, lowX, theme.motion.duration.fast]);
|
|
248
|
+
}, [disabled, isRange, trackWidth, pxToValue, valueToPx, fireChange, fireHaptic, lowX, lowVal, theme.motion.duration.fast]);
|
|
257
249
|
|
|
258
|
-
// Accessibility actions: increment / decrement
|
|
250
|
+
// Accessibility actions: increment / decrement.
|
|
259
251
|
const handleAccessibilityAction = (0, _react.useCallback)(event => {
|
|
260
252
|
if (disabled) return;
|
|
261
253
|
const delta = event.nativeEvent.actionName === 'increment' ? step : -step;
|
|
262
254
|
if (isRange) {
|
|
263
|
-
const nextLow = clamp(
|
|
264
|
-
if (nextLow !==
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
(
|
|
268
|
-
|
|
269
|
-
fireChange(nextLow, highRef.current);
|
|
255
|
+
const nextLow = clamp(lowVal.value + delta, min, highVal.value);
|
|
256
|
+
if (nextLow !== lowVal.value) {
|
|
257
|
+
lowVal.value = nextLow;
|
|
258
|
+
lowX.value = valueToPx(nextLow, trackWidth);
|
|
259
|
+
fireHaptic();
|
|
260
|
+
fireChange(nextLow, highVal.value);
|
|
270
261
|
}
|
|
271
262
|
} else {
|
|
272
|
-
const next = clamp(
|
|
273
|
-
if (next !==
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
(
|
|
277
|
-
if (sliderTheme?.a11yHaptic ?? false) (0, _index2.triggerHaptic)('selection');
|
|
263
|
+
const next = clamp(lowVal.value + delta, min, max);
|
|
264
|
+
if (next !== lowVal.value) {
|
|
265
|
+
lowVal.value = next;
|
|
266
|
+
lowX.value = valueToPx(next, trackWidth);
|
|
267
|
+
fireHaptic();
|
|
278
268
|
fireChange(next, next);
|
|
279
269
|
}
|
|
280
270
|
}
|
|
281
|
-
}, [disabled, step, isRange, min, max, valueToPx, trackWidth, lowX, fireChange,
|
|
271
|
+
}, [disabled, step, isRange, min, max, valueToPx, trackWidth, lowX, lowVal, highVal, fireChange, fireHaptic]);
|
|
282
272
|
const thumbRadius = sizeCfg.thumbDiameter / 2;
|
|
283
273
|
|
|
284
|
-
//
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
}
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
274
|
+
// ───────── Animated styles ─────────
|
|
275
|
+
const fillAnimStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => isRange ? {
|
|
276
|
+
left: lowX.value,
|
|
277
|
+
width: Math.max(0, highX.value - lowX.value)
|
|
278
|
+
} : {
|
|
279
|
+
left: 0,
|
|
280
|
+
width: lowX.value
|
|
281
|
+
});
|
|
282
|
+
const lowThumbStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => ({
|
|
283
|
+
transform: [{
|
|
284
|
+
translateX: lowX.value - thumbRadius
|
|
285
|
+
}, {
|
|
286
|
+
scale: lowScale.value
|
|
287
|
+
}]
|
|
288
|
+
}));
|
|
289
|
+
const highThumbStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => ({
|
|
290
|
+
transform: [{
|
|
291
|
+
translateX: highX.value - thumbRadius
|
|
292
|
+
}, {
|
|
293
|
+
scale: highScale.value
|
|
294
|
+
}]
|
|
295
|
+
}));
|
|
296
|
+
const lowLabelStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => ({
|
|
297
|
+
opacity: lowLabelOpacity.value
|
|
298
|
+
}));
|
|
299
|
+
const highLabelStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => ({
|
|
300
|
+
opacity: highLabelOpacity.value
|
|
301
|
+
}));
|
|
296
302
|
|
|
297
|
-
// Display values for labels.
|
|
298
|
-
const lowDisplayValue = isRange ?
|
|
299
|
-
const highDisplayValue =
|
|
303
|
+
// Display values (from committed state) for labels + a11y.
|
|
304
|
+
const lowDisplayValue = isRange ? Math.min(...currentValue) : currentValue;
|
|
305
|
+
const highDisplayValue = isRange ? Math.max(...currentValue) : currentValue;
|
|
300
306
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
301
307
|
ref: ref,
|
|
302
308
|
style: [styles.container, containerStyle, style],
|
|
@@ -306,10 +312,15 @@ const Slider = exports.Slider = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
|
|
|
306
312
|
accessibilityState: {
|
|
307
313
|
disabled
|
|
308
314
|
},
|
|
309
|
-
accessibilityValue: {
|
|
315
|
+
accessibilityValue: isRange ? {
|
|
316
|
+
min,
|
|
317
|
+
max,
|
|
318
|
+
now: lowDisplayValue,
|
|
319
|
+
text: `${lowDisplayValue} to ${highDisplayValue}`
|
|
320
|
+
} : {
|
|
310
321
|
min,
|
|
311
322
|
max,
|
|
312
|
-
now:
|
|
323
|
+
now: lowDisplayValue
|
|
313
324
|
},
|
|
314
325
|
accessibilityActions: [{
|
|
315
326
|
name: 'increment'
|
|
@@ -330,69 +341,59 @@ const Slider = exports.Slider = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
|
|
|
330
341
|
style: [styles.track, {
|
|
331
342
|
backgroundColor: disabled ? theme.colors.surface.disabled : theme.colors.border.primary
|
|
332
343
|
}, trackStyle]
|
|
333
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
344
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
|
|
334
345
|
style: [styles.fill, {
|
|
335
|
-
left: fillLeft,
|
|
336
|
-
width: fillWidth,
|
|
337
346
|
backgroundColor: disabled ? theme.colors.surface.disabled : fillColor,
|
|
338
|
-
opacity: disabled ? 0.
|
|
339
|
-
}, fillStyle]
|
|
340
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
},
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
backgroundColor: fillColor
|
|
389
|
-
}],
|
|
390
|
-
pointerEvents: "none",
|
|
391
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
392
|
-
style: [styles.bubbleText, labelStyle],
|
|
393
|
-
children: formatLabel(highDisplayValue)
|
|
394
|
-
})
|
|
395
|
-
}) : null
|
|
347
|
+
opacity: disabled ? 0.55 : 1
|
|
348
|
+
}, fillStyle, fillAnimStyle]
|
|
349
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeGestureHandler.GestureDetector, {
|
|
350
|
+
gesture: lowPan,
|
|
351
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
|
|
352
|
+
style: [styles.thumb, {
|
|
353
|
+
width: sizeCfg.thumbDiameter,
|
|
354
|
+
height: sizeCfg.thumbDiameter,
|
|
355
|
+
borderRadius: thumbRadius,
|
|
356
|
+
backgroundColor: theme.colors.background.elevated,
|
|
357
|
+
borderColor: disabled ? theme.colors.surface.disabled : fillColor,
|
|
358
|
+
opacity: disabled ? 0.55 : 1
|
|
359
|
+
}, thumbStyle, lowThumbStyle],
|
|
360
|
+
accessibilityElementsHidden: true,
|
|
361
|
+
importantForAccessibility: "no-hide-descendants",
|
|
362
|
+
children: showLabel ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
|
|
363
|
+
style: [styles.bubble, {
|
|
364
|
+
backgroundColor: fillColor
|
|
365
|
+
}, lowLabelStyle],
|
|
366
|
+
pointerEvents: "none",
|
|
367
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
368
|
+
style: [styles.bubbleText, labelStyle],
|
|
369
|
+
children: formatLabel(lowDisplayValue)
|
|
370
|
+
})
|
|
371
|
+
}) : null
|
|
372
|
+
})
|
|
373
|
+
}), isRange ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeGestureHandler.GestureDetector, {
|
|
374
|
+
gesture: highPan,
|
|
375
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
|
|
376
|
+
style: [styles.thumb, {
|
|
377
|
+
width: sizeCfg.thumbDiameter,
|
|
378
|
+
height: sizeCfg.thumbDiameter,
|
|
379
|
+
borderRadius: thumbRadius,
|
|
380
|
+
backgroundColor: theme.colors.background.elevated,
|
|
381
|
+
borderColor: disabled ? theme.colors.surface.disabled : fillColor,
|
|
382
|
+
opacity: disabled ? 0.55 : 1
|
|
383
|
+
}, thumbStyle, highThumbStyle],
|
|
384
|
+
accessibilityElementsHidden: true,
|
|
385
|
+
importantForAccessibility: "no-hide-descendants",
|
|
386
|
+
children: showLabel ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
|
|
387
|
+
style: [styles.bubble, {
|
|
388
|
+
backgroundColor: fillColor
|
|
389
|
+
}, highLabelStyle],
|
|
390
|
+
pointerEvents: "none",
|
|
391
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
392
|
+
style: [styles.bubbleText, labelStyle],
|
|
393
|
+
children: formatLabel(highDisplayValue)
|
|
394
|
+
})
|
|
395
|
+
}) : null
|
|
396
|
+
})
|
|
396
397
|
}) : null]
|
|
397
398
|
})
|
|
398
399
|
})
|
|
@@ -453,7 +454,6 @@ const buildStyles = (theme, sizeCfg) => {
|
|
|
453
454
|
minWidth: 36,
|
|
454
455
|
alignItems: 'center',
|
|
455
456
|
justifyContent: 'center',
|
|
456
|
-
// A subtle shadow for elevation.
|
|
457
457
|
..._reactNative.Platform.select({
|
|
458
458
|
ios: {
|
|
459
459
|
shadowColor: theme.shadows.sm.shadowColor,
|
|
@@ -39,7 +39,7 @@ const StepCircle = ({
|
|
|
39
39
|
pulseSize,
|
|
40
40
|
pulseEnabled,
|
|
41
41
|
pulseDuration,
|
|
42
|
-
|
|
42
|
+
pressHaptic,
|
|
43
43
|
circleSlotStyle
|
|
44
44
|
}) => {
|
|
45
45
|
const isActive = status === 'active';
|
|
@@ -86,7 +86,7 @@ const StepCircle = ({
|
|
|
86
86
|
const canPress = interactive && status === 'complete';
|
|
87
87
|
const handlePress = () => {
|
|
88
88
|
if (!canPress) return;
|
|
89
|
-
if (
|
|
89
|
+
if (pressHaptic) (0, _hapticUtils.triggerHaptic)(pressHaptic);
|
|
90
90
|
onPress?.(index);
|
|
91
91
|
};
|
|
92
92
|
const inner = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
@@ -181,6 +181,7 @@ const Stepper = exports.Stepper = /*#__PURE__*/(0, _react.forwardRef)((props, re
|
|
|
181
181
|
circleStyle,
|
|
182
182
|
labelStyle,
|
|
183
183
|
connectorStyle,
|
|
184
|
+
haptic,
|
|
184
185
|
testID
|
|
185
186
|
} = props;
|
|
186
187
|
const theme = (0, _index.useTheme)();
|
|
@@ -189,7 +190,7 @@ const Stepper = exports.Stepper = /*#__PURE__*/(0, _react.forwardRef)((props, re
|
|
|
189
190
|
const pulseSize = stepperTheme?.pulseSize ?? PULSE_SIZE;
|
|
190
191
|
const pulseEnabled = stepperTheme?.pulseAnimation ?? false;
|
|
191
192
|
const pulseDuration = stepperTheme?.pulseDuration ?? PULSE_DURATION;
|
|
192
|
-
const
|
|
193
|
+
const pressHaptic = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
|
|
193
194
|
const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
|
|
194
195
|
const toneColor = toneColorFor(theme, tone);
|
|
195
196
|
const upcomingColor = theme.colors.border.primary;
|
|
@@ -270,7 +271,7 @@ const Stepper = exports.Stepper = /*#__PURE__*/(0, _react.forwardRef)((props, re
|
|
|
270
271
|
pulseSize: pulseSize,
|
|
271
272
|
pulseEnabled: pulseEnabled,
|
|
272
273
|
pulseDuration: pulseDuration,
|
|
273
|
-
|
|
274
|
+
pressHaptic: pressHaptic,
|
|
274
275
|
circleSlotStyle: circleStyle
|
|
275
276
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
276
277
|
style: [styles.hLabel, {
|
|
@@ -309,7 +310,7 @@ const Stepper = exports.Stepper = /*#__PURE__*/(0, _react.forwardRef)((props, re
|
|
|
309
310
|
pulseSize: pulseSize,
|
|
310
311
|
pulseEnabled: pulseEnabled,
|
|
311
312
|
pulseDuration: pulseDuration,
|
|
312
|
-
|
|
313
|
+
pressHaptic: pressHaptic,
|
|
313
314
|
circleSlotStyle: circleStyle
|
|
314
315
|
}), !isLast ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
315
316
|
style: [styles.vConnectorContainer, connectorStyle],
|