@webority-technologies/mobile 0.0.23 → 0.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/lib/commonjs/components/Accordion/Accordion.js +5 -5
  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/Banner/Banner.js +12 -2
  6. package/lib/commonjs/components/Card/Card.js +3 -3
  7. package/lib/commonjs/components/Checkbox/Checkbox.js +3 -2
  8. package/lib/commonjs/components/Chip/Chip.js +4 -2
  9. package/lib/commonjs/components/DatePicker/DatePicker.js +23 -18
  10. package/lib/commonjs/components/DateRangePicker/DateRangePicker.js +11 -9
  11. package/lib/commonjs/components/Dialog/Dialog.js +4 -2
  12. package/lib/commonjs/components/Drawer/Drawer.js +4 -2
  13. package/lib/commonjs/components/FloatingActionButton/FloatingActionButton.js +10 -8
  14. package/lib/commonjs/components/ImageGallery/ImageGallery.js +17 -15
  15. package/lib/commonjs/components/ListItem/ListItem.js +4 -3
  16. package/lib/commonjs/components/Modal/Modal.js +4 -3
  17. package/lib/commonjs/components/NumberInput/NumberInput.js +7 -5
  18. package/lib/commonjs/components/OTPInput/OTPInput.js +7 -7
  19. package/lib/commonjs/components/Radio/Radio.js +2 -3
  20. package/lib/commonjs/components/Rating/Rating.js +4 -3
  21. package/lib/commonjs/components/SearchBar/SearchBar.js +7 -4
  22. package/lib/commonjs/components/SegmentedControl/SegmentedControl.js +4 -3
  23. package/lib/commonjs/components/Select/Select.js +7 -4
  24. package/lib/commonjs/components/Slider/Slider.js +228 -228
  25. package/lib/commonjs/components/Stepper/Stepper.js +6 -5
  26. package/lib/commonjs/components/Swipeable/Swipeable.js +8 -9
  27. package/lib/commonjs/components/Tabs/Tabs.js +4 -3
  28. package/lib/commonjs/components/TimePicker/TimePicker.js +14 -9
  29. package/lib/commonjs/components/index.js +121 -114
  30. package/lib/commonjs/utils/hapticUtils.js +11 -1
  31. package/lib/commonjs/utils/index.js +6 -0
  32. package/lib/module/components/Accordion/Accordion.js +6 -6
  33. package/lib/module/components/AnimatePresence/AnimatePresence.js +63 -0
  34. package/lib/module/components/AnimatePresence/index.js +4 -0
  35. package/lib/module/components/AppBar/AppBar.js +10 -7
  36. package/lib/module/components/Banner/Banner.js +12 -2
  37. package/lib/module/components/Card/Card.js +4 -4
  38. package/lib/module/components/Checkbox/Checkbox.js +4 -3
  39. package/lib/module/components/Chip/Chip.js +5 -3
  40. package/lib/module/components/DatePicker/DatePicker.js +24 -19
  41. package/lib/module/components/DateRangePicker/DateRangePicker.js +12 -10
  42. package/lib/module/components/Dialog/Dialog.js +5 -3
  43. package/lib/module/components/Drawer/Drawer.js +5 -3
  44. package/lib/module/components/FloatingActionButton/FloatingActionButton.js +11 -9
  45. package/lib/module/components/ImageGallery/ImageGallery.js +18 -16
  46. package/lib/module/components/ListItem/ListItem.js +5 -4
  47. package/lib/module/components/Modal/Modal.js +5 -4
  48. package/lib/module/components/NumberInput/NumberInput.js +8 -6
  49. package/lib/module/components/OTPInput/OTPInput.js +8 -8
  50. package/lib/module/components/Radio/Radio.js +3 -4
  51. package/lib/module/components/Rating/Rating.js +5 -4
  52. package/lib/module/components/SearchBar/SearchBar.js +8 -5
  53. package/lib/module/components/SegmentedControl/SegmentedControl.js +5 -4
  54. package/lib/module/components/Select/Select.js +8 -5
  55. package/lib/module/components/Slider/Slider.js +231 -231
  56. package/lib/module/components/Stepper/Stepper.js +7 -6
  57. package/lib/module/components/Swipeable/Swipeable.js +9 -10
  58. package/lib/module/components/Tabs/Tabs.js +5 -4
  59. package/lib/module/components/TimePicker/TimePicker.js +15 -10
  60. package/lib/module/components/index.js +1 -0
  61. package/lib/module/utils/hapticUtils.js +9 -0
  62. package/lib/module/utils/index.js +1 -1
  63. package/lib/typescript/commonjs/components/Accordion/Accordion.d.ts +3 -0
  64. package/lib/typescript/commonjs/components/AnimatePresence/AnimatePresence.d.ts +30 -0
  65. package/lib/typescript/commonjs/components/AnimatePresence/index.d.ts +3 -0
  66. package/lib/typescript/commonjs/components/AppBar/AppBar.d.ts +6 -0
  67. package/lib/typescript/commonjs/components/Banner/Banner.d.ts +3 -0
  68. package/lib/typescript/commonjs/components/Card/Card.d.ts +3 -0
  69. package/lib/typescript/commonjs/components/Checkbox/Checkbox.d.ts +1 -0
  70. package/lib/typescript/commonjs/components/Chip/Chip.d.ts +3 -0
  71. package/lib/typescript/commonjs/components/DatePicker/DatePicker.d.ts +3 -0
  72. package/lib/typescript/commonjs/components/DateRangePicker/DateRangePicker.d.ts +6 -0
  73. package/lib/typescript/commonjs/components/Dialog/Dialog.d.ts +3 -0
  74. package/lib/typescript/commonjs/components/Drawer/Drawer.d.ts +3 -0
  75. package/lib/typescript/commonjs/components/FloatingActionButton/FloatingActionButton.d.ts +5 -0
  76. package/lib/typescript/commonjs/components/ImageGallery/ImageGallery.d.ts +6 -0
  77. package/lib/typescript/commonjs/components/ListItem/ListItem.d.ts +3 -0
  78. package/lib/typescript/commonjs/components/Modal/Modal.d.ts +6 -0
  79. package/lib/typescript/commonjs/components/NumberInput/NumberInput.d.ts +3 -0
  80. package/lib/typescript/commonjs/components/OTPInput/OTPInput.d.ts +6 -0
  81. package/lib/typescript/commonjs/components/Rating/Rating.d.ts +6 -0
  82. package/lib/typescript/commonjs/components/SearchBar/SearchBar.d.ts +3 -0
  83. package/lib/typescript/commonjs/components/SegmentedControl/SegmentedControl.d.ts +3 -0
  84. package/lib/typescript/commonjs/components/Select/Select.d.ts +6 -0
  85. package/lib/typescript/commonjs/components/Slider/Slider.d.ts +3 -0
  86. package/lib/typescript/commonjs/components/Stepper/Stepper.d.ts +6 -0
  87. package/lib/typescript/commonjs/components/Swipeable/Swipeable.d.ts +3 -0
  88. package/lib/typescript/commonjs/components/Tabs/Tabs.d.ts +3 -0
  89. package/lib/typescript/commonjs/components/TimePicker/TimePicker.d.ts +3 -0
  90. package/lib/typescript/commonjs/components/index.d.ts +2 -0
  91. package/lib/typescript/commonjs/theme/types.d.ts +2 -67
  92. package/lib/typescript/commonjs/utils/hapticUtils.d.ts +8 -0
  93. package/lib/typescript/commonjs/utils/index.d.ts +1 -1
  94. package/lib/typescript/module/components/Accordion/Accordion.d.ts +3 -0
  95. package/lib/typescript/module/components/AnimatePresence/AnimatePresence.d.ts +30 -0
  96. package/lib/typescript/module/components/AnimatePresence/index.d.ts +3 -0
  97. package/lib/typescript/module/components/AppBar/AppBar.d.ts +6 -0
  98. package/lib/typescript/module/components/Banner/Banner.d.ts +3 -0
  99. package/lib/typescript/module/components/Card/Card.d.ts +3 -0
  100. package/lib/typescript/module/components/Checkbox/Checkbox.d.ts +1 -0
  101. package/lib/typescript/module/components/Chip/Chip.d.ts +3 -0
  102. package/lib/typescript/module/components/DatePicker/DatePicker.d.ts +3 -0
  103. package/lib/typescript/module/components/DateRangePicker/DateRangePicker.d.ts +6 -0
  104. package/lib/typescript/module/components/Dialog/Dialog.d.ts +3 -0
  105. package/lib/typescript/module/components/Drawer/Drawer.d.ts +3 -0
  106. package/lib/typescript/module/components/FloatingActionButton/FloatingActionButton.d.ts +5 -0
  107. package/lib/typescript/module/components/ImageGallery/ImageGallery.d.ts +6 -0
  108. package/lib/typescript/module/components/ListItem/ListItem.d.ts +3 -0
  109. package/lib/typescript/module/components/Modal/Modal.d.ts +6 -0
  110. package/lib/typescript/module/components/NumberInput/NumberInput.d.ts +3 -0
  111. package/lib/typescript/module/components/OTPInput/OTPInput.d.ts +6 -0
  112. package/lib/typescript/module/components/Rating/Rating.d.ts +6 -0
  113. package/lib/typescript/module/components/SearchBar/SearchBar.d.ts +3 -0
  114. package/lib/typescript/module/components/SegmentedControl/SegmentedControl.d.ts +3 -0
  115. package/lib/typescript/module/components/Select/Select.d.ts +6 -0
  116. package/lib/typescript/module/components/Slider/Slider.d.ts +3 -0
  117. package/lib/typescript/module/components/Stepper/Stepper.d.ts +6 -0
  118. package/lib/typescript/module/components/Swipeable/Swipeable.d.ts +3 -0
  119. package/lib/typescript/module/components/Tabs/Tabs.d.ts +3 -0
  120. package/lib/typescript/module/components/TimePicker/TimePicker.d.ts +3 -0
  121. package/lib/typescript/module/components/index.d.ts +2 -0
  122. package/lib/typescript/module/theme/types.d.ts +2 -67
  123. package/lib/typescript/module/utils/hapticUtils.d.ts +8 -0
  124. package/lib/typescript/module/utils/index.d.ts +1 -1
  125. package/package.json +1 -1
@@ -51,6 +51,7 @@ const ImageGallery = ({
51
51
  enableLightbox = true,
52
52
  enablePinchZoom = true,
53
53
  onIndexChange,
54
+ haptic,
54
55
  loading = false,
55
56
  accessibilityLabel,
56
57
  containerStyle,
@@ -58,8 +59,6 @@ const ImageGallery = ({
58
59
  }) => {
59
60
  const theme = (0, _index3.useTheme)();
60
61
  const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
61
- const galleryTokens = theme.components.imageGallery;
62
- const pressHaptic = galleryTokens?.pressHaptic ?? false;
63
62
  const [currentIndex, setCurrentIndex] = (0, _react.useState)(clamp(initialIndex, 0, Math.max(0, images.length - 1)));
64
63
  const [lightboxOpen, setLightboxOpen] = (0, _react.useState)(false);
65
64
  const handleIndexChange = (0, _react.useCallback)(idx => {
@@ -68,13 +67,15 @@ const ImageGallery = ({
68
67
  }, [onIndexChange]);
69
68
  const openLightbox = (0, _react.useCallback)(() => {
70
69
  if (!enableLightbox) return;
71
- if (pressHaptic) (0, _index4.triggerHaptic)('selection');
70
+ const h = (0, _index4.resolveHaptic)(haptic, 'selection');
71
+ if (h) (0, _index4.triggerHaptic)(h);
72
72
  setLightboxOpen(true);
73
- }, [enableLightbox, pressHaptic]);
73
+ }, [enableLightbox, haptic]);
74
74
  const closeLightbox = (0, _react.useCallback)(() => {
75
- if (pressHaptic) (0, _index4.triggerHaptic)('selection');
75
+ const h = (0, _index4.resolveHaptic)(haptic, 'selection');
76
+ if (h) (0, _index4.triggerHaptic)(h);
76
77
  setLightboxOpen(false);
77
- }, [pressHaptic]);
78
+ }, [haptic]);
78
79
  const renderImage = (0, _react.useCallback)((image, idx) => {
79
80
  const a11y = image.alt ?? `Image ${idx + 1} of ${images.length}`;
80
81
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
@@ -128,7 +129,7 @@ const ImageGallery = ({
128
129
  showCounter: showCounter,
129
130
  onClose: closeLightbox,
130
131
  onIndexChange: handleIndexChange,
131
- pressHaptic: pressHaptic
132
+ haptic: haptic
132
133
  }) : null]
133
134
  });
134
135
  if (loading) {
@@ -218,7 +219,7 @@ const Lightbox = ({
218
219
  showCounter,
219
220
  onClose,
220
221
  onIndexChange,
221
- pressHaptic
222
+ haptic
222
223
  }) => {
223
224
  const theme = (0, _index3.useTheme)();
224
225
  const styles = (0, _react.useMemo)(() => buildLightboxStyles(theme), [theme]);
@@ -230,11 +231,12 @@ const Lightbox = ({
230
231
  const [activeIndex, setActiveIndex] = (0, _react.useState)(initialIndex);
231
232
  const handleSwipe = (0, _react.useCallback)(idx => {
232
233
  if (idx !== activeIndex) {
233
- if (pressHaptic) (0, _index4.triggerHaptic)('selection');
234
+ const h = (0, _index4.resolveHaptic)(haptic, 'selection');
235
+ if (h) (0, _index4.triggerHaptic)(h);
234
236
  setActiveIndex(idx);
235
237
  onIndexChange(idx);
236
238
  }
237
- }, [activeIndex, onIndexChange, pressHaptic]);
239
+ }, [activeIndex, onIndexChange, haptic]);
238
240
  const renderItem = (0, _react.useCallback)((image, idx) => /*#__PURE__*/(0, _jsxRuntime.jsx)(ZoomableImage, {
239
241
  image: image,
240
242
  index: idx,
@@ -244,8 +246,8 @@ const Lightbox = ({
244
246
  maxScale: maxScale,
245
247
  minScale: minScale,
246
248
  doubleTapScale: doubleTapScale,
247
- pressHaptic: pressHaptic
248
- }), [activeIndex, enablePinchZoom, images.length, maxScale, minScale, doubleTapScale, pressHaptic]);
249
+ haptic: haptic
250
+ }), [activeIndex, enablePinchZoom, images.length, maxScale, minScale, doubleTapScale, haptic]);
249
251
  const caption = images[activeIndex]?.caption;
250
252
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Modal, {
251
253
  visible: visible,
@@ -316,7 +318,7 @@ const ZoomableImage = ({
316
318
  maxScale,
317
319
  minScale,
318
320
  doubleTapScale,
319
- pressHaptic
321
+ haptic
320
322
  }) => {
321
323
  const screen = _reactNative.Dimensions.get('window');
322
324
  const scale = (0, _reactNativeReanimated.useSharedValue)(1);
@@ -352,8 +354,8 @@ const ZoomableImage = ({
352
354
  }
353
355
  }, [active, scale, translateX, translateY, savedScale, savedTranslateX, savedTranslateY]);
354
356
  const triggerImpact = (0, _react.useCallback)(() => {
355
- if (pressHaptic) (0, _index4.triggerHaptic)('impactLight');
356
- }, [pressHaptic]);
357
+ if (haptic !== false) (0, _index4.triggerHaptic)('impactLight');
358
+ }, [haptic]);
357
359
  const pinch = (0, _react.useMemo)(() => _reactNativeGestureHandler.Gesture.Pinch().enabled(enabled).onStart(() => {
358
360
  'worklet';
359
361
 
@@ -69,6 +69,7 @@ const ListItem = exports.ListItem = /*#__PURE__*/(0, _react.forwardRef)((props,
69
69
  left,
70
70
  right,
71
71
  onPress,
72
+ haptic,
72
73
  selected = false,
73
74
  disabled = false,
74
75
  size = 'md',
@@ -88,7 +89,6 @@ const ListItem = exports.ListItem = /*#__PURE__*/(0, _react.forwardRef)((props,
88
89
  testID
89
90
  } = props;
90
91
  const theme = (0, _index.useTheme)();
91
- const pressHaptic = theme.components.listItem?.pressHaptic ?? false;
92
92
  const sz = (0, _react.useMemo)(() => sizeFor(theme, size), [theme, size]);
93
93
  const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
94
94
  const isInteractive = !!onPress && !disabled;
@@ -101,7 +101,8 @@ const ListItem = exports.ListItem = /*#__PURE__*/(0, _react.forwardRef)((props,
101
101
  });
102
102
  const handlePress = event => {
103
103
  if (!isInteractive) return;
104
- if (pressHaptic) (0, _hapticUtils.triggerHaptic)('selection');
104
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
105
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
105
106
  onPress?.(event);
106
107
  };
107
108
  const a11yLabel = accessibilityLabel ?? title;
@@ -296,7 +297,7 @@ const buildStyles = theme => _reactNative.StyleSheet.create({
296
297
  backgroundColor: theme.colors.surface.pressed
297
298
  },
298
299
  disabled: {
299
- opacity: 0.6
300
+ opacity: 0.55
300
301
  },
301
302
  leftSlot: {
302
303
  marginRight: theme.spacing.md,
@@ -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;
@@ -131,9 +131,10 @@ const Modal = exports.Modal = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
131
131
  }, [visible, duration, restoreFocusRef]);
132
132
  const handleBackdropPress = (0, _react.useCallback)(() => {
133
133
  if (!backdropPressClose) return;
134
- if (backdropHaptic) (0, _hapticUtils.triggerHaptic)('selection');
134
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
135
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
135
136
  onRequestClose();
136
- }, [backdropPressClose, onRequestClose, backdropHaptic]);
137
+ }, [backdropPressClose, onRequestClose, haptic]);
137
138
  const handleHardwareBack = (0, _react.useCallback)(() => {
138
139
  if (hardwareBackPress) {
139
140
  onRequestClose();
@@ -63,6 +63,7 @@ const NumberInput = exports.NumberInput = /*#__PURE__*/(0, _react.forwardRef)((p
63
63
  size = 'md',
64
64
  variant = 'inline',
65
65
  unit,
66
+ haptic,
66
67
  accessibilityLabel,
67
68
  style,
68
69
  containerStyle,
@@ -86,7 +87,6 @@ const NumberInput = exports.NumberInput = /*#__PURE__*/(0, _react.forwardRef)((p
86
87
  const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
87
88
  const longPressDelay = theme.components.numberInput?.longPressDelayMs ?? DEFAULT_LONG_PRESS_DELAY;
88
89
  const longPressInterval = theme.components.numberInput?.longPressIntervalMs ?? DEFAULT_LONG_PRESS_INTERVAL;
89
- const pressHaptic = theme.components.numberInput?.pressHaptic ?? false;
90
90
  const inputRef = (0, _react.useRef)(null);
91
91
  const [draft, setDraft] = (0, _react.useState)(formatValue(current, allowDecimal, precision));
92
92
  const [editing, setEditing] = (0, _react.useState)(false);
@@ -121,14 +121,16 @@ const NumberInput = exports.NumberInput = /*#__PURE__*/(0, _react.forwardRef)((p
121
121
  }, [allowDecimal, max, min, setCurrent, precision, current]);
122
122
  const decrement = (0, _react.useCallback)(() => {
123
123
  if (!interactive || atMin) return;
124
- if (pressHaptic) (0, _index3.triggerHaptic)('impactLight');
124
+ const h = (0, _index3.resolveHaptic)(haptic, 'selection');
125
+ if (h) (0, _index3.triggerHaptic)(h);
125
126
  setExternal(current - step);
126
- }, [atMin, interactive, pressHaptic, setExternal, step, current]);
127
+ }, [atMin, interactive, haptic, setExternal, step, current]);
127
128
  const increment = (0, _react.useCallback)(() => {
128
129
  if (!interactive || atMax) return;
129
- if (pressHaptic) (0, _index3.triggerHaptic)('impactLight');
130
+ const h = (0, _index3.resolveHaptic)(haptic, 'selection');
131
+ if (h) (0, _index3.triggerHaptic)(h);
130
132
  setExternal(current + step);
131
- }, [atMax, interactive, pressHaptic, setExternal, step, current]);
133
+ }, [atMax, interactive, haptic, setExternal, step, current]);
132
134
  _react.default.useImperativeHandle(ref, () => ({
133
135
  focus: () => inputRef.current?.focus(),
134
136
  blur: () => inputRef.current?.blur(),
@@ -52,6 +52,7 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
52
52
  error,
53
53
  size = 'md',
54
54
  secure = false,
55
+ haptic,
55
56
  accessibilityLabel,
56
57
  style,
57
58
  cellStyle,
@@ -94,8 +95,6 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
94
95
  const previousFocusedIndexRef = (0, _react.useRef)(-1);
95
96
  const shakeOnError = theme.components.otpInput?.shakeOnError ?? false;
96
97
  const reduceMotion = (0, _index2.useReducedMotion)();
97
- const errorHaptic = theme.components.otpInput?.errorHaptic ?? false;
98
- const selectionHaptic = theme.components.otpInput?.selectionHaptic ?? false;
99
98
  const hasError = Boolean(error);
100
99
  const errorMessage = typeof error === 'string' ? error : undefined;
101
100
 
@@ -105,7 +104,7 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
105
104
  const isFirstRun = previousErrorRef.current === null;
106
105
  let anim;
107
106
  if (!isFirstRun && hasError && !previousErrorRef.current) {
108
- if (errorHaptic) (0, _index3.triggerHaptic)('notificationError');
107
+ if (haptic !== false) (0, _index3.triggerHaptic)('notificationError');
109
108
  if (shakeOnError && !reduceMotion) {
110
109
  (0, _index.setNativeValue)(shake, 0);
111
110
  anim = _reactNative.Animated.sequence([_reactNative.Animated.timing(shake, {
@@ -134,7 +133,7 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
134
133
  }
135
134
  previousErrorRef.current = hasError;
136
135
  return () => anim?.stop();
137
- }, [hasError, shake, shakeOnError, errorHaptic]);
136
+ }, [hasError, shake, shakeOnError, haptic]);
138
137
 
139
138
  // Animate underline opacity for the focused cell. Skip on first mount
140
139
  // (no prior focus state) — values are already at 0 and there's nothing to animate.
@@ -230,8 +229,9 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
230
229
  const next = chars.join('').slice(0, length);
231
230
  const previousLength = current.length;
232
231
  updateValue(next);
233
- if (next.length !== previousLength && selectionHaptic) {
234
- (0, _index3.triggerHaptic)('selection');
232
+ if (next.length !== previousLength) {
233
+ const h = (0, _index3.resolveHaptic)(haptic, 'selection');
234
+ if (h) (0, _index3.triggerHaptic)(h);
235
235
  }
236
236
 
237
237
  // Move focus to the next empty cell or last cell.
@@ -241,7 +241,7 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
241
241
  } else {
242
242
  focusCell(nextFocus);
243
243
  }
244
- }, [cells, focusCell, keyboardType, length, selectionHaptic, updateValue, current]);
244
+ }, [cells, focusCell, keyboardType, length, haptic, updateValue, current]);
245
245
  const handleKeyPress = (0, _react.useCallback)((index, e) => {
246
246
  const key = e.nativeEvent.key;
247
247
  if (key !== 'Backspace') return;
@@ -70,8 +70,6 @@ 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
75
  const anim = _reactNative.Animated.spring(progress, {
@@ -90,7 +88,8 @@ const Radio = exports.Radio = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
90
88
  });
91
89
  const handlePress = event => {
92
90
  if (disabled) return;
93
- if (resolvedHaptic !== false) (0, _hapticUtils.triggerHaptic)(resolvedHaptic);
91
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
92
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
94
93
  if (ctx) {
95
94
  ctx.onChange(value);
96
95
  } else {
@@ -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,
@@ -97,16 +98,18 @@ const SearchBar = exports.SearchBar = /*#__PURE__*/(0, _react.forwardRef)((props
97
98
  onChangeText(text);
98
99
  }, [debounceMs, onChangeText]);
99
100
  const handleClear = (0, _react.useCallback)(() => {
100
- (0, _hapticUtils.triggerHaptic)('selection');
101
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
102
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
101
103
  if (debounceMs !== undefined) {
102
104
  setInternalValue('');
103
105
  lastSentRef.current = '';
104
106
  }
105
107
  onChangeText('');
106
108
  onClear?.();
107
- }, [debounceMs, onChangeText, onClear]);
109
+ }, [haptic, debounceMs, onChangeText, onClear]);
108
110
  const handleCancel = (0, _react.useCallback)(() => {
109
- (0, _hapticUtils.triggerHaptic)('selection');
111
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
112
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
110
113
  if (debounceMs !== undefined) {
111
114
  setInternalValue('');
112
115
  lastSentRef.current = '';
@@ -114,7 +117,7 @@ const SearchBar = exports.SearchBar = /*#__PURE__*/(0, _react.forwardRef)((props
114
117
  onChangeText('');
115
118
  setIsFocused(false);
116
119
  onCancel?.();
117
- }, [debounceMs, onChangeText, onCancel]);
120
+ }, [haptic, debounceMs, onChangeText, onCancel]);
118
121
  const handleSubmit = (0, _react.useCallback)(() => {
119
122
  onSubmit?.(debounceMs !== undefined ? internalValue : value);
120
123
  }, [onSubmit, debounceMs, internalValue, value]);
@@ -42,6 +42,7 @@ const SegmentedControl = exports.SegmentedControl = /*#__PURE__*/(0, _react.forw
42
42
  fullWidth = true,
43
43
  disabled = false,
44
44
  tone = 'primary',
45
+ haptic,
45
46
  accessibilityLabel,
46
47
  style,
47
48
  containerStyle,
@@ -66,7 +67,6 @@ const SegmentedControl = exports.SegmentedControl = /*#__PURE__*/(0, _react.forw
66
67
  paddingHorizontal: segTheme?.[size]?.paddingHorizontal ?? baseSize.paddingHorizontal
67
68
  };
68
69
  const trackPadding = segTheme?.trackPadding ?? TRACK_PADDING;
69
- const changeHapticEnabled = segTheme?.changeHaptic ?? false;
70
70
 
71
71
  // Track width is measured from onLayout. Thumb width is a regular number (not
72
72
  // animated) — `width` cannot be driven by the native animated module, and mixing
@@ -107,9 +107,10 @@ const SegmentedControl = exports.SegmentedControl = /*#__PURE__*/(0, _react.forw
107
107
  const handlePress = (0, _react.useCallback)(segment => {
108
108
  if (disabled) return;
109
109
  if (segment.value === current) return;
110
- if (changeHapticEnabled) (0, _index2.triggerHaptic)('selection');
110
+ const h = (0, _index2.resolveHaptic)(haptic, 'selection');
111
+ if (h) (0, _index2.triggerHaptic)(h);
111
112
  setCurrent(segment.value);
112
- }, [disabled, setCurrent, current, changeHapticEnabled]);
113
+ }, [disabled, setCurrent, current, haptic]);
113
114
  const thumbBg = tone === 'primary' ? theme.colors.background.elevated : theme.colors.background.elevated;
114
115
  const activeTextColor = tone === 'primary' ? theme.colors.text.primary : theme.colors.text.primary;
115
116
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
@@ -32,6 +32,7 @@ const Select = exports.Select = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
32
32
  getOptionDescription,
33
33
  placeholder,
34
34
  searchable = false,
35
+ haptic,
35
36
  label,
36
37
  error,
37
38
  disabled = false,
@@ -119,9 +120,10 @@ const Select = exports.Select = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
119
120
  }, [searchable, query, options, labelOf, descriptionOf]);
120
121
  const handleOpen = (0, _react.useCallback)(() => {
121
122
  if (disabled) return;
122
- (0, _index2.triggerHaptic)('selection');
123
+ const h = (0, _index2.resolveHaptic)(haptic, 'selection');
124
+ if (h) (0, _index2.triggerHaptic)(h);
123
125
  setOpen(true);
124
- }, [disabled]);
126
+ }, [disabled, haptic]);
125
127
  const handleClose = (0, _react.useCallback)(() => {
126
128
  setOpen(false);
127
129
  setQuery('');
@@ -129,7 +131,8 @@ const Select = exports.Select = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
129
131
  const handleSelect = (0, _react.useCallback)(option => {
130
132
  if (disabledOf(option)) return;
131
133
  const optValue = valueOf(option);
132
- (0, _index2.triggerHaptic)('selection');
134
+ const h = (0, _index2.resolveHaptic)(haptic, 'selection');
135
+ if (h) (0, _index2.triggerHaptic)(h);
133
136
  if (multi) {
134
137
  const current = props.value ?? [];
135
138
  const next = current.includes(optValue) ? current.filter(v => v !== optValue) : [...current, optValue];
@@ -138,7 +141,7 @@ const Select = exports.Select = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
138
141
  }
139
142
  props.onChange(optValue);
140
143
  handleClose();
141
- }, [multi, props, handleClose, disabledOf, valueOf]);
144
+ }, [multi, props, handleClose, disabledOf, valueOf, haptic]);
142
145
 
143
146
  // Trigger label / placeholder text.
144
147
  const triggerText = selectedOptions.length === 0 ? placeholder ?? 'Select…' : selectedOptions.map(o => labelOf(o)).join(', ');