@lekoala/slot-picker 0.1.0 → 0.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/README.md +85 -39
- package/custom-elements.json +0 -5
- package/dist/slot-picker.css +22 -0
- package/dist/slot-picker.js +160 -134
- package/dist/slot-picker.min.css +1 -1
- package/dist/slot-picker.min.js +24 -24
- package/dist/types/date.d.ts +8 -1
- package/dist/types/date.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/locales/ar.d.ts +0 -1
- package/dist/types/locales/ar.d.ts.map +1 -1
- package/dist/types/locales/de.d.ts +0 -1
- package/dist/types/locales/de.d.ts.map +1 -1
- package/dist/types/locales/en.d.ts +0 -1
- package/dist/types/locales/en.d.ts.map +1 -1
- package/dist/types/locales/es.d.ts +0 -1
- package/dist/types/locales/es.d.ts.map +1 -1
- package/dist/types/locales/fr.d.ts +0 -1
- package/dist/types/locales/fr.d.ts.map +1 -1
- package/dist/types/locales/hi.d.ts +0 -1
- package/dist/types/locales/hi.d.ts.map +1 -1
- package/dist/types/locales/id.d.ts +0 -1
- package/dist/types/locales/id.d.ts.map +1 -1
- package/dist/types/locales/it.d.ts +0 -1
- package/dist/types/locales/it.d.ts.map +1 -1
- package/dist/types/locales/ja.d.ts +0 -1
- package/dist/types/locales/ja.d.ts.map +1 -1
- package/dist/types/locales/ko.d.ts +0 -1
- package/dist/types/locales/ko.d.ts.map +1 -1
- package/dist/types/locales/nl.d.ts +0 -1
- package/dist/types/locales/nl.d.ts.map +1 -1
- package/dist/types/locales/pl.d.ts +0 -1
- package/dist/types/locales/pl.d.ts.map +1 -1
- package/dist/types/locales/pt-BR.d.ts +0 -1
- package/dist/types/locales/pt-BR.d.ts.map +1 -1
- package/dist/types/locales/pt-PT.d.ts +0 -1
- package/dist/types/locales/pt-PT.d.ts.map +1 -1
- package/dist/types/locales/ru.d.ts +0 -1
- package/dist/types/locales/ru.d.ts.map +1 -1
- package/dist/types/locales/tr.d.ts +0 -1
- package/dist/types/locales/tr.d.ts.map +1 -1
- package/dist/types/locales/zh-CN.d.ts +0 -1
- package/dist/types/locales/zh-CN.d.ts.map +1 -1
- package/dist/types/messages.d.ts +0 -3
- package/dist/types/messages.d.ts.map +1 -1
- package/dist/types/model.d.ts +58 -23
- package/dist/types/model.d.ts.map +1 -1
- package/dist/types/slot-picker.d.ts +25 -15
- package/dist/types/slot-picker.d.ts.map +1 -1
- package/dist/types/views/shared.d.ts +5 -4
- package/dist/types/views/shared.d.ts.map +1 -1
- package/docs/USE_CASES.md +24 -18
- package/package.json +1 -1
- package/src/date.js +11 -1
- package/src/index.js +13 -2
- package/src/locales/ar.js +0 -1
- package/src/locales/de.js +0 -1
- package/src/locales/en.js +0 -1
- package/src/locales/es.js +0 -1
- package/src/locales/fr.js +0 -1
- package/src/locales/hi.js +0 -1
- package/src/locales/id.js +0 -1
- package/src/locales/it.js +0 -1
- package/src/locales/ja.js +0 -1
- package/src/locales/ko.js +0 -1
- package/src/locales/nl.js +0 -1
- package/src/locales/pl.js +0 -1
- package/src/locales/pt-BR.js +0 -1
- package/src/locales/pt-PT.js +0 -1
- package/src/locales/ru.js +0 -1
- package/src/locales/tr.js +0 -1
- package/src/locales/zh-CN.js +0 -1
- package/src/messages.js +0 -1
- package/src/model.js +149 -55
- package/src/slot-picker.css +22 -0
- package/src/slot-picker.js +123 -100
- package/src/views/shared.js +10 -7
package/dist/slot-picker.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*** @lekoala/slot-picker v0.1.
|
|
1
|
+
/*** @lekoala/slot-picker v0.1.2 - https://github.com/lekoala/slot-picker ***/
|
|
2
2
|
(() => {
|
|
3
3
|
// src/date.js
|
|
4
4
|
var DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
@@ -27,11 +27,8 @@
|
|
|
27
27
|
function compareDates(a, b) {
|
|
28
28
|
return a.localeCompare(b);
|
|
29
29
|
}
|
|
30
|
-
function
|
|
31
|
-
return
|
|
32
|
-
}
|
|
33
|
-
function rangeEnd(start, dayCount) {
|
|
34
|
-
return addDays(start, Math.max(1, dayCount) - 1);
|
|
30
|
+
function weekdayIndex(value) {
|
|
31
|
+
return toUtcDate(value).getUTCDay();
|
|
35
32
|
}
|
|
36
33
|
function toUtcDate(value) {
|
|
37
34
|
const { year, month, day } = parts(value);
|
|
@@ -57,7 +54,6 @@
|
|
|
57
54
|
loading: "Loading availability",
|
|
58
55
|
empty: "No availability",
|
|
59
56
|
closed: "Closed",
|
|
60
|
-
closedRange: "Closed during this period",
|
|
61
57
|
rangeEmptyTitle: "No availability in this period",
|
|
62
58
|
rangeEmptyDescription: "From {start} to {end}",
|
|
63
59
|
rangeEmptyNext: "See the next period",
|
|
@@ -135,13 +131,10 @@
|
|
|
135
131
|
};
|
|
136
132
|
}).sort((a, b) => a.date.localeCompare(b.date));
|
|
137
133
|
}
|
|
138
|
-
function visibleDays(days,
|
|
134
|
+
function visibleDays(days, dates) {
|
|
139
135
|
const normalized = normalizeDays(days);
|
|
140
136
|
const byDate = new Map(normalized.map((day) => [day.date, day]));
|
|
141
|
-
return
|
|
142
|
-
const date = addDays(start, index);
|
|
143
|
-
return byDate.get(date) ?? { date, slots: [] };
|
|
144
|
-
});
|
|
137
|
+
return dates.map((date) => byDate.get(date) ?? { date, slots: [] });
|
|
145
138
|
}
|
|
146
139
|
function collapsedDays(days, maxVisibleRows, expanded) {
|
|
147
140
|
const maxRows = Math.max(0, ...days.map((day) => day.slots.length));
|
|
@@ -155,13 +148,64 @@
|
|
|
155
148
|
function isValidRange(min, max) {
|
|
156
149
|
return !min || !max || compareDates(min, max) <= 0;
|
|
157
150
|
}
|
|
158
|
-
function
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
151
|
+
function clampDate(date, min, max) {
|
|
152
|
+
if (min && compareDates(date, min) < 0)
|
|
153
|
+
return min;
|
|
154
|
+
if (max && compareDates(date, max) > 0)
|
|
155
|
+
return max;
|
|
156
|
+
return date;
|
|
157
|
+
}
|
|
158
|
+
function normalizeHiddenDays(input) {
|
|
159
|
+
if (input === null || input === undefined)
|
|
160
|
+
return [];
|
|
161
|
+
if (!Array.isArray(input))
|
|
162
|
+
throw new TypeError("hiddenDays must be an array of weekday indexes");
|
|
163
|
+
const indexes = input.map((value) => {
|
|
164
|
+
const index = Number(value);
|
|
165
|
+
if (!Number.isInteger(index) || index < 0 || index > 6) {
|
|
166
|
+
throw new TypeError("hiddenDays entries must be integers from 0 (Sunday) to 6 (Saturday)");
|
|
167
|
+
}
|
|
168
|
+
return index;
|
|
169
|
+
});
|
|
170
|
+
const hidden = [...new Set(indexes)].sort((a, b) => a - b);
|
|
171
|
+
if (hidden.length === 7)
|
|
172
|
+
throw new TypeError("hiddenDays cannot hide every weekday");
|
|
173
|
+
return hidden;
|
|
174
|
+
}
|
|
175
|
+
function walk(from, count, hidden, step, bound) {
|
|
176
|
+
const dates = [];
|
|
177
|
+
let date = from;
|
|
178
|
+
while (dates.length < count) {
|
|
179
|
+
if (bound && (step > 0 ? compareDates(date, bound) > 0 : compareDates(date, bound) < 0))
|
|
180
|
+
break;
|
|
181
|
+
if (!hidden.includes(weekdayIndex(date)))
|
|
182
|
+
dates.push(date);
|
|
183
|
+
date = addDays(date, step);
|
|
184
|
+
}
|
|
185
|
+
return dates;
|
|
186
|
+
}
|
|
187
|
+
function projectDates(start, dayCount, hiddenDays = [], min = "", max = "") {
|
|
188
|
+
const count = Math.max(0, Math.trunc(Number(dayCount) || 0));
|
|
189
|
+
if (!count || !isDateValue(start) || !isValidRange(min, max))
|
|
190
|
+
return [];
|
|
191
|
+
const hidden = normalizeHiddenDays(hiddenDays);
|
|
192
|
+
const from = clampDate(start, min, max);
|
|
193
|
+
const forward = walk(from, count, hidden, 1, max);
|
|
194
|
+
if (forward.length === count)
|
|
195
|
+
return forward;
|
|
196
|
+
const backward = walk(addDays(forward[0] ?? from, -1), count - forward.length, hidden, -1, min);
|
|
197
|
+
return [...backward.reverse(), ...forward];
|
|
198
|
+
}
|
|
199
|
+
function stepStart(dates, direction, hiddenDays = [], min = "", max = "") {
|
|
200
|
+
if (!dates.length)
|
|
201
|
+
return "";
|
|
202
|
+
const hidden = normalizeHiddenDays(hiddenDays);
|
|
203
|
+
const count = dates.length;
|
|
204
|
+
if (direction > 0) {
|
|
205
|
+
return projectDates(addDays(dates[count - 1], 1), count, hidden, min, max)[0] ?? dates[0];
|
|
206
|
+
}
|
|
207
|
+
const backward = walk(addDays(dates[0], -1), count, hidden, -1, min);
|
|
208
|
+
return projectDates(backward[backward.length - 1] ?? dates[0], count, hidden, min, max)[0] ?? dates[0];
|
|
165
209
|
}
|
|
166
210
|
function normalizeBreakpoints(breakpoints) {
|
|
167
211
|
return breakpoints.map((breakpoint) => ({
|
|
@@ -178,46 +222,47 @@
|
|
|
178
222
|
const match = ladder.find((breakpoint) => size >= breakpoint.minWidth) ?? ladder[ladder.length - 1];
|
|
179
223
|
return Math.min(requested, match.dayCount);
|
|
180
224
|
}
|
|
181
|
-
function clampStart(start, min, max, dayCount) {
|
|
182
|
-
|
|
183
|
-
if (min && compareDates(next, min) < 0)
|
|
184
|
-
next = min;
|
|
185
|
-
const count = Math.max(1, dayCount);
|
|
186
|
-
if (max) {
|
|
187
|
-
const latest = addDays(max, -(count - 1));
|
|
188
|
-
if (compareDates(latest, min || next) < 0)
|
|
189
|
-
next = min || latest;
|
|
190
|
-
else if (compareDates(next, latest) > 0)
|
|
191
|
-
next = latest;
|
|
192
|
-
}
|
|
193
|
-
return next;
|
|
225
|
+
function clampStart(start, min, max, dayCount, hiddenDays = []) {
|
|
226
|
+
return projectDates(start, dayCount, hiddenDays, min, max)[0] ?? clampDate(start, min, max);
|
|
194
227
|
}
|
|
195
|
-
function ensureVisible(start, dayCount, date, min, max) {
|
|
228
|
+
function ensureVisible(start, dayCount, date, min, max, hiddenDays = []) {
|
|
229
|
+
const hidden = normalizeHiddenDays(hiddenDays);
|
|
196
230
|
const count = Math.max(1, dayCount);
|
|
197
|
-
const
|
|
231
|
+
const dates = projectDates(start, count, hidden, min, max);
|
|
232
|
+
if (!dates.length)
|
|
233
|
+
return clampDate(start, min, max);
|
|
234
|
+
const first = dates[0];
|
|
198
235
|
if (!isDateValue(date))
|
|
199
|
-
return
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
236
|
+
return first;
|
|
237
|
+
if (compareDates(date, first) < 0)
|
|
238
|
+
return projectDates(date, count, hidden, min, max)[0] ?? first;
|
|
239
|
+
if (compareDates(date, dates[dates.length - 1]) <= 0)
|
|
240
|
+
return first;
|
|
241
|
+
const target = walk(date, 1, hidden, 1, max)[0];
|
|
242
|
+
if (!target)
|
|
243
|
+
return first;
|
|
244
|
+
const backward = walk(target, count, hidden, -1, min);
|
|
245
|
+
return projectDates(backward[backward.length - 1] ?? target, count, hidden, min, max)[0] ?? first;
|
|
205
246
|
}
|
|
206
247
|
function hasDayContent(days) {
|
|
207
248
|
return days.some((day) => Array.isArray(day.slots) && day.slots.length > 0 || Boolean(day.notice) || Boolean(day.closed));
|
|
208
249
|
}
|
|
209
|
-
function rangeDetail(
|
|
210
|
-
|
|
250
|
+
function rangeDetail(dates) {
|
|
251
|
+
if (!dates.length)
|
|
252
|
+
return { start: "", end: "", dayCount: 0 };
|
|
253
|
+
return { start: dates[0], end: dates[dates.length - 1], dayCount: dates.length };
|
|
211
254
|
}
|
|
212
|
-
function resolveActiveDate(
|
|
255
|
+
function resolveActiveDate(dates, activeDate) {
|
|
256
|
+
if (!dates.length)
|
|
257
|
+
return "";
|
|
258
|
+
const last = dates[dates.length - 1];
|
|
213
259
|
if (!isDateValue(activeDate))
|
|
214
|
-
return
|
|
215
|
-
if (compareDates(activeDate,
|
|
216
|
-
return
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
return activeDate;
|
|
260
|
+
return dates[0];
|
|
261
|
+
if (compareDates(activeDate, dates[0]) <= 0)
|
|
262
|
+
return dates[0];
|
|
263
|
+
if (compareDates(activeDate, last) >= 0)
|
|
264
|
+
return last;
|
|
265
|
+
return dates.find((date) => compareDates(date, activeDate) >= 0) ?? last;
|
|
221
266
|
}
|
|
222
267
|
function firstEnabledIndex(day) {
|
|
223
268
|
return day.slots.findIndex((slot) => !slot.disabled);
|
|
@@ -369,7 +414,7 @@
|
|
|
369
414
|
const description = slot.description ? ` aria-description="${escapeAttr(slot.description)}"` : "";
|
|
370
415
|
const disabled = slot.disabled ? ' disabled aria-disabled="true"' : "";
|
|
371
416
|
const tone = slot.tone ? ` data-tone="${escapeAttr(slot.tone)}"` : "";
|
|
372
|
-
return `<button type="button" role="option" class="sp-slot" data-day-index="${dayIndex}" data-slot-index="${slotIndex}" data-value="${escapeAttr(value)}"${tone} aria-selected="${selected ? "true" : "false"}" tabindex="${tabbed ? 0 : -1}"${disabled}${description}>${escapeHtml(slot.start)}</button>`;
|
|
417
|
+
return `<button type="button" role="option" class="sp-slot" data-day-index="${dayIndex}" data-slot-index="${slotIndex}" data-value="${escapeAttr(value)}"${tone} aria-selected="${selected ? "true" : "false"}" tabindex="${tabbed ? 0 : -1}"${disabled}${description}><span class="sp-slot-time">${escapeHtml(slot.start)}</span></button>`;
|
|
373
418
|
}
|
|
374
419
|
function noticeIndicator(options = {}) {
|
|
375
420
|
if (options.interactive) {
|
|
@@ -393,7 +438,7 @@
|
|
|
393
438
|
return messages.oneSlot;
|
|
394
439
|
return messages.manySlots.replace("{n}", String(count));
|
|
395
440
|
}
|
|
396
|
-
function rangeEmpty({ start, end, invalid, canNext, nextAvailability,
|
|
441
|
+
function rangeEmpty({ start, end, invalid, canNext, nextAvailability, locale, messages }) {
|
|
397
442
|
const showDescription = !invalid && Boolean(start);
|
|
398
443
|
let description = "";
|
|
399
444
|
if (showDescription) {
|
|
@@ -413,9 +458,8 @@
|
|
|
413
458
|
actions.push(`<button type="button" class="sp-range-empty-availability">${escapeHtml(messages.nextAvailability)}</button>`);
|
|
414
459
|
}
|
|
415
460
|
const action = actions.length ? `<div class="sp-range-empty-actions">${actions.join("")}</div>` : "";
|
|
416
|
-
const title = closed ? messages.closedRange : messages.rangeEmptyTitle;
|
|
417
461
|
return `<div class="sp-range-empty">
|
|
418
|
-
<strong class="sp-range-empty-title">${escapeHtml(
|
|
462
|
+
<strong class="sp-range-empty-title">${escapeHtml(messages.rangeEmptyTitle)}</strong>
|
|
419
463
|
${description}
|
|
420
464
|
${action}
|
|
421
465
|
</div>`;
|
|
@@ -577,11 +621,11 @@
|
|
|
577
621
|
"home-date",
|
|
578
622
|
"next-availability",
|
|
579
623
|
"notice-display",
|
|
580
|
-
"closed-days",
|
|
581
624
|
"locale",
|
|
582
625
|
"lang"
|
|
583
626
|
];
|
|
584
627
|
#days = [];
|
|
628
|
+
#hiddenDays = [];
|
|
585
629
|
#sourceController = new SlotSourceController;
|
|
586
630
|
#messages = null;
|
|
587
631
|
#loading = false;
|
|
@@ -642,7 +686,7 @@
|
|
|
642
686
|
if (!isDateValue(value))
|
|
643
687
|
throw new TypeError("start must be YYYY-MM-DD");
|
|
644
688
|
const count = this.visibleDayCount;
|
|
645
|
-
this.setAttribute("start", count > 0 ? clampStart(value, this.min, this.max, count) : value);
|
|
689
|
+
this.setAttribute("start", count > 0 ? clampStart(value, this.min, this.max, count, this.#hiddenDays) : value);
|
|
646
690
|
}
|
|
647
691
|
get dayCount() {
|
|
648
692
|
const value = Number.parseInt(this.getAttribute("day-count") || "5", 10);
|
|
@@ -652,13 +696,25 @@
|
|
|
652
696
|
const next = Math.max(1, Math.min(14, Number(value) || 5));
|
|
653
697
|
this.setAttribute("day-count", String(next));
|
|
654
698
|
}
|
|
655
|
-
get
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
699
|
+
get hiddenDays() {
|
|
700
|
+
return [...this.#hiddenDays];
|
|
701
|
+
}
|
|
702
|
+
set hiddenDays(value) {
|
|
703
|
+
this.#hiddenDays = normalizeHiddenDays(value);
|
|
704
|
+
if (!this.isConnected || this.#batching)
|
|
705
|
+
return;
|
|
706
|
+
this.#reconcile({ pinActive: true });
|
|
707
|
+
}
|
|
708
|
+
#requestedDayCount() {
|
|
659
709
|
if (!this.responsive || this.#measuredWidth === null)
|
|
660
|
-
return
|
|
661
|
-
return resolveVisibleDayCount(
|
|
710
|
+
return this.dayCount;
|
|
711
|
+
return resolveVisibleDayCount(this.dayCount, this.#measuredWidth, this.#breakpoints ?? RESPONSIVE_BREAKPOINTS);
|
|
712
|
+
}
|
|
713
|
+
#projection() {
|
|
714
|
+
return projectDates(this.start, this.#requestedDayCount(), this.#hiddenDays, this.min, this.max);
|
|
715
|
+
}
|
|
716
|
+
get visibleDayCount() {
|
|
717
|
+
return this.#projection().length;
|
|
662
718
|
}
|
|
663
719
|
get responsive() {
|
|
664
720
|
return this.hasAttribute("responsive");
|
|
@@ -714,12 +770,10 @@
|
|
|
714
770
|
throw new TypeError("value must be a valid YYYY-MM-DDTHH:mm or empty");
|
|
715
771
|
}
|
|
716
772
|
get activeDate() {
|
|
717
|
-
const
|
|
718
|
-
if (!
|
|
773
|
+
const dates = this.#projection();
|
|
774
|
+
if (!dates.length)
|
|
719
775
|
return "";
|
|
720
|
-
|
|
721
|
-
const base = isDateValue(raw) ? raw : this.start;
|
|
722
|
-
return resolveActiveDate(this.start, count, base);
|
|
776
|
+
return resolveActiveDate(dates, this.getAttribute("active-date") || "");
|
|
723
777
|
}
|
|
724
778
|
set activeDate(value) {
|
|
725
779
|
if (!value)
|
|
@@ -762,15 +816,6 @@
|
|
|
762
816
|
}
|
|
763
817
|
this.setAttribute("notice-display", value);
|
|
764
818
|
}
|
|
765
|
-
get closedDays() {
|
|
766
|
-
return this.getAttribute("closed-days") === "hide" ? "hide" : "show";
|
|
767
|
-
}
|
|
768
|
-
set closedDays(value) {
|
|
769
|
-
if (value !== "show" && value !== "hide") {
|
|
770
|
-
throw new TypeError('closed-days must be "show" or "hide"');
|
|
771
|
-
}
|
|
772
|
-
this.setAttribute("closed-days", value);
|
|
773
|
-
}
|
|
774
819
|
get expanded() {
|
|
775
820
|
return this.hasAttribute("expanded");
|
|
776
821
|
}
|
|
@@ -815,23 +860,19 @@
|
|
|
815
860
|
this.setAttribute("locale", value);
|
|
816
861
|
}
|
|
817
862
|
get range() {
|
|
818
|
-
|
|
819
|
-
if (!count)
|
|
820
|
-
return { start: "", end: "", dayCount: 0 };
|
|
821
|
-
return rangeDetail(this.start, count);
|
|
863
|
+
return rangeDetail(this.#projection());
|
|
822
864
|
}
|
|
823
865
|
previous() {
|
|
824
|
-
this.#navigate(-
|
|
866
|
+
this.#navigate(-1);
|
|
825
867
|
}
|
|
826
868
|
next() {
|
|
827
|
-
this.#navigate(
|
|
869
|
+
this.#navigate(1);
|
|
828
870
|
}
|
|
829
871
|
goTo(date) {
|
|
830
|
-
|
|
831
|
-
if (!count)
|
|
872
|
+
if (!this.visibleDayCount)
|
|
832
873
|
return "";
|
|
833
|
-
const target = isDateValue(date) ?
|
|
834
|
-
this.#mutate(() => this.#moveTo(target
|
|
874
|
+
const target = isDateValue(date) ? clampDate(date, this.min, this.max) : this.start;
|
|
875
|
+
this.#mutate(() => this.#moveTo(target));
|
|
835
876
|
this.#commit();
|
|
836
877
|
return this.activeDate;
|
|
837
878
|
}
|
|
@@ -875,8 +916,8 @@
|
|
|
875
916
|
this.homeDate = options.homeDate ?? "";
|
|
876
917
|
if (options.responsiveBreakpoints !== undefined)
|
|
877
918
|
this.responsiveBreakpoints = options.responsiveBreakpoints;
|
|
878
|
-
if (options.
|
|
879
|
-
this.
|
|
919
|
+
if (options.hiddenDays !== undefined)
|
|
920
|
+
this.hiddenDays = options.hiddenDays;
|
|
880
921
|
});
|
|
881
922
|
this.#reconcile({ pinActive: options.start === undefined });
|
|
882
923
|
}
|
|
@@ -900,39 +941,32 @@
|
|
|
900
941
|
if (options.responsiveBreakpoints != null && !Array.isArray(options.responsiveBreakpoints)) {
|
|
901
942
|
throw new TypeError("responsiveBreakpoints must be an array or null");
|
|
902
943
|
}
|
|
903
|
-
if (options.
|
|
904
|
-
|
|
905
|
-
}
|
|
944
|
+
if (options.hiddenDays !== undefined)
|
|
945
|
+
normalizeHiddenDays(options.hiddenDays);
|
|
906
946
|
}
|
|
907
947
|
async reload() {
|
|
908
948
|
await this.#load();
|
|
909
949
|
}
|
|
910
|
-
#navigate(
|
|
911
|
-
const
|
|
912
|
-
if (!
|
|
950
|
+
#navigate(direction) {
|
|
951
|
+
const dates = this.#projection();
|
|
952
|
+
if (!dates.length)
|
|
913
953
|
return;
|
|
914
|
-
const next =
|
|
915
|
-
if (next === this.start)
|
|
954
|
+
const next = stepStart(dates, direction, this.#hiddenDays, this.min, this.max);
|
|
955
|
+
if (!next || next === this.start)
|
|
916
956
|
return;
|
|
917
957
|
this.#mutate(() => this.setAttribute("start", next));
|
|
918
958
|
this.#commit();
|
|
919
959
|
}
|
|
920
|
-
#moveTo(target
|
|
921
|
-
const
|
|
960
|
+
#moveTo(target) {
|
|
961
|
+
const count = this.#requestedDayCount();
|
|
962
|
+
const nextStart = ensureVisible(this.start, count, target, this.min, this.max, this.#hiddenDays);
|
|
922
963
|
if (nextStart !== this.getAttribute("start"))
|
|
923
964
|
this.setAttribute("start", nextStart);
|
|
924
|
-
const
|
|
965
|
+
const dates = projectDates(nextStart, count, this.#hiddenDays, this.min, this.max);
|
|
966
|
+
const nextActive = resolveActiveDate(dates, target);
|
|
925
967
|
if (this.getAttribute("active-date") !== nextActive)
|
|
926
968
|
this.setAttribute("active-date", nextActive);
|
|
927
969
|
}
|
|
928
|
-
#clampToBounds(date) {
|
|
929
|
-
let next = date;
|
|
930
|
-
if (this.min && compareDates(next, this.min) < 0)
|
|
931
|
-
next = this.min;
|
|
932
|
-
if (this.max && compareDates(next, this.max) > 0)
|
|
933
|
-
next = this.max;
|
|
934
|
-
return next;
|
|
935
|
-
}
|
|
936
970
|
#mutate(fn) {
|
|
937
971
|
const wasBatching = this.#batching;
|
|
938
972
|
this.#batching = true;
|
|
@@ -948,8 +982,8 @@
|
|
|
948
982
|
const wasBatching = this.#batching;
|
|
949
983
|
this.#batching = true;
|
|
950
984
|
try {
|
|
951
|
-
const count = this
|
|
952
|
-
const invalid =
|
|
985
|
+
const count = this.#requestedDayCount();
|
|
986
|
+
const invalid = this.visibleDayCount === 0;
|
|
953
987
|
this.toggleAttribute("data-invalid-range", invalid);
|
|
954
988
|
if (!invalid) {
|
|
955
989
|
const rawActive = this.getAttribute("active-date") || "";
|
|
@@ -957,18 +991,19 @@
|
|
|
957
991
|
let anchor = this.start;
|
|
958
992
|
if (pinActive) {
|
|
959
993
|
if (previous?.dayCount && isDateValue(rawActive)) {
|
|
960
|
-
anchor =
|
|
994
|
+
anchor = clampDate(rawActive, previous.start, previous.end);
|
|
961
995
|
} else if (isDateValue(rawActive)) {
|
|
962
996
|
anchor = rawActive;
|
|
963
997
|
} else if (previous?.start) {
|
|
964
998
|
anchor = previous.start;
|
|
965
999
|
}
|
|
966
1000
|
}
|
|
967
|
-
const nextStart = ensureVisible(this.start, count, anchor, this.min, this.max);
|
|
1001
|
+
const nextStart = ensureVisible(this.start, count, anchor, this.min, this.max, this.#hiddenDays);
|
|
968
1002
|
if (nextStart !== this.getAttribute("start"))
|
|
969
1003
|
this.setAttribute("start", nextStart);
|
|
970
1004
|
if (pinActive && isDateValue(anchor)) {
|
|
971
|
-
const
|
|
1005
|
+
const dates = projectDates(nextStart, count, this.#hiddenDays, this.min, this.max);
|
|
1006
|
+
const nextActive = resolveActiveDate(dates, anchor);
|
|
972
1007
|
if (this.getAttribute("active-date") !== nextActive)
|
|
973
1008
|
this.setAttribute("active-date", nextActive);
|
|
974
1009
|
}
|
|
@@ -1025,10 +1060,10 @@
|
|
|
1025
1060
|
return content ? content.getBoundingClientRect().width : null;
|
|
1026
1061
|
}
|
|
1027
1062
|
#setActiveDate(date, emit = true) {
|
|
1028
|
-
const
|
|
1029
|
-
if (!
|
|
1063
|
+
const dates = this.#projection();
|
|
1064
|
+
if (!dates.length)
|
|
1030
1065
|
return;
|
|
1031
|
-
const resolved = resolveActiveDate(
|
|
1066
|
+
const resolved = resolveActiveDate(dates, date);
|
|
1032
1067
|
const before = this.activeDate;
|
|
1033
1068
|
if (resolved === before && this.getAttribute("active-date") === resolved)
|
|
1034
1069
|
return;
|
|
@@ -1116,40 +1151,31 @@
|
|
|
1116
1151
|
return this.querySelector('.sp-slot[tabindex="0"]') ?? this.querySelector('.sp-strip-day[tabindex="0"]');
|
|
1117
1152
|
}
|
|
1118
1153
|
#projectedDays() {
|
|
1119
|
-
|
|
1120
|
-
if (!count)
|
|
1121
|
-
return [];
|
|
1122
|
-
const days = visibleDays(this.#days, this.start, count);
|
|
1123
|
-
if (this.closedDays !== "hide")
|
|
1124
|
-
return days;
|
|
1125
|
-
const active = this.activeDate;
|
|
1126
|
-
return days.filter((day) => !day.closed || this.layout === "day" && day.date === active);
|
|
1154
|
+
return visibleDays(this.#days, this.#projection());
|
|
1127
1155
|
}
|
|
1128
1156
|
#render() {
|
|
1129
1157
|
const focused = document.activeElement;
|
|
1130
1158
|
const fallbackSelector = focused instanceof Element && this.contains(focused) ? this.#focusSelector(focused) : "";
|
|
1131
1159
|
const pendingSelector = this.#pendingFocus;
|
|
1132
1160
|
this.#pendingFocus = "";
|
|
1133
|
-
const
|
|
1134
|
-
const
|
|
1135
|
-
const
|
|
1136
|
-
const days = this.#
|
|
1137
|
-
const allClosed = civilDays.length > 0 && civilDays.every((day) => day.closed);
|
|
1161
|
+
const dates = this.#projection();
|
|
1162
|
+
const range = rangeDetail(dates);
|
|
1163
|
+
const invalid = range.dayCount === 0;
|
|
1164
|
+
const days = visibleDays(this.#days, dates);
|
|
1138
1165
|
const messages = resolveMessages(this.#messages);
|
|
1139
1166
|
const locale = this.locale;
|
|
1140
|
-
const canPrevious = !invalid && (
|
|
1141
|
-
const canNext = !invalid && (
|
|
1167
|
+
const canPrevious = !invalid && stepStart(dates, -1, this.#hiddenDays, this.min, this.max) !== range.start;
|
|
1168
|
+
const canNext = !invalid && stepStart(dates, 1, this.#hiddenDays, this.min, this.max) !== range.start;
|
|
1142
1169
|
const empty = !this.#loading && !this.#error && !hasDayContent(days);
|
|
1143
1170
|
let content;
|
|
1144
1171
|
let hasOverflow = false;
|
|
1145
1172
|
if (empty) {
|
|
1146
1173
|
content = rangeEmpty({
|
|
1147
|
-
start:
|
|
1148
|
-
end:
|
|
1174
|
+
start: range.start,
|
|
1175
|
+
end: range.end,
|
|
1149
1176
|
invalid,
|
|
1150
1177
|
canNext,
|
|
1151
1178
|
nextAvailability: this.hasAttribute("next-availability"),
|
|
1152
|
-
closed: allClosed,
|
|
1153
1179
|
locale,
|
|
1154
1180
|
messages
|
|
1155
1181
|
});
|
|
@@ -1180,7 +1206,7 @@
|
|
|
1180
1206
|
}
|
|
1181
1207
|
const status = this.#loading ? `<div class="sp-status sp-visually-hidden" role="status">${escapeHtml(messages.loading)}</div>` : this.#error ? `<div class="sp-status sp-status-error" role="status">${escapeHtml(String(this.#error))}</div>` : "";
|
|
1182
1208
|
const homeAvailable = this.hasAttribute("home-date") && !invalid;
|
|
1183
|
-
const homeInRange = homeAvailable && compareDates(this.homeDate,
|
|
1209
|
+
const homeInRange = homeAvailable && compareDates(this.homeDate, range.start) >= 0 && compareDates(this.homeDate, range.end) <= 0;
|
|
1184
1210
|
this.style.setProperty("--_sp-day-count", String(Math.max(1, days.length)));
|
|
1185
1211
|
this.style.setProperty("--_sp-max-visible-rows", String(this.maxVisibleRows));
|
|
1186
1212
|
if (this.#loading)
|
package/dist/slot-picker.min.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
:where(slot-picker){--sp-bg:#fff;--sp-fg:#1f2328;--sp-muted:color-mix(in srgb,var(--sp-fg)58%,var(--sp-bg));--sp-border:color-mix(in srgb,var(--sp-fg)16%,var(--sp-bg));--sp-hover:color-mix(in srgb,var(--sp-fg)5%,var(--sp-bg));--sp-notice-hover-bg:color-mix(in srgb,var(--sp-fg)12%,var(--sp-bg));--sp-accent:#2563eb;--sp-accent-fg:#fff;--sp-accent-soft:color-mix(in srgb,var(--sp-accent)16%,var(--sp-bg));--sp-focus:var(--sp-accent);--sp-radius:.5rem;--sp-gap:.5rem;--sp-day-gap:.75rem;--sp-slot-columns:3;--sp-card-bg:transparent;--sp-slot-block-size:2.75rem;--sp-slot-bg:var(--sp-accent-soft);--sp-slot-fg:var(--sp-fg);--sp-slot-border:transparent;--sp-slot-hover-bg:color-mix(in srgb,var(--sp-accent)22%,var(--sp-bg));--sp-slot-selected-bg:var(--sp-accent);--sp-slot-selected-fg:var(--sp-accent-fg);--sp-nav-size:2.5rem;--sp-day-header-block-size:3.4rem;--sp-collapsed-rows:var(--_sp-max-visible-rows,5);--sp-collapsed-body-block-size:calc(var(--sp-collapsed-rows)*(var(--sp-slot-block-size) + var(--sp-gap)) - var(--sp-gap));--sp-footer-block-size:2.5rem;--sp-shortcuts-block-size:2.5rem;--sp-collapsed-block-size:calc(var(--sp-day-header-block-size) + var(--sp-collapsed-body-block-size) + var(--sp-footer-block-size));--sp-more-fade-size:4rem;--sp-more-bg:var(--sp-bg);--sp-panel-min-block-size:calc(2*var(--sp-slot-block-size) + var(--sp-gap));--sp-closed-opacity:.55;--sp-loading-fade-opacity:.72;--sp-loading-fade-delay:.4s;display:block;color:var(--sp-fg);font:inherit}.sp-visually-hidden{position:absolute!important;overflow:hidden!important;clip:rect(0 0 0 0)!important;white-space:nowrap!important;border:0!important;block-size:1px!important;inline-size:1px!important;margin:-1px!important;padding:0!important}.sp-shell{display:block}.sp-projection{display:grid;grid-template-columns:auto minmax(0,1fr)auto;align-items: start;gap:var(--sp-gap)}.sp-content{position:relative;opacity:1;min-inline-size:0;transition:opacity .16s}slot-picker[aria-busy=true] .sp-content{opacity:var(--sp-loading-fade-opacity,.72);transition-delay:var(--sp-loading-fade-delay,.4s)}@media (prefers-reduced-motion:reduce){.sp-content{transition-duration:0s}}slot-picker:not([layout=day]) .sp-content{min-block-size:var(--sp-collapsed-block-size)}.sp-shortcuts{display:flex;justify-content:flex-start;margin-block-start:var(--sp-gap)}slot-picker[home-date] .sp-shortcuts{min-block-size:var(--sp-shortcuts-block-size,2.5rem)}.sp-home{display:inline-flex;color:var(--sp-accent);font:inherit;cursor:pointer;background:0 0;border:0;align-items: center;gap:.35rem;padding:.25rem 0}.sp-home:hover{text-decoration:underline}.sp-grid{display:grid;grid-template-columns:repeat(var(--_sp-day-count,5),minmax(0,1fr));gap:var(--sp-day-gap)}.sp-day{min-inline-size:0}.sp-day-header{position:relative;display:grid;box-sizing:border-box;min-block-size:var(--sp-day-header-block-size);text-align:center;justify-items:center;gap:.1rem;padding-block-start:.15rem;padding-block-end:.55rem;line-height:1.25}.sp-weekday{color:var(--sp-muted);font-size:.85rem}.sp-date{font-size:.9rem;font-weight:650}.sp-notice{position:absolute;display:grid;color:var(--sp-muted);pointer-events:none;place-items: center;block-size:1.5rem;inline-size:1.5rem;top:0}.sp-notice:not(:-webkit-any(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi))){right:0}.sp-notice:not(:-moz-any(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi))){right:0}.sp-notice:not(:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi))){right:0}.sp-notice:-webkit-any(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){left:0}.sp-notice:-moz-any(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){left:0}.sp-notice:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){left:0}.sp-notice[data-day-index]{pointer-events:auto;cursor:pointer;background:0 0;border:0;border-radius:50%;padding:0;transition:background-color .12s}.sp-notice[data-day-index]:hover{background:var(--sp-notice-hover-bg);color:var(--sp-fg)}.sp-notice-dot{background:currentColor;border-radius:50%;block-size:.45rem;inline-size:.45rem}.sp-slots{display:grid;gap:var(--sp-gap)}.sp-slot,.sp-empty{display:grid;min-block-size:var(--sp-slot-block-size);box-sizing:border-box;border-radius:var(--sp-radius);font:inherit;place-items: center}.sp-slot{border:1px solid var(--sp-slot-border);background:var(--sp-slot-bg);color:var(--sp-slot-fg);cursor:pointer}.sp-slot:hover:not(:disabled):not([aria-selected=true]){background:var(--sp-slot-hover-bg)}.sp-slot[aria-selected=true]{background:var(--sp-slot-selected-bg);color:var(--sp-slot-selected-fg)}.sp-slot:disabled{cursor:not-allowed;opacity:.45}.sp-slot:focus-visible{outline:2px solid var(--sp-focus);outline-offset:2px}.sp-slot[aria-selected=true]:focus-visible{outline-color:var(--sp-fg)}.sp-empty{color:var(--sp-muted);user-select:none}.sp-nav{display:grid;inline-size:var(--sp-nav-size);block-size:var(--sp-nav-size);border:1px solid var(--sp-border);background:var(--sp-bg);color:var(--sp-fg);cursor:pointer;border-radius:50%;place-items: center;margin-block-start:.45rem;padding:0}.sp-nav:hover:not(:disabled){background:var(--sp-hover)}.sp-nav:disabled{cursor:not-allowed;opacity:.4}.sp-nav svg{display:block;pointer-events:none;block-size:1rem;inline-size:1rem}[dir=rtl] .sp-nav svg,html[dir=rtl] .sp-nav svg{transform:scaleX(-1)}.sp-more{display:flex;justify-content:center;margin-block-start:1rem}slot-picker:not([expanded]) .sp-more{position:absolute;display:grid;min-block-size:var(--sp-footer-block-size);place-items: end center;margin-block-start:0;bottom:0;left:0;right:0}slot-picker:not([expanded]) .sp-more:before{content:"";position:absolute;block-size:var(--sp-more-fade-size,4rem);background:linear-gradient(to bottom,transparent,var(--sp-more-bg,var(--sp-bg)));pointer-events:none;bottom:0;left:0;right:0}slot-picker[expanded] .sp-more{position:static}slot-picker[expanded] .sp-more:before{content:none}.sp-more-button{position:relative;z-index:1;color:var(--sp-accent);font:inherit;cursor:pointer;background:0 0;border:0}.sp-status{color:var(--sp-muted);text-align:center;margin-block-end:.75rem}.sp-status-error{color:var(--sp-fg)}.sp-day-empty{display:grid;min-block-size:var(--sp-slot-block-size);color:var(--sp-muted);text-align:center;place-items: center;padding-inline-start:.5rem;padding-inline-end:.5rem;font-size:.9rem}.sp-day[data-closed],.sp-panel[data-closed],.sp-strip-day[data-closed]{opacity:var(--sp-closed-opacity,.55)}.sp-range-empty{display:grid;box-sizing:border-box;min-block-size:var(--sp-collapsed-block-size);border-radius:var(--sp-radius);background:var(--sp-card-bg);text-align:center;align-content: center;justify-items:center;gap:.5rem;padding:1.5rem 1rem}slot-picker[layout=day] .sp-range-empty{min-block-size:var(--sp-panel-min-block-size)}slot-picker[layout=day] .sp-day-empty{min-block-size:var(--sp-panel-min-block-size);align-content: center}.sp-range-empty-title{font-size:1rem}.sp-range-empty-description{color:var(--sp-muted);margin:0}.sp-range-empty-actions{display:flex;flex-wrap:wrap;justify-content:center;gap:.5rem}.sp-range-empty-next{border-radius:var(--sp-radius);background:var(--sp-accent);color:var(--sp-accent-fg);font:inherit;cursor:pointer;border:0;padding:.6rem 1rem}.sp-range-empty-next:hover{background:color-mix(in srgb,var(--sp-accent)85%,var(--sp-bg))}.sp-range-empty-availability{border:1px solid var(--sp-border);border-radius:var(--sp-radius);background:var(--sp-bg);color:var(--sp-accent);font:inherit;cursor:pointer;padding:.6rem 1rem}.sp-range-empty-availability:hover{background:var(--sp-hover)}.sp-range-empty-next:focus-visible{outline:2px solid var(--sp-focus);outline-offset:2px}.sp-range-empty-availability:focus-visible{outline:2px solid var(--sp-focus);outline-offset:2px}.sp-daystrip{display:grid;grid-template-columns:repeat(var(--_sp-day-count,5),minmax(0,1fr));gap:var(--sp-gap);margin-block-end:1rem}.sp-strip-day{display:grid;border:1px solid var(--sp-border);border-radius:var(--sp-radius);background:var(--sp-card-bg);color:var(--sp-fg);font:inherit;cursor:pointer;justify-items:center;gap:.1rem;min-inline-size:0;padding-block-start:.6rem;padding-block-end:.55rem;padding-inline-start:.25rem;padding-inline-end:.25rem}.sp-strip-day:hover{background:var(--sp-hover)}.sp-strip-day[aria-pressed=true]{border-color:var(--sp-accent);background:var(--sp-accent-soft)}.sp-strip-weekday{color:var(--sp-muted);font-size:.85rem}.sp-strip-day[data-today] .sp-strip-weekday{font-weight:700}.sp-strip-date{font-size:.9rem}.sp-strip-count{color:var(--sp-muted);text-align:center;overflow-wrap:anywhere;max-inline-size:100%;font-size:.8rem}.sp-panel-header{position:relative;display:flex;text-align:center;justify-content:center;align-items: center;gap:.5rem;margin-block-end:.75rem}.sp-panel-title{font-size:1rem}.sp-panel-slots{display:grid;grid-template-columns:repeat(var(--sp-slot-columns,3),minmax(0,1fr));gap:var(--sp-gap)}.sp-day-notice{display:block;box-sizing:border-box;overflow:hidden;border-radius:var(--sp-radius);background:var(--sp-hover);text-align:center;min-inline-size:0;max-inline-size:100%;margin-block-end:.75rem;padding:.75rem 1rem}.sp-day-notice-label{display:-webkit-box;overflow:hidden;overflow-wrap:anywhere;-webkit-line-clamp:2;-webkit-box-orient:vertical;margin-block-end:.25rem}.sp-day-notice-description{display:none;overflow-wrap:anywhere;color:var(--sp-muted);min-inline-size:0;max-inline-size:100%;margin:0;font-size:.9rem}slot-picker[layout=day] .sp-day-notice-label{display:block;-webkit-line-clamp:unset}slot-picker[layout=day] .sp-day-notice-description{display:block}.sp-nav:focus-visible{outline:2px solid var(--sp-focus);outline-offset:2px}.sp-home:focus-visible{outline:2px solid var(--sp-focus);outline-offset:2px}.sp-more-button:focus-visible{outline:2px solid var(--sp-focus);outline-offset:2px}.sp-notice[data-day-index]:focus-visible{outline:2px solid var(--sp-focus);outline-offset:2px}.sp-strip-day:focus-visible{outline:2px solid var(--sp-focus);outline-offset:2px}@media (forced-colors:active){.sp-slot{border-color:buttontext}.sp-slot[aria-selected=true]{border-width:2px}.sp-strip-day[aria-pressed=true]{border-width:2px;border-color:buttontext}.sp-day-notice{border:1px solid buttontext}.sp-notice-dot{background:canvastext}}
|
|
1
|
+
:where(slot-picker){--sp-bg:#fff;--sp-fg:#1f2328;--sp-muted:color-mix(in srgb,var(--sp-fg)58%,var(--sp-bg));--sp-border:color-mix(in srgb,var(--sp-fg)16%,var(--sp-bg));--sp-hover:color-mix(in srgb,var(--sp-fg)5%,var(--sp-bg));--sp-notice-hover-bg:color-mix(in srgb,var(--sp-fg)12%,var(--sp-bg));--sp-accent:#2563eb;--sp-accent-fg:#fff;--sp-accent-soft:color-mix(in srgb,var(--sp-accent)16%,var(--sp-bg));--sp-focus:var(--sp-accent);--sp-radius:.5rem;--sp-gap:.5rem;--sp-day-gap:.75rem;--sp-slot-columns:3;--sp-card-bg:transparent;--sp-slot-block-size:2.75rem;--sp-slot-bg:var(--sp-accent-soft);--sp-slot-fg:var(--sp-fg);--sp-slot-border:transparent;--sp-slot-hover-bg:color-mix(in srgb,var(--sp-accent)22%,var(--sp-bg));--sp-slot-selected-bg:var(--sp-accent);--sp-slot-selected-fg:var(--sp-accent-fg);--sp-nav-size:2.5rem;--sp-day-header-block-size:3.4rem;--sp-collapsed-rows:var(--_sp-max-visible-rows,5);--sp-collapsed-body-block-size:calc(var(--sp-collapsed-rows)*(var(--sp-slot-block-size) + var(--sp-gap)) - var(--sp-gap));--sp-footer-block-size:2.5rem;--sp-shortcuts-block-size:2.5rem;--sp-collapsed-block-size:calc(var(--sp-day-header-block-size) + var(--sp-collapsed-body-block-size) + var(--sp-footer-block-size));--sp-more-fade-size:4rem;--sp-more-bg:var(--sp-bg);--sp-panel-min-block-size:calc(2*var(--sp-slot-block-size) + var(--sp-gap));--sp-closed-opacity:.55;--sp-loading-fade-opacity:.72;--sp-loading-fade-delay:.4s;display:block;color:var(--sp-fg);font:inherit}.sp-visually-hidden{position:absolute!important;overflow:hidden!important;clip:rect(0 0 0 0)!important;white-space:nowrap!important;border:0!important;block-size:1px!important;inline-size:1px!important;margin:-1px!important;padding:0!important}.sp-shell{display:block}.sp-projection{display:grid;grid-template-columns:auto minmax(0,1fr)auto;align-items: start;gap:var(--sp-gap)}.sp-content{position:relative;opacity:1;min-inline-size:0;transition:opacity .16s}slot-picker[aria-busy=true] .sp-content{opacity:var(--sp-loading-fade-opacity,.72);transition-delay:var(--sp-loading-fade-delay,.4s)}@media (prefers-reduced-motion:reduce){.sp-content{transition-duration:0s}}slot-picker:not([layout=day]) .sp-content{min-block-size:var(--sp-collapsed-block-size)}.sp-shortcuts{display:flex;justify-content:flex-start;margin-block-start:var(--sp-gap)}slot-picker[home-date] .sp-shortcuts{min-block-size:var(--sp-shortcuts-block-size,2.5rem)}.sp-home{display:inline-flex;color:var(--sp-accent);font:inherit;cursor:pointer;background:0 0;border:0;align-items: center;gap:.35rem;padding:.25rem 0}.sp-home:hover{text-decoration:underline}.sp-grid{display:grid;grid-template-columns:repeat(var(--_sp-day-count,5),minmax(0,1fr));gap:var(--sp-day-gap)}.sp-day{min-inline-size:0}.sp-day-header{position:relative;display:grid;box-sizing:border-box;min-block-size:var(--sp-day-header-block-size);text-align:center;justify-items:center;gap:.1rem;padding-block-start:.15rem;padding-block-end:.55rem;line-height:1.25}.sp-weekday{color:var(--sp-muted);font-size:.85rem}.sp-date{font-size:.9rem;font-weight:650}.sp-notice{position:absolute;display:grid;color:var(--sp-muted);pointer-events:none;place-items: center;block-size:1.5rem;inline-size:1.5rem;top:0}.sp-notice:not(:-webkit-any(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi))){right:0}.sp-notice:not(:-moz-any(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi))){right:0}.sp-notice:not(:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi))){right:0}.sp-notice:-webkit-any(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){left:0}.sp-notice:-moz-any(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){left:0}.sp-notice:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){left:0}.sp-notice[data-day-index]{pointer-events:auto;cursor:pointer;background:0 0;border:0;border-radius:50%;padding:0;transition:background-color .12s}.sp-notice[data-day-index]:hover{background:var(--sp-notice-hover-bg);color:var(--sp-fg)}.sp-notice-dot{background:currentColor;border-radius:50%;block-size:.45rem;inline-size:.45rem}.sp-slots{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--sp-gap)}.sp-slot,.sp-empty{display:grid;min-block-size:var(--sp-slot-block-size);box-sizing:border-box;border-radius:var(--sp-radius);font:inherit;place-items: center;min-inline-size:0;max-inline-size:100%}.sp-slot-time{display:inline-flex;justify-content:center;align-items: center}.sp-slot{border:1px solid var(--sp-slot-border);background:var(--sp-slot-bg);color:var(--sp-slot-fg);cursor:pointer}.sp-slot:hover:not(:disabled):not([aria-selected=true]){background:var(--sp-slot-hover-bg)}.sp-slot[aria-selected=true]{background:var(--sp-slot-selected-bg);color:var(--sp-slot-selected-fg)}.sp-slot:disabled{cursor:not-allowed;opacity:.45}.sp-slot:focus-visible{outline:2px solid var(--sp-focus);outline-offset:2px}.sp-slot[aria-selected=true]:focus-visible{outline-color:var(--sp-fg)}.sp-empty{color:var(--sp-muted);user-select:none}.sp-nav{display:grid;inline-size:var(--sp-nav-size);block-size:var(--sp-nav-size);border:1px solid var(--sp-border);background:var(--sp-bg);color:var(--sp-fg);cursor:pointer;border-radius:50%;place-items: center;margin-block-start:.45rem;padding:0}.sp-nav:hover:not(:disabled){background:var(--sp-hover)}.sp-nav:disabled{cursor:not-allowed;opacity:.4}.sp-nav svg{display:block;pointer-events:none;block-size:1rem;inline-size:1rem}[dir=rtl] .sp-nav svg,html[dir=rtl] .sp-nav svg{transform:scaleX(-1)}.sp-more{display:flex;justify-content:center;margin-block-start:1rem}slot-picker:not([expanded]) .sp-more{position:absolute;display:grid;min-block-size:var(--sp-footer-block-size);place-items: end center;margin-block-start:0;bottom:0;left:0;right:0}slot-picker:not([expanded]) .sp-more:before{content:"";position:absolute;block-size:var(--sp-more-fade-size,4rem);background:linear-gradient(to bottom,transparent,var(--sp-more-bg,var(--sp-bg)));pointer-events:none;bottom:0;left:0;right:0}slot-picker[expanded] .sp-more{position:static}slot-picker[expanded] .sp-more:before{content:none}.sp-more-button{position:relative;z-index:1;color:var(--sp-accent);font:inherit;cursor:pointer;background:0 0;border:0}.sp-status{color:var(--sp-muted);text-align:center;margin-block-end:.75rem}.sp-status-error{color:var(--sp-fg)}.sp-day-empty{display:grid;min-block-size:var(--sp-slot-block-size);color:var(--sp-muted);text-align:center;place-items: center;padding-inline-start:.5rem;padding-inline-end:.5rem;font-size:.9rem}.sp-day[data-closed],.sp-panel[data-closed],.sp-strip-day[data-closed]{opacity:var(--sp-closed-opacity,.55)}.sp-range-empty{display:grid;box-sizing:border-box;min-block-size:var(--sp-collapsed-block-size);border-radius:var(--sp-radius);background:var(--sp-card-bg);text-align:center;align-content: center;justify-items:center;gap:.5rem;padding:1.5rem 1rem}slot-picker[layout=day] .sp-range-empty{min-block-size:var(--sp-panel-min-block-size)}slot-picker[layout=day] .sp-day-empty{min-block-size:var(--sp-panel-min-block-size);align-content: center}.sp-range-empty-title{font-size:1rem}.sp-range-empty-description{color:var(--sp-muted);margin:0}.sp-range-empty-actions{display:flex;flex-wrap:wrap;justify-content:center;gap:.5rem}.sp-range-empty-next{border-radius:var(--sp-radius);background:var(--sp-accent);color:var(--sp-accent-fg);font:inherit;cursor:pointer;border:0;padding:.6rem 1rem}.sp-range-empty-next:hover{background:color-mix(in srgb,var(--sp-accent)85%,var(--sp-bg))}.sp-range-empty-availability{border:1px solid var(--sp-border);border-radius:var(--sp-radius);background:var(--sp-bg);color:var(--sp-accent);font:inherit;cursor:pointer;padding:.6rem 1rem}.sp-range-empty-availability:hover{background:var(--sp-hover)}.sp-range-empty-next:focus-visible{outline:2px solid var(--sp-focus);outline-offset:2px}.sp-range-empty-availability:focus-visible{outline:2px solid var(--sp-focus);outline-offset:2px}.sp-daystrip{display:grid;grid-template-columns:repeat(var(--_sp-day-count,5),minmax(0,1fr));gap:var(--sp-gap);margin-block-end:1rem}.sp-strip-day{display:grid;border:1px solid var(--sp-border);border-radius:var(--sp-radius);background:var(--sp-card-bg);color:var(--sp-fg);font:inherit;cursor:pointer;justify-items:center;gap:.1rem;min-inline-size:0;padding-block-start:.6rem;padding-block-end:.55rem;padding-inline-start:.25rem;padding-inline-end:.25rem}.sp-strip-day:hover{background:var(--sp-hover)}.sp-strip-day[aria-pressed=true]{border-color:var(--sp-accent);background:var(--sp-accent-soft)}.sp-strip-weekday{color:var(--sp-muted);font-size:.85rem}.sp-strip-day[data-today] .sp-strip-weekday{font-weight:700}.sp-strip-date{font-size:.9rem}.sp-strip-count{color:var(--sp-muted);text-align:center;overflow-wrap:anywhere;max-inline-size:100%;font-size:.8rem}.sp-panel-header{position:relative;display:flex;text-align:center;justify-content:center;align-items: center;gap:.5rem;margin-block-end:.75rem}.sp-panel-title{font-size:1rem}.sp-panel-slots{display:grid;grid-template-columns:repeat(var(--sp-slot-columns,3),minmax(0,1fr));gap:var(--sp-gap)}.sp-day-notice{display:block;box-sizing:border-box;overflow:hidden;border-radius:var(--sp-radius);background:var(--sp-hover);text-align:center;min-inline-size:0;max-inline-size:100%;margin-block-end:.75rem;padding:.75rem 1rem}.sp-day-notice-label{display:-webkit-box;overflow:hidden;overflow-wrap:anywhere;-webkit-line-clamp:2;-webkit-box-orient:vertical;margin-block-end:.25rem}.sp-day-notice-description{display:none;overflow-wrap:anywhere;color:var(--sp-muted);min-inline-size:0;max-inline-size:100%;margin:0;font-size:.9rem}slot-picker[layout=day] .sp-day-notice-label{display:block;-webkit-line-clamp:unset}slot-picker[layout=day] .sp-day-notice-description{display:block}.sp-nav:focus-visible{outline:2px solid var(--sp-focus);outline-offset:2px}.sp-home:focus-visible{outline:2px solid var(--sp-focus);outline-offset:2px}.sp-more-button:focus-visible{outline:2px solid var(--sp-focus);outline-offset:2px}.sp-notice[data-day-index]:focus-visible{outline:2px solid var(--sp-focus);outline-offset:2px}.sp-strip-day:focus-visible{outline:2px solid var(--sp-focus);outline-offset:2px}@media (forced-colors:active){.sp-slot{border-color:buttontext}.sp-slot[aria-selected=true]{border-width:2px}.sp-strip-day[aria-pressed=true]{border-width:2px;border-color:buttontext}.sp-day-notice{border:1px solid buttontext}.sp-notice-dot{background:canvastext}}
|