@webority-technologies/mobile 0.0.15 → 0.0.20

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 (202) hide show
  1. package/lib/commonjs/components/Accordion/Accordion.js +60 -19
  2. package/lib/commonjs/components/AppBar/AppBar.js +29 -20
  3. package/lib/commonjs/components/Avatar/Avatar.js +38 -8
  4. package/lib/commonjs/components/Badge/Badge.js +66 -4
  5. package/lib/commonjs/components/Banner/Banner.js +146 -66
  6. package/lib/commonjs/components/BottomNavigation/BottomNavigation.js +37 -15
  7. package/lib/commonjs/components/BottomSheet/BottomSheet.js +78 -53
  8. package/lib/commonjs/components/Button/Button.js +12 -5
  9. package/lib/commonjs/components/Card/Card.js +106 -16
  10. package/lib/commonjs/components/Carousel/Carousel.js +66 -12
  11. package/lib/commonjs/components/Checkbox/Checkbox.js +11 -7
  12. package/lib/commonjs/components/Chip/Chip.js +44 -12
  13. package/lib/commonjs/components/DatePicker/DatePicker.js +185 -76
  14. package/lib/commonjs/components/DateRangePicker/DateRangePicker.js +133 -59
  15. package/lib/commonjs/components/Dialog/Dialog.js +16 -10
  16. package/lib/commonjs/components/Drawer/Drawer.js +13 -10
  17. package/lib/commonjs/components/FieldBase/FieldBase.js +306 -0
  18. package/lib/commonjs/components/FieldBase/index.js +32 -0
  19. package/lib/commonjs/components/FloatingActionButton/FloatingActionButton.js +69 -44
  20. package/lib/commonjs/components/ForceUpdateDialog/ForceUpdateDialog.js +8 -2
  21. package/lib/commonjs/components/FormField/FormField.js +3 -2
  22. package/lib/commonjs/components/ImageGallery/ImageGallery.js +132 -44
  23. package/lib/commonjs/components/Input/Input.js +144 -181
  24. package/lib/commonjs/components/ListItem/ListItem.js +90 -11
  25. package/lib/commonjs/components/Modal/Modal.js +55 -27
  26. package/lib/commonjs/components/NumberInput/NumberInput.js +60 -106
  27. package/lib/commonjs/components/OTPInput/OTPInput.js +65 -58
  28. package/lib/commonjs/components/PickerTrigger/PickerTrigger.js +185 -0
  29. package/lib/commonjs/components/{AppIcon → PickerTrigger}/index.js +4 -4
  30. package/lib/commonjs/components/ProgressBar/ProgressBar.js +19 -11
  31. package/lib/commonjs/components/Radio/Radio.js +11 -6
  32. package/lib/commonjs/components/Rating/Rating.js +85 -19
  33. package/lib/commonjs/components/SearchBar/SearchBar.js +84 -107
  34. package/lib/commonjs/components/SegmentedControl/SegmentedControl.js +22 -11
  35. package/lib/commonjs/components/Select/Select.js +62 -91
  36. package/lib/commonjs/components/Skeleton/Skeleton.js +131 -174
  37. package/lib/commonjs/components/Skeleton/SkeletonClock.js +117 -0
  38. package/lib/commonjs/components/Skeleton/SkeletonContent.js +164 -81
  39. package/lib/commonjs/components/Skeleton/SkeletonProvider.js +72 -10
  40. package/lib/commonjs/components/Skeleton/index.js +17 -16
  41. package/lib/commonjs/components/Slider/Slider.js +44 -25
  42. package/lib/commonjs/components/Stepper/Stepper.js +199 -29
  43. package/lib/commonjs/components/Swipeable/Swipeable.js +36 -19
  44. package/lib/commonjs/components/Switch/Switch.js +9 -2
  45. package/lib/commonjs/components/Tabs/Tabs.js +84 -21
  46. package/lib/commonjs/components/TimePicker/TimePicker.js +123 -45
  47. package/lib/commonjs/components/Toast/Toast.js +27 -16
  48. package/lib/commonjs/components/Tooltip/Tooltip.js +56 -32
  49. package/lib/commonjs/components/index.js +37 -37
  50. package/lib/commonjs/theme/tokens.js +55 -7
  51. package/lib/module/components/Accordion/Accordion.js +61 -20
  52. package/lib/module/components/AppBar/AppBar.js +29 -20
  53. package/lib/module/components/Avatar/Avatar.js +39 -9
  54. package/lib/module/components/Badge/Badge.js +67 -5
  55. package/lib/module/components/Banner/Banner.js +147 -67
  56. package/lib/module/components/BottomNavigation/BottomNavigation.js +37 -15
  57. package/lib/module/components/BottomSheet/BottomSheet.js +80 -55
  58. package/lib/module/components/Button/Button.js +12 -5
  59. package/lib/module/components/Card/Card.js +107 -17
  60. package/lib/module/components/Carousel/Carousel.js +67 -13
  61. package/lib/module/components/Checkbox/Checkbox.js +11 -7
  62. package/lib/module/components/Chip/Chip.js +45 -13
  63. package/lib/module/components/DatePicker/DatePicker.js +185 -76
  64. package/lib/module/components/DateRangePicker/DateRangePicker.js +134 -60
  65. package/lib/module/components/Dialog/Dialog.js +16 -10
  66. package/lib/module/components/Drawer/Drawer.js +13 -10
  67. package/lib/module/components/FieldBase/FieldBase.js +297 -0
  68. package/lib/module/components/FieldBase/index.js +4 -0
  69. package/lib/module/components/FloatingActionButton/FloatingActionButton.js +69 -44
  70. package/lib/module/components/ForceUpdateDialog/ForceUpdateDialog.js +8 -2
  71. package/lib/module/components/FormField/FormField.js +3 -2
  72. package/lib/module/components/ImageGallery/ImageGallery.js +128 -40
  73. package/lib/module/components/Input/Input.js +144 -179
  74. package/lib/module/components/ListItem/ListItem.js +91 -12
  75. package/lib/module/components/Modal/Modal.js +55 -27
  76. package/lib/module/components/NumberInput/NumberInput.js +60 -106
  77. package/lib/module/components/OTPInput/OTPInput.js +65 -58
  78. package/lib/module/components/PickerTrigger/PickerTrigger.js +181 -0
  79. package/lib/module/components/PickerTrigger/index.js +4 -0
  80. package/lib/module/components/ProgressBar/ProgressBar.js +19 -11
  81. package/lib/module/components/Radio/Radio.js +11 -6
  82. package/lib/module/components/Rating/Rating.js +86 -20
  83. package/lib/module/components/SearchBar/SearchBar.js +84 -107
  84. package/lib/module/components/SegmentedControl/SegmentedControl.js +22 -11
  85. package/lib/module/components/Select/Select.js +62 -91
  86. package/lib/module/components/Skeleton/Skeleton.js +135 -175
  87. package/lib/module/components/Skeleton/SkeletonClock.js +110 -0
  88. package/lib/module/components/Skeleton/SkeletonContent.js +167 -84
  89. package/lib/module/components/Skeleton/SkeletonProvider.js +71 -10
  90. package/lib/module/components/Skeleton/index.js +3 -2
  91. package/lib/module/components/Slider/Slider.js +44 -25
  92. package/lib/module/components/Stepper/Stepper.js +201 -31
  93. package/lib/module/components/Swipeable/Swipeable.js +36 -19
  94. package/lib/module/components/Switch/Switch.js +9 -2
  95. package/lib/module/components/Tabs/Tabs.js +84 -21
  96. package/lib/module/components/TimePicker/TimePicker.js +123 -45
  97. package/lib/module/components/Toast/Toast.js +27 -16
  98. package/lib/module/components/Tooltip/Tooltip.js +56 -32
  99. package/lib/module/components/index.js +2 -2
  100. package/lib/module/theme/tokens.js +55 -7
  101. package/lib/typescript/commonjs/components/Accordion/Accordion.d.ts +10 -5
  102. package/lib/typescript/commonjs/components/AppBar/AppBar.d.ts +8 -0
  103. package/lib/typescript/commonjs/components/Avatar/Avatar.d.ts +12 -6
  104. package/lib/typescript/commonjs/components/Badge/Badge.d.ts +7 -6
  105. package/lib/typescript/commonjs/components/Banner/Banner.d.ts +17 -6
  106. package/lib/typescript/commonjs/components/BottomSheet/BottomSheet.d.ts +7 -0
  107. package/lib/typescript/commonjs/components/Card/Card.d.ts +17 -6
  108. package/lib/typescript/commonjs/components/Carousel/Carousel.d.ts +7 -6
  109. package/lib/typescript/commonjs/components/Checkbox/Checkbox.d.ts +9 -1
  110. package/lib/typescript/commonjs/components/Chip/Chip.d.ts +13 -6
  111. package/lib/typescript/commonjs/components/DatePicker/DatePicker.d.ts +38 -3
  112. package/lib/typescript/commonjs/components/DateRangePicker/DateRangePicker.d.ts +36 -3
  113. package/lib/typescript/commonjs/components/Dialog/Dialog.d.ts +13 -1
  114. package/lib/typescript/commonjs/components/FieldBase/FieldBase.d.ts +141 -0
  115. package/lib/typescript/commonjs/components/FieldBase/index.d.ts +3 -0
  116. package/lib/typescript/commonjs/components/FloatingActionButton/FloatingActionButton.d.ts +8 -6
  117. package/lib/typescript/commonjs/components/FloatingActionButton/index.d.ts +1 -1
  118. package/lib/typescript/commonjs/components/ForceUpdateDialog/ForceUpdateDialog.d.ts +7 -0
  119. package/lib/typescript/commonjs/components/FormField/FormField.d.ts +7 -0
  120. package/lib/typescript/commonjs/components/ImageGallery/ImageGallery.d.ts +6 -4
  121. package/lib/typescript/commonjs/components/Input/Input.d.ts +6 -0
  122. package/lib/typescript/commonjs/components/ListItem/ListItem.d.ts +13 -6
  123. package/lib/typescript/commonjs/components/NumberInput/NumberInput.d.ts +3 -0
  124. package/lib/typescript/commonjs/components/PickerTrigger/PickerTrigger.d.ts +57 -0
  125. package/lib/typescript/commonjs/components/PickerTrigger/index.d.ts +3 -0
  126. package/lib/typescript/commonjs/components/ProgressBar/ProgressBar.d.ts +2 -0
  127. package/lib/typescript/commonjs/components/Radio/Radio.d.ts +3 -0
  128. package/lib/typescript/commonjs/components/Rating/Rating.d.ts +9 -6
  129. package/lib/typescript/commonjs/components/SegmentedControl/SegmentedControl.d.ts +3 -0
  130. package/lib/typescript/commonjs/components/Skeleton/Skeleton.d.ts +49 -20
  131. package/lib/typescript/commonjs/components/Skeleton/SkeletonClock.d.ts +60 -0
  132. package/lib/typescript/commonjs/components/Skeleton/SkeletonContent.d.ts +80 -19
  133. package/lib/typescript/commonjs/components/Skeleton/SkeletonProvider.d.ts +39 -5
  134. package/lib/typescript/commonjs/components/Skeleton/index.d.ts +6 -4
  135. package/lib/typescript/commonjs/components/Slider/Slider.d.ts +12 -1
  136. package/lib/typescript/commonjs/components/Stepper/Stepper.d.ts +18 -6
  137. package/lib/typescript/commonjs/components/Swipeable/Swipeable.d.ts +2 -0
  138. package/lib/typescript/commonjs/components/Switch/Switch.d.ts +1 -0
  139. package/lib/typescript/commonjs/components/Tabs/Tabs.d.ts +26 -2
  140. package/lib/typescript/commonjs/components/TimePicker/TimePicker.d.ts +36 -3
  141. package/lib/typescript/commonjs/components/Toast/Toast.d.ts +8 -0
  142. package/lib/typescript/commonjs/components/Tooltip/Tooltip.d.ts +7 -1
  143. package/lib/typescript/commonjs/components/index.d.ts +5 -5
  144. package/lib/typescript/commonjs/index.d.ts +1 -1
  145. package/lib/typescript/commonjs/theme/index.d.ts +1 -1
  146. package/lib/typescript/commonjs/theme/types.d.ts +553 -11
  147. package/lib/typescript/module/components/Accordion/Accordion.d.ts +10 -5
  148. package/lib/typescript/module/components/AppBar/AppBar.d.ts +8 -0
  149. package/lib/typescript/module/components/Avatar/Avatar.d.ts +12 -6
  150. package/lib/typescript/module/components/Badge/Badge.d.ts +7 -6
  151. package/lib/typescript/module/components/Banner/Banner.d.ts +17 -6
  152. package/lib/typescript/module/components/BottomSheet/BottomSheet.d.ts +7 -0
  153. package/lib/typescript/module/components/Card/Card.d.ts +17 -6
  154. package/lib/typescript/module/components/Carousel/Carousel.d.ts +7 -6
  155. package/lib/typescript/module/components/Checkbox/Checkbox.d.ts +9 -1
  156. package/lib/typescript/module/components/Chip/Chip.d.ts +13 -6
  157. package/lib/typescript/module/components/DatePicker/DatePicker.d.ts +38 -3
  158. package/lib/typescript/module/components/DateRangePicker/DateRangePicker.d.ts +36 -3
  159. package/lib/typescript/module/components/Dialog/Dialog.d.ts +13 -1
  160. package/lib/typescript/module/components/FieldBase/FieldBase.d.ts +141 -0
  161. package/lib/typescript/module/components/FieldBase/index.d.ts +3 -0
  162. package/lib/typescript/module/components/FloatingActionButton/FloatingActionButton.d.ts +8 -6
  163. package/lib/typescript/module/components/FloatingActionButton/index.d.ts +1 -1
  164. package/lib/typescript/module/components/ForceUpdateDialog/ForceUpdateDialog.d.ts +7 -0
  165. package/lib/typescript/module/components/FormField/FormField.d.ts +7 -0
  166. package/lib/typescript/module/components/ImageGallery/ImageGallery.d.ts +6 -4
  167. package/lib/typescript/module/components/Input/Input.d.ts +6 -0
  168. package/lib/typescript/module/components/ListItem/ListItem.d.ts +13 -6
  169. package/lib/typescript/module/components/NumberInput/NumberInput.d.ts +3 -0
  170. package/lib/typescript/module/components/PickerTrigger/PickerTrigger.d.ts +57 -0
  171. package/lib/typescript/module/components/PickerTrigger/index.d.ts +3 -0
  172. package/lib/typescript/module/components/ProgressBar/ProgressBar.d.ts +2 -0
  173. package/lib/typescript/module/components/Radio/Radio.d.ts +3 -0
  174. package/lib/typescript/module/components/Rating/Rating.d.ts +9 -6
  175. package/lib/typescript/module/components/SegmentedControl/SegmentedControl.d.ts +3 -0
  176. package/lib/typescript/module/components/Skeleton/Skeleton.d.ts +49 -20
  177. package/lib/typescript/module/components/Skeleton/SkeletonClock.d.ts +60 -0
  178. package/lib/typescript/module/components/Skeleton/SkeletonContent.d.ts +80 -19
  179. package/lib/typescript/module/components/Skeleton/SkeletonProvider.d.ts +39 -5
  180. package/lib/typescript/module/components/Skeleton/index.d.ts +6 -4
  181. package/lib/typescript/module/components/Slider/Slider.d.ts +12 -1
  182. package/lib/typescript/module/components/Stepper/Stepper.d.ts +18 -6
  183. package/lib/typescript/module/components/Swipeable/Swipeable.d.ts +2 -0
  184. package/lib/typescript/module/components/Switch/Switch.d.ts +1 -0
  185. package/lib/typescript/module/components/Tabs/Tabs.d.ts +26 -2
  186. package/lib/typescript/module/components/TimePicker/TimePicker.d.ts +36 -3
  187. package/lib/typescript/module/components/Toast/Toast.d.ts +8 -0
  188. package/lib/typescript/module/components/Tooltip/Tooltip.d.ts +7 -1
  189. package/lib/typescript/module/components/index.d.ts +5 -5
  190. package/lib/typescript/module/index.d.ts +1 -1
  191. package/lib/typescript/module/theme/index.d.ts +1 -1
  192. package/lib/typescript/module/theme/types.d.ts +553 -11
  193. package/package.json +2 -6
  194. package/lib/commonjs/components/AppIcon/AppIcon.js +0 -120
  195. package/lib/commonjs/types/vector-icons.d.js +0 -2
  196. package/lib/module/components/AppIcon/AppIcon.js +0 -111
  197. package/lib/module/components/AppIcon/index.js +0 -4
  198. package/lib/module/types/vector-icons.d.js +0 -2
  199. package/lib/typescript/commonjs/components/AppIcon/AppIcon.d.ts +0 -20
  200. package/lib/typescript/commonjs/components/AppIcon/index.d.ts +0 -3
  201. package/lib/typescript/module/components/AppIcon/AppIcon.d.ts +0 -20
  202. package/lib/typescript/module/components/AppIcon/index.d.ts +0 -3
@@ -2,9 +2,21 @@
2
2
 
3
3
  import React, { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
  import { AccessibilityInfo, Animated, Easing, Modal, Pressable, StyleSheet, Text, View } from 'react-native';
5
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
5
6
  import { useTheme, createAnimatedValue, setNativeValue } from "../../theme/index.js";
6
7
  import { triggerHaptic } from "../../utils/index.js";
7
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
+ import { PickerTrigger } from "../PickerTrigger/index.js";
9
+
10
+ /**
11
+ * DateRangePicker — supports two usage modes:
12
+ *
13
+ * 1. Controlled-modal mode (pass `visible` + `onClose`): renders only the
14
+ * modal; parent owns open/close state.
15
+ * 2. Trigger mode (omit `visible`): renders a built-in `PickerTrigger`
16
+ * field that opens an internally-managed modal on tap. Confirm fires
17
+ * `onChange?.(...)` and closes.
18
+ */
19
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
8
20
  const DAY_MS = 24 * 60 * 60 * 1000;
9
21
  const startOfDay = date => new Date(date.getFullYear(), date.getMonth(), date.getDate());
10
22
  const isSameDay = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
@@ -70,6 +82,18 @@ const DateRangePicker = /*#__PURE__*/forwardRef((props, ref) => {
70
82
  value,
71
83
  onChange,
72
84
  onClose,
85
+ label,
86
+ placeholder,
87
+ helperText,
88
+ error,
89
+ required,
90
+ disabled,
91
+ size,
92
+ variant,
93
+ clearable,
94
+ onClear,
95
+ formatValue,
96
+ triggerStyle,
73
97
  minDate,
74
98
  maxDate,
75
99
  disabledDates,
@@ -80,9 +104,17 @@ const DateRangePicker = /*#__PURE__*/forwardRef((props, ref) => {
80
104
  cancelLabel = 'Cancel',
81
105
  maxRange,
82
106
  style,
107
+ containerStyle,
108
+ headerLabelStyle,
109
+ navButtonStyle,
110
+ footerButtonStyle,
83
111
  testID
84
112
  } = props;
113
+ const isControlled = visible !== undefined;
114
+ const [internalOpen, setInternalOpen] = useState(false);
115
+ const open = isControlled ? visible : internalOpen;
85
116
  const theme = useTheme();
117
+ const insets = useSafeAreaInsets();
86
118
  const styles = useMemo(() => buildStyles(theme), [theme]);
87
119
  const today = useMemo(() => startOfDay(new Date()), []);
88
120
  const initialAnchor = value.start ? startOfDay(value.start) : today;
@@ -112,16 +144,17 @@ const DateRangePicker = /*#__PURE__*/forwardRef((props, ref) => {
112
144
  }
113
145
  }, [value.start, value.end]);
114
146
 
115
- // Modal open / close animation.
147
+ // Modal open / close animation. Backdrop opacity uses JS driver — see
148
+ // Modal.tsx for the Fabric reason. Sheet transform stays native.
116
149
  useEffect(() => {
117
- if (visible) {
118
- setNativeValue(backdrop, 0);
150
+ if (open) {
151
+ backdrop.setValue(0);
119
152
  setNativeValue(sheet, 0);
120
153
  Animated.parallel([Animated.timing(backdrop, {
121
154
  toValue: 1,
122
155
  duration: theme.motion.duration.normal,
123
156
  easing: Easing.out(Easing.cubic),
124
- useNativeDriver: true
157
+ useNativeDriver: false
125
158
  }), Animated.spring(sheet, {
126
159
  toValue: 1,
127
160
  damping: theme.motion.spring.gentle.damping,
@@ -130,7 +163,7 @@ const DateRangePicker = /*#__PURE__*/forwardRef((props, ref) => {
130
163
  useNativeDriver: true
131
164
  })]).start();
132
165
  }
133
- }, [visible, backdrop, sheet, theme.motion]);
166
+ }, [open, backdrop, sheet, theme.motion]);
134
167
  const disabledIsoSet = useMemo(() => {
135
168
  const set = new Set();
136
169
  disabledDates?.forEach(d => set.add(toIso(startOfDay(d))));
@@ -148,17 +181,19 @@ const DateRangePicker = /*#__PURE__*/forwardRef((props, ref) => {
148
181
  const headerLabel = useMemo(() => formatMonthYear(anchor, locale), [anchor, locale]);
149
182
  const weekdays = useMemo(() => weekdayLabels(locale, weekStartsOn), [locale, weekStartsOn]);
150
183
  const animateMonthChange = useCallback(delta => {
151
- triggerHaptic('impactLight');
184
+ if (theme.components.dateRangePicker?.haptic) triggerHaptic('impactLight');
152
185
  const direction = delta > 0 ? 1 : -1;
153
- const distance = 32;
186
+ const distance = theme.components.dateRangePicker?.monthSlideDistance ?? 32;
187
+ const outDuration = theme.components.dateRangePicker?.monthSlideOutDuration ?? theme.motion.duration.fast ?? 140;
188
+ const inDuration = theme.components.dateRangePicker?.monthSlideInDuration ?? theme.motion.duration.fast ?? 160;
154
189
  Animated.sequence([Animated.parallel([Animated.timing(monthSlide, {
155
190
  toValue: -direction * distance,
156
- duration: 140,
191
+ duration: outDuration,
157
192
  easing: Easing.out(Easing.quad),
158
193
  useNativeDriver: true
159
194
  }), Animated.timing(monthFade, {
160
195
  toValue: 0,
161
- duration: 140,
196
+ duration: outDuration,
162
197
  useNativeDriver: true
163
198
  })]), Animated.timing(monthSlide, {
164
199
  toValue: direction * distance,
@@ -166,23 +201,23 @@ const DateRangePicker = /*#__PURE__*/forwardRef((props, ref) => {
166
201
  useNativeDriver: true
167
202
  }), Animated.parallel([Animated.timing(monthSlide, {
168
203
  toValue: 0,
169
- duration: 160,
204
+ duration: inDuration,
170
205
  easing: Easing.out(Easing.cubic),
171
206
  useNativeDriver: true
172
207
  }), Animated.timing(monthFade, {
173
208
  toValue: 1,
174
- duration: 160,
209
+ duration: inDuration,
175
210
  useNativeDriver: true
176
211
  })])]).start();
177
212
  const next = addMonths(anchor, delta);
178
213
  setAnchor(next);
179
214
  AccessibilityInfo.announceForAccessibility(formatMonthYear(next, locale));
180
- }, [anchor, locale, monthFade, monthSlide]);
215
+ }, [anchor, locale, monthFade, monthSlide, theme.components.dateRangePicker, theme.motion.duration.fast]);
181
216
  const goPrev = useCallback(() => animateMonthChange(-1), [animateMonthChange]);
182
217
  const goNext = useCallback(() => animateMonthChange(1), [animateMonthChange]);
183
218
  const pressDay = useCallback(cell => {
184
219
  if (isDisabled(cell.date)) return;
185
- triggerHaptic('selection');
220
+ if (theme.components.dateRangePicker?.haptic) triggerHaptic('selection');
186
221
  const target = cell.date;
187
222
 
188
223
  // First tap: pick start. Or, when there's already a complete range, restart.
@@ -201,7 +236,7 @@ const DateRangePicker = /*#__PURE__*/forwardRef((props, ref) => {
201
236
  } else {
202
237
  if (maxRange && daysBetween(pendingStart, target) + 1 > maxRange) {
203
238
  // Reject ranges longer than maxRange — restart from the new tap.
204
- triggerHaptic('notificationWarning');
239
+ if (theme.components.dateRangePicker?.haptic) triggerHaptic('notificationWarning');
205
240
  setPendingStart(target);
206
241
  setPendingEnd(null);
207
242
  return;
@@ -212,35 +247,42 @@ const DateRangePicker = /*#__PURE__*/forwardRef((props, ref) => {
212
247
  if (!cell.inMonth) {
213
248
  setAnchor(new Date(cell.date.getFullYear(), cell.date.getMonth(), 1));
214
249
  }
215
- }, [isDisabled, pendingStart, pendingEnd, maxRange]);
250
+ }, [isDisabled, pendingStart, pendingEnd, maxRange, theme.components.dateRangePicker]);
251
+ const handleCloseModal = useCallback(() => {
252
+ if (isControlled) {
253
+ onClose?.();
254
+ } else {
255
+ setInternalOpen(false);
256
+ }
257
+ }, [isControlled, onClose]);
216
258
  const handleClose = useCallback(() => {
217
259
  Animated.parallel([Animated.timing(backdrop, {
218
260
  toValue: 0,
219
261
  duration: theme.motion.duration.fast,
220
262
  easing: Easing.in(Easing.cubic),
221
- useNativeDriver: true
263
+ useNativeDriver: false
222
264
  }), Animated.timing(sheet, {
223
265
  toValue: 0,
224
266
  duration: theme.motion.duration.fast,
225
267
  easing: Easing.in(Easing.cubic),
226
268
  useNativeDriver: true
227
269
  })]).start(() => {
228
- onClose();
270
+ handleCloseModal();
229
271
  });
230
- }, [backdrop, onClose, sheet, theme.motion.duration.fast]);
272
+ }, [backdrop, handleCloseModal, sheet, theme.motion.duration.fast]);
231
273
  const handleCancel = useCallback(() => {
232
- triggerHaptic('selection');
274
+ if (theme.components.dateRangePicker?.haptic) triggerHaptic('selection');
233
275
  handleClose();
234
- }, [handleClose]);
276
+ }, [handleClose, theme.components.dateRangePicker]);
235
277
  const handleConfirm = useCallback(() => {
236
278
  if (!pendingStart || !pendingEnd) return;
237
- triggerHaptic('notificationSuccess');
238
- onChange({
279
+ if (theme.components.dateRangePicker?.haptic) triggerHaptic('notificationSuccess');
280
+ onChange?.({
239
281
  start: pendingStart,
240
282
  end: pendingEnd
241
283
  });
242
284
  handleClose();
243
- }, [handleClose, onChange, pendingStart, pendingEnd]);
285
+ }, [handleClose, onChange, pendingStart, pendingEnd, theme.components.dateRangePicker]);
244
286
  const sheetTranslate = sheet.interpolate({
245
287
  inputRange: [0, 1],
246
288
  outputRange: [320, 0]
@@ -261,7 +303,7 @@ const DateRangePicker = /*#__PURE__*/forwardRef((props, ref) => {
261
303
  }, [pendingStart, pendingEnd]);
262
304
  const confirmDisabled = !pendingStart || !pendingEnd;
263
305
  const calendar = /*#__PURE__*/_jsxs(View, {
264
- style: [styles.card, style],
306
+ style: [styles.card, style, containerStyle],
265
307
  ref: ref,
266
308
  accessible: false,
267
309
  testID: testID,
@@ -282,7 +324,7 @@ const DateRangePicker = /*#__PURE__*/forwardRef((props, ref) => {
282
324
  onPress: goPrev,
283
325
  style: ({
284
326
  pressed
285
- }) => [styles.navBtn, pressed && styles.navBtnPressed],
327
+ }) => [styles.navBtn, pressed && styles.navBtnPressed, navButtonStyle],
286
328
  accessibilityRole: "button",
287
329
  accessibilityLabel: "Previous month",
288
330
  hitSlop: 8,
@@ -296,7 +338,7 @@ const DateRangePicker = /*#__PURE__*/forwardRef((props, ref) => {
296
338
  transform: [{
297
339
  translateX: monthSlide
298
340
  }]
299
- }],
341
+ }, headerLabelStyle],
300
342
  children: /*#__PURE__*/_jsx(Text, {
301
343
  style: styles.headerLabel,
302
344
  accessibilityLiveRegion: "polite",
@@ -306,7 +348,7 @@ const DateRangePicker = /*#__PURE__*/forwardRef((props, ref) => {
306
348
  onPress: goNext,
307
349
  style: ({
308
350
  pressed
309
- }) => [styles.navBtn, pressed && styles.navBtnPressed],
351
+ }) => [styles.navBtn, pressed && styles.navBtnPressed, navButtonStyle],
310
352
  accessibilityRole: "button",
311
353
  accessibilityLabel: "Next month",
312
354
  hitSlop: 8,
@@ -397,7 +439,7 @@ const DateRangePicker = /*#__PURE__*/forwardRef((props, ref) => {
397
439
  onPress: handleCancel,
398
440
  style: ({
399
441
  pressed
400
- }) => [styles.footerBtn, styles.footerCancel, pressed && styles.footerBtnPressed],
442
+ }) => [styles.footerBtn, styles.footerCancel, pressed && styles.footerBtnPressed, footerButtonStyle],
401
443
  accessibilityRole: "button",
402
444
  accessibilityLabel: cancelLabel,
403
445
  children: /*#__PURE__*/_jsx(Text, {
@@ -416,7 +458,7 @@ const DateRangePicker = /*#__PURE__*/forwardRef((props, ref) => {
416
458
  opacity: confirmDisabled ? 0.5 : 1
417
459
  }, pressed && {
418
460
  backgroundColor: theme.colors.primaryHover
419
- }],
461
+ }, footerButtonStyle],
420
462
  accessibilityRole: "button",
421
463
  accessibilityLabel: confirmLabel,
422
464
  accessibilityState: {
@@ -431,32 +473,64 @@ const DateRangePicker = /*#__PURE__*/forwardRef((props, ref) => {
431
473
  })]
432
474
  })]
433
475
  });
434
- return /*#__PURE__*/_jsxs(Modal, {
435
- visible: visible,
436
- transparent: true,
437
- statusBarTranslucent: true,
438
- animationType: "none",
439
- onRequestClose: handleClose,
440
- children: [/*#__PURE__*/_jsx(Animated.View, {
441
- style: [styles.backdrop, {
442
- opacity: backdrop,
443
- backgroundColor: theme.colors.background.overlay
444
- }],
445
- children: /*#__PURE__*/_jsx(Pressable, {
446
- style: StyleSheet.absoluteFill,
447
- onPress: handleClose,
448
- accessibilityLabel: "Dismiss"
476
+ const triggerValueText = useMemo(() => {
477
+ if (!value.start || !value.end) return '';
478
+ const range = {
479
+ start: value.start,
480
+ end: value.end
481
+ };
482
+ if (formatValue) return formatValue(range);
483
+ return `${range.start.toLocaleDateString()} – ${range.end.toLocaleDateString()}`;
484
+ }, [value.start, value.end, formatValue]);
485
+ return /*#__PURE__*/_jsxs(_Fragment, {
486
+ children: [!isControlled ? /*#__PURE__*/_jsx(PickerTrigger, {
487
+ label: label,
488
+ placeholder: placeholder,
489
+ helperText: helperText,
490
+ error: error,
491
+ required: required,
492
+ disabled: disabled,
493
+ size: size,
494
+ variant: variant,
495
+ clearable: clearable,
496
+ onClear: onClear,
497
+ value: triggerValueText,
498
+ onPress: () => setInternalOpen(true),
499
+ triggerStyle: triggerStyle
500
+ }) : null, /*#__PURE__*/_jsx(Modal, {
501
+ visible: open,
502
+ transparent: true,
503
+ statusBarTranslucent: true
504
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
505
+ // @ts-ignore — Android-only RN 0.71+; iOS ignores it.
506
+ ,
507
+ navigationBarTranslucent: true,
508
+ animationType: "none",
509
+ onRequestClose: handleClose,
510
+ children: /*#__PURE__*/_jsxs(View
511
+ // Backdrop wraps the sheet — see Modal.tsx for the Fabric reason.
512
+ , {
513
+ collapsable: false,
514
+ style: [styles.backdrop, {
515
+ backgroundColor: theme.colors.background.overlay
516
+ }],
517
+ children: [/*#__PURE__*/_jsx(Pressable, {
518
+ style: StyleSheet.absoluteFill,
519
+ onPress: handleClose,
520
+ accessibilityLabel: "Dismiss"
521
+ }), /*#__PURE__*/_jsx(Animated.View, {
522
+ style: [styles.sheetWrap, {
523
+ paddingBottom: insets.bottom + theme.spacing.lg,
524
+ opacity: sheet,
525
+ transform: [{
526
+ translateY: sheetTranslate
527
+ }]
528
+ }],
529
+ accessibilityViewIsModal: true,
530
+ accessibilityRole: "none",
531
+ children: calendar
532
+ })]
449
533
  })
450
- }), /*#__PURE__*/_jsx(Animated.View, {
451
- style: [styles.sheetWrap, {
452
- opacity: sheet,
453
- transform: [{
454
- translateY: sheetTranslate
455
- }]
456
- }],
457
- accessibilityViewIsModal: true,
458
- accessibilityRole: "none",
459
- children: calendar
460
534
  })]
461
535
  });
462
536
  });
@@ -505,8 +579,8 @@ const buildStyles = theme => {
505
579
  marginBottom: theme.spacing.md
506
580
  },
507
581
  navBtn: {
508
- width: 36,
509
- height: 36,
582
+ width: theme.components.dateRangePicker?.navButtonSize ?? 36,
583
+ height: theme.components.dateRangePicker?.navButtonSize ?? 36,
510
584
  borderRadius: theme.radius.full,
511
585
  alignItems: 'center',
512
586
  justifyContent: 'center',
@@ -516,8 +590,8 @@ const buildStyles = theme => {
516
590
  backgroundColor: theme.colors.surface.pressed
517
591
  },
518
592
  navText: {
519
- fontSize: 22,
520
- lineHeight: 24,
593
+ fontSize: theme.components.dateRangePicker?.navTextFontSize ?? 22,
594
+ lineHeight: theme.components.dateRangePicker?.navTextLineHeight ?? 24,
521
595
  color: theme.colors.text.primary,
522
596
  fontWeight: theme.typography.fontWeight.semibold
523
597
  },
@@ -599,7 +673,7 @@ const buildStyles = theme => {
599
673
  paddingHorizontal: theme.spacing.lg,
600
674
  paddingVertical: theme.spacing.sm,
601
675
  borderRadius: theme.radius.md,
602
- minHeight: 40,
676
+ minHeight: theme.components.dateRangePicker?.footerButtonMinHeight ?? 40,
603
677
  alignItems: 'center',
604
678
  justifyContent: 'center'
605
679
  },
@@ -19,6 +19,12 @@ const Dialog = props => {
19
19
  accessibilityLabel,
20
20
  contentStyle,
21
21
  containerStyle,
22
+ titleStyle,
23
+ messageStyle,
24
+ iconWrapperStyle,
25
+ actionsRowStyle,
26
+ actionButtonStyle,
27
+ actionTextStyle,
22
28
  testID
23
29
  } = props;
24
30
  const theme = useTheme();
@@ -30,12 +36,12 @@ const Dialog = props => {
30
36
  const actionButtonMinHeight = dialogTokens?.actionButtonMinHeight ?? 44;
31
37
  const handleAction = useCallback(action => {
32
38
  if (action.loading) return;
33
- triggerHaptic('selection');
39
+ if (dialogTokens?.actionHaptic) triggerHaptic('selection');
34
40
  action.onPress();
35
41
  if (dismissOnAction) {
36
42
  onClose();
37
43
  }
38
- }, [dismissOnAction, onClose]);
44
+ }, [dismissOnAction, onClose, dialogTokens?.actionHaptic]);
39
45
  return /*#__PURE__*/_jsx(Modal, {
40
46
  visible: visible,
41
47
  onRequestClose: onClose,
@@ -44,7 +50,7 @@ const Dialog = props => {
44
50
  contentStyle: contentStyle,
45
51
  testID: testID,
46
52
  children: /*#__PURE__*/_jsxs(View, {
47
- accessibilityRole: 'alertdialog',
53
+ accessibilityRole: "alert",
48
54
  accessibilityLabel: accessibilityLabel ?? title,
49
55
  style: [styles.container, containerStyle],
50
56
  children: [icon ? /*#__PURE__*/_jsx(View, {
@@ -54,7 +60,7 @@ const Dialog = props => {
54
60
  borderRadius: iconWrapperBorderRadius,
55
61
  backgroundColor: variantTint.muted,
56
62
  marginBottom: theme.spacing.md
57
- }],
63
+ }, iconWrapperStyle],
58
64
  children: icon
59
65
  }) : null, title ? /*#__PURE__*/_jsx(Text, {
60
66
  style: [styles.title, {
@@ -62,7 +68,7 @@ const Dialog = props => {
62
68
  fontSize: theme.typography.fontSize.xl,
63
69
  ...fontFor(theme, 'semibold'),
64
70
  marginBottom: message ? theme.spacing.sm : theme.spacing.md
65
- }],
71
+ }, titleStyle],
66
72
  accessibilityRole: "header",
67
73
  children: title
68
74
  }) : null, typeof message === 'string' ? /*#__PURE__*/_jsx(Text, {
@@ -71,7 +77,7 @@ const Dialog = props => {
71
77
  fontSize: theme.typography.fontSize.base,
72
78
  lineHeight: theme.typography.fontSize.base * theme.typography.lineHeight.normal,
73
79
  marginBottom: actions && actions.length > 0 ? theme.spacing.lg : 0
74
- }],
80
+ }, messageStyle],
75
81
  children: message
76
82
  }) : message ? /*#__PURE__*/_jsx(View, {
77
83
  style: {
@@ -79,7 +85,7 @@ const Dialog = props => {
79
85
  },
80
86
  children: message
81
87
  }) : null, actions && actions.length > 0 ? /*#__PURE__*/_jsx(View, {
82
- style: styles.actionsRow,
88
+ style: [styles.actionsRow, actionsRowStyle],
83
89
  children: actions.map((action, index) => {
84
90
  const tone = action.tone ?? 'primary';
85
91
  const buttonStyle = actionStyleFor(theme, tone, variant);
@@ -105,17 +111,17 @@ const Dialog = props => {
105
111
  paddingHorizontal: theme.spacing.lg,
106
112
  marginRight: isLast ? 0 : theme.spacing.sm,
107
113
  opacity: action.loading ? 0.7 : pressed ? 0.85 : 1
108
- }],
114
+ }, actionButtonStyle],
109
115
  children: action.loading ? /*#__PURE__*/_jsx(ActivityIndicator, {
110
116
  size: "small",
111
117
  color: buttonStyle.textColor
112
118
  }) : /*#__PURE__*/_jsx(Text, {
113
- style: {
119
+ style: [{
114
120
  color: buttonStyle.textColor,
115
121
  fontSize: theme.typography.fontSize.base,
116
122
  ...fontFor(theme, 'semibold'),
117
123
  textAlign: 'center'
118
- },
124
+ }, actionTextStyle],
119
125
  numberOfLines: 1,
120
126
  children: action.label
121
127
  })
@@ -28,8 +28,8 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
28
28
  import { useTheme } from "../../theme/index.js";
29
29
  import { triggerHaptic } from "../../utils/index.js";
30
30
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
31
- const CLOSE_VELOCITY_THRESHOLD = 1000;
32
- const DRAG_ACTIVATION_OFFSET = 10;
31
+ const DEFAULT_CLOSE_VELOCITY_THRESHOLD = 1000;
32
+ const DEFAULT_DRAG_ACTIVATION_OFFSET = 10;
33
33
  const Drawer = /*#__PURE__*/forwardRef((props, ref) => {
34
34
  const {
35
35
  visible: controlledVisible,
@@ -48,6 +48,9 @@ const Drawer = /*#__PURE__*/forwardRef((props, ref) => {
48
48
  const theme = useTheme();
49
49
  const insets = useSafeAreaInsets();
50
50
  const isControlled = typeof controlledVisible === 'boolean';
51
+ const drawerTokens = theme.components.drawer;
52
+ const closeVelocityThreshold = drawerTokens?.closeVelocityThreshold ?? DEFAULT_CLOSE_VELOCITY_THRESHOLD;
53
+ const dragActivationOffset = drawerTokens?.dragActivationOffset ?? DEFAULT_DRAG_ACTIVATION_OFFSET;
51
54
  const [windowDims, setWindowDims] = useState(() => Dimensions.get('window'));
52
55
  useEffect(() => {
53
56
  const sub = Dimensions.addEventListener('change', ({
@@ -132,9 +135,9 @@ const Drawer = /*#__PURE__*/forwardRef((props, ref) => {
132
135
  const swipeAllowed = enableSwipe;
133
136
  let g = Gesture.Pan();
134
137
  if (isHorizontal) {
135
- g = g.activeOffsetX([-DRAG_ACTIVATION_OFFSET, DRAG_ACTIVATION_OFFSET]).failOffsetY([-15, 15]);
138
+ g = g.activeOffsetX([-dragActivationOffset, dragActivationOffset]).failOffsetY([-15, 15]);
136
139
  } else {
137
- g = g.activeOffsetY([-DRAG_ACTIVATION_OFFSET, DRAG_ACTIVATION_OFFSET]).failOffsetX([-15, 15]);
140
+ g = g.activeOffsetY([-dragActivationOffset, dragActivationOffset]).failOffsetX([-15, 15]);
138
141
  }
139
142
  return g.onStart(() => {
140
143
  'worklet';
@@ -172,9 +175,9 @@ const Drawer = /*#__PURE__*/forwardRef((props, ref) => {
172
175
  // bottom → positive Y
173
176
  let isFastClose = false;
174
177
  if (sideValue === 'left' || sideValue === 'top') {
175
- isFastClose = velocity < -CLOSE_VELOCITY_THRESHOLD;
178
+ isFastClose = velocity < -closeVelocityThreshold;
176
179
  } else {
177
- isFastClose = velocity > CLOSE_VELOCITY_THRESHOLD;
180
+ isFastClose = velocity > closeVelocityThreshold;
178
181
  }
179
182
  const closedAbs = Math.abs(closed);
180
183
  const traveledClosed = Math.abs(releaseOffset) / closedAbs; // 0 = open, 1 = closed
@@ -187,7 +190,7 @@ const Drawer = /*#__PURE__*/forwardRef((props, ref) => {
187
190
  offset.value = withSpring(0, springCfg);
188
191
  }
189
192
  });
190
- }, [closedOffset, dragStart, enableSwipe, isHorizontal, offset, setOpenJS, side, springCfg]);
193
+ }, [closedOffset, dragStart, enableSwipe, isHorizontal, offset, setOpenJS, side, springCfg, closeVelocityThreshold, dragActivationOffset]);
191
194
 
192
195
  // ───────── Animated styles ─────────
193
196
  const sheetStyle = useAnimatedStyle(() => {
@@ -216,9 +219,9 @@ const Drawer = /*#__PURE__*/forwardRef((props, ref) => {
216
219
  const styles = useMemo(() => buildStyles(theme), [theme]);
217
220
  const handleBackdropPress = useCallback(() => {
218
221
  if (!enableBackdropPress) return;
219
- triggerHaptic('selection');
222
+ if (drawerTokens?.backdropPressHaptic) triggerHaptic('selection');
220
223
  close();
221
- }, [enableBackdropPress, close]);
224
+ }, [enableBackdropPress, close, drawerTokens?.backdropPressHaptic]);
222
225
 
223
226
  // Per-side container layout — must be a hook on every render path so we
224
227
  // can't gate it on the lazy-mount early-return below.
@@ -297,7 +300,7 @@ const Drawer = /*#__PURE__*/forwardRef((props, ref) => {
297
300
  }), /*#__PURE__*/_jsx(GestureDetector, {
298
301
  gesture: panGesture,
299
302
  children: /*#__PURE__*/_jsx(Animated.View, {
300
- accessibilityRole: 'dialog',
303
+ accessibilityRole: "alert",
301
304
  accessibilityLabel: accessibilityLabel ?? 'Drawer',
302
305
  accessibilityViewIsModal: isOpen,
303
306
  style: [sideLayout, {