@kanso-labs/react-native-kanso-ui 0.6.0 → 0.7.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.
@@ -0,0 +1,1182 @@
1
+ import { useTheme } from "../theme/scope.js";
2
+ import { composeStyles } from "../theme/styles.js";
3
+ import { hitSlop, usePressFeedback } from "../press/index.js";
4
+ import { useTypeRole } from "../typography/roles.js";
5
+ import { withOpacity } from "../theme/color.js";
6
+ import { ArrowDropDownGlyph, CheckGlyph, ChevronEndGlyph } from "../glyphs/index.js";
7
+ import { messagesFor } from "../i18n/index.js";
8
+ import { IconButton } from "../components/icon-button/index.js";
9
+ import { useFocusOnPlaced, useReturnFocus } from "../overlay/panel.js";
10
+ import { styles, stylesOf } from "./styles.js";
11
+ import { c } from "react/compiler-runtime";
12
+ import { FlatList, I18nManager, Pressable, Text, View } from "react-native";
13
+ import Animated, { Easing, useAnimatedStyle, useReducedMotion, useSharedValue, withTiming } from "react-native-reanimated";
14
+ import { useLayoutEffect, useRef, useState } from "react";
15
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
16
+ import { DateFormatter, endOfMonth, isSameDay, isSameYear, isToday, startOfMonth, startOfWeek, toCalendarDate, today } from "@internationalized/date";
17
+ //#region src/calendar/index.tsx
18
+ const LISTED_YEARS = 201;
19
+ const ROWS_ABOVE_SHOWN = 3;
20
+ /**
21
+ * What a calendar draws inside its container. With `showMonthYearMenus` the
22
+ * header is the date pickers page's docked one, the month and the year as
23
+ * menu buttons, and while either is open its list takes the grid's place.
24
+ */
25
+ function CalendarFrame(t0) {
26
+ const $ = c(14);
27
+ const { firstDayOfWeek, locale, showMonthYearMenus, state } = t0;
28
+ let t1;
29
+ if ($[0] !== firstDayOfWeek || $[1] !== locale || $[2] !== state) {
30
+ t1 = /* @__PURE__ */ jsx(MonthGrid, {
31
+ firstDayOfWeek,
32
+ locale,
33
+ state
34
+ });
35
+ $[0] = firstDayOfWeek;
36
+ $[1] = locale;
37
+ $[2] = state;
38
+ $[3] = t1;
39
+ } else t1 = $[3];
40
+ const grid = t1;
41
+ if (showMonthYearMenus) {
42
+ let t2;
43
+ if ($[4] !== grid || $[5] !== locale || $[6] !== state) {
44
+ t2 = /* @__PURE__ */ jsx(CalendarMenus, {
45
+ locale,
46
+ state,
47
+ children: grid
48
+ });
49
+ $[4] = grid;
50
+ $[5] = locale;
51
+ $[6] = state;
52
+ $[7] = t2;
53
+ } else t2 = $[7];
54
+ return t2;
55
+ }
56
+ let t2;
57
+ if ($[8] !== locale || $[9] !== state) {
58
+ t2 = /* @__PURE__ */ jsx(CalendarHeader, {
59
+ locale,
60
+ state
61
+ });
62
+ $[8] = locale;
63
+ $[9] = state;
64
+ $[10] = t2;
65
+ } else t2 = $[10];
66
+ let t3;
67
+ if ($[11] !== grid || $[12] !== t2) {
68
+ t3 = /* @__PURE__ */ jsxs(Fragment$1, { children: [t2, grid] });
69
+ $[11] = grid;
70
+ $[12] = t2;
71
+ $[13] = t3;
72
+ } else t3 = $[13];
73
+ return t3;
74
+ }
75
+ /** The two chevrons with the month and year between them. */
76
+ function CalendarHeader(t0) {
77
+ const $ = c(19);
78
+ const { locale, state } = t0;
79
+ const own = stylesOf(useTheme());
80
+ const role = useTypeRole("labelLarge");
81
+ const T0 = View;
82
+ const t1 = own.header;
83
+ let t2;
84
+ if ($[0] !== locale || $[1] !== state) {
85
+ t2 = /* @__PURE__ */ jsx(Chevron, {
86
+ direction: "previous",
87
+ locale,
88
+ state
89
+ });
90
+ $[0] = locale;
91
+ $[1] = state;
92
+ $[2] = t2;
93
+ } else t2 = $[2];
94
+ const T1 = Text;
95
+ const t3 = "polite";
96
+ const t4 = "heading";
97
+ const t5 = composeStyles(role, own.heading);
98
+ let t6;
99
+ if ($[3] !== locale || $[4] !== state) {
100
+ t6 = visibleMonthOf(state, locale);
101
+ $[3] = locale;
102
+ $[4] = state;
103
+ $[5] = t6;
104
+ } else t6 = $[5];
105
+ let t7;
106
+ if ($[6] !== T1 || $[7] !== t5 || $[8] !== t6) {
107
+ t7 = /* @__PURE__ */ jsx(T1, {
108
+ "aria-live": t3,
109
+ role: t4,
110
+ style: t5,
111
+ children: t6
112
+ });
113
+ $[6] = T1;
114
+ $[7] = t5;
115
+ $[8] = t6;
116
+ $[9] = t7;
117
+ } else t7 = $[9];
118
+ let t8;
119
+ if ($[10] !== locale || $[11] !== state) {
120
+ t8 = /* @__PURE__ */ jsx(Chevron, {
121
+ direction: "next",
122
+ locale,
123
+ state
124
+ });
125
+ $[10] = locale;
126
+ $[11] = state;
127
+ $[12] = t8;
128
+ } else t8 = $[12];
129
+ let t9;
130
+ if ($[13] !== T0 || $[14] !== own || $[15] !== t2 || $[16] !== t7 || $[17] !== t8) {
131
+ t9 = /* @__PURE__ */ jsxs(T0, {
132
+ style: t1,
133
+ children: [
134
+ t2,
135
+ t7,
136
+ t8
137
+ ]
138
+ });
139
+ $[13] = T0;
140
+ $[14] = own;
141
+ $[15] = t2;
142
+ $[16] = t7;
143
+ $[17] = t8;
144
+ $[18] = t9;
145
+ } else t9 = $[18];
146
+ return t9;
147
+ }
148
+ /**
149
+ * The docked header: the month's menu button between the chevrons that step
150
+ * it, and the year's after them. A press opens the button's list in the
151
+ * grid's place, where the page draws it, rather than in a menu over it; a
152
+ * calendar inside a picker is already in one. While a list is open the
153
+ * chevrons give way to the room they took and the other button is disabled,
154
+ * and choosing an entry, or pressing the one already checked, closes the
155
+ * list and sends the screen reader back to its button.
156
+ *
157
+ * The month list names the months in full where the button names the month
158
+ * short, as the page does. The year list runs a century either side of the
159
+ * year shown, and `minValue` and `maxValue` cut it short; a month with no day
160
+ * inside them is disabled.
161
+ */
162
+ function CalendarMenus(t0) {
163
+ const $ = c(55);
164
+ const { children, locale, state } = t0;
165
+ const t1 = useTheme();
166
+ let t2;
167
+ if ($[0] !== t1) {
168
+ t2 = stylesOf(t1);
169
+ $[0] = t1;
170
+ $[1] = t2;
171
+ } else t2 = $[1];
172
+ const own = t2;
173
+ let t3;
174
+ if ($[2] !== locale) {
175
+ t3 = messagesFor(locale);
176
+ $[2] = locale;
177
+ $[3] = t3;
178
+ } else t3 = $[3];
179
+ const words = t3.calendar;
180
+ const [open, setOpen] = useState(null);
181
+ const monthButton = useRef(null);
182
+ const yearButton = useRef(null);
183
+ const shownMonth = state.focusedDate.month - 1;
184
+ useReturnFocus(open === "month", false, monthButton);
185
+ useReturnFocus(open === "year", false, yearButton);
186
+ const t4 = own.header;
187
+ const t5 = own.headerGroup;
188
+ let t6;
189
+ if ($[4] !== locale || $[5] !== open || $[6] !== own.chevronRoom || $[7] !== state) {
190
+ t6 = open === null ? /* @__PURE__ */ jsx(Chevron, {
191
+ direction: "previous",
192
+ locale,
193
+ state
194
+ }) : /* @__PURE__ */ jsx(View, { style: own.chevronRoom });
195
+ $[4] = locale;
196
+ $[5] = open;
197
+ $[6] = own.chevronRoom;
198
+ $[7] = state;
199
+ $[8] = t6;
200
+ } else t6 = $[8];
201
+ const t7 = open === "month";
202
+ const t8 = state.isDisabled || open === "year";
203
+ let t9;
204
+ if ($[9] !== locale || $[10] !== shownMonth || $[11] !== state) {
205
+ t9 = monthsOf(state, locale, "short")[shownMonth]?.formatted;
206
+ $[9] = locale;
207
+ $[10] = shownMonth;
208
+ $[11] = state;
209
+ $[12] = t9;
210
+ } else t9 = $[12];
211
+ const t10 = words.month;
212
+ let t11;
213
+ if ($[13] === Symbol.for("react.memo_cache_sentinel")) {
214
+ t11 = toggleThen(setOpen, "month");
215
+ $[13] = t11;
216
+ } else t11 = $[13];
217
+ let t12;
218
+ if ($[14] !== t7 || $[15] !== t8 || $[16] !== t9 || $[17] !== words.month) {
219
+ t12 = /* @__PURE__ */ jsx(MenuButton, {
220
+ buttonRef: monthButton,
221
+ expanded: t7,
222
+ isDisabled: t8,
223
+ label: t9,
224
+ name: t10,
225
+ onPress: t11
226
+ });
227
+ $[14] = t7;
228
+ $[15] = t8;
229
+ $[16] = t9;
230
+ $[17] = words.month;
231
+ $[18] = t12;
232
+ } else t12 = $[18];
233
+ let t13;
234
+ if ($[19] !== locale || $[20] !== open || $[21] !== own.chevronRoom || $[22] !== state) {
235
+ t13 = open === null ? /* @__PURE__ */ jsx(Chevron, {
236
+ direction: "next",
237
+ locale,
238
+ state
239
+ }) : /* @__PURE__ */ jsx(View, { style: own.chevronRoom });
240
+ $[19] = locale;
241
+ $[20] = open;
242
+ $[21] = own.chevronRoom;
243
+ $[22] = state;
244
+ $[23] = t13;
245
+ } else t13 = $[23];
246
+ let t14;
247
+ if ($[24] !== own.headerGroup || $[25] !== t12 || $[26] !== t13 || $[27] !== t6) {
248
+ t14 = /* @__PURE__ */ jsxs(View, {
249
+ style: t5,
250
+ children: [
251
+ t6,
252
+ t12,
253
+ t13
254
+ ]
255
+ });
256
+ $[24] = own.headerGroup;
257
+ $[25] = t12;
258
+ $[26] = t13;
259
+ $[27] = t6;
260
+ $[28] = t14;
261
+ } else t14 = $[28];
262
+ const t15 = open === "year";
263
+ const t16 = state.isDisabled || open === "month";
264
+ let t17;
265
+ if ($[29] !== locale || $[30] !== state) {
266
+ t17 = yearOf(state, locale);
267
+ $[29] = locale;
268
+ $[30] = state;
269
+ $[31] = t17;
270
+ } else t17 = $[31];
271
+ const t18 = words.year;
272
+ let t19;
273
+ if ($[32] === Symbol.for("react.memo_cache_sentinel")) {
274
+ t19 = toggleThen(setOpen, "year");
275
+ $[32] = t19;
276
+ } else t19 = $[32];
277
+ let t20;
278
+ if ($[33] !== t15 || $[34] !== t16 || $[35] !== t17 || $[36] !== words.year) {
279
+ t20 = /* @__PURE__ */ jsx(MenuButton, {
280
+ buttonRef: yearButton,
281
+ expanded: t15,
282
+ isDisabled: t16,
283
+ label: t17,
284
+ name: t18,
285
+ onPress: t19
286
+ });
287
+ $[33] = t15;
288
+ $[34] = t16;
289
+ $[35] = t17;
290
+ $[36] = words.year;
291
+ $[37] = t20;
292
+ } else t20 = $[37];
293
+ let t21;
294
+ if ($[38] !== own.header || $[39] !== t14 || $[40] !== t20) {
295
+ t21 = /* @__PURE__ */ jsxs(View, {
296
+ style: t4,
297
+ children: [t14, t20]
298
+ });
299
+ $[38] = own.header;
300
+ $[39] = t14;
301
+ $[40] = t20;
302
+ $[41] = t21;
303
+ } else t21 = $[41];
304
+ const t22 = open === null ? children : null;
305
+ let t23;
306
+ if ($[42] !== locale || $[43] !== open || $[44] !== state) {
307
+ t23 = open === "month" ? /* @__PURE__ */ jsx(MonthList, {
308
+ locale,
309
+ setOpen,
310
+ state
311
+ }) : null;
312
+ $[42] = locale;
313
+ $[43] = open;
314
+ $[44] = state;
315
+ $[45] = t23;
316
+ } else t23 = $[45];
317
+ let t24;
318
+ if ($[46] !== locale || $[47] !== open || $[48] !== state) {
319
+ t24 = open === "year" ? /* @__PURE__ */ jsx(YearList, {
320
+ locale,
321
+ setOpen,
322
+ state
323
+ }) : null;
324
+ $[46] = locale;
325
+ $[47] = open;
326
+ $[48] = state;
327
+ $[49] = t24;
328
+ } else t24 = $[49];
329
+ let t25;
330
+ if ($[50] !== t21 || $[51] !== t22 || $[52] !== t23 || $[53] !== t24) {
331
+ t25 = /* @__PURE__ */ jsxs(Fragment$1, { children: [
332
+ t21,
333
+ t22,
334
+ t23,
335
+ t24
336
+ ] });
337
+ $[50] = t21;
338
+ $[51] = t22;
339
+ $[52] = t23;
340
+ $[53] = t24;
341
+ $[54] = t25;
342
+ } else t25 = $[54];
343
+ return t25;
344
+ }
345
+ /**
346
+ * A chevron that moves the month, the icon buttons page's standard 40dp
347
+ * button. Disabled where the month it would move to is outside `minValue`
348
+ * and `maxValue`, or the whole calendar is disabled.
349
+ */
350
+ function Chevron(t0) {
351
+ const $ = c(20);
352
+ const { direction, locale, state } = t0;
353
+ const t1 = useTheme();
354
+ let t2;
355
+ if ($[0] !== t1) {
356
+ t2 = stylesOf(t1);
357
+ $[0] = t1;
358
+ $[1] = t2;
359
+ } else t2 = $[1];
360
+ const own = t2;
361
+ const previous = direction === "previous";
362
+ let t3;
363
+ if ($[2] !== previous || $[3] !== state) {
364
+ t3 = previous ? state.isPreviousVisibleRangeInvalid() : state.isNextVisibleRangeInvalid();
365
+ $[2] = previous;
366
+ $[3] = state;
367
+ $[4] = t3;
368
+ } else t3 = $[4];
369
+ const outside = t3;
370
+ let t4;
371
+ if ($[5] !== locale) {
372
+ t4 = messagesFor(locale);
373
+ $[5] = locale;
374
+ $[6] = t4;
375
+ } else t4 = $[6];
376
+ const t5 = t4.calendar[direction];
377
+ const t6 = state.isDisabled || outside;
378
+ let t7;
379
+ if ($[7] !== direction || $[8] !== state) {
380
+ t7 = pageThen(state, direction);
381
+ $[7] = direction;
382
+ $[8] = state;
383
+ $[9] = t7;
384
+ } else t7 = $[9];
385
+ let t8;
386
+ if ($[10] !== previous) {
387
+ t8 = previous ? previousGlyphStyle() : void 0;
388
+ $[10] = previous;
389
+ $[11] = t8;
390
+ } else t8 = $[11];
391
+ let t9;
392
+ if ($[12] !== t8) {
393
+ t9 = /* @__PURE__ */ jsx(ChevronEndGlyph, { style: t8 });
394
+ $[12] = t8;
395
+ $[13] = t9;
396
+ } else t9 = $[13];
397
+ let t10;
398
+ if ($[14] !== own.chevron || $[15] !== t5 || $[16] !== t6 || $[17] !== t7 || $[18] !== t9) {
399
+ t10 = /* @__PURE__ */ jsx(IconButton, {
400
+ "aria-label": t5,
401
+ isDisabled: t6,
402
+ onPress: t7,
403
+ style: own.chevron,
404
+ children: t9
405
+ });
406
+ $[14] = own.chevron;
407
+ $[15] = t5;
408
+ $[16] = t6;
409
+ $[17] = t7;
410
+ $[18] = t9;
411
+ $[19] = t10;
412
+ } else t10 = $[19];
413
+ return t10;
414
+ }
415
+ function chooseThen(state, setOpen, shown) {
416
+ return (entry) => {
417
+ if (entry.id !== shown) state.setFocusedDate(entry.date);
418
+ setOpen(null);
419
+ };
420
+ }
421
+ /**
422
+ * One date: the page's 40dp circle in its 48dp square, which `hitSlop` makes
423
+ * the press target. Its name is the date in full, with today, the selection
424
+ * and the first or last date the bounds allow said as web says them, and it
425
+ * reports itself disabled where it cannot be picked.
426
+ */
427
+ function DateCell(t0) {
428
+ const $ = c(29);
429
+ const { date, locale, state } = t0;
430
+ const theme = useTheme();
431
+ const { colors, sizing } = theme;
432
+ const own = stylesOf(theme);
433
+ const role = useTypeRole("bodyLarge");
434
+ let t1;
435
+ if ($[0] !== date || $[1] !== state) {
436
+ t1 = state.isCellDisabled(date);
437
+ $[0] = date;
438
+ $[1] = state;
439
+ $[2] = t1;
440
+ } else t1 = $[2];
441
+ const isDisabled = t1;
442
+ let t2;
443
+ if ($[3] !== date || $[4] !== state) {
444
+ t2 = state.isCellUnavailable(date);
445
+ $[3] = date;
446
+ $[4] = state;
447
+ $[5] = t2;
448
+ } else t2 = $[5];
449
+ const isUnavailable = t2;
450
+ const selectable = !isDisabled && !isUnavailable;
451
+ const isSelected = selectable && state.isSelected(date);
452
+ const isCurrent = isToday(date, state.timeZone);
453
+ const feedback = usePressFeedback({
454
+ color: isSelected ? colors.onPrimary : colors.onSurface,
455
+ corners: own.date,
456
+ disabled: !selectable
457
+ });
458
+ const T0 = Pressable;
459
+ const t3 = dateLabelOf(date, state, locale, isCurrent, isSelected);
460
+ let t4;
461
+ if ($[6] !== sizing.controlSm) {
462
+ t4 = hitSlop(sizing.controlSm, sizing.controlSm);
463
+ $[6] = sizing.controlSm;
464
+ $[7] = t4;
465
+ } else t4 = $[7];
466
+ let t5;
467
+ if ($[8] !== date || $[9] !== state) {
468
+ t5 = selectThen(state, date);
469
+ $[8] = date;
470
+ $[9] = state;
471
+ $[10] = t5;
472
+ } else t5 = $[10];
473
+ const t6 = "button";
474
+ const t7 = feedback.handlers;
475
+ const t8 = !selectable;
476
+ const t9 = composeStyles(own.date, isCurrent ? own.dateToday : void 0, isSelected ? own.dateSelected : void 0, feedback.ring);
477
+ const t10 = feedback.layer;
478
+ const T1 = Text;
479
+ const t11 = composeStyles(role, own.dateText, isCurrent ? own.dateTextToday : void 0, isSelected ? own.dateTextSelected : void 0, isUnavailable ? own.dateTextUnavailable : void 0, isDisabled ? own.dateTextDisabled : void 0);
480
+ let t12;
481
+ if ($[11] !== date || $[12] !== locale || $[13] !== state) {
482
+ t12 = dayOf(date, state, locale);
483
+ $[11] = date;
484
+ $[12] = locale;
485
+ $[13] = state;
486
+ $[14] = t12;
487
+ } else t12 = $[14];
488
+ let t13;
489
+ if ($[15] !== T1 || $[16] !== t11 || $[17] !== t12) {
490
+ t13 = /* @__PURE__ */ jsx(T1, {
491
+ style: t11,
492
+ children: t12
493
+ });
494
+ $[15] = T1;
495
+ $[16] = t11;
496
+ $[17] = t12;
497
+ $[18] = t13;
498
+ } else t13 = $[18];
499
+ let t14;
500
+ if ($[19] !== T0 || $[20] !== feedback.handlers || $[21] !== feedback.layer || $[22] !== t13 || $[23] !== t3 || $[24] !== t4 || $[25] !== t5 || $[26] !== t8 || $[27] !== t9) {
501
+ t14 = /* @__PURE__ */ jsxs(T0, {
502
+ "aria-label": t3,
503
+ hitSlop: t4,
504
+ onPress: t5,
505
+ role: t6,
506
+ ...t7,
507
+ disabled: t8,
508
+ style: t9,
509
+ children: [t10, t13]
510
+ });
511
+ $[19] = T0;
512
+ $[20] = feedback.handlers;
513
+ $[21] = feedback.layer;
514
+ $[22] = t13;
515
+ $[23] = t3;
516
+ $[24] = t4;
517
+ $[25] = t5;
518
+ $[26] = t8;
519
+ $[27] = t9;
520
+ $[28] = t14;
521
+ } else t14 = $[28];
522
+ return t14;
523
+ }
524
+ function dateLabelOf(date, state, locale, isCurrent, isSelected) {
525
+ const words = messagesFor(locale).calendar;
526
+ const full = new DateFormatter(locale, {
527
+ day: "numeric",
528
+ era: eraOf(date),
529
+ month: "long",
530
+ timeZone: state.timeZone,
531
+ weekday: "long",
532
+ year: "numeric"
533
+ }).format(date.toDate(state.timeZone));
534
+ const said = isCurrent ? (isSelected ? words.todayDateSelected : words.todayDate).replace("{date}", full) : isSelected ? words.dateSelected.replace("{date}", full) : full;
535
+ if (state.minValue != null && isSameDay(date, state.minValue)) return `${said}, ${words.minimumDate}`;
536
+ if (state.maxValue != null && isSameDay(date, state.maxValue)) return `${said}, ${words.maximumDate}`;
537
+ return said;
538
+ }
539
+ function dayOf(date, state, locale) {
540
+ return new DateFormatter(locale, {
541
+ calendar: date.calendar.identifier,
542
+ day: "numeric",
543
+ timeZone: state.timeZone
544
+ }).formatToParts(date.toDate(state.timeZone)).find((part) => part.type === "day")?.value ?? String(date.day);
545
+ }
546
+ function eraOf(date) {
547
+ return date.calendar.identifier === "gregory" && date.era === "BC" ? "short" : void 0;
548
+ }
549
+ function layoutOf(height) {
550
+ return (_data, index) => ({
551
+ index,
552
+ length: height,
553
+ offset: height * index
554
+ });
555
+ }
556
+ function listKeyOf(entry) {
557
+ return String(entry.id);
558
+ }
559
+ /**
560
+ * The month or the year as the page's menu button, opening its list. Named
561
+ * by what it shows and then by what it is, "Sep month", which keeps the
562
+ * visible text the start of the name.
563
+ */
564
+ function MenuButton(t0) {
565
+ const $ = c(27);
566
+ const { buttonRef, expanded, isDisabled, label, name, onPress } = t0;
567
+ const theme = useTheme();
568
+ const { colors, sizing, stateLayerOpacity } = theme;
569
+ const own = stylesOf(theme);
570
+ const role = useTypeRole("labelLarge");
571
+ const feedback = usePressFeedback({
572
+ color: colors.onSurfaceVariant,
573
+ corners: own.menuButton,
574
+ disabled: isDisabled
575
+ });
576
+ const T0 = Pressable;
577
+ const t1 = `${label ?? ""} ${name}`;
578
+ let t2;
579
+ if ($[0] !== sizing.controlSm) {
580
+ t2 = hitSlop(sizing.controlSm);
581
+ $[0] = sizing.controlSm;
582
+ $[1] = t2;
583
+ } else t2 = $[1];
584
+ const t3 = "button";
585
+ const t4 = feedback.handlers;
586
+ const t5 = composeStyles(own.menuButton, feedback.ring);
587
+ const t6 = feedback.layer;
588
+ const T1 = Text;
589
+ const t7 = composeStyles(role, own.menuButtonText, isDisabled ? own.dateTextDisabled : void 0);
590
+ let t8;
591
+ if ($[2] !== T1 || $[3] !== label || $[4] !== t7) {
592
+ t8 = /* @__PURE__ */ jsx(T1, {
593
+ style: t7,
594
+ children: label
595
+ });
596
+ $[2] = T1;
597
+ $[3] = label;
598
+ $[4] = t7;
599
+ $[5] = t8;
600
+ } else t8 = $[5];
601
+ let t9;
602
+ if ($[6] !== colors.onSurface || $[7] !== colors.onSurfaceVariant || $[8] !== isDisabled || $[9] !== stateLayerOpacity) {
603
+ t9 = isDisabled ? withOpacity(colors.onSurface, stateLayerOpacity.disabledContent) : colors.onSurfaceVariant;
604
+ $[6] = colors.onSurface;
605
+ $[7] = colors.onSurfaceVariant;
606
+ $[8] = isDisabled;
607
+ $[9] = stateLayerOpacity;
608
+ $[10] = t9;
609
+ } else t9 = $[10];
610
+ const t10 = expanded ? own.arrowExpanded : void 0;
611
+ let t11;
612
+ if ($[11] !== t10 || $[12] !== t9) {
613
+ t11 = /* @__PURE__ */ jsx(ArrowDropDownGlyph, {
614
+ color: t9,
615
+ size: 18,
616
+ style: t10
617
+ });
618
+ $[11] = t10;
619
+ $[12] = t9;
620
+ $[13] = t11;
621
+ } else t11 = $[13];
622
+ let t12;
623
+ if ($[14] !== T0 || $[15] !== buttonRef || $[16] !== expanded || $[17] !== feedback.handlers || $[18] !== feedback.layer || $[19] !== isDisabled || $[20] !== onPress || $[21] !== t1 || $[22] !== t11 || $[23] !== t2 || $[24] !== t5 || $[25] !== t8) {
624
+ t12 = /* @__PURE__ */ jsxs(T0, {
625
+ "aria-expanded": expanded,
626
+ "aria-label": t1,
627
+ hitSlop: t2,
628
+ onPress,
629
+ ref: buttonRef,
630
+ role: t3,
631
+ ...t4,
632
+ disabled: isDisabled,
633
+ style: t5,
634
+ children: [
635
+ t6,
636
+ t8,
637
+ t11
638
+ ]
639
+ });
640
+ $[14] = T0;
641
+ $[15] = buttonRef;
642
+ $[16] = expanded;
643
+ $[17] = feedback.handlers;
644
+ $[18] = feedback.layer;
645
+ $[19] = isDisabled;
646
+ $[20] = onPress;
647
+ $[21] = t1;
648
+ $[22] = t11;
649
+ $[23] = t2;
650
+ $[24] = t5;
651
+ $[25] = t8;
652
+ $[26] = t12;
653
+ } else t12 = $[26];
654
+ return t12;
655
+ }
656
+ /**
657
+ * An open month or year list, in the grid's place: a list of radio rows, the
658
+ * entry shown checked, opening scrolled so that entry sits in the middle with
659
+ * the entries either side of it in view. The screen reader is sent to it as
660
+ * it opens.
661
+ */
662
+ function MenuList(t0) {
663
+ const $ = c(15);
664
+ const { disabled, entries, name, onChoose, shown } = t0;
665
+ const theme = useTheme();
666
+ let t1;
667
+ if ($[0] !== theme) {
668
+ t1 = stylesOf(theme);
669
+ $[0] = theme;
670
+ $[1] = t1;
671
+ } else t1 = $[1];
672
+ const own = t1;
673
+ const [checked, setChecked] = useState(null);
674
+ useFocusOnPlaced(true, checked);
675
+ let t2;
676
+ if ($[2] !== theme.sizing.controlMd) {
677
+ t2 = layoutOf(theme.sizing.controlMd);
678
+ $[2] = theme.sizing.controlMd;
679
+ $[3] = t2;
680
+ } else t2 = $[3];
681
+ const t3 = Math.max(0, Math.min(shown - ROWS_ABOVE_SHOWN, entries.length - 7));
682
+ let t4;
683
+ if ($[4] !== disabled || $[5] !== onChoose || $[6] !== shown) {
684
+ t4 = rowOf({
685
+ disabled,
686
+ onChoose,
687
+ setChecked,
688
+ shown
689
+ });
690
+ $[4] = disabled;
691
+ $[5] = onChoose;
692
+ $[6] = shown;
693
+ $[7] = t4;
694
+ } else t4 = $[7];
695
+ let t5;
696
+ if ($[8] !== entries || $[9] !== name || $[10] !== own.list || $[11] !== t2 || $[12] !== t3 || $[13] !== t4) {
697
+ t5 = /* @__PURE__ */ jsx(FlatList, {
698
+ "aria-label": name,
699
+ data: entries,
700
+ getItemLayout: t2,
701
+ initialScrollIndex: t3,
702
+ keyExtractor: listKeyOf,
703
+ renderItem: t4,
704
+ role: "radiogroup",
705
+ style: own.list
706
+ });
707
+ $[8] = entries;
708
+ $[9] = name;
709
+ $[10] = own.list;
710
+ $[11] = t2;
711
+ $[12] = t3;
712
+ $[13] = t4;
713
+ $[14] = t5;
714
+ } else t5 = $[14];
715
+ return t5;
716
+ }
717
+ /**
718
+ * The weekday row and the month's weeks, held at six weeks of room so the
719
+ * calendar keeps its height from month to month. The weeks slide in from the
720
+ * side the new month comes from.
721
+ */
722
+ function MonthGrid(t0) {
723
+ const $ = c(16);
724
+ const { firstDayOfWeek, locale, state } = t0;
725
+ const theme = useTheme();
726
+ const own = stylesOf(theme);
727
+ const role = useTypeRole("bodyLarge");
728
+ const start = state.visibleRange.start;
729
+ const slide = useMonthSlide(start, theme);
730
+ const rowStyle = composeStyles(styles.row, own.rowHeight);
731
+ const T0 = View;
732
+ const t1 = own.grid;
733
+ const T1 = View;
734
+ const t2 = true;
735
+ const t3 = weekdaysOf(state, locale, firstDayOfWeek).map((weekday) => /* @__PURE__ */ jsx(View, {
736
+ style: styles.column,
737
+ children: /* @__PURE__ */ jsx(Text, {
738
+ style: composeStyles(role, own.weekday),
739
+ children: weekday.label
740
+ })
741
+ }, weekday.key));
742
+ let t4;
743
+ if ($[0] !== T1 || $[1] !== rowStyle || $[2] !== t3) {
744
+ t4 = /* @__PURE__ */ jsx(T1, {
745
+ "aria-hidden": t2,
746
+ style: rowStyle,
747
+ children: t3
748
+ });
749
+ $[0] = T1;
750
+ $[1] = rowStyle;
751
+ $[2] = t3;
752
+ $[3] = t4;
753
+ } else t4 = $[3];
754
+ let t5;
755
+ if ($[4] !== locale || $[5] !== rowStyle || $[6] !== state) {
756
+ t5 = weeksOf(state).map((week) => /* @__PURE__ */ jsx(View, {
757
+ style: rowStyle,
758
+ children: week.days.map((day) => /* @__PURE__ */ jsx(View, {
759
+ style: styles.column,
760
+ children: day.date === null ? null : /* @__PURE__ */ jsx(DateCell, {
761
+ date: day.date,
762
+ locale,
763
+ state
764
+ })
765
+ }, day.key))
766
+ }, week.key));
767
+ $[4] = locale;
768
+ $[5] = rowStyle;
769
+ $[6] = state;
770
+ $[7] = t5;
771
+ } else t5 = $[7];
772
+ let t6;
773
+ if ($[8] !== slide || $[9] !== t5) {
774
+ t6 = /* @__PURE__ */ jsx(Animated.View, {
775
+ style: slide,
776
+ children: t5
777
+ });
778
+ $[8] = slide;
779
+ $[9] = t5;
780
+ $[10] = t6;
781
+ } else t6 = $[10];
782
+ let t7;
783
+ if ($[11] !== T0 || $[12] !== own || $[13] !== t4 || $[14] !== t6) {
784
+ t7 = /* @__PURE__ */ jsxs(T0, {
785
+ style: t1,
786
+ children: [t4, t6]
787
+ });
788
+ $[11] = T0;
789
+ $[12] = own;
790
+ $[13] = t4;
791
+ $[14] = t6;
792
+ $[15] = t7;
793
+ } else t7 = $[15];
794
+ return t7;
795
+ }
796
+ /** The open month list: the months of the year shown, named in full. */
797
+ function MonthList(t0) {
798
+ const $ = c(19);
799
+ const { locale, setOpen, state } = t0;
800
+ let T0;
801
+ let months;
802
+ let shown;
803
+ let t1;
804
+ if ($[0] !== locale || $[1] !== state) {
805
+ months = monthsOf(state, locale, "long");
806
+ shown = state.focusedDate.month - 1;
807
+ T0 = MenuList;
808
+ t1 = outsideBounds(state, months);
809
+ $[0] = locale;
810
+ $[1] = state;
811
+ $[2] = T0;
812
+ $[3] = months;
813
+ $[4] = shown;
814
+ $[5] = t1;
815
+ } else {
816
+ T0 = $[2];
817
+ months = $[3];
818
+ shown = $[4];
819
+ t1 = $[5];
820
+ }
821
+ let t2;
822
+ if ($[6] !== locale) {
823
+ t2 = messagesFor(locale);
824
+ $[6] = locale;
825
+ $[7] = t2;
826
+ } else t2 = $[7];
827
+ const t3 = t2.calendar.month;
828
+ let t4;
829
+ if ($[8] !== setOpen || $[9] !== shown || $[10] !== state) {
830
+ t4 = chooseThen(state, setOpen, shown);
831
+ $[8] = setOpen;
832
+ $[9] = shown;
833
+ $[10] = state;
834
+ $[11] = t4;
835
+ } else t4 = $[11];
836
+ let t5;
837
+ if ($[12] !== T0 || $[13] !== months || $[14] !== shown || $[15] !== t1 || $[16] !== t2.calendar.month || $[17] !== t4) {
838
+ t5 = /* @__PURE__ */ jsx(T0, {
839
+ disabled: t1,
840
+ entries: months,
841
+ name: t3,
842
+ onChoose: t4,
843
+ shown
844
+ });
845
+ $[12] = T0;
846
+ $[13] = months;
847
+ $[14] = shown;
848
+ $[15] = t1;
849
+ $[16] = t2.calendar.month;
850
+ $[17] = t4;
851
+ $[18] = t5;
852
+ } else t5 = $[18];
853
+ return t5;
854
+ }
855
+ function monthsOf(state, locale, format) {
856
+ const { focusedDate, timeZone } = state;
857
+ const formatter = new DateFormatter(locale, {
858
+ calendar: focusedDate.calendar.identifier,
859
+ month: format,
860
+ timeZone
861
+ });
862
+ return Array.from({ length: focusedDate.calendar.getMonthsInYear(focusedDate) }, (_unused, index) => {
863
+ const date = focusedDate.set({ month: index + 1 });
864
+ const shown = date.calendar.getFormattableMonth?.(date) ?? date;
865
+ return {
866
+ date,
867
+ formatted: formatter.format(shown.toDate(timeZone)),
868
+ id: index
869
+ };
870
+ });
871
+ }
872
+ function outsideBounds(state, months) {
873
+ const { maxValue, minValue } = state;
874
+ return new Set(months.filter(({ date }) => maxValue != null && startOfMonth(date).compare(maxValue) > 0 || minValue != null && endOfMonth(date).compare(minValue) < 0).map(({ id }) => id));
875
+ }
876
+ function pageThen(state, direction) {
877
+ return () => {
878
+ if (direction === "next") state.focusNextPage();
879
+ else state.focusPreviousPage();
880
+ };
881
+ }
882
+ function previousGlyphStyle() {
883
+ return I18nManager.isRTL ? styles.previousGlyphRightToLeft : styles.previousGlyph;
884
+ }
885
+ /**
886
+ * One row of an open list: the check where the row is the entry shown, the
887
+ * room it takes where it is not, then the month or the year, in body large.
888
+ */
889
+ function Row(t0) {
890
+ const $ = c(13);
891
+ const { entry, isChecked, isDisabled, onChoose, setChecked } = t0;
892
+ const theme = useTheme();
893
+ const own = stylesOf(theme);
894
+ const role = useTypeRole("bodyLarge");
895
+ let t1;
896
+ if ($[0] !== isDisabled || $[1] !== theme.colors.onSurface) {
897
+ t1 = {
898
+ color: theme.colors.onSurface,
899
+ disabled: isDisabled
900
+ };
901
+ $[0] = isDisabled;
902
+ $[1] = theme.colors.onSurface;
903
+ $[2] = t1;
904
+ } else t1 = $[2];
905
+ const feedback = usePressFeedback(t1);
906
+ let t2;
907
+ if ($[3] !== entry || $[4] !== onChoose) {
908
+ t2 = rowPressThen(onChoose, entry);
909
+ $[3] = entry;
910
+ $[4] = onChoose;
911
+ $[5] = t2;
912
+ } else t2 = $[5];
913
+ const t3 = feedback.handlers;
914
+ const t4 = composeStyles(own.listRow, isChecked ? own.listRowSelected : void 0, feedback.ring);
915
+ const t5 = feedback.layer;
916
+ let t6;
917
+ if ($[6] !== isChecked || $[7] !== theme.colors.onSurface) {
918
+ t6 = isChecked ? /* @__PURE__ */ jsx(CheckGlyph, { color: theme.colors.onSurface }) : null;
919
+ $[6] = isChecked;
920
+ $[7] = theme.colors.onSurface;
921
+ $[8] = t6;
922
+ } else t6 = $[8];
923
+ const T0 = Text;
924
+ const t7 = composeStyles(role, own.listText, isDisabled ? own.listTextDisabled : void 0);
925
+ let t8;
926
+ if ($[9] !== T0 || $[10] !== entry.formatted || $[11] !== t7) {
927
+ t8 = /* @__PURE__ */ jsx(T0, {
928
+ style: t7,
929
+ children: entry.formatted
930
+ });
931
+ $[9] = T0;
932
+ $[10] = entry.formatted;
933
+ $[11] = t7;
934
+ $[12] = t8;
935
+ } else t8 = $[12];
936
+ return /* @__PURE__ */ jsxs(Pressable, {
937
+ "aria-checked": isChecked,
938
+ onPress: t2,
939
+ ref: isChecked ? setChecked : void 0,
940
+ role: "radio",
941
+ ...t3,
942
+ disabled: isDisabled,
943
+ style: t4,
944
+ children: [
945
+ t5,
946
+ /* @__PURE__ */ jsx(View, {
947
+ style: own.listCheck,
948
+ children: t6
949
+ }),
950
+ t8
951
+ ]
952
+ });
953
+ }
954
+ function rowOf({ disabled, onChoose, setChecked, shown }) {
955
+ return ({ item }) => /* @__PURE__ */ jsx(Row, {
956
+ entry: item,
957
+ isChecked: item.id === shown,
958
+ isDisabled: disabled.has(item.id),
959
+ onChoose,
960
+ setChecked
961
+ });
962
+ }
963
+ function rowPressThen(onChoose, entry) {
964
+ return () => {
965
+ onChoose(entry);
966
+ };
967
+ }
968
+ function selectThen(state, date) {
969
+ return () => {
970
+ state.selectDate(date);
971
+ state.setFocusedDate(date);
972
+ };
973
+ }
974
+ function toggleThen(setOpen, list) {
975
+ return () => {
976
+ setOpen((open) => open === list ? null : list);
977
+ };
978
+ }
979
+ /**
980
+ * Slides the weeks in from the side the new month comes from as the month
981
+ * moves, 30dp over the medium duration on the emphasised decelerating curve,
982
+ * fading in as they come: Material Design's shared axis transition for an
983
+ * incoming page. The side follows the writing direction, so a later month
984
+ * arrives from the end. Under reduced motion the month changes at once.
985
+ */
986
+ function useMonthSlide(start, t0) {
987
+ const $ = c(7);
988
+ const { motion } = t0;
989
+ const reduceMotion = useReducedMotion();
990
+ const offset = useSharedValue(0);
991
+ const opacity = useSharedValue(1);
992
+ const shown = useRef(start);
993
+ let t1;
994
+ let t2;
995
+ if ($[0] !== motion || $[1] !== offset || $[2] !== opacity || $[3] !== reduceMotion || $[4] !== start) {
996
+ t1 = () => {
997
+ const travel = start.compare(shown.current);
998
+ shown.current = start;
999
+ if (travel === 0 || reduceMotion) return;
1000
+ const timing = {
1001
+ duration: motion.durationMedium2,
1002
+ easing: Easing.bezier(...motion.easingEmphasizedDecelerate)
1003
+ };
1004
+ const side = (travel > 0 ? 1 : -1) * (I18nManager.isRTL ? -1 : 1);
1005
+ offset.set(side * 30);
1006
+ offset.set(withTiming(0, timing));
1007
+ opacity.set(0);
1008
+ opacity.set(withTiming(1, timing));
1009
+ };
1010
+ t2 = [
1011
+ motion,
1012
+ offset,
1013
+ opacity,
1014
+ reduceMotion,
1015
+ start
1016
+ ];
1017
+ $[0] = motion;
1018
+ $[1] = offset;
1019
+ $[2] = opacity;
1020
+ $[3] = reduceMotion;
1021
+ $[4] = start;
1022
+ $[5] = t1;
1023
+ $[6] = t2;
1024
+ } else {
1025
+ t1 = $[5];
1026
+ t2 = $[6];
1027
+ }
1028
+ useLayoutEffect(t1, t2);
1029
+ return useAnimatedStyle(() => {
1030
+ "worklet";
1031
+ return {
1032
+ opacity: opacity.get(),
1033
+ transform: [{ translateX: offset.get() }]
1034
+ };
1035
+ });
1036
+ }
1037
+ function visibleMonthOf(state, locale) {
1038
+ const { start } = state.visibleRange;
1039
+ return new DateFormatter(locale, {
1040
+ calendar: start.calendar.identifier,
1041
+ era: eraOf(start),
1042
+ month: "long",
1043
+ timeZone: state.timeZone,
1044
+ year: "numeric"
1045
+ }).format(start.toDate(state.timeZone));
1046
+ }
1047
+ function weekdaysOf(state, locale, firstDayOfWeek) {
1048
+ const first = startOfWeek(today(state.timeZone), locale, firstDayOfWeek);
1049
+ const formatter = new DateFormatter(locale, {
1050
+ timeZone: state.timeZone,
1051
+ weekday: "narrow"
1052
+ });
1053
+ return Array.from({ length: 7 }, (_unused, index) => {
1054
+ const date = first.add({ days: index });
1055
+ return {
1056
+ key: date.toString(),
1057
+ label: formatter.format(date.toDate(state.timeZone))
1058
+ };
1059
+ });
1060
+ }
1061
+ function weeksOf(state) {
1062
+ const { start } = state.visibleRange;
1063
+ return Array.from({ length: state.getWeeksInMonth() }, (_unused, week) => {
1064
+ const key = start.add({ weeks: week }).toString();
1065
+ return {
1066
+ days: state.getDatesInWeek(week).map((date, day) => ({
1067
+ date,
1068
+ key: date?.toString() ?? `${key}+${String(day)}`
1069
+ })),
1070
+ key
1071
+ };
1072
+ });
1073
+ }
1074
+ /** The open year list: the years either side of the one shown. */
1075
+ function YearList(t0) {
1076
+ const $ = c(18);
1077
+ const { locale, setOpen, state } = t0;
1078
+ let T0;
1079
+ let shown;
1080
+ let t1;
1081
+ let t2;
1082
+ let t3;
1083
+ let t4;
1084
+ if ($[0] !== locale || $[1] !== setOpen || $[2] !== state) {
1085
+ const { entries, shown: t5 } = yearsOf(state, locale);
1086
+ shown = t5;
1087
+ T0 = MenuList;
1088
+ t1 = NONE;
1089
+ t2 = entries;
1090
+ let t6;
1091
+ if ($[9] !== locale) {
1092
+ t6 = messagesFor(locale);
1093
+ $[9] = locale;
1094
+ $[10] = t6;
1095
+ } else t6 = $[10];
1096
+ t3 = t6.calendar.year;
1097
+ t4 = chooseThen(state, setOpen, shown);
1098
+ $[0] = locale;
1099
+ $[1] = setOpen;
1100
+ $[2] = state;
1101
+ $[3] = T0;
1102
+ $[4] = shown;
1103
+ $[5] = t1;
1104
+ $[6] = t2;
1105
+ $[7] = t3;
1106
+ $[8] = t4;
1107
+ } else {
1108
+ T0 = $[3];
1109
+ shown = $[4];
1110
+ t1 = $[5];
1111
+ t2 = $[6];
1112
+ t3 = $[7];
1113
+ t4 = $[8];
1114
+ }
1115
+ let t5;
1116
+ if ($[11] !== T0 || $[12] !== shown || $[13] !== t1 || $[14] !== t2 || $[15] !== t3 || $[16] !== t4) {
1117
+ t5 = /* @__PURE__ */ jsx(T0, {
1118
+ disabled: t1,
1119
+ entries: t2,
1120
+ name: t3,
1121
+ onChoose: t4,
1122
+ shown
1123
+ });
1124
+ $[11] = T0;
1125
+ $[12] = shown;
1126
+ $[13] = t1;
1127
+ $[14] = t2;
1128
+ $[15] = t3;
1129
+ $[16] = t4;
1130
+ $[17] = t5;
1131
+ } else t5 = $[17];
1132
+ return t5;
1133
+ }
1134
+ function yearOf(state, locale) {
1135
+ const { focusedDate, timeZone } = state;
1136
+ return new DateFormatter(locale, {
1137
+ calendar: focusedDate.calendar.identifier,
1138
+ era: eraOf(focusedDate),
1139
+ timeZone,
1140
+ year: "numeric"
1141
+ }).format(focusedDate.toDate(timeZone));
1142
+ }
1143
+ function yearsOf(state, locale) {
1144
+ const { focusedDate, maxValue, minValue, timeZone } = state;
1145
+ const formatter = new DateFormatter(locale, {
1146
+ calendar: focusedDate.calendar.identifier,
1147
+ era: eraOf(focusedDate),
1148
+ timeZone,
1149
+ year: "numeric"
1150
+ });
1151
+ let first = focusedDate.subtract({ years: Math.floor(LISTED_YEARS / 2) });
1152
+ let last = focusedDate.add({ years: Math.ceil(LISTED_YEARS / 2) - 1 });
1153
+ if (maxValue != null && last.compare(maxValue) > 0) {
1154
+ last = toCalendarDate(maxValue);
1155
+ first = last.subtract({ years: 200 });
1156
+ }
1157
+ if (minValue != null && first.compare(minValue) < 0) {
1158
+ first = toCalendarDate(minValue);
1159
+ last = first.add({ years: 200 });
1160
+ if (maxValue != null && last.compare(maxValue) > 0) last = toCalendarDate(maxValue);
1161
+ }
1162
+ const entries = [];
1163
+ let shown = 0;
1164
+ for (let date = first; date.compare(last) <= 0 || isSameYear(date, last); date = date.add({ years: 1 })) {
1165
+ const entry = date.compare(last) > 0 ? last : date;
1166
+ if (isSameYear(entry, focusedDate)) shown = entries.length;
1167
+ entries.push({
1168
+ date: entry,
1169
+ formatted: formatter.format(entry.toDate(timeZone)),
1170
+ id: entries.length
1171
+ });
1172
+ }
1173
+ return {
1174
+ entries,
1175
+ shown
1176
+ };
1177
+ }
1178
+ const NONE = /* @__PURE__ */ new Set();
1179
+ //#endregion
1180
+ export { CalendarFrame, visibleMonthOf };
1181
+
1182
+ //# sourceMappingURL=index.js.map