@webority-technologies/mobile 0.0.21 → 0.0.23

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 (187) hide show
  1. package/lib/commonjs/components/Accordion/Accordion.js +4 -2
  2. package/lib/commonjs/components/Avatar/Avatar.js +4 -2
  3. package/lib/commonjs/components/Badge/Badge.js +5 -5
  4. package/lib/commonjs/components/Banner/Banner.js +8 -4
  5. package/lib/commonjs/components/BottomNavigation/BottomNavigation.js +6 -4
  6. package/lib/commonjs/components/BottomSheet/BottomSheet.js +69 -13
  7. package/lib/commonjs/components/BottomSheet/index.js +6 -0
  8. package/lib/commonjs/components/Box/Box.js +162 -0
  9. package/lib/commonjs/components/Box/index.js +37 -0
  10. package/lib/commonjs/components/Button/Button.js +7 -7
  11. package/lib/commonjs/components/Carousel/Carousel.js +4 -2
  12. package/lib/commonjs/components/Checkbox/Checkbox.js +14 -5
  13. package/lib/commonjs/components/DatePicker/DatePicker.js +9 -7
  14. package/lib/commonjs/components/DateRangePicker/DateRangePicker.js +5 -2
  15. package/lib/commonjs/components/Dialog/Dialog.js +2 -2
  16. package/lib/commonjs/components/FieldBase/FieldBase.js +8 -4
  17. package/lib/commonjs/components/FloatingActionButton/FloatingActionButton.js +13 -5
  18. package/lib/commonjs/components/FormField/FormField.js +61 -25
  19. package/lib/commonjs/components/Input/Input.js +41 -29
  20. package/lib/commonjs/components/KeyboardAwareScrollView/KeyboardAwareScrollView.js +102 -0
  21. package/lib/commonjs/components/KeyboardAwareScrollView/index.js +13 -0
  22. package/lib/commonjs/components/KeyboardToolbar/KeyboardToolbar.js +130 -0
  23. package/lib/commonjs/components/KeyboardToolbar/index.js +13 -0
  24. package/lib/commonjs/components/Modal/Modal.js +17 -6
  25. package/lib/commonjs/components/NumberInput/NumberInput.js +35 -28
  26. package/lib/commonjs/components/OTPInput/OTPInput.js +33 -18
  27. package/lib/commonjs/components/Radio/Radio.js +7 -5
  28. package/lib/commonjs/components/Radio/RadioGroup.js +10 -3
  29. package/lib/commonjs/components/SearchBar/SearchBar.js +4 -2
  30. package/lib/commonjs/components/SegmentedControl/SegmentedControl.js +20 -10
  31. package/lib/commonjs/components/Select/Select.js +33 -32
  32. package/lib/commonjs/components/Skeleton/SkeletonContent.js +5 -2
  33. package/lib/commonjs/components/Slider/Slider.js +42 -26
  34. package/lib/commonjs/components/Spinner/Spinner.js +5 -5
  35. package/lib/commonjs/components/Switch/Switch.js +29 -16
  36. package/lib/commonjs/components/Tabs/Tabs.js +4 -2
  37. package/lib/commonjs/components/Text/Text.js +142 -0
  38. package/lib/commonjs/components/Text/index.js +13 -0
  39. package/lib/commonjs/components/TimePicker/TimePicker.js +10 -7
  40. package/lib/commonjs/components/Toast/Toast.js +22 -10
  41. package/lib/commonjs/components/Tooltip/Tooltip.js +6 -2
  42. package/lib/commonjs/components/index.js +141 -89
  43. package/lib/commonjs/form/FormContext.js +40 -0
  44. package/lib/commonjs/form/index.js +68 -0
  45. package/lib/commonjs/form/path.js +79 -0
  46. package/lib/commonjs/form/rules.js +67 -0
  47. package/lib/commonjs/form/types.js +2 -0
  48. package/lib/commonjs/form/useField.js +54 -0
  49. package/lib/commonjs/form/useForm.js +316 -0
  50. package/lib/commonjs/hooks/index.js +14 -0
  51. package/lib/commonjs/hooks/useControllableState.js +30 -0
  52. package/lib/commonjs/hooks/useReducedMotion.js +31 -0
  53. package/lib/commonjs/index.js +96 -11
  54. package/lib/commonjs/theme/ThemeContext.js +30 -2
  55. package/lib/commonjs/theme/tokens.js +12 -0
  56. package/lib/module/components/Accordion/Accordion.js +4 -2
  57. package/lib/module/components/Avatar/Avatar.js +4 -2
  58. package/lib/module/components/Badge/Badge.js +5 -5
  59. package/lib/module/components/Banner/Banner.js +8 -4
  60. package/lib/module/components/BottomNavigation/BottomNavigation.js +6 -4
  61. package/lib/module/components/BottomSheet/BottomSheet.js +68 -13
  62. package/lib/module/components/BottomSheet/index.js +1 -1
  63. package/lib/module/components/Box/Box.js +156 -0
  64. package/lib/module/components/Box/index.js +4 -0
  65. package/lib/module/components/Button/Button.js +7 -7
  66. package/lib/module/components/Carousel/Carousel.js +4 -2
  67. package/lib/module/components/Checkbox/Checkbox.js +14 -5
  68. package/lib/module/components/DatePicker/DatePicker.js +9 -7
  69. package/lib/module/components/DateRangePicker/DateRangePicker.js +5 -2
  70. package/lib/module/components/Dialog/Dialog.js +2 -2
  71. package/lib/module/components/FieldBase/FieldBase.js +8 -4
  72. package/lib/module/components/FloatingActionButton/FloatingActionButton.js +13 -5
  73. package/lib/module/components/FormField/FormField.js +62 -26
  74. package/lib/module/components/Input/Input.js +41 -29
  75. package/lib/module/components/KeyboardAwareScrollView/KeyboardAwareScrollView.js +98 -0
  76. package/lib/module/components/KeyboardAwareScrollView/index.js +4 -0
  77. package/lib/module/components/KeyboardToolbar/KeyboardToolbar.js +125 -0
  78. package/lib/module/components/KeyboardToolbar/index.js +4 -0
  79. package/lib/module/components/Modal/Modal.js +17 -6
  80. package/lib/module/components/NumberInput/NumberInput.js +30 -23
  81. package/lib/module/components/OTPInput/OTPInput.js +30 -15
  82. package/lib/module/components/Radio/Radio.js +7 -5
  83. package/lib/module/components/Radio/RadioGroup.js +10 -3
  84. package/lib/module/components/SearchBar/SearchBar.js +4 -2
  85. package/lib/module/components/SegmentedControl/SegmentedControl.js +20 -10
  86. package/lib/module/components/Select/Select.js +33 -32
  87. package/lib/module/components/Skeleton/SkeletonContent.js +5 -2
  88. package/lib/module/components/Slider/Slider.js +42 -26
  89. package/lib/module/components/Spinner/Spinner.js +5 -5
  90. package/lib/module/components/Switch/Switch.js +29 -16
  91. package/lib/module/components/Tabs/Tabs.js +4 -2
  92. package/lib/module/components/Text/Text.js +138 -0
  93. package/lib/module/components/Text/index.js +4 -0
  94. package/lib/module/components/TimePicker/TimePicker.js +10 -7
  95. package/lib/module/components/Toast/Toast.js +22 -10
  96. package/lib/module/components/Tooltip/Tooltip.js +6 -2
  97. package/lib/module/components/index.js +5 -1
  98. package/lib/module/form/FormContext.js +32 -0
  99. package/lib/module/form/index.js +12 -0
  100. package/lib/module/form/path.js +72 -0
  101. package/lib/module/form/rules.js +52 -0
  102. package/lib/module/form/types.js +2 -0
  103. package/lib/module/form/useField.js +49 -0
  104. package/lib/module/form/useForm.js +312 -0
  105. package/lib/module/hooks/index.js +2 -0
  106. package/lib/module/hooks/useControllableState.js +26 -0
  107. package/lib/module/hooks/useReducedMotion.js +27 -0
  108. package/lib/module/index.js +3 -1
  109. package/lib/module/theme/ThemeContext.js +30 -2
  110. package/lib/module/theme/tokens.js +12 -0
  111. package/lib/typescript/commonjs/components/BottomNavigation/BottomNavigation.d.ts +1 -1
  112. package/lib/typescript/commonjs/components/BottomSheet/BottomSheet.d.ts +41 -0
  113. package/lib/typescript/commonjs/components/BottomSheet/index.d.ts +2 -2
  114. package/lib/typescript/commonjs/components/Box/Box.d.ts +60 -0
  115. package/lib/typescript/commonjs/components/Box/index.d.ts +3 -0
  116. package/lib/typescript/commonjs/components/Button/Button.d.ts +1 -1
  117. package/lib/typescript/commonjs/components/Checkbox/Checkbox.d.ts +3 -2
  118. package/lib/typescript/commonjs/components/DatePicker/DatePicker.d.ts +3 -3
  119. package/lib/typescript/commonjs/components/Dialog/Dialog.d.ts +2 -2
  120. package/lib/typescript/commonjs/components/FormField/FormField.d.ts +13 -2
  121. package/lib/typescript/commonjs/components/KeyboardAwareScrollView/KeyboardAwareScrollView.d.ts +20 -0
  122. package/lib/typescript/commonjs/components/KeyboardAwareScrollView/index.d.ts +3 -0
  123. package/lib/typescript/commonjs/components/KeyboardToolbar/KeyboardToolbar.d.ts +29 -0
  124. package/lib/typescript/commonjs/components/KeyboardToolbar/index.d.ts +3 -0
  125. package/lib/typescript/commonjs/components/NumberInput/NumberInput.d.ts +3 -2
  126. package/lib/typescript/commonjs/components/OTPInput/OTPInput.d.ts +3 -2
  127. package/lib/typescript/commonjs/components/Radio/Radio.d.ts +2 -2
  128. package/lib/typescript/commonjs/components/Radio/RadioGroup.d.ts +3 -2
  129. package/lib/typescript/commonjs/components/SegmentedControl/SegmentedControl.d.ts +3 -2
  130. package/lib/typescript/commonjs/components/Slider/Slider.d.ts +6 -4
  131. package/lib/typescript/commonjs/components/Spinner/Spinner.d.ts +1 -1
  132. package/lib/typescript/commonjs/components/Switch/Switch.d.ts +3 -2
  133. package/lib/typescript/commonjs/components/Text/Text.d.ts +25 -0
  134. package/lib/typescript/commonjs/components/Text/index.d.ts +3 -0
  135. package/lib/typescript/commonjs/components/TimePicker/TimePicker.d.ts +3 -3
  136. package/lib/typescript/commonjs/components/index.d.ts +10 -2
  137. package/lib/typescript/commonjs/form/FormContext.d.ts +17 -0
  138. package/lib/typescript/commonjs/form/index.d.ts +9 -0
  139. package/lib/typescript/commonjs/form/path.d.ts +10 -0
  140. package/lib/typescript/commonjs/form/rules.d.ts +31 -0
  141. package/lib/typescript/commonjs/form/types.d.ts +94 -0
  142. package/lib/typescript/commonjs/form/useField.d.ts +27 -0
  143. package/lib/typescript/commonjs/form/useForm.d.ts +10 -0
  144. package/lib/typescript/commonjs/hooks/index.d.ts +3 -0
  145. package/lib/typescript/commonjs/hooks/useControllableState.d.ts +17 -0
  146. package/lib/typescript/commonjs/hooks/useReducedMotion.d.ts +8 -0
  147. package/lib/typescript/commonjs/index.d.ts +4 -2
  148. package/lib/typescript/commonjs/theme/types.d.ts +15 -0
  149. package/lib/typescript/module/components/BottomNavigation/BottomNavigation.d.ts +1 -1
  150. package/lib/typescript/module/components/BottomSheet/BottomSheet.d.ts +41 -0
  151. package/lib/typescript/module/components/BottomSheet/index.d.ts +2 -2
  152. package/lib/typescript/module/components/Box/Box.d.ts +60 -0
  153. package/lib/typescript/module/components/Box/index.d.ts +3 -0
  154. package/lib/typescript/module/components/Button/Button.d.ts +1 -1
  155. package/lib/typescript/module/components/Checkbox/Checkbox.d.ts +3 -2
  156. package/lib/typescript/module/components/DatePicker/DatePicker.d.ts +3 -3
  157. package/lib/typescript/module/components/Dialog/Dialog.d.ts +2 -2
  158. package/lib/typescript/module/components/FormField/FormField.d.ts +13 -2
  159. package/lib/typescript/module/components/KeyboardAwareScrollView/KeyboardAwareScrollView.d.ts +20 -0
  160. package/lib/typescript/module/components/KeyboardAwareScrollView/index.d.ts +3 -0
  161. package/lib/typescript/module/components/KeyboardToolbar/KeyboardToolbar.d.ts +29 -0
  162. package/lib/typescript/module/components/KeyboardToolbar/index.d.ts +3 -0
  163. package/lib/typescript/module/components/NumberInput/NumberInput.d.ts +3 -2
  164. package/lib/typescript/module/components/OTPInput/OTPInput.d.ts +3 -2
  165. package/lib/typescript/module/components/Radio/Radio.d.ts +2 -2
  166. package/lib/typescript/module/components/Radio/RadioGroup.d.ts +3 -2
  167. package/lib/typescript/module/components/SegmentedControl/SegmentedControl.d.ts +3 -2
  168. package/lib/typescript/module/components/Slider/Slider.d.ts +6 -4
  169. package/lib/typescript/module/components/Spinner/Spinner.d.ts +1 -1
  170. package/lib/typescript/module/components/Switch/Switch.d.ts +3 -2
  171. package/lib/typescript/module/components/Text/Text.d.ts +25 -0
  172. package/lib/typescript/module/components/Text/index.d.ts +3 -0
  173. package/lib/typescript/module/components/TimePicker/TimePicker.d.ts +3 -3
  174. package/lib/typescript/module/components/index.d.ts +10 -2
  175. package/lib/typescript/module/form/FormContext.d.ts +17 -0
  176. package/lib/typescript/module/form/index.d.ts +9 -0
  177. package/lib/typescript/module/form/path.d.ts +10 -0
  178. package/lib/typescript/module/form/rules.d.ts +31 -0
  179. package/lib/typescript/module/form/types.d.ts +94 -0
  180. package/lib/typescript/module/form/useField.d.ts +27 -0
  181. package/lib/typescript/module/form/useForm.d.ts +10 -0
  182. package/lib/typescript/module/hooks/index.d.ts +3 -0
  183. package/lib/typescript/module/hooks/useControllableState.d.ts +17 -0
  184. package/lib/typescript/module/hooks/useReducedMotion.d.ts +8 -0
  185. package/lib/typescript/module/index.d.ts +4 -2
  186. package/lib/typescript/module/theme/types.d.ts +15 -0
  187. package/package.json +1 -1
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.KeyboardToolbar = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _index = require("../../theme/index.js");
10
+ var _FormContext = require("../../form/FormContext.js");
11
+ var _index2 = require("../Text/index.js");
12
+ var _jsxRuntime = require("react/jsx-runtime");
13
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
14
+ const NavButton = ({
15
+ label,
16
+ accessibilityLabel,
17
+ onPress,
18
+ theme
19
+ }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
20
+ onPress: onPress,
21
+ disabled: !onPress,
22
+ accessibilityRole: "button",
23
+ accessibilityLabel: accessibilityLabel,
24
+ hitSlop: 8,
25
+ style: {
26
+ paddingHorizontal: theme.spacing.sm,
27
+ opacity: onPress ? 1 : 0.4
28
+ },
29
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.Text, {
30
+ variant: "h2",
31
+ color: onPress ? 'link' : 'disabled',
32
+ children: label
33
+ })
34
+ });
35
+
36
+ /**
37
+ * An accessory bar pinned just above the keyboard — pure RN, no native
38
+ * dependency. Shows a Done (dismiss) button and optional prev/next chevrons
39
+ * that, inside a `<Form>`, walk the registered field order. Render it at the
40
+ * screen root (a `flex: 1` ancestor) so its `bottom: keyboardHeight` offset
41
+ * lands it on top of the keyboard. Renders nothing while the keyboard is hidden.
42
+ */
43
+ const KeyboardToolbar = props => {
44
+ const {
45
+ doneLabel = 'Done',
46
+ showNavigation,
47
+ onDone,
48
+ onNext,
49
+ onPrev,
50
+ leading,
51
+ style,
52
+ testID
53
+ } = props;
54
+ const theme = (0, _index.useTheme)();
55
+ const form = (0, _FormContext.useOptionalFormContext)();
56
+ const [keyboardHeight, setKeyboardHeight] = (0, _react.useState)(0);
57
+ (0, _react.useEffect)(() => {
58
+ const showEvent = _reactNative.Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow';
59
+ const hideEvent = _reactNative.Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide';
60
+ const showSub = _reactNative.Keyboard.addListener(showEvent, e => setKeyboardHeight(e.endCoordinates?.height ?? 0));
61
+ const hideSub = _reactNative.Keyboard.addListener(hideEvent, () => setKeyboardHeight(0));
62
+ return () => {
63
+ showSub.remove();
64
+ hideSub.remove();
65
+ };
66
+ }, []);
67
+ if (keyboardHeight <= 0) return null;
68
+ const handleDone = onDone ?? (() => _reactNative.Keyboard.dismiss());
69
+ const handlePrev = onPrev ?? form?.focusPrev;
70
+ const handleNext = onNext ?? form?.focusNext;
71
+ const navEnabled = showNavigation ?? Boolean(handlePrev || handleNext);
72
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
73
+ testID: testID,
74
+ accessibilityRole: "toolbar",
75
+ style: [styles.bar, {
76
+ bottom: keyboardHeight,
77
+ backgroundColor: theme.colors.background.elevated,
78
+ borderTopColor: theme.colors.border.primary,
79
+ paddingHorizontal: theme.spacing.md
80
+ }, style],
81
+ children: [navEnabled ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
82
+ style: styles.nav,
83
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(NavButton, {
84
+ label: "\u2039",
85
+ accessibilityLabel: "Previous field",
86
+ onPress: handlePrev,
87
+ theme: theme
88
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(NavButton, {
89
+ label: "\u203A",
90
+ accessibilityLabel: "Next field",
91
+ onPress: handleNext,
92
+ theme: theme
93
+ })]
94
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {}), leading, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
95
+ style: styles.spacer
96
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
97
+ onPress: handleDone,
98
+ accessibilityRole: "button",
99
+ accessibilityLabel: doneLabel,
100
+ hitSlop: 8,
101
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.Text, {
102
+ variant: "body",
103
+ weight: "semibold",
104
+ color: "link",
105
+ children: doneLabel
106
+ })
107
+ })]
108
+ });
109
+ };
110
+ exports.KeyboardToolbar = KeyboardToolbar;
111
+ const styles = _reactNative.StyleSheet.create({
112
+ bar: {
113
+ position: 'absolute',
114
+ left: 0,
115
+ right: 0,
116
+ height: 44,
117
+ flexDirection: 'row',
118
+ alignItems: 'center',
119
+ borderTopWidth: _reactNative.StyleSheet.hairlineWidth
120
+ },
121
+ nav: {
122
+ flexDirection: 'row',
123
+ alignItems: 'center'
124
+ },
125
+ spacer: {
126
+ flex: 1
127
+ }
128
+ });
129
+ var _default = exports.default = KeyboardToolbar;
130
+ //# sourceMappingURL=KeyboardToolbar.js.map
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "KeyboardToolbar", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _KeyboardToolbar.KeyboardToolbar;
10
+ }
11
+ });
12
+ var _KeyboardToolbar = require("./KeyboardToolbar.js");
13
+ //# sourceMappingURL=index.js.map
@@ -44,6 +44,7 @@ const Modal = exports.Modal = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
44
44
  const wasVisibleRef = (0, _react.useRef)(false);
45
45
  const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
46
46
  (0, _react.useEffect)(() => {
47
+ const running = [];
47
48
  if (visible) {
48
49
  // Two Fabric quirks force this combination: backdrop View needs
49
50
  // `collapsable={false}` (see render) so flattening doesn't drop it,
@@ -51,21 +52,25 @@ const Modal = exports.Modal = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
51
52
  // Animated.View that also sets backgroundColor inline renders as 0 on
52
53
  // RN 0.85 / Fabric / iOS, leaving the dim layer invisible. Single
53
54
  // 240ms tween — JS thread cost is negligible.
54
- _reactNative.Animated.timing(backdropAnim, {
55
+ const backdrop = _reactNative.Animated.timing(backdropAnim, {
55
56
  toValue: 1,
56
57
  duration,
57
58
  useNativeDriver: false
58
- }).start();
59
+ });
60
+ backdrop.start();
61
+ running.push(backdrop);
59
62
  if (presentation === 'bottom') {
60
- _reactNative.Animated.spring(translateYAnim, {
63
+ const slide = _reactNative.Animated.spring(translateYAnim, {
61
64
  toValue: 0,
62
65
  damping: theme.motion.spring.gentle.damping,
63
66
  stiffness: theme.motion.spring.gentle.stiffness,
64
67
  mass: theme.motion.spring.gentle.mass,
65
68
  useNativeDriver: true
66
- }).start();
69
+ });
70
+ slide.start();
71
+ running.push(slide);
67
72
  } else {
68
- _reactNative.Animated.parallel([_reactNative.Animated.spring(scaleAnim, {
73
+ const enter = _reactNative.Animated.parallel([_reactNative.Animated.spring(scaleAnim, {
69
74
  toValue: 1,
70
75
  damping: theme.motion.spring.gentle.damping,
71
76
  stiffness: theme.motion.spring.gentle.stiffness,
@@ -75,7 +80,9 @@ const Modal = exports.Modal = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
75
80
  toValue: 1,
76
81
  duration,
77
82
  useNativeDriver: true
78
- })]).start();
83
+ })]);
84
+ enter.start();
85
+ running.push(enter);
79
86
  }
80
87
  } else {
81
88
  // backdropAnim is JS-driven (see note above) — reset directly so a
@@ -85,6 +92,10 @@ const Modal = exports.Modal = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
85
92
  (0, _index.setNativeValue)(opacityAnim, 0);
86
93
  (0, _index.setNativeValue)(translateYAnim, screenHeight);
87
94
  }
95
+ // Stop in-flight tweens on unmount / visibility flip so an enter animation
96
+ // never resolves against a torn-down tree (fixes the jest async leak and
97
+ // the equivalent post-unmount work in the real app).
98
+ return () => running.forEach(animation => animation.stop());
88
99
  }, [visible, presentation, duration, backdropAnim, scaleAnim, opacityAnim, translateYAnim, screenHeight, theme.motion.spring.gentle.damping, theme.motion.spring.gentle.stiffness, theme.motion.spring.gentle.mass, scaleStartValue]);
89
100
 
90
101
  // Accessibility focus trap: when the modal opens, push screen-reader focus
@@ -6,8 +6,9 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = exports.NumberInput = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactNative = require("react-native");
9
- var _index = require("../../theme/index.js");
10
- var _index2 = require("../../utils/index.js");
9
+ var _index = require("../../hooks/index.js");
10
+ var _index2 = require("../../theme/index.js");
11
+ var _index3 = require("../../utils/index.js");
11
12
  var _FieldBase = require("../FieldBase/FieldBase.js");
12
13
  var _jsxRuntime = require("react/jsx-runtime");
13
14
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
@@ -48,6 +49,7 @@ const sanitizeTyped = (raw, allowDecimal) => {
48
49
  const NumberInput = exports.NumberInput = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
49
50
  const {
50
51
  value,
52
+ defaultValue,
51
53
  onChange,
52
54
  min = Number.NEGATIVE_INFINITY,
53
55
  max = Number.POSITIVE_INFINITY,
@@ -71,7 +73,12 @@ const NumberInput = exports.NumberInput = /*#__PURE__*/(0, _react.forwardRef)((p
71
73
  textInputProps,
72
74
  testID
73
75
  } = props;
74
- const theme = (0, _index.useTheme)();
76
+ const [current, setCurrent] = (0, _index.useControllableState)({
77
+ value,
78
+ defaultValue: defaultValue ?? props.min ?? 0,
79
+ onChange
80
+ });
81
+ const theme = (0, _index2.useTheme)();
75
82
  const sizeTokens = (0, _FieldBase.resolveFieldSize)(theme, size);
76
83
  const fieldText = (0, _FieldBase.resolveFieldTextStyle)(theme, {
77
84
  disabled
@@ -81,7 +88,7 @@ const NumberInput = exports.NumberInput = /*#__PURE__*/(0, _react.forwardRef)((p
81
88
  const longPressInterval = theme.components.numberInput?.longPressIntervalMs ?? DEFAULT_LONG_PRESS_INTERVAL;
82
89
  const pressHaptic = theme.components.numberInput?.pressHaptic ?? false;
83
90
  const inputRef = (0, _react.useRef)(null);
84
- const [draft, setDraft] = (0, _react.useState)(formatValue(value, allowDecimal, precision));
91
+ const [draft, setDraft] = (0, _react.useState)(formatValue(current, allowDecimal, precision));
85
92
  const [editing, setEditing] = (0, _react.useState)(false);
86
93
  const [focused, setFocused] = (0, _react.useState)(false);
87
94
  const repeatTimeoutRef = (0, _react.useRef)(null);
@@ -99,41 +106,41 @@ const NumberInput = exports.NumberInput = /*#__PURE__*/(0, _react.forwardRef)((p
99
106
  (0, _react.useEffect)(() => clearRepeat, [clearRepeat]);
100
107
  (0, _react.useEffect)(() => {
101
108
  if (!editing) {
102
- setDraft(formatValue(value, allowDecimal, precision));
109
+ setDraft(formatValue(current, allowDecimal, precision));
103
110
  }
104
- }, [value, allowDecimal, precision, editing]);
105
- const atMin = value <= min;
106
- const atMax = value >= max;
111
+ }, [current, allowDecimal, precision, editing]);
112
+ const atMin = current <= min;
113
+ const atMax = current >= max;
107
114
  const interactive = !disabled;
108
115
  const setExternal = (0, _react.useCallback)(next => {
109
116
  const rounded = roundToPrecision(next, allowDecimal ? precision : 0);
110
117
  const clamped = clamp(rounded, min, max);
111
- if (clamped !== value) {
112
- onChange(clamped);
118
+ if (clamped !== current) {
119
+ setCurrent(clamped);
113
120
  }
114
- }, [allowDecimal, max, min, onChange, precision, value]);
121
+ }, [allowDecimal, max, min, setCurrent, precision, current]);
115
122
  const decrement = (0, _react.useCallback)(() => {
116
123
  if (!interactive || atMin) return;
117
- if (pressHaptic) (0, _index2.triggerHaptic)('impactLight');
118
- setExternal(value - step);
119
- }, [atMin, interactive, pressHaptic, setExternal, step, value]);
124
+ if (pressHaptic) (0, _index3.triggerHaptic)('impactLight');
125
+ setExternal(current - step);
126
+ }, [atMin, interactive, pressHaptic, setExternal, step, current]);
120
127
  const increment = (0, _react.useCallback)(() => {
121
128
  if (!interactive || atMax) return;
122
- if (pressHaptic) (0, _index2.triggerHaptic)('impactLight');
123
- setExternal(value + step);
124
- }, [atMax, interactive, pressHaptic, setExternal, step, value]);
129
+ if (pressHaptic) (0, _index3.triggerHaptic)('impactLight');
130
+ setExternal(current + step);
131
+ }, [atMax, interactive, pressHaptic, setExternal, step, current]);
125
132
  _react.default.useImperativeHandle(ref, () => ({
126
133
  focus: () => inputRef.current?.focus(),
127
134
  blur: () => inputRef.current?.blur(),
128
135
  clear: () => {
129
136
  setDraft('');
130
137
  if (Number.isFinite(min) && min > 0) {
131
- onChange(min);
138
+ setCurrent(min);
132
139
  } else {
133
- onChange(0 < min ? min : 0 > max ? max : 0);
140
+ setCurrent(0 < min ? min : 0 > max ? max : 0);
134
141
  }
135
142
  }
136
- }), [max, min, onChange]);
143
+ }), [max, min, setCurrent]);
137
144
  const startRepeating = (0, _react.useCallback)(direction => {
138
145
  if (!interactive) return;
139
146
  clearRepeat();
@@ -153,27 +160,27 @@ const NumberInput = exports.NumberInput = /*#__PURE__*/(0, _react.forwardRef)((p
153
160
  const parsed = Number(cleaned);
154
161
  if (cleaned !== '' && cleaned !== '-' && cleaned !== '.' && Number.isFinite(parsed)) {
155
162
  if (parsed >= min && parsed <= max) {
156
- if (parsed !== value) {
157
- onChange(roundToPrecision(parsed, allowDecimal ? precision : 0));
163
+ if (parsed !== current) {
164
+ setCurrent(roundToPrecision(parsed, allowDecimal ? precision : 0));
158
165
  }
159
166
  }
160
167
  }
161
- }, [allowDecimal, max, min, onChange, precision, value]);
168
+ }, [allowDecimal, max, min, setCurrent, precision, current]);
162
169
  const handleBlur = (0, _react.useCallback)(() => {
163
170
  setEditing(false);
164
171
  setFocused(false);
165
172
  const parsed = Number(draft);
166
173
  if (draft === '' || !Number.isFinite(parsed)) {
167
- setDraft(formatValue(value, allowDecimal, precision));
174
+ setDraft(formatValue(current, allowDecimal, precision));
168
175
  return;
169
176
  }
170
177
  const rounded = roundToPrecision(parsed, allowDecimal ? precision : 0);
171
178
  const clamped = clamp(rounded, min, max);
172
- if (clamped !== value) {
173
- onChange(clamped);
179
+ if (clamped !== current) {
180
+ setCurrent(clamped);
174
181
  }
175
182
  setDraft(formatValue(clamped, allowDecimal, precision));
176
- }, [allowDecimal, draft, max, min, onChange, precision, value]);
183
+ }, [allowDecimal, draft, max, min, setCurrent, precision, current]);
177
184
  const handleFocus = (0, _react.useCallback)(() => {
178
185
  setEditing(true);
179
186
  setFocused(true);
@@ -237,7 +244,7 @@ const NumberInput = exports.NumberInput = /*#__PURE__*/(0, _react.forwardRef)((p
237
244
  accessibilityRole: "adjustable",
238
245
  accessibilityLabel: accessibleInputLabel,
239
246
  accessibilityValue: {
240
- now: Number.isFinite(value) ? value : 0
247
+ now: Number.isFinite(current) ? current : 0
241
248
  },
242
249
  accessibilityState: {
243
250
  disabled
@@ -7,7 +7,8 @@ exports.default = exports.OTPInput = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactNative = require("react-native");
9
9
  var _index = require("../../theme/index.js");
10
- var _index2 = require("../../utils/index.js");
10
+ var _index2 = require("../../hooks/index.js");
11
+ var _index3 = require("../../utils/index.js");
11
12
  var _FieldBase = require("../FieldBase/FieldBase.js");
12
13
  var _jsxRuntime = require("react/jsx-runtime");
13
14
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
@@ -41,6 +42,7 @@ const sanitizeChar = (input, kind) => {
41
42
  const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
42
43
  const {
43
44
  value,
45
+ defaultValue,
44
46
  onChange,
45
47
  onComplete,
46
48
  length = 6,
@@ -56,6 +58,11 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
56
58
  textStyle,
57
59
  testID
58
60
  } = props;
61
+ const [current, setCurrent] = (0, _index2.useControllableState)({
62
+ value,
63
+ defaultValue: defaultValue ?? '',
64
+ onChange
65
+ });
59
66
  const theme = (0, _index.useTheme)();
60
67
  const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
61
68
  const sizeStyles = {
@@ -86,6 +93,7 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
86
93
  }, [length]);
87
94
  const previousFocusedIndexRef = (0, _react.useRef)(-1);
88
95
  const shakeOnError = theme.components.otpInput?.shakeOnError ?? false;
96
+ const reduceMotion = (0, _index2.useReducedMotion)();
89
97
  const errorHaptic = theme.components.otpInput?.errorHaptic ?? false;
90
98
  const selectionHaptic = theme.components.otpInput?.selectionHaptic ?? false;
91
99
  const hasError = Boolean(error);
@@ -95,11 +103,12 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
95
103
  // error is initially true — there's no transition to animate.
96
104
  (0, _react.useEffect)(() => {
97
105
  const isFirstRun = previousErrorRef.current === null;
106
+ let anim;
98
107
  if (!isFirstRun && hasError && !previousErrorRef.current) {
99
- if (errorHaptic) (0, _index2.triggerHaptic)('notificationError');
100
- if (shakeOnError) {
108
+ if (errorHaptic) (0, _index3.triggerHaptic)('notificationError');
109
+ if (shakeOnError && !reduceMotion) {
101
110
  (0, _index.setNativeValue)(shake, 0);
102
- _reactNative.Animated.sequence([_reactNative.Animated.timing(shake, {
111
+ anim = _reactNative.Animated.sequence([_reactNative.Animated.timing(shake, {
103
112
  toValue: 1,
104
113
  duration: 75,
105
114
  easing: _reactNative.Easing.linear,
@@ -119,10 +128,12 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
119
128
  duration: 75,
120
129
  easing: _reactNative.Easing.linear,
121
130
  useNativeDriver: true
122
- })]).start();
131
+ })]);
132
+ anim.start();
123
133
  }
124
134
  }
125
135
  previousErrorRef.current = hasError;
136
+ return () => anim?.stop();
126
137
  }, [hasError, shake, shakeOnError, errorHaptic]);
127
138
 
128
139
  // Animate underline opacity for the focused cell. Skip on first mount
@@ -132,17 +143,21 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
132
143
  previousFocusedIndexRef.current = focusedIndex;
133
144
  if (previous === focusedIndex) return;
134
145
  if (previous === -1 && focusedIndex === -1) return;
146
+ const anims = [];
135
147
  underlines.forEach((anim, idx) => {
136
148
  const target = idx === focusedIndex ? 1 : 0;
137
149
  // Only animate the cells whose target changed.
138
150
  if (idx !== focusedIndex && idx !== previous) return;
139
- _reactNative.Animated.timing(anim, {
151
+ const animation = _reactNative.Animated.timing(anim, {
140
152
  toValue: target,
141
153
  duration: theme.motion.duration.fast,
142
154
  easing: _reactNative.Easing.bezier(...theme.motion.easing.standard),
143
155
  useNativeDriver: true
144
- }).start();
156
+ });
157
+ animation.start();
158
+ anims.push(animation);
145
159
  });
160
+ return () => anims.forEach(a => a.stop());
146
161
  }, [focusedIndex, underlines, theme]);
147
162
  const focusCell = (0, _react.useCallback)(index => {
148
163
  const target = inputsRef.current[index];
@@ -157,10 +172,10 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
157
172
  current?.blur();
158
173
  },
159
174
  clear: () => {
160
- onChange('');
175
+ setCurrent('');
161
176
  focusCell(0);
162
177
  }
163
- }), [focusCell, focusedIndex, onChange]);
178
+ }), [focusCell, focusedIndex, setCurrent]);
164
179
  (0, _react.useEffect)(() => {
165
180
  if (autoFocus && !disabled) {
166
181
  // Defer one frame so the inputs are mounted.
@@ -171,19 +186,19 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
171
186
  }, [autoFocus, disabled, focusCell]);
172
187
  const cells = (0, _react.useMemo)(() => {
173
188
  const arr = new Array(length).fill('');
174
- for (let i = 0; i < Math.min(value.length, length); i += 1) {
175
- arr[i] = value[i] ?? '';
189
+ for (let i = 0; i < Math.min(current.length, length); i += 1) {
190
+ arr[i] = current[i] ?? '';
176
191
  }
177
192
  return arr;
178
- }, [value, length]);
193
+ }, [current, length]);
179
194
  const updateValue = (0, _react.useCallback)(next => {
180
195
  const trimmed = next.slice(0, length);
181
- if (trimmed === value) return;
182
- onChange(trimmed);
196
+ if (trimmed === current) return;
197
+ setCurrent(trimmed);
183
198
  if (trimmed.length === length && onComplete) {
184
199
  onComplete(trimmed);
185
200
  }
186
- }, [length, onChange, onComplete, value]);
201
+ }, [length, setCurrent, onComplete, current]);
187
202
  const handleChangeText = (0, _react.useCallback)((index, raw) => {
188
203
  // Strip the ZWSP placeholder (used so iOS fires onKeyPress/Backspace on otherwise-empty cells).
189
204
  const stripped = raw.replace(/\u200B/g, '');
@@ -213,10 +228,10 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
213
228
  writeIndex += 1;
214
229
  }
215
230
  const next = chars.join('').slice(0, length);
216
- const previousLength = value.length;
231
+ const previousLength = current.length;
217
232
  updateValue(next);
218
233
  if (next.length !== previousLength && selectionHaptic) {
219
- (0, _index2.triggerHaptic)('selection');
234
+ (0, _index3.triggerHaptic)('selection');
220
235
  }
221
236
 
222
237
  // Move focus to the next empty cell or last cell.
@@ -226,7 +241,7 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
226
241
  } else {
227
242
  focusCell(nextFocus);
228
243
  }
229
- }, [cells, focusCell, keyboardType, length, selectionHaptic, updateValue, value]);
244
+ }, [cells, focusCell, keyboardType, length, selectionHaptic, updateValue, current]);
230
245
  const handleKeyPress = (0, _react.useCallback)((index, e) => {
231
246
  const key = e.nativeEvent.key;
232
247
  if (key !== 'Backspace') return;
@@ -44,7 +44,7 @@ const Radio = exports.Radio = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
44
44
  const {
45
45
  value,
46
46
  selected: selectedProp,
47
- onSelect,
47
+ onChange,
48
48
  disabled: disabledProp = false,
49
49
  label,
50
50
  size = 'md',
@@ -74,13 +74,15 @@ const Radio = exports.Radio = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
74
74
  const resolvedHaptic = haptic === undefined ? pressHapticEnabled ? 'selection' : false : haptic;
75
75
  const progress = (0, _react.useRef)((0, _index.createAnimatedValue)(selected ? 1 : 0)).current;
76
76
  (0, _react.useEffect)(() => {
77
- _reactNative.Animated.spring(progress, {
77
+ const anim = _reactNative.Animated.spring(progress, {
78
78
  toValue: selected ? 1 : 0,
79
79
  damping: theme.motion.spring.snappy.damping,
80
80
  stiffness: theme.motion.spring.snappy.stiffness,
81
81
  mass: theme.motion.spring.snappy.mass,
82
82
  useNativeDriver: true
83
- }).start();
83
+ });
84
+ anim.start();
85
+ return () => anim.stop();
84
86
  }, [selected, progress, theme.motion.spring.snappy]);
85
87
  const scale = progress.interpolate({
86
88
  inputRange: [0, 1],
@@ -90,9 +92,9 @@ const Radio = exports.Radio = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
90
92
  if (disabled) return;
91
93
  if (resolvedHaptic !== false) (0, _hapticUtils.triggerHaptic)(resolvedHaptic);
92
94
  if (ctx) {
93
- ctx.onSelect(value);
95
+ ctx.onChange(value);
94
96
  } else {
95
- onSelect?.(value);
97
+ onChange?.(value);
96
98
  }
97
99
  rest.onPressOut?.(event);
98
100
  };
@@ -7,10 +7,12 @@ exports.default = exports.RadioGroup = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactNative = require("react-native");
9
9
  var _Radio = require("./Radio.js");
10
+ var _index = require("../../hooks/index.js");
10
11
  var _jsxRuntime = require("react/jsx-runtime");
11
12
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
12
13
  const RadioGroup = ({
13
14
  value,
15
+ defaultValue,
14
16
  onChange,
15
17
  children,
16
18
  disabled = false,
@@ -18,11 +20,16 @@ const RadioGroup = ({
18
20
  style,
19
21
  testID
20
22
  }) => {
23
+ const [current, setCurrent] = (0, _index.useControllableState)({
24
+ value,
25
+ defaultValue: defaultValue ?? undefined,
26
+ onChange: onChange
27
+ });
21
28
  const ctx = (0, _react.useMemo)(() => ({
22
- selectedValue: value,
23
- onSelect: onChange,
29
+ selectedValue: current,
30
+ onChange: setCurrent,
24
31
  disabled
25
- }), [value, onChange, disabled]);
32
+ }), [current, setCurrent, disabled]);
26
33
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Radio.RadioGroupContext.Provider, {
27
34
  value: ctx,
28
35
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
@@ -80,12 +80,14 @@ const SearchBar = exports.SearchBar = /*#__PURE__*/(0, _react.forwardRef)((props
80
80
  }, [debouncedValue, debounceMs, onChangeText]);
81
81
  const showCancelButton = showCancel && isFocused;
82
82
  (0, _react.useEffect)(() => {
83
- _reactNative.Animated.timing(cancelAnim, {
83
+ const anim = _reactNative.Animated.timing(cancelAnim, {
84
84
  toValue: showCancelButton ? 1 : 0,
85
85
  duration: 200,
86
86
  easing: _reactNative.Easing.bezier(...theme.motion.easing.standard),
87
87
  useNativeDriver: false
88
- }).start();
88
+ });
89
+ anim.start();
90
+ return () => anim.stop();
89
91
  }, [showCancelButton, cancelAnim, theme.motion.easing.standard]);
90
92
  const handleChangeText = (0, _react.useCallback)(text => {
91
93
  if (debounceMs !== undefined) {