@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);
|