@webority-technologies/mobile 0.0.12 → 0.0.13
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/Badge/Badge.js +1 -1
- package/lib/commonjs/components/BottomNavigation/BottomNavigation.js +11 -3
- package/lib/commonjs/components/DatePicker/DatePicker.js +18 -12
- package/lib/commonjs/components/DateRangePicker/DateRangePicker.js +14 -9
- package/lib/commonjs/components/FloatingActionButton/FloatingActionButton.js +1 -1
- package/lib/commonjs/components/Input/Input.js +1 -1
- package/lib/commonjs/components/Modal/Modal.js +4 -4
- package/lib/commonjs/components/OTPInput/OTPInput.js +29 -9
- package/lib/commonjs/components/ProgressBar/ProgressBar.js +1 -1
- package/lib/commonjs/components/SegmentedControl/SegmentedControl.js +23 -28
- package/lib/commonjs/components/Skeleton/Skeleton.js +1 -1
- package/lib/commonjs/components/Slider/Slider.js +11 -11
- package/lib/commonjs/components/Stepper/Stepper.js +10 -4
- package/lib/commonjs/components/Tabs/Tabs.js +7 -5
- package/lib/commonjs/components/TimePicker/TimePicker.js +3 -3
- package/lib/commonjs/components/Toast/Toast.js +2 -2
- package/lib/commonjs/theme/animatedValue.js +20 -1
- package/lib/commonjs/theme/index.js +8 -1
- package/lib/module/components/Badge/Badge.js +2 -2
- package/lib/module/components/BottomNavigation/BottomNavigation.js +11 -3
- package/lib/module/components/DatePicker/DatePicker.js +19 -13
- package/lib/module/components/DateRangePicker/DateRangePicker.js +15 -10
- package/lib/module/components/FloatingActionButton/FloatingActionButton.js +2 -2
- package/lib/module/components/Input/Input.js +2 -2
- package/lib/module/components/Modal/Modal.js +5 -5
- package/lib/module/components/OTPInput/OTPInput.js +30 -10
- package/lib/module/components/ProgressBar/ProgressBar.js +2 -2
- package/lib/module/components/SegmentedControl/SegmentedControl.js +24 -29
- package/lib/module/components/Skeleton/Skeleton.js +2 -2
- package/lib/module/components/Slider/Slider.js +12 -12
- package/lib/module/components/Stepper/Stepper.js +10 -4
- package/lib/module/components/Tabs/Tabs.js +7 -5
- package/lib/module/components/TimePicker/TimePicker.js +4 -4
- package/lib/module/components/Toast/Toast.js +3 -3
- package/lib/module/theme/animatedValue.js +18 -0
- package/lib/module/theme/index.js +1 -1
- package/lib/typescript/commonjs/components/BottomNavigation/BottomNavigation.d.ts +7 -0
- package/lib/typescript/commonjs/theme/animatedValue.d.ts +11 -0
- package/lib/typescript/commonjs/theme/index.d.ts +1 -1
- package/lib/typescript/module/components/BottomNavigation/BottomNavigation.d.ts +7 -0
- package/lib/typescript/module/theme/animatedValue.d.ts +11 -0
- package/lib/typescript/module/theme/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -131,7 +131,7 @@ const Badge = exports.Badge = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
|
|
|
131
131
|
const pulseScale = (0, _react.useRef)((0, _index.createAnimatedValue)(1)).current;
|
|
132
132
|
(0, _react.useEffect)(() => {
|
|
133
133
|
if (!pulse || !shouldRender) {
|
|
134
|
-
|
|
134
|
+
(0, _index.setNativeValue)(pulseScale, 1);
|
|
135
135
|
return;
|
|
136
136
|
}
|
|
137
137
|
const loop = _reactNative.Animated.loop(_reactNative.Animated.sequence([_reactNative.Animated.timing(pulseScale, {
|
|
@@ -53,6 +53,7 @@ const BottomNavigation = exports.BottomNavigation = /*#__PURE__*/(0, _react.forw
|
|
|
53
53
|
haptic = 'selection',
|
|
54
54
|
showLabels = true,
|
|
55
55
|
variant = 'pill',
|
|
56
|
+
indicatorPosition = 'bottom',
|
|
56
57
|
style,
|
|
57
58
|
indicatorStyle,
|
|
58
59
|
labelStyle,
|
|
@@ -198,7 +199,7 @@ const BottomNavigation = exports.BottomNavigation = /*#__PURE__*/(0, _react.forw
|
|
|
198
199
|
}, tab.key);
|
|
199
200
|
}), variant === 'underline' && tabWidth > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
200
201
|
pointerEvents: "none",
|
|
201
|
-
style: [styles.underline, {
|
|
202
|
+
style: [styles.underline, indicatorPosition === 'top' ? styles.underlineTop : styles.underlineBottom, {
|
|
202
203
|
width: tabWidth,
|
|
203
204
|
backgroundColor: theme.colors.primary,
|
|
204
205
|
transform: [{
|
|
@@ -248,12 +249,19 @@ const buildStyles = theme => _reactNative.StyleSheet.create({
|
|
|
248
249
|
},
|
|
249
250
|
underline: {
|
|
250
251
|
position: 'absolute',
|
|
251
|
-
bottom: -6,
|
|
252
252
|
left: 0,
|
|
253
|
-
height: UNDERLINE_HEIGHT
|
|
253
|
+
height: UNDERLINE_HEIGHT
|
|
254
|
+
},
|
|
255
|
+
underlineBottom: {
|
|
256
|
+
bottom: -6,
|
|
254
257
|
borderTopLeftRadius: 2,
|
|
255
258
|
borderTopRightRadius: 2
|
|
256
259
|
},
|
|
260
|
+
underlineTop: {
|
|
261
|
+
top: -6,
|
|
262
|
+
borderBottomLeftRadius: 2,
|
|
263
|
+
borderBottomRightRadius: 2
|
|
264
|
+
},
|
|
257
265
|
badgePill: {
|
|
258
266
|
position: 'absolute',
|
|
259
267
|
top: -4,
|
|
@@ -135,8 +135,8 @@ const DatePicker = props => {
|
|
|
135
135
|
(0, _react.useEffect)(() => {
|
|
136
136
|
if (mode !== 'modal') return;
|
|
137
137
|
if (visible) {
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
(0, _index.setNativeValue)(backdrop, 0);
|
|
139
|
+
(0, _index.setNativeValue)(sheet, 0);
|
|
140
140
|
_reactNative.Animated.parallel([_reactNative.Animated.timing(backdrop, {
|
|
141
141
|
toValue: 1,
|
|
142
142
|
duration: theme.motion.duration.normal,
|
|
@@ -248,8 +248,8 @@ const DatePicker = props => {
|
|
|
248
248
|
|
|
249
249
|
// View-mode transition: fade + scale (200ms, native driver).
|
|
250
250
|
const animateViewTransition = (0, _react.useCallback)(() => {
|
|
251
|
-
|
|
252
|
-
|
|
251
|
+
(0, _index.setNativeValue)(viewFade, 0);
|
|
252
|
+
(0, _index.setNativeValue)(viewScale, 0.9);
|
|
253
253
|
_reactNative.Animated.parallel([_reactNative.Animated.timing(viewFade, {
|
|
254
254
|
toValue: 1,
|
|
255
255
|
duration: 200,
|
|
@@ -300,7 +300,7 @@ const DatePicker = props => {
|
|
|
300
300
|
if (!cell.inMonth) {
|
|
301
301
|
setAnchor(new Date(cell.date.getFullYear(), cell.date.getMonth(), 1));
|
|
302
302
|
}
|
|
303
|
-
|
|
303
|
+
(0, _index.setNativeValue)(selectScale, 0.7);
|
|
304
304
|
_reactNative.Animated.spring(selectScale, {
|
|
305
305
|
toValue: 1,
|
|
306
306
|
damping: theme.motion.spring.bouncy.damping,
|
|
@@ -382,11 +382,16 @@ const DatePicker = props => {
|
|
|
382
382
|
opacity: viewMode === 'days' ? monthFade : 1
|
|
383
383
|
}],
|
|
384
384
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.Text, {
|
|
385
|
-
style: [styles.headerLabel,
|
|
385
|
+
style: [styles.headerLabel,
|
|
386
|
+
// Always include the transform — passing null/undefined as a
|
|
387
|
+
// transform value confuses Animated's processTransform on Fabric.
|
|
388
|
+
// When the month slide isn't active we still drive translateX
|
|
389
|
+
// through the same value, just with target 0.
|
|
390
|
+
{
|
|
386
391
|
transform: [{
|
|
387
|
-
translateX: monthSlide
|
|
392
|
+
translateX: viewMode === 'days' ? monthSlide : 0
|
|
388
393
|
}]
|
|
389
|
-
}
|
|
394
|
+
}],
|
|
390
395
|
accessibilityLiveRegion: "polite",
|
|
391
396
|
children: headerLabel
|
|
392
397
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
@@ -452,11 +457,12 @@ const DatePicker = props => {
|
|
|
452
457
|
backgroundColor: cellBg,
|
|
453
458
|
borderColor,
|
|
454
459
|
borderWidth: todayCell && !selected ? 1.5 : 0,
|
|
455
|
-
opacity
|
|
456
|
-
|
|
460
|
+
opacity
|
|
461
|
+
}, selected ? {
|
|
462
|
+
transform: [{
|
|
457
463
|
scale: selectScale
|
|
458
|
-
}]
|
|
459
|
-
}],
|
|
464
|
+
}]
|
|
465
|
+
} : null],
|
|
460
466
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
461
467
|
style: [styles.dayText, {
|
|
462
468
|
color: textColor
|
|
@@ -120,8 +120,8 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/(0, _react.forwar
|
|
|
120
120
|
// Modal open / close animation.
|
|
121
121
|
(0, _react.useEffect)(() => {
|
|
122
122
|
if (visible) {
|
|
123
|
-
|
|
124
|
-
|
|
123
|
+
(0, _index.setNativeValue)(backdrop, 0);
|
|
124
|
+
(0, _index.setNativeValue)(sheet, 0);
|
|
125
125
|
_reactNative.Animated.parallel([_reactNative.Animated.timing(backdrop, {
|
|
126
126
|
toValue: 1,
|
|
127
127
|
duration: theme.motion.duration.normal,
|
|
@@ -561,26 +561,31 @@ const buildStyles = theme => {
|
|
|
561
561
|
aspectRatio: 1,
|
|
562
562
|
alignItems: 'center',
|
|
563
563
|
justifyContent: 'center',
|
|
564
|
-
padding
|
|
564
|
+
// No horizontal padding so the connector bars on adjacent cells meet
|
|
565
|
+
// without a gap. Vertical breathing room comes from dayInner's height.
|
|
566
|
+
padding: 0,
|
|
565
567
|
position: 'relative'
|
|
566
568
|
},
|
|
569
|
+
// Bars sit BEHIND dayInner and bridge the start/end circles to mid-range
|
|
570
|
+
// cells. Their height mirrors dayInner (~90% of cell height) so the visual
|
|
571
|
+
// pill is one continuous shape across multiple cells.
|
|
567
572
|
barLeft: {
|
|
568
573
|
position: 'absolute',
|
|
569
574
|
left: 0,
|
|
570
575
|
right: '50%',
|
|
571
|
-
top: '
|
|
572
|
-
bottom: '
|
|
576
|
+
top: '5%',
|
|
577
|
+
bottom: '5%'
|
|
573
578
|
},
|
|
574
579
|
barRight: {
|
|
575
580
|
position: 'absolute',
|
|
576
581
|
left: '50%',
|
|
577
582
|
right: 0,
|
|
578
|
-
top: '
|
|
579
|
-
bottom: '
|
|
583
|
+
top: '5%',
|
|
584
|
+
bottom: '5%'
|
|
580
585
|
},
|
|
581
586
|
dayInner: {
|
|
582
|
-
width: '
|
|
583
|
-
height: '
|
|
587
|
+
width: '90%',
|
|
588
|
+
height: '90%',
|
|
584
589
|
alignItems: 'center',
|
|
585
590
|
justifyContent: 'center'
|
|
586
591
|
},
|
|
@@ -86,7 +86,7 @@ const FloatingActionButton = exports.FloatingActionButton = /*#__PURE__*/(0, _re
|
|
|
86
86
|
const hideAnim = (0, _react.useRef)((0, _index.createAnimatedValue)(0)).current;
|
|
87
87
|
(0, _react.useEffect)(() => {
|
|
88
88
|
if (!hideOnScroll) {
|
|
89
|
-
|
|
89
|
+
(0, _index.setNativeValue)(hideAnim, 0);
|
|
90
90
|
return;
|
|
91
91
|
}
|
|
92
92
|
_reactNative.Animated.timing(hideAnim, {
|
|
@@ -147,7 +147,7 @@ const Input = exports.Input = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
|
|
|
147
147
|
const prevErrorRef = (0, _react.useRef)(hasError);
|
|
148
148
|
(0, _react.useEffect)(() => {
|
|
149
149
|
if (hasError && !prevErrorRef.current) {
|
|
150
|
-
|
|
150
|
+
(0, _index.setNativeValue)(shakeAnim, 0);
|
|
151
151
|
_reactNative.Animated.sequence([_reactNative.Animated.timing(shakeAnim, {
|
|
152
152
|
toValue: 1,
|
|
153
153
|
duration: 50,
|
|
@@ -65,10 +65,10 @@ const Modal = exports.Modal = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
|
|
|
65
65
|
})]).start();
|
|
66
66
|
}
|
|
67
67
|
} else {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
(0, _index.setNativeValue)(backdropAnim, 0);
|
|
69
|
+
(0, _index.setNativeValue)(scaleAnim, 0.9);
|
|
70
|
+
(0, _index.setNativeValue)(opacityAnim, 0);
|
|
71
|
+
(0, _index.setNativeValue)(translateYAnim, screenHeight);
|
|
72
72
|
}
|
|
73
73
|
}, [visible, presentation, duration, backdropAnim, scaleAnim, opacityAnim, translateYAnim, screenHeight, theme.motion.spring.gentle.damping, theme.motion.spring.gentle.stiffness, theme.motion.spring.gentle.mass]);
|
|
74
74
|
|
|
@@ -89,7 +89,7 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
|
|
|
89
89
|
const isFirstRun = previousErrorRef.current === null;
|
|
90
90
|
if (!isFirstRun && hasError && !previousErrorRef.current) {
|
|
91
91
|
(0, _index2.triggerHaptic)('notificationError');
|
|
92
|
-
|
|
92
|
+
(0, _index.setNativeValue)(shake, 0);
|
|
93
93
|
_reactNative.Animated.sequence([_reactNative.Animated.timing(shake, {
|
|
94
94
|
toValue: 1,
|
|
95
95
|
duration: 75,
|
|
@@ -175,16 +175,27 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
|
|
|
175
175
|
}
|
|
176
176
|
}, [length, onChange, onComplete, value]);
|
|
177
177
|
const handleChangeText = (0, _react.useCallback)((index, raw) => {
|
|
178
|
-
|
|
178
|
+
// Strip the ZWSP placeholder (used so iOS fires onKeyPress/Backspace on otherwise-empty cells).
|
|
179
|
+
const stripped = raw.replace(/\u200B/g, '');
|
|
180
|
+
const sanitized = sanitizeChar(stripped, keyboardType);
|
|
179
181
|
if (!sanitized) {
|
|
180
|
-
//
|
|
182
|
+
// Cell was cleared (delete / cut). Clear this cell and step focus back.
|
|
181
183
|
const chars = cells.slice();
|
|
184
|
+
const wasFilled = (chars[index] ?? '').length > 0;
|
|
182
185
|
chars[index] = '';
|
|
183
186
|
updateValue(chars.join('').slice(0, length));
|
|
187
|
+
if (!wasFilled && index > 0) {
|
|
188
|
+
// Empty cell + backspace → also clear and focus the previous cell.
|
|
189
|
+
const prev = cells.slice();
|
|
190
|
+
prev[index - 1] = '';
|
|
191
|
+
updateValue(prev.join(''));
|
|
192
|
+
focusCell(index - 1);
|
|
193
|
+
}
|
|
184
194
|
return;
|
|
185
195
|
}
|
|
186
196
|
|
|
187
197
|
// Fill cells from current index onward (handles paste of multi-char text).
|
|
198
|
+
// For single-character typing, this overwrites the current cell and advances.
|
|
188
199
|
const chars = cells.slice();
|
|
189
200
|
let writeIndex = index;
|
|
190
201
|
for (let i = 0; i < sanitized.length && writeIndex < length; i += 1) {
|
|
@@ -201,7 +212,6 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
|
|
|
201
212
|
// Move focus to the next empty cell or last cell.
|
|
202
213
|
const nextFocus = Math.min(writeIndex, length - 1);
|
|
203
214
|
if (writeIndex >= length) {
|
|
204
|
-
// All filled — blur last cell.
|
|
205
215
|
inputsRef.current[length - 1]?.blur();
|
|
206
216
|
} else {
|
|
207
217
|
focusCell(nextFocus);
|
|
@@ -210,9 +220,12 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
|
|
|
210
220
|
const handleKeyPress = (0, _react.useCallback)((index, e) => {
|
|
211
221
|
const key = e.nativeEvent.key;
|
|
212
222
|
if (key !== 'Backspace') return;
|
|
223
|
+
// Backspace on a non-empty cell — clear it. Backspace on an empty cell —
|
|
224
|
+
// step back and clear the previous cell. handleChangeText also covers the
|
|
225
|
+
// empty-cell case via the ZWSP placeholder, so this branch only matters
|
|
226
|
+
// when the platform fires onKeyPress without firing onChangeText.
|
|
213
227
|
const current = cells[index] ?? '';
|
|
214
228
|
if (current.length === 0) {
|
|
215
|
-
// Move back, clear previous cell.
|
|
216
229
|
if (index > 0) {
|
|
217
230
|
const chars = cells.slice();
|
|
218
231
|
chars[index - 1] = '';
|
|
@@ -288,8 +301,11 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
|
|
|
288
301
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
|
|
289
302
|
ref: node => {
|
|
290
303
|
inputsRef.current[index] = node;
|
|
291
|
-
}
|
|
292
|
-
|
|
304
|
+
}
|
|
305
|
+
// Always render at least the ZWSP placeholder so iOS keeps
|
|
306
|
+
// firing onChangeText/onKeyPress for Backspace on empty cells.
|
|
307
|
+
,
|
|
308
|
+
value: (secure && isFilled ? '' : char) || '\u200B',
|
|
293
309
|
onChangeText: t => handleChangeText(index, t),
|
|
294
310
|
onKeyPress: e => handleKeyPress(index, e),
|
|
295
311
|
onFocus: () => handleFocus(index),
|
|
@@ -297,8 +313,12 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
|
|
|
297
313
|
keyboardType: keyboardType,
|
|
298
314
|
editable: !disabled,
|
|
299
315
|
selectTextOnFocus: true,
|
|
300
|
-
caretHidden: isFilled
|
|
301
|
-
|
|
316
|
+
caretHidden: isFilled
|
|
317
|
+
// Only the first cell accepts paste-like multi-char input
|
|
318
|
+
// (e.g., when SMS autofill or clipboard delivers the full code);
|
|
319
|
+
// every other cell is single-char so typing always overwrites.
|
|
320
|
+
,
|
|
321
|
+
maxLength: index === 0 ? length : 2,
|
|
302
322
|
textContentType: index === 0 ? 'oneTimeCode' : 'none',
|
|
303
323
|
autoComplete: index === 0 ? 'sms-otp' : 'off',
|
|
304
324
|
importantForAutofill: index === 0 ? 'yes' : 'no',
|
|
@@ -67,7 +67,7 @@ const ProgressBar = exports.ProgressBar = /*#__PURE__*/(0, _react.forwardRef)((p
|
|
|
67
67
|
}, [animated, clamped, fillAnim, isIndeterminate, theme]);
|
|
68
68
|
(0, _react.useEffect)(() => {
|
|
69
69
|
if (!isIndeterminate) return;
|
|
70
|
-
|
|
70
|
+
(0, _index.setNativeValue)(loopAnim, 0);
|
|
71
71
|
const animation = _reactNative.Animated.loop(_reactNative.Animated.timing(loopAnim, {
|
|
72
72
|
toValue: 1,
|
|
73
73
|
duration: 1500,
|
|
@@ -50,44 +50,39 @@ const SegmentedControl = exports.SegmentedControl = /*#__PURE__*/(0, _react.forw
|
|
|
50
50
|
const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
|
|
51
51
|
const sizeStyles = sizeMap[size];
|
|
52
52
|
|
|
53
|
-
//
|
|
54
|
-
|
|
53
|
+
// Track width is measured from onLayout. Thumb width is a regular number (not
|
|
54
|
+
// animated) — `width` cannot be driven by the native animated module, and mixing
|
|
55
|
+
// a JS-driven width with a native-driven translateX inside `Animated.parallel`
|
|
56
|
+
// sends the parallel composite into the native driver and JS setValue/timing
|
|
57
|
+
// calls on the same value then throw "moved to native". Keep width as state and
|
|
58
|
+
// only animate translateX via the native driver.
|
|
59
|
+
const [trackWidth, setTrackWidth] = (0, _react.useState)(0);
|
|
55
60
|
const thumbTranslateX = (0, _react.useRef)((0, _index.createAnimatedValue)(0)).current;
|
|
56
|
-
const thumbWidth = (0, _react.useRef)((0, _index.createAnimatedValue)(0)).current;
|
|
57
61
|
const activeIndex = Math.max(0, segments.findIndex(s => s.value === value));
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
const segmentWidth = trackWidth > 0 ? (trackWidth - TRACK_PADDING * 2) / Math.max(segments.length, 1) : 0;
|
|
63
|
+
const animateThumb = (0, _react.useCallback)((index, segWidth) => {
|
|
64
|
+
if (segWidth <= 0) return;
|
|
61
65
|
const targetX = TRACK_PADDING + segWidth * index;
|
|
62
66
|
const spring = theme.motion.spring.snappy;
|
|
63
|
-
_reactNative.Animated.
|
|
67
|
+
_reactNative.Animated.spring(thumbTranslateX, {
|
|
64
68
|
toValue: targetX,
|
|
65
69
|
damping: spring.damping,
|
|
66
70
|
stiffness: spring.stiffness,
|
|
67
71
|
mass: spring.mass,
|
|
68
72
|
useNativeDriver: true
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
damping: spring.damping,
|
|
72
|
-
stiffness: spring.stiffness,
|
|
73
|
-
mass: spring.mass,
|
|
74
|
-
useNativeDriver: false
|
|
75
|
-
})]).start();
|
|
76
|
-
}, [segments.length, theme.motion.spring.snappy, thumbTranslateX, thumbWidth]);
|
|
73
|
+
}).start();
|
|
74
|
+
}, [theme.motion.spring.snappy, thumbTranslateX]);
|
|
77
75
|
(0, _react.useEffect)(() => {
|
|
78
|
-
if (
|
|
79
|
-
animateThumb(activeIndex,
|
|
76
|
+
if (segmentWidth > 0) {
|
|
77
|
+
animateThumb(activeIndex, segmentWidth);
|
|
80
78
|
}
|
|
81
|
-
}, [activeIndex, animateThumb]);
|
|
79
|
+
}, [activeIndex, segmentWidth, animateThumb]);
|
|
82
80
|
const handleTrackLayout = (0, _react.useCallback)(e => {
|
|
83
81
|
const width = e.nativeEvent.layout.width;
|
|
84
|
-
if (width
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
thumbWidth.setValue(segWidth);
|
|
89
|
-
thumbTranslateX.setValue(TRACK_PADDING + segWidth * activeIndex);
|
|
90
|
-
}, [activeIndex, segments.length, thumbTranslateX, thumbWidth]);
|
|
82
|
+
if (width !== trackWidth) {
|
|
83
|
+
setTrackWidth(width);
|
|
84
|
+
}
|
|
85
|
+
}, [trackWidth]);
|
|
91
86
|
const handlePress = (0, _react.useCallback)(segment => {
|
|
92
87
|
if (disabled) return;
|
|
93
88
|
if (segment.value === value) return;
|
|
@@ -110,10 +105,10 @@ const SegmentedControl = exports.SegmentedControl = /*#__PURE__*/(0, _react.forw
|
|
|
110
105
|
alignSelf: fullWidth ? 'stretch' : 'flex-start'
|
|
111
106
|
}, style],
|
|
112
107
|
onLayout: handleTrackLayout,
|
|
113
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
108
|
+
children: [segmentWidth > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
114
109
|
pointerEvents: "none",
|
|
115
110
|
style: [styles.thumb, {
|
|
116
|
-
width:
|
|
111
|
+
width: segmentWidth,
|
|
117
112
|
height: sizeStyles.height - TRACK_PADDING * 2,
|
|
118
113
|
borderRadius: theme.radius.sm,
|
|
119
114
|
backgroundColor: thumbBg,
|
|
@@ -122,7 +117,7 @@ const SegmentedControl = exports.SegmentedControl = /*#__PURE__*/(0, _react.forw
|
|
|
122
117
|
}],
|
|
123
118
|
...theme.shadows.sm
|
|
124
119
|
}]
|
|
125
|
-
}), segments.map(segment => {
|
|
120
|
+
}) : null, segments.map(segment => {
|
|
126
121
|
const isActive = segment.value === value;
|
|
127
122
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
|
|
128
123
|
onPress: () => handlePress(segment),
|
|
@@ -55,7 +55,7 @@ const Skeleton = ({
|
|
|
55
55
|
const progress = (0, _react.useRef)((0, _index.createAnimatedValue)(0)).current;
|
|
56
56
|
const [containerWidth, setContainerWidth] = (0, _react.useState)(0);
|
|
57
57
|
(0, _react.useEffect)(() => {
|
|
58
|
-
|
|
58
|
+
(0, _index.setNativeValue)(progress, 0);
|
|
59
59
|
const duration = resolvedVariant === 'pulse' ? PULSE_DURATION : SPEED_DURATION[resolvedSpeed];
|
|
60
60
|
const animation = resolvedVariant === 'pulse' ? _reactNative.Animated.loop(_reactNative.Animated.sequence([_reactNative.Animated.timing(progress, {
|
|
61
61
|
toValue: 1,
|
|
@@ -110,14 +110,14 @@ const Slider = exports.Slider = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
|
|
|
110
110
|
highRef.current = hi;
|
|
111
111
|
lastReportedLow.current = lo;
|
|
112
112
|
lastReportedHigh.current = hi;
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
(0, _index.setNativeValue)(lowX, valueToPx(lo, trackWidth));
|
|
114
|
+
(0, _index.setNativeValue)(highX, valueToPx(hi, trackWidth));
|
|
115
115
|
} else {
|
|
116
116
|
const v = props.value;
|
|
117
117
|
lowRef.current = v;
|
|
118
118
|
highRef.current = v;
|
|
119
119
|
lastReportedLow.current = v;
|
|
120
|
-
|
|
120
|
+
(0, _index.setNativeValue)(lowX, valueToPx(v, trackWidth));
|
|
121
121
|
}
|
|
122
122
|
// We intentionally listen to props.value across both shapes via JSON; ESLint is fine.
|
|
123
123
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -130,10 +130,10 @@ const Slider = exports.Slider = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
|
|
|
130
130
|
const [v0, v1] = props.value;
|
|
131
131
|
const lo = Math.min(v0, v1);
|
|
132
132
|
const hi = Math.max(v0, v1);
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
(0, _index.setNativeValue)(lowX, valueToPx(lo, w));
|
|
134
|
+
(0, _index.setNativeValue)(highX, valueToPx(hi, w));
|
|
135
135
|
} else {
|
|
136
|
-
|
|
136
|
+
(0, _index.setNativeValue)(lowX, valueToPx(props.value, w));
|
|
137
137
|
}
|
|
138
138
|
},
|
|
139
139
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -184,7 +184,7 @@ const Slider = exports.Slider = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
|
|
|
184
184
|
lastReportedLow.current = nextValue;
|
|
185
185
|
}
|
|
186
186
|
lowRef.current = nextValue;
|
|
187
|
-
|
|
187
|
+
(0, _index.setNativeValue)(lowX, valueToPx(nextValue, trackWidth));
|
|
188
188
|
fireChange(nextValue, highRef.current);
|
|
189
189
|
} else {
|
|
190
190
|
if (isRange && nextValue < lowRef.current) nextValue = lowRef.current;
|
|
@@ -193,7 +193,7 @@ const Slider = exports.Slider = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
|
|
|
193
193
|
lastReportedHigh.current = nextValue;
|
|
194
194
|
}
|
|
195
195
|
highRef.current = nextValue;
|
|
196
|
-
|
|
196
|
+
(0, _index.setNativeValue)(highX, valueToPx(nextValue, trackWidth));
|
|
197
197
|
fireChange(lowRef.current, nextValue);
|
|
198
198
|
}
|
|
199
199
|
},
|
|
@@ -223,7 +223,7 @@ const Slider = exports.Slider = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
|
|
|
223
223
|
toValue: valueToPx(next, trackWidth),
|
|
224
224
|
duration: theme.motion.duration.fast,
|
|
225
225
|
easing: _reactNative.Easing.out(_reactNative.Easing.cubic),
|
|
226
|
-
useNativeDriver:
|
|
226
|
+
useNativeDriver: true
|
|
227
227
|
}).start();
|
|
228
228
|
fireChange(next, next);
|
|
229
229
|
}
|
|
@@ -238,7 +238,7 @@ const Slider = exports.Slider = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
|
|
|
238
238
|
if (nextLow !== lowRef.current) {
|
|
239
239
|
lowRef.current = nextLow;
|
|
240
240
|
lastReportedLow.current = nextLow;
|
|
241
|
-
|
|
241
|
+
(0, _index.setNativeValue)(lowX, valueToPx(nextLow, trackWidth));
|
|
242
242
|
(0, _index2.triggerHaptic)('selection');
|
|
243
243
|
fireChange(nextLow, highRef.current);
|
|
244
244
|
}
|
|
@@ -247,7 +247,7 @@ const Slider = exports.Slider = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
|
|
|
247
247
|
if (next !== lowRef.current) {
|
|
248
248
|
lowRef.current = next;
|
|
249
249
|
lastReportedLow.current = next;
|
|
250
|
-
|
|
250
|
+
(0, _index.setNativeValue)(lowX, valueToPx(next, trackWidth));
|
|
251
251
|
(0, _index2.triggerHaptic)('selection');
|
|
252
252
|
fireChange(next, next);
|
|
253
253
|
}
|
|
@@ -28,6 +28,7 @@ const StepCircle = ({
|
|
|
28
28
|
status,
|
|
29
29
|
toneColor,
|
|
30
30
|
upcomingColor,
|
|
31
|
+
upcomingFillColor,
|
|
31
32
|
textOnColor,
|
|
32
33
|
upcomingTextColor,
|
|
33
34
|
interactive,
|
|
@@ -70,7 +71,7 @@ const StepCircle = ({
|
|
|
70
71
|
loop.start();
|
|
71
72
|
return () => loop.stop();
|
|
72
73
|
}, [isActive, pulseScale, pulseOpacity]);
|
|
73
|
-
const bgColor = status === 'upcoming' ?
|
|
74
|
+
const bgColor = status === 'upcoming' ? upcomingFillColor : toneColor;
|
|
74
75
|
const borderColor = status === 'upcoming' ? upcomingColor : toneColor;
|
|
75
76
|
const textColor = status === 'upcoming' ? upcomingTextColor : textOnColor;
|
|
76
77
|
const isComplete = status === 'complete';
|
|
@@ -174,6 +175,7 @@ const Stepper = exports.Stepper = /*#__PURE__*/(0, _react.forwardRef)((props, re
|
|
|
174
175
|
const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
|
|
175
176
|
const toneColor = toneColorFor(theme, tone);
|
|
176
177
|
const upcomingColor = theme.colors.border.primary;
|
|
178
|
+
const upcomingFillColor = theme.colors.background.primary;
|
|
177
179
|
const upcomingTextColor = theme.colors.text.secondary;
|
|
178
180
|
const textOnColor = theme.colors.text.inverse;
|
|
179
181
|
const interactive = typeof onStepPress === 'function';
|
|
@@ -203,11 +205,15 @@ const Stepper = exports.Stepper = /*#__PURE__*/(0, _react.forwardRef)((props, re
|
|
|
203
205
|
outputRange: ['0%', '100%']
|
|
204
206
|
});
|
|
205
207
|
const a11yLabel = accessibilityLabel ?? `Progress: step ${activeStep + 1} of ${total}`;
|
|
208
|
+
const halfStepPct = total > 0 ? `${50 / total}%` : `0%`;
|
|
206
209
|
const renderHorizontal = () => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
207
210
|
style: styles.hRow,
|
|
208
211
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
209
212
|
pointerEvents: "none",
|
|
210
|
-
style: styles.hConnectorContainer,
|
|
213
|
+
style: [styles.hConnectorContainer, {
|
|
214
|
+
left: halfStepPct,
|
|
215
|
+
right: halfStepPct
|
|
216
|
+
}],
|
|
211
217
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
212
218
|
style: [styles.hConnectorTrack, {
|
|
213
219
|
backgroundColor: upcomingColor
|
|
@@ -228,6 +234,7 @@ const Stepper = exports.Stepper = /*#__PURE__*/(0, _react.forwardRef)((props, re
|
|
|
228
234
|
status: status,
|
|
229
235
|
toneColor: toneColor,
|
|
230
236
|
upcomingColor: upcomingColor,
|
|
237
|
+
upcomingFillColor: upcomingFillColor,
|
|
231
238
|
onPressColor: toneColor,
|
|
232
239
|
textOnColor: textOnColor,
|
|
233
240
|
upcomingTextColor: upcomingTextColor,
|
|
@@ -260,6 +267,7 @@ const Stepper = exports.Stepper = /*#__PURE__*/(0, _react.forwardRef)((props, re
|
|
|
260
267
|
status: status,
|
|
261
268
|
toneColor: toneColor,
|
|
262
269
|
upcomingColor: upcomingColor,
|
|
270
|
+
upcomingFillColor: upcomingFillColor,
|
|
263
271
|
onPressColor: toneColor,
|
|
264
272
|
textOnColor: textOnColor,
|
|
265
273
|
upcomingTextColor: upcomingTextColor,
|
|
@@ -338,8 +346,6 @@ const buildStyles = theme => _reactNative.StyleSheet.create({
|
|
|
338
346
|
hConnectorContainer: {
|
|
339
347
|
position: 'absolute',
|
|
340
348
|
top: CIRCLE_SIZE / 2 - 1,
|
|
341
|
-
left: CIRCLE_SIZE / 2,
|
|
342
|
-
right: CIRCLE_SIZE / 2,
|
|
343
349
|
height: 2,
|
|
344
350
|
flexDirection: 'row',
|
|
345
351
|
alignItems: 'center'
|
|
@@ -47,15 +47,17 @@ const Tabs = exports.Tabs = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =>
|
|
|
47
47
|
(0, _react.useEffect)(() => {
|
|
48
48
|
if (!activeLayout) return;
|
|
49
49
|
const spring = theme.motion.spring.snappy;
|
|
50
|
-
_reactNative.Animated.parallel([
|
|
50
|
+
_reactNative.Animated.parallel([
|
|
51
|
+
// Both must use the JS driver: width can't run on native, and mixing
|
|
52
|
+
// drivers on the same view (transform native + width JS) trips RN's
|
|
53
|
+
// "node already moved to native" guard under the new architecture.
|
|
54
|
+
_reactNative.Animated.spring(indicatorTranslateX, {
|
|
51
55
|
toValue: activeLayout.x,
|
|
52
56
|
damping: spring.damping,
|
|
53
57
|
stiffness: spring.stiffness,
|
|
54
58
|
mass: spring.mass,
|
|
55
|
-
useNativeDriver:
|
|
56
|
-
}),
|
|
57
|
-
// width is a layout prop — must run on JS thread (useNativeDriver: false).
|
|
58
|
-
_reactNative.Animated.spring(indicatorWidth, {
|
|
59
|
+
useNativeDriver: false
|
|
60
|
+
}), _reactNative.Animated.spring(indicatorWidth, {
|
|
59
61
|
toValue: activeLayout.width,
|
|
60
62
|
damping: spring.damping,
|
|
61
63
|
stiffness: spring.stiffness,
|
|
@@ -74,7 +74,7 @@ const Wheel = ({
|
|
|
74
74
|
if (lastIndexRef.current !== selectedIndex) {
|
|
75
75
|
lastIndexRef.current = selectedIndex;
|
|
76
76
|
const offset = selectedIndex * ITEM_HEIGHT;
|
|
77
|
-
|
|
77
|
+
(0, _index.setNativeValue)(scrollY, offset);
|
|
78
78
|
// Defer to next frame so FlatList has measured.
|
|
79
79
|
requestAnimationFrame(() => {
|
|
80
80
|
listRef.current?.scrollToOffset({
|
|
@@ -281,8 +281,8 @@ const TimePicker = ({
|
|
|
281
281
|
useNativeDriver: true
|
|
282
282
|
})]).start();
|
|
283
283
|
} else {
|
|
284
|
-
|
|
285
|
-
|
|
284
|
+
(0, _index.setNativeValue)(opacity, 0);
|
|
285
|
+
(0, _index.setNativeValue)(translateY, 40);
|
|
286
286
|
}
|
|
287
287
|
}, [visible, opacity, translateY, theme.motion]);
|
|
288
288
|
const announce = (0, _react.useCallback)(msg => {
|
|
@@ -73,9 +73,9 @@ const Toast = ({
|
|
|
73
73
|
const panResponder = (0, _react.useMemo)(() => _reactNative.PanResponder.create({
|
|
74
74
|
onMoveShouldSetPanResponder: (_evt, gesture) => Math.abs(gesture.dx) > Math.abs(gesture.dy) && Math.abs(gesture.dx) > 6,
|
|
75
75
|
onPanResponderMove: (_evt, gesture) => {
|
|
76
|
-
|
|
76
|
+
(0, _index.setNativeValue)(translateX, gesture.dx);
|
|
77
77
|
const fade = 1 - Math.min(Math.abs(gesture.dx) / 200, 1) * 0.7;
|
|
78
|
-
|
|
78
|
+
(0, _index.setNativeValue)(opacity, fade);
|
|
79
79
|
},
|
|
80
80
|
onPanResponderRelease: (_evt, gesture) => {
|
|
81
81
|
if (Math.abs(gesture.dx) > SWIPE_DISMISS_THRESHOLD || Math.abs(gesture.vx) > SWIPE_VELOCITY_THRESHOLD) {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.createAnimatedValue = void 0;
|
|
6
|
+
exports.setNativeValue = exports.createAnimatedValue = void 0;
|
|
7
7
|
var _reactNative = require("react-native");
|
|
8
8
|
/**
|
|
9
9
|
* Create an `Animated.Value` that survives RN 0.85's dev-mode prop deepFreeze.
|
|
@@ -24,5 +24,24 @@ var _reactNative = require("react-native");
|
|
|
24
24
|
* Use everywhere the library would otherwise call `new Animated.Value(...)`.
|
|
25
25
|
*/
|
|
26
26
|
const createAnimatedValue = (initial, config) => Object.seal(new _reactNative.Animated.Value(initial, config));
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Set an `Animated.Value` to a target without going through JS.
|
|
30
|
+
*
|
|
31
|
+
* Once a value has been driven by `useNativeDriver: true`, the underlying
|
|
32
|
+
* native node owns it — calling `value.setValue(x)` from JS throws
|
|
33
|
+
* "Attempting to run JS driven animation on animated node that has been moved to native".
|
|
34
|
+
* Use this helper for any value that is *also* used in a native-driven
|
|
35
|
+
* `Animated.timing/spring`. A zero-duration native timing routes the update
|
|
36
|
+
* through the same driver and stays valid across re-mounts and re-runs.
|
|
37
|
+
*/
|
|
27
38
|
exports.createAnimatedValue = createAnimatedValue;
|
|
39
|
+
const setNativeValue = (value, to) => {
|
|
40
|
+
_reactNative.Animated.timing(value, {
|
|
41
|
+
toValue: to,
|
|
42
|
+
duration: 0,
|
|
43
|
+
useNativeDriver: true
|
|
44
|
+
}).start();
|
|
45
|
+
};
|
|
46
|
+
exports.setNativeValue = setNativeValue;
|
|
28
47
|
//# sourceMappingURL=animatedValue.js.map
|
|
@@ -52,7 +52,14 @@ Object.defineProperty(exports, "mergeTheme", {
|
|
|
52
52
|
return _merge.mergeTheme;
|
|
53
53
|
}
|
|
54
54
|
});
|
|
55
|
-
exports.
|
|
55
|
+
exports.setColorMode = exports.resetTheme = void 0;
|
|
56
|
+
Object.defineProperty(exports, "setNativeValue", {
|
|
57
|
+
enumerable: true,
|
|
58
|
+
get: function () {
|
|
59
|
+
return _animatedValue.setNativeValue;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
exports.subscribeTheme = exports.setTheme = void 0;
|
|
56
63
|
Object.defineProperty(exports, "useTheme", {
|
|
57
64
|
enumerable: true,
|
|
58
65
|
get: function () {
|