@webority-technologies/mobile 0.0.22 → 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.
Files changed (249) hide show
  1. package/lib/commonjs/components/Accordion/Accordion.js +9 -7
  2. package/lib/commonjs/components/AnimatePresence/AnimatePresence.js +69 -0
  3. package/lib/commonjs/components/AnimatePresence/index.js +13 -0
  4. package/lib/commonjs/components/AppBar/AppBar.js +9 -6
  5. package/lib/commonjs/components/Avatar/Avatar.js +4 -2
  6. package/lib/commonjs/components/Badge/Badge.js +5 -5
  7. package/lib/commonjs/components/Banner/Banner.js +20 -6
  8. package/lib/commonjs/components/BottomNavigation/BottomNavigation.js +6 -4
  9. package/lib/commonjs/components/BottomSheet/BottomSheet.js +8 -9
  10. package/lib/commonjs/components/Box/Box.js +162 -0
  11. package/lib/commonjs/components/Box/index.js +37 -0
  12. package/lib/commonjs/components/Button/Button.js +7 -7
  13. package/lib/commonjs/components/Card/Card.js +3 -3
  14. package/lib/commonjs/components/Carousel/Carousel.js +4 -2
  15. package/lib/commonjs/components/Checkbox/Checkbox.js +17 -7
  16. package/lib/commonjs/components/Chip/Chip.js +4 -2
  17. package/lib/commonjs/components/DatePicker/DatePicker.js +31 -24
  18. package/lib/commonjs/components/DateRangePicker/DateRangePicker.js +16 -11
  19. package/lib/commonjs/components/Dialog/Dialog.js +6 -4
  20. package/lib/commonjs/components/Drawer/Drawer.js +4 -2
  21. package/lib/commonjs/components/FieldBase/FieldBase.js +8 -4
  22. package/lib/commonjs/components/FloatingActionButton/FloatingActionButton.js +23 -13
  23. package/lib/commonjs/components/FormField/FormField.js +61 -25
  24. package/lib/commonjs/components/ImageGallery/ImageGallery.js +17 -15
  25. package/lib/commonjs/components/Input/Input.js +41 -29
  26. package/lib/commonjs/components/KeyboardAwareScrollView/KeyboardAwareScrollView.js +102 -0
  27. package/lib/commonjs/components/KeyboardAwareScrollView/index.js +13 -0
  28. package/lib/commonjs/components/KeyboardToolbar/KeyboardToolbar.js +130 -0
  29. package/lib/commonjs/components/KeyboardToolbar/index.js +13 -0
  30. package/lib/commonjs/components/ListItem/ListItem.js +4 -3
  31. package/lib/commonjs/components/Modal/Modal.js +21 -9
  32. package/lib/commonjs/components/NumberInput/NumberInput.js +38 -29
  33. package/lib/commonjs/components/OTPInput/OTPInput.js +37 -22
  34. package/lib/commonjs/components/Radio/Radio.js +9 -8
  35. package/lib/commonjs/components/Radio/RadioGroup.js +10 -3
  36. package/lib/commonjs/components/Rating/Rating.js +4 -3
  37. package/lib/commonjs/components/SearchBar/SearchBar.js +11 -6
  38. package/lib/commonjs/components/SegmentedControl/SegmentedControl.js +23 -12
  39. package/lib/commonjs/components/Select/Select.js +40 -36
  40. package/lib/commonjs/components/Skeleton/SkeletonContent.js +5 -2
  41. package/lib/commonjs/components/Slider/Slider.js +241 -225
  42. package/lib/commonjs/components/Spinner/Spinner.js +5 -5
  43. package/lib/commonjs/components/Stepper/Stepper.js +6 -5
  44. package/lib/commonjs/components/Swipeable/Swipeable.js +8 -9
  45. package/lib/commonjs/components/Switch/Switch.js +29 -16
  46. package/lib/commonjs/components/Tabs/Tabs.js +8 -5
  47. package/lib/commonjs/components/Text/Text.js +142 -0
  48. package/lib/commonjs/components/Text/index.js +13 -0
  49. package/lib/commonjs/components/TimePicker/TimePicker.js +23 -15
  50. package/lib/commonjs/components/Toast/Toast.js +22 -10
  51. package/lib/commonjs/components/Tooltip/Tooltip.js +6 -2
  52. package/lib/commonjs/components/index.js +156 -103
  53. package/lib/commonjs/form/FormContext.js +40 -0
  54. package/lib/commonjs/form/index.js +68 -0
  55. package/lib/commonjs/form/path.js +79 -0
  56. package/lib/commonjs/form/rules.js +67 -0
  57. package/lib/commonjs/form/types.js +2 -0
  58. package/lib/commonjs/form/useField.js +54 -0
  59. package/lib/commonjs/form/useForm.js +316 -0
  60. package/lib/commonjs/hooks/index.js +14 -0
  61. package/lib/commonjs/hooks/useControllableState.js +30 -0
  62. package/lib/commonjs/hooks/useReducedMotion.js +31 -0
  63. package/lib/commonjs/index.js +96 -11
  64. package/lib/commonjs/theme/ThemeContext.js +30 -2
  65. package/lib/commonjs/theme/tokens.js +12 -0
  66. package/lib/commonjs/utils/hapticUtils.js +11 -1
  67. package/lib/commonjs/utils/index.js +6 -0
  68. package/lib/module/components/Accordion/Accordion.js +10 -8
  69. package/lib/module/components/AnimatePresence/AnimatePresence.js +63 -0
  70. package/lib/module/components/AnimatePresence/index.js +4 -0
  71. package/lib/module/components/AppBar/AppBar.js +10 -7
  72. package/lib/module/components/Avatar/Avatar.js +4 -2
  73. package/lib/module/components/Badge/Badge.js +5 -5
  74. package/lib/module/components/Banner/Banner.js +20 -6
  75. package/lib/module/components/BottomNavigation/BottomNavigation.js +6 -4
  76. package/lib/module/components/BottomSheet/BottomSheet.js +8 -9
  77. package/lib/module/components/Box/Box.js +156 -0
  78. package/lib/module/components/Box/index.js +4 -0
  79. package/lib/module/components/Button/Button.js +7 -7
  80. package/lib/module/components/Card/Card.js +4 -4
  81. package/lib/module/components/Carousel/Carousel.js +4 -2
  82. package/lib/module/components/Checkbox/Checkbox.js +18 -8
  83. package/lib/module/components/Chip/Chip.js +5 -3
  84. package/lib/module/components/DatePicker/DatePicker.js +32 -25
  85. package/lib/module/components/DateRangePicker/DateRangePicker.js +17 -12
  86. package/lib/module/components/Dialog/Dialog.js +7 -5
  87. package/lib/module/components/Drawer/Drawer.js +5 -3
  88. package/lib/module/components/FieldBase/FieldBase.js +8 -4
  89. package/lib/module/components/FloatingActionButton/FloatingActionButton.js +24 -14
  90. package/lib/module/components/FormField/FormField.js +62 -26
  91. package/lib/module/components/ImageGallery/ImageGallery.js +18 -16
  92. package/lib/module/components/Input/Input.js +41 -29
  93. package/lib/module/components/KeyboardAwareScrollView/KeyboardAwareScrollView.js +98 -0
  94. package/lib/module/components/KeyboardAwareScrollView/index.js +4 -0
  95. package/lib/module/components/KeyboardToolbar/KeyboardToolbar.js +125 -0
  96. package/lib/module/components/KeyboardToolbar/index.js +4 -0
  97. package/lib/module/components/ListItem/ListItem.js +5 -4
  98. package/lib/module/components/Modal/Modal.js +22 -10
  99. package/lib/module/components/NumberInput/NumberInput.js +36 -27
  100. package/lib/module/components/OTPInput/OTPInput.js +37 -22
  101. package/lib/module/components/Radio/Radio.js +10 -9
  102. package/lib/module/components/Radio/RadioGroup.js +10 -3
  103. package/lib/module/components/Rating/Rating.js +5 -4
  104. package/lib/module/components/SearchBar/SearchBar.js +12 -7
  105. package/lib/module/components/SegmentedControl/SegmentedControl.js +24 -13
  106. package/lib/module/components/Select/Select.js +41 -37
  107. package/lib/module/components/Skeleton/SkeletonContent.js +5 -2
  108. package/lib/module/components/Slider/Slider.js +244 -228
  109. package/lib/module/components/Spinner/Spinner.js +5 -5
  110. package/lib/module/components/Stepper/Stepper.js +7 -6
  111. package/lib/module/components/Swipeable/Swipeable.js +9 -10
  112. package/lib/module/components/Switch/Switch.js +29 -16
  113. package/lib/module/components/Tabs/Tabs.js +9 -6
  114. package/lib/module/components/Text/Text.js +138 -0
  115. package/lib/module/components/Text/index.js +4 -0
  116. package/lib/module/components/TimePicker/TimePicker.js +24 -16
  117. package/lib/module/components/Toast/Toast.js +22 -10
  118. package/lib/module/components/Tooltip/Tooltip.js +6 -2
  119. package/lib/module/components/index.js +5 -0
  120. package/lib/module/form/FormContext.js +32 -0
  121. package/lib/module/form/index.js +12 -0
  122. package/lib/module/form/path.js +72 -0
  123. package/lib/module/form/rules.js +52 -0
  124. package/lib/module/form/types.js +2 -0
  125. package/lib/module/form/useField.js +49 -0
  126. package/lib/module/form/useForm.js +312 -0
  127. package/lib/module/hooks/index.js +2 -0
  128. package/lib/module/hooks/useControllableState.js +26 -0
  129. package/lib/module/hooks/useReducedMotion.js +27 -0
  130. package/lib/module/index.js +3 -1
  131. package/lib/module/theme/ThemeContext.js +30 -2
  132. package/lib/module/theme/tokens.js +12 -0
  133. package/lib/module/utils/hapticUtils.js +9 -0
  134. package/lib/module/utils/index.js +1 -1
  135. package/lib/typescript/commonjs/components/Accordion/Accordion.d.ts +3 -0
  136. package/lib/typescript/commonjs/components/AnimatePresence/AnimatePresence.d.ts +30 -0
  137. package/lib/typescript/commonjs/components/AnimatePresence/index.d.ts +3 -0
  138. package/lib/typescript/commonjs/components/AppBar/AppBar.d.ts +6 -0
  139. package/lib/typescript/commonjs/components/Banner/Banner.d.ts +3 -0
  140. package/lib/typescript/commonjs/components/BottomNavigation/BottomNavigation.d.ts +1 -1
  141. package/lib/typescript/commonjs/components/Box/Box.d.ts +60 -0
  142. package/lib/typescript/commonjs/components/Box/index.d.ts +3 -0
  143. package/lib/typescript/commonjs/components/Button/Button.d.ts +1 -1
  144. package/lib/typescript/commonjs/components/Card/Card.d.ts +3 -0
  145. package/lib/typescript/commonjs/components/Checkbox/Checkbox.d.ts +4 -2
  146. package/lib/typescript/commonjs/components/Chip/Chip.d.ts +3 -0
  147. package/lib/typescript/commonjs/components/DatePicker/DatePicker.d.ts +6 -3
  148. package/lib/typescript/commonjs/components/DateRangePicker/DateRangePicker.d.ts +6 -0
  149. package/lib/typescript/commonjs/components/Dialog/Dialog.d.ts +5 -2
  150. package/lib/typescript/commonjs/components/Drawer/Drawer.d.ts +3 -0
  151. package/lib/typescript/commonjs/components/FloatingActionButton/FloatingActionButton.d.ts +5 -0
  152. package/lib/typescript/commonjs/components/FormField/FormField.d.ts +13 -2
  153. package/lib/typescript/commonjs/components/ImageGallery/ImageGallery.d.ts +6 -0
  154. package/lib/typescript/commonjs/components/KeyboardAwareScrollView/KeyboardAwareScrollView.d.ts +20 -0
  155. package/lib/typescript/commonjs/components/KeyboardAwareScrollView/index.d.ts +3 -0
  156. package/lib/typescript/commonjs/components/KeyboardToolbar/KeyboardToolbar.d.ts +29 -0
  157. package/lib/typescript/commonjs/components/KeyboardToolbar/index.d.ts +3 -0
  158. package/lib/typescript/commonjs/components/ListItem/ListItem.d.ts +3 -0
  159. package/lib/typescript/commonjs/components/Modal/Modal.d.ts +6 -0
  160. package/lib/typescript/commonjs/components/NumberInput/NumberInput.d.ts +6 -2
  161. package/lib/typescript/commonjs/components/OTPInput/OTPInput.d.ts +9 -2
  162. package/lib/typescript/commonjs/components/Radio/Radio.d.ts +2 -2
  163. package/lib/typescript/commonjs/components/Radio/RadioGroup.d.ts +3 -2
  164. package/lib/typescript/commonjs/components/Rating/Rating.d.ts +6 -0
  165. package/lib/typescript/commonjs/components/SearchBar/SearchBar.d.ts +3 -0
  166. package/lib/typescript/commonjs/components/SegmentedControl/SegmentedControl.d.ts +6 -2
  167. package/lib/typescript/commonjs/components/Select/Select.d.ts +6 -0
  168. package/lib/typescript/commonjs/components/Slider/Slider.d.ts +9 -4
  169. package/lib/typescript/commonjs/components/Spinner/Spinner.d.ts +1 -1
  170. package/lib/typescript/commonjs/components/Stepper/Stepper.d.ts +6 -0
  171. package/lib/typescript/commonjs/components/Swipeable/Swipeable.d.ts +3 -0
  172. package/lib/typescript/commonjs/components/Switch/Switch.d.ts +3 -2
  173. package/lib/typescript/commonjs/components/Tabs/Tabs.d.ts +3 -0
  174. package/lib/typescript/commonjs/components/Text/Text.d.ts +25 -0
  175. package/lib/typescript/commonjs/components/Text/index.d.ts +3 -0
  176. package/lib/typescript/commonjs/components/TimePicker/TimePicker.d.ts +6 -3
  177. package/lib/typescript/commonjs/components/index.d.ts +10 -0
  178. package/lib/typescript/commonjs/form/FormContext.d.ts +17 -0
  179. package/lib/typescript/commonjs/form/index.d.ts +9 -0
  180. package/lib/typescript/commonjs/form/path.d.ts +10 -0
  181. package/lib/typescript/commonjs/form/rules.d.ts +31 -0
  182. package/lib/typescript/commonjs/form/types.d.ts +94 -0
  183. package/lib/typescript/commonjs/form/useField.d.ts +27 -0
  184. package/lib/typescript/commonjs/form/useForm.d.ts +10 -0
  185. package/lib/typescript/commonjs/hooks/index.d.ts +3 -0
  186. package/lib/typescript/commonjs/hooks/useControllableState.d.ts +17 -0
  187. package/lib/typescript/commonjs/hooks/useReducedMotion.d.ts +8 -0
  188. package/lib/typescript/commonjs/index.d.ts +4 -2
  189. package/lib/typescript/commonjs/theme/types.d.ts +17 -67
  190. package/lib/typescript/commonjs/utils/hapticUtils.d.ts +8 -0
  191. package/lib/typescript/commonjs/utils/index.d.ts +1 -1
  192. package/lib/typescript/module/components/Accordion/Accordion.d.ts +3 -0
  193. package/lib/typescript/module/components/AnimatePresence/AnimatePresence.d.ts +30 -0
  194. package/lib/typescript/module/components/AnimatePresence/index.d.ts +3 -0
  195. package/lib/typescript/module/components/AppBar/AppBar.d.ts +6 -0
  196. package/lib/typescript/module/components/Banner/Banner.d.ts +3 -0
  197. package/lib/typescript/module/components/BottomNavigation/BottomNavigation.d.ts +1 -1
  198. package/lib/typescript/module/components/Box/Box.d.ts +60 -0
  199. package/lib/typescript/module/components/Box/index.d.ts +3 -0
  200. package/lib/typescript/module/components/Button/Button.d.ts +1 -1
  201. package/lib/typescript/module/components/Card/Card.d.ts +3 -0
  202. package/lib/typescript/module/components/Checkbox/Checkbox.d.ts +4 -2
  203. package/lib/typescript/module/components/Chip/Chip.d.ts +3 -0
  204. package/lib/typescript/module/components/DatePicker/DatePicker.d.ts +6 -3
  205. package/lib/typescript/module/components/DateRangePicker/DateRangePicker.d.ts +6 -0
  206. package/lib/typescript/module/components/Dialog/Dialog.d.ts +5 -2
  207. package/lib/typescript/module/components/Drawer/Drawer.d.ts +3 -0
  208. package/lib/typescript/module/components/FloatingActionButton/FloatingActionButton.d.ts +5 -0
  209. package/lib/typescript/module/components/FormField/FormField.d.ts +13 -2
  210. package/lib/typescript/module/components/ImageGallery/ImageGallery.d.ts +6 -0
  211. package/lib/typescript/module/components/KeyboardAwareScrollView/KeyboardAwareScrollView.d.ts +20 -0
  212. package/lib/typescript/module/components/KeyboardAwareScrollView/index.d.ts +3 -0
  213. package/lib/typescript/module/components/KeyboardToolbar/KeyboardToolbar.d.ts +29 -0
  214. package/lib/typescript/module/components/KeyboardToolbar/index.d.ts +3 -0
  215. package/lib/typescript/module/components/ListItem/ListItem.d.ts +3 -0
  216. package/lib/typescript/module/components/Modal/Modal.d.ts +6 -0
  217. package/lib/typescript/module/components/NumberInput/NumberInput.d.ts +6 -2
  218. package/lib/typescript/module/components/OTPInput/OTPInput.d.ts +9 -2
  219. package/lib/typescript/module/components/Radio/Radio.d.ts +2 -2
  220. package/lib/typescript/module/components/Radio/RadioGroup.d.ts +3 -2
  221. package/lib/typescript/module/components/Rating/Rating.d.ts +6 -0
  222. package/lib/typescript/module/components/SearchBar/SearchBar.d.ts +3 -0
  223. package/lib/typescript/module/components/SegmentedControl/SegmentedControl.d.ts +6 -2
  224. package/lib/typescript/module/components/Select/Select.d.ts +6 -0
  225. package/lib/typescript/module/components/Slider/Slider.d.ts +9 -4
  226. package/lib/typescript/module/components/Spinner/Spinner.d.ts +1 -1
  227. package/lib/typescript/module/components/Stepper/Stepper.d.ts +6 -0
  228. package/lib/typescript/module/components/Swipeable/Swipeable.d.ts +3 -0
  229. package/lib/typescript/module/components/Switch/Switch.d.ts +3 -2
  230. package/lib/typescript/module/components/Tabs/Tabs.d.ts +3 -0
  231. package/lib/typescript/module/components/Text/Text.d.ts +25 -0
  232. package/lib/typescript/module/components/Text/index.d.ts +3 -0
  233. package/lib/typescript/module/components/TimePicker/TimePicker.d.ts +6 -3
  234. package/lib/typescript/module/components/index.d.ts +10 -0
  235. package/lib/typescript/module/form/FormContext.d.ts +17 -0
  236. package/lib/typescript/module/form/index.d.ts +9 -0
  237. package/lib/typescript/module/form/path.d.ts +10 -0
  238. package/lib/typescript/module/form/rules.d.ts +31 -0
  239. package/lib/typescript/module/form/types.d.ts +94 -0
  240. package/lib/typescript/module/form/useField.d.ts +27 -0
  241. package/lib/typescript/module/form/useForm.d.ts +10 -0
  242. package/lib/typescript/module/hooks/index.d.ts +3 -0
  243. package/lib/typescript/module/hooks/useControllableState.d.ts +17 -0
  244. package/lib/typescript/module/hooks/useReducedMotion.d.ts +8 -0
  245. package/lib/typescript/module/index.d.ts +4 -2
  246. package/lib/typescript/module/theme/types.d.ts +17 -67
  247. package/lib/typescript/module/utils/hapticUtils.d.ts +8 -0
  248. package/lib/typescript/module/utils/index.d.ts +1 -1
  249. package/package.json +1 -1
@@ -27,6 +27,7 @@ const Modal = exports.Modal = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
27
27
  contentStyle,
28
28
  backdropStyle,
29
29
  restoreFocusRef,
30
+ haptic,
30
31
  testID
31
32
  } = props;
32
33
  const theme = (0, _index.useTheme)();
@@ -35,7 +36,6 @@ const Modal = exports.Modal = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
35
36
  const screenHeight = _reactNative.Dimensions.get('window').height;
36
37
  const modalTokens = theme.components.modal;
37
38
  const scaleStartValue = modalTokens?.scaleStartValue ?? 0.9;
38
- const backdropHaptic = modalTokens?.backdropHaptic ?? false;
39
39
  const backdropAnim = (0, _react.useRef)((0, _index.createAnimatedValue)(0)).current;
40
40
  const scaleAnim = (0, _react.useRef)((0, _index.createAnimatedValue)(scaleStartValue)).current;
41
41
  const opacityAnim = (0, _react.useRef)((0, _index.createAnimatedValue)(0)).current;
@@ -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
@@ -120,9 +131,10 @@ const Modal = exports.Modal = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
120
131
  }, [visible, duration, restoreFocusRef]);
121
132
  const handleBackdropPress = (0, _react.useCallback)(() => {
122
133
  if (!backdropPressClose) return;
123
- if (backdropHaptic) (0, _hapticUtils.triggerHaptic)('selection');
134
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
135
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
124
136
  onRequestClose();
125
- }, [backdropPressClose, onRequestClose, backdropHaptic]);
137
+ }, [backdropPressClose, onRequestClose, haptic]);
126
138
  const handleHardwareBack = (0, _react.useCallback)(() => {
127
139
  if (hardwareBackPress) {
128
140
  onRequestClose();
@@ -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,
@@ -61,6 +63,7 @@ const NumberInput = exports.NumberInput = /*#__PURE__*/(0, _react.forwardRef)((p
61
63
  size = 'md',
62
64
  variant = 'inline',
63
65
  unit,
66
+ haptic,
64
67
  accessibilityLabel,
65
68
  style,
66
69
  containerStyle,
@@ -71,7 +74,12 @@ const NumberInput = exports.NumberInput = /*#__PURE__*/(0, _react.forwardRef)((p
71
74
  textInputProps,
72
75
  testID
73
76
  } = props;
74
- const theme = (0, _index.useTheme)();
77
+ const [current, setCurrent] = (0, _index.useControllableState)({
78
+ value,
79
+ defaultValue: defaultValue ?? props.min ?? 0,
80
+ onChange
81
+ });
82
+ const theme = (0, _index2.useTheme)();
75
83
  const sizeTokens = (0, _FieldBase.resolveFieldSize)(theme, size);
76
84
  const fieldText = (0, _FieldBase.resolveFieldTextStyle)(theme, {
77
85
  disabled
@@ -79,9 +87,8 @@ const NumberInput = exports.NumberInput = /*#__PURE__*/(0, _react.forwardRef)((p
79
87
  const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
80
88
  const longPressDelay = theme.components.numberInput?.longPressDelayMs ?? DEFAULT_LONG_PRESS_DELAY;
81
89
  const longPressInterval = theme.components.numberInput?.longPressIntervalMs ?? DEFAULT_LONG_PRESS_INTERVAL;
82
- 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,43 @@ 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
+ const h = (0, _index3.resolveHaptic)(haptic, 'selection');
125
+ if (h) (0, _index3.triggerHaptic)(h);
126
+ setExternal(current - step);
127
+ }, [atMin, interactive, haptic, setExternal, step, current]);
120
128
  const increment = (0, _react.useCallback)(() => {
121
129
  if (!interactive || atMax) return;
122
- if (pressHaptic) (0, _index2.triggerHaptic)('impactLight');
123
- setExternal(value + step);
124
- }, [atMax, interactive, pressHaptic, setExternal, step, value]);
130
+ const h = (0, _index3.resolveHaptic)(haptic, 'selection');
131
+ if (h) (0, _index3.triggerHaptic)(h);
132
+ setExternal(current + step);
133
+ }, [atMax, interactive, haptic, setExternal, step, current]);
125
134
  _react.default.useImperativeHandle(ref, () => ({
126
135
  focus: () => inputRef.current?.focus(),
127
136
  blur: () => inputRef.current?.blur(),
128
137
  clear: () => {
129
138
  setDraft('');
130
139
  if (Number.isFinite(min) && min > 0) {
131
- onChange(min);
140
+ setCurrent(min);
132
141
  } else {
133
- onChange(0 < min ? min : 0 > max ? max : 0);
142
+ setCurrent(0 < min ? min : 0 > max ? max : 0);
134
143
  }
135
144
  }
136
- }), [max, min, onChange]);
145
+ }), [max, min, setCurrent]);
137
146
  const startRepeating = (0, _react.useCallback)(direction => {
138
147
  if (!interactive) return;
139
148
  clearRepeat();
@@ -153,27 +162,27 @@ const NumberInput = exports.NumberInput = /*#__PURE__*/(0, _react.forwardRef)((p
153
162
  const parsed = Number(cleaned);
154
163
  if (cleaned !== '' && cleaned !== '-' && cleaned !== '.' && Number.isFinite(parsed)) {
155
164
  if (parsed >= min && parsed <= max) {
156
- if (parsed !== value) {
157
- onChange(roundToPrecision(parsed, allowDecimal ? precision : 0));
165
+ if (parsed !== current) {
166
+ setCurrent(roundToPrecision(parsed, allowDecimal ? precision : 0));
158
167
  }
159
168
  }
160
169
  }
161
- }, [allowDecimal, max, min, onChange, precision, value]);
170
+ }, [allowDecimal, max, min, setCurrent, precision, current]);
162
171
  const handleBlur = (0, _react.useCallback)(() => {
163
172
  setEditing(false);
164
173
  setFocused(false);
165
174
  const parsed = Number(draft);
166
175
  if (draft === '' || !Number.isFinite(parsed)) {
167
- setDraft(formatValue(value, allowDecimal, precision));
176
+ setDraft(formatValue(current, allowDecimal, precision));
168
177
  return;
169
178
  }
170
179
  const rounded = roundToPrecision(parsed, allowDecimal ? precision : 0);
171
180
  const clamped = clamp(rounded, min, max);
172
- if (clamped !== value) {
173
- onChange(clamped);
181
+ if (clamped !== current) {
182
+ setCurrent(clamped);
174
183
  }
175
184
  setDraft(formatValue(clamped, allowDecimal, precision));
176
- }, [allowDecimal, draft, max, min, onChange, precision, value]);
185
+ }, [allowDecimal, draft, max, min, setCurrent, precision, current]);
177
186
  const handleFocus = (0, _react.useCallback)(() => {
178
187
  setEditing(true);
179
188
  setFocused(true);
@@ -237,7 +246,7 @@ const NumberInput = exports.NumberInput = /*#__PURE__*/(0, _react.forwardRef)((p
237
246
  accessibilityRole: "adjustable",
238
247
  accessibilityLabel: accessibleInputLabel,
239
248
  accessibilityValue: {
240
- now: Number.isFinite(value) ? value : 0
249
+ now: Number.isFinite(current) ? current : 0
241
250
  },
242
251
  accessibilityState: {
243
252
  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,
@@ -50,12 +52,18 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
50
52
  error,
51
53
  size = 'md',
52
54
  secure = false,
55
+ haptic,
53
56
  accessibilityLabel,
54
57
  style,
55
58
  cellStyle,
56
59
  textStyle,
57
60
  testID
58
61
  } = props;
62
+ const [current, setCurrent] = (0, _index2.useControllableState)({
63
+ value,
64
+ defaultValue: defaultValue ?? '',
65
+ onChange
66
+ });
59
67
  const theme = (0, _index.useTheme)();
60
68
  const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
61
69
  const sizeStyles = {
@@ -86,8 +94,7 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
86
94
  }, [length]);
87
95
  const previousFocusedIndexRef = (0, _react.useRef)(-1);
88
96
  const shakeOnError = theme.components.otpInput?.shakeOnError ?? false;
89
- const errorHaptic = theme.components.otpInput?.errorHaptic ?? false;
90
- const selectionHaptic = theme.components.otpInput?.selectionHaptic ?? false;
97
+ const reduceMotion = (0, _index2.useReducedMotion)();
91
98
  const hasError = Boolean(error);
92
99
  const errorMessage = typeof error === 'string' ? error : undefined;
93
100
 
@@ -95,11 +102,12 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
95
102
  // error is initially true — there's no transition to animate.
96
103
  (0, _react.useEffect)(() => {
97
104
  const isFirstRun = previousErrorRef.current === null;
105
+ let anim;
98
106
  if (!isFirstRun && hasError && !previousErrorRef.current) {
99
- if (errorHaptic) (0, _index2.triggerHaptic)('notificationError');
100
- if (shakeOnError) {
107
+ if (haptic !== false) (0, _index3.triggerHaptic)('notificationError');
108
+ if (shakeOnError && !reduceMotion) {
101
109
  (0, _index.setNativeValue)(shake, 0);
102
- _reactNative.Animated.sequence([_reactNative.Animated.timing(shake, {
110
+ anim = _reactNative.Animated.sequence([_reactNative.Animated.timing(shake, {
103
111
  toValue: 1,
104
112
  duration: 75,
105
113
  easing: _reactNative.Easing.linear,
@@ -119,11 +127,13 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
119
127
  duration: 75,
120
128
  easing: _reactNative.Easing.linear,
121
129
  useNativeDriver: true
122
- })]).start();
130
+ })]);
131
+ anim.start();
123
132
  }
124
133
  }
125
134
  previousErrorRef.current = hasError;
126
- }, [hasError, shake, shakeOnError, errorHaptic]);
135
+ return () => anim?.stop();
136
+ }, [hasError, shake, shakeOnError, haptic]);
127
137
 
128
138
  // Animate underline opacity for the focused cell. Skip on first mount
129
139
  // (no prior focus state) — values are already at 0 and there's nothing to animate.
@@ -132,17 +142,21 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
132
142
  previousFocusedIndexRef.current = focusedIndex;
133
143
  if (previous === focusedIndex) return;
134
144
  if (previous === -1 && focusedIndex === -1) return;
145
+ const anims = [];
135
146
  underlines.forEach((anim, idx) => {
136
147
  const target = idx === focusedIndex ? 1 : 0;
137
148
  // Only animate the cells whose target changed.
138
149
  if (idx !== focusedIndex && idx !== previous) return;
139
- _reactNative.Animated.timing(anim, {
150
+ const animation = _reactNative.Animated.timing(anim, {
140
151
  toValue: target,
141
152
  duration: theme.motion.duration.fast,
142
153
  easing: _reactNative.Easing.bezier(...theme.motion.easing.standard),
143
154
  useNativeDriver: true
144
- }).start();
155
+ });
156
+ animation.start();
157
+ anims.push(animation);
145
158
  });
159
+ return () => anims.forEach(a => a.stop());
146
160
  }, [focusedIndex, underlines, theme]);
147
161
  const focusCell = (0, _react.useCallback)(index => {
148
162
  const target = inputsRef.current[index];
@@ -157,10 +171,10 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
157
171
  current?.blur();
158
172
  },
159
173
  clear: () => {
160
- onChange('');
174
+ setCurrent('');
161
175
  focusCell(0);
162
176
  }
163
- }), [focusCell, focusedIndex, onChange]);
177
+ }), [focusCell, focusedIndex, setCurrent]);
164
178
  (0, _react.useEffect)(() => {
165
179
  if (autoFocus && !disabled) {
166
180
  // Defer one frame so the inputs are mounted.
@@ -171,19 +185,19 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
171
185
  }, [autoFocus, disabled, focusCell]);
172
186
  const cells = (0, _react.useMemo)(() => {
173
187
  const arr = new Array(length).fill('');
174
- for (let i = 0; i < Math.min(value.length, length); i += 1) {
175
- arr[i] = value[i] ?? '';
188
+ for (let i = 0; i < Math.min(current.length, length); i += 1) {
189
+ arr[i] = current[i] ?? '';
176
190
  }
177
191
  return arr;
178
- }, [value, length]);
192
+ }, [current, length]);
179
193
  const updateValue = (0, _react.useCallback)(next => {
180
194
  const trimmed = next.slice(0, length);
181
- if (trimmed === value) return;
182
- onChange(trimmed);
195
+ if (trimmed === current) return;
196
+ setCurrent(trimmed);
183
197
  if (trimmed.length === length && onComplete) {
184
198
  onComplete(trimmed);
185
199
  }
186
- }, [length, onChange, onComplete, value]);
200
+ }, [length, setCurrent, onComplete, current]);
187
201
  const handleChangeText = (0, _react.useCallback)((index, raw) => {
188
202
  // Strip the ZWSP placeholder (used so iOS fires onKeyPress/Backspace on otherwise-empty cells).
189
203
  const stripped = raw.replace(/\u200B/g, '');
@@ -213,10 +227,11 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
213
227
  writeIndex += 1;
214
228
  }
215
229
  const next = chars.join('').slice(0, length);
216
- const previousLength = value.length;
230
+ const previousLength = current.length;
217
231
  updateValue(next);
218
- if (next.length !== previousLength && selectionHaptic) {
219
- (0, _index2.triggerHaptic)('selection');
232
+ if (next.length !== previousLength) {
233
+ const h = (0, _index3.resolveHaptic)(haptic, 'selection');
234
+ if (h) (0, _index3.triggerHaptic)(h);
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, haptic, 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',
@@ -70,17 +70,17 @@ const Radio = exports.Radio = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
70
70
  const inner = sizeOverrides?.inner ?? sizeMap[size].inner;
71
71
  const radioBorderWidth = theme.colors.border.width;
72
72
  const radioLabelGap = theme.components.radio?.labelGap ?? 10;
73
- const pressHapticEnabled = theme.components.radio?.pressHaptic ?? false;
74
- const resolvedHaptic = haptic === undefined ? pressHapticEnabled ? 'selection' : false : haptic;
75
73
  const progress = (0, _react.useRef)((0, _index.createAnimatedValue)(selected ? 1 : 0)).current;
76
74
  (0, _react.useEffect)(() => {
77
- _reactNative.Animated.spring(progress, {
75
+ const anim = _reactNative.Animated.spring(progress, {
78
76
  toValue: selected ? 1 : 0,
79
77
  damping: theme.motion.spring.snappy.damping,
80
78
  stiffness: theme.motion.spring.snappy.stiffness,
81
79
  mass: theme.motion.spring.snappy.mass,
82
80
  useNativeDriver: true
83
- }).start();
81
+ });
82
+ anim.start();
83
+ return () => anim.stop();
84
84
  }, [selected, progress, theme.motion.spring.snappy]);
85
85
  const scale = progress.interpolate({
86
86
  inputRange: [0, 1],
@@ -88,11 +88,12 @@ const Radio = exports.Radio = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
88
88
  });
89
89
  const handlePress = event => {
90
90
  if (disabled) return;
91
- if (resolvedHaptic !== false) (0, _hapticUtils.triggerHaptic)(resolvedHaptic);
91
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
92
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
92
93
  if (ctx) {
93
- ctx.onSelect(value);
94
+ ctx.onChange(value);
94
95
  } else {
95
- onSelect?.(value);
96
+ onChange?.(value);
96
97
  }
97
98
  rest.onPressOut?.(event);
98
99
  };
@@ -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, {
@@ -85,6 +85,7 @@ const Rating = exports.Rating = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
85
85
  tone = 'warning',
86
86
  label,
87
87
  loading = false,
88
+ haptic,
88
89
  accessibilityLabel,
89
90
  style,
90
91
  containerStyle,
@@ -121,7 +122,6 @@ const Rating = exports.Rating = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
121
122
  }, [max]);
122
123
  const pulseOnPress = theme.components.rating?.pulseOnPress ?? false;
123
124
  const pulseScale = theme.components.rating?.pulseScale ?? 1.2;
124
- const pressHapticEnabled = theme.components.rating?.pressHaptic ?? false;
125
125
  const pulse = (0, _react.useCallback)(idx => {
126
126
  const v = scaleRefs[idx];
127
127
  if (!v) return;
@@ -141,10 +141,11 @@ const Rating = exports.Rating = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
141
141
  const commit = (0, _react.useCallback)((next, animatedIndex) => {
142
142
  if (!interactive || !onChange) return;
143
143
  const cleaned = clampToStep(next, max, step);
144
- if (pressHapticEnabled) (0, _hapticUtils.triggerHaptic)('selection');
144
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
145
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
145
146
  if (pulseOnPress && typeof animatedIndex === 'number') pulse(animatedIndex);
146
147
  onChange(cleaned);
147
- }, [interactive, onChange, max, step, pulse, pressHapticEnabled, pulseOnPress]);
148
+ }, [interactive, onChange, max, step, pulse, haptic, pulseOnPress]);
148
149
  const handleStarPress = (0, _react.useCallback)(index => e => {
149
150
  if (!interactive) return;
150
151
  const w = starWidthRef.current || starSize;
@@ -29,6 +29,7 @@ const SearchBar = exports.SearchBar = /*#__PURE__*/(0, _react.forwardRef)((props
29
29
  size = 'md',
30
30
  variant: variantProp,
31
31
  cancelLabel = 'Cancel',
32
+ haptic,
32
33
  style,
33
34
  accessibilityLabel,
34
35
  testID,
@@ -80,12 +81,14 @@ const SearchBar = exports.SearchBar = /*#__PURE__*/(0, _react.forwardRef)((props
80
81
  }, [debouncedValue, debounceMs, onChangeText]);
81
82
  const showCancelButton = showCancel && isFocused;
82
83
  (0, _react.useEffect)(() => {
83
- _reactNative.Animated.timing(cancelAnim, {
84
+ const anim = _reactNative.Animated.timing(cancelAnim, {
84
85
  toValue: showCancelButton ? 1 : 0,
85
86
  duration: 200,
86
87
  easing: _reactNative.Easing.bezier(...theme.motion.easing.standard),
87
88
  useNativeDriver: false
88
- }).start();
89
+ });
90
+ anim.start();
91
+ return () => anim.stop();
89
92
  }, [showCancelButton, cancelAnim, theme.motion.easing.standard]);
90
93
  const handleChangeText = (0, _react.useCallback)(text => {
91
94
  if (debounceMs !== undefined) {
@@ -95,16 +98,18 @@ const SearchBar = exports.SearchBar = /*#__PURE__*/(0, _react.forwardRef)((props
95
98
  onChangeText(text);
96
99
  }, [debounceMs, onChangeText]);
97
100
  const handleClear = (0, _react.useCallback)(() => {
98
- (0, _hapticUtils.triggerHaptic)('selection');
101
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
102
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
99
103
  if (debounceMs !== undefined) {
100
104
  setInternalValue('');
101
105
  lastSentRef.current = '';
102
106
  }
103
107
  onChangeText('');
104
108
  onClear?.();
105
- }, [debounceMs, onChangeText, onClear]);
109
+ }, [haptic, debounceMs, onChangeText, onClear]);
106
110
  const handleCancel = (0, _react.useCallback)(() => {
107
- (0, _hapticUtils.triggerHaptic)('selection');
111
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
112
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
108
113
  if (debounceMs !== undefined) {
109
114
  setInternalValue('');
110
115
  lastSentRef.current = '';
@@ -112,7 +117,7 @@ const SearchBar = exports.SearchBar = /*#__PURE__*/(0, _react.forwardRef)((props
112
117
  onChangeText('');
113
118
  setIsFocused(false);
114
119
  onCancel?.();
115
- }, [debounceMs, onChangeText, onCancel]);
120
+ }, [haptic, debounceMs, onChangeText, onCancel]);
116
121
  const handleSubmit = (0, _react.useCallback)(() => {
117
122
  onSubmit?.(debounceMs !== undefined ? internalValue : value);
118
123
  }, [onSubmit, debounceMs, internalValue, value]);