@webority-technologies/mobile 0.0.23 → 0.0.25

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 (171) 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/Autocomplete/Autocomplete.js +204 -0
  6. package/lib/commonjs/components/Autocomplete/index.js +13 -0
  7. package/lib/commonjs/components/Banner/Banner.js +12 -2
  8. package/lib/commonjs/components/BottomNavigation/BottomNavigation.js +1 -1
  9. package/lib/commonjs/components/Card/Card.js +3 -3
  10. package/lib/commonjs/components/Checkbox/Checkbox.js +3 -2
  11. package/lib/commonjs/components/Chip/Chip.js +4 -2
  12. package/lib/commonjs/components/Confetti/Confetti.js +170 -0
  13. package/lib/commonjs/components/Confetti/index.js +13 -0
  14. package/lib/commonjs/components/DatePicker/DatePicker.js +23 -18
  15. package/lib/commonjs/components/DateRangePicker/DateRangePicker.js +11 -9
  16. package/lib/commonjs/components/Dialog/Dialog.js +4 -2
  17. package/lib/commonjs/components/Drawer/Drawer.js +4 -2
  18. package/lib/commonjs/components/FieldBase/FieldBase.js +0 -2
  19. package/lib/commonjs/components/FloatingActionButton/FloatingActionButton.js +10 -8
  20. package/lib/commonjs/components/IconButton/IconButton.js +176 -0
  21. package/lib/commonjs/components/IconButton/index.js +13 -0
  22. package/lib/commonjs/components/ImageGallery/ImageGallery.js +17 -15
  23. package/lib/commonjs/components/ListItem/ListItem.js +4 -3
  24. package/lib/commonjs/components/Modal/Modal.js +4 -4
  25. package/lib/commonjs/components/NumberInput/NumberInput.js +7 -5
  26. package/lib/commonjs/components/OTPInput/OTPInput.js +7 -7
  27. package/lib/commonjs/components/ProgressBar/ProgressBar.js +32 -4
  28. package/lib/commonjs/components/Radio/Radio.js +2 -3
  29. package/lib/commonjs/components/Rating/Rating.js +4 -3
  30. package/lib/commonjs/components/SearchBar/SearchBar.js +7 -4
  31. package/lib/commonjs/components/SegmentedControl/SegmentedControl.js +4 -3
  32. package/lib/commonjs/components/Select/Select.js +7 -4
  33. package/lib/commonjs/components/SlideToConfirm/SlideToConfirm.js +224 -0
  34. package/lib/commonjs/components/SlideToConfirm/index.js +13 -0
  35. package/lib/commonjs/components/Slider/Slider.js +228 -228
  36. package/lib/commonjs/components/Stepper/Stepper.js +6 -5
  37. package/lib/commonjs/components/Swipeable/Swipeable.js +8 -9
  38. package/lib/commonjs/components/Tabs/Tabs.js +4 -3
  39. package/lib/commonjs/components/TimePicker/TimePicker.js +14 -9
  40. package/lib/commonjs/components/index.js +149 -114
  41. package/lib/commonjs/hooks/usePressAnimation.js +0 -1
  42. package/lib/commonjs/utils/hapticUtils.js +11 -1
  43. package/lib/commonjs/utils/index.js +6 -0
  44. package/lib/module/components/Accordion/Accordion.js +6 -6
  45. package/lib/module/components/AnimatePresence/AnimatePresence.js +63 -0
  46. package/lib/module/components/AnimatePresence/index.js +4 -0
  47. package/lib/module/components/AppBar/AppBar.js +10 -7
  48. package/lib/module/components/Autocomplete/Autocomplete.js +199 -0
  49. package/lib/module/components/Autocomplete/index.js +4 -0
  50. package/lib/module/components/Banner/Banner.js +12 -2
  51. package/lib/module/components/BottomNavigation/BottomNavigation.js +1 -1
  52. package/lib/module/components/Card/Card.js +4 -4
  53. package/lib/module/components/Checkbox/Checkbox.js +4 -3
  54. package/lib/module/components/Chip/Chip.js +5 -3
  55. package/lib/module/components/Confetti/Confetti.js +166 -0
  56. package/lib/module/components/Confetti/index.js +4 -0
  57. package/lib/module/components/DatePicker/DatePicker.js +24 -19
  58. package/lib/module/components/DateRangePicker/DateRangePicker.js +12 -10
  59. package/lib/module/components/Dialog/Dialog.js +5 -3
  60. package/lib/module/components/Drawer/Drawer.js +5 -3
  61. package/lib/module/components/FieldBase/FieldBase.js +0 -2
  62. package/lib/module/components/FloatingActionButton/FloatingActionButton.js +11 -9
  63. package/lib/module/components/IconButton/IconButton.js +172 -0
  64. package/lib/module/components/IconButton/index.js +4 -0
  65. package/lib/module/components/ImageGallery/ImageGallery.js +18 -16
  66. package/lib/module/components/ListItem/ListItem.js +5 -4
  67. package/lib/module/components/Modal/Modal.js +5 -5
  68. package/lib/module/components/NumberInput/NumberInput.js +8 -6
  69. package/lib/module/components/OTPInput/OTPInput.js +8 -8
  70. package/lib/module/components/ProgressBar/ProgressBar.js +33 -5
  71. package/lib/module/components/Radio/Radio.js +3 -4
  72. package/lib/module/components/Rating/Rating.js +5 -4
  73. package/lib/module/components/SearchBar/SearchBar.js +8 -5
  74. package/lib/module/components/SegmentedControl/SegmentedControl.js +5 -4
  75. package/lib/module/components/Select/Select.js +8 -5
  76. package/lib/module/components/SlideToConfirm/SlideToConfirm.js +220 -0
  77. package/lib/module/components/SlideToConfirm/index.js +4 -0
  78. package/lib/module/components/Slider/Slider.js +231 -231
  79. package/lib/module/components/Stepper/Stepper.js +7 -6
  80. package/lib/module/components/Swipeable/Swipeable.js +9 -10
  81. package/lib/module/components/Tabs/Tabs.js +5 -4
  82. package/lib/module/components/TimePicker/TimePicker.js +15 -10
  83. package/lib/module/components/index.js +5 -0
  84. package/lib/module/hooks/usePressAnimation.js +0 -1
  85. package/lib/module/utils/hapticUtils.js +9 -0
  86. package/lib/module/utils/index.js +1 -1
  87. package/lib/typescript/commonjs/components/Accordion/Accordion.d.ts +3 -0
  88. package/lib/typescript/commonjs/components/AnimatePresence/AnimatePresence.d.ts +30 -0
  89. package/lib/typescript/commonjs/components/AnimatePresence/index.d.ts +3 -0
  90. package/lib/typescript/commonjs/components/AppBar/AppBar.d.ts +6 -0
  91. package/lib/typescript/commonjs/components/Autocomplete/Autocomplete.d.ts +53 -0
  92. package/lib/typescript/commonjs/components/Autocomplete/index.d.ts +3 -0
  93. package/lib/typescript/commonjs/components/Banner/Banner.d.ts +3 -0
  94. package/lib/typescript/commonjs/components/Card/Card.d.ts +3 -0
  95. package/lib/typescript/commonjs/components/Checkbox/Checkbox.d.ts +1 -0
  96. package/lib/typescript/commonjs/components/Chip/Chip.d.ts +3 -0
  97. package/lib/typescript/commonjs/components/Confetti/Confetti.d.ts +41 -0
  98. package/lib/typescript/commonjs/components/Confetti/index.d.ts +3 -0
  99. package/lib/typescript/commonjs/components/DatePicker/DatePicker.d.ts +3 -0
  100. package/lib/typescript/commonjs/components/DateRangePicker/DateRangePicker.d.ts +6 -0
  101. package/lib/typescript/commonjs/components/Dialog/Dialog.d.ts +3 -0
  102. package/lib/typescript/commonjs/components/Drawer/Drawer.d.ts +3 -0
  103. package/lib/typescript/commonjs/components/FloatingActionButton/FloatingActionButton.d.ts +5 -0
  104. package/lib/typescript/commonjs/components/IconButton/IconButton.d.ts +34 -0
  105. package/lib/typescript/commonjs/components/IconButton/index.d.ts +3 -0
  106. package/lib/typescript/commonjs/components/ImageGallery/ImageGallery.d.ts +6 -0
  107. package/lib/typescript/commonjs/components/ListItem/ListItem.d.ts +3 -0
  108. package/lib/typescript/commonjs/components/Modal/Modal.d.ts +6 -0
  109. package/lib/typescript/commonjs/components/NumberInput/NumberInput.d.ts +3 -0
  110. package/lib/typescript/commonjs/components/OTPInput/OTPInput.d.ts +6 -0
  111. package/lib/typescript/commonjs/components/ProgressBar/ProgressBar.d.ts +12 -0
  112. package/lib/typescript/commonjs/components/ProgressBar/index.d.ts +1 -1
  113. package/lib/typescript/commonjs/components/Rating/Rating.d.ts +6 -0
  114. package/lib/typescript/commonjs/components/SearchBar/SearchBar.d.ts +3 -0
  115. package/lib/typescript/commonjs/components/SegmentedControl/SegmentedControl.d.ts +3 -0
  116. package/lib/typescript/commonjs/components/Select/Select.d.ts +6 -0
  117. package/lib/typescript/commonjs/components/SlideToConfirm/SlideToConfirm.d.ts +34 -0
  118. package/lib/typescript/commonjs/components/SlideToConfirm/index.d.ts +3 -0
  119. package/lib/typescript/commonjs/components/Slider/Slider.d.ts +3 -0
  120. package/lib/typescript/commonjs/components/Stepper/Stepper.d.ts +6 -0
  121. package/lib/typescript/commonjs/components/Swipeable/Swipeable.d.ts +3 -0
  122. package/lib/typescript/commonjs/components/Tabs/Tabs.d.ts +3 -0
  123. package/lib/typescript/commonjs/components/TimePicker/TimePicker.d.ts +3 -0
  124. package/lib/typescript/commonjs/components/index.d.ts +11 -1
  125. package/lib/typescript/commonjs/hooks/usePressAnimation.d.ts +1 -2
  126. package/lib/typescript/commonjs/theme/types.d.ts +2 -67
  127. package/lib/typescript/commonjs/utils/hapticUtils.d.ts +8 -0
  128. package/lib/typescript/commonjs/utils/index.d.ts +1 -1
  129. package/lib/typescript/module/components/Accordion/Accordion.d.ts +3 -0
  130. package/lib/typescript/module/components/AnimatePresence/AnimatePresence.d.ts +30 -0
  131. package/lib/typescript/module/components/AnimatePresence/index.d.ts +3 -0
  132. package/lib/typescript/module/components/AppBar/AppBar.d.ts +6 -0
  133. package/lib/typescript/module/components/Autocomplete/Autocomplete.d.ts +53 -0
  134. package/lib/typescript/module/components/Autocomplete/index.d.ts +3 -0
  135. package/lib/typescript/module/components/Banner/Banner.d.ts +3 -0
  136. package/lib/typescript/module/components/Card/Card.d.ts +3 -0
  137. package/lib/typescript/module/components/Checkbox/Checkbox.d.ts +1 -0
  138. package/lib/typescript/module/components/Chip/Chip.d.ts +3 -0
  139. package/lib/typescript/module/components/Confetti/Confetti.d.ts +41 -0
  140. package/lib/typescript/module/components/Confetti/index.d.ts +3 -0
  141. package/lib/typescript/module/components/DatePicker/DatePicker.d.ts +3 -0
  142. package/lib/typescript/module/components/DateRangePicker/DateRangePicker.d.ts +6 -0
  143. package/lib/typescript/module/components/Dialog/Dialog.d.ts +3 -0
  144. package/lib/typescript/module/components/Drawer/Drawer.d.ts +3 -0
  145. package/lib/typescript/module/components/FloatingActionButton/FloatingActionButton.d.ts +5 -0
  146. package/lib/typescript/module/components/IconButton/IconButton.d.ts +34 -0
  147. package/lib/typescript/module/components/IconButton/index.d.ts +3 -0
  148. package/lib/typescript/module/components/ImageGallery/ImageGallery.d.ts +6 -0
  149. package/lib/typescript/module/components/ListItem/ListItem.d.ts +3 -0
  150. package/lib/typescript/module/components/Modal/Modal.d.ts +6 -0
  151. package/lib/typescript/module/components/NumberInput/NumberInput.d.ts +3 -0
  152. package/lib/typescript/module/components/OTPInput/OTPInput.d.ts +6 -0
  153. package/lib/typescript/module/components/ProgressBar/ProgressBar.d.ts +12 -0
  154. package/lib/typescript/module/components/ProgressBar/index.d.ts +1 -1
  155. package/lib/typescript/module/components/Rating/Rating.d.ts +6 -0
  156. package/lib/typescript/module/components/SearchBar/SearchBar.d.ts +3 -0
  157. package/lib/typescript/module/components/SegmentedControl/SegmentedControl.d.ts +3 -0
  158. package/lib/typescript/module/components/Select/Select.d.ts +6 -0
  159. package/lib/typescript/module/components/SlideToConfirm/SlideToConfirm.d.ts +34 -0
  160. package/lib/typescript/module/components/SlideToConfirm/index.d.ts +3 -0
  161. package/lib/typescript/module/components/Slider/Slider.d.ts +3 -0
  162. package/lib/typescript/module/components/Stepper/Stepper.d.ts +6 -0
  163. package/lib/typescript/module/components/Swipeable/Swipeable.d.ts +3 -0
  164. package/lib/typescript/module/components/Tabs/Tabs.d.ts +3 -0
  165. package/lib/typescript/module/components/TimePicker/TimePicker.d.ts +3 -0
  166. package/lib/typescript/module/components/index.d.ts +11 -1
  167. package/lib/typescript/module/hooks/usePressAnimation.d.ts +1 -2
  168. package/lib/typescript/module/theme/types.d.ts +2 -67
  169. package/lib/typescript/module/utils/hapticUtils.d.ts +8 -0
  170. package/lib/typescript/module/utils/index.d.ts +1 -1
  171. package/package.json +1 -1
@@ -4,7 +4,7 @@ import React, { forwardRef, useMemo } from 'react';
4
4
  import { Animated, Pressable, StyleSheet, Text, View } from 'react-native';
5
5
  import { fontFor, useTheme } from "../../theme/index.js";
6
6
  import { usePressAnimation } from "../../hooks/usePressAnimation.js";
7
- import { triggerHaptic } from "../../utils/hapticUtils.js";
7
+ import { resolveHaptic, triggerHaptic } from "../../utils/hapticUtils.js";
8
8
  import { Swipeable } from "../Swipeable/index.js";
9
9
  import { Skeleton } from "../Skeleton/index.js";
10
10
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -64,6 +64,7 @@ const ListItem = /*#__PURE__*/forwardRef((props, ref) => {
64
64
  left,
65
65
  right,
66
66
  onPress,
67
+ haptic,
67
68
  selected = false,
68
69
  disabled = false,
69
70
  size = 'md',
@@ -83,7 +84,6 @@ const ListItem = /*#__PURE__*/forwardRef((props, ref) => {
83
84
  testID
84
85
  } = props;
85
86
  const theme = useTheme();
86
- const pressHaptic = theme.components.listItem?.pressHaptic ?? false;
87
87
  const sz = useMemo(() => sizeFor(theme, size), [theme, size]);
88
88
  const styles = useMemo(() => buildStyles(theme), [theme]);
89
89
  const isInteractive = !!onPress && !disabled;
@@ -96,7 +96,8 @@ const ListItem = /*#__PURE__*/forwardRef((props, ref) => {
96
96
  });
97
97
  const handlePress = event => {
98
98
  if (!isInteractive) return;
99
- if (pressHaptic) triggerHaptic('selection');
99
+ const h = resolveHaptic(haptic, 'selection');
100
+ if (h) triggerHaptic(h);
100
101
  onPress?.(event);
101
102
  };
102
103
  const a11yLabel = accessibilityLabel ?? title;
@@ -291,7 +292,7 @@ const buildStyles = theme => StyleSheet.create({
291
292
  backgroundColor: theme.colors.surface.pressed
292
293
  },
293
294
  disabled: {
294
- opacity: 0.6
295
+ opacity: 0.55
295
296
  },
296
297
  leftSlot: {
297
298
  marginRight: theme.spacing.md,
@@ -4,7 +4,7 @@ import React, { forwardRef, useCallback, useEffect, useMemo, useRef } from 'reac
4
4
  import { AccessibilityInfo, Animated, Dimensions, findNodeHandle, Modal as RNModal, Pressable, StyleSheet, View } from 'react-native';
5
5
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
6
6
  import { useTheme, createAnimatedValue, setNativeValue } from "../../theme/index.js";
7
- import { triggerHaptic } from "../../utils/hapticUtils.js";
7
+ import { triggerHaptic, resolveHaptic } from "../../utils/hapticUtils.js";
8
8
 
9
9
  // Local shape mirror — see types.ts ModalTokens for the canonical definition.
10
10
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -13,7 +13,6 @@ const Modal = /*#__PURE__*/forwardRef((props, ref) => {
13
13
  visible,
14
14
  onRequestClose,
15
15
  presentation = 'centered',
16
- backdropOpacity = 0.5,
17
16
  backdropPressClose = true,
18
17
  animationDuration,
19
18
  accessibilityLabel,
@@ -22,6 +21,7 @@ const Modal = /*#__PURE__*/forwardRef((props, ref) => {
22
21
  contentStyle,
23
22
  backdropStyle,
24
23
  restoreFocusRef,
24
+ haptic,
25
25
  testID
26
26
  } = props;
27
27
  const theme = useTheme();
@@ -30,7 +30,6 @@ const Modal = /*#__PURE__*/forwardRef((props, ref) => {
30
30
  const screenHeight = Dimensions.get('window').height;
31
31
  const modalTokens = theme.components.modal;
32
32
  const scaleStartValue = modalTokens?.scaleStartValue ?? 0.9;
33
- const backdropHaptic = modalTokens?.backdropHaptic ?? false;
34
33
  const backdropAnim = useRef(createAnimatedValue(0)).current;
35
34
  const scaleAnim = useRef(createAnimatedValue(scaleStartValue)).current;
36
35
  const opacityAnim = useRef(createAnimatedValue(0)).current;
@@ -126,9 +125,10 @@ const Modal = /*#__PURE__*/forwardRef((props, ref) => {
126
125
  }, [visible, duration, restoreFocusRef]);
127
126
  const handleBackdropPress = useCallback(() => {
128
127
  if (!backdropPressClose) return;
129
- if (backdropHaptic) triggerHaptic('selection');
128
+ const h = resolveHaptic(haptic, 'selection');
129
+ if (h) triggerHaptic(h);
130
130
  onRequestClose();
131
- }, [backdropPressClose, onRequestClose, backdropHaptic]);
131
+ }, [backdropPressClose, onRequestClose, haptic]);
132
132
  const handleHardwareBack = useCallback(() => {
133
133
  if (hardwareBackPress) {
134
134
  onRequestClose();
@@ -4,7 +4,7 @@ import React, { forwardRef, useCallback, useEffect, useMemo, useRef, useState }
4
4
  import { Pressable, StyleSheet, Text, TextInput, View } from 'react-native';
5
5
  import { useControllableState } from "../../hooks/index.js";
6
6
  import { useTheme } from "../../theme/index.js";
7
- import { triggerHaptic } from "../../utils/index.js";
7
+ import { resolveHaptic, triggerHaptic } from "../../utils/index.js";
8
8
  import { FieldBase, resolveFieldSize, resolveFieldTextStyle } from "../FieldBase/FieldBase.js";
9
9
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
10
  const DEFAULT_LONG_PRESS_DELAY = 500;
@@ -58,6 +58,7 @@ const NumberInput = /*#__PURE__*/forwardRef((props, ref) => {
58
58
  size = 'md',
59
59
  variant = 'inline',
60
60
  unit,
61
+ haptic,
61
62
  accessibilityLabel,
62
63
  style,
63
64
  containerStyle,
@@ -81,7 +82,6 @@ const NumberInput = /*#__PURE__*/forwardRef((props, ref) => {
81
82
  const styles = useMemo(() => buildStyles(theme), [theme]);
82
83
  const longPressDelay = theme.components.numberInput?.longPressDelayMs ?? DEFAULT_LONG_PRESS_DELAY;
83
84
  const longPressInterval = theme.components.numberInput?.longPressIntervalMs ?? DEFAULT_LONG_PRESS_INTERVAL;
84
- const pressHaptic = theme.components.numberInput?.pressHaptic ?? false;
85
85
  const inputRef = useRef(null);
86
86
  const [draft, setDraft] = useState(formatValue(current, allowDecimal, precision));
87
87
  const [editing, setEditing] = useState(false);
@@ -116,14 +116,16 @@ const NumberInput = /*#__PURE__*/forwardRef((props, ref) => {
116
116
  }, [allowDecimal, max, min, setCurrent, precision, current]);
117
117
  const decrement = useCallback(() => {
118
118
  if (!interactive || atMin) return;
119
- if (pressHaptic) triggerHaptic('impactLight');
119
+ const h = resolveHaptic(haptic, 'selection');
120
+ if (h) triggerHaptic(h);
120
121
  setExternal(current - step);
121
- }, [atMin, interactive, pressHaptic, setExternal, step, current]);
122
+ }, [atMin, interactive, haptic, setExternal, step, current]);
122
123
  const increment = useCallback(() => {
123
124
  if (!interactive || atMax) return;
124
- if (pressHaptic) triggerHaptic('impactLight');
125
+ const h = resolveHaptic(haptic, 'selection');
126
+ if (h) triggerHaptic(h);
125
127
  setExternal(current + step);
126
- }, [atMax, interactive, pressHaptic, setExternal, step, current]);
128
+ }, [atMax, interactive, haptic, setExternal, step, current]);
127
129
  React.useImperativeHandle(ref, () => ({
128
130
  focus: () => inputRef.current?.focus(),
129
131
  blur: () => inputRef.current?.blur(),
@@ -4,7 +4,7 @@ import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo
4
4
  import { Animated, Easing, Pressable, StyleSheet, Text, TextInput, View } from 'react-native';
5
5
  import { fontFor, useTheme, createAnimatedValue, setNativeValue } from "../../theme/index.js";
6
6
  import { useReducedMotion, useControllableState } from "../../hooks/index.js";
7
- import { triggerHaptic } from "../../utils/index.js";
7
+ import { triggerHaptic, resolveHaptic } from "../../utils/index.js";
8
8
  import { FieldBase } from "../FieldBase/FieldBase.js";
9
9
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
10
  const sizeMap = {
@@ -47,6 +47,7 @@ const OTPInput = /*#__PURE__*/forwardRef((props, ref) => {
47
47
  error,
48
48
  size = 'md',
49
49
  secure = false,
50
+ haptic,
50
51
  accessibilityLabel,
51
52
  style,
52
53
  cellStyle,
@@ -89,8 +90,6 @@ const OTPInput = /*#__PURE__*/forwardRef((props, ref) => {
89
90
  const previousFocusedIndexRef = useRef(-1);
90
91
  const shakeOnError = theme.components.otpInput?.shakeOnError ?? false;
91
92
  const reduceMotion = useReducedMotion();
92
- const errorHaptic = theme.components.otpInput?.errorHaptic ?? false;
93
- const selectionHaptic = theme.components.otpInput?.selectionHaptic ?? false;
94
93
  const hasError = Boolean(error);
95
94
  const errorMessage = typeof error === 'string' ? error : undefined;
96
95
 
@@ -100,7 +99,7 @@ const OTPInput = /*#__PURE__*/forwardRef((props, ref) => {
100
99
  const isFirstRun = previousErrorRef.current === null;
101
100
  let anim;
102
101
  if (!isFirstRun && hasError && !previousErrorRef.current) {
103
- if (errorHaptic) triggerHaptic('notificationError');
102
+ if (haptic !== false) triggerHaptic('notificationError');
104
103
  if (shakeOnError && !reduceMotion) {
105
104
  setNativeValue(shake, 0);
106
105
  anim = Animated.sequence([Animated.timing(shake, {
@@ -129,7 +128,7 @@ const OTPInput = /*#__PURE__*/forwardRef((props, ref) => {
129
128
  }
130
129
  previousErrorRef.current = hasError;
131
130
  return () => anim?.stop();
132
- }, [hasError, shake, shakeOnError, errorHaptic]);
131
+ }, [hasError, shake, shakeOnError, haptic]);
133
132
 
134
133
  // Animate underline opacity for the focused cell. Skip on first mount
135
134
  // (no prior focus state) — values are already at 0 and there's nothing to animate.
@@ -225,8 +224,9 @@ const OTPInput = /*#__PURE__*/forwardRef((props, ref) => {
225
224
  const next = chars.join('').slice(0, length);
226
225
  const previousLength = current.length;
227
226
  updateValue(next);
228
- if (next.length !== previousLength && selectionHaptic) {
229
- triggerHaptic('selection');
227
+ if (next.length !== previousLength) {
228
+ const h = resolveHaptic(haptic, 'selection');
229
+ if (h) triggerHaptic(h);
230
230
  }
231
231
 
232
232
  // Move focus to the next empty cell or last cell.
@@ -236,7 +236,7 @@ const OTPInput = /*#__PURE__*/forwardRef((props, ref) => {
236
236
  } else {
237
237
  focusCell(nextFocus);
238
238
  }
239
- }, [cells, focusCell, keyboardType, length, selectionHaptic, updateValue, current]);
239
+ }, [cells, focusCell, keyboardType, length, haptic, updateValue, current]);
240
240
  const handleKeyPress = useCallback((index, e) => {
241
241
  const key = e.nativeEvent.key;
242
242
  if (key !== 'Backspace') return;
@@ -2,7 +2,7 @@
2
2
 
3
3
  import React, { forwardRef, useEffect, useMemo, useRef } from 'react';
4
4
  import { Animated, Easing, StyleSheet, View } from 'react-native';
5
- import { useTheme, createAnimatedValue, setNativeValue } from "../../theme/index.js";
5
+ import { useTheme, createAnimatedValue, setNativeValue, Gradient } from "../../theme/index.js";
6
6
  import { jsx as _jsx } from "react/jsx-runtime";
7
7
  const toneColor = (theme, tone) => {
8
8
  switch (tone) {
@@ -33,6 +33,8 @@ const ProgressBar = /*#__PURE__*/forwardRef((props, ref) => {
33
33
  tone = 'primary',
34
34
  trackColor,
35
35
  barColor,
36
+ gradient,
37
+ segments,
36
38
  animated = true,
37
39
  style,
38
40
  containerStyle,
@@ -53,6 +55,12 @@ const ProgressBar = /*#__PURE__*/forwardRef((props, ref) => {
53
55
  const resolvedRadius = radius ?? theme.radius.full;
54
56
  const resolvedTrack = trackColor ?? theme.colors.surface.disabled;
55
57
  const resolvedBar = barColor ?? toneColor(theme, tone);
58
+ const resolvedGradient = useMemo(() => {
59
+ if (!gradient) return null;
60
+ if (typeof gradient === 'string') return theme.gradients[gradient] ?? null;
61
+ return gradient;
62
+ }, [gradient, theme.gradients]);
63
+ const hasSegments = Array.isArray(segments) && segments.length > 0;
56
64
  useEffect(() => {
57
65
  if (isIndeterminate) return;
58
66
  if (!animated) {
@@ -111,7 +119,18 @@ const ProgressBar = /*#__PURE__*/forwardRef((props, ref) => {
111
119
  borderRadius: resolvedRadius,
112
120
  backgroundColor: resolvedTrack
113
121
  }, style, containerStyle],
114
- children: isIndeterminate ? /*#__PURE__*/_jsx(Animated.View, {
122
+ children: hasSegments ? /*#__PURE__*/_jsx(View, {
123
+ style: [styles.segments, {
124
+ height
125
+ }],
126
+ children: (segments ?? []).map((s, i) => /*#__PURE__*/_jsx(View, {
127
+ style: {
128
+ width: `${clampProgress(s.value) * 100}%`,
129
+ height,
130
+ backgroundColor: s.color ?? toneColor(theme, s.tone ?? 'primary')
131
+ }
132
+ }, i))
133
+ }) : isIndeterminate ? /*#__PURE__*/_jsx(Animated.View, {
115
134
  style: [styles.indeterminateBar, {
116
135
  height,
117
136
  borderRadius: resolvedRadius,
@@ -125,9 +144,14 @@ const ProgressBar = /*#__PURE__*/forwardRef((props, ref) => {
125
144
  style: [styles.determinateBar, {
126
145
  height,
127
146
  borderRadius: resolvedRadius,
128
- backgroundColor: resolvedBar,
129
- width: determinateWidth
130
- }, barStyle]
147
+ backgroundColor: resolvedGradient ? 'transparent' : resolvedBar,
148
+ width: determinateWidth,
149
+ overflow: resolvedGradient ? 'hidden' : undefined
150
+ }, barStyle],
151
+ children: resolvedGradient ? /*#__PURE__*/_jsx(Gradient, {
152
+ gradient: resolvedGradient,
153
+ style: StyleSheet.absoluteFill
154
+ }) : null
131
155
  })
132
156
  });
133
157
  });
@@ -146,6 +170,10 @@ const buildStyles = _theme => StyleSheet.create({
146
170
  position: 'absolute',
147
171
  left: 0,
148
172
  top: 0
173
+ },
174
+ segments: {
175
+ flexDirection: 'row',
176
+ width: '100%'
149
177
  }
150
178
  });
151
179
  export { ProgressBar };
@@ -3,7 +3,7 @@
3
3
  import React, { createContext, forwardRef, useContext, useEffect, useMemo, useRef } from 'react';
4
4
  import { Animated, Pressable, StyleSheet, Text, View } from 'react-native';
5
5
  import { useTheme, createAnimatedValue } from "../../theme/index.js";
6
- import { triggerHaptic } from "../../utils/hapticUtils.js";
6
+ import { triggerHaptic, resolveHaptic } from "../../utils/hapticUtils.js";
7
7
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
8
  export const RadioGroupContext = /*#__PURE__*/createContext(null);
9
9
  export const useRadioGroup = () => useContext(RadioGroupContext);
@@ -64,8 +64,6 @@ const Radio = /*#__PURE__*/forwardRef((props, ref) => {
64
64
  const inner = sizeOverrides?.inner ?? sizeMap[size].inner;
65
65
  const radioBorderWidth = theme.colors.border.width;
66
66
  const radioLabelGap = theme.components.radio?.labelGap ?? 10;
67
- const pressHapticEnabled = theme.components.radio?.pressHaptic ?? false;
68
- const resolvedHaptic = haptic === undefined ? pressHapticEnabled ? 'selection' : false : haptic;
69
67
  const progress = useRef(createAnimatedValue(selected ? 1 : 0)).current;
70
68
  useEffect(() => {
71
69
  const anim = Animated.spring(progress, {
@@ -84,7 +82,8 @@ const Radio = /*#__PURE__*/forwardRef((props, ref) => {
84
82
  });
85
83
  const handlePress = event => {
86
84
  if (disabled) return;
87
- if (resolvedHaptic !== false) triggerHaptic(resolvedHaptic);
85
+ const h = resolveHaptic(haptic, 'selection');
86
+ if (h) triggerHaptic(h);
88
87
  if (ctx) {
89
88
  ctx.onChange(value);
90
89
  } else {
@@ -3,7 +3,7 @@
3
3
  import React, { forwardRef, useCallback, useMemo, useRef } from 'react';
4
4
  import { Animated, Easing, Pressable, StyleSheet, Text, View } from 'react-native';
5
5
  import { useTheme } from "../../theme/index.js";
6
- import { triggerHaptic } from "../../utils/hapticUtils.js";
6
+ import { resolveHaptic, triggerHaptic } from "../../utils/hapticUtils.js";
7
7
  import { Skeleton } from "../Skeleton/index.js";
8
8
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
9
  const sizePxMap = {
@@ -80,6 +80,7 @@ const Rating = /*#__PURE__*/forwardRef((props, ref) => {
80
80
  tone = 'warning',
81
81
  label,
82
82
  loading = false,
83
+ haptic,
83
84
  accessibilityLabel,
84
85
  style,
85
86
  containerStyle,
@@ -116,7 +117,6 @@ const Rating = /*#__PURE__*/forwardRef((props, ref) => {
116
117
  }, [max]);
117
118
  const pulseOnPress = theme.components.rating?.pulseOnPress ?? false;
118
119
  const pulseScale = theme.components.rating?.pulseScale ?? 1.2;
119
- const pressHapticEnabled = theme.components.rating?.pressHaptic ?? false;
120
120
  const pulse = useCallback(idx => {
121
121
  const v = scaleRefs[idx];
122
122
  if (!v) return;
@@ -136,10 +136,11 @@ const Rating = /*#__PURE__*/forwardRef((props, ref) => {
136
136
  const commit = useCallback((next, animatedIndex) => {
137
137
  if (!interactive || !onChange) return;
138
138
  const cleaned = clampToStep(next, max, step);
139
- if (pressHapticEnabled) triggerHaptic('selection');
139
+ const h = resolveHaptic(haptic, 'selection');
140
+ if (h) triggerHaptic(h);
140
141
  if (pulseOnPress && typeof animatedIndex === 'number') pulse(animatedIndex);
141
142
  onChange(cleaned);
142
- }, [interactive, onChange, max, step, pulse, pressHapticEnabled, pulseOnPress]);
143
+ }, [interactive, onChange, max, step, pulse, haptic, pulseOnPress]);
143
144
  const handleStarPress = useCallback(index => e => {
144
145
  if (!interactive) return;
145
146
  const w = starWidthRef.current || starSize;
@@ -3,7 +3,7 @@
3
3
  import React, { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
  import { Animated, Easing, Pressable, StyleSheet, Text, TextInput, View } from 'react-native';
5
5
  import { fontFor, useTheme, createAnimatedValue } from "../../theme/index.js";
6
- import { triggerHaptic } from "../../utils/hapticUtils.js";
6
+ import { resolveHaptic, triggerHaptic } from "../../utils/hapticUtils.js";
7
7
  import { useDebounce } from "../../hooks/useDebounce.js";
8
8
  import { FieldBase, resolveFieldSize, resolveFieldTextStyle, resolveVariantColors } from "../FieldBase/FieldBase.js";
9
9
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -24,6 +24,7 @@ const SearchBar = /*#__PURE__*/forwardRef((props, ref) => {
24
24
  size = 'md',
25
25
  variant: variantProp,
26
26
  cancelLabel = 'Cancel',
27
+ haptic,
27
28
  style,
28
29
  accessibilityLabel,
29
30
  testID,
@@ -92,16 +93,18 @@ const SearchBar = /*#__PURE__*/forwardRef((props, ref) => {
92
93
  onChangeText(text);
93
94
  }, [debounceMs, onChangeText]);
94
95
  const handleClear = useCallback(() => {
95
- triggerHaptic('selection');
96
+ const h = resolveHaptic(haptic, 'selection');
97
+ if (h) triggerHaptic(h);
96
98
  if (debounceMs !== undefined) {
97
99
  setInternalValue('');
98
100
  lastSentRef.current = '';
99
101
  }
100
102
  onChangeText('');
101
103
  onClear?.();
102
- }, [debounceMs, onChangeText, onClear]);
104
+ }, [haptic, debounceMs, onChangeText, onClear]);
103
105
  const handleCancel = useCallback(() => {
104
- triggerHaptic('selection');
106
+ const h = resolveHaptic(haptic, 'selection');
107
+ if (h) triggerHaptic(h);
105
108
  if (debounceMs !== undefined) {
106
109
  setInternalValue('');
107
110
  lastSentRef.current = '';
@@ -109,7 +112,7 @@ const SearchBar = /*#__PURE__*/forwardRef((props, ref) => {
109
112
  onChangeText('');
110
113
  setIsFocused(false);
111
114
  onCancel?.();
112
- }, [debounceMs, onChangeText, onCancel]);
115
+ }, [haptic, debounceMs, onChangeText, onCancel]);
113
116
  const handleSubmit = useCallback(() => {
114
117
  onSubmit?.(debounceMs !== undefined ? internalValue : value);
115
118
  }, [onSubmit, debounceMs, internalValue, value]);
@@ -11,7 +11,7 @@
11
11
  import React, { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from 'react';
12
12
  import { Animated, Pressable, StyleSheet, Text, View } from 'react-native';
13
13
  import { useTheme, createAnimatedValue } from "../../theme/index.js";
14
- import { triggerHaptic } from "../../utils/index.js";
14
+ import { triggerHaptic, resolveHaptic } from "../../utils/index.js";
15
15
  import { useControllableState } from "../../hooks/index.js";
16
16
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
17
17
  const sizeMap = {
@@ -37,6 +37,7 @@ const SegmentedControl = /*#__PURE__*/forwardRef((props, ref) => {
37
37
  fullWidth = true,
38
38
  disabled = false,
39
39
  tone = 'primary',
40
+ haptic,
40
41
  accessibilityLabel,
41
42
  style,
42
43
  containerStyle,
@@ -61,7 +62,6 @@ const SegmentedControl = /*#__PURE__*/forwardRef((props, ref) => {
61
62
  paddingHorizontal: segTheme?.[size]?.paddingHorizontal ?? baseSize.paddingHorizontal
62
63
  };
63
64
  const trackPadding = segTheme?.trackPadding ?? TRACK_PADDING;
64
- const changeHapticEnabled = segTheme?.changeHaptic ?? false;
65
65
 
66
66
  // Track width is measured from onLayout. Thumb width is a regular number (not
67
67
  // animated) — `width` cannot be driven by the native animated module, and mixing
@@ -102,9 +102,10 @@ const SegmentedControl = /*#__PURE__*/forwardRef((props, ref) => {
102
102
  const handlePress = useCallback(segment => {
103
103
  if (disabled) return;
104
104
  if (segment.value === current) return;
105
- if (changeHapticEnabled) triggerHaptic('selection');
105
+ const h = resolveHaptic(haptic, 'selection');
106
+ if (h) triggerHaptic(h);
106
107
  setCurrent(segment.value);
107
- }, [disabled, setCurrent, current, changeHapticEnabled]);
108
+ }, [disabled, setCurrent, current, haptic]);
108
109
  const thumbBg = tone === 'primary' ? theme.colors.background.elevated : theme.colors.background.elevated;
109
110
  const activeTextColor = tone === 'primary' ? theme.colors.text.primary : theme.colors.text.primary;
110
111
  return /*#__PURE__*/_jsxs(View, {
@@ -12,7 +12,7 @@ import React, { forwardRef, useCallback, useEffect, useMemo, useRef, useState }
12
12
  import { Animated, Dimensions, Easing, FlatList, Modal, Pressable, StyleSheet, Text, TextInput, View } from 'react-native';
13
13
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
14
14
  import { useTheme, createAnimatedValue } from "../../theme/index.js";
15
- import { triggerHaptic } from "../../utils/index.js";
15
+ import { resolveHaptic, triggerHaptic } from "../../utils/index.js";
16
16
  import { FieldBase, resolveFieldSize, resolveFieldTextStyle, resolveVariantColors } from "../FieldBase/FieldBase.js";
17
17
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
18
18
  // `unknown` here keeps the forwardRef signature non-generic — consumers who
@@ -27,6 +27,7 @@ const Select = /*#__PURE__*/forwardRef((props, ref) => {
27
27
  getOptionDescription,
28
28
  placeholder,
29
29
  searchable = false,
30
+ haptic,
30
31
  label,
31
32
  error,
32
33
  disabled = false,
@@ -114,9 +115,10 @@ const Select = /*#__PURE__*/forwardRef((props, ref) => {
114
115
  }, [searchable, query, options, labelOf, descriptionOf]);
115
116
  const handleOpen = useCallback(() => {
116
117
  if (disabled) return;
117
- triggerHaptic('selection');
118
+ const h = resolveHaptic(haptic, 'selection');
119
+ if (h) triggerHaptic(h);
118
120
  setOpen(true);
119
- }, [disabled]);
121
+ }, [disabled, haptic]);
120
122
  const handleClose = useCallback(() => {
121
123
  setOpen(false);
122
124
  setQuery('');
@@ -124,7 +126,8 @@ const Select = /*#__PURE__*/forwardRef((props, ref) => {
124
126
  const handleSelect = useCallback(option => {
125
127
  if (disabledOf(option)) return;
126
128
  const optValue = valueOf(option);
127
- triggerHaptic('selection');
129
+ const h = resolveHaptic(haptic, 'selection');
130
+ if (h) triggerHaptic(h);
128
131
  if (multi) {
129
132
  const current = props.value ?? [];
130
133
  const next = current.includes(optValue) ? current.filter(v => v !== optValue) : [...current, optValue];
@@ -133,7 +136,7 @@ const Select = /*#__PURE__*/forwardRef((props, ref) => {
133
136
  }
134
137
  props.onChange(optValue);
135
138
  handleClose();
136
- }, [multi, props, handleClose, disabledOf, valueOf]);
139
+ }, [multi, props, handleClose, disabledOf, valueOf, haptic]);
137
140
 
138
141
  // Trigger label / placeholder text.
139
142
  const triggerText = selectedOptions.length === 0 ? placeholder ?? 'Select…' : selectedOptions.map(o => labelOf(o)).join(', ');