@k2b/ui 0.43.0 → 0.45.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.
- package/dist/browser/actions/Tabs.js +3 -4
- package/dist/browser/actions/Tabs.js.map +1 -1
- package/dist/browser/actions/menu-sheet.js +2 -3
- package/dist/browser/actions/menu-sheet.js.map +1 -1
- package/dist/browser/actions/phone-sheet.js +4 -0
- package/dist/browser/actions/phone-sheet.js.map +1 -0
- package/dist/browser/content/DataTable.js +47 -51
- package/dist/browser/content/DataTable.js.map +1 -1
- package/dist/browser/feedback/dialog-core.js +5 -1
- package/dist/browser/feedback/dialog-core.js.map +1 -1
- package/dist/browser/feedback/dialog-tone.js +26 -0
- package/dist/browser/feedback/dialog-tone.js.map +1 -0
- package/dist/browser/feedback/index.js.map +1 -1
- package/dist/browser/feedback/prompt-confirm.js +223 -0
- package/dist/browser/feedback/prompt-confirm.js.map +1 -0
- package/dist/browser/feedback/prompts.js +195 -343
- package/dist/browser/feedback/prompts.js.map +1 -1
- package/dist/browser/inputs/ChoiceList.js +45 -17
- package/dist/browser/inputs/ChoiceList.js.map +1 -1
- package/dist/browser/inputs/DatePicker.js +1647 -334
- package/dist/browser/inputs/DatePicker.js.map +1 -1
- package/dist/browser/inputs/TextInput.js +5 -4
- package/dist/browser/inputs/TextInput.js.map +1 -1
- package/dist/browser/inputs/date-input-messages.js +128 -0
- package/dist/browser/inputs/date-input-messages.js.map +1 -0
- package/dist/browser/inputs/date-input-status.js +132 -0
- package/dist/browser/inputs/date-input-status.js.map +1 -0
- package/dist/browser/inputs/date-input.js +334 -0
- package/dist/browser/inputs/date-input.js.map +1 -0
- package/dist/browser/inputs/date-sheet.js +49 -0
- package/dist/browser/inputs/date-sheet.js.map +1 -0
- package/dist/browser/internal/reveal-in-scroller.js +28 -0
- package/dist/browser/internal/reveal-in-scroller.js.map +1 -0
- package/dist/browser/intl/messages.js +6 -0
- package/dist/browser/intl/messages.js.map +1 -1
- package/dist/browser/layout/AppWorkspace.js +536 -512
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/BottomSheet.js +3 -0
- package/dist/browser/layout/BottomSheet.js.map +1 -1
- package/dist/browser/layout/PanelDialog.js +167 -132
- package/dist/browser/layout/PanelDialog.js.map +1 -1
- package/dist/browser/layout/Settings.js +175 -139
- package/dist/browser/layout/Settings.js.map +1 -1
- package/dist/browser/layout/SettingsModal.js +2 -4
- package/dist/browser/layout/SettingsModal.js.map +1 -1
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/browser/layout/navigation-model.js +12 -2
- package/dist/browser/layout/navigation-model.js.map +1 -1
- package/dist/browser/surfaces/StatusBadge.js +47 -14
- package/dist/browser/surfaces/StatusBadge.js.map +1 -1
- package/dist/browser/text-editor/TextEditor.js +7 -0
- package/dist/browser/text-editor/TextEditor.js.map +1 -1
- package/dist/ssr/actions/Tabs.js +3 -4
- package/dist/ssr/actions/Tabs.js.map +1 -1
- package/dist/ssr/actions/menu-sheet.js +2 -3
- package/dist/ssr/actions/menu-sheet.js.map +1 -1
- package/dist/ssr/actions/phone-sheet.js +4 -0
- package/dist/ssr/actions/phone-sheet.js.map +1 -0
- package/dist/ssr/content/DataTable.js +1 -2
- package/dist/ssr/content/DataTable.js.map +1 -1
- package/dist/ssr/feedback/dialog-core.js +5 -1
- package/dist/ssr/feedback/dialog-core.js.map +1 -1
- package/dist/ssr/feedback/dialog-tone.js +26 -0
- package/dist/ssr/feedback/dialog-tone.js.map +1 -0
- package/dist/ssr/feedback/index.js.map +1 -1
- package/dist/ssr/feedback/prompt-confirm.js +123 -0
- package/dist/ssr/feedback/prompt-confirm.js.map +1 -0
- package/dist/ssr/feedback/prompts.js +60 -132
- package/dist/ssr/feedback/prompts.js.map +1 -1
- package/dist/ssr/inputs/ChoiceList.js +29 -9
- package/dist/ssr/inputs/ChoiceList.js.map +1 -1
- package/dist/ssr/inputs/DatePicker.js +1183 -166
- package/dist/ssr/inputs/DatePicker.js.map +1 -1
- package/dist/ssr/inputs/TextInput.js +5 -4
- package/dist/ssr/inputs/TextInput.js.map +1 -1
- package/dist/ssr/inputs/date-input-messages.js +128 -0
- package/dist/ssr/inputs/date-input-messages.js.map +1 -0
- package/dist/ssr/inputs/date-input-status.js +132 -0
- package/dist/ssr/inputs/date-input-status.js.map +1 -0
- package/dist/ssr/inputs/date-input.js +334 -0
- package/dist/ssr/inputs/date-input.js.map +1 -0
- package/dist/ssr/inputs/date-sheet.js +44 -0
- package/dist/ssr/inputs/date-sheet.js.map +1 -0
- package/dist/ssr/internal/reveal-in-scroller.js +28 -0
- package/dist/ssr/internal/reveal-in-scroller.js.map +1 -0
- package/dist/ssr/intl/messages.js +6 -0
- package/dist/ssr/intl/messages.js.map +1 -1
- package/dist/ssr/layout/AppWorkspace.js +44 -23
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/BottomSheet.js +3 -0
- package/dist/ssr/layout/BottomSheet.js.map +1 -1
- package/dist/ssr/layout/PanelDialog.js +48 -30
- package/dist/ssr/layout/PanelDialog.js.map +1 -1
- package/dist/ssr/layout/Settings.js +34 -18
- package/dist/ssr/layout/Settings.js.map +1 -1
- package/dist/ssr/layout/SettingsModal.js +2 -4
- package/dist/ssr/layout/SettingsModal.js.map +1 -1
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/ssr/layout/navigation-model.js +12 -2
- package/dist/ssr/layout/navigation-model.js.map +1 -1
- package/dist/ssr/surfaces/StatusBadge.js +26 -8
- package/dist/ssr/surfaces/StatusBadge.js.map +1 -1
- package/dist/ssr/text-editor/TextEditor.js +7 -0
- package/dist/ssr/text-editor/TextEditor.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/menu-sheet.d.ts +1 -3
- package/dist/types/actions/phone-sheet.d.ts +3 -0
- package/dist/types/feedback/dialog-tone.d.ts +10 -0
- package/dist/types/feedback/index.d.ts +1 -0
- package/dist/types/feedback/prompt-confirm.d.ts +19 -0
- package/dist/types/feedback/prompts.d.ts +4 -8
- package/dist/types/inputs/ChoiceList.d.ts +7 -3
- package/dist/types/inputs/DatePicker.d.ts +13 -3
- package/dist/types/inputs/TextInput.d.ts +1 -1
- package/dist/types/inputs/date-input-messages.d.ts +64 -0
- package/dist/types/inputs/date-input-status.d.ts +35 -0
- package/dist/types/inputs/date-input.d.ts +90 -0
- package/dist/types/inputs/date-sheet.d.ts +14 -0
- package/dist/types/internal/reveal-in-scroller.d.ts +6 -0
- package/dist/types/intl/messages.d.ts +3 -0
- package/dist/types/layout/AppWorkspace.d.ts +14 -0
- package/dist/types/layout/BottomSheet.d.ts +3 -0
- package/dist/types/layout/PanelDialog.d.ts +3 -0
- package/dist/types/layout/Settings.d.ts +17 -1
- package/dist/types/layout/index.d.ts +1 -1
- package/dist/types/layout/navigation-model.d.ts +1 -1
- package/dist/types/surfaces/StatusBadge.d.ts +5 -0
- package/package.json +1 -1
|
@@ -18,32 +18,44 @@ var _tmpl$ = ["<i class=\"", "\" aria-hidden=\"true\"></i>"],
|
|
|
18
18
|
_tmpl$0 = ["<button type=\"button\">", "</button>"],
|
|
19
19
|
_tmpl$1 = ["<div class=\"k2b-date-weekdays\" aria-hidden=\"true\">", "", "</div>"],
|
|
20
20
|
_tmpl$10 = ["<div class=\"k2b-date-grid\" role=\"grid\">", "", "</div>"],
|
|
21
|
-
_tmpl$11 = ["<
|
|
22
|
-
_tmpl$12 = ["<
|
|
23
|
-
_tmpl$13 = ["<
|
|
24
|
-
_tmpl$14 = ["<
|
|
25
|
-
_tmpl$15 = ["<span"
|
|
26
|
-
_tmpl$16 = ["<span
|
|
27
|
-
_tmpl$17 = ["<
|
|
28
|
-
_tmpl$18 = ["<
|
|
29
|
-
_tmpl$19 = ["<
|
|
30
|
-
_tmpl$20 = ["<
|
|
31
|
-
_tmpl$21 = ["<
|
|
32
|
-
_tmpl$22 = ["<
|
|
33
|
-
_tmpl$23 = ["<
|
|
34
|
-
_tmpl$24 = ["<
|
|
35
|
-
_tmpl$25 = ["<button type=\"button\" class=\"k2b-date-
|
|
36
|
-
_tmpl$26 = ["<
|
|
37
|
-
_tmpl$27 = ["<
|
|
38
|
-
_tmpl$28 =
|
|
39
|
-
_tmpl$29 = ["<div class=\"k2b-date-
|
|
21
|
+
_tmpl$11 = ["<footer class=\"k2b-date-calendar__limits\"><span>", "</span><span>", "</span></footer>"],
|
|
22
|
+
_tmpl$12 = ["<section class=\"k2b-date-calendar\"", "><header class=\"k2b-date-calendar__header\"><button type=\"button\" class=\"k2b-date-calendar__nav\"", "><i class=\"ti ti-chevron-left\" aria-hidden=\"true\"></i></button><button type=\"button\" class=\"k2b-date-calendar__title\">", "</button><button type=\"button\" class=\"k2b-date-calendar__nav\"", "><i class=\"ti ti-chevron-right\" aria-hidden=\"true\"></i></button></header>", "", "</section>"],
|
|
23
|
+
_tmpl$13 = ["<div class=\"k2b-date-months\" role=\"group\" aria-label=\"", "\">", "</div>"],
|
|
24
|
+
_tmpl$14 = ["<button type=\"button\"", ">", "</button>"],
|
|
25
|
+
_tmpl$15 = ["<span class=\"k2b-date-weekend\" style=\"", "\"></span>"],
|
|
26
|
+
_tmpl$16 = ["<span", ">", "</span>"],
|
|
27
|
+
_tmpl$17 = ["<span class=\"k2b-date-weekend\" aria-hidden=\"true\" style=\"", "\"></span>"],
|
|
28
|
+
_tmpl$18 = ["<div class=\"k2b-date-week\" role=\"row\">", "</div>"],
|
|
29
|
+
_tmpl$19 = ["<button type=\"button\" role=\"gridcell\"", "", ">", "</button>"],
|
|
30
|
+
_tmpl$20 = ["<span>", "</span>"],
|
|
31
|
+
_tmpl$21 = ["<label class=\"k2b-date-time\">", "<span class=\"k2b-date-time__control\"><input type=\"text\" inputmode=\"numeric\"", " placeholder=\"09:00\"", "><i class=\"ti ti-clock\" aria-hidden=\"true\"></i></span></label>"],
|
|
32
|
+
_tmpl$22 = ["<p", " class=\"k2b-date-status\"", ">", "</p>"],
|
|
33
|
+
_tmpl$23 = ["<span class=\"k2b-sr-only\" aria-live=\"polite\">", "</span>"],
|
|
34
|
+
_tmpl$24 = ["<button type=\"button\" class=\"k2b-input-shell__clear k2b-input-clear-action k2b-date-field__clear\"", "><i class=\"ti ti-x\" aria-hidden=\"true\"></i></button>"],
|
|
35
|
+
_tmpl$25 = ["<button type=\"button\" class=\"k2b-date-field__toggle\" tabindex=\"-1\"", "><i class=\"ti ti-chevron-down\" aria-hidden=\"true\"></i></button>"],
|
|
36
|
+
_tmpl$26 = ["<div class=\"k2b-date-popover__body\">", "", "</div>"],
|
|
37
|
+
_tmpl$27 = ["<div class=\"k2b-date-picker k2b-date-field\"", "><div class=\"k2b-input-shell\"", "><span class=\"k2b-input-shell__icon k2b-date-field__icon\" aria-hidden=\"true\"><i class=\"ti ti-calendar\"></i></span>", "", "", "<div", " class=\"k2b-date-popover\" popover=\"manual\" role=\"dialog\"", ">", "</div></div>", "</div>"],
|
|
38
|
+
_tmpl$28 = "<span class=\"k2b-date-field__lock\" aria-hidden=\"true\"><i class=\"ti ti-lock\"></i></span>",
|
|
39
|
+
_tmpl$29 = ["<div class=\"k2b-date-actions\">", "<button type=\"button\" class=\"k2b-date-apply\"", ">", "</button></div>"],
|
|
40
|
+
_tmpl$30 = ["<span class=\"k2b-date-duration\"><i class=\"ti ti-hourglass-low\" aria-hidden=\"true\"></i>", "</span>"],
|
|
41
|
+
_tmpl$31 = ["<div class=\"k2b-date-picker k2b-date-field\" data-range=\"true\"", "><div class=\"k2b-input-shell\" role=\"group\"", "><span class=\"k2b-input-shell__icon k2b-date-field__icon\" aria-hidden=\"true\"><i class=\"ti ti-calendar-stats\"></i></span>", "<i class=\"ti ti-arrow-narrow-right k2b-date-field__arrow\" aria-hidden=\"true\"></i>", "<span class=\"k2b-date-field__spacer\"></span>", "", "<div", " class=\"k2b-date-popover\" popover=\"manual\" role=\"dialog\"", ">", "</div></div>", "</div>"],
|
|
42
|
+
_tmpl$32 = ["<button type=\"button\" class=\"k2b-date-optional-time__remove\"", "><i class=\"ti ti-x\" aria-hidden=\"true\"></i></button>"],
|
|
43
|
+
_tmpl$33 = ["<div class=\"k2b-date-optional-time\"", ">", "</div>"],
|
|
44
|
+
_tmpl$34 = ["<button type=\"button\" class=\"k2b-date-optional-time__add\"><i class=\"ti ti-clock-plus\" aria-hidden=\"true\"></i>", "</button>"],
|
|
45
|
+
_tmpl$35 = ["<span class=\"k2b-date-range-value\"><span>", "</span><i class=\"ti ti-arrow-narrow-right\" aria-hidden=\"true\"></i><span>", "</span></span>"],
|
|
46
|
+
_tmpl$36 = ["<div class=\"k2b-date-range-times\">", "", "</div>"],
|
|
47
|
+
_tmpl$37 = ["<div class=\"k2b-date-durations\" role=\"group\"", ">", "</div>"];
|
|
40
48
|
import { dates } from "@k2b/stdlib";
|
|
41
|
-
import { createEffect, createMemo, createSignal, For, onCleanup, onMount, Show } from "solid-js";
|
|
49
|
+
import { batch, createEffect, createMemo, createSignal, For, on, onCleanup, onMount, Show } from "solid-js";
|
|
50
|
+
import { prefersMenuSheet } from "../actions/phone-sheet";
|
|
42
51
|
import { createFieldMeta, Field, fieldControlAria, fieldDescribedBy } from "../internal/field";
|
|
43
52
|
import { returnFocus, ringOnReturn } from "../internal/focus-return";
|
|
44
53
|
import { useDateConfigLocale } from "../intl/locale";
|
|
45
54
|
import { resolveUiMessages, useUiMessages } from "../intl/messages";
|
|
46
55
|
import { isWeekendKey } from "../intl/weekend";
|
|
56
|
+
import { dateInputPattern, formatDateInput, parseDateInput } from "./date-input";
|
|
57
|
+
import { resolveDateInputMessages } from "./date-input-messages";
|
|
58
|
+
import { draftStatusText, errorText, formatDateLong, limitErrorText, rangeStatusText, restStatusText, spokenDateText, typingStatusText } from "./date-input-status";
|
|
47
59
|
import { dateKey, displayDate, filterTimeInput, formatDateOnlyRangeDuration, formatDateTimeValue, inRange, isCompleteTime, isDateKey, isRangeEdge, monthDate, monthNames, msUntilNextDay, normalizeTimeInput, parseDateValue, pickerContext, pickRangeDay, previewRange, rangeAnchor, resolveFocusDay, splitDateTime, toDateTimeValue, weekendBands, yearMonth } from "./date-picker";
|
|
48
60
|
import { commitFieldValue, resolveMaybeAccessor } from "./field-contract";
|
|
49
61
|
const popoverIsOpen = popover => {
|
|
@@ -54,10 +66,18 @@ const popoverIsOpen = popover => {
|
|
|
54
66
|
return false;
|
|
55
67
|
}
|
|
56
68
|
};
|
|
57
|
-
|
|
69
|
+
|
|
70
|
+
/** `below` is a line under the trigger that the panel must not cover, such as a typed field's status line. */
|
|
71
|
+
export const placeDatePopover = (trigger, popover, wide, below) => {
|
|
58
72
|
const margin = 8;
|
|
59
73
|
const gap = 4;
|
|
60
|
-
const
|
|
74
|
+
const triggerRect = trigger.getBoundingClientRect();
|
|
75
|
+
const belowRect = below?.getBoundingClientRect();
|
|
76
|
+
const rect = {
|
|
77
|
+
left: triggerRect.left,
|
|
78
|
+
top: triggerRect.top,
|
|
79
|
+
bottom: Math.max(triggerRect.bottom, belowRect?.height ? belowRect.bottom : 0)
|
|
80
|
+
};
|
|
61
81
|
// Keep the panel at its designed width instead of stretching to a full-width
|
|
62
82
|
// trigger; it only ever shrinks to fit a narrow viewport.
|
|
63
83
|
const preferredWidth = wide ? 440 : 336;
|
|
@@ -234,7 +254,19 @@ function DatePickerPanel(props) {
|
|
|
234
254
|
const [view, setView] = createSignal("days");
|
|
235
255
|
const context = createMemo(() => pickerContext(props.dateConfig));
|
|
236
256
|
const month = createMemo(() => yearMonth(props.visibleMonth(), context()));
|
|
237
|
-
|
|
257
|
+
// Always six weeks: typing moves an open calendar between months, and a month with fewer weeks would resize it.
|
|
258
|
+
const weeks = createMemo(() => {
|
|
259
|
+
const grid = [...dates.getMonthGrid(month().year, month().month, context())];
|
|
260
|
+
while (grid.length < 6) {
|
|
261
|
+
const last = grid[grid.length - 1].at(-1);
|
|
262
|
+
grid.push(Array.from({
|
|
263
|
+
length: 7
|
|
264
|
+
}, (_, index) => dates.addDays(last, index + 1, context())));
|
|
265
|
+
}
|
|
266
|
+
return grid;
|
|
267
|
+
});
|
|
268
|
+
const blocked = key => Boolean(props.min && key < props.min || props.max && key > props.max);
|
|
269
|
+
const inputMessages = createMemo(() => resolveDateInputMessages(context().locale));
|
|
238
270
|
const weekdays = createMemo(() => dates.weekdays(context()));
|
|
239
271
|
const months = createMemo(() => monthNames(context()));
|
|
240
272
|
const dayNameFormatter = createMemo(() => new Intl.DateTimeFormat(context().locale, {
|
|
@@ -291,7 +323,7 @@ function DatePickerPanel(props) {
|
|
|
291
323
|
let calendar;
|
|
292
324
|
// Days that belong to the visible month; the roving tabindex must land on one
|
|
293
325
|
// of them or the grid becomes unreachable by keyboard after month navigation.
|
|
294
|
-
const monthDayKeys = createMemo(() => dayRows().flat().filter(day => !day.outside).map(day => day.key));
|
|
326
|
+
const monthDayKeys = createMemo(() => dayRows().flat().filter(day => !day.outside && !blocked(day.key)).map(day => day.key));
|
|
295
327
|
// Remembers where arrow-key navigation left off so Tab returns to that day.
|
|
296
328
|
const [focusedKey, setFocusedKey] = createSignal();
|
|
297
329
|
const defaultFocus = createMemo(() => resolveFocusDay(monthDayKeys(), focusedKey() || props.focusDate?.() || props.selected?.() || todayKey()));
|
|
@@ -299,8 +331,18 @@ function DatePickerPanel(props) {
|
|
|
299
331
|
const moveYear = delta => props.setVisibleMonth(monthDate(month().year + delta, month().month, context()));
|
|
300
332
|
const previousLabel = () => view() === "days" ? messages().previousMonth : messages().previousYear;
|
|
301
333
|
const nextLabel = () => view() === "days" ? messages().nextMonth : messages().nextYear;
|
|
334
|
+
// A step whose whole month (or year) lies outside min/max is not offered.
|
|
335
|
+
const stepBlocked = delta => {
|
|
336
|
+
if (view() === "days") {
|
|
337
|
+
const target = dateKey(dates.addMonths(props.visibleMonth(), delta, context()), context()).slice(0, 7);
|
|
338
|
+
return Boolean(props.min && target < props.min.slice(0, 7) || props.max && target > props.max.slice(0, 7));
|
|
339
|
+
}
|
|
340
|
+
const year = String(month().year + delta);
|
|
341
|
+
return Boolean(props.min && year < props.min.slice(0, 4) || props.max && year > props.max.slice(0, 4));
|
|
342
|
+
};
|
|
302
343
|
const focusDate = date => {
|
|
303
344
|
const targetKey = dateKey(date, context());
|
|
345
|
+
if (blocked(targetKey)) return;
|
|
304
346
|
if (!dates.isSameMonth(date, props.visibleMonth(), context())) props.setVisibleMonth(date);
|
|
305
347
|
queueMicrotask(() => calendar?.querySelector(`[data-date-day="${targetKey}"]`)?.focus());
|
|
306
348
|
};
|
|
@@ -330,7 +372,7 @@ function DatePickerPanel(props) {
|
|
|
330
372
|
focusDate(dates.addDays(day, offset, context()));
|
|
331
373
|
}
|
|
332
374
|
};
|
|
333
|
-
return _$ssr(_tmpl$
|
|
375
|
+
return _$ssr(_tmpl$12, _$ssrAttribute("aria-label", _$escape(messages().calendar, true), false), _$ssrAttribute("disabled", stepBlocked(-1), true) + _$ssrAttribute("aria-label", _$escape(previousLabel(), true), false), _$escape(_$createComponent(Show, {
|
|
334
376
|
get when() {
|
|
335
377
|
return view() === "days";
|
|
336
378
|
},
|
|
@@ -340,16 +382,16 @@ function DatePickerPanel(props) {
|
|
|
340
382
|
get children() {
|
|
341
383
|
return dates.formatMonthYear(props.visibleMonth(), context());
|
|
342
384
|
}
|
|
343
|
-
})), _$ssrAttribute("aria-label", _$escape(nextLabel(), true), false), _$escape(_$createComponent(Show, {
|
|
385
|
+
})), _$ssrAttribute("disabled", stepBlocked(1), true) + _$ssrAttribute("aria-label", _$escape(nextLabel(), true), false), _$escape(_$createComponent(Show, {
|
|
344
386
|
get when() {
|
|
345
387
|
return view() === "days";
|
|
346
388
|
},
|
|
347
389
|
get fallback() {
|
|
348
|
-
return _$ssr(_tmpl$
|
|
390
|
+
return _$ssr(_tmpl$13, `Months in ${_$escape(month().year, true)}`, _$escape(_$createComponent(For, {
|
|
349
391
|
get each() {
|
|
350
392
|
return months();
|
|
351
393
|
},
|
|
352
|
-
children: (name, index) => _$ssr(_tmpl$
|
|
394
|
+
children: (name, index) => _$ssr(_tmpl$14, _$ssrAttribute("aria-pressed", _$escape(index(), true) === _$escape(month().month, true), false) + _$ssrAttribute("data-selected", index() === month().month ? "true" : _$escape(undefined, true), false), _$escape(name))
|
|
353
395
|
})));
|
|
354
396
|
},
|
|
355
397
|
get children() {
|
|
@@ -357,22 +399,22 @@ function DatePickerPanel(props) {
|
|
|
357
399
|
get each() {
|
|
358
400
|
return bands();
|
|
359
401
|
},
|
|
360
|
-
children: band => _$ssr(_tmpl$
|
|
402
|
+
children: band => _$ssr(_tmpl$15, _$ssrStyleProperty("grid-column:", `${_$escape(band.start, true) + 1} / span ${_$escape(band.span, true)}`))
|
|
361
403
|
})), _$escape(_$createComponent(For, {
|
|
362
404
|
get each() {
|
|
363
405
|
return weekdays();
|
|
364
406
|
},
|
|
365
|
-
children: (day, index) => _$ssr(_tmpl$
|
|
407
|
+
children: (day, index) => _$ssr(_tmpl$16, _$ssrAttribute("data-weekend", weekendColumns()[index()] ? "true" : _$escape(undefined, true), false), _$escape(day))
|
|
366
408
|
}))), _$ssr(_tmpl$10, _$escape(_$createComponent(For, {
|
|
367
409
|
get each() {
|
|
368
410
|
return bands();
|
|
369
411
|
},
|
|
370
|
-
children: band => _$ssr(_tmpl$
|
|
412
|
+
children: band => _$ssr(_tmpl$17, _$ssrStyleProperty("grid-column:", `${_$escape(band.start, true) + 1} / span ${_$escape(band.span, true)}`) + _$ssrStyleProperty(";grid-row:", `1 / span ${_$escape(dayRows().length, true)}`))
|
|
371
413
|
})), _$escape(_$createComponent(For, {
|
|
372
414
|
get each() {
|
|
373
415
|
return dayRows();
|
|
374
416
|
},
|
|
375
|
-
children: week => _$ssr(_tmpl$
|
|
417
|
+
children: week => _$ssr(_tmpl$18, _$escape(_$createComponent(For, {
|
|
376
418
|
each: week,
|
|
377
419
|
children: (cell, cellIndex) => {
|
|
378
420
|
const selected = () => props.selected?.() === cell.key;
|
|
@@ -383,64 +425,1007 @@ function DatePickerPanel(props) {
|
|
|
383
425
|
const active = () => selected() || isRangeEdge(cell.key, range());
|
|
384
426
|
const focusable = () => cell.key === defaultFocus();
|
|
385
427
|
const today = () => cell.key === todayKey();
|
|
386
|
-
|
|
428
|
+
const label = () => {
|
|
429
|
+
const name = today() ? todayLabel(cell.label) : cell.label;
|
|
430
|
+
return blocked(cell.key) ? inputMessages().notSelectable({
|
|
431
|
+
date: name
|
|
432
|
+
}) : name;
|
|
433
|
+
};
|
|
434
|
+
return _$ssr(_tmpl$19, _$ssrAttribute("data-date-day", _$escape(cell.key, true), false) + _$ssrAttribute("data-date-focus", focusable() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-outside", cell.outside ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-weekend", weekendColumns()[cellIndex()] ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-in-range", inRange(cell.key, range()) && !active() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-today", today() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("aria-current", today() ? "date" : _$escape(undefined, true), false) + _$ssrAttribute("aria-label", _$escape(label(), true), false) + _$ssrAttribute("aria-selected", _$escape(active(), true), false), _$ssrAttribute("disabled", blocked(cell.key), true) + _$ssrAttribute("tabindex", focusable() ? 0 : -1, false), _$escape(cell.number));
|
|
387
435
|
}
|
|
388
436
|
})))
|
|
389
437
|
})))];
|
|
390
438
|
}
|
|
439
|
+
})), _$escape(_$createComponent(Show, {
|
|
440
|
+
get when() {
|
|
441
|
+
return props.min || props.max;
|
|
442
|
+
},
|
|
443
|
+
get children() {
|
|
444
|
+
return _$ssr(_tmpl$11, props.min ? _$escape(inputMessages().limitFrom({
|
|
445
|
+
date: formatDateInput(props.min, context().locale)
|
|
446
|
+
})) : "", props.max ? _$escape(inputMessages().limitUntil({
|
|
447
|
+
date: formatDateInput(props.max, context().locale)
|
|
448
|
+
})) : "");
|
|
449
|
+
}
|
|
391
450
|
})));
|
|
392
451
|
}
|
|
393
452
|
function TimeInput(props) {
|
|
394
453
|
const messages = useUiMessages();
|
|
395
|
-
return _$ssr(_tmpl$
|
|
454
|
+
return _$ssr(_tmpl$21, _$escape(_$createComponent(Show, {
|
|
396
455
|
get when() {
|
|
397
456
|
return props.label;
|
|
398
457
|
},
|
|
399
458
|
get children() {
|
|
400
|
-
return _$ssr(_tmpl$
|
|
459
|
+
return _$ssr(_tmpl$20, _$escape(props.label));
|
|
401
460
|
}
|
|
402
461
|
})), _$ssrAttribute("value", _$escape(props.time, true), false), _$ssrAttribute("aria-label", props.label ? _$escape(messages().timeLabel({
|
|
403
462
|
label: props.label
|
|
404
463
|
}), true) : _$escape(messages().time, true), false));
|
|
405
464
|
}
|
|
465
|
+
|
|
466
|
+
/** The calendar popover of a typed field: it lives inside the field's shell, so focus in the calendar keeps the field's focus edge. */
|
|
467
|
+
function createCalendarPopover(options) {
|
|
468
|
+
const [open, setOpen] = createSignal(false);
|
|
469
|
+
let popover;
|
|
470
|
+
const place = () => {
|
|
471
|
+
const anchor = options.anchor();
|
|
472
|
+
if (anchor && popover && open()) placeDatePopover(anchor, popover, options.wide(), options.below());
|
|
473
|
+
};
|
|
474
|
+
const show = () => {
|
|
475
|
+
if (!popover || popoverIsOpen(popover)) return;
|
|
476
|
+
setOpen(true);
|
|
477
|
+
popover.showPopover();
|
|
478
|
+
place();
|
|
479
|
+
};
|
|
480
|
+
const close = () => {
|
|
481
|
+
if (popoverIsOpen(popover)) popover?.hidePopover();
|
|
482
|
+
setOpen(false);
|
|
483
|
+
};
|
|
484
|
+
createEffect(() => {
|
|
485
|
+
if (!open()) return;
|
|
486
|
+
window.addEventListener("resize", place);
|
|
487
|
+
window.addEventListener("scroll", place, true);
|
|
488
|
+
onCleanup(() => {
|
|
489
|
+
window.removeEventListener("resize", place);
|
|
490
|
+
window.removeEventListener("scroll", place, true);
|
|
491
|
+
});
|
|
492
|
+
});
|
|
493
|
+
onCleanup(close);
|
|
494
|
+
return {
|
|
495
|
+
open,
|
|
496
|
+
show,
|
|
497
|
+
close,
|
|
498
|
+
place,
|
|
499
|
+
ref: element => {
|
|
500
|
+
popover = element;
|
|
501
|
+
// The browser also hides a popover itself, for example when it leaves the top layer.
|
|
502
|
+
element.addEventListener("toggle", () => setOpen(popoverIsOpen(element)));
|
|
503
|
+
},
|
|
504
|
+
element: () => popover,
|
|
505
|
+
focusDay: () => queueMicrotask(() => popover?.querySelector('[data-date-focus="true"]')?.focus())
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/** The day an empty calendar opens on: today, moved inside min/max, so a limited field never opens on locked months only. */
|
|
510
|
+
const openingDay = (value, limits, context) => {
|
|
511
|
+
if (value) return value;
|
|
512
|
+
const today = dateKey(new Date(), context);
|
|
513
|
+
if (limits.min && today < limits.min) return limits.min;
|
|
514
|
+
if (limits.max && today > limits.max) return limits.max;
|
|
515
|
+
return today;
|
|
516
|
+
};
|
|
517
|
+
const fieldName = owner => typeof owner.label === "string" ? owner.label : owner["aria-label"];
|
|
518
|
+
|
|
519
|
+
/** Clicks on the calendar's empty space keep focus where it is, so the draft and caret stay in the text. */
|
|
520
|
+
const keepFocus = event => {
|
|
521
|
+
if (!event.target.closest("button")) event.preventDefault();
|
|
522
|
+
};
|
|
523
|
+
const caretToEnd = input => {
|
|
524
|
+
input?.focus();
|
|
525
|
+
input?.setSelectionRange(input.value.length, input.value.length);
|
|
526
|
+
};
|
|
527
|
+
function DateStatusLine(props) {
|
|
528
|
+
return [_$ssr(_tmpl$22, _$ssrAttribute("id", _$escape(props.id, true), false), _$ssrAttribute("data-tone", _$escape(props.tone, true), false) + _$ssrAttribute("title", typeof props.text === "string" && props.text ? _$escape(props.text, true) : _$escape(undefined, true), false), _$escape(props.text)), _$ssr(_tmpl$23, _$escape(props.announcement))];
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* The typed date field. The text and the calendar always show the same day: typing moves the calendar, picking a day
|
|
533
|
+
* fills the text, and the status line says which day the text means before it is committed.
|
|
534
|
+
*/
|
|
535
|
+
function DateTextField(props) {
|
|
536
|
+
const uiMessages = useUiMessages();
|
|
537
|
+
const meta = createFieldMeta(props.owner.id);
|
|
538
|
+
const locale = () => props.dateConfig().locale;
|
|
539
|
+
const t = createMemo(() => resolveDateInputMessages(locale()));
|
|
540
|
+
const today = () => dateKey(new Date(), props.dateConfig());
|
|
541
|
+
const format = key => key ? formatDateInput(key, locale()) : "";
|
|
542
|
+
const limits = () => ({
|
|
543
|
+
min: props.owner.min,
|
|
544
|
+
max: props.owner.max
|
|
545
|
+
});
|
|
546
|
+
const interactive = () => !props.owner.disabled && !props.owner.readOnly;
|
|
547
|
+
const [text, setText] = createSignal(format(props.value()));
|
|
548
|
+
const [dirty, setDirty] = createSignal(false);
|
|
549
|
+
const [failure, setFailure] = createSignal();
|
|
550
|
+
const [announcement, setAnnouncement] = createSignal("");
|
|
551
|
+
const [visibleMonth, setVisibleMonth] = createSignal(parseDateValue(openingDay(props.value(), limits(), props.dateConfig()), props.dateConfig()));
|
|
552
|
+
let shell;
|
|
553
|
+
let input;
|
|
554
|
+
let toggle;
|
|
555
|
+
let statusLine;
|
|
556
|
+
const [sheetOpen, setSheetOpen] = createSignal(false);
|
|
557
|
+
let announceTimer;
|
|
558
|
+
const calendar = createCalendarPopover({
|
|
559
|
+
anchor: () => shell,
|
|
560
|
+
below: () => statusLine,
|
|
561
|
+
wide: () => Boolean(props.owner.presets?.length)
|
|
562
|
+
});
|
|
563
|
+
const popoverId = `${meta.controlId}-calendar`;
|
|
564
|
+
const sheetId = `${meta.controlId}-sheet`;
|
|
565
|
+
// The status line holds the field's message slot, so it carries the `<id>-error` every field family uses.
|
|
566
|
+
const statusId = meta.errorId;
|
|
567
|
+
const parse = value => parseDateInput(value, {
|
|
568
|
+
today: today(),
|
|
569
|
+
locale: locale()
|
|
570
|
+
});
|
|
571
|
+
const parsed = createMemo(() => dirty() ? parse(text()) : undefined);
|
|
572
|
+
const draftKey = () => {
|
|
573
|
+
const result = parsed();
|
|
574
|
+
if (!result) return props.value();
|
|
575
|
+
return result.kind === "date" ? result.date : null;
|
|
576
|
+
};
|
|
577
|
+
|
|
578
|
+
// A value set from outside replaces the text, unless someone is typing.
|
|
579
|
+
createEffect(on([props.value, locale], () => {
|
|
580
|
+
if (dirty()) return;
|
|
581
|
+
setText(format(props.value()));
|
|
582
|
+
setFailure(undefined);
|
|
583
|
+
setVisibleMonth(parseDateValue(openingDay(props.value(), limits(), props.dateConfig()), props.dateConfig()));
|
|
584
|
+
}));
|
|
585
|
+
// The calendar follows the typed day, and a refused text stops being red once it means an allowed day.
|
|
586
|
+
createEffect(on(parsed, result => {
|
|
587
|
+
if (result?.kind === "date") {
|
|
588
|
+
setVisibleMonth(parseDateValue(result.date, props.dateConfig()));
|
|
589
|
+
if (!limitErrorText(result.date, limits(), locale(), t())) setFailure(undefined);
|
|
590
|
+
} else if (result?.kind === "empty") setFailure(undefined);
|
|
591
|
+
}));
|
|
592
|
+
onCleanup(() => clearTimeout(announceTimer));
|
|
593
|
+
const externalError = () => resolveMaybeAccessor(props.owner.error);
|
|
594
|
+
const invalid = () => Boolean(failure() || externalError());
|
|
595
|
+
const status = createMemo(() => {
|
|
596
|
+
const failed = failure();
|
|
597
|
+
if (failed) return {
|
|
598
|
+
tone: "error",
|
|
599
|
+
text: failed
|
|
600
|
+
};
|
|
601
|
+
const result = parsed();
|
|
602
|
+
if (result?.kind === "date") {
|
|
603
|
+
const limit = limitErrorText(result.date, limits(), locale(), t());
|
|
604
|
+
return limit ? {
|
|
605
|
+
tone: "rest",
|
|
606
|
+
text: limit
|
|
607
|
+
} : {
|
|
608
|
+
tone: "draft",
|
|
609
|
+
text: draftStatusText(result.date, result.note, locale(), t())
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
if (result?.kind === "error") return {
|
|
613
|
+
tone: "rest",
|
|
614
|
+
text: typingStatusText(result.error, locale(), t(), today())
|
|
615
|
+
};
|
|
616
|
+
const external = externalError();
|
|
617
|
+
if (external) return {
|
|
618
|
+
tone: "error",
|
|
619
|
+
text: external
|
|
620
|
+
};
|
|
621
|
+
const value = props.value();
|
|
622
|
+
if (!value || result) return {
|
|
623
|
+
tone: "rest",
|
|
624
|
+
text: ""
|
|
625
|
+
};
|
|
626
|
+
return {
|
|
627
|
+
tone: "rest",
|
|
628
|
+
text: props.owner.renderValue?.(value) ?? restStatusText(value, today(), locale())
|
|
629
|
+
};
|
|
630
|
+
});
|
|
631
|
+
const save = next => {
|
|
632
|
+
if (next !== props.value()) commitFieldValue(props.owner, next);
|
|
633
|
+
};
|
|
634
|
+
const fail = message => {
|
|
635
|
+
setFailure(message);
|
|
636
|
+
setAnnouncement(message);
|
|
637
|
+
};
|
|
638
|
+
/** Enter, leaving the field and a picked day commit; a refused text stays for correction and the value is kept. */
|
|
639
|
+
const commit = () => {
|
|
640
|
+
const result = parse(text());
|
|
641
|
+
setDirty(false);
|
|
642
|
+
if (result.kind === "empty") {
|
|
643
|
+
if (props.owner.required) return fail(t().required);
|
|
644
|
+
setFailure(undefined);
|
|
645
|
+
return save(null);
|
|
646
|
+
}
|
|
647
|
+
if (result.kind === "error") return fail(errorText(result.error, locale(), t(), today()));
|
|
648
|
+
const limit = limitErrorText(result.date, limits(), locale(), t());
|
|
649
|
+
if (limit) return fail(limit);
|
|
650
|
+
setFailure(undefined);
|
|
651
|
+
setText(format(result.date));
|
|
652
|
+
save(result.date);
|
|
653
|
+
};
|
|
654
|
+
const restore = () => {
|
|
655
|
+
setText(format(props.value()));
|
|
656
|
+
setDirty(false);
|
|
657
|
+
setFailure(undefined);
|
|
658
|
+
setVisibleMonth(parseDateValue(openingDay(props.value(), limits(), props.dateConfig()), props.dateConfig()));
|
|
659
|
+
calendar.close();
|
|
660
|
+
};
|
|
661
|
+
const pick = key => {
|
|
662
|
+
setText(format(key));
|
|
663
|
+
setDirty(false);
|
|
664
|
+
setFailure(undefined);
|
|
665
|
+
save(key);
|
|
666
|
+
calendar.close();
|
|
667
|
+
};
|
|
668
|
+
const openSheet = async () => {
|
|
669
|
+
setSheetOpen(true);
|
|
670
|
+
calendar.close();
|
|
671
|
+
const {
|
|
672
|
+
openDateSheet
|
|
673
|
+
} = await import("./date-sheet");
|
|
674
|
+
await openDateSheet({
|
|
675
|
+
title: props.owner.label ?? props.owner["aria-label"],
|
|
676
|
+
subtitle: props.value() ? formatDateLong(props.value(), locale()) : t().noDate,
|
|
677
|
+
ariaLabel: fieldName(props.owner),
|
|
678
|
+
id: sheetId,
|
|
679
|
+
locale: locale() ?? "en",
|
|
680
|
+
content: close => _$createComponent(DatePickerPanel, {
|
|
681
|
+
visibleMonth: visibleMonth,
|
|
682
|
+
setVisibleMonth: setVisibleMonth,
|
|
683
|
+
selected: draftKey,
|
|
684
|
+
focusDate: draftKey,
|
|
685
|
+
onSelect: key => {
|
|
686
|
+
// Saved at once: the sheet's promise settles only after its history entry has gone.
|
|
687
|
+
pick(key);
|
|
688
|
+
close(key);
|
|
689
|
+
},
|
|
690
|
+
get dateConfig() {
|
|
691
|
+
return props.dateConfig();
|
|
692
|
+
},
|
|
693
|
+
get min() {
|
|
694
|
+
return props.owner.min;
|
|
695
|
+
},
|
|
696
|
+
get max() {
|
|
697
|
+
return props.owner.max;
|
|
698
|
+
}
|
|
699
|
+
})
|
|
700
|
+
});
|
|
701
|
+
setSheetOpen(false);
|
|
702
|
+
toggle?.focus({
|
|
703
|
+
preventScroll: true
|
|
704
|
+
});
|
|
705
|
+
};
|
|
706
|
+
/** Phones open the calendar as a sheet; there the text only brings up the keypad. */
|
|
707
|
+
const openCalendar = focusDay => {
|
|
708
|
+
if (!interactive()) return;
|
|
709
|
+
if (prefersMenuSheet()) return void openSheet();
|
|
710
|
+
if (!dirty()) setVisibleMonth(parseDateValue(openingDay(props.value(), limits(), props.dateConfig()), props.dateConfig()));
|
|
711
|
+
calendar.show();
|
|
712
|
+
if (focusDay) calendar.focusDay();
|
|
713
|
+
};
|
|
714
|
+
const onPointerDown = event => {
|
|
715
|
+
const target = event.target;
|
|
716
|
+
if (!interactive() || calendar.element()?.contains(target) || target.closest(".k2b-date-field__clear")) return;
|
|
717
|
+
const onIcon = target.closest(".k2b-date-field__toggle, .k2b-date-field__icon");
|
|
718
|
+
if (prefersMenuSheet()) {
|
|
719
|
+
if (onIcon) {
|
|
720
|
+
event.preventDefault();
|
|
721
|
+
void openSheet();
|
|
722
|
+
}
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
725
|
+
if (onIcon) {
|
|
726
|
+
event.preventDefault();
|
|
727
|
+
input?.focus();
|
|
728
|
+
if (calendar.open()) calendar.close();else openCalendar(false);
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
731
|
+
// A pointer in the text opens the calendar and keeps the caret; Tab focus never opens it.
|
|
732
|
+
if (event.button === 0 && !calendar.open()) setTimeout(() => openCalendar(false));
|
|
733
|
+
};
|
|
734
|
+
const onKeyDown = event => {
|
|
735
|
+
// A refused text keeps Enter too, so it does not submit the form around it.
|
|
736
|
+
if (event.key === "Enter" && (dirty() || calendar.open() || failure())) {
|
|
737
|
+
event.preventDefault();
|
|
738
|
+
commit();
|
|
739
|
+
calendar.close();
|
|
740
|
+
} else if (event.key === "Escape" && (dirty() || calendar.open() || failure())) {
|
|
741
|
+
event.preventDefault();
|
|
742
|
+
event.stopPropagation();
|
|
743
|
+
restore();
|
|
744
|
+
} else if (event.key === "ArrowDown") {
|
|
745
|
+
event.preventDefault();
|
|
746
|
+
openCalendar(true);
|
|
747
|
+
} else if (event.key === "ArrowUp" && event.altKey) {
|
|
748
|
+
event.preventDefault();
|
|
749
|
+
calendar.close();
|
|
750
|
+
}
|
|
751
|
+
};
|
|
752
|
+
const onFocusOut = event => {
|
|
753
|
+
const next = event.relatedTarget;
|
|
754
|
+
if (sheetOpen() || next === input || next && calendar.element()?.contains(next)) return;
|
|
755
|
+
if (dirty()) commit();
|
|
756
|
+
calendar.close();
|
|
757
|
+
};
|
|
758
|
+
return _$createComponent(Field, {
|
|
759
|
+
get ["class"]() {
|
|
760
|
+
return props.owner.class;
|
|
761
|
+
},
|
|
762
|
+
get label() {
|
|
763
|
+
return props.owner.label;
|
|
764
|
+
},
|
|
765
|
+
get description() {
|
|
766
|
+
return props.owner.description;
|
|
767
|
+
},
|
|
768
|
+
get required() {
|
|
769
|
+
return props.owner.required;
|
|
770
|
+
},
|
|
771
|
+
get disabled() {
|
|
772
|
+
return props.owner.disabled;
|
|
773
|
+
},
|
|
774
|
+
meta: meta,
|
|
775
|
+
get children() {
|
|
776
|
+
return _$ssr(_tmpl$27, _$ssrAttribute("data-open", calendar.open() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-readonly", props.owner.readOnly ? "true" : _$escape(undefined, true), false), _$ssrAttribute("data-invalid", invalid() ? "true" : _$escape(undefined, true), false), _$ssrElement("input", _$mergeProps(() => fieldControlAria(meta, props.owner), {
|
|
777
|
+
get id() {
|
|
778
|
+
return meta.controlId;
|
|
779
|
+
},
|
|
780
|
+
"class": "k2b-input",
|
|
781
|
+
type: "text",
|
|
782
|
+
inputMode: "numeric",
|
|
783
|
+
autocomplete: "off",
|
|
784
|
+
spellcheck: false,
|
|
785
|
+
role: "combobox",
|
|
786
|
+
"aria-haspopup": "dialog",
|
|
787
|
+
get ["aria-expanded"]() {
|
|
788
|
+
return calendar.open() || sheetOpen();
|
|
789
|
+
},
|
|
790
|
+
get ["aria-controls"]() {
|
|
791
|
+
return sheetOpen() ? sheetId : popoverId;
|
|
792
|
+
},
|
|
793
|
+
get ["aria-describedby"]() {
|
|
794
|
+
return [props.owner["aria-describedby"], props.owner.description ? meta.descriptionId : undefined, statusId].filter(Boolean).join(" ");
|
|
795
|
+
},
|
|
796
|
+
get ["aria-invalid"]() {
|
|
797
|
+
return invalid() ? "true" : undefined;
|
|
798
|
+
},
|
|
799
|
+
get placeholder() {
|
|
800
|
+
return props.owner.placeholder ?? datePattern(locale(), t());
|
|
801
|
+
},
|
|
802
|
+
get value() {
|
|
803
|
+
return text();
|
|
804
|
+
},
|
|
805
|
+
get disabled() {
|
|
806
|
+
return props.owner.disabled;
|
|
807
|
+
},
|
|
808
|
+
get readOnly() {
|
|
809
|
+
return props.owner.readOnly;
|
|
810
|
+
}
|
|
811
|
+
}), undefined, false), _$escape(_$createComponent(Show, {
|
|
812
|
+
get when() {
|
|
813
|
+
return _$memo(() => !!props.owner.clearable)() && interactive();
|
|
814
|
+
},
|
|
815
|
+
get children() {
|
|
816
|
+
return _$ssr(_tmpl$24, _$ssrAttribute("data-hidden", text() ? _$escape(undefined, true) : "true", false) + _$ssrAttribute("aria-label", _$escape(uiMessages().clearDate, true), false));
|
|
817
|
+
}
|
|
818
|
+
})), _$escape(_$createComponent(Show, {
|
|
819
|
+
get when() {
|
|
820
|
+
return !props.owner.readOnly;
|
|
821
|
+
},
|
|
822
|
+
get fallback() {
|
|
823
|
+
return _$ssr(_tmpl$28);
|
|
824
|
+
},
|
|
825
|
+
get children() {
|
|
826
|
+
return _$ssr(_tmpl$25, _$ssrAttribute("disabled", props.owner.disabled, true) + _$ssrAttribute("aria-label", calendar.open() ? _$escape(t().closeCalendar, true) : _$escape(t().openCalendar, true), false) + _$ssrAttribute("aria-expanded", _$escape(calendar.open() || sheetOpen(), true), false) + _$ssrAttribute("aria-controls", sheetOpen() ? _$escape(sheetId, true) : _$escape(popoverId, true), false));
|
|
827
|
+
}
|
|
828
|
+
})), _$ssrAttribute("id", _$escape(popoverId, true), false), _$ssrAttribute("aria-label", _$escape(fieldName(props.owner) ?? uiMessages().datePicker, true), false), _$escape(_$createComponent(Show, {
|
|
829
|
+
get when() {
|
|
830
|
+
return calendar.open();
|
|
831
|
+
},
|
|
832
|
+
get children() {
|
|
833
|
+
return _$ssr(_tmpl$26, _$escape(_$createComponent(PresetRail, {
|
|
834
|
+
get presets() {
|
|
835
|
+
return props.owner.presets;
|
|
836
|
+
},
|
|
837
|
+
onSelect: value => {
|
|
838
|
+
pick(value);
|
|
839
|
+
caretToEnd(input);
|
|
840
|
+
}
|
|
841
|
+
})), _$escape(_$createComponent(DatePickerPanel, {
|
|
842
|
+
visibleMonth: visibleMonth,
|
|
843
|
+
setVisibleMonth: setVisibleMonth,
|
|
844
|
+
selected: draftKey,
|
|
845
|
+
focusDate: draftKey,
|
|
846
|
+
onSelect: key => {
|
|
847
|
+
pick(key);
|
|
848
|
+
caretToEnd(input);
|
|
849
|
+
},
|
|
850
|
+
get dateConfig() {
|
|
851
|
+
return props.dateConfig();
|
|
852
|
+
},
|
|
853
|
+
get min() {
|
|
854
|
+
return props.owner.min;
|
|
855
|
+
},
|
|
856
|
+
get max() {
|
|
857
|
+
return props.owner.max;
|
|
858
|
+
}
|
|
859
|
+
})));
|
|
860
|
+
}
|
|
861
|
+
})), _$escape(_$createComponent(DateStatusLine, {
|
|
862
|
+
id: statusId,
|
|
863
|
+
get tone() {
|
|
864
|
+
return status().tone;
|
|
865
|
+
},
|
|
866
|
+
get text() {
|
|
867
|
+
return status().text;
|
|
868
|
+
},
|
|
869
|
+
get announcement() {
|
|
870
|
+
return announcement();
|
|
871
|
+
}
|
|
872
|
+
})));
|
|
873
|
+
}
|
|
874
|
+
});
|
|
875
|
+
}
|
|
876
|
+
const datePattern = (locale, t) => dateInputPattern(locale, {
|
|
877
|
+
day: t.dayLetters,
|
|
878
|
+
month: t.monthLetters,
|
|
879
|
+
year: t.yearLetters
|
|
880
|
+
});
|
|
881
|
+
|
|
882
|
+
/** "11.11.2026 – 14.11.2026", "11.11. bis 14.11." or "Nov 11 to Nov 14" pasted into either half fills both. */
|
|
883
|
+
const splitPastedRange = text => {
|
|
884
|
+
const parts = text.trim().split(/\s*[–—]\s*|\s+-\s+|\s+(?:bis|to|until)\s+/i);
|
|
885
|
+
return parts.length === 2 && parts[0] && parts[1] ? [parts[0], parts[1]] : undefined;
|
|
886
|
+
};
|
|
887
|
+
|
|
888
|
+
/** A date-only range as two typed halves in one field; the calendar keeps two clicks and Apply. */
|
|
889
|
+
function DateRangeTextField(props) {
|
|
890
|
+
const uiMessages = useUiMessages();
|
|
891
|
+
const meta = createFieldMeta(props.owner.id);
|
|
892
|
+
const locale = () => props.dateConfig().locale;
|
|
893
|
+
const t = createMemo(() => resolveDateInputMessages(locale()));
|
|
894
|
+
const today = () => dateKey(new Date(), props.dateConfig());
|
|
895
|
+
const format = key => key ? formatDateInput(key, locale()) : "";
|
|
896
|
+
const limits = () => ({
|
|
897
|
+
min: props.owner.min,
|
|
898
|
+
max: props.owner.max
|
|
899
|
+
});
|
|
900
|
+
const interactive = () => !props.owner.disabled && !props.owner.readOnly;
|
|
901
|
+
const [startText, setStartText] = createSignal(format(props.value().start));
|
|
902
|
+
const [endText, setEndText] = createSignal(format(props.value().end));
|
|
903
|
+
const [dirty, setDirty] = createSignal(false);
|
|
904
|
+
const [failure, setFailure] = createSignal();
|
|
905
|
+
const [announcement, setAnnouncement] = createSignal("");
|
|
906
|
+
const [visibleMonth, setVisibleMonth] = createSignal(parseDateValue(openingDay(props.value().start || props.value().end, limits(), props.dateConfig()), props.dateConfig()));
|
|
907
|
+
// The calendar's own draft: two clicks pick a range, Apply commits it.
|
|
908
|
+
const [picked, setPicked] = createSignal(props.value());
|
|
909
|
+
const [anchor, setAnchor] = createSignal(null);
|
|
910
|
+
const [previewDate, setPreviewDate] = createSignal(null);
|
|
911
|
+
let shell;
|
|
912
|
+
let startInput;
|
|
913
|
+
let endInput;
|
|
914
|
+
let toggle;
|
|
915
|
+
let statusLine;
|
|
916
|
+
const [sheetOpen, setSheetOpen] = createSignal(false);
|
|
917
|
+
let announceTimer;
|
|
918
|
+
const wide = () => Boolean(props.owner.datePresets?.length || props.owner.presets?.length);
|
|
919
|
+
const calendar = createCalendarPopover({
|
|
920
|
+
anchor: () => shell,
|
|
921
|
+
below: () => statusLine,
|
|
922
|
+
wide
|
|
923
|
+
});
|
|
924
|
+
const popoverId = `${meta.controlId}-calendar`;
|
|
925
|
+
const sheetId = `${meta.controlId}-sheet`;
|
|
926
|
+
// The status line holds the field's message slot, so it carries the `<id>-error` every field family uses.
|
|
927
|
+
const statusId = meta.errorId;
|
|
928
|
+
const name = () => fieldName(props.owner);
|
|
929
|
+
const parse = value => parseDateInput(value, {
|
|
930
|
+
today: today(),
|
|
931
|
+
locale: locale()
|
|
932
|
+
});
|
|
933
|
+
const halves = createMemo(() => dirty() ? [parse(startText()), parse(endText())] : undefined);
|
|
934
|
+
const draft = createMemo(() => {
|
|
935
|
+
const current = halves();
|
|
936
|
+
if (!current) return props.value();
|
|
937
|
+
const [start, end] = current;
|
|
938
|
+
return {
|
|
939
|
+
start: start.kind === "date" ? start.date : null,
|
|
940
|
+
end: end.kind === "date" ? end.date : null
|
|
941
|
+
};
|
|
942
|
+
});
|
|
943
|
+
const shownRange = createMemo(() => previewRange(picked(), anchor(), previewDate()));
|
|
944
|
+
const fill = range => {
|
|
945
|
+
setStartText(format(range.start));
|
|
946
|
+
setEndText(format(range.end));
|
|
947
|
+
};
|
|
948
|
+
createEffect(on([props.value, locale], () => {
|
|
949
|
+
if (dirty()) return;
|
|
950
|
+
fill(props.value());
|
|
951
|
+
setPicked(props.value());
|
|
952
|
+
setFailure(undefined);
|
|
953
|
+
}));
|
|
954
|
+
createEffect(on(draft, range => {
|
|
955
|
+
// A day picked in the calendar wrote this text itself; its half-picked range keeps going.
|
|
956
|
+
if (!dirty() || range.start === picked().start && range.end === picked().end) return;
|
|
957
|
+
setPicked(range);
|
|
958
|
+
setAnchor(null);
|
|
959
|
+
if (range.start || range.end) setVisibleMonth(parseDateValue(range.start || range.end, props.dateConfig()));
|
|
960
|
+
setFailure(undefined);
|
|
961
|
+
}));
|
|
962
|
+
onCleanup(() => clearTimeout(announceTimer));
|
|
963
|
+
const externalError = () => resolveMaybeAccessor(props.owner.error);
|
|
964
|
+
const invalid = () => Boolean(failure() || externalError());
|
|
965
|
+
const status = createMemo(() => {
|
|
966
|
+
const failed = failure();
|
|
967
|
+
if (failed) return {
|
|
968
|
+
tone: "error",
|
|
969
|
+
text: failed
|
|
970
|
+
};
|
|
971
|
+
const current = halves();
|
|
972
|
+
if (current) {
|
|
973
|
+
const mistake = current.find(half => half.kind === "error");
|
|
974
|
+
if (mistake) return {
|
|
975
|
+
tone: "rest",
|
|
976
|
+
text: typingStatusText(mistake.error, locale(), t(), today())
|
|
977
|
+
};
|
|
978
|
+
const range = draft();
|
|
979
|
+
const limit = [range.start, range.end].map(key => key && limitErrorText(key, limits(), locale(), t())).find(Boolean);
|
|
980
|
+
if (limit) return {
|
|
981
|
+
tone: "rest",
|
|
982
|
+
text: limit
|
|
983
|
+
};
|
|
984
|
+
const text = rangeStatusText(range, locale(), t());
|
|
985
|
+
return {
|
|
986
|
+
tone: text ? "draft" : "rest",
|
|
987
|
+
text: text ? `→ ${text}` : ""
|
|
988
|
+
};
|
|
989
|
+
}
|
|
990
|
+
const external = externalError();
|
|
991
|
+
if (external) return {
|
|
992
|
+
tone: "error",
|
|
993
|
+
text: external
|
|
994
|
+
};
|
|
995
|
+
return {
|
|
996
|
+
tone: "rest",
|
|
997
|
+
text: rangeStatusText(props.value(), locale(), t())
|
|
998
|
+
};
|
|
999
|
+
});
|
|
1000
|
+
const save = next => {
|
|
1001
|
+
if (next.start !== props.value().start || next.end !== props.value().end) commitFieldValue(props.owner, next);
|
|
1002
|
+
};
|
|
1003
|
+
const fail = message => {
|
|
1004
|
+
setFailure(message);
|
|
1005
|
+
setAnnouncement(message);
|
|
1006
|
+
};
|
|
1007
|
+
const commitRange = range => {
|
|
1008
|
+
setDirty(false);
|
|
1009
|
+
const limit = [range.start, range.end].map(key => key && limitErrorText(key, limits(), locale(), t())).find(Boolean);
|
|
1010
|
+
if (limit) return fail(limit);
|
|
1011
|
+
if (range.start && range.end && range.end < range.start) return fail(t().endBeforeStart);
|
|
1012
|
+
if (range.start && !range.end) return fail(t().missingEnd);
|
|
1013
|
+
if (range.end && !range.start) return fail(t().missingStart);
|
|
1014
|
+
if (!range.start && props.owner.required) return fail(t().required);
|
|
1015
|
+
setFailure(undefined);
|
|
1016
|
+
fill(range);
|
|
1017
|
+
setPicked(range);
|
|
1018
|
+
save(range);
|
|
1019
|
+
};
|
|
1020
|
+
const commit = () => {
|
|
1021
|
+
const [start, end] = [parse(startText()), parse(endText())];
|
|
1022
|
+
const mistake = [start, end].find(half => half.kind === "error");
|
|
1023
|
+
if (mistake) {
|
|
1024
|
+
setDirty(false);
|
|
1025
|
+
return fail(errorText(mistake.error, locale(), t(), today()));
|
|
1026
|
+
}
|
|
1027
|
+
commitRange({
|
|
1028
|
+
start: start.kind === "date" ? start.date : null,
|
|
1029
|
+
end: end.kind === "date" ? end.date : null
|
|
1030
|
+
});
|
|
1031
|
+
};
|
|
1032
|
+
const restore = () => {
|
|
1033
|
+
fill(props.value());
|
|
1034
|
+
setPicked(props.value());
|
|
1035
|
+
setAnchor(null);
|
|
1036
|
+
setDirty(false);
|
|
1037
|
+
setFailure(undefined);
|
|
1038
|
+
calendar.close();
|
|
1039
|
+
};
|
|
1040
|
+
/** Calendar clicks fill both halves at once, so the text, the status line and the calendar show the same range. */
|
|
1041
|
+
const pickDay = key => {
|
|
1042
|
+
const next = pickRangeDay(picked(), anchor(), key);
|
|
1043
|
+
// One update: the start alone would read as a typed range and reset the anchor of the next click.
|
|
1044
|
+
batch(() => {
|
|
1045
|
+
setPicked(next.range);
|
|
1046
|
+
setAnchor(next.anchor);
|
|
1047
|
+
setPreviewDate(null);
|
|
1048
|
+
fill(next.range);
|
|
1049
|
+
setDirty(true);
|
|
1050
|
+
});
|
|
1051
|
+
};
|
|
1052
|
+
const apply = range => {
|
|
1053
|
+
commitRange(range);
|
|
1054
|
+
calendar.close();
|
|
1055
|
+
};
|
|
1056
|
+
const canApply = () => Boolean(picked().start) === Boolean(picked().end);
|
|
1057
|
+
const rangeCalendar = onApply => [_$ssr(_tmpl$26, _$escape(_$createComponent(Show, {
|
|
1058
|
+
get when() {
|
|
1059
|
+
return props.owner.datePresets?.length;
|
|
1060
|
+
},
|
|
1061
|
+
get fallback() {
|
|
1062
|
+
return _$createComponent(PresetRail, {
|
|
1063
|
+
get presets() {
|
|
1064
|
+
return props.owner.presets;
|
|
1065
|
+
},
|
|
1066
|
+
onSelect: onApply
|
|
1067
|
+
});
|
|
1068
|
+
},
|
|
1069
|
+
get children() {
|
|
1070
|
+
return _$createComponent(PresetRail, {
|
|
1071
|
+
get presets() {
|
|
1072
|
+
return props.owner.datePresets;
|
|
1073
|
+
},
|
|
1074
|
+
onSelect: value => {
|
|
1075
|
+
const next = value ? {
|
|
1076
|
+
start: value,
|
|
1077
|
+
end: value
|
|
1078
|
+
} : {
|
|
1079
|
+
start: null,
|
|
1080
|
+
end: null
|
|
1081
|
+
};
|
|
1082
|
+
batch(() => {
|
|
1083
|
+
setPicked(next);
|
|
1084
|
+
setAnchor(null);
|
|
1085
|
+
fill(next);
|
|
1086
|
+
setDirty(true);
|
|
1087
|
+
});
|
|
1088
|
+
if (value) setVisibleMonth(parseDateValue(value, props.dateConfig()));
|
|
1089
|
+
}
|
|
1090
|
+
});
|
|
1091
|
+
}
|
|
1092
|
+
})), _$escape(_$createComponent(DatePickerPanel, {
|
|
1093
|
+
visibleMonth: visibleMonth,
|
|
1094
|
+
setVisibleMonth: setVisibleMonth,
|
|
1095
|
+
range: shownRange,
|
|
1096
|
+
focusDate: () => picked().start,
|
|
1097
|
+
onSelect: pickDay,
|
|
1098
|
+
onDayPreview: key => setPreviewDate(rangeAnchor(picked(), anchor()) ? key : null),
|
|
1099
|
+
get dateConfig() {
|
|
1100
|
+
return props.dateConfig();
|
|
1101
|
+
},
|
|
1102
|
+
get min() {
|
|
1103
|
+
return props.owner.min;
|
|
1104
|
+
},
|
|
1105
|
+
get max() {
|
|
1106
|
+
return props.owner.max;
|
|
1107
|
+
}
|
|
1108
|
+
}))), _$ssr(_tmpl$29, _$escape(_$createComponent(Show, {
|
|
1109
|
+
get when() {
|
|
1110
|
+
return formatDateOnlyRangeDuration(shownRange(), props.dateConfig());
|
|
1111
|
+
},
|
|
1112
|
+
children: duration => _$ssr(_tmpl$30, _$escape(duration()))
|
|
1113
|
+
})), _$ssrAttribute("disabled", !canApply(), true), _$escape(uiMessages().apply))];
|
|
1114
|
+
const openSheet = async () => {
|
|
1115
|
+
setSheetOpen(true);
|
|
1116
|
+
calendar.close();
|
|
1117
|
+
const before = {
|
|
1118
|
+
start: startText(),
|
|
1119
|
+
end: endText(),
|
|
1120
|
+
dirty: dirty()
|
|
1121
|
+
};
|
|
1122
|
+
// Every opening starts from the text, also after a dismissed sheet left other days picked.
|
|
1123
|
+
batch(() => {
|
|
1124
|
+
setPicked(draft());
|
|
1125
|
+
setAnchor(null);
|
|
1126
|
+
setPreviewDate(null);
|
|
1127
|
+
});
|
|
1128
|
+
const {
|
|
1129
|
+
openDateSheet
|
|
1130
|
+
} = await import("./date-sheet");
|
|
1131
|
+
const range = await openDateSheet({
|
|
1132
|
+
title: props.owner.label ?? props.owner["aria-label"],
|
|
1133
|
+
subtitle: rangeStatusText(props.value(), locale(), t()) || t().noDate,
|
|
1134
|
+
ariaLabel: name(),
|
|
1135
|
+
id: sheetId,
|
|
1136
|
+
locale: locale() ?? "en",
|
|
1137
|
+
content: close => rangeCalendar(next => {
|
|
1138
|
+
// Saved at once, as in the single date sheet.
|
|
1139
|
+
commitRange(next);
|
|
1140
|
+
close(next);
|
|
1141
|
+
})
|
|
1142
|
+
});
|
|
1143
|
+
setSheetOpen(false);
|
|
1144
|
+
// A dismissed sheet saves nothing and leaves the text as it was before the sheet opened.
|
|
1145
|
+
if (!range) batch(() => {
|
|
1146
|
+
setStartText(before.start);
|
|
1147
|
+
setEndText(before.end);
|
|
1148
|
+
setDirty(before.dirty);
|
|
1149
|
+
setAnchor(null);
|
|
1150
|
+
});
|
|
1151
|
+
toggle?.focus({
|
|
1152
|
+
preventScroll: true
|
|
1153
|
+
});
|
|
1154
|
+
};
|
|
1155
|
+
const openCalendar = focusDay => {
|
|
1156
|
+
if (!interactive()) return;
|
|
1157
|
+
setAnchor(null);
|
|
1158
|
+
setPreviewDate(null);
|
|
1159
|
+
setPicked(draft());
|
|
1160
|
+
if (prefersMenuSheet()) return void openSheet();
|
|
1161
|
+
const range = draft();
|
|
1162
|
+
setVisibleMonth(parseDateValue(openingDay(range.start || range.end, limits(), props.dateConfig()), props.dateConfig()));
|
|
1163
|
+
calendar.show();
|
|
1164
|
+
if (focusDay) calendar.focusDay();
|
|
1165
|
+
};
|
|
1166
|
+
const onPointerDown = event => {
|
|
1167
|
+
const target = event.target;
|
|
1168
|
+
if (!interactive() || calendar.element()?.contains(target) || target.closest(".k2b-date-field__clear")) return;
|
|
1169
|
+
const onIcon = target.closest(".k2b-date-field__toggle, .k2b-date-field__icon");
|
|
1170
|
+
if (prefersMenuSheet()) {
|
|
1171
|
+
if (onIcon) {
|
|
1172
|
+
event.preventDefault();
|
|
1173
|
+
void openSheet();
|
|
1174
|
+
}
|
|
1175
|
+
return;
|
|
1176
|
+
}
|
|
1177
|
+
if (onIcon) {
|
|
1178
|
+
event.preventDefault();
|
|
1179
|
+
if (!shell?.contains(document.activeElement)) startInput?.focus();
|
|
1180
|
+
if (calendar.open()) calendar.close();else openCalendar(false);
|
|
1181
|
+
return;
|
|
1182
|
+
}
|
|
1183
|
+
if (event.button === 0 && !calendar.open()) setTimeout(() => openCalendar(false));
|
|
1184
|
+
};
|
|
1185
|
+
const onKeyDown = event => {
|
|
1186
|
+
// A refused text keeps Enter too, so it does not submit the form around it.
|
|
1187
|
+
if (event.key === "Enter" && (dirty() || calendar.open() || failure())) {
|
|
1188
|
+
event.preventDefault();
|
|
1189
|
+
commit();
|
|
1190
|
+
calendar.close();
|
|
1191
|
+
} else if (event.key === "Escape" && (dirty() || calendar.open() || failure())) {
|
|
1192
|
+
event.preventDefault();
|
|
1193
|
+
event.stopPropagation();
|
|
1194
|
+
restore();
|
|
1195
|
+
} else if (event.key === "ArrowDown") {
|
|
1196
|
+
event.preventDefault();
|
|
1197
|
+
openCalendar(true);
|
|
1198
|
+
} else if (event.key === "ArrowUp" && event.altKey) {
|
|
1199
|
+
event.preventDefault();
|
|
1200
|
+
calendar.close();
|
|
1201
|
+
}
|
|
1202
|
+
};
|
|
1203
|
+
const onInput = setter => event => {
|
|
1204
|
+
setter(event.currentTarget.value);
|
|
1205
|
+
setDirty(true);
|
|
1206
|
+
clearTimeout(announceTimer);
|
|
1207
|
+
announceTimer = setTimeout(() => {
|
|
1208
|
+
const range = draft();
|
|
1209
|
+
setAnnouncement(range.start || range.end ? rangeStatusText(range, locale(), t()) : "");
|
|
1210
|
+
}, 500);
|
|
1211
|
+
};
|
|
1212
|
+
const onPaste = event => {
|
|
1213
|
+
const parts = splitPastedRange(event.clipboardData?.getData("text") ?? "");
|
|
1214
|
+
if (!parts) return;
|
|
1215
|
+
event.preventDefault();
|
|
1216
|
+
setStartText(parts[0]);
|
|
1217
|
+
setEndText(parts[1]);
|
|
1218
|
+
setDirty(true);
|
|
1219
|
+
};
|
|
1220
|
+
const onFocusOut = event => {
|
|
1221
|
+
const next = event.relatedTarget;
|
|
1222
|
+
if (sheetOpen() || next && shell?.contains(next)) return;
|
|
1223
|
+
if (dirty()) commit();
|
|
1224
|
+
calendar.close();
|
|
1225
|
+
};
|
|
1226
|
+
const inputProps = {
|
|
1227
|
+
class: "k2b-input",
|
|
1228
|
+
type: "text",
|
|
1229
|
+
inputMode: "numeric",
|
|
1230
|
+
autocomplete: "off",
|
|
1231
|
+
spellcheck: false,
|
|
1232
|
+
"aria-haspopup": "dialog",
|
|
1233
|
+
onKeyDown,
|
|
1234
|
+
onPaste
|
|
1235
|
+
};
|
|
1236
|
+
const describedBy = () => [props.owner["aria-describedby"], props.owner.description ? meta.descriptionId : undefined, statusId].filter(Boolean).join(" ");
|
|
1237
|
+
return _$createComponent(Field, {
|
|
1238
|
+
get ["class"]() {
|
|
1239
|
+
return props.owner.class;
|
|
1240
|
+
},
|
|
1241
|
+
get label() {
|
|
1242
|
+
return props.owner.label;
|
|
1243
|
+
},
|
|
1244
|
+
get description() {
|
|
1245
|
+
return props.owner.description;
|
|
1246
|
+
},
|
|
1247
|
+
get required() {
|
|
1248
|
+
return props.owner.required;
|
|
1249
|
+
},
|
|
1250
|
+
get disabled() {
|
|
1251
|
+
return props.owner.disabled;
|
|
1252
|
+
},
|
|
1253
|
+
meta: meta,
|
|
1254
|
+
get children() {
|
|
1255
|
+
return _$ssr(_tmpl$31, _$ssrAttribute("data-open", calendar.open() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-readonly", props.owner.readOnly ? "true" : _$escape(undefined, true), false), _$ssrAttribute("aria-labelledby", props.owner.label ? _$escape(meta.labelId, true) : _$escape(undefined, true), false) + _$ssrAttribute("aria-label", props.owner.label ? _$escape(undefined, true) : _$escape(props.owner["aria-label"], true), false) + _$ssrAttribute("data-invalid", invalid() ? "true" : _$escape(undefined, true), false), _$ssrElement("input", _$mergeProps(inputProps, {
|
|
1256
|
+
role: "combobox",
|
|
1257
|
+
get ["aria-controls"]() {
|
|
1258
|
+
return sheetOpen() ? sheetId : popoverId;
|
|
1259
|
+
},
|
|
1260
|
+
get id() {
|
|
1261
|
+
return meta.controlId;
|
|
1262
|
+
},
|
|
1263
|
+
get ["aria-label"]() {
|
|
1264
|
+
return name() ? t().startOf({
|
|
1265
|
+
label: name()
|
|
1266
|
+
}) : t().start;
|
|
1267
|
+
},
|
|
1268
|
+
get ["aria-expanded"]() {
|
|
1269
|
+
return calendar.open() || sheetOpen();
|
|
1270
|
+
},
|
|
1271
|
+
get ["aria-describedby"]() {
|
|
1272
|
+
return describedBy();
|
|
1273
|
+
},
|
|
1274
|
+
get ["aria-invalid"]() {
|
|
1275
|
+
return invalid() ? "true" : undefined;
|
|
1276
|
+
},
|
|
1277
|
+
get ["aria-required"]() {
|
|
1278
|
+
return props.owner.required || undefined;
|
|
1279
|
+
},
|
|
1280
|
+
get placeholder() {
|
|
1281
|
+
return t().start;
|
|
1282
|
+
},
|
|
1283
|
+
get value() {
|
|
1284
|
+
return startText();
|
|
1285
|
+
},
|
|
1286
|
+
get disabled() {
|
|
1287
|
+
return props.owner.disabled;
|
|
1288
|
+
},
|
|
1289
|
+
get readOnly() {
|
|
1290
|
+
return props.owner.readOnly;
|
|
1291
|
+
}
|
|
1292
|
+
}), undefined, false), _$ssrElement("input", _$mergeProps(inputProps, {
|
|
1293
|
+
role: "combobox",
|
|
1294
|
+
get ["aria-controls"]() {
|
|
1295
|
+
return sheetOpen() ? sheetId : popoverId;
|
|
1296
|
+
},
|
|
1297
|
+
get ["aria-label"]() {
|
|
1298
|
+
return name() ? t().endOf({
|
|
1299
|
+
label: name()
|
|
1300
|
+
}) : t().end;
|
|
1301
|
+
},
|
|
1302
|
+
get ["aria-expanded"]() {
|
|
1303
|
+
return calendar.open() || sheetOpen();
|
|
1304
|
+
},
|
|
1305
|
+
get ["aria-describedby"]() {
|
|
1306
|
+
return describedBy();
|
|
1307
|
+
},
|
|
1308
|
+
get ["aria-invalid"]() {
|
|
1309
|
+
return invalid() ? "true" : undefined;
|
|
1310
|
+
},
|
|
1311
|
+
get ["aria-required"]() {
|
|
1312
|
+
return props.owner.required || undefined;
|
|
1313
|
+
},
|
|
1314
|
+
get placeholder() {
|
|
1315
|
+
return t().end;
|
|
1316
|
+
},
|
|
1317
|
+
get value() {
|
|
1318
|
+
return endText();
|
|
1319
|
+
},
|
|
1320
|
+
get disabled() {
|
|
1321
|
+
return props.owner.disabled;
|
|
1322
|
+
},
|
|
1323
|
+
get readOnly() {
|
|
1324
|
+
return props.owner.readOnly;
|
|
1325
|
+
}
|
|
1326
|
+
}), undefined, false), _$escape(_$createComponent(Show, {
|
|
1327
|
+
get when() {
|
|
1328
|
+
return _$memo(() => !!props.owner.clearable)() && interactive();
|
|
1329
|
+
},
|
|
1330
|
+
get children() {
|
|
1331
|
+
return _$ssr(_tmpl$24, _$ssrAttribute("data-hidden", startText() || endText() ? _$escape(undefined, true) : "true", false) + _$ssrAttribute("aria-label", _$escape(uiMessages().clearDate, true), false));
|
|
1332
|
+
}
|
|
1333
|
+
})), _$escape(_$createComponent(Show, {
|
|
1334
|
+
get when() {
|
|
1335
|
+
return !props.owner.readOnly;
|
|
1336
|
+
},
|
|
1337
|
+
get fallback() {
|
|
1338
|
+
return _$ssr(_tmpl$28);
|
|
1339
|
+
},
|
|
1340
|
+
get children() {
|
|
1341
|
+
return _$ssr(_tmpl$25, _$ssrAttribute("disabled", props.owner.disabled, true) + _$ssrAttribute("aria-label", calendar.open() ? _$escape(t().closeCalendar, true) : _$escape(t().openCalendar, true), false) + _$ssrAttribute("aria-expanded", _$escape(calendar.open() || sheetOpen(), true), false) + _$ssrAttribute("aria-controls", sheetOpen() ? _$escape(sheetId, true) : _$escape(popoverId, true), false));
|
|
1342
|
+
}
|
|
1343
|
+
})), _$ssrAttribute("id", _$escape(popoverId, true), false), _$ssrAttribute("aria-label", _$escape(name() ?? uiMessages().datePicker, true), false), _$escape(_$createComponent(Show, {
|
|
1344
|
+
get when() {
|
|
1345
|
+
return calendar.open();
|
|
1346
|
+
},
|
|
1347
|
+
get children() {
|
|
1348
|
+
return rangeCalendar(range => {
|
|
1349
|
+
apply(range);
|
|
1350
|
+
caretToEnd(endInput);
|
|
1351
|
+
});
|
|
1352
|
+
}
|
|
1353
|
+
})), _$escape(_$createComponent(DateStatusLine, {
|
|
1354
|
+
id: statusId,
|
|
1355
|
+
get tone() {
|
|
1356
|
+
return status().tone;
|
|
1357
|
+
},
|
|
1358
|
+
get text() {
|
|
1359
|
+
return status().text;
|
|
1360
|
+
},
|
|
1361
|
+
get announcement() {
|
|
1362
|
+
return announcement();
|
|
1363
|
+
}
|
|
1364
|
+
})));
|
|
1365
|
+
}
|
|
1366
|
+
});
|
|
1367
|
+
}
|
|
406
1368
|
export function DatePicker(props) {
|
|
407
1369
|
const value = () => resolveMaybeAccessor(props.value);
|
|
408
1370
|
const dateConfig = useDateConfigLocale(() => props.dateConfig);
|
|
409
1371
|
const [visibleMonth, setVisibleMonth] = createSignal(parseDateValue(value(), dateConfig()));
|
|
410
1372
|
const valueLabel = () => displayDate(value(), dateConfig());
|
|
411
|
-
return _$createComponent(
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
valueLabel: valueLabel,
|
|
415
|
-
get valueContent() {
|
|
416
|
-
return props.renderValue ? () => props.renderValue(value()) : undefined;
|
|
1373
|
+
return _$createComponent(Show, {
|
|
1374
|
+
get when() {
|
|
1375
|
+
return props.appearance === "plain";
|
|
417
1376
|
},
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
1377
|
+
get fallback() {
|
|
1378
|
+
return _$createComponent(DateTextField, {
|
|
1379
|
+
owner: props,
|
|
1380
|
+
value: value,
|
|
1381
|
+
dateConfig: dateConfig
|
|
1382
|
+
});
|
|
422
1383
|
},
|
|
423
|
-
children
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
1384
|
+
get children() {
|
|
1385
|
+
return _$createComponent(PickerShell, {
|
|
1386
|
+
owner: props,
|
|
1387
|
+
icon: "ti ti-calendar",
|
|
1388
|
+
valueLabel: valueLabel,
|
|
1389
|
+
get valueContent() {
|
|
1390
|
+
return props.renderValue ? () => props.renderValue(value()) : undefined;
|
|
1391
|
+
},
|
|
1392
|
+
clearValue: null,
|
|
1393
|
+
onOpen: () => setVisibleMonth(parseDateValue(openingDay(value(), {
|
|
1394
|
+
min: props.min,
|
|
1395
|
+
max: props.max
|
|
1396
|
+
}, dateConfig()), dateConfig())),
|
|
1397
|
+
get wide() {
|
|
1398
|
+
return Boolean(props.presets?.length);
|
|
1399
|
+
},
|
|
1400
|
+
children: close => _$ssr(_tmpl$26, _$escape(_$createComponent(PresetRail, {
|
|
1401
|
+
get presets() {
|
|
1402
|
+
return props.presets;
|
|
1403
|
+
},
|
|
1404
|
+
onSelect: value => {
|
|
1405
|
+
close();
|
|
1406
|
+
commitFieldValue(props, value);
|
|
1407
|
+
}
|
|
1408
|
+
})), _$escape(_$createComponent(DatePickerPanel, {
|
|
1409
|
+
visibleMonth: visibleMonth,
|
|
1410
|
+
setVisibleMonth: setVisibleMonth,
|
|
1411
|
+
selected: value,
|
|
1412
|
+
focusDate: value,
|
|
1413
|
+
onSelect: value => {
|
|
1414
|
+
close();
|
|
1415
|
+
commitFieldValue(props, value);
|
|
1416
|
+
},
|
|
1417
|
+
get dateConfig() {
|
|
1418
|
+
return dateConfig();
|
|
1419
|
+
},
|
|
1420
|
+
get min() {
|
|
1421
|
+
return props.min;
|
|
1422
|
+
},
|
|
1423
|
+
get max() {
|
|
1424
|
+
return props.max;
|
|
1425
|
+
}
|
|
1426
|
+
})))
|
|
1427
|
+
});
|
|
1428
|
+
}
|
|
444
1429
|
});
|
|
445
1430
|
}
|
|
446
1431
|
export function DateTimePicker(props) {
|
|
@@ -463,7 +1448,10 @@ export function DateTimePicker(props) {
|
|
|
463
1448
|
setDraftDate(next.date);
|
|
464
1449
|
setDraftTime(next.time || defaultTime());
|
|
465
1450
|
setWithTime(valueHasTime());
|
|
466
|
-
setVisibleMonth(parseDateValue(next.date,
|
|
1451
|
+
setVisibleMonth(parseDateValue(openingDay(next.date, {
|
|
1452
|
+
min: props.min,
|
|
1453
|
+
max: props.max
|
|
1454
|
+
}, dateConfig()), dateConfig()));
|
|
467
1455
|
};
|
|
468
1456
|
const canApply = () => Boolean(draftDate()) && (!withTime() || isCompleteTime(draftTime()));
|
|
469
1457
|
const draftValue = () => withTime() ? toDateTimeValue(draftDate(), draftTime(), dateConfig()) : draftDate() || null;
|
|
@@ -499,7 +1487,7 @@ export function DateTimePicker(props) {
|
|
|
499
1487
|
close();
|
|
500
1488
|
commitFieldValue(props, next);
|
|
501
1489
|
};
|
|
502
|
-
return [_$ssr(_tmpl$
|
|
1490
|
+
return [_$ssr(_tmpl$26, _$escape(_$createComponent(PresetRail, {
|
|
503
1491
|
get presets() {
|
|
504
1492
|
return props.presets;
|
|
505
1493
|
},
|
|
@@ -520,8 +1508,14 @@ export function DateTimePicker(props) {
|
|
|
520
1508
|
},
|
|
521
1509
|
get dateConfig() {
|
|
522
1510
|
return dateConfig();
|
|
1511
|
+
},
|
|
1512
|
+
get min() {
|
|
1513
|
+
return props.min;
|
|
1514
|
+
},
|
|
1515
|
+
get max() {
|
|
1516
|
+
return props.max;
|
|
523
1517
|
}
|
|
524
|
-
}))), _$ssr(_tmpl$
|
|
1518
|
+
}))), _$ssr(_tmpl$29, _$escape(_$createComponent(Show, {
|
|
525
1519
|
get when() {
|
|
526
1520
|
return props.optionalTime;
|
|
527
1521
|
},
|
|
@@ -534,12 +1528,12 @@ export function DateTimePicker(props) {
|
|
|
534
1528
|
});
|
|
535
1529
|
},
|
|
536
1530
|
get children() {
|
|
537
|
-
return _$ssr(_tmpl$
|
|
1531
|
+
return _$ssr(_tmpl$33, _$ssrAttribute("data-with-time", withTime() ? "true" : _$escape(undefined, true), false), _$escape(_$createComponent(Show, {
|
|
538
1532
|
get when() {
|
|
539
1533
|
return withTime();
|
|
540
1534
|
},
|
|
541
1535
|
get fallback() {
|
|
542
|
-
return _$ssr(_tmpl$
|
|
1536
|
+
return _$ssr(_tmpl$34, _$escape(messages().addTime));
|
|
543
1537
|
},
|
|
544
1538
|
get children() {
|
|
545
1539
|
return [_$createComponent(TimeInput, {
|
|
@@ -547,7 +1541,7 @@ export function DateTimePicker(props) {
|
|
|
547
1541
|
return draftTime();
|
|
548
1542
|
},
|
|
549
1543
|
onChange: setDraftTime
|
|
550
|
-
}), _$ssr(_tmpl$
|
|
1544
|
+
}), _$ssr(_tmpl$32, _$ssrAttribute("aria-label", _$escape(messages().removeTime, true), false) + _$ssrAttribute("title", _$escape(messages().removeTime, true), false))];
|
|
551
1545
|
}
|
|
552
1546
|
})));
|
|
553
1547
|
}
|
|
@@ -591,7 +1585,10 @@ export function DateRangePicker(props) {
|
|
|
591
1585
|
setPreviewDate(null);
|
|
592
1586
|
setStartTime(next.start.time || "09:00");
|
|
593
1587
|
setEndTime(next.end.time || "10:00");
|
|
594
|
-
setVisibleMonth(parseDateValue(next.start.date || next.end.date,
|
|
1588
|
+
setVisibleMonth(parseDateValue(openingDay(next.start.date || next.end.date, {
|
|
1589
|
+
min: props.min,
|
|
1590
|
+
max: props.max
|
|
1591
|
+
}, dateConfig()), dateConfig()));
|
|
595
1592
|
};
|
|
596
1593
|
const valueLabel = () => {
|
|
597
1594
|
if (!value().start && !value().end) return "";
|
|
@@ -600,7 +1597,7 @@ export function DateRangePicker(props) {
|
|
|
600
1597
|
};
|
|
601
1598
|
const valueContent = () => {
|
|
602
1599
|
const format = withTime() ? formatDateTimeValue : displayDate;
|
|
603
|
-
return _$ssr(_tmpl$
|
|
1600
|
+
return _$ssr(_tmpl$35, value().start ? _$escape(format(value().start, dateConfig())) : _$escape(messages().start), value().end ? _$escape(format(value().end, dateConfig())) : "End");
|
|
604
1601
|
};
|
|
605
1602
|
const selectDate = value => {
|
|
606
1603
|
const next = pickRangeDay(draftRange(), anchor(), value);
|
|
@@ -653,108 +1650,128 @@ export function DateRangePicker(props) {
|
|
|
653
1650
|
close();
|
|
654
1651
|
commitFieldValue(props, value);
|
|
655
1652
|
};
|
|
656
|
-
return _$createComponent(
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
valueLabel: valueLabel,
|
|
660
|
-
valueContent: valueContent,
|
|
661
|
-
clearValue: {
|
|
662
|
-
start: null,
|
|
663
|
-
end: null
|
|
1653
|
+
return _$createComponent(Show, {
|
|
1654
|
+
get when() {
|
|
1655
|
+
return props.appearance === "plain" || withTime();
|
|
664
1656
|
},
|
|
665
|
-
get
|
|
666
|
-
return _$
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
get
|
|
687
|
-
return
|
|
1657
|
+
get fallback() {
|
|
1658
|
+
return _$createComponent(DateRangeTextField, {
|
|
1659
|
+
owner: props,
|
|
1660
|
+
value: value,
|
|
1661
|
+
dateConfig: dateConfig
|
|
1662
|
+
});
|
|
1663
|
+
},
|
|
1664
|
+
get children() {
|
|
1665
|
+
return _$createComponent(PickerShell, {
|
|
1666
|
+
owner: props,
|
|
1667
|
+
icon: "ti ti-calendar-stats",
|
|
1668
|
+
valueLabel: valueLabel,
|
|
1669
|
+
valueContent: valueContent,
|
|
1670
|
+
clearValue: {
|
|
1671
|
+
start: null,
|
|
1672
|
+
end: null
|
|
1673
|
+
},
|
|
1674
|
+
get timezone() {
|
|
1675
|
+
return _$memo(() => !!withTime())() ? dateConfig().timeZone : undefined;
|
|
1676
|
+
},
|
|
1677
|
+
footerMeta: () => _$createComponent(Show, {
|
|
1678
|
+
get when() {
|
|
1679
|
+
return durationLabel();
|
|
688
1680
|
},
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
commitFieldValue(props, value);
|
|
1681
|
+
get children() {
|
|
1682
|
+
return _$ssr(_tmpl$30, _$escape(durationLabel()));
|
|
692
1683
|
}
|
|
693
|
-
})
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
1684
|
+
}),
|
|
1685
|
+
onOpen: syncDraft,
|
|
1686
|
+
get wide() {
|
|
1687
|
+
return Boolean(props.datePresets?.length || props.presets?.length);
|
|
1688
|
+
},
|
|
1689
|
+
children: close => [_$ssr(_tmpl$26, _$escape(_$createComponent(Show, {
|
|
1690
|
+
get when() {
|
|
1691
|
+
return props.datePresets?.length;
|
|
699
1692
|
},
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
1693
|
+
get fallback() {
|
|
1694
|
+
return _$createComponent(PresetRail, {
|
|
1695
|
+
get presets() {
|
|
1696
|
+
return props.presets;
|
|
1697
|
+
},
|
|
1698
|
+
onSelect: value => {
|
|
1699
|
+
close();
|
|
1700
|
+
commitFieldValue(props, value);
|
|
1701
|
+
}
|
|
707
1702
|
});
|
|
708
|
-
if (value) setVisibleMonth(parseDateValue(value, dateConfig()));
|
|
709
|
-
}
|
|
710
|
-
});
|
|
711
|
-
}
|
|
712
|
-
})), _$escape(_$createComponent(DatePickerPanel, {
|
|
713
|
-
visibleMonth: visibleMonth,
|
|
714
|
-
setVisibleMonth: setVisibleMonth,
|
|
715
|
-
range: displayRange,
|
|
716
|
-
focusDate: () => draftRange().start,
|
|
717
|
-
onSelect: selectDate,
|
|
718
|
-
onDayPreview: value => setPreviewDate(rangeAnchor(draftRange(), anchor()) ? value : null),
|
|
719
|
-
get dateConfig() {
|
|
720
|
-
return dateConfig();
|
|
721
|
-
}
|
|
722
|
-
}))), _$createComponent(Show, {
|
|
723
|
-
get when() {
|
|
724
|
-
return withTime();
|
|
725
|
-
},
|
|
726
|
-
get children() {
|
|
727
|
-
return _$ssr(_tmpl$28, _$escape(_$createComponent(TimeInput, {
|
|
728
|
-
get label() {
|
|
729
|
-
return messages().start;
|
|
730
1703
|
},
|
|
731
|
-
get
|
|
732
|
-
return
|
|
1704
|
+
get children() {
|
|
1705
|
+
return _$createComponent(PresetRail, {
|
|
1706
|
+
get presets() {
|
|
1707
|
+
return props.datePresets;
|
|
1708
|
+
},
|
|
1709
|
+
onSelect: value => {
|
|
1710
|
+
setDraftRange(value ? {
|
|
1711
|
+
start: value,
|
|
1712
|
+
end: value
|
|
1713
|
+
} : {
|
|
1714
|
+
start: null,
|
|
1715
|
+
end: null
|
|
1716
|
+
});
|
|
1717
|
+
if (value) setVisibleMonth(parseDateValue(value, dateConfig()));
|
|
1718
|
+
}
|
|
1719
|
+
});
|
|
1720
|
+
}
|
|
1721
|
+
})), _$escape(_$createComponent(DatePickerPanel, {
|
|
1722
|
+
visibleMonth: visibleMonth,
|
|
1723
|
+
setVisibleMonth: setVisibleMonth,
|
|
1724
|
+
range: displayRange,
|
|
1725
|
+
focusDate: () => draftRange().start,
|
|
1726
|
+
onSelect: selectDate,
|
|
1727
|
+
onDayPreview: value => setPreviewDate(rangeAnchor(draftRange(), anchor()) ? value : null),
|
|
1728
|
+
get dateConfig() {
|
|
1729
|
+
return dateConfig();
|
|
733
1730
|
},
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
get label() {
|
|
737
|
-
return messages().end;
|
|
1731
|
+
get min() {
|
|
1732
|
+
return props.min;
|
|
738
1733
|
},
|
|
739
|
-
get
|
|
740
|
-
return
|
|
1734
|
+
get max() {
|
|
1735
|
+
return props.max;
|
|
1736
|
+
}
|
|
1737
|
+
}))), _$createComponent(Show, {
|
|
1738
|
+
get when() {
|
|
1739
|
+
return withTime();
|
|
741
1740
|
},
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
1741
|
+
get children() {
|
|
1742
|
+
return _$ssr(_tmpl$36, _$escape(_$createComponent(TimeInput, {
|
|
1743
|
+
get label() {
|
|
1744
|
+
return messages().start;
|
|
1745
|
+
},
|
|
1746
|
+
get time() {
|
|
1747
|
+
return startTime();
|
|
1748
|
+
},
|
|
1749
|
+
onChange: setStartTime
|
|
1750
|
+
})), _$escape(_$createComponent(TimeInput, {
|
|
1751
|
+
get label() {
|
|
1752
|
+
return messages().end;
|
|
1753
|
+
},
|
|
1754
|
+
get time() {
|
|
1755
|
+
return endTime();
|
|
1756
|
+
},
|
|
1757
|
+
onChange: setEndTime
|
|
1758
|
+
})));
|
|
1759
|
+
}
|
|
1760
|
+
}), _$ssr(_tmpl$29, _$escape(_$createComponent(Show, {
|
|
1761
|
+
get when() {
|
|
1762
|
+
return _$memo(() => !!withTime())() && props.durationPresets?.length;
|
|
753
1763
|
},
|
|
754
|
-
children
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
1764
|
+
get children() {
|
|
1765
|
+
return _$ssr(_tmpl$37, _$ssrAttribute("aria-label", _$escape(messages().durationPresets, true), false), _$escape(_$createComponent(For, {
|
|
1766
|
+
get each() {
|
|
1767
|
+
return props.durationPresets;
|
|
1768
|
+
},
|
|
1769
|
+
children: preset => _$ssr(_tmpl$14, _$ssrAttribute("aria-pressed", _$escape(durationMinutes(), true) === _$escape(preset.minutes, true), false), _$escape(preset.label))
|
|
1770
|
+
})));
|
|
1771
|
+
}
|
|
1772
|
+
})), _$ssrAttribute("disabled", Boolean(draftRange().start) !== Boolean(draftRange().end) || Boolean(withTime() && draftRange().start && draftRange().end && (!isCompleteTime(startTime()) || !isCompleteTime(endTime()))), true), _$escape(messages().apply))]
|
|
1773
|
+
});
|
|
1774
|
+
}
|
|
758
1775
|
});
|
|
759
1776
|
}
|
|
760
1777
|
//# sourceMappingURL=DatePicker.js.map
|