@webority-technologies/mobile 0.0.15 → 0.0.21
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.
- package/lib/commonjs/components/Accordion/Accordion.js +60 -19
- package/lib/commonjs/components/AppBar/AppBar.js +29 -20
- package/lib/commonjs/components/Avatar/Avatar.js +38 -8
- package/lib/commonjs/components/Badge/Badge.js +66 -4
- package/lib/commonjs/components/Banner/Banner.js +146 -66
- package/lib/commonjs/components/BottomNavigation/BottomNavigation.js +37 -15
- package/lib/commonjs/components/BottomSheet/BottomSheet.js +78 -53
- package/lib/commonjs/components/Button/Button.js +12 -5
- package/lib/commonjs/components/Card/Card.js +106 -16
- package/lib/commonjs/components/Carousel/Carousel.js +66 -12
- package/lib/commonjs/components/Checkbox/Checkbox.js +11 -7
- package/lib/commonjs/components/Chip/Chip.js +44 -12
- package/lib/commonjs/components/DatePicker/DatePicker.js +185 -76
- package/lib/commonjs/components/DateRangePicker/DateRangePicker.js +133 -59
- package/lib/commonjs/components/Dialog/Dialog.js +16 -10
- package/lib/commonjs/components/Drawer/Drawer.js +13 -10
- package/lib/commonjs/components/FieldBase/FieldBase.js +494 -0
- package/lib/commonjs/components/FieldBase/index.js +32 -0
- package/lib/commonjs/components/FloatingActionButton/FloatingActionButton.js +69 -44
- package/lib/commonjs/components/ForceUpdateDialog/ForceUpdateDialog.js +8 -2
- package/lib/commonjs/components/FormField/FormField.js +3 -2
- package/lib/commonjs/components/ImageGallery/ImageGallery.js +132 -44
- package/lib/commonjs/components/Input/Input.js +144 -181
- package/lib/commonjs/components/ListItem/ListItem.js +90 -11
- package/lib/commonjs/components/Modal/Modal.js +55 -27
- package/lib/commonjs/components/NumberInput/NumberInput.js +60 -106
- package/lib/commonjs/components/OTPInput/OTPInput.js +65 -58
- package/lib/commonjs/components/PickerTrigger/PickerTrigger.js +185 -0
- package/lib/commonjs/components/{AppIcon → PickerTrigger}/index.js +4 -4
- package/lib/commonjs/components/ProgressBar/ProgressBar.js +19 -11
- package/lib/commonjs/components/Radio/Radio.js +11 -6
- package/lib/commonjs/components/Rating/Rating.js +85 -19
- package/lib/commonjs/components/SearchBar/SearchBar.js +90 -107
- package/lib/commonjs/components/SegmentedControl/SegmentedControl.js +22 -11
- package/lib/commonjs/components/Select/Select.js +62 -91
- package/lib/commonjs/components/Skeleton/Skeleton.js +131 -174
- package/lib/commonjs/components/Skeleton/SkeletonClock.js +117 -0
- package/lib/commonjs/components/Skeleton/SkeletonContent.js +164 -81
- package/lib/commonjs/components/Skeleton/SkeletonProvider.js +72 -10
- package/lib/commonjs/components/Skeleton/index.js +17 -16
- package/lib/commonjs/components/Slider/Slider.js +44 -25
- package/lib/commonjs/components/Stepper/Stepper.js +199 -29
- package/lib/commonjs/components/Swipeable/Swipeable.js +36 -19
- package/lib/commonjs/components/Switch/Switch.js +9 -2
- package/lib/commonjs/components/Tabs/Tabs.js +84 -21
- package/lib/commonjs/components/TimePicker/TimePicker.js +123 -45
- package/lib/commonjs/components/Toast/Toast.js +27 -16
- package/lib/commonjs/components/Tooltip/Tooltip.js +56 -32
- package/lib/commonjs/components/index.js +37 -37
- package/lib/commonjs/theme/tokens.js +55 -7
- package/lib/module/components/Accordion/Accordion.js +61 -20
- package/lib/module/components/AppBar/AppBar.js +29 -20
- package/lib/module/components/Avatar/Avatar.js +39 -9
- package/lib/module/components/Badge/Badge.js +67 -5
- package/lib/module/components/Banner/Banner.js +147 -67
- package/lib/module/components/BottomNavigation/BottomNavigation.js +37 -15
- package/lib/module/components/BottomSheet/BottomSheet.js +80 -55
- package/lib/module/components/Button/Button.js +12 -5
- package/lib/module/components/Card/Card.js +107 -17
- package/lib/module/components/Carousel/Carousel.js +67 -13
- package/lib/module/components/Checkbox/Checkbox.js +11 -7
- package/lib/module/components/Chip/Chip.js +45 -13
- package/lib/module/components/DatePicker/DatePicker.js +185 -76
- package/lib/module/components/DateRangePicker/DateRangePicker.js +134 -60
- package/lib/module/components/Dialog/Dialog.js +16 -10
- package/lib/module/components/Drawer/Drawer.js +13 -10
- package/lib/module/components/FieldBase/FieldBase.js +485 -0
- package/lib/module/components/FieldBase/index.js +4 -0
- package/lib/module/components/FloatingActionButton/FloatingActionButton.js +69 -44
- package/lib/module/components/ForceUpdateDialog/ForceUpdateDialog.js +8 -2
- package/lib/module/components/FormField/FormField.js +3 -2
- package/lib/module/components/ImageGallery/ImageGallery.js +128 -40
- package/lib/module/components/Input/Input.js +144 -179
- package/lib/module/components/ListItem/ListItem.js +91 -12
- package/lib/module/components/Modal/Modal.js +55 -27
- package/lib/module/components/NumberInput/NumberInput.js +60 -106
- package/lib/module/components/OTPInput/OTPInput.js +65 -58
- package/lib/module/components/PickerTrigger/PickerTrigger.js +181 -0
- package/lib/module/components/PickerTrigger/index.js +4 -0
- package/lib/module/components/ProgressBar/ProgressBar.js +19 -11
- package/lib/module/components/Radio/Radio.js +11 -6
- package/lib/module/components/Rating/Rating.js +86 -20
- package/lib/module/components/SearchBar/SearchBar.js +90 -107
- package/lib/module/components/SegmentedControl/SegmentedControl.js +22 -11
- package/lib/module/components/Select/Select.js +62 -91
- package/lib/module/components/Skeleton/Skeleton.js +135 -175
- package/lib/module/components/Skeleton/SkeletonClock.js +110 -0
- package/lib/module/components/Skeleton/SkeletonContent.js +167 -84
- package/lib/module/components/Skeleton/SkeletonProvider.js +71 -10
- package/lib/module/components/Skeleton/index.js +3 -2
- package/lib/module/components/Slider/Slider.js +44 -25
- package/lib/module/components/Stepper/Stepper.js +201 -31
- package/lib/module/components/Swipeable/Swipeable.js +36 -19
- package/lib/module/components/Switch/Switch.js +9 -2
- package/lib/module/components/Tabs/Tabs.js +84 -21
- package/lib/module/components/TimePicker/TimePicker.js +123 -45
- package/lib/module/components/Toast/Toast.js +27 -16
- package/lib/module/components/Tooltip/Tooltip.js +56 -32
- package/lib/module/components/index.js +2 -2
- package/lib/module/theme/tokens.js +55 -7
- package/lib/typescript/commonjs/components/Accordion/Accordion.d.ts +10 -5
- package/lib/typescript/commonjs/components/AppBar/AppBar.d.ts +8 -0
- package/lib/typescript/commonjs/components/Avatar/Avatar.d.ts +12 -6
- package/lib/typescript/commonjs/components/Badge/Badge.d.ts +7 -6
- package/lib/typescript/commonjs/components/Banner/Banner.d.ts +17 -6
- package/lib/typescript/commonjs/components/BottomSheet/BottomSheet.d.ts +7 -0
- package/lib/typescript/commonjs/components/Card/Card.d.ts +17 -6
- package/lib/typescript/commonjs/components/Carousel/Carousel.d.ts +7 -6
- package/lib/typescript/commonjs/components/Checkbox/Checkbox.d.ts +9 -1
- package/lib/typescript/commonjs/components/Chip/Chip.d.ts +13 -6
- package/lib/typescript/commonjs/components/DatePicker/DatePicker.d.ts +38 -3
- package/lib/typescript/commonjs/components/DateRangePicker/DateRangePicker.d.ts +36 -3
- package/lib/typescript/commonjs/components/Dialog/Dialog.d.ts +13 -1
- package/lib/typescript/commonjs/components/FieldBase/FieldBase.d.ts +172 -0
- package/lib/typescript/commonjs/components/FieldBase/index.d.ts +3 -0
- package/lib/typescript/commonjs/components/FloatingActionButton/FloatingActionButton.d.ts +8 -6
- package/lib/typescript/commonjs/components/FloatingActionButton/index.d.ts +1 -1
- package/lib/typescript/commonjs/components/ForceUpdateDialog/ForceUpdateDialog.d.ts +7 -0
- package/lib/typescript/commonjs/components/FormField/FormField.d.ts +7 -0
- package/lib/typescript/commonjs/components/ImageGallery/ImageGallery.d.ts +6 -4
- package/lib/typescript/commonjs/components/Input/Input.d.ts +7 -1
- package/lib/typescript/commonjs/components/ListItem/ListItem.d.ts +13 -6
- package/lib/typescript/commonjs/components/NumberInput/NumberInput.d.ts +3 -0
- package/lib/typescript/commonjs/components/PickerTrigger/PickerTrigger.d.ts +57 -0
- package/lib/typescript/commonjs/components/PickerTrigger/index.d.ts +3 -0
- package/lib/typescript/commonjs/components/ProgressBar/ProgressBar.d.ts +2 -0
- package/lib/typescript/commonjs/components/Radio/Radio.d.ts +3 -0
- package/lib/typescript/commonjs/components/Rating/Rating.d.ts +9 -6
- package/lib/typescript/commonjs/components/SegmentedControl/SegmentedControl.d.ts +3 -0
- package/lib/typescript/commonjs/components/Skeleton/Skeleton.d.ts +49 -20
- package/lib/typescript/commonjs/components/Skeleton/SkeletonClock.d.ts +60 -0
- package/lib/typescript/commonjs/components/Skeleton/SkeletonContent.d.ts +80 -19
- package/lib/typescript/commonjs/components/Skeleton/SkeletonProvider.d.ts +39 -5
- package/lib/typescript/commonjs/components/Skeleton/index.d.ts +6 -4
- package/lib/typescript/commonjs/components/Slider/Slider.d.ts +12 -1
- package/lib/typescript/commonjs/components/Stepper/Stepper.d.ts +18 -6
- package/lib/typescript/commonjs/components/Swipeable/Swipeable.d.ts +2 -0
- package/lib/typescript/commonjs/components/Switch/Switch.d.ts +1 -0
- package/lib/typescript/commonjs/components/Tabs/Tabs.d.ts +26 -2
- package/lib/typescript/commonjs/components/TimePicker/TimePicker.d.ts +36 -3
- package/lib/typescript/commonjs/components/Toast/Toast.d.ts +8 -0
- package/lib/typescript/commonjs/components/Tooltip/Tooltip.d.ts +7 -1
- package/lib/typescript/commonjs/components/index.d.ts +5 -5
- package/lib/typescript/commonjs/index.d.ts +1 -1
- package/lib/typescript/commonjs/theme/index.d.ts +1 -1
- package/lib/typescript/commonjs/theme/types.d.ts +578 -12
- package/lib/typescript/module/components/Accordion/Accordion.d.ts +10 -5
- package/lib/typescript/module/components/AppBar/AppBar.d.ts +8 -0
- package/lib/typescript/module/components/Avatar/Avatar.d.ts +12 -6
- package/lib/typescript/module/components/Badge/Badge.d.ts +7 -6
- package/lib/typescript/module/components/Banner/Banner.d.ts +17 -6
- package/lib/typescript/module/components/BottomSheet/BottomSheet.d.ts +7 -0
- package/lib/typescript/module/components/Card/Card.d.ts +17 -6
- package/lib/typescript/module/components/Carousel/Carousel.d.ts +7 -6
- package/lib/typescript/module/components/Checkbox/Checkbox.d.ts +9 -1
- package/lib/typescript/module/components/Chip/Chip.d.ts +13 -6
- package/lib/typescript/module/components/DatePicker/DatePicker.d.ts +38 -3
- package/lib/typescript/module/components/DateRangePicker/DateRangePicker.d.ts +36 -3
- package/lib/typescript/module/components/Dialog/Dialog.d.ts +13 -1
- package/lib/typescript/module/components/FieldBase/FieldBase.d.ts +172 -0
- package/lib/typescript/module/components/FieldBase/index.d.ts +3 -0
- package/lib/typescript/module/components/FloatingActionButton/FloatingActionButton.d.ts +8 -6
- package/lib/typescript/module/components/FloatingActionButton/index.d.ts +1 -1
- package/lib/typescript/module/components/ForceUpdateDialog/ForceUpdateDialog.d.ts +7 -0
- package/lib/typescript/module/components/FormField/FormField.d.ts +7 -0
- package/lib/typescript/module/components/ImageGallery/ImageGallery.d.ts +6 -4
- package/lib/typescript/module/components/Input/Input.d.ts +7 -1
- package/lib/typescript/module/components/ListItem/ListItem.d.ts +13 -6
- package/lib/typescript/module/components/NumberInput/NumberInput.d.ts +3 -0
- package/lib/typescript/module/components/PickerTrigger/PickerTrigger.d.ts +57 -0
- package/lib/typescript/module/components/PickerTrigger/index.d.ts +3 -0
- package/lib/typescript/module/components/ProgressBar/ProgressBar.d.ts +2 -0
- package/lib/typescript/module/components/Radio/Radio.d.ts +3 -0
- package/lib/typescript/module/components/Rating/Rating.d.ts +9 -6
- package/lib/typescript/module/components/SegmentedControl/SegmentedControl.d.ts +3 -0
- package/lib/typescript/module/components/Skeleton/Skeleton.d.ts +49 -20
- package/lib/typescript/module/components/Skeleton/SkeletonClock.d.ts +60 -0
- package/lib/typescript/module/components/Skeleton/SkeletonContent.d.ts +80 -19
- package/lib/typescript/module/components/Skeleton/SkeletonProvider.d.ts +39 -5
- package/lib/typescript/module/components/Skeleton/index.d.ts +6 -4
- package/lib/typescript/module/components/Slider/Slider.d.ts +12 -1
- package/lib/typescript/module/components/Stepper/Stepper.d.ts +18 -6
- package/lib/typescript/module/components/Swipeable/Swipeable.d.ts +2 -0
- package/lib/typescript/module/components/Switch/Switch.d.ts +1 -0
- package/lib/typescript/module/components/Tabs/Tabs.d.ts +26 -2
- package/lib/typescript/module/components/TimePicker/TimePicker.d.ts +36 -3
- package/lib/typescript/module/components/Toast/Toast.d.ts +8 -0
- package/lib/typescript/module/components/Tooltip/Tooltip.d.ts +7 -1
- package/lib/typescript/module/components/index.d.ts +5 -5
- package/lib/typescript/module/index.d.ts +1 -1
- package/lib/typescript/module/theme/index.d.ts +1 -1
- package/lib/typescript/module/theme/types.d.ts +578 -12
- package/package.json +2 -6
- package/lib/commonjs/components/AppIcon/AppIcon.js +0 -120
- package/lib/commonjs/types/vector-icons.d.js +0 -2
- package/lib/module/components/AppIcon/AppIcon.js +0 -111
- package/lib/module/components/AppIcon/index.js +0 -4
- package/lib/module/types/vector-icons.d.js +0 -2
- package/lib/typescript/commonjs/components/AppIcon/AppIcon.d.ts +0 -20
- package/lib/typescript/commonjs/components/AppIcon/index.d.ts +0 -3
- package/lib/typescript/module/components/AppIcon/AppIcon.d.ts +0 -20
- package/lib/typescript/module/components/AppIcon/index.d.ts +0 -3
|
@@ -2,8 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
import React, { 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";
|
|
8
|
+
import { PickerTrigger } from "../PickerTrigger/index.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* DatePicker operates in two modes:
|
|
12
|
+
*
|
|
13
|
+
* 1. **Controlled-modal mode** — pass `visible` (plus `onSelect` / `onClose`)
|
|
14
|
+
* and own the open state externally. The component renders only the modal.
|
|
15
|
+
* 2. **Trigger mode** — omit `visible`. The component renders a built-in
|
|
16
|
+
* PickerTrigger field (label / value / placeholder / chevron / clear /
|
|
17
|
+
* helper / error / size / variant) and manages its own open state. The
|
|
18
|
+
* field opens the modal on press and closes it on confirm/cancel.
|
|
19
|
+
*
|
|
20
|
+
* `onSelect` / `onClose` are typed optional to support trigger-only usage
|
|
21
|
+
* where the consumer may not need either callback. In controlled-modal mode
|
|
22
|
+
* they remain semantically required.
|
|
23
|
+
*/
|
|
7
24
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
8
25
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
9
26
|
const GRID_SIZE = 12; // 4 cols x 3 rows for year / decade grids
|
|
@@ -81,7 +98,6 @@ const buildDecadeCells = anchorYear => {
|
|
|
81
98
|
};
|
|
82
99
|
const DatePicker = props => {
|
|
83
100
|
const {
|
|
84
|
-
visible,
|
|
85
101
|
value,
|
|
86
102
|
onSelect,
|
|
87
103
|
onClose,
|
|
@@ -95,9 +111,32 @@ const DatePicker = props => {
|
|
|
95
111
|
confirmLabel = 'Confirm',
|
|
96
112
|
cancelLabel = 'Cancel',
|
|
97
113
|
style,
|
|
98
|
-
|
|
114
|
+
containerStyle,
|
|
115
|
+
headerLabelStyle,
|
|
116
|
+
navButtonStyle,
|
|
117
|
+
footerButtonStyle,
|
|
118
|
+
testID,
|
|
119
|
+
label,
|
|
120
|
+
placeholder,
|
|
121
|
+
helperText,
|
|
122
|
+
error,
|
|
123
|
+
required,
|
|
124
|
+
disabled,
|
|
125
|
+
size,
|
|
126
|
+
variant,
|
|
127
|
+
clearable,
|
|
128
|
+
onClear,
|
|
129
|
+
formatValue,
|
|
130
|
+
triggerStyle
|
|
99
131
|
} = props;
|
|
132
|
+
|
|
133
|
+
// Controlled vs uncontrolled detection: if `visible` is supplied (even
|
|
134
|
+
// `false`), the consumer owns the open state; otherwise we own it.
|
|
135
|
+
const isControlled = props.visible !== undefined;
|
|
136
|
+
const [internalOpen, setInternalOpen] = useState(false);
|
|
137
|
+
const open = isControlled ? props.visible : internalOpen;
|
|
100
138
|
const theme = useTheme();
|
|
139
|
+
const insets = useSafeAreaInsets();
|
|
101
140
|
const styles = useMemo(() => buildStyles(theme), [theme]);
|
|
102
141
|
const today = useMemo(() => startOfDay(new Date()), []);
|
|
103
142
|
const initialAnchor = value ? startOfDay(value) : today;
|
|
@@ -126,17 +165,20 @@ const DatePicker = props => {
|
|
|
126
165
|
}
|
|
127
166
|
}, [value]);
|
|
128
167
|
|
|
129
|
-
// Modal open / close animation.
|
|
168
|
+
// Modal open / close animation. Backdrop opacity runs on JS driver — see
|
|
169
|
+
// Modal.tsx for the RN 0.85 / Fabric two-bug reason (view flattening +
|
|
170
|
+
// native-driver opacity on Animated.View with backgroundColor). Sheet
|
|
171
|
+
// transform stays native.
|
|
130
172
|
useEffect(() => {
|
|
131
173
|
if (mode !== 'modal') return;
|
|
132
|
-
if (
|
|
133
|
-
|
|
174
|
+
if (open) {
|
|
175
|
+
backdrop.setValue(0);
|
|
134
176
|
setNativeValue(sheet, 0);
|
|
135
177
|
Animated.parallel([Animated.timing(backdrop, {
|
|
136
178
|
toValue: 1,
|
|
137
179
|
duration: theme.motion.duration.normal,
|
|
138
180
|
easing: Easing.out(Easing.cubic),
|
|
139
|
-
useNativeDriver:
|
|
181
|
+
useNativeDriver: false
|
|
140
182
|
}), Animated.spring(sheet, {
|
|
141
183
|
toValue: 1,
|
|
142
184
|
damping: theme.motion.spring.gentle.damping,
|
|
@@ -145,7 +187,7 @@ const DatePicker = props => {
|
|
|
145
187
|
useNativeDriver: true
|
|
146
188
|
})]).start();
|
|
147
189
|
}
|
|
148
|
-
}, [
|
|
190
|
+
}, [open, mode, backdrop, sheet, theme.motion]);
|
|
149
191
|
const disabledIsoSet = useMemo(() => {
|
|
150
192
|
const set = new Set();
|
|
151
193
|
disabledDates?.forEach(d => set.add(toIso(startOfDay(d))));
|
|
@@ -186,17 +228,19 @@ const DatePicker = props => {
|
|
|
186
228
|
return false;
|
|
187
229
|
}, [minDay, maxDay]);
|
|
188
230
|
const animateMonthChange = useCallback(delta => {
|
|
189
|
-
triggerHaptic('impactLight');
|
|
231
|
+
if (theme.components.datePicker?.haptic) triggerHaptic('impactLight');
|
|
190
232
|
const direction = delta > 0 ? 1 : -1;
|
|
191
|
-
const distance = 32;
|
|
233
|
+
const distance = theme.components.datePicker?.monthSlideDistance ?? 32;
|
|
234
|
+
const outDuration = theme.components.datePicker?.monthSlideOutDuration ?? theme.motion.duration.fast ?? 140;
|
|
235
|
+
const inDuration = theme.components.datePicker?.monthSlideInDuration ?? theme.motion.duration.fast ?? 160;
|
|
192
236
|
Animated.sequence([Animated.parallel([Animated.timing(monthSlide, {
|
|
193
237
|
toValue: -direction * distance,
|
|
194
|
-
duration:
|
|
238
|
+
duration: outDuration,
|
|
195
239
|
easing: Easing.out(Easing.quad),
|
|
196
240
|
useNativeDriver: true
|
|
197
241
|
}), Animated.timing(monthFade, {
|
|
198
242
|
toValue: 0,
|
|
199
|
-
duration:
|
|
243
|
+
duration: outDuration,
|
|
200
244
|
useNativeDriver: true
|
|
201
245
|
})]), Animated.timing(monthSlide, {
|
|
202
246
|
toValue: direction * distance,
|
|
@@ -204,68 +248,71 @@ const DatePicker = props => {
|
|
|
204
248
|
useNativeDriver: true
|
|
205
249
|
}), Animated.parallel([Animated.timing(monthSlide, {
|
|
206
250
|
toValue: 0,
|
|
207
|
-
duration:
|
|
251
|
+
duration: inDuration,
|
|
208
252
|
easing: Easing.out(Easing.cubic),
|
|
209
253
|
useNativeDriver: true
|
|
210
254
|
}), Animated.timing(monthFade, {
|
|
211
255
|
toValue: 1,
|
|
212
|
-
duration:
|
|
256
|
+
duration: inDuration,
|
|
213
257
|
useNativeDriver: true
|
|
214
258
|
})])]).start();
|
|
215
259
|
const next = addMonths(anchor, delta);
|
|
216
260
|
setAnchor(next);
|
|
217
261
|
AccessibilityInfo.announceForAccessibility(formatMonthYear(next, locale));
|
|
218
|
-
}, [anchor, locale, monthFade, monthSlide]);
|
|
262
|
+
}, [anchor, locale, monthFade, monthSlide, theme.components.datePicker, theme.motion.duration.fast]);
|
|
219
263
|
const goPrev = useCallback(() => {
|
|
220
264
|
if (viewMode === 'days') {
|
|
221
265
|
animateMonthChange(-1);
|
|
222
266
|
return;
|
|
223
267
|
}
|
|
224
|
-
triggerHaptic('impactLight');
|
|
268
|
+
if (theme.components.datePicker?.haptic) triggerHaptic('impactLight');
|
|
225
269
|
if (viewMode === 'years') {
|
|
226
270
|
setAnchor(prev => new Date(prev.getFullYear() - GRID_SIZE, prev.getMonth(), 1));
|
|
227
271
|
} else {
|
|
228
272
|
setAnchor(prev => new Date(prev.getFullYear() - GRID_SIZE * DECADE_SPAN, prev.getMonth(), 1));
|
|
229
273
|
}
|
|
230
|
-
}, [animateMonthChange, viewMode]);
|
|
274
|
+
}, [animateMonthChange, viewMode, theme.components.datePicker]);
|
|
231
275
|
const goNext = useCallback(() => {
|
|
232
276
|
if (viewMode === 'days') {
|
|
233
277
|
animateMonthChange(1);
|
|
234
278
|
return;
|
|
235
279
|
}
|
|
236
|
-
triggerHaptic('impactLight');
|
|
280
|
+
if (theme.components.datePicker?.haptic) triggerHaptic('impactLight');
|
|
237
281
|
if (viewMode === 'years') {
|
|
238
282
|
setAnchor(prev => new Date(prev.getFullYear() + GRID_SIZE, prev.getMonth(), 1));
|
|
239
283
|
} else {
|
|
240
284
|
setAnchor(prev => new Date(prev.getFullYear() + GRID_SIZE * DECADE_SPAN, prev.getMonth(), 1));
|
|
241
285
|
}
|
|
242
|
-
}, [animateMonthChange, viewMode]);
|
|
286
|
+
}, [animateMonthChange, viewMode, theme.components.datePicker]);
|
|
243
287
|
|
|
244
|
-
// View-mode transition: fade + scale
|
|
288
|
+
// View-mode transition: fade + scale, native driver.
|
|
245
289
|
const animateViewTransition = useCallback(() => {
|
|
290
|
+
const dur = theme.components.datePicker?.viewTransitionDuration ?? theme.motion.duration.normal ?? 200;
|
|
246
291
|
setNativeValue(viewFade, 0);
|
|
247
292
|
setNativeValue(viewScale, 0.9);
|
|
248
293
|
Animated.parallel([Animated.timing(viewFade, {
|
|
249
294
|
toValue: 1,
|
|
250
|
-
duration:
|
|
295
|
+
duration: dur,
|
|
251
296
|
easing: Easing.out(Easing.cubic),
|
|
252
297
|
useNativeDriver: true
|
|
253
298
|
}), Animated.timing(viewScale, {
|
|
254
299
|
toValue: 1,
|
|
255
|
-
duration:
|
|
300
|
+
duration: dur,
|
|
256
301
|
easing: Easing.out(Easing.cubic),
|
|
257
302
|
useNativeDriver: true
|
|
258
303
|
})]).start();
|
|
259
|
-
}, [viewFade, viewScale]);
|
|
304
|
+
}, [viewFade, viewScale, theme.components.datePicker, theme.motion.duration.normal]);
|
|
260
305
|
const cycleViewMode = useCallback(() => {
|
|
261
|
-
triggerHaptic('selection');
|
|
306
|
+
if (theme.components.datePicker?.haptic) triggerHaptic('selection');
|
|
307
|
+
const pressDur = theme.components.datePicker?.headerPressDuration ?? 80;
|
|
308
|
+
const releaseDur = theme.components.datePicker?.headerReleaseDuration ?? 100;
|
|
262
309
|
Animated.sequence([Animated.timing(headerScale, {
|
|
263
310
|
toValue: 0.96,
|
|
264
|
-
duration:
|
|
311
|
+
duration: pressDur,
|
|
265
312
|
useNativeDriver: true
|
|
266
313
|
}), Animated.timing(headerScale, {
|
|
267
314
|
toValue: 1,
|
|
268
|
-
duration:
|
|
315
|
+
duration: releaseDur,
|
|
269
316
|
useNativeDriver: true
|
|
270
317
|
})]).start();
|
|
271
318
|
setViewMode(prev => {
|
|
@@ -274,23 +321,23 @@ const DatePicker = props => {
|
|
|
274
321
|
return 'years';
|
|
275
322
|
});
|
|
276
323
|
animateViewTransition();
|
|
277
|
-
}, [animateViewTransition, headerScale]);
|
|
324
|
+
}, [animateViewTransition, headerScale, theme.components.datePicker]);
|
|
278
325
|
const pickYear = useCallback(year => {
|
|
279
|
-
triggerHaptic('selection');
|
|
326
|
+
if (theme.components.datePicker?.haptic) triggerHaptic('selection');
|
|
280
327
|
setAnchor(prev => new Date(year, prev.getMonth(), 1));
|
|
281
328
|
setViewMode('days');
|
|
282
329
|
animateViewTransition();
|
|
283
|
-
}, [animateViewTransition]);
|
|
330
|
+
}, [animateViewTransition, theme.components.datePicker]);
|
|
284
331
|
const pickDecade = useCallback(decadeStart => {
|
|
285
|
-
triggerHaptic('selection');
|
|
332
|
+
if (theme.components.datePicker?.haptic) triggerHaptic('selection');
|
|
286
333
|
// Anchor mid-decade so the year grid centers nicely on this decade.
|
|
287
334
|
setAnchor(prev => new Date(decadeStart + 4, prev.getMonth(), 1));
|
|
288
335
|
setViewMode('years');
|
|
289
336
|
animateViewTransition();
|
|
290
|
-
}, [animateViewTransition]);
|
|
337
|
+
}, [animateViewTransition, theme.components.datePicker]);
|
|
291
338
|
const pressDay = useCallback(cell => {
|
|
292
339
|
if (isDisabled(cell.date)) return;
|
|
293
|
-
triggerHaptic('selection');
|
|
340
|
+
if (theme.components.datePicker?.haptic) triggerHaptic('selection');
|
|
294
341
|
setPendingDate(cell.date);
|
|
295
342
|
if (!cell.inMonth) {
|
|
296
343
|
setAnchor(new Date(cell.date.getFullYear(), cell.date.getMonth(), 1));
|
|
@@ -303,42 +350,50 @@ const DatePicker = props => {
|
|
|
303
350
|
mass: theme.motion.spring.bouncy.mass,
|
|
304
351
|
useNativeDriver: true
|
|
305
352
|
}).start();
|
|
306
|
-
}, [isDisabled, selectScale, theme.motion.spring.bouncy]);
|
|
353
|
+
}, [isDisabled, selectScale, theme.motion.spring.bouncy, theme.components.datePicker]);
|
|
354
|
+
const finalizeClose = useCallback(() => {
|
|
355
|
+
if (isControlled) {
|
|
356
|
+
onClose?.();
|
|
357
|
+
} else {
|
|
358
|
+
setInternalOpen(false);
|
|
359
|
+
onClose?.();
|
|
360
|
+
}
|
|
361
|
+
}, [isControlled, onClose]);
|
|
307
362
|
const handleClose = useCallback(() => {
|
|
308
363
|
if (mode !== 'modal') {
|
|
309
|
-
|
|
364
|
+
finalizeClose();
|
|
310
365
|
return;
|
|
311
366
|
}
|
|
312
367
|
Animated.parallel([Animated.timing(backdrop, {
|
|
313
368
|
toValue: 0,
|
|
314
369
|
duration: theme.motion.duration.fast,
|
|
315
370
|
easing: Easing.in(Easing.cubic),
|
|
316
|
-
useNativeDriver:
|
|
371
|
+
useNativeDriver: false
|
|
317
372
|
}), Animated.timing(sheet, {
|
|
318
373
|
toValue: 0,
|
|
319
374
|
duration: theme.motion.duration.fast,
|
|
320
375
|
easing: Easing.in(Easing.cubic),
|
|
321
376
|
useNativeDriver: true
|
|
322
377
|
})]).start(() => {
|
|
323
|
-
|
|
378
|
+
finalizeClose();
|
|
324
379
|
});
|
|
325
|
-
}, [backdrop, mode,
|
|
380
|
+
}, [backdrop, mode, finalizeClose, sheet, theme.motion.duration.fast]);
|
|
326
381
|
const handleCancel = useCallback(() => {
|
|
327
|
-
triggerHaptic('selection');
|
|
382
|
+
if (theme.components.datePicker?.haptic) triggerHaptic('selection');
|
|
328
383
|
handleClose();
|
|
329
|
-
}, [handleClose]);
|
|
384
|
+
}, [handleClose, theme.components.datePicker]);
|
|
330
385
|
const handleConfirm = useCallback(() => {
|
|
331
386
|
if (!pendingDate) return;
|
|
332
|
-
triggerHaptic('notificationSuccess');
|
|
333
|
-
onSelect(pendingDate);
|
|
387
|
+
if (theme.components.datePicker?.haptic) triggerHaptic('notificationSuccess');
|
|
388
|
+
onSelect?.(pendingDate);
|
|
334
389
|
handleClose();
|
|
335
|
-
}, [handleClose, onSelect, pendingDate]);
|
|
390
|
+
}, [handleClose, onSelect, pendingDate, theme.components.datePicker]);
|
|
336
391
|
const sheetTranslate = sheet.interpolate({
|
|
337
392
|
inputRange: [0, 1],
|
|
338
393
|
outputRange: [320, 0]
|
|
339
394
|
});
|
|
340
395
|
const calendar = /*#__PURE__*/_jsxs(View, {
|
|
341
|
-
style: [styles.card, style],
|
|
396
|
+
style: [styles.card, style, containerStyle],
|
|
342
397
|
accessibilityRole: mode === 'modal' ? undefined : 'none',
|
|
343
398
|
accessible: false,
|
|
344
399
|
testID: testID,
|
|
@@ -355,7 +410,7 @@ const DatePicker = props => {
|
|
|
355
410
|
onPress: goPrev,
|
|
356
411
|
style: ({
|
|
357
412
|
pressed
|
|
358
|
-
}) => [styles.navBtn, pressed && styles.navBtnPressed],
|
|
413
|
+
}) => [styles.navBtn, pressed && styles.navBtnPressed, navButtonStyle],
|
|
359
414
|
accessibilityRole: "button",
|
|
360
415
|
accessibilityLabel: viewMode === 'days' ? 'Previous month' : viewMode === 'years' ? 'Previous years' : 'Previous decades',
|
|
361
416
|
hitSlop: 8,
|
|
@@ -365,7 +420,7 @@ const DatePicker = props => {
|
|
|
365
420
|
})
|
|
366
421
|
}), /*#__PURE__*/_jsx(Pressable, {
|
|
367
422
|
onPress: cycleViewMode,
|
|
368
|
-
style: styles.headerLabelWrap,
|
|
423
|
+
style: [styles.headerLabelWrap, headerLabelStyle],
|
|
369
424
|
accessibilityRole: "button",
|
|
370
425
|
accessibilityLabel: viewMode === 'days' ? `${headerLabel}, switch to year selection` : viewMode === 'years' ? `${headerLabel}, switch to decade selection` : `${headerLabel}, switch to year selection`,
|
|
371
426
|
hitSlop: 8,
|
|
@@ -399,7 +454,7 @@ const DatePicker = props => {
|
|
|
399
454
|
onPress: goNext,
|
|
400
455
|
style: ({
|
|
401
456
|
pressed
|
|
402
|
-
}) => [styles.navBtn, pressed && styles.navBtnPressed],
|
|
457
|
+
}) => [styles.navBtn, pressed && styles.navBtnPressed, navButtonStyle],
|
|
403
458
|
accessibilityRole: "button",
|
|
404
459
|
accessibilityLabel: viewMode === 'days' ? 'Next month' : viewMode === 'years' ? 'Next years' : 'Next decades',
|
|
405
460
|
hitSlop: 8,
|
|
@@ -573,7 +628,7 @@ const DatePicker = props => {
|
|
|
573
628
|
onPress: handleCancel,
|
|
574
629
|
style: ({
|
|
575
630
|
pressed
|
|
576
|
-
}) => [styles.footerBtn, styles.footerCancel, pressed && styles.footerBtnPressed],
|
|
631
|
+
}) => [styles.footerBtn, styles.footerCancel, pressed && styles.footerBtnPressed, footerButtonStyle],
|
|
577
632
|
accessibilityRole: "button",
|
|
578
633
|
accessibilityLabel: cancelLabel,
|
|
579
634
|
children: /*#__PURE__*/_jsx(Text, {
|
|
@@ -592,7 +647,7 @@ const DatePicker = props => {
|
|
|
592
647
|
opacity: !pendingDate ? 0.5 : 1
|
|
593
648
|
}, pressed && {
|
|
594
649
|
backgroundColor: theme.colors.primaryHover
|
|
595
|
-
}],
|
|
650
|
+
}, footerButtonStyle],
|
|
596
651
|
accessibilityRole: "button",
|
|
597
652
|
accessibilityLabel: confirmLabel,
|
|
598
653
|
accessibilityState: {
|
|
@@ -607,38 +662,92 @@ const DatePicker = props => {
|
|
|
607
662
|
})]
|
|
608
663
|
})]
|
|
609
664
|
});
|
|
665
|
+
const formatTriggerValue = formatValue ?? (d => d.toLocaleDateString());
|
|
666
|
+
const triggerValueText = value ? formatTriggerValue(value) : undefined;
|
|
667
|
+
const showTrigger = !isControlled;
|
|
610
668
|
if (mode === 'inline') {
|
|
611
|
-
if (!
|
|
669
|
+
if (!open && !showTrigger) return null;
|
|
670
|
+
if (showTrigger) {
|
|
671
|
+
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
672
|
+
children: [/*#__PURE__*/_jsx(PickerTrigger, {
|
|
673
|
+
label: label,
|
|
674
|
+
value: triggerValueText,
|
|
675
|
+
placeholder: placeholder,
|
|
676
|
+
helperText: helperText,
|
|
677
|
+
error: error,
|
|
678
|
+
required: required,
|
|
679
|
+
disabled: disabled,
|
|
680
|
+
size: size,
|
|
681
|
+
variant: variant,
|
|
682
|
+
clearable: clearable,
|
|
683
|
+
onClear: onClear,
|
|
684
|
+
onPress: () => setInternalOpen(true),
|
|
685
|
+
triggerStyle: triggerStyle
|
|
686
|
+
}), open ? calendar : null]
|
|
687
|
+
});
|
|
688
|
+
}
|
|
612
689
|
return calendar;
|
|
613
690
|
}
|
|
614
|
-
|
|
615
|
-
visible:
|
|
691
|
+
const modalNode = /*#__PURE__*/_jsx(Modal, {
|
|
692
|
+
visible: open,
|
|
616
693
|
transparent: true,
|
|
617
|
-
statusBarTranslucent: true
|
|
694
|
+
statusBarTranslucent: true
|
|
695
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
696
|
+
// @ts-ignore — Android-only RN 0.71+; iOS ignores it.
|
|
697
|
+
,
|
|
698
|
+
navigationBarTranslucent: true,
|
|
618
699
|
animationType: "none",
|
|
619
700
|
onRequestClose: handleClose,
|
|
620
|
-
children:
|
|
701
|
+
children: /*#__PURE__*/_jsxs(View
|
|
702
|
+
// Backdrop wraps the sheet (not sibling) — on Fabric a sibling
|
|
703
|
+
// backdrop is occluded by the sheet wrapper regardless of order.
|
|
704
|
+
// collapsable={false} prevents flattening; plain View + pre-baked
|
|
705
|
+
// rgba colour avoids the Fabric animated-opacity-on-coloured-View bug.
|
|
706
|
+
, {
|
|
707
|
+
collapsable: false,
|
|
621
708
|
style: [styles.backdrop, {
|
|
622
|
-
opacity: backdrop,
|
|
623
709
|
backgroundColor: theme.colors.background.overlay
|
|
624
710
|
}],
|
|
625
|
-
children: /*#__PURE__*/_jsx(Pressable, {
|
|
711
|
+
children: [/*#__PURE__*/_jsx(Pressable, {
|
|
626
712
|
style: StyleSheet.absoluteFill,
|
|
627
713
|
onPress: handleClose,
|
|
628
714
|
accessibilityLabel: "Dismiss"
|
|
629
|
-
})
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
715
|
+
}), /*#__PURE__*/_jsx(Animated.View, {
|
|
716
|
+
style: [styles.sheetWrap, {
|
|
717
|
+
// Push the sheet up by the system nav-bar inset so its content
|
|
718
|
+
// never lands behind Android gesture/3-button chrome.
|
|
719
|
+
paddingBottom: insets.bottom + theme.spacing.lg,
|
|
720
|
+
opacity: sheet,
|
|
721
|
+
transform: [{
|
|
722
|
+
translateY: sheetTranslate
|
|
723
|
+
}]
|
|
724
|
+
}],
|
|
725
|
+
accessibilityViewIsModal: true,
|
|
726
|
+
accessibilityRole: "none",
|
|
727
|
+
children: calendar
|
|
728
|
+
})]
|
|
729
|
+
})
|
|
641
730
|
});
|
|
731
|
+
if (showTrigger) {
|
|
732
|
+
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
733
|
+
children: [/*#__PURE__*/_jsx(PickerTrigger, {
|
|
734
|
+
label: label,
|
|
735
|
+
value: triggerValueText,
|
|
736
|
+
placeholder: placeholder,
|
|
737
|
+
helperText: helperText,
|
|
738
|
+
error: error,
|
|
739
|
+
required: required,
|
|
740
|
+
disabled: disabled,
|
|
741
|
+
size: size,
|
|
742
|
+
variant: variant,
|
|
743
|
+
clearable: clearable,
|
|
744
|
+
onClear: onClear,
|
|
745
|
+
onPress: () => setInternalOpen(true),
|
|
746
|
+
triggerStyle: triggerStyle
|
|
747
|
+
}), modalNode]
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
return modalNode;
|
|
642
751
|
};
|
|
643
752
|
const buildStyles = theme => {
|
|
644
753
|
const cardShadow = theme.shadows.lg;
|
|
@@ -679,8 +788,8 @@ const buildStyles = theme => {
|
|
|
679
788
|
marginBottom: theme.spacing.md
|
|
680
789
|
},
|
|
681
790
|
navBtn: {
|
|
682
|
-
width: 36,
|
|
683
|
-
height: 36,
|
|
791
|
+
width: theme.components.datePicker?.navButtonSize ?? 36,
|
|
792
|
+
height: theme.components.datePicker?.navButtonSize ?? 36,
|
|
684
793
|
borderRadius: theme.radius.full,
|
|
685
794
|
alignItems: 'center',
|
|
686
795
|
justifyContent: 'center',
|
|
@@ -690,8 +799,8 @@ const buildStyles = theme => {
|
|
|
690
799
|
backgroundColor: theme.colors.surface.pressed
|
|
691
800
|
},
|
|
692
801
|
navText: {
|
|
693
|
-
fontSize: 22,
|
|
694
|
-
lineHeight: 24,
|
|
802
|
+
fontSize: theme.components.datePicker?.navTextFontSize ?? 22,
|
|
803
|
+
lineHeight: theme.components.datePicker?.navTextLineHeight ?? 24,
|
|
695
804
|
color: theme.colors.text.primary,
|
|
696
805
|
fontWeight: theme.typography.fontWeight.semibold
|
|
697
806
|
},
|
|
@@ -740,12 +849,12 @@ const buildStyles = theme => {
|
|
|
740
849
|
aspectRatio: 1,
|
|
741
850
|
alignItems: 'center',
|
|
742
851
|
justifyContent: 'center',
|
|
743
|
-
padding: 2
|
|
852
|
+
padding: theme.components.datePicker?.dayCellPadding ?? 2
|
|
744
853
|
},
|
|
745
854
|
dayInner: {
|
|
746
855
|
width: '100%',
|
|
747
856
|
height: '100%',
|
|
748
|
-
borderRadius: theme.radius.full,
|
|
857
|
+
borderRadius: theme.components.datePicker?.dayInnerBorderRadius ?? theme.radius.full,
|
|
749
858
|
alignItems: 'center',
|
|
750
859
|
justifyContent: 'center'
|
|
751
860
|
},
|
|
@@ -761,12 +870,12 @@ const buildStyles = theme => {
|
|
|
761
870
|
aspectRatio: 1.6,
|
|
762
871
|
alignItems: 'center',
|
|
763
872
|
justifyContent: 'center',
|
|
764
|
-
padding: 4
|
|
873
|
+
padding: theme.components.datePicker?.yearCellPadding ?? 4
|
|
765
874
|
},
|
|
766
875
|
yearInner: {
|
|
767
876
|
width: '100%',
|
|
768
877
|
height: '100%',
|
|
769
|
-
borderRadius: theme.radius.lg,
|
|
878
|
+
borderRadius: theme.components.datePicker?.yearInnerBorderRadius ?? theme.radius.lg,
|
|
770
879
|
alignItems: 'center',
|
|
771
880
|
justifyContent: 'center'
|
|
772
881
|
},
|
|
@@ -777,7 +886,7 @@ const buildStyles = theme => {
|
|
|
777
886
|
decadeRangeText: {
|
|
778
887
|
fontSize: theme.typography.fontSize.xs,
|
|
779
888
|
fontWeight: theme.typography.fontWeight.medium,
|
|
780
|
-
marginTop: 2
|
|
889
|
+
marginTop: theme.components.datePicker?.decadeRangeMarginTop ?? 2
|
|
781
890
|
},
|
|
782
891
|
footer: {
|
|
783
892
|
flexDirection: 'row',
|
|
@@ -790,7 +899,7 @@ const buildStyles = theme => {
|
|
|
790
899
|
paddingHorizontal: theme.spacing.lg,
|
|
791
900
|
paddingVertical: theme.spacing.sm,
|
|
792
901
|
borderRadius: theme.radius.md,
|
|
793
|
-
minHeight: 40,
|
|
902
|
+
minHeight: theme.components.datePicker?.footerButtonMinHeight ?? 40,
|
|
794
903
|
alignItems: 'center',
|
|
795
904
|
justifyContent: 'center'
|
|
796
905
|
},
|