@coinbase/cds-mobile 8.53.1 → 8.55.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +5 -2
  3. package/dts/buttons/IconButton.d.ts +23 -1
  4. package/dts/buttons/IconButton.d.ts.map +1 -1
  5. package/dts/controls/InputIconButton.d.ts +22 -1
  6. package/dts/controls/InputIconButton.d.ts.map +1 -1
  7. package/dts/dates/Calendar.d.ts +170 -0
  8. package/dts/dates/Calendar.d.ts.map +1 -0
  9. package/dts/dates/DateInput.d.ts +2 -2
  10. package/dts/dates/DateInput.d.ts.map +1 -1
  11. package/dts/dates/DatePicker.d.ts +136 -67
  12. package/dts/dates/DatePicker.d.ts.map +1 -1
  13. package/dts/overlays/drawer/Drawer.d.ts +12 -0
  14. package/dts/overlays/drawer/Drawer.d.ts.map +1 -1
  15. package/dts/overlays/drawer/useDrawerSpacing.d.ts +4 -1
  16. package/dts/overlays/drawer/useDrawerSpacing.d.ts.map +1 -1
  17. package/dts/overlays/tooltip/Tooltip.d.ts +9 -1
  18. package/dts/overlays/tooltip/Tooltip.d.ts.map +1 -1
  19. package/dts/overlays/tray/Tray.d.ts +3 -0
  20. package/dts/overlays/tray/Tray.d.ts.map +1 -1
  21. package/dts/sticky-footer/StickyFooter.d.ts.map +1 -1
  22. package/esm/buttons/IconButton.js +4 -3
  23. package/esm/controls/InputIconButton.js +4 -3
  24. package/esm/dates/Calendar.js +346 -0
  25. package/esm/dates/DateInput.js +3 -1
  26. package/esm/dates/DatePicker.js +116 -39
  27. package/esm/dates/__stories__/Calendar.stories.js +360 -0
  28. package/esm/dates/__stories__/DatePicker.stories.js +51 -25
  29. package/esm/overlays/__stories__/TrayAction.stories.js +20 -21
  30. package/esm/overlays/__stories__/TrayInformational.stories.js +40 -43
  31. package/esm/overlays/__stories__/TrayMessaging.stories.js +36 -37
  32. package/esm/overlays/__stories__/TrayPromotional.stories.js +51 -74
  33. package/esm/overlays/__stories__/TrayRedesign.stories.js +5 -12
  34. package/esm/overlays/__stories__/Trays.js +1 -0
  35. package/esm/overlays/drawer/Drawer.js +9 -13
  36. package/esm/overlays/drawer/useDrawerSpacing.js +11 -8
  37. package/esm/overlays/tooltip/Tooltip.js +7 -2
  38. package/esm/overlays/tray/Tray.js +5 -0
  39. package/esm/sticky-footer/StickyFooter.js +4 -2
  40. package/esm/sticky-footer/__stories__/StickyFooterWithTray.stories.js +37 -42
  41. package/package.json +2 -4
@@ -1,15 +1,24 @@
1
- const _excluded = ["date", "onChangeDate", "error", "onErrorDate", "required", "disabled", "seedDate", "minDate", "maxDate", "requiredError", "invalidDateError", "disabledDateError", "label", "accessibilityLabel", "accessibilityLabelledBy", "calendarIconButtonAccessibilityLabel", "dateInputStyle", "compact", "variant", "helperText", "width", "onOpen", "onClose", "onConfirm", "onCancel", "onChange"];
1
+ const _excluded = ["date", "styles", "highlightedDates", "highlightedDateAccessibilityHint", "nextArrowAccessibilityLabel", "previousArrowAccessibilityLabel", "disabledDates", "onChangeDate", "error", "onErrorDate", "required", "disabled", "seedDate", "minDate", "maxDate", "requiredError", "invalidDateError", "disabledDateError", "label", "accessibilityHint", "accessibilityLabel", "accessibilityLabelledBy", "calendarIconButtonAccessibilityLabel", "openCalendarAccessibilityLabel", "closeCalendarAccessibilityLabel", "dateInputStyle", "compact", "variant", "confirmText", "confirmButtonAccessibilityHint", "helperText", "width", "onOpen", "onClose", "onConfirm", "onCancel", "onChange"];
2
2
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
3
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
4
4
  import { forwardRef, memo, useCallback, useMemo, useRef, useState } from 'react';
5
- import NativeDatePicker from 'react-native-date-picker';
5
+ import { Button } from '../buttons/Button';
6
6
  import { InputIconButton } from '../controls/InputIconButton';
7
7
  import { Box, VStack } from '../layout';
8
+ import { Tray } from '../overlays/tray/Tray';
9
+ import { StickyFooter } from '../sticky-footer/StickyFooter';
10
+ import { Calendar } from './Calendar';
8
11
  import { DateInput } from './DateInput';
9
12
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
13
  export const DatePicker = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) => {
11
14
  let {
12
15
  date,
16
+ styles,
17
+ highlightedDates,
18
+ highlightedDateAccessibilityHint,
19
+ nextArrowAccessibilityLabel,
20
+ previousArrowAccessibilityLabel,
21
+ disabledDates,
13
22
  onChangeDate,
14
23
  error,
15
24
  onErrorDate,
@@ -22,12 +31,17 @@ export const DatePicker = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref)
22
31
  invalidDateError = 'Please enter a valid date',
23
32
  disabledDateError = 'Date unavailable',
24
33
  label,
34
+ accessibilityHint = 'Enter date or select from calendar using the calendar button.',
25
35
  accessibilityLabel,
26
36
  accessibilityLabelledBy,
27
37
  calendarIconButtonAccessibilityLabel,
38
+ openCalendarAccessibilityLabel = 'Open calendar',
39
+ closeCalendarAccessibilityLabel = 'Close calendar without selecting a date',
28
40
  dateInputStyle,
29
41
  compact,
30
42
  variant,
43
+ confirmText = 'Confirm',
44
+ confirmButtonAccessibilityHint,
31
45
  helperText,
32
46
  width = '100%',
33
47
  onOpen,
@@ -37,61 +51,78 @@ export const DatePicker = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref)
37
51
  onChange
38
52
  } = _ref,
39
53
  props = _objectWithoutPropertiesLoose(_ref, _excluded);
40
- const [showNativePicker, setShowNativePicker] = useState(false);
54
+ const [showPicker, setShowPicker] = useState(false);
55
+ const [calendarSelectedDate, setCalendarSelectedDate] = useState(null);
41
56
  const dateInputRef = useRef(null);
42
- const today = useMemo(() => new Date(), []);
43
-
57
+ const calendarButtonRef = useRef(null);
58
+ const calendarRef = useRef(null);
59
+ const closedByConfirmRef = useRef(false);
44
60
  /**
45
61
  * Be careful to preserve the correct event orders
46
- * 1. Selecting a date with the native picker: onOpen -> onConfirm -> onChangeDate -> onErrorDate -> onClose
47
- * 2. Closing the native picker without selecting a date: onOpen -> onCancel -> onClose
62
+ * 1. Selecting a date with the picker: onOpen -> onConfirm -> onChangeDate -> onErrorDate -> onClose
63
+ * 2. Closing the picker without selecting a date: onOpen -> onCancel -> onClose
48
64
  * 3. Typing a date in a blank DateInput: onChange -> onChange -> ... -> onChangeDate -> onErrorDate
49
65
  * 4. Typing a date in a DateInput that already had a date: onChange -> onChangeDate -> onChange -> onChange -> ... -> onChangeDate -> onErrorDate
50
66
  */
51
67
 
52
- const handleOpenNativePicker = useCallback(() => {
68
+ const handleOpenPicker = useCallback(() => {
53
69
  onOpen == null || onOpen();
54
- setShowNativePicker(true);
55
- }, [onOpen]);
56
- const handleCloseNativePicker = useCallback(() => {
57
- onClose == null || onClose();
58
- setShowNativePicker(false);
59
- }, [onClose]);
60
- const handleConfirmNativePicker = useCallback(date => {
61
- var _dateInputRef$current;
70
+ setCalendarSelectedDate(date); // Initialize with current date
71
+ setShowPicker(true);
72
+ }, [onOpen, date]);
73
+ const handleConfirmPicker = useCallback(selectedDate => {
74
+ closedByConfirmRef.current = true;
62
75
  onConfirm == null || onConfirm();
63
- onChangeDate(date);
64
- if (error && error.type !== 'custom') onErrorDate(null);
65
- handleCloseNativePicker();
66
- (_dateInputRef$current = dateInputRef.current) == null || _dateInputRef$current.focus();
67
- }, [onChangeDate, onConfirm, error, onErrorDate, handleCloseNativePicker]);
68
- const handleCancelNativePicker = useCallback(() => {
69
- onCancel == null || onCancel();
70
- handleCloseNativePicker();
71
- }, [onCancel, handleCloseNativePicker]);
76
+ onChangeDate(selectedDate);
77
+ if (error && error.type !== 'custom') {
78
+ onErrorDate(null);
79
+ }
80
+ }, [onChangeDate, onConfirm, error, onErrorDate]);
81
+ const handleTrayCloseComplete = useCallback(() => {
82
+ if (!closedByConfirmRef.current) {
83
+ onCancel == null || onCancel();
84
+ setCalendarSelectedDate(null);
85
+ }
86
+ onClose == null || onClose();
87
+ setShowPicker(false);
88
+ closedByConfirmRef.current = false;
89
+ }, [onCancel, onClose]);
90
+ const handleCalendarDatePress = useCallback(selectedDate => {
91
+ // Update local state, user must press confirm button
92
+ setCalendarSelectedDate(selectedDate);
93
+ }, []);
94
+ const handleModalShow = useCallback(() => {
95
+ var _calendarRef$current;
96
+ (_calendarRef$current = calendarRef.current) == null || _calendarRef$current.focusInitialDate();
97
+ }, []);
72
98
  const dateInputCalendarButton = useMemo(() => /*#__PURE__*/_jsx(VStack, {
99
+ accessible: true,
73
100
  paddingEnd: 0.5,
74
101
  children: /*#__PURE__*/_jsx(InputIconButton, {
102
+ ref: calendarButtonRef,
75
103
  disableInheritFocusStyle: true,
76
104
  transparent: true,
77
- accessibilityLabel: calendarIconButtonAccessibilityLabel != null ? calendarIconButtonAccessibilityLabel : showNativePicker ? 'Close calendar' : 'Open calendar',
105
+ accessibilityLabel: calendarIconButtonAccessibilityLabel != null ? calendarIconButtonAccessibilityLabel : openCalendarAccessibilityLabel,
106
+ disabled: disabled,
78
107
  name: "calendarEmpty",
79
- onPress: handleOpenNativePicker,
108
+ onPress: handleOpenPicker,
80
109
  variant: "secondary"
81
110
  })
82
- }), [handleOpenNativePicker, showNativePicker, calendarIconButtonAccessibilityLabel]);
111
+ }), [handleOpenPicker, openCalendarAccessibilityLabel, calendarIconButtonAccessibilityLabel, disabled]);
83
112
  return /*#__PURE__*/_jsxs(Box, {
84
113
  ref: ref,
85
114
  width: width,
86
115
  children: [/*#__PURE__*/_jsx(DateInput, _extends({
87
116
  ref: dateInputRef
88
117
  }, props, {
118
+ accessibilityHint: accessibilityHint,
89
119
  accessibilityLabel: accessibilityLabel,
90
120
  accessibilityLabelledBy: accessibilityLabelledBy,
91
121
  compact: compact,
92
122
  date: date,
93
123
  disabled: disabled,
94
124
  disabledDateError: disabledDateError,
125
+ disabledDates: disabledDates,
95
126
  end: dateInputCalendarButton,
96
127
  error: error,
97
128
  helperText: helperText,
@@ -104,17 +135,63 @@ export const DatePicker = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref)
104
135
  onErrorDate: onErrorDate,
105
136
  required: required,
106
137
  requiredError: requiredError,
107
- style: dateInputStyle,
138
+ style: [dateInputStyle, styles == null ? void 0 : styles.dateInput],
108
139
  variant: variant
109
- })), showNativePicker && /*#__PURE__*/_jsx(NativeDatePicker, {
110
- modal: true,
111
- date: date || seedDate || today,
112
- maximumDate: maxDate,
113
- minimumDate: minDate,
114
- mode: "date",
115
- onCancel: handleCancelNativePicker,
116
- onConfirm: handleConfirmNativePicker,
117
- open: showNativePicker
140
+ })), showPicker && /*#__PURE__*/_jsx(Tray, {
141
+ accessibilityRole: "none",
142
+ footer: _ref2 => {
143
+ let {
144
+ handleClose
145
+ } = _ref2;
146
+ return /*#__PURE__*/_jsx(StickyFooter, {
147
+ paddingTop: 3,
148
+ paddingX: 3,
149
+ role: "none",
150
+ children: /*#__PURE__*/_jsx(Button, {
151
+ block: true,
152
+ compact: true,
153
+ accessibilityHint: confirmButtonAccessibilityHint,
154
+ disabled: disabled || !calendarSelectedDate,
155
+ onPress: () => {
156
+ if (calendarSelectedDate) {
157
+ handleConfirmPicker(calendarSelectedDate);
158
+ handleClose();
159
+ }
160
+ },
161
+ children: confirmText
162
+ })
163
+ });
164
+ },
165
+ handleBarAccessibilityLabel: closeCalendarAccessibilityLabel,
166
+ handleBarVariant: "inside",
167
+ onCloseComplete: handleTrayCloseComplete,
168
+ onOpenComplete: handleModalShow,
169
+ children: /*#__PURE__*/_jsx(Calendar, {
170
+ ref: calendarRef,
171
+ disabled: disabled,
172
+ disabledDateError: disabledDateError,
173
+ disabledDates: disabledDates,
174
+ highlightedDateAccessibilityHint: highlightedDateAccessibilityHint,
175
+ highlightedDates: highlightedDates,
176
+ maxDate: maxDate,
177
+ minDate: minDate,
178
+ nextArrowAccessibilityLabel: nextArrowAccessibilityLabel,
179
+ onPressDate: handleCalendarDatePress,
180
+ paddingBottom: 2,
181
+ paddingX: 3,
182
+ previousArrowAccessibilityLabel: previousArrowAccessibilityLabel,
183
+ seedDate: seedDate,
184
+ selectedDate: calendarSelectedDate,
185
+ styles: {
186
+ root: styles == null ? void 0 : styles.calendar,
187
+ header: styles == null ? void 0 : styles.calendarHeader,
188
+ title: styles == null ? void 0 : styles.calendarTitle,
189
+ navigation: styles == null ? void 0 : styles.calendarNavigation,
190
+ content: styles == null ? void 0 : styles.calendarContent,
191
+ day: styles == null ? void 0 : styles.calendarDay
192
+ }
193
+ })
118
194
  })]
119
195
  });
120
- }));
196
+ }));
197
+ DatePicker.displayName = 'DatePicker';
@@ -0,0 +1,360 @@
1
+ import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
+ import { useLocale } from '@coinbase/cds-common/system/LocaleProvider';
3
+ import { Accordion, AccordionItem } from '../../accordion';
4
+ import { Button } from '../../buttons/Button';
5
+ import { Chip } from '../../chips';
6
+ import { Example, ExampleScreen } from '../../examples/ExampleScreen';
7
+ import { useTheme } from '../../hooks/useTheme';
8
+ import { Icon } from '../../icons';
9
+ import { Box } from '../../layout';
10
+ import { AnimatedCaret } from '../../motion/AnimatedCaret';
11
+ import { Tray } from '../../overlays/tray/Tray';
12
+ import { Calendar } from '../Calendar';
13
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
14
+ const today = new Date(new Date().setHours(0, 0, 0, 0));
15
+ const nextMonth15th = new Date(today.getFullYear(), today.getMonth() + 1, 15);
16
+ const lastMonth15th = new Date(today.getFullYear(), today.getMonth() - 1, 15);
17
+ const nextWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 7);
18
+ const yesterday = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1);
19
+ const tomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
20
+ const twoDaysAgo = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 2);
21
+
22
+ // Generate all weekend date ranges for a wide range (10 years before and after)
23
+ const getWeekendDates = centerDate => {
24
+ const weekends = [];
25
+
26
+ // Cover 10 years before and after to ensure all weekends are disabled
27
+ const startDate = new Date(centerDate.getFullYear() - 10, 0, 1);
28
+ const endDate = new Date(centerDate.getFullYear() + 10, 11, 31);
29
+
30
+ // Find the first Saturday in the range
31
+ const currentDate = new Date(startDate);
32
+ const dayOfWeek = currentDate.getDay();
33
+ const daysUntilSaturday = dayOfWeek === 6 ? 0 : (6 - dayOfWeek + 7) % 7;
34
+ currentDate.setDate(currentDate.getDate() + daysUntilSaturday);
35
+
36
+ // Iterate through weekends, jumping 7 days at a time
37
+ while (currentDate <= endDate) {
38
+ const saturday = new Date(currentDate);
39
+ const sunday = new Date(currentDate);
40
+ sunday.setDate(sunday.getDate() + 1);
41
+
42
+ // Add the weekend as a date range tuple
43
+ weekends.push([saturday, sunday]);
44
+
45
+ // Jump to next Saturday (7 days later)
46
+ currentDate.setDate(currentDate.getDate() + 7);
47
+ }
48
+ return weekends;
49
+ };
50
+
51
+ // Compute weekends once at module level
52
+ const disabledWeekend = getWeekendDates(today);
53
+ const DATE_ACCORDION_ITEM_KEY = 'date';
54
+ const formatDateLabel = (date, locale) => {
55
+ if (!date) {
56
+ return 'Select date';
57
+ }
58
+ return date.toLocaleDateString(locale, {
59
+ month: 'short',
60
+ day: 'numeric',
61
+ year: 'numeric'
62
+ });
63
+ };
64
+ const CalendarTrayExample = /*#__PURE__*/memo(function CalendarTrayExample(_ref) {
65
+ let {
66
+ renderTrigger
67
+ } = _ref;
68
+ const {
69
+ locale
70
+ } = useLocale();
71
+ const [date, setDate] = useState(null);
72
+ const [showPicker, setShowPicker] = useState(false);
73
+ const [calendarSelectedDate, setCalendarSelectedDate] = useState(null);
74
+ const calendarRef = useRef(null);
75
+ const handleOpenPicker = useCallback(() => {
76
+ setCalendarSelectedDate(date);
77
+ setShowPicker(true);
78
+ }, [date]);
79
+ const handleClosePicker = useCallback(() => {
80
+ setShowPicker(false);
81
+ }, []);
82
+ const handleCancelPicker = useCallback(() => {
83
+ setCalendarSelectedDate(null);
84
+ handleClosePicker();
85
+ }, [handleClosePicker]);
86
+ const handleCalendarDatePress = useCallback(selectedDate => {
87
+ setCalendarSelectedDate(selectedDate);
88
+ }, []);
89
+ const handleModalShow = useCallback(() => {
90
+ var _calendarRef$current;
91
+ (_calendarRef$current = calendarRef.current) == null || _calendarRef$current.focusInitialDate();
92
+ }, []);
93
+ const handleConfirmCalendar = useCallback(() => {
94
+ if (calendarSelectedDate) {
95
+ setDate(calendarSelectedDate);
96
+ handleClosePicker();
97
+ }
98
+ }, [calendarSelectedDate, handleClosePicker]);
99
+ const trayFooter = useMemo(() => /*#__PURE__*/_jsx(Box, {
100
+ paddingTop: 3,
101
+ paddingX: 3,
102
+ children: /*#__PURE__*/_jsx(Button, {
103
+ block: true,
104
+ compact: true,
105
+ accessibilityHint: !calendarSelectedDate ? 'Select a date first' : undefined,
106
+ accessibilityLabel: "Confirm date selection",
107
+ disabled: !calendarSelectedDate,
108
+ onPress: handleConfirmCalendar,
109
+ children: "Confirm"
110
+ })
111
+ }), [calendarSelectedDate, handleConfirmCalendar]);
112
+ const formattedLabel = formatDateLabel(date, locale);
113
+ const triggerProps = useMemo(() => ({
114
+ formattedLabel,
115
+ onOpen: handleOpenPicker,
116
+ showPicker
117
+ }), [formattedLabel, handleOpenPicker, showPicker]);
118
+ return /*#__PURE__*/_jsxs(_Fragment, {
119
+ children: [renderTrigger(triggerProps), showPicker && /*#__PURE__*/_jsx(Tray, {
120
+ accessibilityRole: "none",
121
+ footer: trayFooter,
122
+ handleBarAccessibilityLabel: "Close calendar",
123
+ handleBarVariant: "inside",
124
+ onCloseComplete: handleCancelPicker,
125
+ onOpenComplete: handleModalShow,
126
+ children: /*#__PURE__*/_jsx(Calendar, {
127
+ ref: calendarRef,
128
+ onPressDate: handleCalendarDatePress,
129
+ paddingBottom: 2,
130
+ paddingX: 2,
131
+ selectedDate: calendarSelectedDate
132
+ })
133
+ })]
134
+ });
135
+ });
136
+ const CalendarChipWithTrayExample = () => {
137
+ const renderTrigger = useCallback(_ref2 => {
138
+ let {
139
+ formattedLabel,
140
+ onOpen,
141
+ showPicker
142
+ } = _ref2;
143
+ return /*#__PURE__*/_jsx(Box, {
144
+ alignSelf: "flex-start",
145
+ children: /*#__PURE__*/_jsx(Chip, {
146
+ compact: true,
147
+ accessibilityLabel: formattedLabel,
148
+ end: /*#__PURE__*/_jsx(AnimatedCaret, {
149
+ active: true,
150
+ color: "fg",
151
+ rotate: showPicker ? 0 : 180,
152
+ size: "xs"
153
+ }),
154
+ onPress: onOpen,
155
+ children: formattedLabel
156
+ })
157
+ });
158
+ }, []);
159
+ return /*#__PURE__*/_jsx(CalendarTrayExample, {
160
+ renderTrigger: renderTrigger
161
+ });
162
+ };
163
+ const CalendarChipWithTrayButtonExample = () => {
164
+ const renderTrigger = useCallback(_ref3 => {
165
+ let {
166
+ formattedLabel,
167
+ onOpen
168
+ } = _ref3;
169
+ return /*#__PURE__*/_jsx(Button, {
170
+ compact: true,
171
+ accessibilityLabel: formattedLabel,
172
+ onPress: onOpen,
173
+ children: formattedLabel
174
+ });
175
+ }, []);
176
+ return /*#__PURE__*/_jsx(CalendarTrayExample, {
177
+ renderTrigger: renderTrigger
178
+ });
179
+ };
180
+ const CalendarAccordionExample = () => {
181
+ const {
182
+ locale
183
+ } = useLocale();
184
+ const [date, setDate] = useState(null);
185
+ const [activeKey, setActiveKey] = useState(null);
186
+ const expanded = activeKey === DATE_ACCORDION_ITEM_KEY;
187
+ const calendarRef = useRef(null);
188
+ const handleDatePress = useCallback(selectedDate => {
189
+ setDate(selectedDate);
190
+ setActiveKey(null);
191
+ }, []);
192
+ useEffect(() => {
193
+ if (expanded) {
194
+ const id = requestAnimationFrame(() => {
195
+ var _calendarRef$current2;
196
+ (_calendarRef$current2 = calendarRef.current) == null || _calendarRef$current2.focusInitialDate();
197
+ });
198
+ return () => cancelAnimationFrame(id);
199
+ }
200
+ }, [expanded]);
201
+ return /*#__PURE__*/_jsx(Accordion, {
202
+ activeKey: activeKey,
203
+ setActiveKey: setActiveKey,
204
+ children: /*#__PURE__*/_jsx(AccordionItem, {
205
+ itemKey: DATE_ACCORDION_ITEM_KEY,
206
+ media: /*#__PURE__*/_jsx(Icon, {
207
+ color: "fg",
208
+ name: "calendarEmpty"
209
+ }),
210
+ subtitle: formatDateLabel(date, locale),
211
+ title: "Date",
212
+ children: expanded ? /*#__PURE__*/_jsx(Calendar, {
213
+ ref: calendarRef,
214
+ onPressDate: handleDatePress,
215
+ selectedDate: date
216
+ }) : null
217
+ })
218
+ });
219
+ };
220
+ const CalendarScreen = () => {
221
+ const [basicDate, setBasicDate] = useState(today);
222
+ const [noSelectionDate, setNoSelectionDate] = useState(null);
223
+ const [seedDateDate, setSeedDateDate] = useState(null);
224
+ const [minMaxDate, setMinMaxDate] = useState(today);
225
+ const [futureDatesDate, setFutureDatesDate] = useState(null);
226
+ const [highlightedDate, setHighlightedDate] = useState(today);
227
+ const [disabledDatesDate, setDisabledDatesDate] = useState(null);
228
+ const [rangeDate, setRangeDate] = useState(today);
229
+ const [hiddenControlsDate, setHiddenControlsDate] = useState(today);
230
+ const highlightedRange = [yesterday, nextWeek];
231
+ const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);
232
+ const lastDayOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0);
233
+ const {
234
+ color
235
+ } = useTheme();
236
+ return /*#__PURE__*/_jsxs(ExampleScreen, {
237
+ children: [/*#__PURE__*/_jsx(Example, {
238
+ title: "Basic",
239
+ children: /*#__PURE__*/_jsx(Calendar, {
240
+ onPressDate: setBasicDate,
241
+ selectedDate: basicDate
242
+ })
243
+ }), /*#__PURE__*/_jsx(Example, {
244
+ title: "No selection",
245
+ children: /*#__PURE__*/_jsx(Calendar, {
246
+ onPressDate: setNoSelectionDate,
247
+ selectedDate: noSelectionDate
248
+ })
249
+ }), /*#__PURE__*/_jsx(Example, {
250
+ title: "With seedDate (different month)",
251
+ children: /*#__PURE__*/_jsx(Calendar, {
252
+ onPressDate: setSeedDateDate,
253
+ seedDate: nextMonth15th,
254
+ selectedDate: seedDateDate
255
+ })
256
+ }), /*#__PURE__*/_jsx(Example, {
257
+ title: "With min/max dates",
258
+ children: /*#__PURE__*/_jsx(Calendar, {
259
+ disabledDateError: "Date is outside allowed range",
260
+ maxDate: nextMonth15th,
261
+ minDate: lastMonth15th,
262
+ onPressDate: setMinMaxDate,
263
+ selectedDate: minMaxDate
264
+ })
265
+ }), /*#__PURE__*/_jsx(Example, {
266
+ title: "Future dates only",
267
+ children: /*#__PURE__*/_jsx(Calendar, {
268
+ disabledDateError: "Past dates are not available",
269
+ minDate: today,
270
+ onPressDate: setFutureDatesDate,
271
+ selectedDate: futureDatesDate
272
+ })
273
+ }), /*#__PURE__*/_jsx(Example, {
274
+ title: "With highlighted dates",
275
+ children: /*#__PURE__*/_jsx(Calendar, {
276
+ highlightedDates: [yesterday, today, nextWeek],
277
+ onPressDate: setHighlightedDate,
278
+ selectedDate: highlightedDate
279
+ })
280
+ }), /*#__PURE__*/_jsx(Example, {
281
+ title: "With disabled dates",
282
+ children: /*#__PURE__*/_jsx(Calendar, {
283
+ disabledDateError: "Weekends are not available",
284
+ disabledDates: disabledWeekend,
285
+ onPressDate: setDisabledDatesDate,
286
+ seedDate: today,
287
+ selectedDate: disabledDatesDate
288
+ })
289
+ }), /*#__PURE__*/_jsx(Example, {
290
+ title: "With date range",
291
+ children: /*#__PURE__*/_jsx(Calendar, {
292
+ highlightedDates: [highlightedRange],
293
+ onPressDate: setRangeDate,
294
+ selectedDate: rangeDate
295
+ })
296
+ }), /*#__PURE__*/_jsx(Example, {
297
+ title: "Hidden controls",
298
+ children: /*#__PURE__*/_jsx(Calendar, {
299
+ hideControls: true,
300
+ maxDate: lastDayOfMonth,
301
+ minDate: firstDayOfMonth,
302
+ onPressDate: setHiddenControlsDate,
303
+ selectedDate: hiddenControlsDate
304
+ })
305
+ }), /*#__PURE__*/_jsx(Example, {
306
+ title: "Disabled",
307
+ children: /*#__PURE__*/_jsx(Calendar, {
308
+ disabled: true,
309
+ selectedDate: today
310
+ })
311
+ }), /*#__PURE__*/_jsx(Example, {
312
+ title: "Slot styling",
313
+ children: /*#__PURE__*/_jsx(Calendar, {
314
+ disabledDateError: "Date unavailable",
315
+ disabledDates: [twoDaysAgo],
316
+ highlightedDates: [tomorrow],
317
+ maxDate: nextMonth15th,
318
+ minDate: lastMonth15th,
319
+ onPressDate: setBasicDate,
320
+ selectedDate: basicDate,
321
+ styles: {
322
+ root: {
323
+ borderColor: color.bgLineHeavy,
324
+ borderRadius: 16,
325
+ borderWidth: 1,
326
+ padding: 12
327
+ },
328
+ header: {
329
+ backgroundColor: color.bgPositiveWash,
330
+ borderRadius: 16,
331
+ paddingBottom: 0
332
+ },
333
+ content: {
334
+ paddingVertical: 8
335
+ },
336
+ day: {
337
+ borderColor: color.bgNegative,
338
+ borderWidth: 1
339
+ },
340
+ navigation: {
341
+ borderColor: color.bgLineHeavy,
342
+ borderRadius: 8,
343
+ borderStyle: 'dashed',
344
+ borderWidth: 1
345
+ }
346
+ }
347
+ })
348
+ }), /*#__PURE__*/_jsx(Example, {
349
+ title: "With tray (Chip trigger)",
350
+ children: /*#__PURE__*/_jsx(CalendarChipWithTrayExample, {})
351
+ }), /*#__PURE__*/_jsx(Example, {
352
+ title: "With tray (Button trigger)",
353
+ children: /*#__PURE__*/_jsx(CalendarChipWithTrayButtonExample, {})
354
+ }), /*#__PURE__*/_jsx(Example, {
355
+ title: "With Accordion (select to collapse)",
356
+ children: /*#__PURE__*/_jsx(CalendarAccordionExample, {})
357
+ })]
358
+ });
359
+ };
360
+ export default CalendarScreen;