@expokit/cli 0.4.4 → 0.5.0
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/README.md +30 -3
- package/bin/expo-kit.js +749 -288
- package/bin/lib.mjs +310 -3
- package/package.json +1 -1
- package/registry/_docs/action-sheet.json +1 -1
- package/registry/_docs/alert.json +6 -0
- package/registry/_docs/bottom-sheet.json +6 -0
- package/registry/_docs/bullet.json +6 -0
- package/registry/_docs/dialog.json +1 -1
- package/registry/_docs/drawer.json +3 -3
- package/registry/_docs/glass-search-bar.json +1 -1
- package/registry/_docs/grain.json +6 -1
- package/registry/_docs/isometric-bar.json +6 -0
- package/registry/_docs/liquidglass-tab.json +1 -1
- package/registry/_docs/password-input.json +1 -1
- package/registry/_docs/pixel-bar.json +6 -0
- package/registry/_docs/polar-area.json +6 -0
- package/registry/_docs/qr-code-button.json +9 -3
- package/registry/_docs/scratch-card.json +7 -1
- package/registry/_docs/search-bar.json +1 -1
- package/registry/_docs/select.json +2 -2
- package/registry/_docs/slide-to-confirm.json +2 -2
- package/registry/_docs/spinner.json +1 -1
- package/registry/_docs/stateful-button.json +2 -2
- package/registry/_docs/swipe-deck.json +1 -1
- package/registry/_docs/time-picker.json +2 -2
- package/registry/_docs/timeline-chart.json +6 -0
- package/registry/_docs/toast.json +15 -3
- package/registry/_docs/treemap.json +6 -0
- package/registry/_docs/waterfall.json +6 -0
- package/registry/accordion/files/src/components/ui/accordion.tsx +6 -4
- package/registry/accordion/files/src/lib/kit.tsx +363 -11
- package/registry/accordion.json +1 -0
- package/registry/action-sheet/files/src/components/ui/action-sheet.tsx +43 -48
- package/registry/action-sheet/files/src/lib/kit.tsx +363 -11
- package/registry/action-sheet.json +1 -0
- package/registry/alert/files/src/components/ui/alert.tsx +19 -12
- package/registry/alert/files/src/lib/kit.tsx +363 -11
- package/registry/alert.json +3 -4
- package/registry/assistant-app.json +1 -0
- package/registry/avatar/files/src/components/ui/avatar.tsx +84 -66
- package/registry/avatar/files/src/lib/kit.tsx +363 -11
- package/registry/avatar.json +1 -0
- package/registry/badge/files/src/components/ui/badge.tsx +34 -34
- package/registry/badge/files/src/lib/kit.tsx +363 -11
- package/registry/badge.json +1 -0
- package/registry/bottom-nav/files/src/components/ui/bottom-nav.tsx +28 -27
- package/registry/bottom-nav/files/src/lib/kit.tsx +363 -11
- package/registry/bottom-nav.json +5 -0
- package/registry/bottom-sheet/files/src/components/ui/bottom-sheet.tsx +353 -289
- package/registry/bottom-sheet/files/src/lib/kit.tsx +363 -11
- package/registry/bottom-sheet.json +5 -1
- package/registry/bullet.json +1 -0
- package/registry/button/files/src/components/ui/button.tsx +18 -16
- package/registry/button/files/src/lib/kit.tsx +363 -11
- package/registry/button-3d/files/src/components/ui/button-3d.tsx +2 -2
- package/registry/button-3d/files/src/lib/kit.tsx +363 -11
- package/registry/button-3d.json +1 -0
- package/registry/button.json +1 -0
- package/registry/calendar/files/src/components/ui/calendar.tsx +74 -76
- package/registry/calendar/files/src/lib/kit.tsx +363 -11
- package/registry/calendar.json +1 -0
- package/registry/card/files/src/components/ui/card.tsx +3 -3
- package/registry/card/files/src/lib/kit.tsx +363 -11
- package/registry/card-stack.json +1 -0
- package/registry/card.json +1 -0
- package/registry/carousel.json +1 -0
- package/registry/chat.json +7 -0
- package/registry/checkbox/files/src/components/ui/checkbox.tsx +4 -4
- package/registry/checkbox/files/src/lib/kit.tsx +363 -11
- package/registry/checkbox.json +1 -0
- package/registry/checkout.json +1 -0
- package/registry/chip-group/files/src/components/ui/chip-group.tsx +22 -22
- package/registry/chip-group/files/src/lib/kit.tsx +363 -11
- package/registry/chip-group.json +1 -0
- package/registry/confetti/files/src/components/ui/confetti.tsx +15 -14
- package/registry/confetti.json +3 -6
- package/registry/coupon/files/src/components/ui/coupon.tsx +42 -42
- package/registry/coupon/files/src/components/ui/flip-card.tsx +6 -5
- package/registry/coupon/files/src/components/ui/tilt-card.tsx +76 -91
- package/registry/coupon/files/src/lib/kit.tsx +363 -11
- package/registry/coupon/files/src/lib/ticket-shape.tsx +54 -44
- package/registry/coupon.json +1 -0
- package/registry/cube-pager.json +1 -0
- package/registry/dashboard.json +1 -0
- package/registry/date-picker/files/src/components/ui/calendar.tsx +74 -76
- package/registry/date-picker/files/src/components/ui/date-picker.tsx +55 -56
- package/registry/date-picker/files/src/lib/kit.tsx +363 -11
- package/registry/date-picker.json +1 -0
- package/registry/dialog/files/src/components/ui/dialog.tsx +60 -56
- package/registry/dialog/files/src/lib/kit.tsx +363 -11
- package/registry/dialog.json +1 -0
- package/registry/donut-shop.json +1 -0
- package/registry/drawer/files/src/components/ui/drawer.tsx +73 -69
- package/registry/drawer/files/src/lib/kit.tsx +363 -11
- package/registry/drawer.json +1 -0
- package/registry/fab.json +1 -0
- package/registry/fintech-app.json +1 -0
- package/registry/flip-calendar/files/src/components/ui/flip-calendar.tsx +92 -86
- package/registry/flip-calendar/files/src/lib/kit.tsx +363 -11
- package/registry/flip-calendar.json +7 -0
- package/registry/flip-card/files/src/components/ui/flip-card.tsx +6 -5
- package/registry/flip-card/files/src/lib/kit.tsx +363 -11
- package/registry/flip-card.json +1 -0
- package/registry/floating-input/files/src/components/ui/floating-input.tsx +33 -33
- package/registry/floating-input/files/src/lib/kit.tsx +363 -11
- package/registry/floating-input.json +1 -0
- package/registry/food-app.json +1 -0
- package/registry/gift-card.json +1 -0
- package/registry/glass-button.json +5 -0
- package/registry/glass-nav-bar.json +1 -0
- package/registry/glass-search-bar.json +1 -0
- package/registry/glass-segmented.json +1 -0
- package/registry/glass-sheet.json +1 -0
- package/registry/glass-tab-bar.json +5 -0
- package/registry/glass.json +1 -0
- package/registry/grain/files/src/components/ui/grain.tsx +16 -14
- package/registry/grain.json +8 -6
- package/registry/inbox.json +1 -0
- package/registry/isometric-bar.json +1 -0
- package/registry/kit/files/src/lib/kit.tsx +363 -11
- package/registry/kit.json +1 -0
- package/registry/liquidglass-tab/files/src/app/_layout.tsx +0 -1
- package/registry/liquidglass-tab/files/src/components/GlassTabBar.tsx +23 -9
- package/registry/liquidglass-tab/files/src/components/TabScreen.tsx +2 -2
- package/registry/liquidglass-tab/files/src/lib/tab-icons.ts +1 -1
- package/registry/liquidglass-tab.json +1 -0
- package/registry/list-item/files/src/components/ui/list-item.tsx +42 -42
- package/registry/list-item/files/src/lib/kit.tsx +363 -11
- package/registry/list-item.json +1 -0
- package/registry/loyalty-card.json +1 -0
- package/registry/morphing-button-group.json +1 -0
- package/registry/number-ticker.json +1 -0
- package/registry/offers.json +1 -0
- package/registry/onboarding.json +1 -0
- package/registry/orb-reveal.json +1 -0
- package/registry/otp-input/files/src/components/ui/otp-input.tsx +48 -29
- package/registry/otp-input/files/src/lib/kit.tsx +363 -11
- package/registry/otp-input.json +1 -0
- package/registry/parallax-layers.json +1 -0
- package/registry/parallax-scroll.json +1 -0
- package/registry/password-input/files/src/components/ui/floating-input.tsx +33 -33
- package/registry/password-input/files/src/components/ui/password-input.tsx +29 -25
- package/registry/password-input/files/src/lib/kit.tsx +363 -11
- package/registry/password-input.json +1 -0
- package/registry/payment-card/files/src/components/ui/flip-card.tsx +6 -5
- package/registry/payment-card/files/src/components/ui/payment-card.tsx +17 -17
- package/registry/payment-card/files/src/components/ui/tilt-card.tsx +76 -91
- package/registry/payment-card/files/src/lib/kit.tsx +363 -11
- package/registry/payment-card.json +1 -0
- package/registry/paywall.json +1 -0
- package/registry/pixel-bar.json +1 -0
- package/registry/polar-area.json +1 -0
- package/registry/profile.json +1 -0
- package/registry/progress/files/src/components/ui/progress.tsx +29 -29
- package/registry/progress/files/src/lib/kit.tsx +363 -11
- package/registry/progress-steps/files/src/components/ui/progress-steps.tsx +20 -20
- package/registry/progress-steps/files/src/lib/kit.tsx +363 -11
- package/registry/progress-steps.json +1 -0
- package/registry/progress.json +1 -0
- package/registry/qr-code-button.json +1 -0
- package/registry/radio-group/files/src/components/ui/radio-group.tsx +19 -19
- package/registry/radio-group/files/src/lib/kit.tsx +363 -11
- package/registry/radio-group.json +1 -0
- package/registry/rating.json +1 -0
- package/registry/ring-carousel.json +1 -0
- package/registry/ruler-time-picker/files/src/components/ui/ruler-time-picker.tsx +98 -82
- package/registry/ruler-time-picker/files/src/lib/kit.tsx +363 -11
- package/registry/ruler-time-picker.json +7 -0
- package/registry/scratch-card.json +1 -0
- package/registry/search-bar/files/src/components/ui/search-bar.tsx +25 -21
- package/registry/search-bar/files/src/lib/kit.tsx +363 -11
- package/registry/search-bar.json +1 -0
- package/registry/search-results.json +4 -0
- package/registry/segmented-control/files/src/components/ui/segmented-control.tsx +8 -7
- package/registry/segmented-control/files/src/lib/kit.tsx +363 -11
- package/registry/segmented-control.json +1 -0
- package/registry/select/files/src/components/ui/select.tsx +93 -88
- package/registry/select/files/src/lib/kit.tsx +363 -11
- package/registry/select.json +6 -0
- package/registry/settings.json +1 -0
- package/registry/sign-in.json +1 -0
- package/registry/skeleton/files/src/components/ui/skeleton.tsx +149 -80
- package/registry/skeleton/files/src/lib/kit.tsx +363 -11
- package/registry/skeleton.json +1 -0
- package/registry/slide-to-confirm.json +1 -0
- package/registry/slider/files/src/components/ui/slider.tsx +103 -96
- package/registry/slider/files/src/lib/kit.tsx +363 -11
- package/registry/slider.json +5 -0
- package/registry/spin-wheel.json +1 -0
- package/registry/spinner/files/src/components/ui/spinner.tsx +39 -29
- package/registry/spinner/files/src/lib/kit.tsx +363 -11
- package/registry/spinner.json +6 -0
- package/registry/stateful-button/files/src/components/ui/stateful-button.tsx +39 -32
- package/registry/stateful-button/files/src/lib/kit.tsx +363 -11
- package/registry/stateful-button.json +5 -0
- package/registry/stepper/files/src/components/ui/stepper.tsx +38 -36
- package/registry/stepper/files/src/lib/kit.tsx +363 -11
- package/registry/stepper.json +1 -0
- package/registry/swipe-deck.json +1 -0
- package/registry/swipeable-row.json +4 -0
- package/registry/switch/files/src/components/ui/switch.tsx +39 -42
- package/registry/switch/files/src/lib/kit.tsx +363 -11
- package/registry/switch.json +1 -0
- package/registry/tabs/files/src/components/ui/tabs.tsx +59 -62
- package/registry/tabs/files/src/lib/kit.tsx +363 -11
- package/registry/tabs.json +1 -0
- package/registry/text-animation/files/src/components/ui/text-animation.tsx +55 -42
- package/registry/text-animation/files/src/lib/kit.tsx +363 -11
- package/registry/text-animation.json +7 -0
- package/registry/textarea/files/src/components/ui/textarea.tsx +10 -10
- package/registry/textarea/files/src/lib/kit.tsx +363 -11
- package/registry/textarea.json +1 -0
- package/registry/ticket-card.json +1 -0
- package/registry/ticket-shape/files/src/lib/kit.tsx +363 -11
- package/registry/ticket-shape/files/src/lib/ticket-shape.tsx +54 -44
- package/registry/ticket-shape.json +1 -0
- package/registry/tilt-card/files/src/components/ui/tilt-card.tsx +76 -91
- package/registry/tilt-card/files/src/lib/kit.tsx +363 -11
- package/registry/tilt-card.json +1 -0
- package/registry/time-picker/files/src/components/ui/time-picker.tsx +122 -119
- package/registry/time-picker/files/src/lib/kit.tsx +363 -11
- package/registry/time-picker.json +1 -0
- package/registry/timeline/files/src/components/ui/avatar.tsx +84 -66
- package/registry/timeline/files/src/components/ui/timeline.tsx +44 -41
- package/registry/timeline/files/src/lib/kit.tsx +363 -11
- package/registry/timeline-chart.json +1 -0
- package/registry/timeline.json +1 -0
- package/registry/toast/files/src/components/ui/toast.tsx +541 -463
- package/registry/toast/files/src/lib/kit.tsx +363 -11
- package/registry/toast.json +7 -5
- package/registry/treemap.json +1 -0
- package/registry/waterfall.json +1 -0
- package/registry/wheel-list.json +1 -0
- package/schema/components.schema.json +1 -0
- package/registry/alert/files/src/components/ui/button.tsx +0 -290
- package/registry/confetti/files/src/lib/kit.tsx +0 -320
- package/registry/grain/files/src/lib/kit.tsx +0 -320
- package/registry/toast/files/src/components/ui/button.tsx +0 -290
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
AccessibilityInfo,
|
|
4
4
|
Animated,
|
|
5
5
|
Easing,
|
|
6
|
-
PanResponder,
|
|
7
6
|
Pressable,
|
|
8
7
|
StyleSheet,
|
|
9
8
|
Text,
|
|
@@ -14,7 +13,7 @@ import {
|
|
|
14
13
|
} from 'react-native';
|
|
15
14
|
import Svg, { Path } from 'react-native-svg';
|
|
16
15
|
|
|
17
|
-
import { alpha, motion, readableOn, useKit } from '@/lib/kit';
|
|
16
|
+
import { alpha, motion, readableOn, useKit, usePanResponder } from '@/lib/kit';
|
|
18
17
|
|
|
19
18
|
export type CalendarMode = 'single' | 'range' | 'multiple';
|
|
20
19
|
|
|
@@ -30,65 +29,65 @@ export type CalendarMarks = Record<string, string | string[]>;
|
|
|
30
29
|
|
|
31
30
|
export interface CalendarBaseProps {
|
|
32
31
|
/** Controlled visible month (any date inside it). */
|
|
33
|
-
month?: Date;
|
|
32
|
+
month?: Date | undefined;
|
|
34
33
|
/** Month shown first (default: the selected date, else today). */
|
|
35
|
-
defaultMonth?: Date;
|
|
36
|
-
onMonthChange?: (month: Date) => void;
|
|
34
|
+
defaultMonth?: Date | undefined;
|
|
35
|
+
onMonthChange?: ((month: Date) => void) | undefined;
|
|
37
36
|
/** 0 = Sunday, 1 = Monday. */
|
|
38
|
-
weekStartsOn?: 0 | 1;
|
|
37
|
+
weekStartsOn?: 0 | 1 | undefined;
|
|
39
38
|
/** BCP 47 locale for month and weekday names (default: device locale). */
|
|
40
|
-
locale?: string;
|
|
39
|
+
locale?: string | undefined;
|
|
41
40
|
/** Earliest selectable day. */
|
|
42
|
-
minDate?: Date;
|
|
41
|
+
minDate?: Date | undefined;
|
|
43
42
|
/** Latest selectable day. */
|
|
44
|
-
maxDate?: Date;
|
|
43
|
+
maxDate?: Date | undefined;
|
|
45
44
|
/** Return true to disable a day (booked, holidays…). */
|
|
46
|
-
isDateDisabled?: (date: Date) => boolean;
|
|
45
|
+
isDateDisabled?: ((date: Date) => boolean) | undefined;
|
|
47
46
|
/** Coloured dots under dates: `{ [toDateKey(date)]: '#22c55e' | ['#22c55e', '#f59e0b'] }`. */
|
|
48
|
-
markedDates?: CalendarMarks;
|
|
47
|
+
markedDates?: CalendarMarks | undefined;
|
|
49
48
|
/** Fill whole days with a colour (birthdays, shifts, people…): `{ [toDateKey(date)]: '#f472b6' }`. */
|
|
50
|
-
highlightedDates?: Record<string, string
|
|
49
|
+
highlightedDates?: Record<string, string> | undefined;
|
|
51
50
|
/** `tiles` puts every day on a soft tile; `minimal` shows bare numbers. */
|
|
52
|
-
variant?: 'tiles' | 'minimal';
|
|
51
|
+
variant?: 'tiles' | 'minimal' | undefined;
|
|
53
52
|
/** Weekday header: `narrow` (M T W) or `short` (Mon Tue Wed). */
|
|
54
|
-
weekdayFormat?: 'narrow' | 'short';
|
|
53
|
+
weekdayFormat?: 'narrow' | 'short' | undefined;
|
|
55
54
|
/** Show a "Today" pill in the header while another month is on screen. */
|
|
56
|
-
showTodayButton?: boolean;
|
|
55
|
+
showTodayButton?: boolean | undefined;
|
|
57
56
|
/** Show the faded trailing / leading days of the neighbouring months. */
|
|
58
|
-
showOutsideDays?: boolean;
|
|
57
|
+
showOutsideDays?: boolean | undefined;
|
|
59
58
|
/** Ring and tint today's date. */
|
|
60
|
-
showToday?: boolean;
|
|
59
|
+
showToday?: boolean | undefined;
|
|
61
60
|
/** Always render six week rows so the height never changes between months. */
|
|
62
|
-
fixedWeeks?: boolean;
|
|
61
|
+
fixedWeeks?: boolean | undefined;
|
|
63
62
|
/** Tap the month title to jump through a month / year grid. */
|
|
64
|
-
monthPicker?: boolean;
|
|
63
|
+
monthPicker?: boolean | undefined;
|
|
65
64
|
/** Most dates selectable in `multiple` mode. */
|
|
66
|
-
max?: number;
|
|
65
|
+
max?: number | undefined;
|
|
67
66
|
/** Selection and today colour (default: theme accent). */
|
|
68
|
-
accent?: string;
|
|
69
|
-
style?: StyleProp<ViewStyle
|
|
67
|
+
accent?: string | undefined;
|
|
68
|
+
style?: StyleProp<ViewStyle> | undefined;
|
|
70
69
|
}
|
|
71
70
|
|
|
72
71
|
export interface CalendarSingleProps {
|
|
73
|
-
mode?: 'single';
|
|
74
|
-
value?: Date | null;
|
|
75
|
-
defaultValue?: Date | null;
|
|
76
|
-
onChange?: (date: Date) => void;
|
|
72
|
+
mode?: 'single' | undefined;
|
|
73
|
+
value?: Date | null | undefined;
|
|
74
|
+
defaultValue?: Date | null | undefined;
|
|
75
|
+
onChange?: ((date: Date) => void) | undefined;
|
|
77
76
|
}
|
|
78
77
|
|
|
79
78
|
export interface CalendarRangeProps {
|
|
80
79
|
mode: 'range';
|
|
81
|
-
value?: DateRange | null;
|
|
82
|
-
defaultValue?: DateRange | null;
|
|
80
|
+
value?: DateRange | null | undefined;
|
|
81
|
+
defaultValue?: DateRange | null | undefined;
|
|
83
82
|
/** Fires on every tap: first with `{ start, end: null }`, then with both ends. */
|
|
84
|
-
onChange?: (range: DateRange) => void;
|
|
83
|
+
onChange?: ((range: DateRange) => void) | undefined;
|
|
85
84
|
}
|
|
86
85
|
|
|
87
86
|
export interface CalendarMultipleProps {
|
|
88
87
|
mode: 'multiple';
|
|
89
|
-
value?: Date[];
|
|
90
|
-
defaultValue?: Date[];
|
|
91
|
-
onChange?: (dates: Date[]) => void;
|
|
88
|
+
value?: Date[] | undefined;
|
|
89
|
+
defaultValue?: Date[] | undefined;
|
|
90
|
+
onChange?: ((dates: Date[]) => void) | undefined;
|
|
92
91
|
}
|
|
93
92
|
|
|
94
93
|
export type CalendarProps = CalendarBaseProps & (CalendarSingleProps | CalendarRangeProps | CalendarMultipleProps);
|
|
@@ -161,11 +160,11 @@ function useFormatters(locale?: string) {
|
|
|
161
160
|
}
|
|
162
161
|
};
|
|
163
162
|
return {
|
|
164
|
-
title: make({ month: 'long', year: 'numeric' }, (d) => `${EN_MONTHS[d.getMonth()]} ${d.getFullYear()}`),
|
|
165
|
-
month: make({ month: 'short' }, (d) => EN_MONTHS[d.getMonth()].slice(0, 3)),
|
|
166
|
-
weekday: make({ weekday: 'short' }, (d) => EN_DAYS[d.getDay()]),
|
|
167
|
-
weekdayNarrow: make({ weekday: 'narrow' }, (d) => EN_DAYS[d.getDay()]
|
|
168
|
-
weekdayLong: make({ weekday: 'long' }, (d) => EN_DAYS[d.getDay()]),
|
|
163
|
+
title: make({ month: 'long', year: 'numeric' }, (d) => `${EN_MONTHS[d.getMonth()] ?? ''} ${d.getFullYear()}`),
|
|
164
|
+
month: make({ month: 'short' }, (d) => (EN_MONTHS[d.getMonth()] ?? '').slice(0, 3)),
|
|
165
|
+
weekday: make({ weekday: 'short' }, (d) => EN_DAYS[d.getDay()] ?? ''),
|
|
166
|
+
weekdayNarrow: make({ weekday: 'narrow' }, (d) => (EN_DAYS[d.getDay()] ?? '').slice(0, 1)),
|
|
167
|
+
weekdayLong: make({ weekday: 'long' }, (d) => EN_DAYS[d.getDay()] ?? ''),
|
|
169
168
|
full: make({ weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' }, (d) => d.toDateString()),
|
|
170
169
|
};
|
|
171
170
|
}, [locale]);
|
|
@@ -206,7 +205,7 @@ export function Calendar(props: CalendarProps) {
|
|
|
206
205
|
accent,
|
|
207
206
|
style,
|
|
208
207
|
} = props as unknown as FlatProps;
|
|
209
|
-
const { colors, radius, font } = useKit();
|
|
208
|
+
const { colors, radius, font, labels } = useKit();
|
|
210
209
|
const ff = font.family ? { fontFamily: font.family } : null;
|
|
211
210
|
const tint = accent ?? colors.accent;
|
|
212
211
|
const fmt = useFormatters(locale);
|
|
@@ -244,9 +243,10 @@ export function Calendar(props: CalendarProps) {
|
|
|
244
243
|
|
|
245
244
|
/* month slide transition */
|
|
246
245
|
const [width, setWidth] = useState(0);
|
|
247
|
-
const slide =
|
|
246
|
+
const [slide] = useState(() => new Animated.Value(1)); // native
|
|
248
247
|
const [leaving, setLeaving] = useState<{ month: Date; dir: number } | null>(null);
|
|
249
|
-
|
|
248
|
+
// Which way the last month change went: the incoming grid slides in from that side.
|
|
249
|
+
const [slideDir, setSlideDir] = useState(1);
|
|
250
250
|
const shownRef = useRef(visible);
|
|
251
251
|
const visibleKey = monthIndex(visible);
|
|
252
252
|
useLayoutEffect(() => {
|
|
@@ -254,7 +254,7 @@ export function Calendar(props: CalendarProps) {
|
|
|
254
254
|
if (monthIndex(prev) === visibleKey) return;
|
|
255
255
|
shownRef.current = visible;
|
|
256
256
|
const dir = visibleKey > monthIndex(prev) ? 1 : -1;
|
|
257
|
-
|
|
257
|
+
setSlideDir(dir);
|
|
258
258
|
setLeaving({ month: prev, dir });
|
|
259
259
|
slide.stopAnimation();
|
|
260
260
|
slide.setValue(0);
|
|
@@ -271,7 +271,7 @@ export function Calendar(props: CalendarProps) {
|
|
|
271
271
|
/* days / months / years view */
|
|
272
272
|
const [view, setView] = useState<'days' | 'months' | 'years'>('days');
|
|
273
273
|
const [pickYear, setPickYear] = useState(visible.getFullYear());
|
|
274
|
-
const viewAnim =
|
|
274
|
+
const [viewAnim] = useState(() => new Animated.Value(1)); // native
|
|
275
275
|
const [gridH, setGridH] = useState(0);
|
|
276
276
|
const switchView = (next: 'days' | 'months' | 'years') => {
|
|
277
277
|
if (next !== 'days' && view === 'days') setPickYear(visible.getFullYear());
|
|
@@ -283,7 +283,9 @@ export function Calendar(props: CalendarProps) {
|
|
|
283
283
|
|
|
284
284
|
/* selection */
|
|
285
285
|
const stateRef = useRef({ mode, current, value, onChange, max, visible, goTo });
|
|
286
|
-
|
|
286
|
+
useLayoutEffect(() => {
|
|
287
|
+
stateRef.current = { mode, current, value, onChange, max, visible, goTo };
|
|
288
|
+
});
|
|
287
289
|
const onDayPress = useCallback((d: Date) => {
|
|
288
290
|
const s = stateRef.current;
|
|
289
291
|
let next: CalendarValue;
|
|
@@ -305,18 +307,14 @@ export function Calendar(props: CalendarProps) {
|
|
|
305
307
|
if (monthIndex(d) !== monthIndex(s.visible)) s.goTo(d);
|
|
306
308
|
}, []);
|
|
307
309
|
|
|
308
|
-
const pan =
|
|
309
|
-
() =>
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
},
|
|
317
|
-
}),
|
|
318
|
-
[]
|
|
319
|
-
);
|
|
310
|
+
const pan = usePanResponder({
|
|
311
|
+
onMoveShouldSetPanResponder: (_, g) => Math.abs(g.dx) > 14 && Math.abs(g.dx) > Math.abs(g.dy) * 1.4,
|
|
312
|
+
onPanResponderRelease: (_, g) => {
|
|
313
|
+
const s = stateRef.current;
|
|
314
|
+
if (g.dx < -40 || g.vx < -0.5) s.goTo(addMonths(s.visible, 1));
|
|
315
|
+
else if (g.dx > 40 || g.vx > 0.5) s.goTo(addMonths(s.visible, -1));
|
|
316
|
+
},
|
|
317
|
+
});
|
|
320
318
|
|
|
321
319
|
const weekdays = useMemo(() => {
|
|
322
320
|
const base = new Date(2023, 0, 1); // a Sunday
|
|
@@ -349,7 +347,7 @@ export function Calendar(props: CalendarProps) {
|
|
|
349
347
|
|
|
350
348
|
const W = width || 320;
|
|
351
349
|
// Reduce Motion: months swap with a fade only, no sideways slide.
|
|
352
|
-
const dir = reduce ? 0 :
|
|
350
|
+
const dir = reduce ? 0 : slideDir;
|
|
353
351
|
const prevDisabled = view === 'days' ? monthIndex(visible) - 1 < minM : view === 'months' ? pickYear * 12 - 1 < minM : false;
|
|
354
352
|
const nextDisabled = view === 'days' ? monthIndex(visible) + 1 > maxM : view === 'months' ? (pickYear + 1) * 12 > maxM : false;
|
|
355
353
|
const decadeStart = Math.floor(pickYear / 12) * 12;
|
|
@@ -374,7 +372,7 @@ export function Calendar(props: CalendarProps) {
|
|
|
374
372
|
onPress={monthPicker ? () => switchView(view === 'days' ? 'months' : view === 'months' ? 'years' : 'days') : undefined}
|
|
375
373
|
disabled={!monthPicker}
|
|
376
374
|
accessibilityRole={monthPicker ? 'button' : 'header'}
|
|
377
|
-
accessibilityLabel={monthPicker ? `${title}, ${view === 'days' ?
|
|
375
|
+
accessibilityLabel={monthPicker ? `${title}, ${view === 'days' ? labels.chooseMonth : view === 'months' ? labels.chooseYear : labels.backToDays}` : title}
|
|
378
376
|
hitSlop={6}
|
|
379
377
|
style={({ pressed }) => [styles.titleBtn, { borderRadius: radius.sm, backgroundColor: pressed ? colors.muted : 'transparent' }]}
|
|
380
378
|
>
|
|
@@ -401,12 +399,12 @@ export function Calendar(props: CalendarProps) {
|
|
|
401
399
|
<Pressable
|
|
402
400
|
onPress={() => goTo(today)}
|
|
403
401
|
accessibilityRole="button"
|
|
404
|
-
accessibilityLabel=
|
|
402
|
+
accessibilityLabel={labels.goToToday}
|
|
405
403
|
hitSlop={4}
|
|
406
404
|
style={({ pressed }) => [styles.todayBtn, { borderRadius: radius.capsule(32), backgroundColor: pressed ? colors.secondary : colors.muted }]}
|
|
407
405
|
>
|
|
408
406
|
<Text maxFontSizeMultiplier={FONT_CAP} style={[styles.todayText, ff, { color: tint }]}>
|
|
409
|
-
|
|
407
|
+
{labels.today}
|
|
410
408
|
</Text>
|
|
411
409
|
</Pressable>
|
|
412
410
|
) : null}
|
|
@@ -429,7 +427,7 @@ export function Calendar(props: CalendarProps) {
|
|
|
429
427
|
</Text>
|
|
430
428
|
))}
|
|
431
429
|
</View>
|
|
432
|
-
<View {...pan
|
|
430
|
+
<View {...pan} style={styles.gridClip} onLayout={(e) => setGridH(e.nativeEvent.layout.height)}>
|
|
433
431
|
{leaving ? (
|
|
434
432
|
<Animated.View
|
|
435
433
|
pointerEvents="none"
|
|
@@ -525,16 +523,16 @@ interface MonthGridProps {
|
|
|
525
523
|
fixedWeeks: boolean;
|
|
526
524
|
showOutsideDays: boolean;
|
|
527
525
|
showToday: boolean;
|
|
528
|
-
minDate?: Date;
|
|
529
|
-
maxDate?: Date;
|
|
530
|
-
isDateDisabled?: (date: Date) => boolean;
|
|
531
|
-
markedDates?: CalendarMarks;
|
|
532
|
-
highlightedDates?: Record<string, string
|
|
526
|
+
minDate?: Date | undefined;
|
|
527
|
+
maxDate?: Date | undefined;
|
|
528
|
+
isDateDisabled?: ((date: Date) => boolean) | undefined;
|
|
529
|
+
markedDates?: CalendarMarks | undefined;
|
|
530
|
+
highlightedDates?: Record<string, string> | undefined;
|
|
533
531
|
tiles: boolean;
|
|
534
|
-
singleKey?: string;
|
|
535
|
-
rangeStart?: number;
|
|
536
|
-
rangeEnd?: number;
|
|
537
|
-
manyKeys?: string;
|
|
532
|
+
singleKey?: string | undefined;
|
|
533
|
+
rangeStart?: number | undefined;
|
|
534
|
+
rangeEnd?: number | undefined;
|
|
535
|
+
manyKeys?: string | undefined;
|
|
538
536
|
tint: string;
|
|
539
537
|
fullLabel: (d: Date) => string;
|
|
540
538
|
reduce: boolean;
|
|
@@ -636,8 +634,8 @@ interface DayCellProps {
|
|
|
636
634
|
band: 'none' | 'start' | 'mid' | 'end';
|
|
637
635
|
roundLeft: boolean;
|
|
638
636
|
roundRight: boolean;
|
|
639
|
-
marks?: string | string[];
|
|
640
|
-
highlight?: string;
|
|
637
|
+
marks?: string | string[] | undefined;
|
|
638
|
+
highlight?: string | undefined;
|
|
641
639
|
tile: boolean;
|
|
642
640
|
tint: string;
|
|
643
641
|
reduce: boolean;
|
|
@@ -665,8 +663,8 @@ const DayCell = memo(function DayCell({
|
|
|
665
663
|
const { colors, radius, font } = useKit();
|
|
666
664
|
const ff = font.family ? { fontFamily: font.family } : null;
|
|
667
665
|
const r = tileRadius(radius.md);
|
|
668
|
-
const pop =
|
|
669
|
-
const bandIn =
|
|
666
|
+
const [pop] = useState(() => new Animated.Value(selected ? 1 : 0)); // native: circle scale + opacity
|
|
667
|
+
const [bandIn] = useState(() => new Animated.Value(band === 'none' ? 0 : 1)); // native: band opacity
|
|
670
668
|
useEffect(() => {
|
|
671
669
|
// Reduce Motion: the selection fills in with a quick fade, no scale pop.
|
|
672
670
|
if (reduce) Animated.timing(pop, { toValue: selected ? 1 : 0, duration: 150, useNativeDriver: true }).start();
|
|
@@ -773,14 +771,14 @@ const DayCell = memo(function DayCell({
|
|
|
773
771
|
/* ───────────────────────────────────── bits ───────────────────────────────────── */
|
|
774
772
|
|
|
775
773
|
function NavButton({ dir, disabled, onPress }: { dir: 1 | -1; disabled: boolean; onPress: () => void }) {
|
|
776
|
-
const { colors } = useKit();
|
|
774
|
+
const { colors, labels } = useKit();
|
|
777
775
|
return (
|
|
778
776
|
<Pressable
|
|
779
777
|
onPress={onPress}
|
|
780
778
|
disabled={disabled}
|
|
781
779
|
hitSlop={4}
|
|
782
780
|
accessibilityRole="button"
|
|
783
|
-
accessibilityLabel={dir < 0 ?
|
|
781
|
+
accessibilityLabel={dir < 0 ? labels.previous : labels.next}
|
|
784
782
|
accessibilityState={{ disabled }}
|
|
785
783
|
style={({ pressed }) => [styles.nav, { backgroundColor: pressed ? colors.secondary : colors.muted, opacity: disabled ? 0.3 : 1 }]}
|
|
786
784
|
>
|
|
@@ -798,7 +796,7 @@ function NavButton({ dir, disabled, onPress }: { dir: 1 | -1; disabled: boolean;
|
|
|
798
796
|
}
|
|
799
797
|
|
|
800
798
|
function Chevron({ turned, color, reduce }: { turned: boolean; color: string; reduce: boolean }) {
|
|
801
|
-
const turn =
|
|
799
|
+
const [turn] = useState(() => new Animated.Value(turned ? 1 : 0)); // native
|
|
802
800
|
useEffect(() => {
|
|
803
801
|
if (reduce) {
|
|
804
802
|
turn.setValue(turned ? 1 : 0);
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import React, { useEffect, useMemo, useRef, useState, type ComponentRef } from 'react';
|
|
1
|
+
import React, { useEffect, useLayoutEffect, useMemo, useRef, useState, type ComponentRef } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
AccessibilityInfo,
|
|
4
4
|
Animated,
|
|
5
5
|
Easing,
|
|
6
6
|
Modal,
|
|
7
|
-
PanResponder,
|
|
8
7
|
Pressable,
|
|
9
8
|
ScrollView,
|
|
10
9
|
StyleSheet,
|
|
@@ -26,7 +25,7 @@ import {
|
|
|
26
25
|
type CalendarProps,
|
|
27
26
|
type DateRange,
|
|
28
27
|
} from '@/components/ui/calendar';
|
|
29
|
-
import { alpha, motion, readableOn, useKit, useLayout } from '@/lib/kit';
|
|
28
|
+
import { alpha, defaultLabels, motion, readableOn, useKit, useLayout, usePanResponder, type Labels } from '@/lib/kit';
|
|
30
29
|
|
|
31
30
|
export type { DateRange } from '@/components/ui/calendar';
|
|
32
31
|
export type DatePickerSize = 'sm' | 'md' | 'lg';
|
|
@@ -148,40 +147,40 @@ const EMPTY_RANGE: DateRange = { start: null, end: null };
|
|
|
148
147
|
|
|
149
148
|
const isRange = (v: Picked): v is DateRange => !!v && !(v instanceof Date);
|
|
150
149
|
|
|
151
|
-
/** Built-in single-date shortcuts, computed relative to now. */
|
|
152
|
-
export function singleDatePresets(): DatePickerPreset<Date>[] {
|
|
150
|
+
/** Built-in single-date shortcuts, computed relative to now. Pass `useKit().labels` for translated names. */
|
|
151
|
+
export function singleDatePresets(labels: Labels = defaultLabels): DatePickerPreset<Date>[] {
|
|
153
152
|
const today = () => startOfDay(new Date());
|
|
154
153
|
return [
|
|
155
|
-
{ label:
|
|
156
|
-
{ label:
|
|
157
|
-
{ label:
|
|
158
|
-
{ label:
|
|
159
|
-
{ label:
|
|
154
|
+
{ label: labels.today, value: today },
|
|
155
|
+
{ label: labels.tomorrow, value: () => addDays(today(), 1) },
|
|
156
|
+
{ label: labels.nextMonday, value: () => addDays(today(), ((8 - today().getDay()) % 7) || 7) },
|
|
157
|
+
{ label: labels.inAWeek, value: () => addDays(today(), 7) },
|
|
158
|
+
{ label: labels.inAMonth, value: () => new Date(today().getFullYear(), today().getMonth() + 1, today().getDate()) },
|
|
160
159
|
];
|
|
161
160
|
}
|
|
162
161
|
|
|
163
|
-
/** Built-in range shortcuts, computed relative to now. */
|
|
164
|
-
export function rangeDatePresets(): DatePickerPreset<DateRange>[] {
|
|
162
|
+
/** Built-in range shortcuts, computed relative to now. Pass `useKit().labels` for translated names. */
|
|
163
|
+
export function rangeDatePresets(labels: Labels = defaultLabels): DatePickerPreset<DateRange>[] {
|
|
165
164
|
const today = () => startOfDay(new Date());
|
|
166
165
|
return [
|
|
167
|
-
{ label:
|
|
168
|
-
{ label:
|
|
166
|
+
{ label: labels.today, value: () => ({ start: today(), end: today() }) },
|
|
167
|
+
{ label: labels.next7Days, value: () => ({ start: today(), end: addDays(today(), 6) }) },
|
|
169
168
|
{
|
|
170
|
-
label:
|
|
169
|
+
label: labels.nextWeekend,
|
|
171
170
|
value: () => {
|
|
172
171
|
const sat = addDays(today(), ((6 - today().getDay() + 7) % 7) || 7);
|
|
173
172
|
return { start: sat, end: addDays(sat, 1) };
|
|
174
173
|
},
|
|
175
174
|
},
|
|
176
175
|
{
|
|
177
|
-
label:
|
|
176
|
+
label: labels.thisMonth,
|
|
178
177
|
value: () => {
|
|
179
178
|
const t = today();
|
|
180
179
|
return { start: new Date(t.getFullYear(), t.getMonth(), 1), end: new Date(t.getFullYear(), t.getMonth() + 1, 0) };
|
|
181
180
|
},
|
|
182
181
|
},
|
|
183
|
-
{ label:
|
|
184
|
-
{ label:
|
|
182
|
+
{ label: labels.last7Days, value: () => ({ start: addDays(today(), -6), end: today() }) },
|
|
183
|
+
{ label: labels.last30Days, value: () => ({ start: addDays(today(), -29), end: today() }) },
|
|
185
184
|
];
|
|
186
185
|
}
|
|
187
186
|
|
|
@@ -231,7 +230,7 @@ export function DatePicker(props: DatePickerProps) {
|
|
|
231
230
|
iconColor,
|
|
232
231
|
menuStyle,
|
|
233
232
|
} = props as unknown as FlatProps;
|
|
234
|
-
const { colors, radius, font } = useKit();
|
|
233
|
+
const { colors, radius, font, labels } = useKit();
|
|
235
234
|
const ff = font.family ? { fontFamily: font.family } : null;
|
|
236
235
|
const tint = accent ?? colors.accent;
|
|
237
236
|
const bg = surface ?? colors.background;
|
|
@@ -249,7 +248,9 @@ export function DatePicker(props: DatePickerProps) {
|
|
|
249
248
|
const reduce = useReduceMotion();
|
|
250
249
|
// The pan responder is built once; it reads Reduce Motion through this ref.
|
|
251
250
|
const live = useRef({ reduce });
|
|
252
|
-
|
|
251
|
+
useLayoutEffect(() => {
|
|
252
|
+
live.current = { reduce };
|
|
253
|
+
});
|
|
253
254
|
|
|
254
255
|
const [inner, setInner] = useState<Picked>(defaultValue);
|
|
255
256
|
const current = value !== undefined ? value : inner;
|
|
@@ -265,13 +266,13 @@ export function DatePicker(props: DatePickerProps) {
|
|
|
265
266
|
|
|
266
267
|
const ok = !error && !!success;
|
|
267
268
|
const floating = open || hasValue;
|
|
268
|
-
const float =
|
|
269
|
-
const focus =
|
|
270
|
-
const halo =
|
|
271
|
-
const show =
|
|
272
|
-
const drag =
|
|
273
|
-
const shake =
|
|
274
|
-
const check =
|
|
269
|
+
const [float] = useState(() => new Animated.Value(floating ? 1 : 0)); // native
|
|
270
|
+
const [focus] = useState(() => new Animated.Value(0)); // JS: border + label colour
|
|
271
|
+
const [halo] = useState(() => new Animated.Value(0)); // native
|
|
272
|
+
const [show] = useState(() => new Animated.Value(0)); // native: backdrop + sheet
|
|
273
|
+
const [drag] = useState(() => new Animated.Value(0)); // native
|
|
274
|
+
const [shake] = useState(() => new Animated.Value(0)); // native
|
|
275
|
+
const [check] = useState(() => new Animated.Value(ok ? 1 : 0)); // native
|
|
275
276
|
|
|
276
277
|
const asSheet = presentation !== 'popover';
|
|
277
278
|
// Centred dialog instead of a bottom sheet: on foldables, tablets and landscape phones.
|
|
@@ -401,9 +402,9 @@ export function DatePicker(props: DatePickerProps) {
|
|
|
401
402
|
|
|
402
403
|
const presetList = useMemo<DatePickerPreset<Picked>[]>(() => {
|
|
403
404
|
if (!presets) return [];
|
|
404
|
-
if (presets === true) return (ranged ? rangeDatePresets() : singleDatePresets()) as DatePickerPreset<Picked>[];
|
|
405
|
+
if (presets === true) return (ranged ? rangeDatePresets(labels) : singleDatePresets(labels)) as DatePickerPreset<Picked>[];
|
|
405
406
|
return presets;
|
|
406
|
-
}, [presets, ranged]);
|
|
407
|
+
}, [presets, ranged, labels]);
|
|
407
408
|
const resolve = (p: DatePickerPreset<Picked>) => (typeof p.value === 'function' ? p.value() : p.value);
|
|
408
409
|
const presetOk = (v: Picked) => {
|
|
409
410
|
const ds = isRange(v) ? [v.start, v.end] : [v];
|
|
@@ -414,23 +415,21 @@ export function DatePicker(props: DatePickerProps) {
|
|
|
414
415
|
const same = (a: Picked, b: Picked) =>
|
|
415
416
|
isRange(a) && isRange(b) ? isSameDay(a.start, b.start) && isSameDay(a.end, b.end) : !isRange(a) && !isRange(b) && isSameDay(a, b);
|
|
416
417
|
|
|
417
|
-
const
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
});
|
|
433
|
-
}, [drag, onOpenChange]);
|
|
418
|
+
const settle = () =>
|
|
419
|
+
reduce
|
|
420
|
+
? Animated.timing(drag, { toValue: 0, duration: 150, easing: Easing.bezier(0.32, 0.72, 0, 1), useNativeDriver: true }).start()
|
|
421
|
+
: Animated.spring(drag, { toValue: 0, useNativeDriver: true, ...motion.snappy }).start();
|
|
422
|
+
const pan = usePanResponder({
|
|
423
|
+
onMoveShouldSetPanResponder: (_, g) => g.dy > 4 && Math.abs(g.dy) > Math.abs(g.dx),
|
|
424
|
+
onPanResponderMove: (_, g) => drag.setValue(Math.max(0, g.dy)),
|
|
425
|
+
onPanResponderRelease: (_, g) => {
|
|
426
|
+
if (g.dy > 110 || g.vy > 1.1) {
|
|
427
|
+
setOpen(false);
|
|
428
|
+
onOpenChange?.(false);
|
|
429
|
+
} else settle();
|
|
430
|
+
},
|
|
431
|
+
onPanResponderTerminate: settle,
|
|
432
|
+
});
|
|
434
433
|
|
|
435
434
|
const active = error ? colors.danger : tint;
|
|
436
435
|
const rest = error ? colors.danger : ok ? colors.success : ((userBorder as string | undefined) ?? colors.input);
|
|
@@ -451,8 +450,8 @@ export function DatePicker(props: DatePickerProps) {
|
|
|
451
450
|
|
|
452
451
|
const subtitle = isRange(draft)
|
|
453
452
|
? draft.start
|
|
454
|
-
? `${fmt.header(draft.start)} → ${draft.end ? fmt.header(draft.end) :
|
|
455
|
-
:
|
|
453
|
+
? `${fmt.header(draft.start)} → ${draft.end ? fmt.header(draft.end) : labels.pickEndDate}`
|
|
454
|
+
: labels.pickStartDate
|
|
456
455
|
: draft
|
|
457
456
|
? fmt.header(draft)
|
|
458
457
|
: placeholder ?? null;
|
|
@@ -520,7 +519,7 @@ export function DatePicker(props: DatePickerProps) {
|
|
|
520
519
|
style={({ pressed }) => [styles.footBtn, { borderRadius: radius.md, opacity: draft ? (pressed ? 0.6 : 1) : 0.4 }]}
|
|
521
520
|
>
|
|
522
521
|
<Text maxFontSizeMultiplier={FONT_CAP} style={[styles.footText, ff, { color: colors.foreground }]}>
|
|
523
|
-
|
|
522
|
+
{labels.clear}
|
|
524
523
|
</Text>
|
|
525
524
|
</Pressable>
|
|
526
525
|
<Pressable
|
|
@@ -529,7 +528,7 @@ export function DatePicker(props: DatePickerProps) {
|
|
|
529
528
|
style={({ pressed }) => [styles.footBtn, styles.footMain, { backgroundColor: tint, borderRadius: radius.md, opacity: pressed ? 0.85 : 1 }]}
|
|
530
529
|
>
|
|
531
530
|
<Text maxFontSizeMultiplier={FONT_CAP} style={[styles.footText, ff, { color: readableOn(tint) }]}>
|
|
532
|
-
{draftDays > 1 ?
|
|
531
|
+
{draftDays > 1 ? labels.doneDays(draftDays) : labels.done}
|
|
533
532
|
</Text>
|
|
534
533
|
</Pressable>
|
|
535
534
|
</View>
|
|
@@ -569,7 +568,7 @@ export function DatePicker(props: DatePickerProps) {
|
|
|
569
568
|
disabled={disabled}
|
|
570
569
|
accessibilityRole="button"
|
|
571
570
|
accessibilityLabel={label}
|
|
572
|
-
accessibilityValue={{ text: text ||
|
|
571
|
+
accessibilityValue={{ text: text || labels.notSet }}
|
|
573
572
|
accessibilityState={{ expanded: open, disabled: !!disabled }}
|
|
574
573
|
style={{ opacity: disabled ? 0.5 : 1 }}
|
|
575
574
|
>
|
|
@@ -597,7 +596,7 @@ export function DatePicker(props: DatePickerProps) {
|
|
|
597
596
|
!text && { color: placeholderTextColor ?? colors.mutedForeground },
|
|
598
597
|
]}
|
|
599
598
|
>
|
|
600
|
-
{text || (open || !floatingLabel ? placeholder ?? (ranged ?
|
|
599
|
+
{text || (open || !floatingLabel ? placeholder ?? (ranged ? labels.selectDates : labels.selectDate) : '')}
|
|
601
600
|
</Text>
|
|
602
601
|
{floatingLabel ? (
|
|
603
602
|
<Animated.View
|
|
@@ -637,7 +636,7 @@ export function DatePicker(props: DatePickerProps) {
|
|
|
637
636
|
onPress={() => commit(null)}
|
|
638
637
|
hitSlop={12}
|
|
639
638
|
accessibilityRole="button"
|
|
640
|
-
accessibilityLabel={
|
|
639
|
+
accessibilityLabel={labels.clearField(label)}
|
|
641
640
|
style={[styles.clear, { backgroundColor: alpha(restIcon, 0.22) }]}
|
|
642
641
|
>
|
|
643
642
|
<Icon name="x" size={11} color={iconColor ?? colors.foreground} strokeWidth={2.4} />
|
|
@@ -651,7 +650,7 @@ export function DatePicker(props: DatePickerProps) {
|
|
|
651
650
|
|
|
652
651
|
<Modal visible={mounted} transparent animationType="none" statusBarTranslucent onRequestClose={close}>
|
|
653
652
|
<Animated.View style={[StyleSheet.absoluteFill, { backgroundColor: asSheet ? colors.overlay : 'transparent', opacity: show }]}>
|
|
654
|
-
<Pressable style={StyleSheet.absoluteFill} onPress={close} accessibilityLabel=
|
|
653
|
+
<Pressable style={StyleSheet.absoluteFill} onPress={close} accessibilityLabel={labels.close} accessibilityRole="button" />
|
|
655
654
|
</Animated.View>
|
|
656
655
|
{asSheet ? (
|
|
657
656
|
<View style={[styles.sheetHost, wide && styles.centered]} pointerEvents="box-none">
|
|
@@ -679,7 +678,7 @@ export function DatePicker(props: DatePickerProps) {
|
|
|
679
678
|
},
|
|
680
679
|
]}
|
|
681
680
|
>
|
|
682
|
-
<View {...pan
|
|
681
|
+
<View {...pan} style={styles.sheetHeader}>
|
|
683
682
|
{!wide ? <View style={[styles.grabber, { backgroundColor: colors.border }]} /> : null}
|
|
684
683
|
<Text style={[styles.title, ff, { color: colors.foreground }]}>{title ?? label}</Text>
|
|
685
684
|
{subtitle ? (
|
|
@@ -737,7 +736,7 @@ function FieldMessage({
|
|
|
737
736
|
style?: StyleProp<TextStyle>;
|
|
738
737
|
}) {
|
|
739
738
|
const { colors, font } = useKit();
|
|
740
|
-
const enter =
|
|
739
|
+
const [enter] = useState(() => new Animated.Value(tone === 'helper' ? 1 : 0)); // native
|
|
741
740
|
useEffect(() => {
|
|
742
741
|
if (reduce) Animated.timing(enter, { toValue: 1, duration: 150, useNativeDriver: true }).start();
|
|
743
742
|
else Animated.spring(enter, { toValue: 1, useNativeDriver: true, ...motion.snappy }).start();
|