@mantine-vue/dates 1.1.2

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/esm/index.mjs ADDED
@@ -0,0 +1,2252 @@
1
+ import dayjs from "dayjs";
2
+ import customParseFormat from "dayjs/plugin/customParseFormat";
3
+ import { computed, defineComponent, h, inject, provide, ref, watch } from "vue";
4
+ import { useUncontrolled } from "@mantine-vue/hooks";
5
+ import { AccordionChevron, ActionIcon, Box, Button, CheckIcon, CloseButton, Group, InputBase, Modal, Popover, ScrollArea, SimpleGrid, Text, UnstyledButton } from "@mantine-vue/core";
6
+ var Dates_module_default = {
7
+ calendar: "_calendar_5kwje_1",
8
+ calendarLevel: "_calendarLevel_5kwje_15",
9
+ calendarHeader: "_calendarHeader_5kwje_19",
10
+ calendarHeaderLevel: "_calendarHeaderLevel_5kwje_32",
11
+ calendarHeaderControl: "_calendarHeaderControl_5kwje_33",
12
+ calendarHeaderControlIcon: "_calendarHeaderControlIcon_5kwje_74",
13
+ month: "_month_5kwje_87",
14
+ monthRow: "_monthRow_5kwje_97",
15
+ monthCell: "_monthCell_5kwje_101",
16
+ weekday: "_weekday_5kwje_110",
17
+ weekNumber: "_weekNumber_5kwje_122",
18
+ day: "_day_5kwje_128",
19
+ pickerControl: "_pickerControl_5kwje_189",
20
+ controlsGrid: "_controlsGrid_5kwje_195",
21
+ timePicker: "_timePicker_5kwje_255",
22
+ dateTimePicker: "_dateTimePicker_5kwje_256",
23
+ datePickerRoot: "_datePickerRoot_5kwje_260",
24
+ timeWrapper: "_timeWrapper_5kwje_270",
25
+ timeInput: "_timeInput_5kwje_276",
26
+ presetsList: "_presetsList_5kwje_281",
27
+ presetButton: "_presetButton_5kwje_289",
28
+ timePickerPresetsGroup: "_timePickerPresetsGroup_5kwje_300",
29
+ dropdown: "_dropdown_5kwje_304",
30
+ placeholder: "_placeholder_5kwje_308",
31
+ timeGridControl: "_timeGridControl_5kwje_312",
32
+ timePickerFieldsRoot: "_timePickerFieldsRoot_5kwje_343",
33
+ timePickerFieldsGroup: "_timePickerFieldsGroup_5kwje_350",
34
+ timePickerField: "_timePickerField_5kwje_343",
35
+ timePickerDropdown: "_timePickerDropdown_5kwje_400",
36
+ timePickerControlsListGroup: "_timePickerControlsListGroup_5kwje_404",
37
+ timePickerControlsList: "_timePickerControlsList_5kwje_404",
38
+ timePickerControl: "_timePickerControl_5kwje_404",
39
+ miniCalendarRoot: "_miniCalendarRoot_5kwje_433",
40
+ miniCalendarDays: "_miniCalendarDays_5kwje_440",
41
+ miniCalendarDay: "_miniCalendarDay_5kwje_440",
42
+ miniCalendarDayMonth: "_miniCalendarDayMonth_5kwje_475",
43
+ miniCalendarDayNumber: "_miniCalendarDayNumber_5kwje_481",
44
+ miniCalendarControl: "_miniCalendarControl_5kwje_486"
45
+ };
46
+ //#endregion
47
+ //#region src/index.ts
48
+ dayjs.extend(customParseFormat);
49
+ var DATES_PROVIDER_DEFAULT_SETTINGS = {
50
+ locale: "en",
51
+ firstDayOfWeek: 1,
52
+ weekendDays: [0, 6],
53
+ timezone: "UTC",
54
+ consistentWeeks: false
55
+ };
56
+ var DatesContextKey = Symbol("DatesContext");
57
+ var DatesProvider = defineComponent({
58
+ name: "DatesProvider",
59
+ props: { settings: {
60
+ type: Object,
61
+ default: () => ({})
62
+ } },
63
+ setup(props, { slots }) {
64
+ const settings = computed(() => ({
65
+ ...DATES_PROVIDER_DEFAULT_SETTINGS,
66
+ ...props.settings
67
+ }));
68
+ provide(DatesContextKey, settings.value);
69
+ watch(settings, (value) => provide(DatesContextKey, value));
70
+ return () => slots.default?.();
71
+ }
72
+ });
73
+ function useDatesContext() {
74
+ return inject(DatesContextKey, DATES_PROVIDER_DEFAULT_SETTINGS);
75
+ }
76
+ function normalizeDate(value) {
77
+ if (value == null || value === "") return null;
78
+ const parsed = dayjs(value);
79
+ return parsed.isValid() ? parsed.format("YYYY-MM-DD") : null;
80
+ }
81
+ function toDateString(value) {
82
+ return normalizeDate(value);
83
+ }
84
+ function shiftTimezone(direction, date, timezone) {
85
+ return date;
86
+ }
87
+ function getTimezoneOffset(date, timezone) {
88
+ return new Date(date).getTimezoneOffset();
89
+ }
90
+ function clampDate(date, minDate, maxDate) {
91
+ const value = dayjs(date);
92
+ const min = normalizeDate(minDate);
93
+ const max = normalizeDate(maxDate);
94
+ if (min && value.isBefore(min, "day")) return min;
95
+ if (max && value.isAfter(max, "day")) return max;
96
+ return value.format("YYYY-MM-DD");
97
+ }
98
+ function getDefaultClampedDate({ minDate, maxDate, defaultDate } = {}) {
99
+ return clampDate(normalizeDate(defaultDate) || dayjs().format("YYYY-MM-DD"), minDate, maxDate);
100
+ }
101
+ function assignTime(date, time) {
102
+ const timeValue = dayjs(time);
103
+ return dayjs(date).hour(timeValue.hour()).minute(timeValue.minute()).second(timeValue.second()).millisecond(timeValue.millisecond()).toDate();
104
+ }
105
+ function getFormattedDate({ date, format = "MMMM D, YYYY", locale }) {
106
+ return dayjs(date).locale(locale || "en").format(format);
107
+ }
108
+ function isSameDate(a, b) {
109
+ if (!a || !b) return false;
110
+ return dayjs(a).isSame(b, "day");
111
+ }
112
+ function isSameMonth(a, b) {
113
+ return dayjs(a).isSame(b, "month");
114
+ }
115
+ function isSameYear(a, b) {
116
+ return dayjs(a).isSame(b, "year");
117
+ }
118
+ function getStartOfWeek(date, firstDayOfWeek = 1) {
119
+ const value = dayjs(date);
120
+ const diff = (value.day() - firstDayOfWeek + 7) % 7;
121
+ return value.subtract(diff, "day").format("YYYY-MM-DD");
122
+ }
123
+ function getEndOfWeek(date, firstDayOfWeek = 1) {
124
+ return dayjs(getStartOfWeek(date, firstDayOfWeek)).add(6, "day").format("YYYY-MM-DD");
125
+ }
126
+ function getWeekNumber(date) {
127
+ const current = dayjs(date);
128
+ const yearStart = dayjs(`${current.year()}-01-01`);
129
+ return Math.ceil((current.diff(yearStart, "day") + yearStart.day() + 1) / 7);
130
+ }
131
+ function handleControlKeyDown({ rowIndex, cellIndex, event, controlsRef }) {
132
+ const rows = controlsRef.length;
133
+ const cols = controlsRef[0]?.length || 0;
134
+ let nextRow = rowIndex;
135
+ let nextCell = cellIndex;
136
+ if (event.key === "ArrowRight") nextCell += 1;
137
+ if (event.key === "ArrowLeft") nextCell -= 1;
138
+ if (event.key === "ArrowDown") nextRow += 1;
139
+ if (event.key === "ArrowUp") nextRow -= 1;
140
+ if (event.key === "Home") nextCell = 0;
141
+ if (event.key === "End") nextCell = cols - 1;
142
+ if (nextCell < 0) {
143
+ nextCell = cols - 1;
144
+ nextRow -= 1;
145
+ }
146
+ if (nextCell >= cols) {
147
+ nextCell = 0;
148
+ nextRow += 1;
149
+ }
150
+ const next = controlsRef[(nextRow + rows) % rows]?.[(nextCell + cols) % cols];
151
+ if (next) {
152
+ event.preventDefault();
153
+ next.focus();
154
+ }
155
+ }
156
+ function focusAdjacentControl(refs, rowIndex, cellIndex, direction) {
157
+ const isFocusable = (el) => !!el && !el.disabled && !el.hasAttribute("data-hidden") && !el.hasAttribute("data-outside");
158
+ let nextRow = rowIndex;
159
+ let nextCell = cellIndex;
160
+ for (let i = 0; i < 60; i += 1) {
161
+ if (direction === "up") nextRow -= 1;
162
+ if (direction === "down") nextRow += 1;
163
+ if (direction === "left") {
164
+ nextCell -= 1;
165
+ if (nextCell < 0) {
166
+ nextRow -= 1;
167
+ nextCell = (refs[nextRow]?.length || 1) - 1;
168
+ }
169
+ }
170
+ if (direction === "right") {
171
+ nextCell += 1;
172
+ if (nextCell >= (refs[nextRow]?.length || 0)) {
173
+ nextRow += 1;
174
+ nextCell = 0;
175
+ }
176
+ }
177
+ const row = refs[nextRow];
178
+ if (!row) return;
179
+ const el = row[nextCell];
180
+ if (el === void 0) return;
181
+ if (isFocusable(el)) {
182
+ el.focus();
183
+ return;
184
+ }
185
+ }
186
+ }
187
+ function keyToDirection(key) {
188
+ if (key === "ArrowUp") return "up";
189
+ if (key === "ArrowDown") return "down";
190
+ if (key === "ArrowLeft") return "left";
191
+ if (key === "ArrowRight") return "right";
192
+ return null;
193
+ }
194
+ function setGridRef(refs, rowIndex, cellIndex, node) {
195
+ if (!refs[rowIndex]) refs[rowIndex] = [];
196
+ refs[rowIndex][cellIndex] = node?.$el ?? node ?? void 0;
197
+ }
198
+ function getMonthDays(month, firstDayOfWeek, consistentWeeks = false) {
199
+ const startOfMonth = dayjs(month).startOf("month");
200
+ const start = dayjs(getStartOfWeek(startOfMonth.format("YYYY-MM-DD"), firstDayOfWeek));
201
+ const weeks = consistentWeeks ? 6 : Math.ceil((startOfMonth.daysInMonth() + startOfMonth.day()) / 7);
202
+ return Array.from({ length: weeks }, (_, week) => Array.from({ length: 7 }, (__, day) => start.add(week * 7 + day, "day").format("YYYY-MM-DD")));
203
+ }
204
+ function isBeforeMin(date, minDate) {
205
+ const min = normalizeDate(minDate);
206
+ return !!min && dayjs(date).isBefore(min, "day");
207
+ }
208
+ function isAfterMax(date, maxDate) {
209
+ const max = normalizeDate(maxDate);
210
+ return !!max && dayjs(date).isAfter(max, "day");
211
+ }
212
+ function formatValue(value, type, format, locale, labelSeparator = "–", valueFormatter) {
213
+ if (valueFormatter) return valueFormatter({
214
+ type,
215
+ date: value,
216
+ locale,
217
+ format,
218
+ labelSeparator
219
+ });
220
+ if (type === "multiple") return Array.isArray(value) ? value.map((item) => dayjs(item).locale(locale || "en").format(format)).join(", ") : "";
221
+ if (type === "range") {
222
+ const [start, end] = Array.isArray(value) ? value : [null, null];
223
+ if (!start && !end) return "";
224
+ if (start && !end) return `${dayjs(start).locale(locale || "en").format(format)} ${labelSeparator} `;
225
+ if (!start && end) return `${labelSeparator} ${dayjs(end).locale(locale || "en").format(format)}`;
226
+ return `${dayjs(start).locale(locale || "en").format(format)} ${labelSeparator} ${dayjs(end).locale(locale || "en").format(format)}`;
227
+ }
228
+ return value ? dayjs(value).locale(locale || "en").format(format) : "";
229
+ }
230
+ function getMonthLabel(date, format = "MMMM YYYY", locale) {
231
+ return dayjs(date).locale(locale || "en").format(format);
232
+ }
233
+ function getYearRange(date) {
234
+ const year = dayjs(date).year();
235
+ const start = year - year % 10;
236
+ return Array.from({ length: 10 }, (_, index) => dayjs(`${start + index}-01-01`).format("YYYY-MM-DD"));
237
+ }
238
+ function getDecadeLabel(date) {
239
+ const years = getYearRange(date);
240
+ return `${dayjs(years[0]).year()} – ${dayjs(years[years.length - 1]).year()}`;
241
+ }
242
+ var Day = defineComponent({
243
+ name: "Day",
244
+ inheritAttrs: false,
245
+ props: {
246
+ date: {
247
+ type: String,
248
+ required: true
249
+ },
250
+ size: {
251
+ type: [String, Number],
252
+ default: "sm"
253
+ },
254
+ static: {
255
+ type: Boolean,
256
+ default: false
257
+ },
258
+ weekend: Boolean,
259
+ outside: Boolean,
260
+ selected: Boolean,
261
+ hidden: Boolean,
262
+ inRange: Boolean,
263
+ firstInRange: Boolean,
264
+ lastInRange: Boolean,
265
+ highlightToday: Boolean,
266
+ fullWidth: Boolean,
267
+ disabled: Boolean,
268
+ renderDay: Function,
269
+ classNames: {
270
+ type: [Object, Function],
271
+ default: void 0
272
+ },
273
+ styles: {
274
+ type: [Object, Function],
275
+ default: void 0
276
+ },
277
+ unstyled: Boolean
278
+ },
279
+ setup(props, { attrs }) {
280
+ return () => h(UnstyledButton, {
281
+ ...attrs,
282
+ component: props.static ? "div" : "button",
283
+ class: [Dates_module_default.day, attrs.class],
284
+ disabled: props.disabled,
285
+ style: [{ display: props.hidden ? "none" : void 0 }, attrs.style],
286
+ "data-today": dayjs(props.date).isSame(/* @__PURE__ */ new Date(), "day") || void 0,
287
+ "data-hidden": props.hidden || void 0,
288
+ "data-highlight-today": props.highlightToday || void 0,
289
+ "data-disabled": props.disabled || void 0,
290
+ "data-weekend": !props.disabled && !props.outside && props.weekend || void 0,
291
+ "data-outside": !props.disabled && props.outside || void 0,
292
+ "data-selected": !props.disabled && props.selected || void 0,
293
+ "data-in-range": props.inRange && !props.disabled || void 0,
294
+ "data-first-in-range": props.firstInRange && !props.disabled || void 0,
295
+ "data-last-in-range": props.lastInRange && !props.disabled || void 0,
296
+ "data-static": props.static || void 0,
297
+ "data-full-width": props.fullWidth || void 0
298
+ }, () => props.renderDay?.(props.date) || dayjs(props.date).date());
299
+ }
300
+ });
301
+ var PickerControl = defineComponent({
302
+ name: "PickerControl",
303
+ inheritAttrs: false,
304
+ props: {
305
+ selected: Boolean,
306
+ disabled: Boolean,
307
+ inRange: Boolean,
308
+ firstInRange: Boolean,
309
+ lastInRange: Boolean,
310
+ withCellSpacing: {
311
+ type: Boolean,
312
+ default: true
313
+ },
314
+ fullWidth: Boolean
315
+ },
316
+ setup(props, { attrs, slots }) {
317
+ return () => h(UnstyledButton, {
318
+ ...attrs,
319
+ class: [Dates_module_default.pickerControl, attrs.class],
320
+ disabled: props.disabled,
321
+ "data-selected": props.selected && !props.disabled || void 0,
322
+ "data-disabled": props.disabled || void 0,
323
+ "data-in-range": props.inRange && !props.disabled && !props.selected || void 0,
324
+ "data-first-in-range": props.firstInRange && !props.disabled || void 0,
325
+ "data-last-in-range": props.lastInRange && !props.disabled || void 0,
326
+ "data-with-cell-spacing": props.withCellSpacing || void 0,
327
+ "data-full-width": props.fullWidth || void 0
328
+ }, () => slots.default?.());
329
+ }
330
+ });
331
+ var CalendarHeader = defineComponent({
332
+ name: "CalendarHeader",
333
+ props: {
334
+ label: {
335
+ type: String,
336
+ required: true
337
+ },
338
+ hasNextLevel: {
339
+ type: Boolean,
340
+ default: true
341
+ },
342
+ withNext: {
343
+ type: Boolean,
344
+ default: true
345
+ },
346
+ withPrevious: {
347
+ type: Boolean,
348
+ default: true
349
+ },
350
+ nextDisabled: Boolean,
351
+ previousDisabled: Boolean,
352
+ nextLabel: {
353
+ type: String,
354
+ default: "Next"
355
+ },
356
+ previousLabel: {
357
+ type: String,
358
+ default: "Previous"
359
+ },
360
+ levelControlAriaLabel: String,
361
+ fullWidth: Boolean,
362
+ onNext: Function,
363
+ onPrevious: Function,
364
+ onLevelClick: Function
365
+ },
366
+ setup(props) {
367
+ return () => {
368
+ const previousControl = props.withPrevious ? h(UnstyledButton, {
369
+ class: Dates_module_default.calendarHeaderControl,
370
+ "data-direction": "previous",
371
+ "aria-label": props.previousLabel,
372
+ onClick: props.onPrevious,
373
+ disabled: props.previousDisabled,
374
+ "data-disabled": props.previousDisabled || void 0
375
+ }, () => h(AccordionChevron, {
376
+ class: Dates_module_default.calendarHeaderControlIcon,
377
+ "data-direction": "previous",
378
+ size: "45%"
379
+ })) : null;
380
+ const levelControl = h(UnstyledButton, {
381
+ component: props.hasNextLevel ? "button" : "div",
382
+ class: Dates_module_default.calendarHeaderLevel,
383
+ onClick: props.hasNextLevel ? props.onLevelClick : void 0,
384
+ disabled: !props.hasNextLevel,
385
+ "data-static": !props.hasNextLevel || void 0,
386
+ "aria-label": props.levelControlAriaLabel
387
+ }, () => props.label);
388
+ const nextControl = props.withNext ? h(UnstyledButton, {
389
+ class: Dates_module_default.calendarHeaderControl,
390
+ "data-direction": "next",
391
+ "aria-label": props.nextLabel,
392
+ onClick: props.onNext,
393
+ disabled: props.nextDisabled,
394
+ "data-disabled": props.nextDisabled || void 0
395
+ }, () => h(AccordionChevron, {
396
+ class: Dates_module_default.calendarHeaderControlIcon,
397
+ "data-direction": "next",
398
+ size: "45%"
399
+ })) : null;
400
+ return h("div", {
401
+ class: Dates_module_default.calendarHeader,
402
+ "data-full-width": props.fullWidth || void 0
403
+ }, [
404
+ previousControl,
405
+ levelControl,
406
+ nextControl
407
+ ]);
408
+ };
409
+ }
410
+ });
411
+ var WeekdaysRow = defineComponent({
412
+ name: "WeekdaysRow",
413
+ props: {
414
+ firstDayOfWeek: Number,
415
+ weekendDays: Array,
416
+ locale: String,
417
+ weekdayFormat: {
418
+ type: [String, Function],
419
+ default: "dd"
420
+ },
421
+ withWeekNumbers: Boolean
422
+ },
423
+ setup(props) {
424
+ const ctx = useDatesContext();
425
+ return () => {
426
+ const first = props.firstDayOfWeek ?? ctx.firstDayOfWeek;
427
+ const days = Array.from({ length: 7 }, (_, index) => dayjs("2024-01-07").add((first + index) % 7, "day"));
428
+ return h("tr", { class: Dates_module_default.weekdaysRow }, [props.withWeekNumbers ? h("th", { class: Dates_module_default.weekday }) : null, ...days.map((date) => h("th", {
429
+ class: Dates_module_default.weekday,
430
+ "data-weekend": (props.weekendDays ?? ctx.weekendDays).includes(date.day()) || void 0
431
+ }, typeof props.weekdayFormat === "function" ? props.weekdayFormat(date.format("YYYY-MM-DD")) : date.locale(props.locale || ctx.locale).format(props.weekdayFormat)))]);
432
+ };
433
+ }
434
+ });
435
+ var Month = defineComponent({
436
+ name: "Month",
437
+ props: {
438
+ month: {
439
+ type: String,
440
+ default: () => dayjs().format("YYYY-MM-DD")
441
+ },
442
+ value: {
443
+ type: [
444
+ String,
445
+ Array,
446
+ null
447
+ ],
448
+ default: null
449
+ },
450
+ type: {
451
+ type: String,
452
+ default: "default"
453
+ },
454
+ firstDayOfWeek: Number,
455
+ weekendDays: Array,
456
+ minDate: [String, Date],
457
+ maxDate: [String, Date],
458
+ excludeDate: Function,
459
+ renderDay: Function,
460
+ hideOutsideDates: Boolean,
461
+ hideWeekdays: Boolean,
462
+ getDayProps: Function,
463
+ getDayAriaLabel: Function,
464
+ onDayClick: Function,
465
+ onDayMouseEnter: Function,
466
+ withCellSpacing: {
467
+ type: Boolean,
468
+ default: true
469
+ },
470
+ highlightToday: Boolean,
471
+ withWeekNumbers: Boolean,
472
+ static: Boolean,
473
+ fullWidth: Boolean
474
+ },
475
+ setup(props) {
476
+ const ctx = useDatesContext();
477
+ const hovered = ref(null);
478
+ const dayRefs = [];
479
+ const isSelected = (date) => {
480
+ if (props.type === "multiple") return Array.isArray(props.value) && props.value.includes(date);
481
+ if (props.type === "range") {
482
+ const [start, end] = Array.isArray(props.value) ? props.value : [null, null];
483
+ return isSameDate(date, start) || isSameDate(date, end);
484
+ }
485
+ return isSameDate(date, props.value);
486
+ };
487
+ const isInRange = (date) => {
488
+ if (props.type !== "range" || !Array.isArray(props.value)) return false;
489
+ const [start, end] = props.value;
490
+ const rangeEnd = end || hovered.value;
491
+ if (!start || !rangeEnd) return false;
492
+ return dayjs(date).isAfter(start, "day") && dayjs(date).isBefore(rangeEnd, "day");
493
+ };
494
+ return () => {
495
+ const first = props.firstDayOfWeek ?? ctx.firstDayOfWeek;
496
+ const rows = getMonthDays(props.month, first, ctx.consistentWeeks);
497
+ const flatDates = rows.flat();
498
+ const isEnabled = (date) => {
499
+ const outside = !dayjs(date).isSame(props.month, "month");
500
+ return !(isBeforeMin(date, props.minDate) || isAfterMax(date, props.maxDate) || props.excludeDate?.(date) || props.getDayProps?.(date)?.disabled) && (!props.hideOutsideDates || !outside);
501
+ };
502
+ const enabledDates = flatDates.filter(isEnabled);
503
+ const dateInTabOrder = enabledDates.find((date) => isSelected(date)) ?? enabledDates.find((date) => dayjs().isSame(date, "date")) ?? enabledDates[0];
504
+ return h("table", {
505
+ class: Dates_module_default.month,
506
+ "data-full-width": props.fullWidth || void 0
507
+ }, [props.hideWeekdays ? null : h("thead", [h(WeekdaysRow, {
508
+ firstDayOfWeek: first,
509
+ weekendDays: props.weekendDays,
510
+ withWeekNumbers: props.withWeekNumbers
511
+ })]), h("tbody", rows.map((week, rowIndex) => h("tr", { class: Dates_module_default.monthRow }, [props.withWeekNumbers ? h("td", { class: Dates_module_default.weekNumber }, getWeekNumber(week[0])) : null, ...week.map((date, cellIndex) => {
512
+ const outside = !dayjs(date).isSame(props.month, "month");
513
+ const disabled = isBeforeMin(date, props.minDate) || isAfterMax(date, props.maxDate) || props.excludeDate?.(date);
514
+ const dayProps = props.getDayProps?.(date) || {};
515
+ const selected = isSelected(date);
516
+ const [start, end] = props.type === "range" && Array.isArray(props.value) ? props.value : [null, null];
517
+ return h("td", {
518
+ class: Dates_module_default.monthCell,
519
+ "data-with-spacing": props.withCellSpacing || void 0
520
+ }, [h(Day, {
521
+ ...dayProps,
522
+ date,
523
+ static: props.static,
524
+ disabled: disabled || dayProps.disabled,
525
+ weekend: (props.weekendDays ?? ctx.weekendDays).includes(dayjs(date).day()),
526
+ outside,
527
+ hidden: props.hideOutsideDates && outside,
528
+ selected,
529
+ inRange: isInRange(date),
530
+ firstInRange: isSameDate(date, start),
531
+ lastInRange: isSameDate(date, end),
532
+ highlightToday: props.highlightToday,
533
+ fullWidth: props.fullWidth,
534
+ renderDay: props.renderDay,
535
+ "aria-label": props.getDayAriaLabel?.(date),
536
+ tabindex: props.static ? void 0 : date === dateInTabOrder ? 0 : -1,
537
+ "data-autofocus": selected || void 0,
538
+ ref: (node) => setGridRef(dayRefs, rowIndex, cellIndex, node),
539
+ onClick: (event) => {
540
+ dayProps.onClick?.(event);
541
+ if (!disabled && !props.static) props.onDayClick?.(date);
542
+ },
543
+ onMouseenter: (event) => {
544
+ hovered.value = date;
545
+ dayProps.onMouseenter?.(event);
546
+ props.onDayMouseEnter?.(date);
547
+ },
548
+ onKeydown: (event) => {
549
+ dayProps.onKeydown?.(event);
550
+ const direction = keyToDirection(event.key);
551
+ if (direction) {
552
+ event.preventDefault();
553
+ focusAdjacentControl(dayRefs, rowIndex, cellIndex, direction);
554
+ }
555
+ }
556
+ })]);
557
+ })])))]);
558
+ };
559
+ }
560
+ });
561
+ var MonthsList = defineComponent({
562
+ name: "MonthsList",
563
+ props: {
564
+ year: {
565
+ type: String,
566
+ default: () => dayjs().format("YYYY-MM-DD")
567
+ },
568
+ value: [
569
+ String,
570
+ Array,
571
+ null
572
+ ],
573
+ minDate: [String, Date],
574
+ maxDate: [String, Date],
575
+ locale: String,
576
+ monthsListFormat: {
577
+ type: [String, Function],
578
+ default: "MMM"
579
+ },
580
+ getMonthControlProps: Function,
581
+ onMonthSelect: Function,
582
+ onMonthMouseEnter: Function,
583
+ fullWidth: Boolean
584
+ },
585
+ setup(props) {
586
+ const controlRefs = [];
587
+ return () => {
588
+ const months = Array.from({ length: 12 }, (_, index) => dayjs(props.year).month(index).startOf("month").format("YYYY-MM-DD"));
589
+ const isEnabled = (date) => !(props.minDate && dayjs(date).endOf("month").isBefore(props.minDate, "day") || props.maxDate && dayjs(date).startOf("month").isAfter(props.maxDate, "day") || props.getMonthControlProps?.(date)?.disabled);
590
+ const isSelected = (date) => Array.isArray(props.value) ? props.value.some((item) => dayjs(item).isSame(date, "month")) : !!props.value && dayjs(props.value).isSame(date, "month");
591
+ const enabledMonths = months.filter(isEnabled);
592
+ const monthInTabOrder = enabledMonths.find(isSelected) ?? enabledMonths.find((date) => dayjs().isSame(date, "month")) ?? enabledMonths[0];
593
+ return h(SimpleGrid, {
594
+ cols: 3,
595
+ spacing: 4,
596
+ class: Dates_module_default.controlsGrid,
597
+ "data-full-width": props.fullWidth || void 0
598
+ }, () => months.map((date, index) => {
599
+ const rowIndex = Math.floor(index / 3);
600
+ const cellIndex = index % 3;
601
+ const disabled = !isEnabled(date);
602
+ const controlProps = props.getMonthControlProps?.(date) || {};
603
+ return h(PickerControl, {
604
+ fullWidth: props.fullWidth,
605
+ ...controlProps,
606
+ disabled: disabled || controlProps.disabled,
607
+ selected: isSelected(date),
608
+ tabindex: date === monthInTabOrder ? 0 : -1,
609
+ "data-autofocus": isSelected(date) || void 0,
610
+ ref: (node) => setGridRef(controlRefs, rowIndex, cellIndex, node),
611
+ onClick: (event) => {
612
+ controlProps.onClick?.(event);
613
+ if (!disabled) props.onMonthSelect?.(date);
614
+ },
615
+ onMouseenter: (event) => {
616
+ controlProps.onMouseenter?.(event);
617
+ props.onMonthMouseEnter?.(date);
618
+ },
619
+ onKeydown: (event) => {
620
+ controlProps.onKeydown?.(event);
621
+ const direction = keyToDirection(event.key);
622
+ if (direction) {
623
+ event.preventDefault();
624
+ focusAdjacentControl(controlRefs, rowIndex, cellIndex, direction);
625
+ }
626
+ }
627
+ }, () => typeof props.monthsListFormat === "function" ? props.monthsListFormat(date) : dayjs(date).locale(props.locale || "en").format(props.monthsListFormat));
628
+ }));
629
+ };
630
+ }
631
+ });
632
+ var YearsList = defineComponent({
633
+ name: "YearsList",
634
+ props: {
635
+ decade: {
636
+ type: String,
637
+ default: () => dayjs().format("YYYY-MM-DD")
638
+ },
639
+ value: [
640
+ String,
641
+ Array,
642
+ null
643
+ ],
644
+ minDate: [String, Date],
645
+ maxDate: [String, Date],
646
+ yearsListFormat: {
647
+ type: [String, Function],
648
+ default: "YYYY"
649
+ },
650
+ getYearControlProps: Function,
651
+ onYearSelect: Function,
652
+ onYearMouseEnter: Function,
653
+ fullWidth: Boolean
654
+ },
655
+ setup(props) {
656
+ const controlRefs = [];
657
+ return () => {
658
+ const years = getYearRange(props.decade);
659
+ const isEnabled = (date) => !(props.minDate && dayjs(date).endOf("year").isBefore(props.minDate, "day") || props.maxDate && dayjs(date).startOf("year").isAfter(props.maxDate, "day") || props.getYearControlProps?.(date)?.disabled);
660
+ const isSelected = (date) => Array.isArray(props.value) ? props.value.some((item) => dayjs(item).isSame(date, "year")) : !!props.value && dayjs(props.value).isSame(date, "year");
661
+ const enabledYears = years.filter(isEnabled);
662
+ const yearInTabOrder = enabledYears.find(isSelected) ?? enabledYears.find((date) => dayjs().isSame(date, "year")) ?? enabledYears[0];
663
+ return h(SimpleGrid, {
664
+ cols: 3,
665
+ spacing: 4,
666
+ class: Dates_module_default.controlsGrid,
667
+ "data-full-width": props.fullWidth || void 0
668
+ }, () => years.map((date, index) => {
669
+ const rowIndex = Math.floor(index / 3);
670
+ const cellIndex = index % 3;
671
+ const disabled = !isEnabled(date);
672
+ const controlProps = props.getYearControlProps?.(date) || {};
673
+ return h(PickerControl, {
674
+ fullWidth: props.fullWidth,
675
+ ...controlProps,
676
+ disabled: disabled || controlProps.disabled,
677
+ selected: isSelected(date),
678
+ tabindex: date === yearInTabOrder ? 0 : -1,
679
+ "data-autofocus": isSelected(date) || void 0,
680
+ ref: (node) => setGridRef(controlRefs, rowIndex, cellIndex, node),
681
+ onClick: (event) => {
682
+ controlProps.onClick?.(event);
683
+ if (!disabled) props.onYearSelect?.(date);
684
+ },
685
+ onMouseenter: (event) => {
686
+ controlProps.onMouseenter?.(event);
687
+ props.onYearMouseEnter?.(date);
688
+ },
689
+ onKeydown: (event) => {
690
+ controlProps.onKeydown?.(event);
691
+ const direction = keyToDirection(event.key);
692
+ if (direction) {
693
+ event.preventDefault();
694
+ focusAdjacentControl(controlRefs, rowIndex, cellIndex, direction);
695
+ }
696
+ }
697
+ }, () => typeof props.yearsListFormat === "function" ? props.yearsListFormat(date) : dayjs(date).format(props.yearsListFormat));
698
+ }));
699
+ };
700
+ }
701
+ });
702
+ function getNextLevel(level, direction) {
703
+ const order = [
704
+ "month",
705
+ "year",
706
+ "decade"
707
+ ];
708
+ return order[Math.max(0, Math.min(order.length - 1, order.indexOf(level) + (direction === "up" ? 1 : -1)))];
709
+ }
710
+ function clampLevel(level, minLevel, maxLevel) {
711
+ const order = [
712
+ "month",
713
+ "year",
714
+ "decade"
715
+ ];
716
+ const toNumber = (value, fallback) => value ? order.indexOf(value) : fallback;
717
+ return order[Math.max(toNumber(minLevel, 0), Math.min(toNumber(maxLevel, 2), toNumber(level, 0)))];
718
+ }
719
+ var Calendar = defineComponent({
720
+ name: "Calendar",
721
+ props: {
722
+ defaultLevel: String,
723
+ level: String,
724
+ onLevelChange: Function,
725
+ maxLevel: {
726
+ type: String,
727
+ default: "decade"
728
+ },
729
+ minLevel: {
730
+ type: String,
731
+ default: "month"
732
+ },
733
+ defaultDate: [String, Date],
734
+ date: [String, Date],
735
+ onDateChange: Function,
736
+ numberOfColumns: {
737
+ type: Number,
738
+ default: 1
739
+ },
740
+ columnsToScroll: Number,
741
+ type: {
742
+ type: String,
743
+ default: "default"
744
+ },
745
+ value: [
746
+ String,
747
+ Array,
748
+ null
749
+ ],
750
+ minDate: [String, Date],
751
+ maxDate: [String, Date],
752
+ locale: String,
753
+ firstDayOfWeek: Number,
754
+ weekendDays: Array,
755
+ renderDay: Function,
756
+ getDayProps: Function,
757
+ getDayAriaLabel: Function,
758
+ getMonthControlProps: Function,
759
+ getYearControlProps: Function,
760
+ excludeDate: Function,
761
+ hideOutsideDates: Boolean,
762
+ hideWeekdays: Boolean,
763
+ monthLabelFormat: {
764
+ type: [String, Function],
765
+ default: "MMMM YYYY"
766
+ },
767
+ yearLabelFormat: {
768
+ type: [String, Function],
769
+ default: "YYYY"
770
+ },
771
+ decadeLabelFormat: Function,
772
+ monthsListFormat: {
773
+ type: [String, Function],
774
+ default: "MMM"
775
+ },
776
+ yearsListFormat: {
777
+ type: [String, Function],
778
+ default: "YYYY"
779
+ },
780
+ onYearSelect: Function,
781
+ onMonthSelect: Function,
782
+ onMonthMouseEnter: Function,
783
+ onYearMouseEnter: Function,
784
+ onDayClick: Function,
785
+ withCellSpacing: {
786
+ type: Boolean,
787
+ default: true
788
+ },
789
+ highlightToday: Boolean,
790
+ withWeekNumbers: Boolean,
791
+ static: Boolean,
792
+ fullWidth: Boolean
793
+ },
794
+ setup(props, { attrs }) {
795
+ const [_level, setLevel] = useUncontrolled({
796
+ value: computed(() => props.level === void 0 ? void 0 : clampLevel(props.level, props.minLevel, props.maxLevel)),
797
+ defaultValue: props.defaultLevel === void 0 ? void 0 : clampLevel(props.defaultLevel, props.minLevel, props.maxLevel),
798
+ finalValue: clampLevel(void 0, props.minLevel, props.maxLevel),
799
+ onChange: (value) => props.onLevelChange?.(value)
800
+ });
801
+ const [_date, setDate] = useUncontrolled({
802
+ value: computed(() => normalizeDate(props.date) || void 0),
803
+ defaultValue: normalizeDate(props.defaultDate) || void 0,
804
+ finalValue: getDefaultClampedDate({
805
+ minDate: props.minDate,
806
+ maxDate: props.maxDate
807
+ }),
808
+ onChange: (value) => props.onDateChange?.(value)
809
+ });
810
+ const scroll = props.columnsToScroll || props.numberOfColumns || 1;
811
+ const updateDate = (amount, unit) => {
812
+ setDate(dayjs(_date.value).add(amount, unit).format("YYYY-MM-DD"));
813
+ };
814
+ return () => h(Box, {
815
+ ...attrs,
816
+ class: [Dates_module_default.calendar, attrs.class],
817
+ "data-calendar": true,
818
+ "data-full-width": props.fullWidth || void 0
819
+ }, () => Array.from({ length: props.numberOfColumns || 1 }, (_, column) => {
820
+ const currentDate = dayjs(_date.value).add(column * scroll, _level.value === "month" ? "month" : _level.value === "year" ? "year" : "year").format("YYYY-MM-DD");
821
+ if (_level.value === "month") return h("div", { class: Dates_module_default.calendarLevel }, [h(CalendarHeader, {
822
+ label: typeof props.monthLabelFormat === "function" ? props.monthLabelFormat(currentDate) : getMonthLabel(currentDate, props.monthLabelFormat, props.locale),
823
+ hasNextLevel: props.maxLevel !== "month",
824
+ withPrevious: column === 0,
825
+ withNext: column === (props.numberOfColumns || 1) - 1,
826
+ fullWidth: props.fullWidth,
827
+ onPrevious: () => updateDate(-scroll, "month"),
828
+ onNext: () => updateDate(scroll, "month"),
829
+ onLevelClick: () => setLevel(getNextLevel(_level.value, "up"))
830
+ }), h(Month, {
831
+ month: currentDate,
832
+ value: props.value,
833
+ type: props.type,
834
+ minDate: props.minDate,
835
+ maxDate: props.maxDate,
836
+ firstDayOfWeek: props.firstDayOfWeek,
837
+ weekendDays: props.weekendDays,
838
+ renderDay: props.renderDay,
839
+ getDayProps: props.getDayProps,
840
+ getDayAriaLabel: props.getDayAriaLabel,
841
+ excludeDate: props.excludeDate,
842
+ hideOutsideDates: props.hideOutsideDates,
843
+ hideWeekdays: props.hideWeekdays,
844
+ withCellSpacing: props.withCellSpacing,
845
+ highlightToday: props.highlightToday,
846
+ withWeekNumbers: props.withWeekNumbers,
847
+ static: props.static,
848
+ fullWidth: props.fullWidth,
849
+ onDayClick: props.onDayClick
850
+ })]);
851
+ if (_level.value === "year") return h("div", { class: Dates_module_default.calendarLevel }, [h(CalendarHeader, {
852
+ label: typeof props.yearLabelFormat === "function" ? props.yearLabelFormat(currentDate) : dayjs(currentDate).format(props.yearLabelFormat),
853
+ hasNextLevel: props.maxLevel === "decade",
854
+ withPrevious: column === 0,
855
+ withNext: column === (props.numberOfColumns || 1) - 1,
856
+ fullWidth: props.fullWidth,
857
+ onPrevious: () => updateDate(-scroll, "year"),
858
+ onNext: () => updateDate(scroll, "year"),
859
+ onLevelClick: () => setLevel(getNextLevel(_level.value, "up"))
860
+ }), h(MonthsList, {
861
+ year: currentDate,
862
+ value: props.value,
863
+ minDate: props.minDate,
864
+ maxDate: props.maxDate,
865
+ monthsListFormat: props.monthsListFormat,
866
+ getMonthControlProps: props.getMonthControlProps,
867
+ fullWidth: props.fullWidth,
868
+ onMonthMouseEnter: props.onMonthMouseEnter,
869
+ onMonthSelect: (date) => {
870
+ setDate(date);
871
+ props.onMonthSelect?.(date);
872
+ setLevel(clampLevel("month", props.minLevel, props.maxLevel));
873
+ }
874
+ })]);
875
+ const years = getYearRange(currentDate);
876
+ return h("div", { class: Dates_module_default.calendarLevel }, [h(CalendarHeader, {
877
+ label: props.decadeLabelFormat ? props.decadeLabelFormat(years[0], years[years.length - 1]) : getDecadeLabel(currentDate),
878
+ withPrevious: column === 0,
879
+ withNext: column === (props.numberOfColumns || 1) - 1,
880
+ hasNextLevel: false,
881
+ fullWidth: props.fullWidth,
882
+ onPrevious: () => updateDate(-10 * scroll, "year"),
883
+ onNext: () => updateDate(10 * scroll, "year")
884
+ }), h(YearsList, {
885
+ decade: currentDate,
886
+ value: props.value,
887
+ minDate: props.minDate,
888
+ maxDate: props.maxDate,
889
+ yearsListFormat: props.yearsListFormat,
890
+ getYearControlProps: props.getYearControlProps,
891
+ fullWidth: props.fullWidth,
892
+ onYearMouseEnter: props.onYearMouseEnter,
893
+ onYearSelect: (date) => {
894
+ setDate(date);
895
+ props.onYearSelect?.(date);
896
+ setLevel(clampLevel("year", props.minLevel, props.maxLevel));
897
+ }
898
+ })]);
899
+ }));
900
+ }
901
+ });
902
+ var MonthLevel = Calendar;
903
+ var YearLevel = Calendar;
904
+ var DecadeLevel = Calendar;
905
+ var MonthLevelGroup = Calendar;
906
+ var YearLevelGroup = Calendar;
907
+ var DecadeLevelGroup = Calendar;
908
+ var LevelsGroup = Calendar;
909
+ function isInRangeGranular(date, range, unit) {
910
+ const sorted = [...range].sort((a, b) => dayjs(a).isAfter(dayjs(b)) ? 1 : -1);
911
+ return !dayjs(date).isBefore(sorted[0], unit) && !dayjs(date).isAfter(sorted[1], unit);
912
+ }
913
+ function getNextPickerValue(value, date, type, sortDates = true) {
914
+ if (type === "multiple") {
915
+ const next = Array.isArray(value) ? [...value] : [];
916
+ const index = next.findIndex((item) => isSameDate(item, date));
917
+ if (index >= 0) next.splice(index, 1);
918
+ else next.push(date);
919
+ return sortDates ? next.sort((a, b) => dayjs(a).valueOf() - dayjs(b).valueOf()) : next;
920
+ }
921
+ if (type === "range") {
922
+ const [start, end] = Array.isArray(value) ? value : [null, null];
923
+ if (!start || start && end || dayjs(date).isBefore(start, "day")) return [date, null];
924
+ return [start, date];
925
+ }
926
+ return date;
927
+ }
928
+ var DatePicker = defineComponent({
929
+ name: "DatePicker",
930
+ props: {
931
+ type: {
932
+ type: String,
933
+ default: "default"
934
+ },
935
+ value: [
936
+ String,
937
+ Array,
938
+ null
939
+ ],
940
+ defaultValue: [
941
+ String,
942
+ Array,
943
+ null
944
+ ],
945
+ onChange: Function,
946
+ allowDeselect: {
947
+ type: Boolean,
948
+ default: true
949
+ },
950
+ sortDates: {
951
+ type: Boolean,
952
+ default: true
953
+ },
954
+ presets: Array
955
+ },
956
+ setup(props, { attrs }) {
957
+ const finalValue = computed(() => props.type === "multiple" ? [] : props.type === "range" ? [null, null] : null);
958
+ const [_value, setValue] = useUncontrolled({
959
+ value: computed(() => props.value),
960
+ defaultValue: props.defaultValue,
961
+ finalValue: finalValue.value,
962
+ onChange: (value) => props.onChange?.(value)
963
+ });
964
+ const selectDate = (date) => {
965
+ if (props.type === "default" && props.allowDeselect && isSameDate(_value.value, date)) setValue(null);
966
+ else setValue(getNextPickerValue(_value.value, date, props.type, props.sortDates));
967
+ };
968
+ const calendarDate = ref(void 0);
969
+ const calendarLevel = ref(void 0);
970
+ const selectPreset = (value) => {
971
+ const date = Array.isArray(value) ? value[0] : value;
972
+ if (date != null) {
973
+ calendarDate.value = date;
974
+ calendarLevel.value = "month";
975
+ }
976
+ setValue(value);
977
+ };
978
+ return () => {
979
+ const calendar = h(Calendar, {
980
+ ...attrs,
981
+ type: props.type,
982
+ value: _value.value,
983
+ date: calendarDate.value,
984
+ onDateChange: (date) => calendarDate.value = date,
985
+ level: calendarLevel.value,
986
+ onLevelChange: (level) => calendarLevel.value = level,
987
+ onDayClick: selectDate
988
+ });
989
+ if (!props.presets?.length) return calendar;
990
+ return h("div", { class: Dates_module_default.datePickerRoot }, [h("div", { class: Dates_module_default.presetsList }, props.presets.map((preset, index) => h(UnstyledButton, {
991
+ key: index,
992
+ class: Dates_module_default.presetButton,
993
+ onClick: () => selectPreset(preset.value),
994
+ onMousedown: (event) => event.preventDefault()
995
+ }, () => preset.label))), calendar]);
996
+ };
997
+ }
998
+ });
999
+ var YearPicker = defineComponent({
1000
+ name: "YearPicker",
1001
+ props: {
1002
+ type: {
1003
+ type: String,
1004
+ default: "default"
1005
+ },
1006
+ value: [
1007
+ String,
1008
+ Array,
1009
+ null
1010
+ ],
1011
+ defaultValue: [
1012
+ String,
1013
+ Array,
1014
+ null
1015
+ ],
1016
+ onChange: Function,
1017
+ allowDeselect: {
1018
+ type: Boolean,
1019
+ default: true
1020
+ },
1021
+ sortDates: {
1022
+ type: Boolean,
1023
+ default: true
1024
+ },
1025
+ presets: Array,
1026
+ onYearSelect: Function
1027
+ },
1028
+ setup(props, { attrs }) {
1029
+ const finalValue = computed(() => props.type === "multiple" ? [] : props.type === "range" ? [null, null] : null);
1030
+ const [_value, setValue] = useUncontrolled({
1031
+ value: computed(() => props.value),
1032
+ defaultValue: props.defaultValue,
1033
+ finalValue: finalValue.value,
1034
+ onChange: (value) => props.onChange?.(value)
1035
+ });
1036
+ const hoveredDate = ref(null);
1037
+ const selectYear = (date) => {
1038
+ if (props.type === "default" && props.allowDeselect && isSameDate(_value.value, date)) setValue(null);
1039
+ else setValue(getNextPickerValue(_value.value, date, props.type, props.sortDates));
1040
+ hoveredDate.value = null;
1041
+ props.onYearSelect?.(date);
1042
+ };
1043
+ const yearControlProps = (date) => {
1044
+ const external = attrs.getYearControlProps?.(date) || {};
1045
+ if (props.type !== "range" || !Array.isArray(_value.value)) return external;
1046
+ const [start, end] = _value.value;
1047
+ const hovered = start && !end ? hoveredDate.value : null;
1048
+ return {
1049
+ inRange: start && hovered ? isInRangeGranular(date, [hovered, start], "year") : start && end ? isInRangeGranular(date, [start, end], "year") : false,
1050
+ firstInRange: start ? dayjs(date).isSame(start, "year") && !(hovered && dayjs(hovered).isBefore(start, "year")) : false,
1051
+ lastInRange: end ? dayjs(date).isSame(end, "year") : !!(start && hovered && dayjs(hovered).isBefore(start, "year") && dayjs(date).isSame(start, "year")),
1052
+ ...external
1053
+ };
1054
+ };
1055
+ const calendarDate = ref(void 0);
1056
+ const selectPreset = (value) => {
1057
+ const date = Array.isArray(value) ? value[0] : value;
1058
+ if (date != null) calendarDate.value = date;
1059
+ setValue(value);
1060
+ };
1061
+ return () => {
1062
+ const calendar = h(Calendar, {
1063
+ ...attrs,
1064
+ type: props.type,
1065
+ value: _value.value,
1066
+ date: calendarDate.value,
1067
+ onDateChange: (date) => calendarDate.value = date,
1068
+ defaultLevel: "decade",
1069
+ minLevel: "decade",
1070
+ onYearSelect: selectYear,
1071
+ getYearControlProps: yearControlProps,
1072
+ onYearMouseEnter: (date) => {
1073
+ const [start, end] = Array.isArray(_value.value) ? _value.value : [null, null];
1074
+ if (props.type === "range" && start && !end) hoveredDate.value = date;
1075
+ },
1076
+ onMouseleave: () => {
1077
+ hoveredDate.value = null;
1078
+ }
1079
+ });
1080
+ if (!props.presets?.length) return calendar;
1081
+ return h("div", { class: Dates_module_default.datePickerRoot }, [h("div", { class: Dates_module_default.presetsList }, props.presets.map((preset, index) => h(UnstyledButton, {
1082
+ key: index,
1083
+ class: Dates_module_default.presetButton,
1084
+ onClick: () => selectPreset(preset.value),
1085
+ onMousedown: (event) => event.preventDefault()
1086
+ }, () => preset.label))), calendar]);
1087
+ };
1088
+ }
1089
+ });
1090
+ var MonthPicker = defineComponent({
1091
+ name: "MonthPicker",
1092
+ props: {
1093
+ type: {
1094
+ type: String,
1095
+ default: "default"
1096
+ },
1097
+ value: [
1098
+ String,
1099
+ Array,
1100
+ null
1101
+ ],
1102
+ defaultValue: [
1103
+ String,
1104
+ Array,
1105
+ null
1106
+ ],
1107
+ onChange: Function,
1108
+ allowDeselect: {
1109
+ type: Boolean,
1110
+ default: true
1111
+ },
1112
+ sortDates: {
1113
+ type: Boolean,
1114
+ default: true
1115
+ },
1116
+ presets: Array,
1117
+ onMonthSelect: Function
1118
+ },
1119
+ setup(props, { attrs }) {
1120
+ const finalValue = computed(() => props.type === "multiple" ? [] : props.type === "range" ? [null, null] : null);
1121
+ const [_value, setValue] = useUncontrolled({
1122
+ value: computed(() => props.value),
1123
+ defaultValue: props.defaultValue,
1124
+ finalValue: finalValue.value,
1125
+ onChange: (value) => props.onChange?.(value)
1126
+ });
1127
+ const hoveredDate = ref(null);
1128
+ const selectMonth = (date) => {
1129
+ if (props.type === "default" && props.allowDeselect && isSameDate(_value.value, date)) setValue(null);
1130
+ else setValue(getNextPickerValue(_value.value, date, props.type, props.sortDates));
1131
+ hoveredDate.value = null;
1132
+ props.onMonthSelect?.(date);
1133
+ };
1134
+ const monthControlProps = (date) => {
1135
+ const external = attrs.getMonthControlProps?.(date) || {};
1136
+ if (props.type !== "range" || !Array.isArray(_value.value)) return external;
1137
+ const [start, end] = _value.value;
1138
+ const hovered = start && !end ? hoveredDate.value : null;
1139
+ return {
1140
+ inRange: start && hovered ? isInRangeGranular(date, [hovered, start], "month") : start && end ? isInRangeGranular(date, [start, end], "month") : false,
1141
+ firstInRange: start ? dayjs(date).isSame(start, "month") && !(hovered && dayjs(hovered).isBefore(start, "month")) : false,
1142
+ lastInRange: end ? dayjs(date).isSame(end, "month") : !!(start && hovered && dayjs(hovered).isBefore(start, "month") && dayjs(date).isSame(start, "month")),
1143
+ ...external
1144
+ };
1145
+ };
1146
+ const calendarDate = ref(void 0);
1147
+ const selectPreset = (value) => {
1148
+ const date = Array.isArray(value) ? value[0] : value;
1149
+ if (date != null) calendarDate.value = date;
1150
+ setValue(value);
1151
+ };
1152
+ return () => {
1153
+ const calendar = h(Calendar, {
1154
+ ...attrs,
1155
+ type: props.type,
1156
+ value: _value.value,
1157
+ date: calendarDate.value,
1158
+ onDateChange: (date) => calendarDate.value = date,
1159
+ defaultLevel: "year",
1160
+ minLevel: "year",
1161
+ onMonthSelect: selectMonth,
1162
+ getMonthControlProps: monthControlProps,
1163
+ onMonthMouseEnter: (date) => {
1164
+ const [start, end] = Array.isArray(_value.value) ? _value.value : [null, null];
1165
+ if (props.type === "range" && start && !end) hoveredDate.value = date;
1166
+ },
1167
+ onMouseleave: () => {
1168
+ hoveredDate.value = null;
1169
+ }
1170
+ });
1171
+ if (!props.presets?.length) return calendar;
1172
+ return h("div", { class: Dates_module_default.datePickerRoot }, [h("div", { class: Dates_module_default.presetsList }, props.presets.map((preset, index) => h(UnstyledButton, {
1173
+ key: index,
1174
+ class: Dates_module_default.presetButton,
1175
+ onClick: () => selectPreset(preset.value),
1176
+ onMousedown: (event) => event.preventDefault()
1177
+ }, () => preset.label))), calendar]);
1178
+ };
1179
+ }
1180
+ });
1181
+ var PickerInputBase = defineComponent({
1182
+ name: "PickerInputBase",
1183
+ props: {
1184
+ formattedValue: {
1185
+ type: String,
1186
+ default: ""
1187
+ },
1188
+ dropdownOpened: Boolean,
1189
+ dropdownType: {
1190
+ type: String,
1191
+ default: "popover"
1192
+ },
1193
+ label: [
1194
+ String,
1195
+ Number,
1196
+ Object,
1197
+ Function
1198
+ ],
1199
+ placeholder: String,
1200
+ clearable: Boolean,
1201
+ disabled: Boolean,
1202
+ required: Boolean,
1203
+ error: [String, Boolean],
1204
+ size: {
1205
+ type: [String, Number],
1206
+ default: "sm"
1207
+ },
1208
+ variant: String,
1209
+ onClear: Function,
1210
+ onDropdownClose: Function,
1211
+ onDropdownOpen: Function
1212
+ },
1213
+ emits: ["click"],
1214
+ inheritAttrs: false,
1215
+ setup(props, { slots, emit, attrs }) {
1216
+ const opened = ref(props.dropdownOpened);
1217
+ watch(() => props.dropdownOpened, (value) => {
1218
+ opened.value = value;
1219
+ });
1220
+ const close = () => {
1221
+ opened.value = false;
1222
+ props.onDropdownClose?.();
1223
+ };
1224
+ const open = () => {
1225
+ if (!props.disabled) {
1226
+ opened.value = true;
1227
+ props.onDropdownOpen?.();
1228
+ }
1229
+ };
1230
+ const target = () => h(InputBase, {
1231
+ ...attrs,
1232
+ component: "button",
1233
+ type: "button",
1234
+ label: props.label,
1235
+ placeholder: props.placeholder,
1236
+ disabled: props.disabled,
1237
+ required: props.required,
1238
+ error: props.error,
1239
+ pointer: true,
1240
+ size: props.size,
1241
+ variant: props.variant,
1242
+ rightSection: props.clearable && props.formattedValue ? h(CloseButton, {
1243
+ size: props.size,
1244
+ onMousedown: (event) => event.stopPropagation(),
1245
+ onClick: (event) => {
1246
+ event.stopPropagation();
1247
+ props.onClear?.();
1248
+ }
1249
+ }) : void 0,
1250
+ rightSectionPointerEvents: props.clearable && props.formattedValue ? "all" : void 0,
1251
+ onClick: (event) => {
1252
+ emit("click", event);
1253
+ open();
1254
+ }
1255
+ }, () => props.formattedValue ? h("span", props.formattedValue) : h("span", { class: Dates_module_default.placeholder }, props.placeholder));
1256
+ return () => props.dropdownType === "modal" ? h(Box, null, () => [target(), h(Modal, {
1257
+ opened: opened.value,
1258
+ onClose: close,
1259
+ title: props.label,
1260
+ size: "auto"
1261
+ }, () => slots.default?.({ close }))]) : h(Popover, {
1262
+ opened: opened.value,
1263
+ onChange: (value) => value ? open() : close(),
1264
+ position: "bottom-start",
1265
+ trapFocus: true,
1266
+ returnFocus: false
1267
+ }, () => [h(Popover.Target, null, target), h(Popover.Dropdown, { class: Dates_module_default.dropdown }, () => slots.default?.({ close }))]);
1268
+ }
1269
+ });
1270
+ function createPickerInput(name, Picker, defaultLevel, defaultValueFormat = "MMMM D, YYYY") {
1271
+ return defineComponent({
1272
+ name,
1273
+ props: {
1274
+ type: {
1275
+ type: String,
1276
+ default: "default"
1277
+ },
1278
+ value: [
1279
+ String,
1280
+ Array,
1281
+ null
1282
+ ],
1283
+ defaultValue: [
1284
+ String,
1285
+ Array,
1286
+ null
1287
+ ],
1288
+ onChange: Function,
1289
+ valueFormat: {
1290
+ type: String,
1291
+ default: defaultValueFormat
1292
+ },
1293
+ labelSeparator: {
1294
+ type: String,
1295
+ default: "–"
1296
+ },
1297
+ locale: String,
1298
+ placeholder: String,
1299
+ label: [
1300
+ String,
1301
+ Number,
1302
+ Object,
1303
+ Function
1304
+ ],
1305
+ clearable: Boolean,
1306
+ closeOnChange: {
1307
+ type: Boolean,
1308
+ default: true
1309
+ },
1310
+ sortDates: {
1311
+ type: Boolean,
1312
+ default: true
1313
+ },
1314
+ valueFormatter: Function
1315
+ },
1316
+ setup(props, { attrs }) {
1317
+ const finalValue = computed(() => props.type === "multiple" ? [] : props.type === "range" ? [null, null] : null);
1318
+ const [_value, setValue] = useUncontrolled({
1319
+ value: computed(() => props.value),
1320
+ defaultValue: props.defaultValue,
1321
+ finalValue: finalValue.value,
1322
+ onChange: (value) => props.onChange?.(value)
1323
+ });
1324
+ const opened = ref(false);
1325
+ const formattedValue = computed(() => formatValue(_value.value, props.type, props.valueFormat, props.locale, props.labelSeparator, props.valueFormatter));
1326
+ return () => h(PickerInputBase, {
1327
+ ...attrs,
1328
+ formattedValue: formattedValue.value,
1329
+ dropdownOpened: opened.value,
1330
+ label: props.label,
1331
+ placeholder: props.placeholder,
1332
+ clearable: props.clearable,
1333
+ onDropdownOpen: () => opened.value = true,
1334
+ onDropdownClose: () => opened.value = false,
1335
+ onClear: () => setValue(finalValue.value)
1336
+ }, { default: ({ close }) => h(Picker, {
1337
+ ...attrs,
1338
+ type: props.type,
1339
+ value: _value.value,
1340
+ sortDates: props.sortDates,
1341
+ defaultLevel,
1342
+ locale: props.locale,
1343
+ onChange: (value) => {
1344
+ setValue(value);
1345
+ if (props.closeOnChange && props.type === "default") close();
1346
+ }
1347
+ }) });
1348
+ }
1349
+ });
1350
+ }
1351
+ var DatePickerInput = createPickerInput("DatePickerInput", DatePicker);
1352
+ var MonthPickerInput = createPickerInput("MonthPickerInput", MonthPicker, "year", "MMMM YYYY");
1353
+ var YearPickerInput = createPickerInput("YearPickerInput", YearPicker, "decade", "YYYY");
1354
+ var HiddenDatesInput = defineComponent({
1355
+ name: "HiddenDatesInput",
1356
+ props: {
1357
+ name: String,
1358
+ value: [
1359
+ String,
1360
+ Array,
1361
+ null
1362
+ ]
1363
+ },
1364
+ setup(props) {
1365
+ return () => {
1366
+ const value = Array.isArray(props.value) ? props.value.filter(Boolean).join(",") : props.value || "";
1367
+ return h("input", {
1368
+ type: "hidden",
1369
+ name: props.name,
1370
+ value
1371
+ });
1372
+ };
1373
+ }
1374
+ });
1375
+ function dateStringParser(value, format = "MMMM D, YYYY", locale) {
1376
+ return dayjs(value, format, locale || "en", true).format("YYYY-MM-DD");
1377
+ }
1378
+ function isDateValid({ date, minDate, maxDate }) {
1379
+ const parsed = dayjs(date);
1380
+ return parsed.isValid() && !isBeforeMin(parsed.format("YYYY-MM-DD"), minDate) && !isAfterMax(parsed.format("YYYY-MM-DD"), maxDate);
1381
+ }
1382
+ var DateInput = defineComponent({
1383
+ name: "DateInput",
1384
+ inheritAttrs: false,
1385
+ props: {
1386
+ value: [
1387
+ String,
1388
+ Date,
1389
+ null
1390
+ ],
1391
+ defaultValue: [
1392
+ String,
1393
+ Date,
1394
+ null
1395
+ ],
1396
+ onChange: Function,
1397
+ valueFormat: {
1398
+ type: String,
1399
+ default: "MMMM D, YYYY"
1400
+ },
1401
+ dateParser: Function,
1402
+ locale: String,
1403
+ clearable: Boolean,
1404
+ minDate: [String, Date],
1405
+ maxDate: [String, Date],
1406
+ presets: Array
1407
+ },
1408
+ setup(props, { attrs }) {
1409
+ const [_value, setValue] = useUncontrolled({
1410
+ value: computed(() => props.value === void 0 ? void 0 : normalizeDate(props.value)),
1411
+ defaultValue: normalizeDate(props.defaultValue),
1412
+ finalValue: null,
1413
+ onChange: (value) => props.onChange?.(value)
1414
+ });
1415
+ const formatValue = (value) => value ? dayjs(value).locale(props.locale || "en").format(props.valueFormat) : "";
1416
+ const inputValue = ref(formatValue(_value.value));
1417
+ const opened = ref(false);
1418
+ watch(_value, (value) => {
1419
+ if (!opened.value) inputValue.value = formatValue(value);
1420
+ });
1421
+ const parseInput = (raw) => {
1422
+ const parsed = props.dateParser?.(raw) || dateStringParser(raw, props.valueFormat, props.locale);
1423
+ return dayjs(parsed).isValid() && isDateValid({
1424
+ date: parsed,
1425
+ minDate: props.minDate,
1426
+ maxDate: props.maxDate
1427
+ }) ? parsed : null;
1428
+ };
1429
+ const commit = () => {
1430
+ opened.value = false;
1431
+ if (!inputValue.value.trim()) {
1432
+ if (props.clearable) setValue(null);
1433
+ else inputValue.value = formatValue(_value.value);
1434
+ return;
1435
+ }
1436
+ const parsed = parseInput(inputValue.value);
1437
+ if (parsed) setValue(parsed);
1438
+ else inputValue.value = formatValue(_value.value);
1439
+ };
1440
+ const selectDay = (date) => {
1441
+ setValue(date);
1442
+ inputValue.value = formatValue(date);
1443
+ opened.value = false;
1444
+ };
1445
+ return () => h(Box, null, () => h(Popover, {
1446
+ opened: opened.value,
1447
+ onChange: (v) => opened.value = v,
1448
+ position: "bottom-start"
1449
+ }, () => [h(Popover.Target, null, () => h(InputBase, {
1450
+ ...attrs,
1451
+ value: inputValue.value,
1452
+ onInput: (event) => inputValue.value = event.target.value,
1453
+ onFocus: () => opened.value = true,
1454
+ onClick: () => opened.value = true,
1455
+ onBlur: commit,
1456
+ onKeydown: (event) => {
1457
+ if (event.key === "Escape") opened.value = false;
1458
+ },
1459
+ rightSection: props.clearable && _value.value ? h(CloseButton, {
1460
+ onMousedown: (event) => event.stopPropagation(),
1461
+ onClick: (event) => {
1462
+ event.stopPropagation();
1463
+ inputValue.value = "";
1464
+ setValue(null);
1465
+ }
1466
+ }) : void 0,
1467
+ rightSectionPointerEvents: props.clearable && _value.value ? "all" : void 0
1468
+ })), h(Popover.Dropdown, { onMousedown: (event) => event.preventDefault() }, () => [props.presets?.length ? h(Group, {
1469
+ gap: 4,
1470
+ mb: 4
1471
+ }, () => props.presets?.map((preset, index) => h(Button, {
1472
+ key: index,
1473
+ size: "xs",
1474
+ variant: "light",
1475
+ onClick: () => selectDay(preset.value)
1476
+ }, () => preset.label))) : null, h(Calendar, {
1477
+ defaultDate: _value.value || void 0,
1478
+ minDate: props.minDate,
1479
+ maxDate: props.maxDate,
1480
+ locale: props.locale,
1481
+ getDayProps: (date) => ({
1482
+ selected: isSameDate(date, _value.value),
1483
+ onClick: () => selectDay(date)
1484
+ })
1485
+ })])]));
1486
+ }
1487
+ });
1488
+ function splitTimeString(value = "") {
1489
+ const [time = "", period] = value.split(" ");
1490
+ const [hours = "00", minutes = "00", seconds = "00"] = time.split(":");
1491
+ return {
1492
+ hours,
1493
+ minutes,
1494
+ seconds,
1495
+ period
1496
+ };
1497
+ }
1498
+ function padTime(value) {
1499
+ return String(value).padStart(2, "0");
1500
+ }
1501
+ var defaultAmPmLabels = {
1502
+ am: "AM",
1503
+ pm: "PM"
1504
+ };
1505
+ function getParsedTime({ time, format, amPmLabels = defaultAmPmLabels }) {
1506
+ if (!time) return {
1507
+ hours: null,
1508
+ minutes: null,
1509
+ seconds: null,
1510
+ amPm: null
1511
+ };
1512
+ const { hours, minutes, seconds } = splitTimeString(time);
1513
+ const h24 = Number(hours);
1514
+ const m = Number(minutes);
1515
+ const s = Number(seconds);
1516
+ if (format === "12h") {
1517
+ const amPm = h24 >= 12 ? amPmLabels.pm : amPmLabels.am;
1518
+ return {
1519
+ hours: h24 % 12 === 0 ? 12 : h24 % 12,
1520
+ minutes: m,
1521
+ seconds: s,
1522
+ amPm
1523
+ };
1524
+ }
1525
+ return {
1526
+ hours: h24,
1527
+ minutes: m,
1528
+ seconds: s,
1529
+ amPm: null
1530
+ };
1531
+ }
1532
+ function getTimeString({ hours, minutes, seconds, format = "24h", withSeconds = false, amPm = null, amPmLabels = defaultAmPmLabels }) {
1533
+ if (hours === null || minutes === null) return {
1534
+ valid: false,
1535
+ value: ""
1536
+ };
1537
+ if (withSeconds && (seconds === null || seconds === void 0)) return {
1538
+ valid: false,
1539
+ value: ""
1540
+ };
1541
+ if (format === "24h") return {
1542
+ valid: true,
1543
+ value: `${padTime(hours)}:${padTime(minutes)}${withSeconds ? `:${padTime(seconds || 0)}` : ""}`
1544
+ };
1545
+ if (amPm === null) return {
1546
+ valid: false,
1547
+ value: ""
1548
+ };
1549
+ let h24 = hours;
1550
+ if (amPm === amPmLabels.pm && hours !== 12) h24 += 12;
1551
+ else if (amPm === amPmLabels.am && hours === 12) h24 = 0;
1552
+ return {
1553
+ valid: true,
1554
+ value: `${padTime(h24)}:${padTime(minutes)}${withSeconds ? `:${padTime(seconds || 0)}` : ""}`
1555
+ };
1556
+ }
1557
+ function timeToSeconds(value) {
1558
+ const { hours, minutes, seconds } = splitTimeString(value);
1559
+ return Number(hours) * 3600 + Number(minutes) * 60 + Number(seconds || 0);
1560
+ }
1561
+ function isSameTime(a, b) {
1562
+ return !!a && !!b && timeToSeconds(a) === timeToSeconds(b);
1563
+ }
1564
+ function compareTime(a, b) {
1565
+ return timeToSeconds(a) - timeToSeconds(b);
1566
+ }
1567
+ function clampTime(value, min, max) {
1568
+ if (min && compareTime(value, min) < 0) return min;
1569
+ if (max && compareTime(value, max) > 0) return max;
1570
+ return value;
1571
+ }
1572
+ function getTimeRange(start, end, step = 60) {
1573
+ const result = [];
1574
+ for (let current = timeToSeconds(start); current <= timeToSeconds(end); current += step) {
1575
+ const hours = Math.floor(current / 3600);
1576
+ const minutes = Math.floor(current % 3600 / 60);
1577
+ result.push(`${padTime(hours)}:${padTime(minutes)}`);
1578
+ }
1579
+ return result;
1580
+ }
1581
+ var TimeInput = defineComponent({
1582
+ name: "TimeInput",
1583
+ props: {
1584
+ withSeconds: Boolean,
1585
+ value: String,
1586
+ defaultValue: String,
1587
+ onChange: Function
1588
+ },
1589
+ setup(props, { attrs }) {
1590
+ return () => h(InputBase, {
1591
+ ...attrs,
1592
+ type: "time",
1593
+ step: props.withSeconds ? 1 : 60,
1594
+ value: props.value,
1595
+ defaultValue: props.defaultValue,
1596
+ onChange: props.onChange
1597
+ });
1598
+ }
1599
+ });
1600
+ var TimeGrid = defineComponent({
1601
+ name: "TimeGrid",
1602
+ props: {
1603
+ data: {
1604
+ type: Array,
1605
+ default: () => []
1606
+ },
1607
+ value: String,
1608
+ defaultValue: String,
1609
+ minTime: String,
1610
+ maxTime: String,
1611
+ allowDeselect: Boolean,
1612
+ disabled: Boolean,
1613
+ onChange: Function,
1614
+ getControlProps: Function
1615
+ },
1616
+ setup(props, { attrs }) {
1617
+ const [_value, setValue] = useUncontrolled({
1618
+ value: computed(() => props.value),
1619
+ defaultValue: props.defaultValue,
1620
+ finalValue: null,
1621
+ onChange: (value) => props.onChange?.(value)
1622
+ });
1623
+ return () => h(Box, {
1624
+ ...attrs,
1625
+ class: [Dates_module_default.timeGridRoot, attrs.class]
1626
+ }, () => h(SimpleGrid, {
1627
+ cols: 3,
1628
+ spacing: "xs",
1629
+ class: Dates_module_default.timeGrid
1630
+ }, () => props.data.map((item) => {
1631
+ const isDisabled = props.disabled || props.minTime && compareTime(item, props.minTime) < 0 || props.maxTime && compareTime(item, props.maxTime) > 0;
1632
+ const controlProps = props.getControlProps?.(item) || {};
1633
+ const active = isSameTime(_value.value ?? void 0, item);
1634
+ return h(UnstyledButton, {
1635
+ ...controlProps,
1636
+ class: [Dates_module_default.timeGridControl, controlProps.class],
1637
+ disabled: isDisabled || controlProps.disabled,
1638
+ "data-active": active || void 0,
1639
+ "data-disabled": isDisabled || controlProps.disabled || void 0,
1640
+ onClick: (event) => {
1641
+ controlProps.onClick?.(event);
1642
+ if (isDisabled) return;
1643
+ const nextValue = props.allowDeselect && active ? null : item;
1644
+ if (nextValue !== _value.value) setValue(nextValue);
1645
+ }
1646
+ }, () => item);
1647
+ })));
1648
+ }
1649
+ });
1650
+ var SpinInput = defineComponent({
1651
+ name: "SpinInput",
1652
+ inheritAttrs: false,
1653
+ props: {
1654
+ value: {
1655
+ type: Number,
1656
+ default: null
1657
+ },
1658
+ min: {
1659
+ type: Number,
1660
+ required: true
1661
+ },
1662
+ max: {
1663
+ type: Number,
1664
+ required: true
1665
+ },
1666
+ onChange: Function,
1667
+ step: {
1668
+ type: Number,
1669
+ default: 1
1670
+ },
1671
+ onNextInput: Function,
1672
+ onPreviousInput: Function,
1673
+ allowTemporaryZero: Boolean,
1674
+ placeholder: {
1675
+ type: String,
1676
+ default: "--"
1677
+ },
1678
+ disableAutoAdvance: Boolean,
1679
+ disabled: Boolean,
1680
+ readOnly: Boolean
1681
+ },
1682
+ setup(props, { attrs }) {
1683
+ const maxDigit = () => Number(props.max.toFixed(0)[0]);
1684
+ const arrowsMax = () => props.max + 1 - props.step;
1685
+ const handleChange = (raw) => {
1686
+ if (props.readOnly) return;
1687
+ const clearValue = raw.replace(/\D/g, "");
1688
+ if (clearValue === "") return;
1689
+ let parsedValue = 0;
1690
+ for (let i = 0; i < clearValue.length; i += 1) {
1691
+ const digit = clearValue.charCodeAt(i) - 48;
1692
+ const next = parsedValue * 10 + digit;
1693
+ parsedValue = next > props.max ? digit : next;
1694
+ }
1695
+ const clampedValue = props.allowTemporaryZero && parsedValue === 0 && props.min > 0 ? 0 : Math.min(Math.max(parsedValue, props.min), props.max);
1696
+ props.onChange?.(clampedValue);
1697
+ if (!props.disableAutoAdvance && (clampedValue > maxDigit() || raw.startsWith("00"))) props.onNextInput?.();
1698
+ };
1699
+ const handleKeydown = (event) => {
1700
+ if (props.readOnly) return;
1701
+ if (event.key === "0" && props.value === 0) {
1702
+ event.preventDefault();
1703
+ props.onNextInput?.();
1704
+ }
1705
+ if (event.key === "Home") {
1706
+ event.preventDefault();
1707
+ props.onChange?.(props.min);
1708
+ }
1709
+ if (event.key === "End") {
1710
+ event.preventDefault();
1711
+ props.onChange?.(props.max);
1712
+ }
1713
+ if (event.key === "Backspace" || event.key === "Delete") {
1714
+ event.preventDefault();
1715
+ if (props.value !== null) props.onChange?.(null);
1716
+ else props.onPreviousInput?.();
1717
+ }
1718
+ if (event.key === "ArrowRight") {
1719
+ event.preventDefault();
1720
+ props.onNextInput?.();
1721
+ }
1722
+ if (event.key === "ArrowLeft") {
1723
+ event.preventDefault();
1724
+ props.onPreviousInput?.();
1725
+ }
1726
+ if (event.key === "ArrowUp") {
1727
+ event.preventDefault();
1728
+ const newValue = props.value === null ? props.min : Math.min(Math.max(props.value + props.step, props.min), arrowsMax());
1729
+ props.onChange?.(newValue);
1730
+ }
1731
+ if (event.key === "ArrowDown") {
1732
+ event.preventDefault();
1733
+ const newValue = props.value === null ? arrowsMax() : Math.min(Math.max(props.value - props.step, props.min), arrowsMax());
1734
+ props.onChange?.(newValue);
1735
+ }
1736
+ };
1737
+ return () => h("input", {
1738
+ ...attrs,
1739
+ type: "text",
1740
+ role: "spinbutton",
1741
+ "aria-valuemin": props.min,
1742
+ "aria-valuemax": props.max,
1743
+ "aria-valuenow": props.value === null ? 0 : props.value,
1744
+ "data-empty": props.value === null || void 0,
1745
+ inputmode: "numeric",
1746
+ placeholder: props.placeholder,
1747
+ disabled: props.disabled,
1748
+ readonly: props.readOnly,
1749
+ value: props.value === null ? "" : padTime(props.value),
1750
+ onInput: (event) => handleChange(event.target.value),
1751
+ onKeydown: handleKeydown,
1752
+ onFocus: (event) => event.target.select(),
1753
+ onClick: (event) => {
1754
+ event.stopPropagation();
1755
+ event.target.select();
1756
+ },
1757
+ onMousedown: (event) => event.stopPropagation()
1758
+ });
1759
+ }
1760
+ });
1761
+ var AmPmInput = defineComponent({
1762
+ name: "AmPmInput",
1763
+ props: {
1764
+ value: {
1765
+ type: String,
1766
+ default: null
1767
+ },
1768
+ labels: {
1769
+ type: Object,
1770
+ default: () => defaultAmPmLabels
1771
+ },
1772
+ onChange: Function,
1773
+ disabled: Boolean,
1774
+ readOnly: Boolean
1775
+ },
1776
+ setup(props, { attrs }) {
1777
+ return () => h("select", {
1778
+ ...attrs,
1779
+ class: Dates_module_default.timePickerField,
1780
+ "data-am-pm": true,
1781
+ disabled: props.disabled,
1782
+ value: props.value ?? props.labels.am,
1783
+ onChange: (event) => props.onChange?.(event.target.value)
1784
+ }, [h("option", { value: props.labels.am }, props.labels.am), h("option", { value: props.labels.pm }, props.labels.pm)]);
1785
+ }
1786
+ });
1787
+ var TimeControlsList = defineComponent({
1788
+ name: "TimeControlsList",
1789
+ props: {
1790
+ min: {
1791
+ type: Number,
1792
+ required: true
1793
+ },
1794
+ max: {
1795
+ type: Number,
1796
+ required: true
1797
+ },
1798
+ step: {
1799
+ type: Number,
1800
+ default: 1
1801
+ },
1802
+ value: {
1803
+ type: Number,
1804
+ default: null
1805
+ },
1806
+ onSelect: Function,
1807
+ formatValue: Function
1808
+ },
1809
+ setup(props) {
1810
+ return () => h(ScrollArea, { h: 200 }, () => h("div", { class: Dates_module_default.timePickerControlsList }, Array.from({ length: Math.floor((props.max - props.min) / props.step) + 1 }, (_, index) => props.min + index * props.step).map((item) => h(UnstyledButton, {
1811
+ key: item,
1812
+ class: Dates_module_default.timePickerControl,
1813
+ "data-active": item === props.value || void 0,
1814
+ onClick: () => props.onSelect?.(item)
1815
+ }, () => props.formatValue ? props.formatValue(item) : padTime(item)))));
1816
+ }
1817
+ });
1818
+ var TimePicker = defineComponent({
1819
+ name: "TimePicker",
1820
+ props: {
1821
+ value: String,
1822
+ defaultValue: String,
1823
+ onChange: Function,
1824
+ withSeconds: Boolean,
1825
+ min: String,
1826
+ max: String,
1827
+ format: {
1828
+ type: String,
1829
+ default: "24h"
1830
+ },
1831
+ amPmLabels: {
1832
+ type: Object,
1833
+ default: () => defaultAmPmLabels
1834
+ },
1835
+ hoursStep: {
1836
+ type: Number,
1837
+ default: 1
1838
+ },
1839
+ minutesStep: {
1840
+ type: Number,
1841
+ default: 1
1842
+ },
1843
+ secondsStep: {
1844
+ type: Number,
1845
+ default: 1
1846
+ },
1847
+ clearable: Boolean,
1848
+ withDropdown: Boolean,
1849
+ disabled: Boolean,
1850
+ readOnly: Boolean,
1851
+ size: {
1852
+ type: [String, Number],
1853
+ default: "sm"
1854
+ },
1855
+ presets: Array,
1856
+ hoursRef: Object
1857
+ },
1858
+ setup(props, { attrs }) {
1859
+ const [_value, setValue] = useUncontrolled({
1860
+ value: computed(() => props.value),
1861
+ defaultValue: props.defaultValue,
1862
+ finalValue: "",
1863
+ onChange: (value) => props.onChange?.(value)
1864
+ });
1865
+ const parsed = computed(() => getParsedTime({
1866
+ time: _value.value,
1867
+ format: props.format,
1868
+ amPmLabels: props.amPmLabels
1869
+ }));
1870
+ const hours = ref(parsed.value.hours);
1871
+ const minutes = ref(parsed.value.minutes);
1872
+ const seconds = ref(parsed.value.seconds);
1873
+ const amPm = ref(parsed.value.amPm);
1874
+ watch(_value, (value) => {
1875
+ const next = getParsedTime({
1876
+ time: value,
1877
+ format: props.format,
1878
+ amPmLabels: props.amPmLabels
1879
+ });
1880
+ hours.value = next.hours;
1881
+ minutes.value = next.minutes;
1882
+ seconds.value = next.seconds;
1883
+ amPm.value = next.amPm;
1884
+ });
1885
+ const hoursRef = ref();
1886
+ const minutesRef = ref();
1887
+ const secondsRef = ref();
1888
+ const amPmRef = ref();
1889
+ const focusRef = (target) => {
1890
+ (target?.$el ?? target)?.focus?.();
1891
+ };
1892
+ const focus = (field) => {
1893
+ focusRef((field === "hours" ? hoursRef : field === "minutes" ? minutesRef : field === "seconds" ? secondsRef : amPmRef).value);
1894
+ };
1895
+ watch(hoursRef, (val) => {
1896
+ if (props.hoursRef) props.hoursRef.value = val?.$el ?? val;
1897
+ }, { immediate: true });
1898
+ const commit = () => {
1899
+ const result = getTimeString({
1900
+ hours: hours.value,
1901
+ minutes: minutes.value,
1902
+ seconds: seconds.value,
1903
+ format: props.format,
1904
+ withSeconds: props.withSeconds,
1905
+ amPm: amPm.value,
1906
+ amPmLabels: props.amPmLabels
1907
+ });
1908
+ setValue(result.valid ? result.value : "");
1909
+ };
1910
+ const setHours = (value) => {
1911
+ let adjusted = value;
1912
+ if (props.format === "12h" && typeof value === "number" && value > 12) adjusted = (value - 1) % 12 + 1;
1913
+ hours.value = adjusted;
1914
+ commit();
1915
+ focus("hours");
1916
+ };
1917
+ const setMinutes = (value) => {
1918
+ minutes.value = value;
1919
+ commit();
1920
+ focus("minutes");
1921
+ };
1922
+ const setSeconds = (value) => {
1923
+ seconds.value = value;
1924
+ commit();
1925
+ focus("seconds");
1926
+ };
1927
+ const setAmPm = (value) => {
1928
+ amPm.value = value;
1929
+ commit();
1930
+ focus("amPm");
1931
+ };
1932
+ const clear = () => {
1933
+ hours.value = null;
1934
+ minutes.value = null;
1935
+ seconds.value = null;
1936
+ amPm.value = null;
1937
+ setValue("");
1938
+ focus("hours");
1939
+ };
1940
+ const isClearable = computed(() => props.clearable && !props.readOnly && !props.disabled && (hours.value !== null || minutes.value !== null || seconds.value !== null || amPm.value !== null));
1941
+ const opened = ref(false);
1942
+ return () => h(Popover, {
1943
+ opened: props.withDropdown && opened.value,
1944
+ position: "bottom-start",
1945
+ transitionProps: { duration: 0 }
1946
+ }, () => [h(Popover.Target, null, () => h(InputBase, {
1947
+ ...attrs,
1948
+ component: "div",
1949
+ size: props.size,
1950
+ disabled: props.disabled,
1951
+ onClick: () => {
1952
+ focus("hours");
1953
+ if (props.withDropdown) opened.value = true;
1954
+ },
1955
+ onMousedown: (event) => event.preventDefault(),
1956
+ onFocusin: () => {
1957
+ if (props.withDropdown) opened.value = true;
1958
+ },
1959
+ onFocusout: () => {
1960
+ if (props.withDropdown) opened.value = false;
1961
+ },
1962
+ rightSection: isClearable.value ? h(CloseButton, {
1963
+ size: props.size,
1964
+ onMousedown: (event) => event.preventDefault(),
1965
+ onClick: clear
1966
+ }) : void 0,
1967
+ rightSectionPointerEvents: isClearable.value ? "all" : void 0
1968
+ }, () => [h("div", {
1969
+ class: Dates_module_default.timePickerFieldsRoot,
1970
+ dir: "ltr"
1971
+ }, [h("div", { class: Dates_module_default.timePickerFieldsGroup }, [
1972
+ h(SpinInput, {
1973
+ ref: hoursRef,
1974
+ class: Dates_module_default.timePickerField,
1975
+ value: hours.value,
1976
+ min: props.format === "12h" ? 1 : 0,
1977
+ max: props.format === "12h" ? 12 : 23,
1978
+ step: props.hoursStep,
1979
+ onChange: setHours,
1980
+ onNextInput: () => focus("minutes"),
1981
+ allowTemporaryZero: props.format === "12h",
1982
+ readOnly: props.readOnly,
1983
+ disabled: props.disabled,
1984
+ placeholder: "--"
1985
+ }),
1986
+ h("span", ":"),
1987
+ h(SpinInput, {
1988
+ ref: minutesRef,
1989
+ class: Dates_module_default.timePickerField,
1990
+ value: minutes.value,
1991
+ min: 0,
1992
+ max: 59,
1993
+ step: props.minutesStep,
1994
+ onChange: setMinutes,
1995
+ onPreviousInput: () => focus("hours"),
1996
+ onNextInput: () => focus(props.withSeconds ? "seconds" : "amPm"),
1997
+ readOnly: props.readOnly,
1998
+ disabled: props.disabled,
1999
+ placeholder: "--"
2000
+ }),
2001
+ props.withSeconds ? h("span", ":") : null,
2002
+ props.withSeconds ? h(SpinInput, {
2003
+ ref: secondsRef,
2004
+ class: Dates_module_default.timePickerField,
2005
+ value: seconds.value,
2006
+ min: 0,
2007
+ max: 59,
2008
+ step: props.secondsStep,
2009
+ onChange: setSeconds,
2010
+ onPreviousInput: () => focus("minutes"),
2011
+ onNextInput: () => focus("amPm"),
2012
+ readOnly: props.readOnly,
2013
+ disabled: props.disabled,
2014
+ placeholder: "--"
2015
+ }) : null,
2016
+ props.format === "12h" ? h(AmPmInput, {
2017
+ ref: amPmRef,
2018
+ value: amPm.value,
2019
+ labels: props.amPmLabels,
2020
+ onChange: setAmPm,
2021
+ readOnly: props.readOnly,
2022
+ disabled: props.disabled
2023
+ }) : null
2024
+ ])])])), h(Popover.Dropdown, {
2025
+ class: Dates_module_default.timePickerDropdown,
2026
+ onMousedown: (event) => event.preventDefault()
2027
+ }, () => [props.presets?.length ? h(Group, {
2028
+ gap: 4,
2029
+ class: Dates_module_default.timePickerPresetsGroup
2030
+ }, () => props.presets?.map((preset) => h(Button, {
2031
+ size: "xs",
2032
+ variant: "light",
2033
+ onClick: () => setValue(preset.value)
2034
+ }, () => preset.label))) : h("div", { class: Dates_module_default.timePickerControlsListGroup }, [
2035
+ h(TimeControlsList, {
2036
+ min: props.format === "12h" ? 1 : 0,
2037
+ max: props.format === "12h" ? 12 : 23,
2038
+ step: props.hoursStep,
2039
+ value: hours.value,
2040
+ onSelect: setHours
2041
+ }),
2042
+ h(TimeControlsList, {
2043
+ min: 0,
2044
+ max: 59,
2045
+ step: props.minutesStep,
2046
+ value: minutes.value,
2047
+ onSelect: setMinutes
2048
+ }),
2049
+ props.withSeconds ? h(TimeControlsList, {
2050
+ min: 0,
2051
+ max: 59,
2052
+ step: props.secondsStep,
2053
+ value: seconds.value,
2054
+ onSelect: setSeconds
2055
+ }) : null
2056
+ ])])]);
2057
+ }
2058
+ });
2059
+ var TimeValue = defineComponent({
2060
+ name: "TimeValue",
2061
+ props: {
2062
+ value: {
2063
+ type: [String, Date],
2064
+ required: true
2065
+ },
2066
+ format: {
2067
+ type: String,
2068
+ default: "HH:mm"
2069
+ },
2070
+ locale: String
2071
+ },
2072
+ setup(props, { attrs }) {
2073
+ return () => h(Text, attrs, () => (props.value instanceof Date ? dayjs(props.value) : dayjs(`2024-01-01 ${props.value}`)).locale(props.locale || "en").format(props.format));
2074
+ }
2075
+ });
2076
+ var DateTimePicker = defineComponent({
2077
+ name: "DateTimePicker",
2078
+ props: {
2079
+ value: [
2080
+ String,
2081
+ Date,
2082
+ null
2083
+ ],
2084
+ defaultValue: [
2085
+ String,
2086
+ Date,
2087
+ null
2088
+ ],
2089
+ onChange: Function,
2090
+ valueFormat: {
2091
+ type: String,
2092
+ default: "MMMM D, YYYY h:mm A"
2093
+ },
2094
+ clearable: Boolean,
2095
+ withSeconds: Boolean,
2096
+ size: {
2097
+ type: [String, Number],
2098
+ default: "sm"
2099
+ },
2100
+ submitButtonProps: Object
2101
+ },
2102
+ setup(props, { attrs }) {
2103
+ const hoursRef = ref();
2104
+ const [_value, setValue] = useUncontrolled({
2105
+ value: computed(() => props.value === void 0 ? void 0 : props.value === null ? null : new Date(props.value)),
2106
+ defaultValue: props.defaultValue ? new Date(props.defaultValue) : null,
2107
+ finalValue: null,
2108
+ onChange: (value) => props.onChange?.(value)
2109
+ });
2110
+ const date = computed(() => _value.value ? dayjs(_value.value).format("YYYY-MM-DD") : null);
2111
+ const time = computed(() => _value.value ? dayjs(_value.value).format(props.withSeconds ? "HH:mm:ss" : "HH:mm") : "");
2112
+ const updateDate = (nextDate) => {
2113
+ if (!nextDate || Array.isArray(nextDate)) return;
2114
+ setValue(assignTime(nextDate, `2024-01-01 ${time.value || "00:00"}`));
2115
+ hoursRef.value?.focus?.();
2116
+ };
2117
+ const updateTime = (nextTime) => {
2118
+ if (date.value) setValue(assignTime(date.value, `2024-01-01 ${nextTime}`));
2119
+ };
2120
+ return () => h(PickerInputBase, {
2121
+ ...attrs,
2122
+ formattedValue: _value.value ? dayjs(_value.value).format(props.valueFormat) : "",
2123
+ clearable: props.clearable,
2124
+ onClear: () => setValue(null)
2125
+ }, { default: ({ close }) => h("div", { class: Dates_module_default.dateTimePicker }, [h(DatePicker, {
2126
+ fullWidth: false,
2127
+ value: date.value,
2128
+ onChange: updateDate
2129
+ }), h("div", { class: Dates_module_default.timeWrapper }, [h("div", { class: Dates_module_default.timeInput }, [h(TimePicker, {
2130
+ value: time.value,
2131
+ withSeconds: props.withSeconds,
2132
+ size: props.size,
2133
+ hoursRef,
2134
+ onChange: updateTime
2135
+ })]), h(ActionIcon, {
2136
+ variant: "default",
2137
+ size: `input-${props.size || "sm"}`,
2138
+ "data-mantine-stop-propagation": true,
2139
+ ...props.submitButtonProps,
2140
+ onClick: (event) => {
2141
+ props.submitButtonProps?.onClick?.(event);
2142
+ close();
2143
+ }
2144
+ }, () => h(CheckIcon, { size: "30%" }))])]) });
2145
+ }
2146
+ });
2147
+ var InlineDateTimePicker = DateTimePicker;
2148
+ var MiniCalendar = defineComponent({
2149
+ name: "MiniCalendar",
2150
+ props: {
2151
+ date: [String, Date],
2152
+ defaultDate: [String, Date],
2153
+ onDateChange: Function,
2154
+ value: [
2155
+ String,
2156
+ Date,
2157
+ null
2158
+ ],
2159
+ onChange: Function,
2160
+ maxDate: [String, Date],
2161
+ minDate: [String, Date],
2162
+ numberOfDays: {
2163
+ type: Number,
2164
+ default: 7
2165
+ },
2166
+ monthLabelFormat: {
2167
+ type: String,
2168
+ default: "MMM"
2169
+ },
2170
+ onNext: Function,
2171
+ onPrevious: Function,
2172
+ getDayProps: Function,
2173
+ size: {
2174
+ type: String,
2175
+ default: "sm"
2176
+ },
2177
+ previousControlProps: Object,
2178
+ nextControlProps: Object,
2179
+ locale: String
2180
+ },
2181
+ setup(props, { attrs }) {
2182
+ const ctx = useDatesContext();
2183
+ const [_date, setDate] = useUncontrolled({
2184
+ value: computed(() => toDateString(props.date ?? null) ?? void 0),
2185
+ defaultValue: toDateString(props.defaultDate ?? null) ?? void 0,
2186
+ finalValue: toDateString(props.value ?? null) || dayjs().format("YYYY-MM-DD"),
2187
+ onChange: (value) => props.onDateChange?.(value)
2188
+ });
2189
+ const handleNext = () => {
2190
+ props.onNext?.();
2191
+ setDate(dayjs(_date.value).add(props.numberOfDays, "days").format("YYYY-MM-DD"));
2192
+ };
2193
+ const handlePrevious = () => {
2194
+ props.onPrevious?.();
2195
+ setDate(dayjs(_date.value).subtract(props.numberOfDays, "days").format("YYYY-MM-DD"));
2196
+ };
2197
+ return () => {
2198
+ const previousDisabled = props.minDate ? dayjs(_date.value).subtract(1, "days").isBefore(dayjs(props.minDate)) : false;
2199
+ const nextDisabled = props.maxDate ? dayjs(_date.value).add(props.numberOfDays, "days").isAfter(dayjs(props.maxDate)) : false;
2200
+ const range = Array.from({ length: props.numberOfDays }, (_, index) => dayjs(_date.value).add(index, "days")).map((date) => {
2201
+ const disabled = props.minDate && date.isBefore(dayjs(props.minDate), "day") || props.maxDate && date.isAfter(dayjs(props.maxDate), "day") || false;
2202
+ const dayProps = props.getDayProps?.(toDateString(date.format("YYYY-MM-DD"))) || {};
2203
+ return h(UnstyledButton, {
2204
+ key: date.toString(),
2205
+ disabled,
2206
+ "aria-label": date.format("YYYY-MM-DD"),
2207
+ "data-disabled": disabled || void 0,
2208
+ "data-selected": props.value && dayjs(date).isSame(props.value, "day") || void 0,
2209
+ ...dayProps,
2210
+ class: [Dates_module_default.miniCalendarDay, dayProps.class],
2211
+ onClick: (event) => {
2212
+ dayProps.onClick?.(event);
2213
+ props.onChange?.(toDateString(date.format("YYYY-MM-DD")));
2214
+ }
2215
+ }, () => [h("span", { class: Dates_module_default.miniCalendarDayMonth }, date.locale(props.locale || ctx.locale).format(props.monthLabelFormat)), h("span", { class: Dates_module_default.miniCalendarDayNumber }, String(date.date()))]);
2216
+ });
2217
+ return h(Box, {
2218
+ ...attrs,
2219
+ class: [Dates_module_default.miniCalendarRoot, attrs.class]
2220
+ }, () => [
2221
+ h(UnstyledButton, {
2222
+ onClick: handlePrevious,
2223
+ disabled: previousDisabled,
2224
+ "data-disabled": previousDisabled || void 0,
2225
+ "data-direction": "previous",
2226
+ ...props.previousControlProps,
2227
+ class: [Dates_module_default.miniCalendarControl, props.previousControlProps?.class]
2228
+ }, () => props.previousControlProps?.children || h(AccordionChevron, {
2229
+ "data-chevron": true,
2230
+ size: props.size
2231
+ })),
2232
+ h("div", { class: Dates_module_default.miniCalendarDays }, range),
2233
+ h(UnstyledButton, {
2234
+ onClick: handleNext,
2235
+ disabled: nextDisabled,
2236
+ "data-disabled": nextDisabled || void 0,
2237
+ "data-direction": "next",
2238
+ ...props.nextControlProps,
2239
+ class: [Dates_module_default.miniCalendarControl, props.nextControlProps?.class]
2240
+ }, () => props.nextControlProps?.children || h(AccordionChevron, {
2241
+ "data-chevron": true,
2242
+ size: props.size
2243
+ }))
2244
+ ]);
2245
+ };
2246
+ }
2247
+ });
2248
+ var getFormattedTime = ({ value, format = "HH:mm" }) => (value instanceof Date ? dayjs(value) : dayjs(`2024-01-01 ${value}`)).format(format);
2249
+ //#endregion
2250
+ export { AmPmInput, Calendar, CalendarHeader, DateInput, DatePicker, DatePickerInput, DateTimePicker, DatesProvider, Day, DecadeLevel, DecadeLevelGroup, HiddenDatesInput, InlineDateTimePicker, LevelsGroup, MiniCalendar, Month, MonthLevel, MonthLevelGroup, MonthPicker, MonthPickerInput, MonthsList, PickerControl, PickerInputBase, SpinInput, TimeControlsList, TimeGrid, TimeInput, TimePicker, TimeValue, WeekdaysRow, YearLevel, YearLevelGroup, YearPicker, YearPickerInput, YearsList, assignTime, clampDate, clampTime, compareTime, dateStringParser, getDefaultClampedDate, getEndOfWeek, getFormattedDate, getFormattedTime, getParsedTime, getStartOfWeek, getTimeRange, getTimeString, getTimezoneOffset, getWeekNumber, handleControlKeyDown, isDateValid, isSameDate, isSameMonth, isSameTime, isSameYear, padTime, shiftTimezone, timeToSeconds, toDateString, useDatesContext };
2251
+
2252
+ //# sourceMappingURL=index.mjs.map