cpk-ui 0.5.5 → 0.8.0-beta.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 (175) hide show
  1. package/README.md +80 -147
  2. package/components/modals/AlertDialog/AlertDialog.d.ts.map +1 -1
  3. package/components/modals/AlertDialog/AlertDialog.js +14 -7
  4. package/components/modals/Snackbar/Snackbar.d.ts.map +1 -1
  5. package/components/modals/Snackbar/Snackbar.js +20 -17
  6. package/components/uis/Accordion/AccordionItem.d.ts.map +1 -1
  7. package/components/uis/Accordion/AccordionItem.js +41 -17
  8. package/components/uis/Button/Button.d.ts.map +1 -1
  9. package/components/uis/Button/Button.js +10 -10
  10. package/components/uis/Calendar/Calendar.d.ts +6 -0
  11. package/components/uis/Calendar/Calendar.d.ts.map +1 -0
  12. package/components/uis/Calendar/Calendar.js +482 -0
  13. package/components/uis/Calendar/CalendarDay.d.ts +21 -0
  14. package/components/uis/Calendar/CalendarDay.d.ts.map +1 -0
  15. package/components/uis/Calendar/CalendarDay.js +172 -0
  16. package/components/uis/Calendar/CalendarHeader.d.ts +22 -0
  17. package/components/uis/Calendar/CalendarHeader.d.ts.map +1 -0
  18. package/components/uis/Calendar/CalendarHeader.js +40 -0
  19. package/components/uis/Calendar/CalendarPage.d.ts +46 -0
  20. package/components/uis/Calendar/CalendarPage.d.ts.map +1 -0
  21. package/components/uis/Calendar/CalendarPage.js +34 -0
  22. package/components/uis/Calendar/CalendarPager.d.ts +11 -0
  23. package/components/uis/Calendar/CalendarPager.d.ts.map +1 -0
  24. package/components/uis/Calendar/CalendarPager.js +115 -0
  25. package/components/uis/Calendar/CalendarPager.web.d.ts +11 -0
  26. package/components/uis/Calendar/CalendarPager.web.d.ts.map +1 -0
  27. package/components/uis/Calendar/CalendarPager.web.js +72 -0
  28. package/components/uis/Calendar/CalendarWeekRow.d.ts +20 -0
  29. package/components/uis/Calendar/CalendarWeekRow.d.ts.map +1 -0
  30. package/components/uis/Calendar/CalendarWeekRow.js +64 -0
  31. package/components/uis/Calendar/CalendarWeekdayRow.d.ts +24 -0
  32. package/components/uis/Calendar/CalendarWeekdayRow.d.ts.map +1 -0
  33. package/components/uis/Calendar/CalendarWeekdayRow.js +45 -0
  34. package/components/uis/Calendar/intl.d.ts +18 -0
  35. package/components/uis/Calendar/intl.d.ts.map +1 -0
  36. package/components/uis/Calendar/intl.js +146 -0
  37. package/components/uis/Calendar/palette.d.ts +10 -0
  38. package/components/uis/Calendar/palette.d.ts.map +1 -0
  39. package/components/uis/Calendar/palette.js +93 -0
  40. package/components/uis/Calendar/types.d.ts +286 -0
  41. package/components/uis/Calendar/types.d.ts.map +1 -0
  42. package/components/uis/Calendar/types.js +1 -0
  43. package/components/uis/Calendar/useCalendarState.d.ts +66 -0
  44. package/components/uis/Calendar/useCalendarState.d.ts.map +1 -0
  45. package/components/uis/Calendar/useCalendarState.js +211 -0
  46. package/components/uis/Calendar/utils.d.ts +114 -0
  47. package/components/uis/Calendar/utils.d.ts.map +1 -0
  48. package/components/uis/Calendar/utils.js +429 -0
  49. package/components/uis/Card/Card.d.ts +2 -1
  50. package/components/uis/Card/Card.d.ts.map +1 -1
  51. package/components/uis/Card/Card.js +12 -3
  52. package/components/uis/Checkbox/Checkbox.d.ts.map +1 -1
  53. package/components/uis/Checkbox/Checkbox.js +1 -1
  54. package/components/uis/CustomPressable/CustomPressable.d.ts.map +1 -1
  55. package/components/uis/CustomPressable/CustomPressable.js +6 -6
  56. package/components/uis/EditText/EditText.d.ts.map +1 -1
  57. package/components/uis/EditText/EditText.js +17 -12
  58. package/components/uis/Fab/Fab.d.ts +2 -2
  59. package/components/uis/Fab/Fab.d.ts.map +1 -1
  60. package/components/uis/Fab/Fab.js +22 -4
  61. package/components/uis/Icon/Icon.d.ts.map +1 -1
  62. package/components/uis/Icon/Icon.js +6 -3
  63. package/components/uis/IconButton/IconButton.d.ts.map +1 -1
  64. package/components/uis/IconButton/IconButton.js +43 -41
  65. package/components/uis/LoadingIndicator/LoadingIndicator.d.ts +2 -1
  66. package/components/uis/LoadingIndicator/LoadingIndicator.d.ts.map +1 -1
  67. package/components/uis/LoadingIndicator/LoadingIndicator.js +4 -4
  68. package/components/uis/ParallaxHeader/ParallaxHeader.d.ts +44 -0
  69. package/components/uis/ParallaxHeader/ParallaxHeader.d.ts.map +1 -0
  70. package/components/uis/ParallaxHeader/ParallaxHeader.js +142 -0
  71. package/components/uis/RadioGroup/RadioButton.d.ts.map +1 -1
  72. package/components/uis/RadioGroup/RadioButton.js +1 -1
  73. package/components/uis/RadioGroup/RadioGroup.d.ts.map +1 -1
  74. package/components/uis/RadioGroup/RadioGroup.js +16 -3
  75. package/components/uis/Rating/Rating.d.ts.map +1 -1
  76. package/components/uis/Rating/Rating.js +23 -19
  77. package/components/uis/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  78. package/components/uis/SegmentedControl/SegmentedControl.js +1 -1
  79. package/components/uis/StatusbarBrightness/StatusBarBrightness.d.ts +2 -2
  80. package/components/uis/StatusbarBrightness/StatusBarBrightness.d.ts.map +1 -1
  81. package/components/uis/StatusbarBrightness/StatusBarBrightness.js +1 -1
  82. package/components/uis/SwitchToggle/SwitchToggle.d.ts.map +1 -1
  83. package/components/uis/SwitchToggle/SwitchToggle.js +1 -1
  84. package/hooks/useHoverState.d.ts +8 -0
  85. package/hooks/useHoverState.d.ts.map +1 -0
  86. package/hooks/useHoverState.js +16 -0
  87. package/index.d.ts +2 -0
  88. package/index.d.ts.map +1 -1
  89. package/index.js +2 -0
  90. package/package.json +19 -6
  91. package/providers/ThemeProvider.d.ts.map +1 -1
  92. package/providers/ThemeProvider.js +0 -1
  93. package/providers/index.d.ts.map +1 -1
  94. package/providers/index.js +3 -2
  95. package/components/uis/Icon/selection.json +0 -1
  96. package/src/components/common/ErrorBoundary/ErrorBoundary.tsx +0 -75
  97. package/src/components/modals/AlertDialog/AlertDialog.stories.tsx +0 -216
  98. package/src/components/modals/AlertDialog/AlertDialog.test.tsx +0 -251
  99. package/src/components/modals/AlertDialog/AlertDialog.tsx +0 -356
  100. package/src/components/modals/Snackbar/Snackbar.stories.tsx +0 -182
  101. package/src/components/modals/Snackbar/Snackbar.test.tsx +0 -319
  102. package/src/components/modals/Snackbar/Snackbar.tsx +0 -260
  103. package/src/components/modals/Snackbar/const.ts +0 -4
  104. package/src/components/uis/Accordion/Accordion.stories.tsx +0 -167
  105. package/src/components/uis/Accordion/Accordion.test.tsx +0 -272
  106. package/src/components/uis/Accordion/Accordion.tsx +0 -109
  107. package/src/components/uis/Accordion/AccordionItem.tsx +0 -306
  108. package/src/components/uis/Button/Button.stories.tsx +0 -218
  109. package/src/components/uis/Button/Button.test.tsx +0 -694
  110. package/src/components/uis/Button/Button.tsx +0 -440
  111. package/src/components/uis/Card/Card.test.tsx +0 -146
  112. package/src/components/uis/Card/Card.tsx +0 -102
  113. package/src/components/uis/Checkbox/Checkbox.stories.tsx +0 -216
  114. package/src/components/uis/Checkbox/Checkbox.test.tsx +0 -267
  115. package/src/components/uis/Checkbox/Checkbox.tsx +0 -225
  116. package/src/components/uis/CustomPressable/CustomPressable.tsx +0 -48
  117. package/src/components/uis/EditText/EditText.stories.tsx +0 -124
  118. package/src/components/uis/EditText/EditText.test.tsx +0 -477
  119. package/src/components/uis/EditText/EditText.tsx +0 -593
  120. package/src/components/uis/Fab/Fab.stories.tsx +0 -133
  121. package/src/components/uis/Fab/Fab.test.tsx +0 -110
  122. package/src/components/uis/Fab/Fab.tsx +0 -168
  123. package/src/components/uis/Hr/Hr.test.tsx +0 -26
  124. package/src/components/uis/Hr/Hr.tsx +0 -19
  125. package/src/components/uis/Icon/Icon.stories.tsx +0 -98
  126. package/src/components/uis/Icon/Icon.test.tsx +0 -49
  127. package/src/components/uis/Icon/Icon.tsx +0 -3819
  128. package/src/components/uis/IconButton/IconButton.test.tsx +0 -204
  129. package/src/components/uis/IconButton/IconButton.tsx +0 -279
  130. package/src/components/uis/LoadingIndicator/LoadingIndicator.tsx +0 -126
  131. package/src/components/uis/LoadingIndicator/LodingIndicator.stories.tsx +0 -81
  132. package/src/components/uis/PinchZoom/PinchZoom.stories.tsx +0 -266
  133. package/src/components/uis/PinchZoom/PinchZoom.test.tsx +0 -113
  134. package/src/components/uis/PinchZoom/PinchZoom.tsx +0 -424
  135. package/src/components/uis/RadioGroup/RadioButton.tsx +0 -193
  136. package/src/components/uis/RadioGroup/RadioGroup.stories.tsx +0 -188
  137. package/src/components/uis/RadioGroup/RadioGroup.test.tsx +0 -354
  138. package/src/components/uis/RadioGroup/RadioGroup.tsx +0 -109
  139. package/src/components/uis/Rating/Rating.test.tsx +0 -98
  140. package/src/components/uis/Rating/Rating.tsx +0 -200
  141. package/src/components/uis/SegmentedControl/SegmentedControl.stories.tsx +0 -546
  142. package/src/components/uis/SegmentedControl/SegmentedControl.test.tsx +0 -274
  143. package/src/components/uis/SegmentedControl/SegmentedControl.tsx +0 -232
  144. package/src/components/uis/StatusbarBrightness/StatusBarBrightness.test.tsx +0 -41
  145. package/src/components/uis/StatusbarBrightness/StatusBarBrightness.tsx +0 -26
  146. package/src/components/uis/Styled/StyledComponents.tsx +0 -217
  147. package/src/components/uis/SwitchToggle/SwitchToggle.stories.tsx +0 -75
  148. package/src/components/uis/SwitchToggle/SwitchToggle.test.tsx +0 -149
  149. package/src/components/uis/SwitchToggle/SwitchToggle.tsx +0 -309
  150. package/src/components/uis/Typography/Typography.stories.tsx +0 -149
  151. package/src/components/uis/Typography/Typography.test.tsx +0 -58
  152. package/src/components/uis/Typography/Typography.tsx +0 -386
  153. package/src/hooks/index.ts +0 -2
  154. package/src/hooks/useAnimations.ts +0 -71
  155. package/src/hooks/useDebouncedColorScheme.tsx +0 -30
  156. package/src/hooks/useOptimizedStyles.ts +0 -22
  157. package/src/hooks/usePerformance.ts +0 -93
  158. package/src/index.tsx +0 -38
  159. package/src/providers/ThemeProvider.tsx +0 -177
  160. package/src/providers/index.tsx +0 -130
  161. package/src/test/testUtils.tsx +0 -101
  162. package/src/types/common.ts +0 -77
  163. package/src/types/index.ts +0 -1
  164. package/src/types/kstyled.d.ts +0 -6
  165. package/src/utils/accessibility.ts +0 -110
  166. package/src/utils/colors.ts +0 -151
  167. package/src/utils/createCtx.tsx +0 -26
  168. package/src/utils/guards.ts +0 -93
  169. package/src/utils/index.ts +0 -2
  170. package/src/utils/performanceTest.ts +0 -174
  171. package/src/utils/platform.ts +0 -69
  172. package/src/utils/theme.ts +0 -38
  173. package/test/testUtils.d.ts +0 -113
  174. package/test/testUtils.d.ts.map +0 -1
  175. package/test/testUtils.js +0 -65
@@ -0,0 +1,482 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState, } from 'react';
3
+ import { AccessibilityInfo, I18nManager, useWindowDimensions, View, } from 'react-native';
4
+ import { css } from 'kstyled';
5
+ import { useAnimatedReaction, useSharedValue, withTiming, runOnJS, } from 'react-native-reanimated';
6
+ import { useTheme } from '../../../providers/ThemeProvider';
7
+ import { CalendarHeader } from './CalendarHeader';
8
+ import { CalendarPage } from './CalendarPage';
9
+ import { CalendarPager } from './CalendarPager';
10
+ import { CalendarWeekdayRow } from './CalendarWeekdayRow';
11
+ import { DEFAULT_FORMATTERS, getFormattersId, resolveLocale } from './intl';
12
+ import { isSamePalette, resolveCalendarPalette } from './palette';
13
+ import { resolveKeyboardAction, useControllable, useDisabledState, useReduceMotion, useShallowStable, useToday, } from './useCalendarState';
14
+ import { addDays, addPages, getCalendarGrid, localNoon, normalizePageKey, pageFirstDate, pageLastDate, resolveMetrics, resolveWeekStart, startOfWeek, toDateKeyInput, toDayKey, } from './utils';
15
+ const CONTAINER = css `
16
+ align-self: center;
17
+ width: 100%;
18
+ `;
19
+ const TWO_UP_ROW = css `
20
+ flex-direction: row;
21
+ align-items: flex-start;
22
+ gap: 24px;
23
+ `;
24
+ const COLUMN = css `
25
+ flex: 1;
26
+ `;
27
+ const EMPTY_MARKERS = Object.freeze({});
28
+ const EMPTY_STYLES = Object.freeze({});
29
+ const DEFAULT_LABELS = Object.freeze({
30
+ previousMonth: 'Previous month',
31
+ nextMonth: 'Next month',
32
+ previousWeek: 'Previous week',
33
+ nextWeek: 'Next week',
34
+ today: 'Today',
35
+ selected: 'Selected',
36
+ weekNumber: 'Week',
37
+ pageAnnouncement: (pageTitle) => pageTitle,
38
+ });
39
+ /** A Sunday, used only to derive weekday header labels. Never rendered. */
40
+ const WEEKDAY_LABEL_ANCHOR = localNoon(2024, 0, 7);
41
+ const COLLAPSE_DURATION = 220;
42
+ const BADGE_FONT_SCALE_LIMIT = 1.3;
43
+ const SINGLE_DOT_FONT_SCALE_LIMIT = 1.5;
44
+ /**
45
+ * `onKeyDown` is forwarded by react-native-web and simply never fires on native,
46
+ * so one handler covers both platforms without a `.web.tsx` split.
47
+ */
48
+ const KeyboardView = View;
49
+ function buildGeometry(metrics) {
50
+ return Object.freeze({
51
+ row: { height: metrics.rowHeight },
52
+ cell: { height: metrics.rowHeight, paddingTop: metrics.pillOffset },
53
+ pill: {
54
+ width: metrics.numberSize,
55
+ height: metrics.numberSize,
56
+ borderRadius: metrics.numberSize / 2,
57
+ },
58
+ dayText: { fontSize: metrics.dayFontSize },
59
+ badgeText: { fontSize: metrics.badgeFontSize },
60
+ dot: {
61
+ width: metrics.dotSize,
62
+ height: metrics.dotSize,
63
+ borderRadius: metrics.dotSize / 2,
64
+ },
65
+ dotRow: { height: metrics.dotRowHeight },
66
+ weekNumber: { width: metrics.weekNumberWidth },
67
+ weekNumberText: { fontSize: metrics.weekdayFontSize },
68
+ });
69
+ }
70
+ function CalendarContainer(props, ref) {
71
+ const { value, defaultValue, onChange, month, defaultMonth, onMonthChange, mode: modeProp, defaultMode, onModeChange, collapseProgress, locale: localeProp, weekStart: weekStartProp, today: todayProp, fixedWeeks = true, markers = EMPTY_MARKERS, showDots = true, maxDotsPerDay = 3, showWeekNumbers = false, showOutsideDays = true, minDate, maxDate, disabledDates, isDateDisabled, showHeader = true, showNavigationButtons = true, showWeekdayRow = true, paging = 'swipe', monthsToShow = 1, size, maxFontSizeMultiplier = 1.6, colors, styles: stylesProp = EMPTY_STYLES, style, formatters: formattersProp, renderHeader, renderWeekdayLabel, renderDay, onDayLongPress, onDisabledDayPress, labels: labelsPropInput, accessibilityLabel, testID = 'calendar', } = props;
72
+ const { theme, media } = useTheme();
73
+ const { fontScale } = useWindowDimensions();
74
+ const reduceMotion = useReduceMotion();
75
+ const locale = useMemo(() => localeProp ?? resolveLocale(), [localeProp]);
76
+ const weekStart = useMemo(() => weekStartProp ?? resolveWeekStart(locale), [locale, weekStartProp]);
77
+ const todayNoon = useToday(todayProp);
78
+ const todayKey = useMemo(() => toDayKey(todayNoon), [todayNoon]);
79
+ // Value comparison, not identity, for the three props callers almost always
80
+ // write as inline object literals. Without it `chrome` is rebuilt on every
81
+ // parent render and all 42 day cells re-render — the exact regression the
82
+ // memo test suite pins for `colors` but never checked for these.
83
+ const labelsProp = useShallowStable(labelsPropInput);
84
+ const styles = useShallowStable(stylesProp);
85
+ const formattersInput = useShallowStable(formattersProp);
86
+ const formatters = useMemo(() => formattersInput
87
+ ? Object.freeze({ ...DEFAULT_FORMATTERS, ...formattersInput })
88
+ : DEFAULT_FORMATTERS, [formattersInput]);
89
+ const formattersId = getFormattersId(formatters);
90
+ const [mode, setModeState] = useControllable(modeProp, defaultMode ?? 'month');
91
+ // ── selection ───────────────────────────────────────────────────────────────
92
+ const isValueControlled = value !== undefined;
93
+ const [selectedKeyState, setSelectedKeyState] = useState(() => defaultValue == null ? null : toDateKeyInput(defaultValue));
94
+ const selectedKey = isValueControlled
95
+ ? value === null
96
+ ? null
97
+ : toDateKeyInput(value)
98
+ : selectedKeyState;
99
+ // ── paging ──────────────────────────────────────────────────────────────────
100
+ const isMonthControlled = month !== undefined;
101
+ const [pageKeyState, setPageKeyState] = useState(() => normalizePageKey(defaultMonth ?? selectedKeyState ?? todayNoon, defaultMode ?? 'month', weekStartProp ?? resolveWeekStart(localeProp ?? resolveLocale()), monthsToShow));
102
+ const pageInput = month === undefined
103
+ ? pageKeyState
104
+ : typeof month === 'string'
105
+ ? month
106
+ : toDayKey(month);
107
+ const pageKey = useMemo(() => normalizePageKey(pageInput, mode, weekStart, monthsToShow), [mode, monthsToShow, pageInput, weekStart]);
108
+ const [focusedKey, setFocusedKey] = useState(null);
109
+ // ── grids ───────────────────────────────────────────────────────────────────
110
+ const gridFor = useCallback((key) => getCalendarGrid({
111
+ pageKey: key,
112
+ mode,
113
+ weekStart,
114
+ fixedWeeks,
115
+ showWeekNumbers,
116
+ locale,
117
+ formatters,
118
+ formattersId,
119
+ }), [
120
+ fixedWeeks,
121
+ formatters,
122
+ formattersId,
123
+ locale,
124
+ mode,
125
+ showWeekNumbers,
126
+ weekStart,
127
+ ]);
128
+ const previousPageKey = useMemo(() => addPages(pageKey, -1, mode, weekStart, monthsToShow), [mode, monthsToShow, pageKey, weekStart]);
129
+ const nextPageKey = useMemo(() => addPages(pageKey, 1, mode, weekStart, monthsToShow), [mode, monthsToShow, pageKey, weekStart]);
130
+ const currentGrid = useMemo(() => gridFor(pageKey), [gridFor, pageKey]);
131
+ // ── theming and geometry ────────────────────────────────────────────────────
132
+ // Value comparison, not identity: `theme` and an inline `colors` object are both
133
+ // rebuilt on every parent render, and a new palette would re-render every cell.
134
+ const paletteRef = useRef(null);
135
+ const palette = useMemo(() => {
136
+ const next = resolveCalendarPalette(theme, colors);
137
+ const previous = paletteRef.current;
138
+ if (previous && isSamePalette(previous, next)) {
139
+ return previous;
140
+ }
141
+ paletteRef.current = next;
142
+ return next;
143
+ }, [colors, theme]);
144
+ const resolvedSize = size ?? (media.isDesktop || media.isTablet ? 'expanded' : 'regular');
145
+ const metrics = useMemo(() => resolveMetrics(resolvedSize, fontScale, maxFontSizeMultiplier), [fontScale, maxFontSizeMultiplier, resolvedSize]);
146
+ const geometry = useMemo(() => buildGeometry(metrics), [metrics]);
147
+ const labels = useMemo(() => labelsProp
148
+ ? Object.freeze({ ...DEFAULT_LABELS, ...labelsProp })
149
+ : DEFAULT_LABELS, [labelsProp]);
150
+ // ── constraints ─────────────────────────────────────────────────────────────
151
+ const { resolver: isDisabled, version: disabledVersion, minKey, maxKey, } = useDisabledState({ minDate, maxDate, disabledDates, isDateDisabled });
152
+ // ── latest-value refs, so no handler identity depends on a changing callback ─
153
+ const callbacksRef = useRef({
154
+ onChange,
155
+ onMonthChange,
156
+ onModeChange,
157
+ onDayLongPress,
158
+ onDisabledDayPress,
159
+ });
160
+ const stateRef = useRef({
161
+ pageKey,
162
+ mode,
163
+ weekStart,
164
+ monthsToShow,
165
+ isMonthControlled,
166
+ isValueControlled,
167
+ isModeControlled: modeProp !== undefined,
168
+ });
169
+ useEffect(() => {
170
+ callbacksRef.current = {
171
+ onChange,
172
+ onMonthChange,
173
+ onModeChange,
174
+ onDayLongPress,
175
+ onDisabledDayPress,
176
+ };
177
+ }, [
178
+ onChange,
179
+ onDayLongPress,
180
+ onDisabledDayPress,
181
+ onModeChange,
182
+ onMonthChange,
183
+ ]);
184
+ useEffect(() => {
185
+ stateRef.current = {
186
+ pageKey,
187
+ mode,
188
+ weekStart,
189
+ monthsToShow,
190
+ isMonthControlled,
191
+ isValueControlled,
192
+ isModeControlled: modeProp !== undefined,
193
+ };
194
+ }, [
195
+ isMonthControlled,
196
+ isValueControlled,
197
+ mode,
198
+ modeProp,
199
+ monthsToShow,
200
+ pageKey,
201
+ weekStart,
202
+ ]);
203
+ const goToPage = useCallback((nextKey, source) => {
204
+ const current = stateRef.current;
205
+ if (!current.isMonthControlled) {
206
+ setPageKeyState(nextKey);
207
+ }
208
+ const first = pageFirstDate(nextKey, current.mode, current.weekStart);
209
+ callbacksRef.current.onMonthChange?.(new Date(first.getFullYear(), first.getMonth(), first.getDate()), nextKey, source);
210
+ }, []);
211
+ const stepPage = useCallback((delta, source) => {
212
+ const current = stateRef.current;
213
+ goToPage(addPages(current.pageKey, delta, current.mode, current.weekStart, current.monthsToShow), source);
214
+ }, [goToPage]);
215
+ const handleSwipeCommit = useCallback((delta) => stepPage(delta, 'swipe'), [stepPage]);
216
+ const focusKey = useCallback((key, source) => {
217
+ setFocusedKey(key);
218
+ const current = stateRef.current;
219
+ const targetPage = normalizePageKey(key, current.mode, current.weekStart, current.monthsToShow);
220
+ if (targetPage !== current.pageKey) {
221
+ goToPage(targetPage, source);
222
+ }
223
+ }, [goToPage]);
224
+ const selectKey = useCallback((key, source) => {
225
+ const current = stateRef.current;
226
+ if (!current.isValueControlled) {
227
+ setSelectedKeyState(key);
228
+ }
229
+ setFocusedKey(key);
230
+ const date = new Date(+key.slice(0, 4), +key.slice(5, 7) - 1, +key.slice(8, 10));
231
+ callbacksRef.current.onChange?.(date, key, source);
232
+ }, []);
233
+ // ── stable cell callbacks. No inline arrow ever reaches a day cell ───────────
234
+ const handleDayPress = useCallback((key) => selectKey(key, 'press'), [selectKey]);
235
+ const handleDayLongPress = useCallback((key) => {
236
+ callbacksRef.current.onDayLongPress?.(new Date(+key.slice(0, 4), +key.slice(5, 7) - 1, +key.slice(8, 10)), key);
237
+ }, []);
238
+ const handleDisabledDayPress = useCallback((key) => {
239
+ callbacksRef.current.onDisabledDayPress?.(new Date(+key.slice(0, 4), +key.slice(5, 7) - 1, +key.slice(8, 10)), key);
240
+ }, []);
241
+ const chrome = useMemo(() => Object.freeze({
242
+ palette,
243
+ metrics,
244
+ geometry,
245
+ showDots,
246
+ maxDots: fontScale > SINGLE_DOT_FONT_SCALE_LIMIT
247
+ ? 1
248
+ : Math.max(maxDotsPerDay, 0),
249
+ showBadges: fontScale <= BADGE_FONT_SCALE_LIMIT,
250
+ maxFontSizeMultiplier,
251
+ fontScale,
252
+ labels,
253
+ styles,
254
+ renderDay,
255
+ onPress: handleDayPress,
256
+ onLongPress: onDayLongPress ? handleDayLongPress : undefined,
257
+ onDisabledPress: onDisabledDayPress
258
+ ? handleDisabledDayPress
259
+ : undefined,
260
+ }), [
261
+ fontScale,
262
+ geometry,
263
+ handleDayLongPress,
264
+ handleDayPress,
265
+ handleDisabledDayPress,
266
+ labels,
267
+ maxDotsPerDay,
268
+ maxFontSizeMultiplier,
269
+ metrics,
270
+ onDayLongPress,
271
+ onDisabledDayPress,
272
+ palette,
273
+ renderDay,
274
+ showDots,
275
+ styles,
276
+ ]);
277
+ // ── collapse ────────────────────────────────────────────────────────────────
278
+ const internalCollapse = useSharedValue(mode === 'week' ? 1 : 0);
279
+ const collapse = collapseProgress ?? internalCollapse;
280
+ const activeRow = useSharedValue(0);
281
+ const anchorKey = selectedKey &&
282
+ selectedKey >= currentGrid.firstKey &&
283
+ selectedKey <= currentGrid.lastKey
284
+ ? selectedKey
285
+ : todayKey >= currentGrid.firstKey && todayKey <= currentGrid.lastKey
286
+ ? todayKey
287
+ : currentGrid.firstKey;
288
+ const activeRowIndex = useMemo(() => {
289
+ for (let i = 0; i < currentGrid.days.length; i++) {
290
+ if (currentGrid.days[i].key === anchorKey) {
291
+ return (i / 7) | 0;
292
+ }
293
+ }
294
+ return 0;
295
+ }, [anchorKey, currentGrid]);
296
+ useEffect(() => {
297
+ activeRow.value = mode === 'week' ? 0 : activeRowIndex;
298
+ }, [activeRow, activeRowIndex, mode]);
299
+ useEffect(() => {
300
+ if (collapseProgress) {
301
+ return;
302
+ }
303
+ internalCollapse.value = withTiming(mode === 'week' ? 1 : 0, {
304
+ duration: reduceMotion ? 0 : COLLAPSE_DURATION,
305
+ });
306
+ }, [collapseProgress, internalCollapse, mode, reduceMotion]);
307
+ const commitMode = useCallback((nextMode) => {
308
+ if (stateRef.current.mode === nextMode) {
309
+ return;
310
+ }
311
+ setModeState(nextMode);
312
+ callbacksRef.current.onModeChange?.(nextMode);
313
+ }, [setModeState]);
314
+ useAnimatedReaction(() => collapse.value, (progress, previous) => {
315
+ if (previous === null) {
316
+ return;
317
+ }
318
+ if (progress >= 0.999 && previous < 0.999) {
319
+ runOnJS(commitMode)('week');
320
+ }
321
+ else if (progress <= 0.001 && previous > 0.001) {
322
+ runOnJS(commitMode)('month');
323
+ }
324
+ }, [collapse, commitMode]);
325
+ // ── derived chrome values ───────────────────────────────────────────────────
326
+ const weekdayLabels = useMemo(() => {
327
+ const anchor = startOfWeek(WEEKDAY_LABEL_ANCHOR, weekStart);
328
+ return Object.freeze(Array.from({ length: 7 }, (_, index) => formatters.weekdayLabel(addDays(anchor, index), locale)));
329
+ }, [formatters, locale, weekStart]);
330
+ const headerDate = useMemo(() => pageFirstDate(pageKey, mode, weekStart), [mode, pageKey, weekStart]);
331
+ const title = useMemo(() => {
332
+ if (mode === 'week') {
333
+ return formatters.weekTitle(headerDate, addDays(headerDate, 6), locale);
334
+ }
335
+ if (monthsToShow > 1) {
336
+ const secondMonth = pageFirstDate(nextPageKey, mode, weekStart);
337
+ return `${formatters.monthTitle(headerDate, locale)} – ${formatters.monthTitle(addDays(secondMonth, -1), locale)}`;
338
+ }
339
+ return formatters.monthTitle(headerDate, locale);
340
+ }, [
341
+ formatters,
342
+ headerDate,
343
+ locale,
344
+ mode,
345
+ monthsToShow,
346
+ nextPageKey,
347
+ weekStart,
348
+ ]);
349
+ // Compared against each neighbouring page's own month/week range, not against the
350
+ // padded grid, so a min date on the 1st really does disable the previous button.
351
+ const canGoPrevious = minKey === null ||
352
+ toDayKey(pageLastDate(previousPageKey, mode, weekStart, monthsToShow)) >=
353
+ minKey;
354
+ const canGoNext = maxKey === null ||
355
+ toDayKey(pageFirstDate(nextPageKey, mode, weekStart)) <= maxKey;
356
+ const goPrevious = useCallback(() => stepPage(-1, 'button'), [stepPage]);
357
+ const goNext = useCallback(() => stepPage(1, 'button'), [stepPage]);
358
+ const headerContext = useMemo(() => ({
359
+ title,
360
+ date: headerDate,
361
+ mode,
362
+ canGoPrevious,
363
+ canGoNext,
364
+ goPrevious,
365
+ goNext,
366
+ }), [canGoNext, canGoPrevious, goNext, goPrevious, headerDate, mode, title]);
367
+ const announcedTitle = useRef(null);
368
+ useEffect(() => {
369
+ if (announcedTitle.current === null) {
370
+ announcedTitle.current = title;
371
+ return;
372
+ }
373
+ if (announcedTitle.current === title) {
374
+ return;
375
+ }
376
+ announcedTitle.current = title;
377
+ AccessibilityInfo.announceForAccessibility(labels.pageAnnouncement(title));
378
+ }, [labels, title]);
379
+ // ── roving focus target ─────────────────────────────────────────────────────
380
+ const tabbableKey = useMemo(() => {
381
+ const inPage = (key) => key >= currentGrid.firstKey && key <= currentGrid.lastKey;
382
+ if (focusedKey !== null && inPage(focusedKey)) {
383
+ return focusedKey;
384
+ }
385
+ if (selectedKey !== null && inPage(selectedKey)) {
386
+ return selectedKey;
387
+ }
388
+ if (inPage(todayKey)) {
389
+ return todayKey;
390
+ }
391
+ for (const day of currentGrid.days) {
392
+ if (!day.isOutside) {
393
+ return day.key;
394
+ }
395
+ }
396
+ return currentGrid.firstKey;
397
+ }, [currentGrid, focusedKey, selectedKey, todayKey]);
398
+ const handleKeyDown = useCallback((event) => {
399
+ const action = resolveKeyboardAction({
400
+ key: event.key,
401
+ shiftKey: event.shiftKey === true,
402
+ focusedKey: tabbableKey,
403
+ weekStart: stateRef.current.weekStart,
404
+ isRTL: I18nManager.isRTL,
405
+ mode: stateRef.current.mode,
406
+ });
407
+ if (!action) {
408
+ return;
409
+ }
410
+ event.preventDefault?.();
411
+ if (action.type === 'select') {
412
+ selectKey(tabbableKey, 'keyboard');
413
+ return;
414
+ }
415
+ focusKey(action.key, 'keyboard');
416
+ }, [focusKey, selectKey, tabbableKey]);
417
+ // ── imperative API ──────────────────────────────────────────────────────────
418
+ useImperativeHandle(ref, () => ({
419
+ goToMonth: (target) => {
420
+ const current = stateRef.current;
421
+ goToPage(normalizePageKey(target, current.mode, current.weekStart, current.monthsToShow), 'imperative');
422
+ },
423
+ goToToday: () => {
424
+ const current = stateRef.current;
425
+ goToPage(normalizePageKey(todayKey, current.mode, current.weekStart, current.monthsToShow), 'imperative');
426
+ },
427
+ next: () => stepPage(1, 'imperative'),
428
+ previous: () => stepPage(-1, 'imperative'),
429
+ setMode: (nextMode) => commitMode(nextMode),
430
+ focusDay: (key) => focusKey(key, 'imperative'),
431
+ }), [commitMode, focusKey, goToPage, stepPage, todayKey]);
432
+ // ── page rendering ──────────────────────────────────────────────────────────
433
+ const rowCount = mode === 'week' ? 1 : currentGrid.rowCount;
434
+ const collapsible = mode === 'week' || (monthsToShow === 1 && rowCount > 1);
435
+ const renderGrid = useCallback((gridPageKey, gridTestID) => {
436
+ const grid = gridFor(gridPageKey);
437
+ return (_jsx(CalendarPage, { activeRow: activeRow, chrome: chrome, collapse: collapse, collapsible: collapsible, disabledVersion: disabledVersion, grid: grid, isDisabled: isDisabled, markers: markers, selectedKey: selectedKey, showOutsideDays: showOutsideDays, showWeekNumbers: showWeekNumbers, tabbableKey: tabbableKey, testID: gridTestID, todayKey: todayKey }));
438
+ }, [
439
+ activeRow,
440
+ chrome,
441
+ collapse,
442
+ collapsible,
443
+ disabledVersion,
444
+ gridFor,
445
+ isDisabled,
446
+ markers,
447
+ selectedKey,
448
+ showOutsideDays,
449
+ showWeekNumbers,
450
+ tabbableKey,
451
+ todayKey,
452
+ ]);
453
+ const renderSlot = useCallback((slotPageKey) => {
454
+ if (monthsToShow === 1) {
455
+ return renderGrid(slotPageKey, `calendar-page-${slotPageKey}`);
456
+ }
457
+ const monthKeys = [slotPageKey];
458
+ for (let index = 1; index < monthsToShow; index++) {
459
+ monthKeys.push(addPages(slotPageKey, index, mode, weekStart, 1));
460
+ }
461
+ return (_jsx(View, { style: TWO_UP_ROW, children: monthKeys.map((monthKey) => (_jsx(View, { style: COLUMN, children: renderGrid(monthKey, `calendar-page-${monthKey}`) }, monthKey))) }));
462
+ }, [mode, monthsToShow, renderGrid, weekStart]);
463
+ const slots = useMemo(() => {
464
+ if (paging === 'none') {
465
+ return [{ key: pageKey, offset: 0, node: renderSlot(pageKey) }];
466
+ }
467
+ return [
468
+ { key: previousPageKey, offset: -1, node: renderSlot(previousPageKey) },
469
+ { key: pageKey, offset: 0, node: renderSlot(pageKey) },
470
+ { key: nextPageKey, offset: 1, node: renderSlot(nextPageKey) },
471
+ ];
472
+ }, [nextPageKey, pageKey, paging, previousPageKey, renderSlot]);
473
+ const containerStyle = useMemo(() => ({
474
+ backgroundColor: palette.background,
475
+ maxWidth: metrics.cellSize * 7 * 1.6 * monthsToShow,
476
+ }), [metrics.cellSize, monthsToShow, palette.background]);
477
+ const weekdayRow = showWeekdayRow ? (_jsx(View, { style: monthsToShow > 1 ? TWO_UP_ROW : undefined, children: Array.from({ length: monthsToShow }, (_, index) => (_jsx(View, { style: COLUMN, children: _jsx(CalendarWeekdayRow, { maxFontSizeMultiplier: maxFontSizeMultiplier, metrics: metrics, palette: palette, renderWeekdayLabel: renderWeekdayLabel, showWeekNumbers: showWeekNumbers, styles: styles, weekStart: weekStart, weekdayLabels: weekdayLabels }) }, `weekday-row-${index}`))) })) : null;
478
+ return (_jsxs(KeyboardView, { accessibilityLabel: accessibilityLabel ?? title, onKeyDown: handleKeyDown, style: [CONTAINER, containerStyle, styles.container, style], testID: testID, children: [showHeader ? (_jsx(CalendarHeader, { canGoNext: canGoNext, canGoPrevious: canGoPrevious, headerContext: headerContext, labels: labels, maxFontSizeMultiplier: maxFontSizeMultiplier, metrics: metrics, mode: mode, onNext: goNext, onPrevious: goPrevious, palette: palette, renderHeader: renderHeader, showNavigationButtons: showNavigationButtons, styles: styles, title: title })) : null, weekdayRow, _jsx(CalendarPager, { activeRow: activeRow, collapse: collapse, onCommit: handleSwipeCommit, reduceMotion: reduceMotion, rowCount: rowCount, rowHeight: metrics.rowHeight, slots: slots, swipeEnabled: paging === 'swipe', testID: "calendar-pager" })] }));
479
+ }
480
+ export const Calendar = React.memo(forwardRef(CalendarContainer));
481
+ export default Calendar;
482
+ export * from './types';
@@ -0,0 +1,21 @@
1
+ import React, { type ReactElement } from 'react';
2
+ import type { CalendarChrome, CalendarDayModel, CalendarMarker } from './types';
3
+ export type CalendarDayProps = {
4
+ day: CalendarDayModel;
5
+ /** Precomputed by the grid builder. A cell never formats a date itself. */
6
+ dayLabel: string;
7
+ accessibilityLabel: string;
8
+ isSelected: boolean;
9
+ isToday: boolean;
10
+ isDisabled: boolean;
11
+ /** Roving tab index: exactly one cell per page is tabbable. */
12
+ isTabbable: boolean;
13
+ /** Inert spacer for an out of month day when `showOutsideDays` is false. */
14
+ isHidden: boolean;
15
+ marker?: CalendarMarker;
16
+ chrome: CalendarChrome;
17
+ };
18
+ declare function CalendarDayContainer(props: CalendarDayProps): ReactElement;
19
+ export declare const CalendarDay: React.MemoExoticComponent<typeof CalendarDayContainer>;
20
+ export default CalendarDay;
21
+ //# sourceMappingURL=CalendarDay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalendarDay.d.ts","sourceRoot":"","sources":["../../../../src/components/uis/Calendar/CalendarDay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAuB,KAAK,YAAY,EAAC,MAAM,OAAO,CAAC;AAKrE,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,cAAc,EAEf,MAAM,SAAS,CAAC;AAyCjB,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,gBAAgB,CAAC;IACtB,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,+DAA+D;IAC/D,UAAU,EAAE,OAAO,CAAC;IACpB,4EAA4E;IAC5E,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,cAAc,CAAC;CACxB,CAAC;AAoDF,iBAAS,oBAAoB,CAAC,KAAK,EAAE,gBAAgB,GAAG,YAAY,CAsMnE;AAcD,eAAO,MAAM,WAAW,wDAAiD,CAAC;AAE1E,eAAe,WAAW,CAAC"}
@@ -0,0 +1,172 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import React, { useCallback, useMemo } from 'react';
3
+ import { Platform, Pressable, Text, View } from 'react-native';
4
+ import { css } from 'kstyled';
5
+ import { isSameMarker } from './utils';
6
+ const CELL = css `
7
+ flex: 1;
8
+ align-items: center;
9
+ justify-content: flex-start;
10
+ overflow: hidden;
11
+ border-radius: 10px;
12
+ `;
13
+ const PILL = css `
14
+ align-items: center;
15
+ justify-content: center;
16
+ `;
17
+ const DAY_TEXT = css `
18
+ text-align: center;
19
+ font-weight: 500;
20
+ `;
21
+ const DECORATIONS = css `
22
+ position: absolute;
23
+ bottom: 0;
24
+ start: 0;
25
+ end: 0;
26
+ align-items: center;
27
+ justify-content: flex-end;
28
+ `;
29
+ const DOT_ROW = css `
30
+ flex-direction: row;
31
+ align-items: center;
32
+ justify-content: center;
33
+ gap: 2px;
34
+ `;
35
+ const BADGE_TEXT = css `
36
+ text-align: center;
37
+ `;
38
+ function resolveTextColor(args) {
39
+ const { palette, isSelected, isDisabled, isToday, isOutside, weekday, markerTextColor, } = args;
40
+ if (isSelected) {
41
+ return palette.selectedText;
42
+ }
43
+ if (isDisabled) {
44
+ return palette.disabledText;
45
+ }
46
+ if (isOutside) {
47
+ return palette.outsideText;
48
+ }
49
+ if (markerTextColor) {
50
+ return markerTextColor;
51
+ }
52
+ if (isToday) {
53
+ return palette.todayText;
54
+ }
55
+ if (weekday === 0) {
56
+ return palette.sundayText;
57
+ }
58
+ if (weekday === 6) {
59
+ return palette.saturdayText;
60
+ }
61
+ return palette.dayText;
62
+ }
63
+ function CalendarDayContainer(props) {
64
+ const { day, dayLabel, accessibilityLabel, isSelected, isToday, isDisabled, isTabbable, isHidden, marker, chrome, } = props;
65
+ const { palette, metrics, geometry, styles } = chrome;
66
+ const pillStyle = useMemo(() => {
67
+ if (isSelected) {
68
+ return {
69
+ backgroundColor: marker?.selectedColor ?? palette.selectedBackground,
70
+ };
71
+ }
72
+ if (isToday) {
73
+ return { borderWidth: 1.5, borderColor: palette.todayRing };
74
+ }
75
+ return null;
76
+ }, [isSelected, isToday, marker?.selectedColor, palette]);
77
+ const textStyle = useMemo(() => ({
78
+ color: resolveTextColor({
79
+ palette,
80
+ isSelected,
81
+ isDisabled,
82
+ isToday,
83
+ isOutside: day.isOutside,
84
+ weekday: day.weekday,
85
+ markerTextColor: marker?.textColor,
86
+ }),
87
+ opacity: isDisabled ? 0.55 : 1,
88
+ }), [
89
+ day.isOutside,
90
+ day.weekday,
91
+ isDisabled,
92
+ isSelected,
93
+ isToday,
94
+ marker?.textColor,
95
+ palette,
96
+ ]);
97
+ const handlePress = useCallback(() => {
98
+ if (isDisabled) {
99
+ chrome.onDisabledPress?.(day.key);
100
+ return;
101
+ }
102
+ chrome.onPress(day.key);
103
+ }, [chrome, day.key, isDisabled]);
104
+ const handleLongPress = useCallback(() => {
105
+ if (isDisabled) {
106
+ return;
107
+ }
108
+ chrome.onLongPress?.(day.key);
109
+ }, [chrome, day.key, isDisabled]);
110
+ const cellStyle = useCallback(({ pressed }) => pressed && !isDisabled
111
+ ? [
112
+ CELL,
113
+ geometry.cell,
114
+ { backgroundColor: palette.underlay },
115
+ styles.dayCell,
116
+ isSelected ? styles.selectedDayCell : null,
117
+ isToday ? styles.todayDayCell : null,
118
+ ]
119
+ : [
120
+ CELL,
121
+ geometry.cell,
122
+ styles.dayCell,
123
+ isSelected ? styles.selectedDayCell : null,
124
+ isToday ? styles.todayDayCell : null,
125
+ ], [geometry.cell, isDisabled, isSelected, isToday, palette.underlay, styles]);
126
+ if (isHidden) {
127
+ return (_jsx(View, { accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants", style: [CELL, geometry.cell], testID: `calendar-day-${day.key}-spacer` }));
128
+ }
129
+ const dots = chrome.showDots && marker?.dots?.length
130
+ ? marker.dots.slice(0, chrome.maxDots)
131
+ : null;
132
+ const badgeText = chrome.showBadges && marker?.badgeText ? marker.badgeText : null;
133
+ return (_jsx(Pressable, { accessibilityLabel: accessibilityLabel, accessibilityRole: "button", accessibilityState: { disabled: isDisabled, selected: isSelected }, "aria-disabled": isDisabled, "aria-selected": isSelected, onLongPress: chrome.onLongPress ? handleLongPress : undefined, onPress: handlePress, style: cellStyle, tabIndex: isTabbable ? 0 : -1, testID: `calendar-day-${day.key}`, children: chrome.renderDay ? (chrome.renderDay({
134
+ day,
135
+ isSelected,
136
+ isToday,
137
+ isDisabled,
138
+ marker,
139
+ palette,
140
+ cellSize: metrics.cellSize,
141
+ })) : (_jsxs(_Fragment, { children: [_jsx(View, { style: [PILL, geometry.pill, pillStyle], children: _jsx(Text, { adjustsFontSizeToFit: Platform.OS === 'ios', maxFontSizeMultiplier: chrome.maxFontSizeMultiplier, minimumFontScale: 0.8, numberOfLines: 1, style: [
142
+ DAY_TEXT,
143
+ geometry.dayText,
144
+ textStyle,
145
+ styles.dayText,
146
+ day.isOutside ? styles.outsideDayText : null,
147
+ isDisabled ? styles.disabledDayText : null,
148
+ isSelected ? styles.selectedDayText : null,
149
+ isToday ? styles.todayDayText : null,
150
+ ], children: dayLabel }) }), dots || badgeText ? (_jsxs(View, { importantForAccessibility: "no", pointerEvents: "none", style: DECORATIONS, children: [dots ? (_jsx(View, { style: [DOT_ROW, geometry.dotRow, styles.dotRow], children: dots.map((dot) => (_jsx(View, { style: [
151
+ geometry.dot,
152
+ { backgroundColor: dot.color ?? palette.dot },
153
+ styles.dot,
154
+ ] }, dot.key))) })) : null, badgeText ? (_jsx(Text, { maxFontSizeMultiplier: chrome.maxFontSizeMultiplier, numberOfLines: 1, style: [
155
+ BADGE_TEXT,
156
+ geometry.badgeText,
157
+ { color: marker?.badgeColor ?? palette.badgeText },
158
+ styles.badgeText,
159
+ ], children: badgeText })) : null] })) : null] })) }));
160
+ }
161
+ const areDaysEqual = (a, b) => a.day === b.day &&
162
+ a.dayLabel === b.dayLabel &&
163
+ a.isSelected === b.isSelected &&
164
+ a.isToday === b.isToday &&
165
+ a.isDisabled === b.isDisabled &&
166
+ a.isTabbable === b.isTabbable &&
167
+ a.isHidden === b.isHidden &&
168
+ a.chrome === b.chrome &&
169
+ a.accessibilityLabel === b.accessibilityLabel &&
170
+ isSameMarker(a.marker, b.marker);
171
+ export const CalendarDay = React.memo(CalendarDayContainer, areDaysEqual);
172
+ export default CalendarDay;