@astryxdesign/core 0.7.9-canary.2ea8f68 → 0.7.9-canary.45f77d0
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/dist/Calendar/Calendar.d.ts +14 -2
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +63 -74
- package/dist/Calendar/getInitialFocusDate.d.ts +4 -1
- package/dist/Calendar/getInitialFocusDate.d.ts.map +1 -1
- package/dist/Calendar/getInitialFocusDate.js +7 -5
- package/dist/Calendar/hooks/useCalendarDays.d.ts +19 -2
- package/dist/Calendar/hooks/useCalendarDays.d.ts.map +1 -1
- package/dist/Calendar/hooks/useCalendarDays.js +57 -64
- package/dist/Calendar/hooks/useCalendarNavigation.d.ts +28 -3
- package/dist/Calendar/hooks/useCalendarNavigation.d.ts.map +1 -1
- package/dist/Calendar/hooks/useCalendarNavigation.js +33 -22
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +4 -1
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +4 -1
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +4 -1
- package/dist/HoverCard/useHoverCard.d.ts +3 -1
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/Layer/useLayer.d.ts +3 -1
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +64 -4
- package/dist/NumberInput/NumberInput.d.ts +4 -2
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +244 -11
- package/dist/Popover/usePopover.d.ts +1 -0
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +14 -81
- package/dist/Spinner/index.d.ts +1 -1
- package/dist/Spinner/index.d.ts.map +1 -1
- package/dist/Spinner/spinnerRotor.d.ts +28 -0
- package/dist/Spinner/spinnerRotor.d.ts.map +1 -0
- package/dist/Spinner/spinnerRotor.js +98 -0
- package/dist/Tooltip/useTooltip.d.ts +3 -1
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/i18n/InternationalizationContext.d.ts +6 -0
- package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
- package/dist/i18n/InternationalizationProvider.d.ts +20 -3
- package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
- package/dist/i18n/InternationalizationProvider.js +8 -3
- package/dist/i18n/index.d.ts +2 -0
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +1 -0
- package/dist/i18n/useCalendarSystem.d.ts +19 -0
- package/dist/i18n/useCalendarSystem.d.ts.map +1 -0
- package/dist/i18n/useCalendarSystem.js +61 -0
- package/dist/internal/spinner-rotor.d.ts +16 -0
- package/dist/internal/spinner-rotor.d.ts.map +1 -0
- package/dist/internal/spinner-rotor.js +16 -0
- package/dist/utils/calendarSystem.d.ts +106 -0
- package/dist/utils/calendarSystem.d.ts.map +1 -0
- package/dist/utils/calendarSystem.js +343 -0
- package/dist/utils/plainDate.d.ts +11 -5
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +34 -15
- package/package.json +11 -5
- package/src/Calendar/Calendar.doc.mjs +76 -6
- package/src/Calendar/Calendar.tsx +123 -104
- package/src/Calendar/getInitialFocusDate.ts +22 -8
- package/src/Calendar/hooks/useCalendarDays.ts +89 -63
- package/src/Calendar/hooks/useCalendarNavigation.ts +68 -26
- package/src/DateInput/DateInput.tsx +2 -0
- package/src/DateRangeInput/DateRangeInput.tsx +2 -0
- package/src/DateTimeInput/DateTimeInput.tsx +2 -0
- package/src/HoverCard/useHoverCard.tsx +3 -1
- package/src/Layer/useLayer.tsx +77 -4
- package/src/NumberInput/NumberInput.doc.mjs +1 -1
- package/src/NumberInput/NumberInput.tsx +259 -11
- package/src/Popover/usePopover.tsx +1 -0
- package/src/Spinner/Spinner.tsx +7 -99
- package/src/Spinner/index.ts +1 -5
- package/src/Spinner/spinnerRotor.ts +113 -0
- package/src/Tooltip/useTooltip.tsx +3 -1
- package/src/i18n/InternationalizationContext.ts +6 -0
- package/src/i18n/InternationalizationProvider.doc.mjs +29 -1
- package/src/i18n/InternationalizationProvider.tsx +32 -3
- package/src/i18n/index.ts +2 -0
- package/src/i18n/useCalendarSystem.ts +95 -0
- package/src/internal/spinner-rotor.ts +20 -0
- package/src/utils/calendarSystem.ts +481 -0
- package/src/utils/plainDate.ts +51 -17
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BaseProps } from '../BaseProps.js';
|
|
2
|
+
import { type CalendarSystem } from '../utils/calendarSystem.js';
|
|
2
3
|
export type { ISODateString, DayOfWeek, DayOfWeekName, DateRange, } from '../utils/dateTypes.js';
|
|
3
4
|
import type { ISODateString, DayOfWeek, DayOfWeekName, DateRange } from '../utils/dateTypes.js';
|
|
4
5
|
/** Imperative handle for Calendar handleRef */
|
|
@@ -56,12 +57,14 @@ interface CalendarBaseProps extends Omit<BaseProps<HTMLDivElement>, 'onChange' |
|
|
|
56
57
|
*/
|
|
57
58
|
hasOutsideDays?: boolean;
|
|
58
59
|
/**
|
|
59
|
-
* Show ISO week numbers in a side column.
|
|
60
|
+
* Show ISO 8601 week numbers in a side column. They are ISO 8601 week
|
|
61
|
+
* numbers in every calendar system.
|
|
60
62
|
* Default: false
|
|
61
63
|
*/
|
|
62
64
|
hasWeekNumbers?: boolean;
|
|
63
65
|
/**
|
|
64
|
-
*
|
|
66
|
+
* Give each month only the rows it needs instead of a fixed 6-row grid.
|
|
67
|
+
* The fixed grid keeps the same height from month to month.
|
|
65
68
|
* Default: false (fixed 6 rows for consistent height)
|
|
66
69
|
*/
|
|
67
70
|
hasVariableRowCount?: boolean;
|
|
@@ -71,6 +74,15 @@ interface CalendarBaseProps extends Omit<BaseProps<HTMLDivElement>, 'onChange' |
|
|
|
71
74
|
* Default: 0 (Sunday)
|
|
72
75
|
*/
|
|
73
76
|
weekStartsOn?: DayOfWeek | DayOfWeekName;
|
|
77
|
+
/**
|
|
78
|
+
* The calendar system the grid shows, such as `'persian'` or `'hebrew'`.
|
|
79
|
+
* It sets the months, their labels, and month and year navigation. `value`,
|
|
80
|
+
* `min`, `max`, `focusDate`, and every callback stay Gregorian ISO dates.
|
|
81
|
+
* Default: the `InternationalizationProvider` calendar, else Gregorian.
|
|
82
|
+
* Calendars other than `gregory`, `iso8601`, `buddhist`, `roc`, and
|
|
83
|
+
* `japanese` need `Temporal`; without it the grid shows Gregorian months.
|
|
84
|
+
*/
|
|
85
|
+
calendar?: CalendarSystem;
|
|
74
86
|
}
|
|
75
87
|
interface CalendarSingleProps extends CalendarBaseProps {
|
|
76
88
|
/** Selection mode */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Calendar.d.ts","sourceRoot":"","sources":["../../src/Calendar/Calendar.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"Calendar.d.ts","sourceRoot":"","sources":["../../src/Calendar/Calendar.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AA6B5C,OAAO,EAEL,KAAK,cAAc,EASpB,MAAM,yBAAyB,CAAC;AAoBjC,YAAY,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACb,SAAS,GACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACb,SAAS,EACV,MAAM,oBAAoB,CAAC;AAiB5B,+CAA+C;AAC/C,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,UAAU,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;CAC3C;AAID,UAAU,iBAAkB,SAAQ,IAAI,CACtC,SAAS,CAAC,cAAc,CAAC,EACzB,UAAU,GAAG,cAAc,CAC5B;IACC,kDAAkD;IAClD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,qDAAqD;IACrD,SAAS,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACtC,+CAA+C;IAC/C,cAAc,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAEvB,4CAA4C;IAC5C,GAAG,CAAC,EAAE,aAAa,CAAC;IAEpB,4CAA4C;IAC5C,GAAG,CAAC,EAAE,aAAa,CAAC;IAEpB;;;OAGG;IACH,eAAe,CAAC,EAAE,aAAa,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC;IAEzD;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,aAAa,CAAC;IAE1B,yDAAyD;IACzD,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,aAAa,KAAK,IAAI,CAAC;IAEvD;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;;OAIG;IACH,YAAY,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC;IAEzC;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAID,UAAU,mBAAoB,SAAQ,iBAAiB;IACrD,qBAAqB;IACrB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAEhB,mFAAmF;IACnF,KAAK,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAE7B,0CAA0C;IAC1C,YAAY,CAAC,EAAE,aAAa,CAAC;IAE7B,qCAAqC;IACrC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,IAAI,KAAK,IAAI,CAAC;CAC9D;AAED,UAAU,kBAAmB,SAAQ,iBAAiB;IACpD,qBAAqB;IACrB,IAAI,EAAE,OAAO,CAAC;IAEd,8DAA8D;IAC9D,KAAK,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAEzB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,SAAS,CAAC;IAEzB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,kBAAkB,CAAC;AA4BrE;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,EAAC,GAAG,EAAE,GAAG,KAAK,EAAC,EAAE,aAAa,+BAogBtD;yBApgBe,QAAQ"}
|
|
@@ -22,10 +22,11 @@ import * as stylex from '@stylexjs/stylex';
|
|
|
22
22
|
import { Button } from "../Button/index.js";
|
|
23
23
|
import { Icon } from "../Icon/index.js";
|
|
24
24
|
import { useAnnounce, useGridFocus } from "../hooks/index.js";
|
|
25
|
-
import {
|
|
25
|
+
import { useCalendarConstraints } from "./hooks/index.js";
|
|
26
|
+
import { useCalendarDays } from "./hooks/useCalendarDays.js";
|
|
26
27
|
import { calendarStyles, monthGridStyles, dayCellStyles, dayCellTheme } from "./styles.js";
|
|
27
|
-
import { plainDateFromISO, plainDateToISO, plainDateToDate, plainDateToday,
|
|
28
|
-
import {
|
|
28
|
+
import { plainDateFromISO, plainDateToISO, plainDateToDate, plainDateToday, plainDateAddDays, plainDateDiffDays, plainDateIsAfter, plainDateIsBefore, plainDateIsEqual, plainDateGetWeekNumber, plainDateWeekFieldName, plainDateFormatDayNumber, DATE_FORMAT_WITH_WEEKDAY } from "../utils/plainDate.js";
|
|
29
|
+
import { calendarAddMonths, calendarMonthOf, calendarShiftMonths, calendarShiftYears, calendarYearMonthOf, formatCalendarDate, formatCalendarMonthLabel, isInCalendarMonth } from "../utils/calendarSystem.js";
|
|
29
30
|
import { mergeProps, composeEventHandlers, rtlStyles } from "../utils/index.js";
|
|
30
31
|
import { focusOutlineProps } from "../utils/focusOutline.stylex.js";
|
|
31
32
|
import { interactionOverlayStyles } from "../utils/interactionOverlay.stylex.js";
|
|
@@ -41,13 +42,14 @@ import { computeDayCellState, computeRangeRounding, computePreviewRounding, comp
|
|
|
41
42
|
import { normalizeDayOfWeek } from "../utils/dateTypes.js";
|
|
42
43
|
import { themeProps } from "../utils/themeProps.js";
|
|
43
44
|
import { useLocale } from "../i18n/index.js";
|
|
45
|
+
import { useCalendarSystem } from "../i18n/useCalendarSystem.js";
|
|
44
46
|
import { VisuallyHidden } from "../VisuallyHidden/index.js";
|
|
45
47
|
import { registerEnglishFallback, useComponentTranslator } from "../i18n/useComponentTranslator.js";
|
|
46
48
|
import english from "../i18n/generated-english/Calendar/Calendar.generated.js";
|
|
47
49
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
48
50
|
registerEnglishFallback(english);
|
|
49
51
|
|
|
50
|
-
/** How a month navigation moves the focused day: by its row offset in days, or by whole months or years. */
|
|
52
|
+
/** How a month navigation moves the focused day: by its row offset in days, or by whole calendar months or years. */
|
|
51
53
|
|
|
52
54
|
/** Imperative handle for Calendar handleRef */
|
|
53
55
|
|
|
@@ -55,15 +57,9 @@ registerEnglishFallback(english);
|
|
|
55
57
|
|
|
56
58
|
// ─── Mode-specific Props (discriminated union) ────────────────
|
|
57
59
|
|
|
58
|
-
/** The first day of `month`'s month that `isDisabled` allows, or null. */
|
|
59
60
|
function firstEnabledDayOfMonth(month, isDisabled) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const pd = {
|
|
63
|
-
year: month.year,
|
|
64
|
-
month: month.month,
|
|
65
|
-
day
|
|
66
|
-
};
|
|
61
|
+
for (let offset = 0; offset < month.length; offset += 1) {
|
|
62
|
+
const pd = plainDateAddDays(month.start, offset);
|
|
67
63
|
if (!isDisabled(pd)) {
|
|
68
64
|
return pd;
|
|
69
65
|
}
|
|
@@ -71,6 +67,11 @@ function firstEnabledDayOfMonth(month, isDisabled) {
|
|
|
71
67
|
return null;
|
|
72
68
|
}
|
|
73
69
|
|
|
70
|
+
/** A day's full label, such as "Friday, Aban 8, 1405 AP", in the calendar. */
|
|
71
|
+
function formatDateLabel(date, calendar, locale) {
|
|
72
|
+
return formatCalendarDate(calendar, date, DATE_FORMAT_WITH_WEEKDAY, locale);
|
|
73
|
+
}
|
|
74
|
+
|
|
74
75
|
// =============================================================================
|
|
75
76
|
// Main Component
|
|
76
77
|
// =============================================================================
|
|
@@ -107,12 +108,14 @@ export function Calendar({
|
|
|
107
108
|
hasWeekNumbers = false,
|
|
108
109
|
hasVariableRowCount = false,
|
|
109
110
|
weekStartsOn: weekStartsOnProp = 0,
|
|
111
|
+
calendar: calendarProp,
|
|
110
112
|
xstyle,
|
|
111
113
|
className,
|
|
112
114
|
style,
|
|
113
115
|
onKeyDown,
|
|
114
116
|
...rest
|
|
115
117
|
} = props;
|
|
118
|
+
const calendar = useCalendarSystem(calendarProp, 'Calendar');
|
|
116
119
|
|
|
117
120
|
// Normalize `weekStartsOn` (number or three-letter day name) to a numeric
|
|
118
121
|
// DayOfWeek so all downstream date math keeps working with an index.
|
|
@@ -150,7 +153,8 @@ export function Calendar({
|
|
|
150
153
|
min,
|
|
151
154
|
max,
|
|
152
155
|
numberOfMonths,
|
|
153
|
-
today
|
|
156
|
+
today,
|
|
157
|
+
calendar
|
|
154
158
|
}));
|
|
155
159
|
|
|
156
160
|
// Use controlled focusDate if callback is provided, otherwise use internal state
|
|
@@ -168,19 +172,20 @@ export function Calendar({
|
|
|
168
172
|
}
|
|
169
173
|
}), [isControlledFocus, onFocusDateChange]);
|
|
170
174
|
|
|
171
|
-
//
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
+
// A controlled focus date is a new object on each render. Key the memo on
|
|
176
|
+
// its ISO string.
|
|
177
|
+
const focusIso = plainDateToISO(focusDate);
|
|
178
|
+
const baseMonth = useMemo(() => calendarMonthOf(calendar, plainDateFromISO(focusIso)), [calendar, focusIso]);
|
|
175
179
|
|
|
176
180
|
// Generate visible months
|
|
177
181
|
const visibleMonths = useMemo(() => {
|
|
178
182
|
return Array.from({
|
|
179
183
|
length: numberOfMonths
|
|
180
184
|
}, (_, i) => {
|
|
181
|
-
return
|
|
185
|
+
return calendarAddMonths(calendar, baseMonth, i);
|
|
182
186
|
});
|
|
183
|
-
}, [baseMonth, numberOfMonths]);
|
|
187
|
+
}, [calendar, baseMonth, numberOfMonths]);
|
|
188
|
+
const lastVisibleMonth = visibleMonths[visibleMonths.length - 1];
|
|
184
189
|
|
|
185
190
|
// A pending target is claimed by the grid that shows its month, or dropped
|
|
186
191
|
// by the next focus move that is not onto the target day: when a controlled
|
|
@@ -194,7 +199,7 @@ export function Calendar({
|
|
|
194
199
|
return null;
|
|
195
200
|
}
|
|
196
201
|
const target = plainDateFromISO(pendingFocus);
|
|
197
|
-
return visibleMonths.some(
|
|
202
|
+
return visibleMonths.some(month => isInCalendarMonth(target, month)) ? pendingFocus : null;
|
|
198
203
|
}, [pendingFocus, visibleMonths]);
|
|
199
204
|
const handleRootBlur = useCallback(e => {
|
|
200
205
|
// Only the move onto the target day itself keeps the target: an arrow
|
|
@@ -209,7 +214,7 @@ export function Calendar({
|
|
|
209
214
|
// Format month header
|
|
210
215
|
// Each month is its own stand-alone label, so each starts with a capital
|
|
211
216
|
// where the locale capitalizes one (FR1).
|
|
212
|
-
const monthYearLabel = useMemo(() => visibleMonths.map(m =>
|
|
217
|
+
const monthYearLabel = useMemo(() => visibleMonths.map(m => formatCalendarMonthLabel(calendar, m, locale)).join(' – '), [calendar, visibleMonths, locale]);
|
|
213
218
|
|
|
214
219
|
// Announce the newly visible month to screen readers whenever it changes.
|
|
215
220
|
// The visible month label (`<span>`) carries no live semantics, so paging the
|
|
@@ -233,23 +238,10 @@ export function Calendar({
|
|
|
233
238
|
// Determine if prev/next navigation is possible based on min/max
|
|
234
239
|
const minDateForKeys = useMemo(() => min ? plainDateFromISO(min) : null, [min]);
|
|
235
240
|
const maxDateForKeys = useMemo(() => max ? plainDateFromISO(max) : null, [max]);
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
const minDate = plainDateFromISO(min);
|
|
241
|
-
// Can't go back if min is in the current focus month
|
|
242
|
-
return minDate.year < baseMonth.year || minDate.year === baseMonth.year && minDate.month < baseMonth.month;
|
|
243
|
-
}, [min, baseMonth]);
|
|
244
|
-
const canNavigateNext = useMemo(() => {
|
|
245
|
-
if (!max) {
|
|
246
|
-
return true;
|
|
247
|
-
}
|
|
248
|
-
const maxDate = plainDateFromISO(max);
|
|
249
|
-
// Check against the last visible month, not just baseMonth
|
|
250
|
-
const lastVisibleMonth = plainDateAddMonths(baseMonth, numberOfMonths - 1);
|
|
251
|
-
return maxDate.year > lastVisibleMonth.year || maxDate.year === lastVisibleMonth.year && maxDate.month > lastVisibleMonth.month;
|
|
252
|
-
}, [max, baseMonth, numberOfMonths]);
|
|
241
|
+
|
|
242
|
+
// A month button is available while a day past the shown months is in range.
|
|
243
|
+
const canNavigatePrevious = minDateForKeys == null || plainDateIsBefore(minDateForKeys, baseMonth.start);
|
|
244
|
+
const canNavigateNext = maxDateForKeys == null || plainDateIsAfter(maxDateForKeys, lastVisibleMonth.end);
|
|
253
245
|
|
|
254
246
|
// Navigation handlers
|
|
255
247
|
// The same constraint view the grids use, so a key can resolve its target
|
|
@@ -266,16 +258,12 @@ export function Calendar({
|
|
|
266
258
|
rangeAnchor: rootRangeAnchor
|
|
267
259
|
});
|
|
268
260
|
const navigateMonth = useCallback((delta, focusedDate, offset, unit = 'days') => {
|
|
269
|
-
const monthIndex = pd => pd.year * 12 + pd.month;
|
|
270
|
-
const firstShown = monthIndex(baseMonth);
|
|
271
|
-
const lastShown = firstShown + numberOfMonths - 1;
|
|
272
|
-
|
|
273
261
|
// The Previous/Next buttons move the month with no focused day.
|
|
274
262
|
if (!focusedDate) {
|
|
275
263
|
if (delta < 0 && !canNavigatePrevious || delta > 0 && !canNavigateNext) {
|
|
276
264
|
return;
|
|
277
265
|
}
|
|
278
|
-
const newPd =
|
|
266
|
+
const newPd = calendarAddMonths(calendar, baseMonth, delta).start;
|
|
279
267
|
if (onFocusDateChange) {
|
|
280
268
|
onFocusDateChange(plainDateToISO(newPd));
|
|
281
269
|
} else {
|
|
@@ -293,15 +281,15 @@ export function Calendar({
|
|
|
293
281
|
const inRange = pd => !(minDateForKeys && plainDateIsBefore(pd, minDateForKeys)) && !(maxDateForKeys && plainDateIsAfter(pd, maxDateForKeys));
|
|
294
282
|
let targetPd;
|
|
295
283
|
if (unit === 'months' || unit === 'years') {
|
|
296
|
-
// A page or a year step keeps the day of the month and clamps
|
|
297
|
-
// target month's length. A month with no enabled day is no
|
|
298
|
-
// same as for an arrow.
|
|
299
|
-
const candidate =
|
|
284
|
+
// A page or a year step keeps the day of the calendar month and clamps
|
|
285
|
+
// it to the target month's length. A month with no enabled day is no
|
|
286
|
+
// target, the same as for an arrow.
|
|
287
|
+
const candidate = unit === 'years' ? calendarShiftYears(calendar, currentPd, delta) : calendarShiftMonths(calendar, currentPd, delta);
|
|
300
288
|
if (!inRange(candidate)) {
|
|
301
289
|
return;
|
|
302
290
|
}
|
|
303
291
|
if (isRootDateDisabled(candidate)) {
|
|
304
|
-
const firstEnabled = firstEnabledDayOfMonth(candidate, isRootDateDisabled);
|
|
292
|
+
const firstEnabled = firstEnabledDayOfMonth(calendarMonthOf(calendar, candidate), isRootDateDisabled);
|
|
305
293
|
if (firstEnabled == null) {
|
|
306
294
|
return;
|
|
307
295
|
}
|
|
@@ -336,23 +324,19 @@ export function Calendar({
|
|
|
336
324
|
// key's direction, so the target month becomes the first (backwards)
|
|
337
325
|
// or last (forwards) month shown.
|
|
338
326
|
const resolved = targetPd;
|
|
339
|
-
const targetMonth = monthIndex(resolved);
|
|
340
327
|
setPendingFocus(plainDateToISO(resolved));
|
|
341
|
-
|
|
328
|
+
const isBeforeShown = plainDateIsBefore(resolved, baseMonth.start);
|
|
329
|
+
if (!isBeforeShown && !plainDateIsAfter(resolved, lastVisibleMonth.end)) {
|
|
342
330
|
return;
|
|
343
331
|
}
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
month: resolved.month,
|
|
347
|
-
day: 1
|
|
348
|
-
};
|
|
349
|
-
const newPd = targetMonth < firstShown ? targetFirst : plainDateAddMonths(targetFirst, -(numberOfMonths - 1));
|
|
332
|
+
const targetMonth = calendarMonthOf(calendar, resolved);
|
|
333
|
+
const newPd = isBeforeShown ? targetMonth.start : calendarAddMonths(calendar, targetMonth, -(numberOfMonths - 1)).start;
|
|
350
334
|
if (onFocusDateChange) {
|
|
351
335
|
onFocusDateChange(plainDateToISO(newPd));
|
|
352
336
|
} else {
|
|
353
337
|
setInternalFocusDate(newPd);
|
|
354
338
|
}
|
|
355
|
-
}, [baseMonth, canNavigateNext, canNavigatePrevious, isRootDateDisabled, maxDateForKeys, minDateForKeys, numberOfMonths, onFocusDateChange]);
|
|
339
|
+
}, [baseMonth, calendar, canNavigateNext, canNavigatePrevious, isRootDateDisabled, lastVisibleMonth, maxDateForKeys, minDateForKeys, numberOfMonths, onFocusDateChange]);
|
|
356
340
|
|
|
357
341
|
// Escape key handler to cancel range selection
|
|
358
342
|
const handleCalendarKeyDown = useCallback(e => {
|
|
@@ -378,7 +362,7 @@ export function Calendar({
|
|
|
378
362
|
// progress through the same polite live region.
|
|
379
363
|
setRangeSelectionStart(iso);
|
|
380
364
|
announce(t('@astryx.calendar.rangeStartAnnounce', {
|
|
381
|
-
date:
|
|
365
|
+
date: formatDateLabel(date, calendar, locale)
|
|
382
366
|
}));
|
|
383
367
|
} else {
|
|
384
368
|
// Second click - complete the range
|
|
@@ -392,7 +376,7 @@ export function Calendar({
|
|
|
392
376
|
if (plainDateIsEqual(date, startPd) && (minRangeSpan ?? 1) > 1) {
|
|
393
377
|
setRangeSelectionStart(null);
|
|
394
378
|
announce(t('@astryx.calendar.rangeClearedAnnounce', {
|
|
395
|
-
date:
|
|
379
|
+
date: formatDateLabel(date, calendar, locale)
|
|
396
380
|
}));
|
|
397
381
|
return;
|
|
398
382
|
}
|
|
@@ -417,12 +401,12 @@ export function Calendar({
|
|
|
417
401
|
// Completed-range announcement, in chronological order (matches the
|
|
418
402
|
// swapped {start, end} above even for a reverse pick).
|
|
419
403
|
announce(t('@astryx.calendar.rangeCompleteAnnounce', {
|
|
420
|
-
start:
|
|
421
|
-
end:
|
|
404
|
+
start: formatDateLabel(plainDateFromISO(start), calendar, locale),
|
|
405
|
+
end: formatDateLabel(plainDateFromISO(end), calendar, locale)
|
|
422
406
|
}));
|
|
423
407
|
}
|
|
424
408
|
}
|
|
425
|
-
}, [mode, onChange, rangeSelectionStart, minRangeSpan, announce, t, locale]);
|
|
409
|
+
}, [mode, onChange, rangeSelectionStart, minRangeSpan, announce, t, locale, calendar]);
|
|
426
410
|
return /*#__PURE__*/_jsxs("div", {
|
|
427
411
|
ref: ref,
|
|
428
412
|
...rest,
|
|
@@ -482,6 +466,7 @@ export function Calendar({
|
|
|
482
466
|
...stylex.props(calendarStyles.monthsContainer),
|
|
483
467
|
children: visibleMonths.map(month => /*#__PURE__*/_jsx(MonthGrid, {
|
|
484
468
|
month: month,
|
|
469
|
+
calendar: calendar,
|
|
485
470
|
value: effectiveValue,
|
|
486
471
|
mode: mode,
|
|
487
472
|
rangeSelectionStart: rangeSelectionStart,
|
|
@@ -502,7 +487,7 @@ export function Calendar({
|
|
|
502
487
|
onNavigateNext: (focusedDate, offset, unit) => navigateMonth(1, focusedDate, offset, unit),
|
|
503
488
|
pendingFocus: claimablePendingFocus,
|
|
504
489
|
onPendingFocusHandled: () => setPendingFocus(null)
|
|
505
|
-
},
|
|
490
|
+
}, plainDateToISO(month.start)))
|
|
506
491
|
})]
|
|
507
492
|
});
|
|
508
493
|
}
|
|
@@ -514,6 +499,7 @@ Calendar.displayName = 'Calendar';
|
|
|
514
499
|
|
|
515
500
|
function MonthGrid({
|
|
516
501
|
month,
|
|
502
|
+
calendar,
|
|
517
503
|
value,
|
|
518
504
|
mode,
|
|
519
505
|
rangeSelectionStart,
|
|
@@ -536,15 +522,16 @@ function MonthGrid({
|
|
|
536
522
|
onPendingFocusHandled
|
|
537
523
|
}) {
|
|
538
524
|
const locale = useLocale();
|
|
539
|
-
const year = month.year;
|
|
540
525
|
|
|
541
526
|
// Use hooks for days generation and constraints
|
|
527
|
+
const yearMonth = useMemo(() => calendarYearMonthOf(calendar, month), [calendar, month]);
|
|
542
528
|
const {
|
|
543
529
|
days,
|
|
544
530
|
weeks
|
|
545
531
|
} = useCalendarDays({
|
|
546
|
-
year,
|
|
547
|
-
month:
|
|
532
|
+
year: yearMonth.year,
|
|
533
|
+
month: yearMonth.month,
|
|
534
|
+
calendar,
|
|
548
535
|
weekStartsOn,
|
|
549
536
|
hasVariableRowCount
|
|
550
537
|
});
|
|
@@ -576,12 +563,12 @@ function MonthGrid({
|
|
|
576
563
|
// enabled) > today (if visible and enabled) > first enabled in-month day.
|
|
577
564
|
const seedTabbableIso = useMemo(() => {
|
|
578
565
|
if (selectedDateForTabindex) {
|
|
579
|
-
const isSelectedInMonth = selectedDateForTabindex
|
|
566
|
+
const isSelectedInMonth = isInCalendarMonth(selectedDateForTabindex, month);
|
|
580
567
|
if (isSelectedInMonth && !isDateDisabled(selectedDateForTabindex)) {
|
|
581
568
|
return plainDateToISO(selectedDateForTabindex);
|
|
582
569
|
}
|
|
583
570
|
}
|
|
584
|
-
const isTodayInMonth = today
|
|
571
|
+
const isTodayInMonth = isInCalendarMonth(today, month);
|
|
585
572
|
if (isTodayInMonth && !isDateDisabled(today)) {
|
|
586
573
|
return plainDateToISO(today);
|
|
587
574
|
}
|
|
@@ -591,7 +578,7 @@ function MonthGrid({
|
|
|
591
578
|
}
|
|
592
579
|
}
|
|
593
580
|
return null;
|
|
594
|
-
}, [days, today,
|
|
581
|
+
}, [days, today, month, isDateDisabled, selectedDateForTabindex]);
|
|
595
582
|
|
|
596
583
|
// Helper to get the focused date from the currently focused element.
|
|
597
584
|
// Reads the machine-readable `data-date` (ISO) attribute rather than parsing
|
|
@@ -681,7 +668,7 @@ function MonthGrid({
|
|
|
681
668
|
return;
|
|
682
669
|
}
|
|
683
670
|
const targetPd = plainDateFromISO(pendingFocus);
|
|
684
|
-
if (targetPd
|
|
671
|
+
if (!isInCalendarMonth(targetPd, month)) {
|
|
685
672
|
return;
|
|
686
673
|
}
|
|
687
674
|
const targetIso = plainDateToISO(targetPd);
|
|
@@ -702,7 +689,7 @@ function MonthGrid({
|
|
|
702
689
|
targetButton.focus();
|
|
703
690
|
}
|
|
704
691
|
onPendingFocusHandled?.();
|
|
705
|
-
}, [pendingFocus, gridRef, month
|
|
692
|
+
}, [pendingFocus, gridRef, month, onPendingFocusHandled]);
|
|
706
693
|
|
|
707
694
|
// Parse selection
|
|
708
695
|
let selectedDate = null;
|
|
@@ -741,8 +728,8 @@ function MonthGrid({
|
|
|
741
728
|
|
|
742
729
|
// Month label for announcements
|
|
743
730
|
const monthLabel = useMemo(() => {
|
|
744
|
-
return
|
|
745
|
-
}, [month, locale]);
|
|
731
|
+
return formatCalendarMonthLabel(calendar, month, locale);
|
|
732
|
+
}, [calendar, month, locale]);
|
|
746
733
|
return /*#__PURE__*/_jsx("div", {
|
|
747
734
|
...stylex.props(monthGridStyles.monthGrid),
|
|
748
735
|
children: /*#__PURE__*/_jsxs("div", {
|
|
@@ -820,6 +807,7 @@ function MonthGrid({
|
|
|
820
807
|
neighbors: neighbors,
|
|
821
808
|
isTabbable: day.iso === seedTabbableIso,
|
|
822
809
|
isRangeSelectionInProgress: rangeSelectionStart !== null,
|
|
810
|
+
calendar: calendar,
|
|
823
811
|
onDayClick: onDayClick,
|
|
824
812
|
onDayHover: onDayHover
|
|
825
813
|
}, day.iso);
|
|
@@ -849,6 +837,7 @@ function DayCell({
|
|
|
849
837
|
neighbors,
|
|
850
838
|
isTabbable: isTabbableDay,
|
|
851
839
|
isRangeSelectionInProgress,
|
|
840
|
+
calendar,
|
|
852
841
|
onDayClick,
|
|
853
842
|
onDayHover
|
|
854
843
|
}) {
|
|
@@ -899,7 +888,7 @@ function DayCell({
|
|
|
899
888
|
// params rather than string concatenation. A mid-flight first pick (where
|
|
900
889
|
// rangeStart === rangeEnd) reads as "range start" only; a completed one-day
|
|
901
890
|
// range reads as both start and end.
|
|
902
|
-
const dateLabel =
|
|
891
|
+
const dateLabel = formatDateLabel(date, calendar, locale);
|
|
903
892
|
const dayLabel = state.isSelected ? t('@astryx.calendar.daySelected', {
|
|
904
893
|
date: dateLabel
|
|
905
894
|
}) : state.isRangeStart && state.isRangeEnd ? isRangeSelectionInProgress ? t('@astryx.calendar.dayRangeStart', {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file getInitialFocusDate.ts
|
|
3
|
-
* @input PlainDate utilities, min/max bounds, today
|
|
3
|
+
* @input PlainDate and calendar-system utilities, min/max bounds, today
|
|
4
4
|
* @output Exports getInitialFocusDate — the month Calendar opens on
|
|
5
5
|
* @position Calendar-specific helper; used by Calendar.tsx
|
|
6
6
|
*
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import type { ISODateString, DateRange } from '../utils/dateTypes.js';
|
|
12
12
|
import { type PlainDate } from '../utils/plainDate.js';
|
|
13
|
+
import { type CalendarSystem } from '../utils/calendarSystem.js';
|
|
13
14
|
export interface InitialFocusDateOptions {
|
|
14
15
|
/** Controlled visible month, if the consumer supplied one. */
|
|
15
16
|
focusDate?: ISODateString;
|
|
@@ -23,6 +24,8 @@ export interface InitialFocusDateOptions {
|
|
|
23
24
|
numberOfMonths: number;
|
|
24
25
|
/** Today, injected so the caller keeps a single memoized source of "now". */
|
|
25
26
|
today: PlainDate;
|
|
27
|
+
/** The calendar system whose months the panes show. Default: `gregory`. */
|
|
28
|
+
calendar?: CalendarSystem;
|
|
26
29
|
}
|
|
27
30
|
/**
|
|
28
31
|
* Picks the date whose month the calendar opens on.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getInitialFocusDate.d.ts","sourceRoot":"","sources":["../../src/Calendar/getInitialFocusDate.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAC,aAAa,EAAE,SAAS,EAAC,MAAM,oBAAoB,CAAC;AACjE,OAAO,EACL,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"getInitialFocusDate.d.ts","sourceRoot":"","sources":["../../src/Calendar/getInitialFocusDate.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAC,aAAa,EAAE,SAAS,EAAC,MAAM,oBAAoB,CAAC;AACjE,OAAO,EACL,KAAK,SAAS,EAIf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,KAAK,cAAc,EAGpB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,uBAAuB;IACtC,8DAA8D;IAC9D,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,yEAAyE;IACzE,KAAK,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAClC,gCAAgC;IAChC,GAAG,CAAC,EAAE,aAAa,CAAC;IACpB,8BAA8B;IAC9B,GAAG,CAAC,EAAE,aAAa,CAAC;IACpB,0DAA0D;IAC1D,cAAc,EAAE,MAAM,CAAC;IACvB,6EAA6E;IAC7E,KAAK,EAAE,SAAS,CAAC;IACjB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,uBAAuB,GAC/B,SAAS,CA2CX"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @file getInitialFocusDate.ts
|
|
5
|
-
* @input PlainDate utilities, min/max bounds, today
|
|
5
|
+
* @input PlainDate and calendar-system utilities, min/max bounds, today
|
|
6
6
|
* @output Exports getInitialFocusDate — the month Calendar opens on
|
|
7
7
|
* @position Calendar-specific helper; used by Calendar.tsx
|
|
8
8
|
*
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
* - /packages/core/src/Calendar/Calendar.tsx (the only caller)
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import { plainDateFromISO,
|
|
14
|
+
import { plainDateFromISO, plainDateIsBefore, plainDateIsAfter } from "../utils/plainDate.js";
|
|
15
|
+
import { calendarAddMonths, calendarMonthOf } from "../utils/calendarSystem.js";
|
|
15
16
|
/**
|
|
16
17
|
* Picks the date whose month the calendar opens on.
|
|
17
18
|
*
|
|
@@ -37,7 +38,8 @@ export function getInitialFocusDate(options) {
|
|
|
37
38
|
min,
|
|
38
39
|
max,
|
|
39
40
|
numberOfMonths,
|
|
40
|
-
today
|
|
41
|
+
today,
|
|
42
|
+
calendar = 'gregory'
|
|
41
43
|
} = options;
|
|
42
44
|
if (focusDate) {
|
|
43
45
|
return plainDateFromISO(focusDate);
|
|
@@ -52,8 +54,8 @@ export function getInitialFocusDate(options) {
|
|
|
52
54
|
}
|
|
53
55
|
if (maxDate && plainDateIsAfter(today, maxDate)) {
|
|
54
56
|
const lastPaneOffset = Math.max(0, numberOfMonths - 1);
|
|
55
|
-
const shifted =
|
|
56
|
-
if (minDate && plainDateIsBefore(shifted,
|
|
57
|
+
const shifted = calendarAddMonths(calendar, calendarMonthOf(calendar, maxDate), -lastPaneOffset).start;
|
|
58
|
+
if (minDate && plainDateIsBefore(shifted, calendarMonthOf(calendar, minDate).start)) {
|
|
57
59
|
return minDate;
|
|
58
60
|
}
|
|
59
61
|
return shifted;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { DayOfWeek, ISODateString } from '../../utils/dateTypes.js';
|
|
2
2
|
import { type PlainDate } from '../../utils/plainDate.js';
|
|
3
|
+
import { type CalendarSystem } from '../../utils/calendarSystem.js';
|
|
3
4
|
/**
|
|
4
5
|
* Represents a single day in the calendar grid.
|
|
5
6
|
*/
|
|
@@ -17,14 +18,27 @@ export interface CalendarDay {
|
|
|
17
18
|
* Configuration for calendar days generation
|
|
18
19
|
*/
|
|
19
20
|
export interface UseCalendarDaysOptions {
|
|
20
|
-
/** The year to generate days for */
|
|
21
|
+
/** The year to generate days for, in `calendar`'s numbering */
|
|
21
22
|
year: number;
|
|
22
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* The month's position in its year (1-based). In the Gregorian calendar,
|
|
25
|
+
* 1 is January and 12 is December. In other calendars it is numbered as
|
|
26
|
+
* `Temporal.PlainDate` numbers it: 1 through 13 in a Hebrew leap year.
|
|
27
|
+
*/
|
|
23
28
|
month: number;
|
|
24
29
|
/** First day of week (0=Sunday through 6=Saturday) */
|
|
25
30
|
weekStartsOn?: DayOfWeek;
|
|
26
31
|
/** Use variable rows per month vs. fixed 6-row grid */
|
|
27
32
|
hasVariableRowCount?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* The calendar system that numbers `year`, `month`, and each `dayNumber`.
|
|
35
|
+
* Each day keeps its Gregorian `date` and `iso`. The hook never reads the
|
|
36
|
+
* InternationalizationProvider calendar. Calendars other than gregory,
|
|
37
|
+
* iso8601, buddhist, roc, and japanese need Temporal; without it, the hook
|
|
38
|
+
* reads Gregorian numbers and warns once in development.
|
|
39
|
+
* @default 'gregory'
|
|
40
|
+
*/
|
|
41
|
+
calendar?: CalendarSystem;
|
|
28
42
|
}
|
|
29
43
|
/**
|
|
30
44
|
* Return type for useCalendarDays hook
|
|
@@ -53,6 +67,9 @@ export interface UseCalendarDaysReturn {
|
|
|
53
67
|
* weekStartsOn: 0, // Sunday
|
|
54
68
|
* });
|
|
55
69
|
* // days[i].date is a PlainDate { year, month (1-based), day }
|
|
70
|
+
*
|
|
71
|
+
* // Aban 1405 in the Persian calendar; dates stay Gregorian
|
|
72
|
+
* useCalendarDays({year: 1405, month: 8, calendar: 'persian'});
|
|
56
73
|
* ```
|
|
57
74
|
*/
|
|
58
75
|
export declare function useCalendarDays(options: UseCalendarDaysOptions): UseCalendarDaysReturn;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCalendarDays.d.ts","sourceRoot":"","sources":["../../../src/Calendar/hooks/useCalendarDays.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useCalendarDays.d.ts","sourceRoot":"","sources":["../../../src/Calendar/hooks/useCalendarDays.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAC,SAAS,EAAE,aAAa,EAAC,MAAM,uBAAuB,CAAC;AACpE,OAAO,EACL,KAAK,SAAS,EAIf,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,KAAK,cAAc,EAGpB,MAAM,4BAA4B,CAAC;AAGpC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,iCAAiC;IACjC,IAAI,EAAE,SAAS,CAAC;IAChB,mCAAmC;IACnC,GAAG,EAAE,aAAa,CAAC;IACnB,oDAAoD;IACpD,SAAS,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,uDAAuD;IACvD,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,mDAAmD;IACnD,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB,8BAA8B;IAC9B,KAAK,EAAE,WAAW,EAAE,EAAE,CAAC;IACvB,yCAAyC;IACzC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,sBAAsB,GAC9B,qBAAqB,CAuBvB"}
|