@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
@@ -442,12 +442,14 @@ const ThumbnailItem = ({
442
442
  }) => {
443
443
  const scale = (0, _react.useRef)((0, _index.createAnimatedValue)(isActive ? 1.1 : 1)).current;
444
444
  (0, _react.useEffect)(() => {
445
- _reactNative.Animated.spring(scale, {
445
+ const anim = _reactNative.Animated.spring(scale, {
446
446
  toValue: isActive ? 1.1 : 1,
447
447
  useNativeDriver: true,
448
448
  friction: 6,
449
449
  tension: 80
450
- }).start();
450
+ });
451
+ anim.start();
452
+ return () => anim.stop();
451
453
  }, [isActive, scale]);
452
454
  const content = (0, _react.useMemo)(() => {
453
455
  if (renderThumbnail) return renderThumbnail(item, index);
@@ -7,6 +7,7 @@ exports.default = exports.Checkbox = 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("../../hooks/index.js");
10
11
  var _hapticUtils = require("../../utils/hapticUtils.js");
11
12
  var _jsxRuntime = require("react/jsx-runtime");
12
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); }
@@ -31,6 +32,7 @@ const toneColor = (theme, tone) => {
31
32
  const Checkbox = exports.Checkbox = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
32
33
  const {
33
34
  checked,
35
+ defaultChecked,
34
36
  onChange,
35
37
  indeterminate = false,
36
38
  disabled = false,
@@ -38,7 +40,7 @@ const Checkbox = exports.Checkbox = /*#__PURE__*/(0, _react.forwardRef)((props,
38
40
  size = 'md',
39
41
  tone = 'primary',
40
42
  accessibilityLabel,
41
- haptic = 'selection',
43
+ haptic,
42
44
  style,
43
45
  boxStyle,
44
46
  checkIconStyle,
@@ -48,22 +50,29 @@ const Checkbox = exports.Checkbox = /*#__PURE__*/(0, _react.forwardRef)((props,
48
50
  testID,
49
51
  ...rest
50
52
  } = props;
53
+ const [current, setCurrent] = (0, _index2.useControllableState)({
54
+ value: checked,
55
+ defaultValue: defaultChecked ?? false,
56
+ onChange
57
+ });
51
58
  const theme = (0, _index.useTheme)();
52
59
  const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
53
60
  const boxSize = theme.components.checkbox?.[size]?.boxSize ?? sizeMap[size];
54
61
  const checkboxBorderWidth = theme.colors.border.width;
55
62
  const checkboxLabelGap = theme.components.checkbox?.labelGap ?? 10;
56
63
  const fillColor = toneColor(theme, tone);
57
- const isActive = checked || indeterminate;
64
+ const isActive = current || indeterminate;
58
65
  const progress = (0, _react.useRef)((0, _index.createAnimatedValue)(isActive ? 1 : 0)).current;
59
66
  (0, _react.useEffect)(() => {
60
- _reactNative.Animated.spring(progress, {
67
+ const anim = _reactNative.Animated.spring(progress, {
61
68
  toValue: isActive ? 1 : 0,
62
69
  damping: theme.motion.spring.snappy.damping,
63
70
  stiffness: theme.motion.spring.snappy.stiffness,
64
71
  mass: theme.motion.spring.snappy.mass,
65
72
  useNativeDriver: true
66
- }).start();
73
+ });
74
+ anim.start();
75
+ return () => anim.stop();
67
76
  }, [isActive, progress, theme.motion.spring.snappy]);
68
77
  const scale = progress.interpolate({
69
78
  inputRange: [0, 1],
@@ -71,8 +80,9 @@ const Checkbox = exports.Checkbox = /*#__PURE__*/(0, _react.forwardRef)((props,
71
80
  });
72
81
  const handlePress = event => {
73
82
  if (disabled) return;
74
- if (haptic !== false && theme.components.checkbox?.pressHaptic) (0, _hapticUtils.triggerHaptic)(haptic);
75
- onChange(!checked);
83
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
84
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
85
+ setCurrent(!current);
76
86
  rest.onPressOut?.(event);
77
87
  };
78
88
  const accessibleLabel = accessibilityLabel ?? label;
@@ -89,7 +99,7 @@ const Checkbox = exports.Checkbox = /*#__PURE__*/(0, _react.forwardRef)((props,
89
99
  accessibilityRole: "checkbox",
90
100
  accessibilityLabel: accessibleLabel,
91
101
  accessibilityState: {
92
- checked: indeterminate ? 'mixed' : checked,
102
+ checked: indeterminate ? 'mixed' : current,
93
103
  disabled
94
104
  },
95
105
  testID: testID,
@@ -104,6 +104,7 @@ const Chip = exports.Chip = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =>
104
104
  disabled = false,
105
105
  loading = false,
106
106
  accessibilityLabel,
107
+ haptic,
107
108
  style,
108
109
  textStyle,
109
110
  containerStyle,
@@ -150,12 +151,13 @@ const Chip = exports.Chip = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =>
150
151
  const borderWidth = isFilled ? 0 : theme.colors.border.width;
151
152
  const handlePress = () => {
152
153
  if (!isPressable) return;
153
- if (theme.components.chip?.pressHaptic) (0, _hapticUtils.triggerHaptic)('selection');
154
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
155
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
154
156
  onPress?.();
155
157
  };
156
158
  const handleClose = () => {
157
159
  if (disabled) return;
158
- if (theme.components.chip?.closeHaptic) (0, _hapticUtils.triggerHaptic)('impactLight');
160
+ if (haptic !== false) (0, _hapticUtils.triggerHaptic)('impactLight');
159
161
  onClose?.();
160
162
  };
161
163
  const a11yLabel = accessibilityLabel ?? label;
@@ -15,14 +15,14 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
15
15
  /**
16
16
  * DatePicker operates in two modes:
17
17
  *
18
- * 1. **Controlled-modal mode** — pass `visible` (plus `onSelect` / `onClose`)
18
+ * 1. **Controlled-modal mode** — pass `visible` (plus `onChange` / `onClose`)
19
19
  * and own the open state externally. The component renders only the modal.
20
20
  * 2. **Trigger mode** — omit `visible`. The component renders a built-in
21
21
  * PickerTrigger field (label / value / placeholder / chevron / clear /
22
22
  * helper / error / size / variant) and manages its own open state. The
23
23
  * field opens the modal on press and closes it on confirm/cancel.
24
24
  *
25
- * `onSelect` / `onClose` are typed optional to support trigger-only usage
25
+ * `onChange` / `onClose` are typed optional to support trigger-only usage
26
26
  * where the consumer may not need either callback. In controlled-modal mode
27
27
  * they remain semantically required.
28
28
  */
@@ -104,7 +104,7 @@ const buildDecadeCells = anchorYear => {
104
104
  const DatePicker = props => {
105
105
  const {
106
106
  value,
107
- onSelect,
107
+ onChange,
108
108
  onClose,
109
109
  minDate,
110
110
  maxDate,
@@ -120,6 +120,7 @@ const DatePicker = props => {
120
120
  headerLabelStyle,
121
121
  navButtonStyle,
122
122
  footerButtonStyle,
123
+ haptic,
123
124
  testID,
124
125
  label,
125
126
  placeholder,
@@ -179,7 +180,7 @@ const DatePicker = props => {
179
180
  if (open) {
180
181
  backdrop.setValue(0);
181
182
  (0, _index.setNativeValue)(sheet, 0);
182
- _reactNative.Animated.parallel([_reactNative.Animated.timing(backdrop, {
183
+ const anim = _reactNative.Animated.parallel([_reactNative.Animated.timing(backdrop, {
183
184
  toValue: 1,
184
185
  duration: theme.motion.duration.normal,
185
186
  easing: _reactNative.Easing.out(_reactNative.Easing.cubic),
@@ -190,7 +191,9 @@ const DatePicker = props => {
190
191
  stiffness: theme.motion.spring.gentle.stiffness,
191
192
  mass: theme.motion.spring.gentle.mass,
192
193
  useNativeDriver: true
193
- })]).start();
194
+ })]);
195
+ anim.start();
196
+ return () => anim.stop();
194
197
  }
195
198
  }, [open, mode, backdrop, sheet, theme.motion]);
196
199
  const disabledIsoSet = (0, _react.useMemo)(() => {
@@ -233,7 +236,7 @@ const DatePicker = props => {
233
236
  return false;
234
237
  }, [minDay, maxDay]);
235
238
  const animateMonthChange = (0, _react.useCallback)(delta => {
236
- if (theme.components.datePicker?.haptic) (0, _index2.triggerHaptic)('impactLight');
239
+ if (haptic !== false) (0, _index2.triggerHaptic)('impactLight');
237
240
  const direction = delta > 0 ? 1 : -1;
238
241
  const distance = theme.components.datePicker?.monthSlideDistance ?? 32;
239
242
  const outDuration = theme.components.datePicker?.monthSlideOutDuration ?? theme.motion.duration.fast ?? 140;
@@ -264,31 +267,31 @@ const DatePicker = props => {
264
267
  const next = addMonths(anchor, delta);
265
268
  setAnchor(next);
266
269
  _reactNative.AccessibilityInfo.announceForAccessibility(formatMonthYear(next, locale));
267
- }, [anchor, locale, monthFade, monthSlide, theme.components.datePicker, theme.motion.duration.fast]);
270
+ }, [anchor, haptic, locale, monthFade, monthSlide, theme.components.datePicker, theme.motion.duration.fast]);
268
271
  const goPrev = (0, _react.useCallback)(() => {
269
272
  if (viewMode === 'days') {
270
273
  animateMonthChange(-1);
271
274
  return;
272
275
  }
273
- if (theme.components.datePicker?.haptic) (0, _index2.triggerHaptic)('impactLight');
276
+ if (haptic !== false) (0, _index2.triggerHaptic)('impactLight');
274
277
  if (viewMode === 'years') {
275
278
  setAnchor(prev => new Date(prev.getFullYear() - GRID_SIZE, prev.getMonth(), 1));
276
279
  } else {
277
280
  setAnchor(prev => new Date(prev.getFullYear() - GRID_SIZE * DECADE_SPAN, prev.getMonth(), 1));
278
281
  }
279
- }, [animateMonthChange, viewMode, theme.components.datePicker]);
282
+ }, [animateMonthChange, viewMode, haptic]);
280
283
  const goNext = (0, _react.useCallback)(() => {
281
284
  if (viewMode === 'days') {
282
285
  animateMonthChange(1);
283
286
  return;
284
287
  }
285
- if (theme.components.datePicker?.haptic) (0, _index2.triggerHaptic)('impactLight');
288
+ if (haptic !== false) (0, _index2.triggerHaptic)('impactLight');
286
289
  if (viewMode === 'years') {
287
290
  setAnchor(prev => new Date(prev.getFullYear() + GRID_SIZE, prev.getMonth(), 1));
288
291
  } else {
289
292
  setAnchor(prev => new Date(prev.getFullYear() + GRID_SIZE * DECADE_SPAN, prev.getMonth(), 1));
290
293
  }
291
- }, [animateMonthChange, viewMode, theme.components.datePicker]);
294
+ }, [animateMonthChange, viewMode, haptic]);
292
295
 
293
296
  // View-mode transition: fade + scale, native driver.
294
297
  const animateViewTransition = (0, _react.useCallback)(() => {
@@ -308,7 +311,8 @@ const DatePicker = props => {
308
311
  })]).start();
309
312
  }, [viewFade, viewScale, theme.components.datePicker, theme.motion.duration.normal]);
310
313
  const cycleViewMode = (0, _react.useCallback)(() => {
311
- if (theme.components.datePicker?.haptic) (0, _index2.triggerHaptic)('selection');
314
+ const h = (0, _index2.resolveHaptic)(haptic, 'selection');
315
+ if (h) (0, _index2.triggerHaptic)(h);
312
316
  const pressDur = theme.components.datePicker?.headerPressDuration ?? 80;
313
317
  const releaseDur = theme.components.datePicker?.headerReleaseDuration ?? 100;
314
318
  _reactNative.Animated.sequence([_reactNative.Animated.timing(headerScale, {
@@ -326,23 +330,26 @@ const DatePicker = props => {
326
330
  return 'years';
327
331
  });
328
332
  animateViewTransition();
329
- }, [animateViewTransition, headerScale, theme.components.datePicker]);
333
+ }, [animateViewTransition, headerScale, haptic, theme.components.datePicker]);
330
334
  const pickYear = (0, _react.useCallback)(year => {
331
- if (theme.components.datePicker?.haptic) (0, _index2.triggerHaptic)('selection');
335
+ const h = (0, _index2.resolveHaptic)(haptic, 'selection');
336
+ if (h) (0, _index2.triggerHaptic)(h);
332
337
  setAnchor(prev => new Date(year, prev.getMonth(), 1));
333
338
  setViewMode('days');
334
339
  animateViewTransition();
335
- }, [animateViewTransition, theme.components.datePicker]);
340
+ }, [animateViewTransition, haptic]);
336
341
  const pickDecade = (0, _react.useCallback)(decadeStart => {
337
- if (theme.components.datePicker?.haptic) (0, _index2.triggerHaptic)('selection');
342
+ const h = (0, _index2.resolveHaptic)(haptic, 'selection');
343
+ if (h) (0, _index2.triggerHaptic)(h);
338
344
  // Anchor mid-decade so the year grid centers nicely on this decade.
339
345
  setAnchor(prev => new Date(decadeStart + 4, prev.getMonth(), 1));
340
346
  setViewMode('years');
341
347
  animateViewTransition();
342
- }, [animateViewTransition, theme.components.datePicker]);
348
+ }, [animateViewTransition, haptic]);
343
349
  const pressDay = (0, _react.useCallback)(cell => {
344
350
  if (isDisabled(cell.date)) return;
345
- if (theme.components.datePicker?.haptic) (0, _index2.triggerHaptic)('selection');
351
+ const h = (0, _index2.resolveHaptic)(haptic, 'selection');
352
+ if (h) (0, _index2.triggerHaptic)(h);
346
353
  setPendingDate(cell.date);
347
354
  if (!cell.inMonth) {
348
355
  setAnchor(new Date(cell.date.getFullYear(), cell.date.getMonth(), 1));
@@ -355,7 +362,7 @@ const DatePicker = props => {
355
362
  mass: theme.motion.spring.bouncy.mass,
356
363
  useNativeDriver: true
357
364
  }).start();
358
- }, [isDisabled, selectScale, theme.motion.spring.bouncy, theme.components.datePicker]);
365
+ }, [isDisabled, selectScale, theme.motion.spring.bouncy, haptic]);
359
366
  const finalizeClose = (0, _react.useCallback)(() => {
360
367
  if (isControlled) {
361
368
  onClose?.();
@@ -384,15 +391,15 @@ const DatePicker = props => {
384
391
  });
385
392
  }, [backdrop, mode, finalizeClose, sheet, theme.motion.duration.fast]);
386
393
  const handleCancel = (0, _react.useCallback)(() => {
387
- if (theme.components.datePicker?.haptic) (0, _index2.triggerHaptic)('selection');
394
+ if (haptic !== false) (0, _index2.triggerHaptic)('selection');
388
395
  handleClose();
389
- }, [handleClose, theme.components.datePicker]);
396
+ }, [handleClose, haptic]);
390
397
  const handleConfirm = (0, _react.useCallback)(() => {
391
398
  if (!pendingDate) return;
392
- if (theme.components.datePicker?.haptic) (0, _index2.triggerHaptic)('notificationSuccess');
393
- onSelect?.(pendingDate);
399
+ if (haptic !== false) (0, _index2.triggerHaptic)('notificationSuccess');
400
+ onChange?.(pendingDate);
394
401
  handleClose();
395
- }, [handleClose, onSelect, pendingDate, theme.components.datePicker]);
402
+ }, [handleClose, onChange, pendingDate, haptic]);
396
403
  const sheetTranslate = sheet.interpolate({
397
404
  inputRange: [0, 1],
398
405
  outputRange: [320, 0]
@@ -108,6 +108,7 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/(0, _react.forwar
108
108
  confirmLabel = 'Confirm',
109
109
  cancelLabel = 'Cancel',
110
110
  maxRange,
111
+ haptic,
111
112
  style,
112
113
  containerStyle,
113
114
  headerLabelStyle,
@@ -152,10 +153,11 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/(0, _react.forwar
152
153
  // Modal open / close animation. Backdrop opacity uses JS driver — see
153
154
  // Modal.tsx for the Fabric reason. Sheet transform stays native.
154
155
  (0, _react.useEffect)(() => {
156
+ let anim;
155
157
  if (open) {
156
158
  backdrop.setValue(0);
157
159
  (0, _index.setNativeValue)(sheet, 0);
158
- _reactNative.Animated.parallel([_reactNative.Animated.timing(backdrop, {
160
+ anim = _reactNative.Animated.parallel([_reactNative.Animated.timing(backdrop, {
159
161
  toValue: 1,
160
162
  duration: theme.motion.duration.normal,
161
163
  easing: _reactNative.Easing.out(_reactNative.Easing.cubic),
@@ -166,8 +168,10 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/(0, _react.forwar
166
168
  stiffness: theme.motion.spring.gentle.stiffness,
167
169
  mass: theme.motion.spring.gentle.mass,
168
170
  useNativeDriver: true
169
- })]).start();
171
+ })]);
172
+ anim.start();
170
173
  }
174
+ return () => anim?.stop();
171
175
  }, [open, backdrop, sheet, theme.motion]);
172
176
  const disabledIsoSet = (0, _react.useMemo)(() => {
173
177
  const set = new Set();
@@ -186,7 +190,7 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/(0, _react.forwar
186
190
  const headerLabel = (0, _react.useMemo)(() => formatMonthYear(anchor, locale), [anchor, locale]);
187
191
  const weekdays = (0, _react.useMemo)(() => weekdayLabels(locale, weekStartsOn), [locale, weekStartsOn]);
188
192
  const animateMonthChange = (0, _react.useCallback)(delta => {
189
- if (theme.components.dateRangePicker?.haptic) (0, _index2.triggerHaptic)('impactLight');
193
+ if (haptic !== false) (0, _index2.triggerHaptic)('impactLight');
190
194
  const direction = delta > 0 ? 1 : -1;
191
195
  const distance = theme.components.dateRangePicker?.monthSlideDistance ?? 32;
192
196
  const outDuration = theme.components.dateRangePicker?.monthSlideOutDuration ?? theme.motion.duration.fast ?? 140;
@@ -217,12 +221,13 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/(0, _react.forwar
217
221
  const next = addMonths(anchor, delta);
218
222
  setAnchor(next);
219
223
  _reactNative.AccessibilityInfo.announceForAccessibility(formatMonthYear(next, locale));
220
- }, [anchor, locale, monthFade, monthSlide, theme.components.dateRangePicker, theme.motion.duration.fast]);
224
+ }, [anchor, haptic, locale, monthFade, monthSlide, theme.components.dateRangePicker, theme.motion.duration.fast]);
221
225
  const goPrev = (0, _react.useCallback)(() => animateMonthChange(-1), [animateMonthChange]);
222
226
  const goNext = (0, _react.useCallback)(() => animateMonthChange(1), [animateMonthChange]);
223
227
  const pressDay = (0, _react.useCallback)(cell => {
224
228
  if (isDisabled(cell.date)) return;
225
- if (theme.components.dateRangePicker?.haptic) (0, _index2.triggerHaptic)('selection');
229
+ const h = (0, _index2.resolveHaptic)(haptic, 'selection');
230
+ if (h) (0, _index2.triggerHaptic)(h);
226
231
  const target = cell.date;
227
232
 
228
233
  // First tap: pick start. Or, when there's already a complete range, restart.
@@ -241,7 +246,7 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/(0, _react.forwar
241
246
  } else {
242
247
  if (maxRange && daysBetween(pendingStart, target) + 1 > maxRange) {
243
248
  // Reject ranges longer than maxRange — restart from the new tap.
244
- if (theme.components.dateRangePicker?.haptic) (0, _index2.triggerHaptic)('notificationWarning');
249
+ if (haptic !== false) (0, _index2.triggerHaptic)('notificationWarning');
245
250
  setPendingStart(target);
246
251
  setPendingEnd(null);
247
252
  return;
@@ -252,7 +257,7 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/(0, _react.forwar
252
257
  if (!cell.inMonth) {
253
258
  setAnchor(new Date(cell.date.getFullYear(), cell.date.getMonth(), 1));
254
259
  }
255
- }, [isDisabled, pendingStart, pendingEnd, maxRange, theme.components.dateRangePicker]);
260
+ }, [isDisabled, pendingStart, pendingEnd, maxRange, haptic]);
256
261
  const handleCloseModal = (0, _react.useCallback)(() => {
257
262
  if (isControlled) {
258
263
  onClose?.();
@@ -276,18 +281,18 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/(0, _react.forwar
276
281
  });
277
282
  }, [backdrop, handleCloseModal, sheet, theme.motion.duration.fast]);
278
283
  const handleCancel = (0, _react.useCallback)(() => {
279
- if (theme.components.dateRangePicker?.haptic) (0, _index2.triggerHaptic)('selection');
284
+ if (haptic !== false) (0, _index2.triggerHaptic)('selection');
280
285
  handleClose();
281
- }, [handleClose, theme.components.dateRangePicker]);
286
+ }, [handleClose, haptic]);
282
287
  const handleConfirm = (0, _react.useCallback)(() => {
283
288
  if (!pendingStart || !pendingEnd) return;
284
- if (theme.components.dateRangePicker?.haptic) (0, _index2.triggerHaptic)('notificationSuccess');
289
+ if (haptic !== false) (0, _index2.triggerHaptic)('notificationSuccess');
285
290
  onChange?.({
286
291
  start: pendingStart,
287
292
  end: pendingEnd
288
293
  });
289
294
  handleClose();
290
- }, [handleClose, onChange, pendingStart, pendingEnd, theme.components.dateRangePicker]);
295
+ }, [handleClose, onChange, pendingStart, pendingEnd, haptic]);
291
296
  const sheetTranslate = sheet.interpolate({
292
297
  inputRange: [0, 1],
293
298
  outputRange: [320, 0]
@@ -30,6 +30,7 @@ const Dialog = props => {
30
30
  actionsRowStyle,
31
31
  actionButtonStyle,
32
32
  actionTextStyle,
33
+ haptic,
33
34
  testID
34
35
  } = props;
35
36
  const theme = (0, _index.useTheme)();
@@ -41,12 +42,13 @@ const Dialog = props => {
41
42
  const actionButtonMinHeight = dialogTokens?.actionButtonMinHeight ?? 44;
42
43
  const handleAction = (0, _react.useCallback)(action => {
43
44
  if (action.loading) return;
44
- if (dialogTokens?.actionHaptic) (0, _hapticUtils.triggerHaptic)('selection');
45
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
46
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
45
47
  action.onPress();
46
48
  if (dismissOnAction) {
47
49
  onClose();
48
50
  }
49
- }, [dismissOnAction, onClose, dialogTokens?.actionHaptic]);
51
+ }, [dismissOnAction, onClose, haptic]);
50
52
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Modal.Modal, {
51
53
  visible: visible,
52
54
  onRequestClose: onClose,
@@ -150,7 +152,7 @@ const tintForVariant = (theme, variant) => {
150
152
  base: theme.colors.warning,
151
153
  muted: theme.colors.background.secondary
152
154
  };
153
- case 'danger':
155
+ case 'error':
154
156
  return {
155
157
  base: theme.colors.error,
156
158
  muted: theme.colors.background.secondary
@@ -181,7 +183,7 @@ const actionStyleFor = (theme, tone, variant) => {
181
183
  textColor: theme.colors.text.inverse
182
184
  };
183
185
  }
184
- case 'danger':
186
+ case 'error':
185
187
  return {
186
188
  backgroundColor: theme.colors.error,
187
189
  borderColor: 'transparent',
@@ -45,6 +45,7 @@ const Drawer = exports.Drawer = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
45
45
  enableSwipe = true,
46
46
  enableBackdropPress = true,
47
47
  backdropOpacity = 0.5,
48
+ haptic,
48
49
  containerStyle,
49
50
  children,
50
51
  accessibilityLabel,
@@ -224,9 +225,10 @@ const Drawer = exports.Drawer = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
224
225
  const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
225
226
  const handleBackdropPress = (0, _react.useCallback)(() => {
226
227
  if (!enableBackdropPress) return;
227
- if (drawerTokens?.backdropPressHaptic) (0, _index2.triggerHaptic)('selection');
228
+ const h = (0, _index2.resolveHaptic)(haptic, 'selection');
229
+ if (h) (0, _index2.triggerHaptic)(h);
228
230
  close();
229
- }, [enableBackdropPress, close, drawerTokens?.backdropPressHaptic]);
231
+ }, [enableBackdropPress, close, haptic]);
230
232
 
231
233
  // Per-side container layout — must be a hook on every render path so we
232
234
  // can't gate it on the lazy-mount early-return below.
@@ -294,20 +294,24 @@ const FieldBase = props => {
294
294
  const focusAnim = (0, _react.useRef)((0, _index.createAnimatedValue)(focused ? 1 : 0)).current;
295
295
  const errorAnim = (0, _react.useRef)((0, _index.createAnimatedValue)(error ? 1 : 0)).current;
296
296
  (0, _react.useEffect)(() => {
297
- _reactNative.Animated.timing(focusAnim, {
297
+ const anim = _reactNative.Animated.timing(focusAnim, {
298
298
  toValue: focused ? 1 : 0,
299
299
  duration: theme.motion.duration.fast,
300
300
  easing: _reactNative.Easing.bezier(...theme.motion.easing.standard),
301
301
  useNativeDriver: false
302
- }).start();
302
+ });
303
+ anim.start();
304
+ return () => anim.stop();
303
305
  }, [focused, focusAnim, theme.motion.duration.fast, theme.motion.easing.standard]);
304
306
  (0, _react.useEffect)(() => {
305
- _reactNative.Animated.timing(errorAnim, {
307
+ const anim = _reactNative.Animated.timing(errorAnim, {
306
308
  toValue: error ? 1 : 0,
307
309
  duration: theme.motion.duration.fast,
308
310
  easing: _reactNative.Easing.bezier(...theme.motion.easing.standard),
309
311
  useNativeDriver: false
310
- }).start();
312
+ });
313
+ anim.start();
314
+ return () => anim.stop();
311
315
  }, [error, errorAnim, theme.motion.duration.fast, theme.motion.easing.standard]);
312
316
 
313
317
  // Resting border + fill (pre-animation). Error wins over focus when both
@@ -69,6 +69,7 @@ const FloatingActionButton = exports.FloatingActionButton = /*#__PURE__*/(0, _re
69
69
  isScrolling = false,
70
70
  accessibilityLabel,
71
71
  accessibilityHint,
72
+ haptic,
72
73
  style,
73
74
  containerStyle,
74
75
  labelStyle,
@@ -88,19 +89,20 @@ const FloatingActionButton = exports.FloatingActionButton = /*#__PURE__*/(0, _re
88
89
  const fabTokens = theme.components.floatingActionButton;
89
90
  const edgeOffset = fabTokens?.edgeOffset ?? 24;
90
91
  const defaultBottomOffset = fabTokens?.bottomOffset ?? 24;
91
- const pressHaptic = fabTokens?.pressHaptic ?? false;
92
92
  const hideAnim = (0, _react.useRef)((0, _index.createAnimatedValue)(0)).current;
93
93
  (0, _react.useEffect)(() => {
94
94
  if (!hideOnScroll) {
95
95
  (0, _index.setNativeValue)(hideAnim, 0);
96
96
  return;
97
97
  }
98
- _reactNative.Animated.timing(hideAnim, {
98
+ const anim = _reactNative.Animated.timing(hideAnim, {
99
99
  toValue: isScrolling ? 1 : 0,
100
100
  duration: theme.motion.duration.normal,
101
101
  easing: _reactNative.Easing.bezier(...theme.motion.easing.standard),
102
102
  useNativeDriver: true
103
- }).start();
103
+ });
104
+ anim.start();
105
+ return () => anim.stop();
104
106
  }, [hideOnScroll, isScrolling, hideAnim, theme.motion.duration.normal, theme.motion.easing.standard]);
105
107
  const hideTranslateY = hideAnim.interpolate({
106
108
  inputRange: [0, 1],
@@ -112,7 +114,8 @@ const FloatingActionButton = exports.FloatingActionButton = /*#__PURE__*/(0, _re
112
114
  });
113
115
  const handlePress = _event => {
114
116
  if (disabled) return;
115
- if (pressHaptic) (0, _hapticUtils.triggerHaptic)('impactLight');
117
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'impactLight');
118
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
116
119
  onPress();
117
120
  };
118
121
  const renderedIcon = icon;
@@ -181,7 +184,7 @@ const FloatingActionButton = exports.FloatingActionButton = /*#__PURE__*/(0, _re
181
184
  borderRadius: sizeStyles.diameter / 2
182
185
  }, theme.shadows.lg, {
183
186
  backgroundColor,
184
- opacity: disabled ? 0.7 : 1
187
+ opacity: disabled ? 0.55 : 1
185
188
  }],
186
189
  children: [renderedIcon, isExtended ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
187
190
  style: [styles.label, {
@@ -227,6 +230,7 @@ const FloatingActionButtonGroup = props => {
227
230
  bottomOffset,
228
231
  size = 'md',
229
232
  accessibilityLabel = 'Quick actions',
233
+ haptic,
230
234
  containerStyle,
231
235
  secondaryActionStyle,
232
236
  labelPillStyle,
@@ -242,7 +246,6 @@ const FloatingActionButtonGroup = props => {
242
246
  const defaultBottomOffset = fabTokens?.bottomOffset ?? 24;
243
247
  const secondaryGap = fabTokens?.secondaryGap ?? 16;
244
248
  const staggerMs = fabTokens?.staggerMs ?? 50;
245
- const pressHaptic = fabTokens?.pressHaptic ?? false;
246
249
  const isControlled = typeof controlledOpen === 'boolean';
247
250
  const [internalOpen, setInternalOpen] = (0, _react.useState)(defaultOpen);
248
251
  const isOpen = isControlled ? controlledOpen : internalOpen;
@@ -276,12 +279,13 @@ const FloatingActionButtonGroup = props => {
276
279
  // eslint-disable-next-line react-hooks/exhaustive-deps
277
280
  }, [actions.length]);
278
281
  (0, _react.useEffect)(() => {
279
- _reactNative.Animated.timing(progress, {
282
+ const progressAnim = _reactNative.Animated.timing(progress, {
280
283
  toValue: isOpen ? 1 : 0,
281
284
  duration: theme.motion.duration.normal,
282
285
  easing: _reactNative.Easing.bezier(...theme.motion.easing.standard),
283
286
  useNativeDriver: true
284
- }).start();
287
+ });
288
+ progressAnim.start();
285
289
  const animations = itemAnims.current.map(value => _reactNative.Animated.timing(value, {
286
290
  toValue: isOpen ? 1 : 0,
287
291
  duration: theme.motion.duration.normal,
@@ -290,23 +294,29 @@ const FloatingActionButtonGroup = props => {
290
294
  }));
291
295
  // Reverse stagger order on close so items closest to primary collapse last
292
296
  const ordered = isOpen ? animations : [...animations].reverse();
293
- _reactNative.Animated.stagger(staggerMs, ordered).start();
297
+ const staggerAnim = _reactNative.Animated.stagger(staggerMs, ordered);
298
+ staggerAnim.start();
299
+ return () => {
300
+ progressAnim.stop();
301
+ staggerAnim.stop();
302
+ };
294
303
  }, [isOpen, progress, theme.motion.duration.normal, theme.motion.easing.standard, actions.length, itemAnimsVersion, staggerMs]);
295
304
  const setOpen = (0, _react.useCallback)(next => {
296
- if (pressHaptic) (0, _hapticUtils.triggerHaptic)('impactLight');
305
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'impactLight');
306
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
297
307
  if (!isControlled) setInternalOpen(next);
298
308
  onOpenChange?.(next);
299
- }, [isControlled, onOpenChange, pressHaptic]);
309
+ }, [isControlled, onOpenChange, haptic]);
300
310
  const handlePrimaryPress = (0, _react.useCallback)(() => {
301
311
  setOpen(!isOpen);
302
312
  }, [isOpen, setOpen]);
303
313
  const handleActionPress = (0, _react.useCallback)(action => {
304
- if (pressHaptic) (0, _hapticUtils.triggerHaptic)('selection');
314
+ if (haptic !== false) (0, _hapticUtils.triggerHaptic)('selection');
305
315
  action.onPress();
306
316
  // Close after action runs
307
317
  if (!isControlled) setInternalOpen(false);
308
318
  onOpenChange?.(false);
309
- }, [isControlled, onOpenChange, pressHaptic]);
319
+ }, [isControlled, onOpenChange, haptic]);
310
320
  const handleBackdropPress = (0, _react.useCallback)(() => {
311
321
  if (isOpen) setOpen(false);
312
322
  }, [isOpen, setOpen]);