@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
@@ -96,7 +96,8 @@ const Accordion = props => {
96
96
  contentWrapperStyle,
97
97
  containerStyle,
98
98
  testID,
99
- loading = false
99
+ loading = false,
100
+ haptic
100
101
  } = props;
101
102
  const theme = (0, _index.useTheme)();
102
103
  const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
@@ -143,9 +144,8 @@ const Accordion = props => {
143
144
  }, [measuredHeight]);
144
145
  const handlePress = (0, _react.useCallback)(() => {
145
146
  if (disabled) return;
146
- if (theme.components.accordion?.pressHaptic ?? false) {
147
- (0, _hapticUtils.triggerHaptic)('selection');
148
- }
147
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
148
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
149
149
  if (group && id) {
150
150
  group.toggle(id);
151
151
  onChange?.(!expanded);
@@ -153,7 +153,7 @@ const Accordion = props => {
153
153
  }
154
154
  if (!isControlled) setInternalExpanded(!expanded);
155
155
  onChange?.(!expanded);
156
- }, [disabled, group, id, expanded, isControlled, onChange, theme.components.accordion]);
156
+ }, [disabled, group, id, expanded, isControlled, onChange, haptic]);
157
157
  const rotate = rotateAnim.interpolate({
158
158
  inputRange: [0, 1],
159
159
  outputRange: ['0deg', '180deg']
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.AnimatePresence = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
9
+ var _index = require("../../theme/index.js");
10
+ var _index2 = require("../../hooks/index.js");
11
+ var _jsxRuntime = require("react/jsx-runtime");
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); }
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
+ /**
15
+ * Animates a single child in on mount and out on unmount. Thin, theme-aware
16
+ * wrapper over Reanimated's `entering`/`exiting` — Reanimated keeps the view
17
+ * alive to play the exit, so the parent only toggles a condition. Honors the OS
18
+ * Reduce Motion setting (renders instantly when reduced).
19
+ *
20
+ * For animating items inside a list, use Reanimated's `itemLayoutAnimation`
21
+ * on `Animated.FlatList` instead — this wrapper targets single conditional nodes.
22
+ */
23
+ const AnimatePresence = ({
24
+ children,
25
+ preset = 'fade',
26
+ duration,
27
+ style,
28
+ testID
29
+ }) => {
30
+ const theme = (0, _index.useTheme)();
31
+ const reduceMotion = (0, _index2.useReducedMotion)();
32
+ const visible = children !== null && children !== undefined && children !== false;
33
+ if (!visible) return null;
34
+ const dur = duration ?? theme.motion.duration.normal;
35
+ let entering;
36
+ let exiting;
37
+ if (!reduceMotion) {
38
+ switch (preset) {
39
+ case 'scale':
40
+ entering = _reactNativeReanimated.ZoomIn.duration(dur);
41
+ exiting = _reactNativeReanimated.ZoomOut.duration(dur);
42
+ break;
43
+ case 'slide-up':
44
+ entering = _reactNativeReanimated.FadeInUp.duration(dur);
45
+ exiting = _reactNativeReanimated.FadeOutDown.duration(dur);
46
+ break;
47
+ case 'slide-down':
48
+ entering = _reactNativeReanimated.FadeInDown.duration(dur);
49
+ exiting = _reactNativeReanimated.FadeOutUp.duration(dur);
50
+ break;
51
+ case 'fade':
52
+ default:
53
+ entering = _reactNativeReanimated.FadeIn.duration(dur);
54
+ exiting = _reactNativeReanimated.FadeOut.duration(dur);
55
+ break;
56
+ }
57
+ }
58
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
59
+ entering: entering,
60
+ exiting: exiting,
61
+ style: style,
62
+ testID: testID,
63
+ children: children
64
+ });
65
+ };
66
+ exports.AnimatePresence = AnimatePresence;
67
+ AnimatePresence.displayName = 'AnimatePresence';
68
+ var _default = exports.default = AnimatePresence;
69
+ //# sourceMappingURL=AnimatePresence.js.map
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "AnimatePresence", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _AnimatePresence.AnimatePresence;
10
+ }
11
+ });
12
+ var _AnimatePresence = require("./AnimatePresence.js");
13
+ //# sourceMappingURL=index.js.map
@@ -41,7 +41,8 @@ const variantSize = (theme, variant) => {
41
41
  const ActionButton = ({
42
42
  action,
43
43
  side,
44
- badgeStyle
44
+ badgeStyle,
45
+ haptic
45
46
  }) => {
46
47
  const theme = (0, _index.useTheme)();
47
48
  const {
@@ -53,9 +54,8 @@ const ActionButton = ({
53
54
  });
54
55
  const styles = (0, _react.useMemo)(() => buildActionStyles(theme), [theme]);
55
56
  const onPress = () => {
56
- if (theme.components.appBar?.pressHaptic ?? false) {
57
- (0, _hapticUtils.triggerHaptic)('selection');
58
- }
57
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
58
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
59
59
  action.onPress();
60
60
  };
61
61
  const badgeValue = action.badge;
@@ -113,6 +113,7 @@ const AppBar = exports.AppBar = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
113
113
  titleStyle,
114
114
  subtitleStyle,
115
115
  badgeStyle,
116
+ haptic,
116
117
  testID
117
118
  } = props;
118
119
  const theme = (0, _index.useTheme)();
@@ -230,7 +231,8 @@ const AppBar = exports.AppBar = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
230
231
  style: styles.sideSlot,
231
232
  children: leftAction ? /*#__PURE__*/(0, _jsxRuntime.jsx)(ActionButton, {
232
233
  action: leftAction,
233
- side: "left"
234
+ side: "left",
235
+ haptic: haptic
234
236
  }) : null
235
237
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
236
238
  style: [styles.center, titleAlignment === 'center' ? styles.centerAligned : styles.centerLeft],
@@ -240,7 +242,8 @@ const AppBar = exports.AppBar = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
240
242
  children: rightActions?.map((action, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(ActionButton, {
241
243
  action: action,
242
244
  side: "right",
243
- badgeStyle: badgeStyle
245
+ badgeStyle: badgeStyle,
246
+ haptic: haptic
244
247
  }, `appbar-right-${index}`))
245
248
  })]
246
249
  })]
@@ -7,6 +7,7 @@ exports.default = exports.Banner = 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 _hapticUtils = require("../../utils/hapticUtils.js");
10
11
  var _index2 = require("../Skeleton/index.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); }
@@ -19,6 +20,7 @@ const Banner = exports.Banner = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
19
20
  actions,
20
21
  dismissible = false,
21
22
  onDismiss,
23
+ haptic,
22
24
  visible = true,
23
25
  animateMount = true,
24
26
  loading = false,
@@ -148,7 +150,11 @@ const Banner = exports.Banner = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
148
150
  }), dismissible ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
149
151
  accessibilityRole: "button",
150
152
  accessibilityLabel: "Dismiss banner",
151
- onPress: onDismiss,
153
+ onPress: () => {
154
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
155
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
156
+ onDismiss?.();
157
+ },
152
158
  hitSlop: 8,
153
159
  style: ({
154
160
  pressed
@@ -173,7 +179,11 @@ const Banner = exports.Banner = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
173
179
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
174
180
  accessibilityRole: "button",
175
181
  accessibilityLabel: action.label,
176
- onPress: action.onPress,
182
+ onPress: () => {
183
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
184
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
185
+ action.onPress();
186
+ },
177
187
  style: ({
178
188
  pressed
179
189
  }) => [styles.actionBtn, {
@@ -36,6 +36,7 @@ const Card = exports.Card = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =>
36
36
  loading = false,
37
37
  gradient,
38
38
  onPress,
39
+ haptic,
39
40
  accessibilityLabel,
40
41
  accessibilityHint,
41
42
  accessibilityRole,
@@ -155,9 +156,8 @@ const Card = exports.Card = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =>
155
156
  let rendered;
156
157
  if (isInteractive) {
157
158
  const handlePress = event => {
158
- if (theme.components.card?.pressHaptic ?? false) {
159
- (0, _hapticUtils.triggerHaptic)('selection');
160
- }
159
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
160
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
161
161
  onPress?.(event);
162
162
  };
163
163
  rendered = /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
@@ -40,7 +40,7 @@ const Checkbox = exports.Checkbox = /*#__PURE__*/(0, _react.forwardRef)((props,
40
40
  size = 'md',
41
41
  tone = 'primary',
42
42
  accessibilityLabel,
43
- haptic = 'selection',
43
+ haptic,
44
44
  style,
45
45
  boxStyle,
46
46
  checkIconStyle,
@@ -80,7 +80,8 @@ const Checkbox = exports.Checkbox = /*#__PURE__*/(0, _react.forwardRef)((props,
80
80
  });
81
81
  const handlePress = event => {
82
82
  if (disabled) return;
83
- if (haptic !== false && theme.components.checkbox?.pressHaptic) (0, _hapticUtils.triggerHaptic)(haptic);
83
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'selection');
84
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
84
85
  setCurrent(!current);
85
86
  rest.onPressOut?.(event);
86
87
  };
@@ -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;
@@ -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,
@@ -235,7 +236,7 @@ const DatePicker = props => {
235
236
  return false;
236
237
  }, [minDay, maxDay]);
237
238
  const animateMonthChange = (0, _react.useCallback)(delta => {
238
- if (theme.components.datePicker?.haptic) (0, _index2.triggerHaptic)('impactLight');
239
+ if (haptic !== false) (0, _index2.triggerHaptic)('impactLight');
239
240
  const direction = delta > 0 ? 1 : -1;
240
241
  const distance = theme.components.datePicker?.monthSlideDistance ?? 32;
241
242
  const outDuration = theme.components.datePicker?.monthSlideOutDuration ?? theme.motion.duration.fast ?? 140;
@@ -266,31 +267,31 @@ const DatePicker = props => {
266
267
  const next = addMonths(anchor, delta);
267
268
  setAnchor(next);
268
269
  _reactNative.AccessibilityInfo.announceForAccessibility(formatMonthYear(next, locale));
269
- }, [anchor, locale, monthFade, monthSlide, theme.components.datePicker, theme.motion.duration.fast]);
270
+ }, [anchor, haptic, locale, monthFade, monthSlide, theme.components.datePicker, theme.motion.duration.fast]);
270
271
  const goPrev = (0, _react.useCallback)(() => {
271
272
  if (viewMode === 'days') {
272
273
  animateMonthChange(-1);
273
274
  return;
274
275
  }
275
- if (theme.components.datePicker?.haptic) (0, _index2.triggerHaptic)('impactLight');
276
+ if (haptic !== false) (0, _index2.triggerHaptic)('impactLight');
276
277
  if (viewMode === 'years') {
277
278
  setAnchor(prev => new Date(prev.getFullYear() - GRID_SIZE, prev.getMonth(), 1));
278
279
  } else {
279
280
  setAnchor(prev => new Date(prev.getFullYear() - GRID_SIZE * DECADE_SPAN, prev.getMonth(), 1));
280
281
  }
281
- }, [animateMonthChange, viewMode, theme.components.datePicker]);
282
+ }, [animateMonthChange, viewMode, haptic]);
282
283
  const goNext = (0, _react.useCallback)(() => {
283
284
  if (viewMode === 'days') {
284
285
  animateMonthChange(1);
285
286
  return;
286
287
  }
287
- if (theme.components.datePicker?.haptic) (0, _index2.triggerHaptic)('impactLight');
288
+ if (haptic !== false) (0, _index2.triggerHaptic)('impactLight');
288
289
  if (viewMode === 'years') {
289
290
  setAnchor(prev => new Date(prev.getFullYear() + GRID_SIZE, prev.getMonth(), 1));
290
291
  } else {
291
292
  setAnchor(prev => new Date(prev.getFullYear() + GRID_SIZE * DECADE_SPAN, prev.getMonth(), 1));
292
293
  }
293
- }, [animateMonthChange, viewMode, theme.components.datePicker]);
294
+ }, [animateMonthChange, viewMode, haptic]);
294
295
 
295
296
  // View-mode transition: fade + scale, native driver.
296
297
  const animateViewTransition = (0, _react.useCallback)(() => {
@@ -310,7 +311,8 @@ const DatePicker = props => {
310
311
  })]).start();
311
312
  }, [viewFade, viewScale, theme.components.datePicker, theme.motion.duration.normal]);
312
313
  const cycleViewMode = (0, _react.useCallback)(() => {
313
- if (theme.components.datePicker?.haptic) (0, _index2.triggerHaptic)('selection');
314
+ const h = (0, _index2.resolveHaptic)(haptic, 'selection');
315
+ if (h) (0, _index2.triggerHaptic)(h);
314
316
  const pressDur = theme.components.datePicker?.headerPressDuration ?? 80;
315
317
  const releaseDur = theme.components.datePicker?.headerReleaseDuration ?? 100;
316
318
  _reactNative.Animated.sequence([_reactNative.Animated.timing(headerScale, {
@@ -328,23 +330,26 @@ const DatePicker = props => {
328
330
  return 'years';
329
331
  });
330
332
  animateViewTransition();
331
- }, [animateViewTransition, headerScale, theme.components.datePicker]);
333
+ }, [animateViewTransition, headerScale, haptic, theme.components.datePicker]);
332
334
  const pickYear = (0, _react.useCallback)(year => {
333
- if (theme.components.datePicker?.haptic) (0, _index2.triggerHaptic)('selection');
335
+ const h = (0, _index2.resolveHaptic)(haptic, 'selection');
336
+ if (h) (0, _index2.triggerHaptic)(h);
334
337
  setAnchor(prev => new Date(year, prev.getMonth(), 1));
335
338
  setViewMode('days');
336
339
  animateViewTransition();
337
- }, [animateViewTransition, theme.components.datePicker]);
340
+ }, [animateViewTransition, haptic]);
338
341
  const pickDecade = (0, _react.useCallback)(decadeStart => {
339
- if (theme.components.datePicker?.haptic) (0, _index2.triggerHaptic)('selection');
342
+ const h = (0, _index2.resolveHaptic)(haptic, 'selection');
343
+ if (h) (0, _index2.triggerHaptic)(h);
340
344
  // Anchor mid-decade so the year grid centers nicely on this decade.
341
345
  setAnchor(prev => new Date(decadeStart + 4, prev.getMonth(), 1));
342
346
  setViewMode('years');
343
347
  animateViewTransition();
344
- }, [animateViewTransition, theme.components.datePicker]);
348
+ }, [animateViewTransition, haptic]);
345
349
  const pressDay = (0, _react.useCallback)(cell => {
346
350
  if (isDisabled(cell.date)) return;
347
- if (theme.components.datePicker?.haptic) (0, _index2.triggerHaptic)('selection');
351
+ const h = (0, _index2.resolveHaptic)(haptic, 'selection');
352
+ if (h) (0, _index2.triggerHaptic)(h);
348
353
  setPendingDate(cell.date);
349
354
  if (!cell.inMonth) {
350
355
  setAnchor(new Date(cell.date.getFullYear(), cell.date.getMonth(), 1));
@@ -357,7 +362,7 @@ const DatePicker = props => {
357
362
  mass: theme.motion.spring.bouncy.mass,
358
363
  useNativeDriver: true
359
364
  }).start();
360
- }, [isDisabled, selectScale, theme.motion.spring.bouncy, theme.components.datePicker]);
365
+ }, [isDisabled, selectScale, theme.motion.spring.bouncy, haptic]);
361
366
  const finalizeClose = (0, _react.useCallback)(() => {
362
367
  if (isControlled) {
363
368
  onClose?.();
@@ -386,15 +391,15 @@ const DatePicker = props => {
386
391
  });
387
392
  }, [backdrop, mode, finalizeClose, sheet, theme.motion.duration.fast]);
388
393
  const handleCancel = (0, _react.useCallback)(() => {
389
- if (theme.components.datePicker?.haptic) (0, _index2.triggerHaptic)('selection');
394
+ if (haptic !== false) (0, _index2.triggerHaptic)('selection');
390
395
  handleClose();
391
- }, [handleClose, theme.components.datePicker]);
396
+ }, [handleClose, haptic]);
392
397
  const handleConfirm = (0, _react.useCallback)(() => {
393
398
  if (!pendingDate) return;
394
- if (theme.components.datePicker?.haptic) (0, _index2.triggerHaptic)('notificationSuccess');
399
+ if (haptic !== false) (0, _index2.triggerHaptic)('notificationSuccess');
395
400
  onChange?.(pendingDate);
396
401
  handleClose();
397
- }, [handleClose, onChange, pendingDate, theme.components.datePicker]);
402
+ }, [handleClose, onChange, pendingDate, haptic]);
398
403
  const sheetTranslate = sheet.interpolate({
399
404
  inputRange: [0, 1],
400
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,
@@ -189,7 +190,7 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/(0, _react.forwar
189
190
  const headerLabel = (0, _react.useMemo)(() => formatMonthYear(anchor, locale), [anchor, locale]);
190
191
  const weekdays = (0, _react.useMemo)(() => weekdayLabels(locale, weekStartsOn), [locale, weekStartsOn]);
191
192
  const animateMonthChange = (0, _react.useCallback)(delta => {
192
- if (theme.components.dateRangePicker?.haptic) (0, _index2.triggerHaptic)('impactLight');
193
+ if (haptic !== false) (0, _index2.triggerHaptic)('impactLight');
193
194
  const direction = delta > 0 ? 1 : -1;
194
195
  const distance = theme.components.dateRangePicker?.monthSlideDistance ?? 32;
195
196
  const outDuration = theme.components.dateRangePicker?.monthSlideOutDuration ?? theme.motion.duration.fast ?? 140;
@@ -220,12 +221,13 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/(0, _react.forwar
220
221
  const next = addMonths(anchor, delta);
221
222
  setAnchor(next);
222
223
  _reactNative.AccessibilityInfo.announceForAccessibility(formatMonthYear(next, locale));
223
- }, [anchor, locale, monthFade, monthSlide, theme.components.dateRangePicker, theme.motion.duration.fast]);
224
+ }, [anchor, haptic, locale, monthFade, monthSlide, theme.components.dateRangePicker, theme.motion.duration.fast]);
224
225
  const goPrev = (0, _react.useCallback)(() => animateMonthChange(-1), [animateMonthChange]);
225
226
  const goNext = (0, _react.useCallback)(() => animateMonthChange(1), [animateMonthChange]);
226
227
  const pressDay = (0, _react.useCallback)(cell => {
227
228
  if (isDisabled(cell.date)) return;
228
- if (theme.components.dateRangePicker?.haptic) (0, _index2.triggerHaptic)('selection');
229
+ const h = (0, _index2.resolveHaptic)(haptic, 'selection');
230
+ if (h) (0, _index2.triggerHaptic)(h);
229
231
  const target = cell.date;
230
232
 
231
233
  // First tap: pick start. Or, when there's already a complete range, restart.
@@ -244,7 +246,7 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/(0, _react.forwar
244
246
  } else {
245
247
  if (maxRange && daysBetween(pendingStart, target) + 1 > maxRange) {
246
248
  // Reject ranges longer than maxRange — restart from the new tap.
247
- if (theme.components.dateRangePicker?.haptic) (0, _index2.triggerHaptic)('notificationWarning');
249
+ if (haptic !== false) (0, _index2.triggerHaptic)('notificationWarning');
248
250
  setPendingStart(target);
249
251
  setPendingEnd(null);
250
252
  return;
@@ -255,7 +257,7 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/(0, _react.forwar
255
257
  if (!cell.inMonth) {
256
258
  setAnchor(new Date(cell.date.getFullYear(), cell.date.getMonth(), 1));
257
259
  }
258
- }, [isDisabled, pendingStart, pendingEnd, maxRange, theme.components.dateRangePicker]);
260
+ }, [isDisabled, pendingStart, pendingEnd, maxRange, haptic]);
259
261
  const handleCloseModal = (0, _react.useCallback)(() => {
260
262
  if (isControlled) {
261
263
  onClose?.();
@@ -279,18 +281,18 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/(0, _react.forwar
279
281
  });
280
282
  }, [backdrop, handleCloseModal, sheet, theme.motion.duration.fast]);
281
283
  const handleCancel = (0, _react.useCallback)(() => {
282
- if (theme.components.dateRangePicker?.haptic) (0, _index2.triggerHaptic)('selection');
284
+ if (haptic !== false) (0, _index2.triggerHaptic)('selection');
283
285
  handleClose();
284
- }, [handleClose, theme.components.dateRangePicker]);
286
+ }, [handleClose, haptic]);
285
287
  const handleConfirm = (0, _react.useCallback)(() => {
286
288
  if (!pendingStart || !pendingEnd) return;
287
- if (theme.components.dateRangePicker?.haptic) (0, _index2.triggerHaptic)('notificationSuccess');
289
+ if (haptic !== false) (0, _index2.triggerHaptic)('notificationSuccess');
288
290
  onChange?.({
289
291
  start: pendingStart,
290
292
  end: pendingEnd
291
293
  });
292
294
  handleClose();
293
- }, [handleClose, onChange, pendingStart, pendingEnd, theme.components.dateRangePicker]);
295
+ }, [handleClose, onChange, pendingStart, pendingEnd, haptic]);
294
296
  const sheetTranslate = sheet.interpolate({
295
297
  inputRange: [0, 1],
296
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,
@@ -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.
@@ -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,7 +89,6 @@ 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) {
@@ -114,7 +114,8 @@ const FloatingActionButton = exports.FloatingActionButton = /*#__PURE__*/(0, _re
114
114
  });
115
115
  const handlePress = _event => {
116
116
  if (disabled) return;
117
- if (pressHaptic) (0, _hapticUtils.triggerHaptic)('impactLight');
117
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'impactLight');
118
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
118
119
  onPress();
119
120
  };
120
121
  const renderedIcon = icon;
@@ -183,7 +184,7 @@ const FloatingActionButton = exports.FloatingActionButton = /*#__PURE__*/(0, _re
183
184
  borderRadius: sizeStyles.diameter / 2
184
185
  }, theme.shadows.lg, {
185
186
  backgroundColor,
186
- opacity: disabled ? 0.7 : 1
187
+ opacity: disabled ? 0.55 : 1
187
188
  }],
188
189
  children: [renderedIcon, isExtended ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
189
190
  style: [styles.label, {
@@ -229,6 +230,7 @@ const FloatingActionButtonGroup = props => {
229
230
  bottomOffset,
230
231
  size = 'md',
231
232
  accessibilityLabel = 'Quick actions',
233
+ haptic,
232
234
  containerStyle,
233
235
  secondaryActionStyle,
234
236
  labelPillStyle,
@@ -244,7 +246,6 @@ const FloatingActionButtonGroup = props => {
244
246
  const defaultBottomOffset = fabTokens?.bottomOffset ?? 24;
245
247
  const secondaryGap = fabTokens?.secondaryGap ?? 16;
246
248
  const staggerMs = fabTokens?.staggerMs ?? 50;
247
- const pressHaptic = fabTokens?.pressHaptic ?? false;
248
249
  const isControlled = typeof controlledOpen === 'boolean';
249
250
  const [internalOpen, setInternalOpen] = (0, _react.useState)(defaultOpen);
250
251
  const isOpen = isControlled ? controlledOpen : internalOpen;
@@ -301,20 +302,21 @@ const FloatingActionButtonGroup = props => {
301
302
  };
302
303
  }, [isOpen, progress, theme.motion.duration.normal, theme.motion.easing.standard, actions.length, itemAnimsVersion, staggerMs]);
303
304
  const setOpen = (0, _react.useCallback)(next => {
304
- if (pressHaptic) (0, _hapticUtils.triggerHaptic)('impactLight');
305
+ const h = (0, _hapticUtils.resolveHaptic)(haptic, 'impactLight');
306
+ if (h) (0, _hapticUtils.triggerHaptic)(h);
305
307
  if (!isControlled) setInternalOpen(next);
306
308
  onOpenChange?.(next);
307
- }, [isControlled, onOpenChange, pressHaptic]);
309
+ }, [isControlled, onOpenChange, haptic]);
308
310
  const handlePrimaryPress = (0, _react.useCallback)(() => {
309
311
  setOpen(!isOpen);
310
312
  }, [isOpen, setOpen]);
311
313
  const handleActionPress = (0, _react.useCallback)(action => {
312
- if (pressHaptic) (0, _hapticUtils.triggerHaptic)('selection');
314
+ if (haptic !== false) (0, _hapticUtils.triggerHaptic)('selection');
313
315
  action.onPress();
314
316
  // Close after action runs
315
317
  if (!isControlled) setInternalOpen(false);
316
318
  onOpenChange?.(false);
317
- }, [isControlled, onOpenChange, pressHaptic]);
319
+ }, [isControlled, onOpenChange, haptic]);
318
320
  const handleBackdropPress = (0, _react.useCallback)(() => {
319
321
  if (isOpen) setOpen(false);
320
322
  }, [isOpen, setOpen]);