calkit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1845 @@
1
+ class ce extends HTMLElement {
2
+ constructor() {
3
+ super(), this.attachShadow({ mode: "open" }), this._initialized = !1;
4
+ }
5
+ /** Override in subclass — return array of CSSStyleSheet or CSS strings. */
6
+ static get styles() {
7
+ return [];
8
+ }
9
+ connectedCallback() {
10
+ this._initialized || (this._adoptStyles(), this._initialized = !0), this.render();
11
+ }
12
+ _adoptStyles() {
13
+ const e = this.constructor.styles;
14
+ if (e.length)
15
+ if ("adoptedStyleSheets" in this.shadowRoot)
16
+ this.shadowRoot.adoptedStyleSheets = e.map((a) => {
17
+ if (a instanceof CSSStyleSheet) return a;
18
+ const t = new CSSStyleSheet();
19
+ return t.replaceSync(a), t;
20
+ });
21
+ else
22
+ for (const a of e) {
23
+ const t = document.createElement("style");
24
+ t.textContent = a instanceof CSSStyleSheet ? "" : a, this.shadowRoot.prepend(t);
25
+ }
26
+ }
27
+ /** Subclasses override to update Shadow DOM. */
28
+ render() {
29
+ }
30
+ /** Dispatch a composed, bubbling custom event. */
31
+ emit(e, a = {}) {
32
+ this.dispatchEvent(
33
+ new CustomEvent(e, { detail: a, bubbles: !0, composed: !0 })
34
+ );
35
+ }
36
+ /** Show an inline status banner. */
37
+ showStatus(e, a, t = {}) {
38
+ if (!this._store) return;
39
+ const { autoDismiss: n, dismissible: i = !0 } = t;
40
+ clearTimeout(this._statusTimer), this._store.set({ statusType: e, statusMessage: a, statusDismissible: i }), this.emit("cal:status", { type: e, message: a }), n && n > 0 && (this._statusTimer = setTimeout(() => this.clearStatus(), n));
41
+ }
42
+ /** Clear the status banner. */
43
+ clearStatus() {
44
+ this._store && (clearTimeout(this._statusTimer), this._store.set({ statusType: null, statusMessage: null, statusDismissible: !0 }), this.emit("cal:status", { type: null, message: null }));
45
+ }
46
+ /** Query within shadow root. */
47
+ $(e) {
48
+ return this.shadowRoot.querySelector(e);
49
+ }
50
+ $$(e) {
51
+ return this.shadowRoot.querySelectorAll(e);
52
+ }
53
+ }
54
+ function de(s) {
55
+ let e = { ...s };
56
+ const a = /* @__PURE__ */ new Set();
57
+ return {
58
+ get(t) {
59
+ return e[t];
60
+ },
61
+ set(t) {
62
+ const n = e;
63
+ e = { ...e, ...t };
64
+ let i = !1;
65
+ for (const r of Object.keys(t))
66
+ if (n[r] !== e[r]) {
67
+ i = !0;
68
+ break;
69
+ }
70
+ if (i)
71
+ for (const r of a) r(e, n);
72
+ },
73
+ getState() {
74
+ return e;
75
+ },
76
+ subscribe(t) {
77
+ return a.add(t), () => a.delete(t);
78
+ }
79
+ };
80
+ }
81
+ const J = [
82
+ "January",
83
+ "February",
84
+ "March",
85
+ "April",
86
+ "May",
87
+ "June",
88
+ "July",
89
+ "August",
90
+ "September",
91
+ "October",
92
+ "November",
93
+ "December"
94
+ ], ue = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
95
+ function ge(s = 0) {
96
+ const e = [];
97
+ for (let a = 0; a < 7; a++)
98
+ e.push(ue[(s + a) % 7]);
99
+ return e;
100
+ }
101
+ function V(s, e) {
102
+ return new Date(s, e + 1, 0).getDate();
103
+ }
104
+ function he(s, e) {
105
+ return new Date(s, e, 1).getDay();
106
+ }
107
+ function T(s) {
108
+ if (typeof s == "string") return s;
109
+ const e = s instanceof Date ? s : new Date(s.year, s.month, s.day), a = e.getFullYear(), t = String(e.getMonth() + 1).padStart(2, "0"), n = String(e.getDate()).padStart(2, "0");
110
+ return `${a}-${t}-${n}`;
111
+ }
112
+ function M(s) {
113
+ if (!s) return null;
114
+ if (s instanceof Date) return s;
115
+ if (typeof s == "string") {
116
+ const [e, a, t] = s.split("-").map(Number);
117
+ return !e || !a || !t ? null : new Date(e, a - 1, t);
118
+ }
119
+ return null;
120
+ }
121
+ function Y(s, e) {
122
+ if (!s || !e) return !1;
123
+ const a = M(s), t = M(e);
124
+ return !a || !t ? !1 : a.getFullYear() === t.getFullYear() && a.getMonth() === t.getMonth() && a.getDate() === t.getDate();
125
+ }
126
+ function be(s, e, a) {
127
+ if (!s || !e || !a) return !1;
128
+ const t = M(s), n = M(e), i = M(a);
129
+ if (!t || !n || !i) return !1;
130
+ const r = t.getTime(), o = Math.min(n.getTime(), i.getTime()), l = Math.max(n.getTime(), i.getTime());
131
+ return r >= o && r <= l;
132
+ }
133
+ function ae() {
134
+ return T(/* @__PURE__ */ new Date());
135
+ }
136
+ function B(s, e, a) {
137
+ const t = new Date(s, e + a, 1);
138
+ return { year: t.getFullYear(), month: t.getMonth() };
139
+ }
140
+ function me(s, e, a = 0) {
141
+ const t = V(s, e), i = (he(s, e) - a + 7) % 7, r = [], o = ae(), l = B(s, e, -1), u = V(l.year, l.month);
142
+ for (let c = i - 1; c >= 0; c--) {
143
+ const d = u - c, b = T({ year: l.year, month: l.month, day: d });
144
+ r.push({ year: l.year, month: l.month, day: d, dateString: b, isCurrentMonth: !1, isToday: b === o });
145
+ }
146
+ for (let c = 1; c <= t; c++) {
147
+ const d = T({ year: s, month: e, day: c });
148
+ r.push({ year: s, month: e, day: c, dateString: d, isCurrentMonth: !0, isToday: d === o });
149
+ }
150
+ const m = B(s, e, 1);
151
+ let g = 1;
152
+ for (; r.length < 42; ) {
153
+ const c = T({ year: m.year, month: m.month, day: g });
154
+ r.push({ year: m.year, month: m.month, day: g, dateString: c, isCurrentMonth: !1, isToday: c === o }), g++;
155
+ }
156
+ return r;
157
+ }
158
+ function N(s) {
159
+ if (!s || typeof s != "string") return null;
160
+ const e = s.trim().toUpperCase(), a = e.match(/^(\d{1,2}):(\d{2})\s*(AM|PM)$/);
161
+ if (a) {
162
+ let n = parseInt(a[1], 10);
163
+ const i = parseInt(a[2], 10), r = a[3];
164
+ return r === "AM" && n === 12 && (n = 0), r === "PM" && n !== 12 && (n += 12), { hours: n, minutes: i };
165
+ }
166
+ const t = e.match(/^(\d{1,2}):(\d{2})$/);
167
+ return t ? { hours: parseInt(t[1], 10), minutes: parseInt(t[2], 10) } : null;
168
+ }
169
+ function K(s, e, a = "24h") {
170
+ const t = String(e).padStart(2, "0");
171
+ if (a === "12h") {
172
+ const n = s >= 12 ? "PM" : "AM";
173
+ return `${s % 12 || 12}:${t} ${n}`;
174
+ }
175
+ return `${String(s).padStart(2, "0")}:${t}`;
176
+ }
177
+ function A(s) {
178
+ const e = N(s);
179
+ return e ? e.hours * 60 + e.minutes : 0;
180
+ }
181
+ function X(s) {
182
+ const e = Math.floor(s / 60) % 24, a = s % 60;
183
+ return `${String(e).padStart(2, "0")}:${String(a).padStart(2, "0")}`;
184
+ }
185
+ function pe(s, e, a) {
186
+ const t = [], n = A(s), i = A(e);
187
+ for (let r = n; r <= i; r += a)
188
+ t.push(X(r));
189
+ return t;
190
+ }
191
+ function fe(s, e, a, t = "24h") {
192
+ const n = [], i = A(s), r = A(e);
193
+ for (let o = i; o <= r; o += a) {
194
+ const l = X(o), u = o + a, m = X(Math.min(u, r + a)), g = N(l), c = N(m), d = g ? K(g.hours, g.minutes, t) : l, b = c ? K(c.hours, c.minutes, t) : m;
195
+ n.push({ time: l, displayText: `${d}–${b}` });
196
+ }
197
+ return n;
198
+ }
199
+ function Q(s, e, a) {
200
+ const t = A(s), n = A(e), i = A(a), r = Math.min(n, i), o = Math.max(n, i);
201
+ return t >= r && t <= o;
202
+ }
203
+ const ve = `
204
+ :host {
205
+ /* Light theme (default) */
206
+ --cal-bg: 0 0% 100%;
207
+ --cal-bg-muted: 240 5% 96%;
208
+ --cal-fg: 240 6% 10%;
209
+ --cal-fg-muted: 240 4% 46%;
210
+ --cal-border: 240 6% 90%;
211
+ --cal-accent: 240 6% 10%;
212
+ --cal-accent-fg: 0 0% 100%;
213
+ --cal-accent-subtle: 240 5% 96%;
214
+ --cal-hover: 240 5% 93%;
215
+ --cal-ring: 240 6% 10%;
216
+ --cal-radius: 8px;
217
+ --cal-radius-sm: 6px;
218
+ --cal-cell-size: 36px;
219
+ --cal-transition: 150ms ease;
220
+
221
+ /* Booking color palette (softer / less saturated) */
222
+ --cal-booking-blue-bg: 217 55% 94%;
223
+ --cal-booking-blue-fg: 217 60% 35%;
224
+ --cal-booking-green-bg: 152 45% 93%;
225
+ --cal-booking-green-fg: 152 55% 28%;
226
+ --cal-booking-red-bg: 4 50% 94%;
227
+ --cal-booking-red-fg: 4 55% 40%;
228
+ --cal-booking-orange-bg: 30 55% 93%;
229
+ --cal-booking-orange-fg: 30 60% 35%;
230
+ --cal-booking-gray-bg: 240 8% 94%;
231
+ --cal-booking-gray-fg: 240 8% 38%;
232
+
233
+ /* Booking hover tokens */
234
+ --cal-booking-blue-hover: 217 55% 88%;
235
+ --cal-booking-green-hover: 152 45% 87%;
236
+ --cal-booking-red-hover: 4 50% 88%;
237
+ --cal-booking-orange-hover: 30 55% 87%;
238
+ --cal-booking-gray-hover: 240 8% 88%;
239
+
240
+ /* Scheduler tokens */
241
+ --cal-sched-grid-line: 240 6% 94%;
242
+ --cal-sched-now-line: 4 70% 55%;
243
+ --cal-sched-slot-hover: 240 5% 97%;
244
+ --cal-sched-header-bg: 240 5% 98%;
245
+
246
+ /* Status tokens */
247
+ --cal-status-error-bg: 4 50% 95%;
248
+ --cal-status-error-fg: 4 55% 40%;
249
+ --cal-status-error-border: 4 50% 85%;
250
+ --cal-status-warning-bg: 40 55% 95%;
251
+ --cal-status-warning-fg: 40 60% 35%;
252
+ --cal-status-warning-border: 40 50% 85%;
253
+ --cal-status-info-bg: 217 55% 95%;
254
+ --cal-status-info-fg: 217 60% 35%;
255
+ --cal-status-info-border: 217 50% 85%;
256
+ --cal-status-success-bg: 152 45% 95%;
257
+ --cal-status-success-fg: 152 55% 28%;
258
+ --cal-status-success-border: 152 45% 85%;
259
+ }
260
+
261
+ :host([theme="dark"]) {
262
+ --cal-bg: 240 6% 10%;
263
+ --cal-bg-muted: 240 4% 16%;
264
+ --cal-fg: 0 0% 98%;
265
+ --cal-fg-muted: 240 4% 54%;
266
+ --cal-border: 240 4% 20%;
267
+ --cal-accent: 0 0% 98%;
268
+ --cal-accent-fg: 240 6% 10%;
269
+ --cal-accent-subtle: 240 4% 16%;
270
+ --cal-hover: 240 4% 20%;
271
+ --cal-ring: 0 0% 98%;
272
+
273
+ --cal-booking-blue-bg: 217 50% 25%;
274
+ --cal-booking-blue-fg: 217 80% 75%;
275
+ --cal-booking-green-bg: 142 40% 22%;
276
+ --cal-booking-green-fg: 142 70% 70%;
277
+ --cal-booking-red-bg: 4 45% 25%;
278
+ --cal-booking-red-fg: 4 70% 75%;
279
+ --cal-booking-orange-bg: 30 45% 25%;
280
+ --cal-booking-orange-fg: 30 80% 75%;
281
+ --cal-booking-gray-bg: 240 5% 22%;
282
+ --cal-booking-gray-fg: 240 5% 65%;
283
+
284
+ --cal-booking-blue-hover: 217 50% 30%;
285
+ --cal-booking-green-hover: 142 40% 27%;
286
+ --cal-booking-red-hover: 4 45% 30%;
287
+ --cal-booking-orange-hover: 30 45% 30%;
288
+ --cal-booking-gray-hover: 240 5% 27%;
289
+
290
+ --cal-sched-grid-line: 240 4% 18%;
291
+ --cal-sched-now-line: 4 55% 55%;
292
+ --cal-sched-slot-hover: 240 4% 14%;
293
+ --cal-sched-header-bg: 240 5% 12%;
294
+
295
+ --cal-status-error-bg: 4 45% 20%;
296
+ --cal-status-error-fg: 4 70% 75%;
297
+ --cal-status-error-border: 4 45% 30%;
298
+ --cal-status-warning-bg: 40 45% 20%;
299
+ --cal-status-warning-fg: 40 80% 75%;
300
+ --cal-status-warning-border: 40 45% 30%;
301
+ --cal-status-info-bg: 217 50% 20%;
302
+ --cal-status-info-fg: 217 80% 75%;
303
+ --cal-status-info-border: 217 50% 30%;
304
+ --cal-status-success-bg: 152 40% 18%;
305
+ --cal-status-success-fg: 152 70% 70%;
306
+ --cal-status-success-border: 152 40% 28%;
307
+ }
308
+
309
+ :host([theme="auto"]) {
310
+ --cal-bg: 0 0% 100%;
311
+ --cal-bg-muted: 240 5% 96%;
312
+ --cal-fg: 240 6% 10%;
313
+ --cal-fg-muted: 240 4% 46%;
314
+ --cal-border: 240 6% 90%;
315
+ --cal-accent: 240 6% 10%;
316
+ --cal-accent-fg: 0 0% 100%;
317
+ --cal-accent-subtle: 240 5% 96%;
318
+ --cal-hover: 240 5% 93%;
319
+ --cal-ring: 240 6% 10%;
320
+ }
321
+
322
+ @media (prefers-color-scheme: dark) {
323
+ :host([theme="auto"]) {
324
+ --cal-bg: 240 6% 10%;
325
+ --cal-bg-muted: 240 4% 16%;
326
+ --cal-fg: 0 0% 98%;
327
+ --cal-fg-muted: 240 4% 54%;
328
+ --cal-border: 240 4% 20%;
329
+ --cal-accent: 0 0% 98%;
330
+ --cal-accent-fg: 240 6% 10%;
331
+ --cal-accent-subtle: 240 4% 16%;
332
+ --cal-hover: 240 4% 20%;
333
+ --cal-ring: 0 0% 98%;
334
+
335
+ --cal-booking-blue-bg: 217 50% 25%;
336
+ --cal-booking-blue-fg: 217 80% 75%;
337
+ --cal-booking-green-bg: 142 40% 22%;
338
+ --cal-booking-green-fg: 142 70% 70%;
339
+ --cal-booking-red-bg: 4 45% 25%;
340
+ --cal-booking-red-fg: 4 70% 75%;
341
+ --cal-booking-orange-bg: 30 45% 25%;
342
+ --cal-booking-orange-fg: 30 80% 75%;
343
+ --cal-booking-gray-bg: 240 5% 22%;
344
+ --cal-booking-gray-fg: 240 5% 65%;
345
+
346
+ --cal-booking-blue-hover: 217 50% 30%;
347
+ --cal-booking-green-hover: 142 40% 27%;
348
+ --cal-booking-red-hover: 4 45% 30%;
349
+ --cal-booking-orange-hover: 30 45% 30%;
350
+ --cal-booking-gray-hover: 240 5% 27%;
351
+
352
+ --cal-sched-grid-line: 240 4% 18%;
353
+ --cal-sched-now-line: 4 55% 55%;
354
+ --cal-sched-slot-hover: 240 4% 14%;
355
+ --cal-sched-header-bg: 240 5% 12%;
356
+
357
+ --cal-status-error-bg: 4 45% 20%;
358
+ --cal-status-error-fg: 4 70% 75%;
359
+ --cal-status-error-border: 4 45% 30%;
360
+ --cal-status-warning-bg: 40 45% 20%;
361
+ --cal-status-warning-fg: 40 80% 75%;
362
+ --cal-status-warning-border: 40 45% 30%;
363
+ --cal-status-info-bg: 217 50% 20%;
364
+ --cal-status-info-fg: 217 80% 75%;
365
+ --cal-status-info-border: 217 50% 30%;
366
+ --cal-status-success-bg: 152 40% 18%;
367
+ --cal-status-success-fg: 152 70% 70%;
368
+ --cal-status-success-border: 152 40% 28%;
369
+ }
370
+ }
371
+ `, ye = `
372
+ :host {
373
+ display: inline-block;
374
+ font-family: inherit;
375
+ font-size: 14px;
376
+ line-height: 1.5;
377
+ color: hsl(var(--cal-fg));
378
+ -webkit-font-smoothing: antialiased;
379
+ -moz-osx-font-smoothing: grayscale;
380
+ }
381
+
382
+ :host([display="inline"]) {
383
+ display: inline-block;
384
+ }
385
+
386
+ *,
387
+ *::before,
388
+ *::after {
389
+ box-sizing: border-box;
390
+ }
391
+
392
+ button {
393
+ font: inherit;
394
+ color: inherit;
395
+ background: none;
396
+ border: none;
397
+ padding: 0;
398
+ margin: 0;
399
+ cursor: pointer;
400
+ -webkit-tap-highlight-color: transparent;
401
+ }
402
+
403
+ button:focus-visible {
404
+ outline: 2px solid hsl(var(--cal-ring));
405
+ outline-offset: 2px;
406
+ border-radius: var(--cal-radius-sm);
407
+ }
408
+
409
+ [hidden] {
410
+ display: none !important;
411
+ }
412
+ `, ke = `
413
+ @keyframes cal-fade-in {
414
+ from { opacity: 0; }
415
+ to { opacity: 1; }
416
+ }
417
+
418
+ @keyframes cal-slide-up {
419
+ from {
420
+ opacity: 0;
421
+ transform: translateY(4px);
422
+ }
423
+ to {
424
+ opacity: 1;
425
+ transform: translateY(0);
426
+ }
427
+ }
428
+
429
+ @keyframes cal-slide-left {
430
+ from {
431
+ opacity: 0;
432
+ transform: translateX(16px);
433
+ }
434
+ to {
435
+ opacity: 1;
436
+ transform: translateX(0);
437
+ }
438
+ }
439
+
440
+ @keyframes cal-slide-right {
441
+ from {
442
+ opacity: 0;
443
+ transform: translateX(-16px);
444
+ }
445
+ to {
446
+ opacity: 1;
447
+ transform: translateX(0);
448
+ }
449
+ }
450
+
451
+ .cal-animate-fade { animation: cal-fade-in 150ms cubic-bezier(0.16, 1, 0.3, 1); }
452
+ .cal-animate-slide-up { animation: cal-slide-up 200ms cubic-bezier(0.16, 1, 0.3, 1); }
453
+ .cal-animate-slide-left { animation: cal-slide-left 200ms cubic-bezier(0.16, 1, 0.3, 1); }
454
+ .cal-animate-slide-right { animation: cal-slide-right 200ms cubic-bezier(0.16, 1, 0.3, 1); }
455
+
456
+ @keyframes cal-shimmer {
457
+ 0% { background-position: -200% 0; }
458
+ 100% { background-position: 200% 0; }
459
+ }
460
+
461
+ .cal-skeleton {
462
+ background: linear-gradient(
463
+ 90deg,
464
+ hsl(var(--cal-bg-muted)) 25%,
465
+ hsl(var(--cal-hover)) 50%,
466
+ hsl(var(--cal-bg-muted)) 75%
467
+ );
468
+ background-size: 200% 100%;
469
+ animation: cal-shimmer 1.5s infinite ease-in-out;
470
+ border-radius: 999px;
471
+ }
472
+
473
+ .cal-skeleton--rect {
474
+ border-radius: var(--cal-radius-sm);
475
+ }
476
+ `, ne = '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M10 12L6 8l4-4"/></svg>', se = '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 4l4 4-4 4"/></svg>';
477
+ function Z({ year: s, month: e, onPrev: a, onNext: t, onTitleClick: n }) {
478
+ const i = document.createElement("div");
479
+ i.classList.add("cal-nav");
480
+ const r = document.createElement("button");
481
+ r.classList.add("cal-nav__btn", "cal-nav__btn--prev"), r.innerHTML = ne, r.setAttribute("aria-label", "Previous month"), r.addEventListener("click", a);
482
+ const o = n ? "button" : "div", l = document.createElement(o);
483
+ l.classList.add("cal-nav__title"), n && (l.classList.add("cal-nav__title--interactive"), l.setAttribute("aria-label", `Select month and year, currently ${J[e]} ${s}`), l.addEventListener("click", n)), l.setAttribute("aria-live", "polite"), l.textContent = `${J[e]} ${s}`;
484
+ const u = document.createElement("button");
485
+ return u.classList.add("cal-nav__btn", "cal-nav__btn--next"), u.innerHTML = se, u.setAttribute("aria-label", "Next month"), u.addEventListener("click", t), i.appendChild(r), i.appendChild(l), i.appendChild(u), i;
486
+ }
487
+ const _e = `
488
+ .cal-nav {
489
+ display: flex;
490
+ align-items: center;
491
+ justify-content: space-between;
492
+ padding: 0 4px;
493
+ margin-bottom: 8px;
494
+ }
495
+
496
+ .cal-nav__btn {
497
+ display: flex;
498
+ align-items: center;
499
+ justify-content: center;
500
+ width: 28px;
501
+ height: 28px;
502
+ border-radius: var(--cal-radius-sm);
503
+ color: hsl(var(--cal-fg));
504
+ transition: background var(--cal-transition);
505
+ }
506
+
507
+ .cal-nav__btn:hover {
508
+ background: hsl(var(--cal-hover));
509
+ }
510
+
511
+ .cal-nav__title {
512
+ font-size: 14px;
513
+ font-weight: 600;
514
+ color: hsl(var(--cal-fg));
515
+ user-select: none;
516
+ }
517
+
518
+ .cal-nav__title--interactive {
519
+ cursor: pointer;
520
+ padding: 2px 8px;
521
+ border-radius: var(--cal-radius-sm);
522
+ transition: background var(--cal-transition);
523
+ }
524
+
525
+ .cal-nav__title--interactive:hover {
526
+ background: hsl(var(--cal-hover));
527
+ }
528
+ `, xe = [
529
+ "Jan",
530
+ "Feb",
531
+ "Mar",
532
+ "Apr",
533
+ "May",
534
+ "Jun",
535
+ "Jul",
536
+ "Aug",
537
+ "Sep",
538
+ "Oct",
539
+ "Nov",
540
+ "Dec"
541
+ ];
542
+ function we({
543
+ pickerYear: s,
544
+ viewMonth: e,
545
+ viewYear: a,
546
+ onMonthSelect: t,
547
+ onYearPrev: n,
548
+ onYearNext: i,
549
+ onClose: r
550
+ }) {
551
+ const o = document.createElement("div");
552
+ o.classList.add("cal-myp", "cal-animate-fade");
553
+ const l = document.createElement("div");
554
+ l.classList.add("cal-myp__year-nav");
555
+ const u = document.createElement("button");
556
+ u.classList.add("cal-nav__btn"), u.innerHTML = ne, u.setAttribute("aria-label", "Previous year"), u.addEventListener("click", n);
557
+ const m = document.createElement("div");
558
+ m.classList.add("cal-myp__year-label"), m.textContent = s;
559
+ const g = document.createElement("button");
560
+ g.classList.add("cal-nav__btn"), g.innerHTML = se, g.setAttribute("aria-label", "Next year"), g.addEventListener("click", i), l.appendChild(u), l.appendChild(m), l.appendChild(g), o.appendChild(l);
561
+ const c = document.createElement("div");
562
+ c.classList.add("cal-myp__grid");
563
+ const d = /* @__PURE__ */ new Date(), b = d.getMonth(), E = d.getFullYear();
564
+ for (let v = 0; v < 12; v++) {
565
+ const x = document.createElement("button");
566
+ x.classList.add("cal-myp__cell"), x.textContent = xe[v], v === e && s === a && x.classList.add("cal-myp__cell--active"), v === b && s === E && x.classList.add("cal-myp__cell--today"), x.addEventListener("click", () => t(v, s)), c.appendChild(x);
567
+ }
568
+ return o.appendChild(c), o.addEventListener("keydown", (v) => {
569
+ v.key === "Escape" && (v.stopPropagation(), r());
570
+ }), o;
571
+ }
572
+ const Se = `
573
+ .cal-myp {
574
+ width: calc(7 * var(--cal-cell-size));
575
+ }
576
+
577
+ .cal-myp__year-nav {
578
+ display: flex;
579
+ align-items: center;
580
+ justify-content: space-between;
581
+ padding: 0 4px;
582
+ margin-bottom: 8px;
583
+ }
584
+
585
+ .cal-myp__year-label {
586
+ font-size: 14px;
587
+ font-weight: 600;
588
+ color: hsl(var(--cal-fg));
589
+ user-select: none;
590
+ }
591
+
592
+ .cal-myp__grid {
593
+ display: grid;
594
+ grid-template-columns: repeat(3, 1fr);
595
+ gap: 4px;
596
+ }
597
+
598
+ .cal-myp__cell {
599
+ display: flex;
600
+ align-items: center;
601
+ justify-content: center;
602
+ height: calc(var(--cal-cell-size) * 1.5);
603
+ font-size: 13px;
604
+ font-weight: 500;
605
+ color: hsl(var(--cal-fg));
606
+ border-radius: var(--cal-radius-sm);
607
+ cursor: pointer;
608
+ transition: background var(--cal-transition);
609
+ user-select: none;
610
+ }
611
+
612
+ .cal-myp__cell:hover {
613
+ background: hsl(var(--cal-hover));
614
+ }
615
+
616
+ .cal-myp__cell--active {
617
+ background: hsl(var(--cal-accent));
618
+ color: hsl(var(--cal-accent-fg));
619
+ font-weight: 600;
620
+ }
621
+
622
+ .cal-myp__cell--active:hover {
623
+ background: hsl(var(--cal-accent));
624
+ }
625
+
626
+ .cal-myp__cell--today:not(.cal-myp__cell--active) {
627
+ border: 1px solid hsl(var(--cal-border));
628
+ font-weight: 600;
629
+ }
630
+ `;
631
+ function Le({ trigger: s, content: e, onClose: a }) {
632
+ const t = document.createElement("div");
633
+ t.classList.add("cal-popover"), t.setAttribute("role", "dialog"), t.setAttribute("aria-modal", "false"), t.style.display = "none", t.appendChild(e);
634
+ let n = !1;
635
+ function i() {
636
+ t.classList.remove("cal-popover--above");
637
+ const g = s.getBoundingClientRect(), c = t.offsetHeight, d = window.innerHeight - g.bottom, b = g.top;
638
+ d < c + 8 && b > d ? (t.classList.add("cal-popover--above"), t.style.top = "auto", t.style.bottom = "100%", t.style.marginBottom = "4px", t.style.marginTop = "0") : (t.style.top = "100%", t.style.bottom = "auto", t.style.marginTop = "4px", t.style.marginBottom = "0");
639
+ }
640
+ function r() {
641
+ n || (n = !0, t.style.display = "", t.classList.add("cal-animate-slide-up"), requestAnimationFrame(() => i()), document.addEventListener("click", l, !0), document.addEventListener("keydown", u, !0));
642
+ }
643
+ function o() {
644
+ n && (n = !1, t.style.display = "none", t.classList.remove("cal-animate-slide-up"), document.removeEventListener("click", l, !0), document.removeEventListener("keydown", u, !0), a == null || a());
645
+ }
646
+ function l(g) {
647
+ var d;
648
+ const c = (d = s.getRootNode()) == null ? void 0 : d.host;
649
+ c && !c.contains(g.target) && g.target !== c && o();
650
+ }
651
+ function u(g) {
652
+ g.key === "Escape" && (g.stopPropagation(), o());
653
+ }
654
+ function m() {
655
+ n && (n = !1, t.style.display = "none", t.classList.remove("cal-animate-slide-up")), document.removeEventListener("click", l, !0), document.removeEventListener("keydown", u, !0);
656
+ }
657
+ return { panel: t, open: r, close: o, destroy: m, get isOpen() {
658
+ return n;
659
+ } };
660
+ }
661
+ const Ee = `
662
+ .cal-popover-wrapper {
663
+ position: relative;
664
+ display: inline-block;
665
+ }
666
+
667
+ .cal-popover {
668
+ position: absolute;
669
+ left: 0;
670
+ z-index: 50;
671
+ background: hsl(var(--cal-bg));
672
+ border: 1px solid hsl(var(--cal-border));
673
+ border-radius: var(--cal-radius);
674
+ box-shadow: 0 4px 16px -2px rgba(0, 0, 0, 0.08), 0 2px 6px -2px rgba(0, 0, 0, 0.04);
675
+ padding: 12px;
676
+ }
677
+
678
+ .cal-trigger {
679
+ display: inline-flex;
680
+ align-items: center;
681
+ gap: 8px;
682
+ height: 36px;
683
+ padding: 0 12px;
684
+ font-size: 14px;
685
+ border: 1px solid hsl(var(--cal-border));
686
+ border-radius: var(--cal-radius-sm);
687
+ background: hsl(var(--cal-bg));
688
+ color: hsl(var(--cal-fg));
689
+ cursor: pointer;
690
+ transition: border-color var(--cal-transition);
691
+ white-space: nowrap;
692
+ }
693
+
694
+ .cal-trigger:hover {
695
+ border-color: hsl(var(--cal-fg-muted));
696
+ }
697
+
698
+ .cal-trigger--placeholder {
699
+ color: hsl(var(--cal-fg-muted));
700
+ }
701
+
702
+ .cal-trigger__icon {
703
+ display: flex;
704
+ color: hsl(var(--cal-fg-muted));
705
+ }
706
+ `, ee = {
707
+ blue: { bg: "var(--cal-booking-blue-bg)", fg: "var(--cal-booking-blue-fg)", hover: "var(--cal-booking-blue-hover)" },
708
+ green: { bg: "var(--cal-booking-green-bg)", fg: "var(--cal-booking-green-fg)", hover: "var(--cal-booking-green-hover)" },
709
+ red: { bg: "var(--cal-booking-red-bg)", fg: "var(--cal-booking-red-fg)", hover: "var(--cal-booking-red-hover)" },
710
+ orange: { bg: "var(--cal-booking-orange-bg)", fg: "var(--cal-booking-orange-fg)", hover: "var(--cal-booking-orange-hover)" },
711
+ gray: { bg: "var(--cal-booking-gray-bg)", fg: "var(--cal-booking-gray-fg)", hover: "var(--cal-booking-gray-hover)" }
712
+ }, z = "blue";
713
+ function P(s) {
714
+ return ee[s] || ee[z];
715
+ }
716
+ function De(s, e = [], a = {}, t = null) {
717
+ const n = e.find((b) => b.end === s), i = e.find((b) => b.start === s), r = e.find(
718
+ (b) => b.start < s && b.end > s
719
+ );
720
+ let o = "available", l = null, u = !1, m = null, g = null, c = null;
721
+ n && i ? (o = "half-day", u = !0, m = P(n.color || z), g = P(i.color || z)) : r ? (o = "booked", c = P(r.color || z)) : i && !n ? (o = "checkin-only", g = P(i.color || z)) : n && !i && (o = "checkout-only", m = P(n.color || z));
722
+ const d = a[s];
723
+ if (d && (d.status && (o = d.status), d.label !== void 0 && (l = d.label)), t) {
724
+ const b = t(s);
725
+ b && (b.status && (o = b.status), b.label !== void 0 && (l = b.label));
726
+ }
727
+ return { status: o, label: l, checkoutBooking: n, checkinBooking: i, halfDay: u, colorOut: m, colorIn: g, colorFull: c };
728
+ }
729
+ function ie(s, e, a = []) {
730
+ if (!s || !e) return !0;
731
+ const t = s < e ? s : e, n = s < e ? e : s;
732
+ for (const i of a)
733
+ if (t < i.end && n > i.start)
734
+ return !1;
735
+ return !0;
736
+ }
737
+ function Me(s, e, a = []) {
738
+ return !s || !e ? !1 : !ie(s, e, a);
739
+ }
740
+ function Ce(s) {
741
+ const {
742
+ year: e,
743
+ month: a,
744
+ firstDay: t = 0,
745
+ selectedDates: n = [],
746
+ rangeStart: i,
747
+ rangeEnd: r,
748
+ hoverDate: o,
749
+ minDate: l,
750
+ maxDate: u,
751
+ disabledDates: m = [],
752
+ mode: g = "single",
753
+ focusedDate: c,
754
+ onSelect: d,
755
+ onHover: b,
756
+ // Booking-specific params
757
+ bookings: E = null,
758
+ dayData: v = null,
759
+ labelFormula: x = null,
760
+ showLabelsOnHover: q = !1
761
+ } = s, y = E !== null, _ = document.createElement("div");
762
+ _.setAttribute("role", "grid"), _.classList.add("cal-grid");
763
+ const S = document.createElement("div");
764
+ S.setAttribute("role", "row"), S.classList.add("cal-weekdays");
765
+ for (const w of ge(t)) {
766
+ const C = document.createElement("div");
767
+ C.setAttribute("role", "columnheader"), C.setAttribute("aria-label", w), C.classList.add("cal-weekday"), C.textContent = w, S.appendChild(C);
768
+ }
769
+ _.appendChild(S);
770
+ const re = me(e, a, t), G = g === "range" && i && !r && o || y && i && !r && o ? o : r, oe = y ? Me(i, o, E) : !1;
771
+ let $;
772
+ return re.forEach((w, C) => {
773
+ C % 7 === 0 && ($ = document.createElement("div"), $.setAttribute("role", "row"), $.classList.add("cal-row"), _.appendChild($));
774
+ const h = document.createElement("button");
775
+ h.setAttribute("role", "gridcell"), h.setAttribute("part", "day"), h.classList.add("cal-day");
776
+ const p = w.dateString;
777
+ h.dataset.date = p;
778
+ const le = new Date(w.year, w.month, w.day);
779
+ h.setAttribute("aria-label", le.toLocaleDateString("en-US", {
780
+ weekday: "long",
781
+ year: "numeric",
782
+ month: "long",
783
+ day: "numeric"
784
+ })), w.isCurrentMonth || h.classList.add("cal-day--outside"), w.isToday && h.classList.add("cal-day--today");
785
+ let k = null, O = !1;
786
+ if (y) {
787
+ k = De(p, E, v || {}, x);
788
+ const { status: f, label: L, halfDay: F, colorOut: R, colorIn: I, colorFull: H } = k;
789
+ if (f === "booked" && (h.classList.add("cal-day--booked"), H && (h.style.setProperty("--booking-bg", `hsl(${H.bg})`), h.style.setProperty("--booking-fg", `hsl(${H.fg})`), h.style.setProperty("--booking-hover", `hsl(${H.hover})`)), O = !0), f === "blocked" && (h.classList.add("cal-day--blocked"), O = !0), F && (h.classList.add("cal-day--half-day"), R && h.style.setProperty("--half-day-color-out", `hsl(${R.bg})`), I && h.style.setProperty("--half-day-color-in", `hsl(${I.bg})`), O = !0), f === "checkout-only" && (h.classList.add("cal-day--checkout-only"), R && h.style.setProperty("--half-day-color-out", `hsl(${R.bg})`)), f === "checkin-only" && (h.classList.add("cal-day--checkin-only"), I && h.style.setProperty("--half-day-color-in", `hsl(${I.bg})`)), q) {
790
+ let D = null;
791
+ if (F && k.checkoutBooking && k.checkinBooking)
792
+ D = `${k.checkoutBooking.label || ""} / ${k.checkinBooking.label || ""}`;
793
+ else if (f === "booked") {
794
+ const j = E.find((W) => W.start <= p && W.end > p);
795
+ j && (D = j.label);
796
+ } else f === "checkout-only" && k.checkoutBooking ? D = k.checkoutBooking.label : f === "checkin-only" && k.checkinBooking && (D = k.checkinBooking.label);
797
+ D && h.setAttribute("data-booking-label", D);
798
+ }
799
+ if (oe && i && !r && o) {
800
+ const D = i < o ? i : o, j = i < o ? o : i;
801
+ p >= D && p <= j && h.classList.add("cal-day--invalid-range");
802
+ }
803
+ }
804
+ if (y ? i && r && (Y(p, i) || Y(p, r)) ? (h.classList.add("cal-day--selected"), h.setAttribute("aria-selected", "true")) : h.setAttribute("aria-selected", "false") : n.some((L) => Y(L, p)) ? (h.classList.add("cal-day--selected"), h.setAttribute("aria-selected", "true")) : h.setAttribute("aria-selected", "false"), (g === "range" || y) && i && G) {
805
+ const f = Y(p, i), L = Y(p, G), F = be(p, i, G);
806
+ f && h.classList.add("cal-day--range-start"), L && h.classList.add("cal-day--range-end"), F && !f && !L && h.classList.add("cal-day--in-range");
807
+ }
808
+ const U = Te(p, l, u, m) || O;
809
+ if (U && (h.classList.add("cal-day--disabled"), h.disabled = !0, h.setAttribute("aria-disabled", "true")), c && Y(p, c) ? h.setAttribute("tabindex", "0") : h.setAttribute("tabindex", "-1"), y && k && k.label != null) {
810
+ h.classList.add("cal-day--with-label");
811
+ const f = document.createElement("span");
812
+ f.classList.add("cal-day__number"), f.textContent = w.day, h.appendChild(f);
813
+ const L = document.createElement("span");
814
+ L.classList.add("cal-day__label"), L.textContent = k.label, h.appendChild(L);
815
+ } else
816
+ h.textContent = w.day;
817
+ U ? y && h.addEventListener("mouseenter", () => b == null ? void 0 : b(p)) : (h.addEventListener("click", () => d == null ? void 0 : d(p)), h.addEventListener("mouseenter", () => b == null ? void 0 : b(p))), $.appendChild(h);
818
+ }), _.addEventListener("mouseleave", () => b == null ? void 0 : b(null)), _;
819
+ }
820
+ function Te(s, e, a, t) {
821
+ return !!(t.includes(s) || e && s < e || a && s > a);
822
+ }
823
+ const Ae = `
824
+ .cal-grid {
825
+ display: flex;
826
+ flex-direction: column;
827
+ gap: 2px;
828
+ }
829
+
830
+ .cal-weekdays {
831
+ display: grid;
832
+ grid-template-columns: repeat(7, var(--cal-cell-size));
833
+ gap: 0;
834
+ margin-bottom: 4px;
835
+ }
836
+
837
+ .cal-weekday {
838
+ display: flex;
839
+ align-items: center;
840
+ justify-content: center;
841
+ height: var(--cal-cell-size);
842
+ font-size: 12px;
843
+ font-weight: 500;
844
+ color: hsl(var(--cal-fg-muted));
845
+ user-select: none;
846
+ }
847
+
848
+ .cal-row {
849
+ display: grid;
850
+ grid-template-columns: repeat(7, var(--cal-cell-size));
851
+ gap: 0;
852
+ }
853
+
854
+ .cal-day {
855
+ display: flex;
856
+ align-items: center;
857
+ justify-content: center;
858
+ width: var(--cal-cell-size);
859
+ height: var(--cal-cell-size);
860
+ font-size: 14px;
861
+ border-radius: var(--cal-radius-sm);
862
+ transition: background var(--cal-transition), color var(--cal-transition);
863
+ position: relative;
864
+ user-select: none;
865
+ }
866
+
867
+ .cal-day:not(.cal-day--disabled):not(.cal-day--selected):not(.cal-day--booked):not(.cal-day--half-day):not(.cal-day--blocked):not(.cal-day--checkout-only):not(.cal-day--checkin-only):hover {
868
+ background: hsl(var(--cal-hover));
869
+ }
870
+
871
+ .cal-day--outside {
872
+ color: hsl(var(--cal-fg-muted));
873
+ opacity: 0.4;
874
+ }
875
+
876
+ .cal-day--today:not(.cal-day--selected):not(.cal-day--booked):not(.cal-day--half-day):not(.cal-day--checkout-only):not(.cal-day--checkin-only) {
877
+ border: 1px solid hsl(var(--cal-border));
878
+ font-weight: 600;
879
+ }
880
+
881
+ .cal-day--selected {
882
+ background: hsl(var(--cal-accent));
883
+ color: hsl(var(--cal-accent-fg));
884
+ font-weight: 600;
885
+ }
886
+
887
+ .cal-day--range-start {
888
+ background: hsl(var(--cal-accent));
889
+ color: hsl(var(--cal-accent-fg));
890
+ font-weight: 600;
891
+ border-radius: var(--cal-radius-sm) 0 0 var(--cal-radius-sm);
892
+ }
893
+
894
+ .cal-day--range-end {
895
+ background: hsl(var(--cal-accent));
896
+ color: hsl(var(--cal-accent-fg));
897
+ font-weight: 600;
898
+ border-radius: 0 var(--cal-radius-sm) var(--cal-radius-sm) 0;
899
+ }
900
+
901
+ .cal-day--range-start.cal-day--range-end {
902
+ border-radius: var(--cal-radius-sm);
903
+ }
904
+
905
+ .cal-day--in-range {
906
+ background: hsl(var(--cal-accent-subtle));
907
+ border-radius: 0;
908
+ }
909
+
910
+ .cal-day--in-range:hover {
911
+ background: hsl(var(--cal-accent-subtle)) !important;
912
+ }
913
+
914
+ .cal-day--disabled {
915
+ opacity: 0.3;
916
+ cursor: not-allowed;
917
+ }
918
+
919
+ /* ── Booking-specific styles ── */
920
+
921
+ /* Booked (fully occupied) */
922
+ .cal-day--booked {
923
+ background: var(--booking-bg, hsl(var(--cal-booking-blue-bg)));
924
+ color: var(--booking-fg, hsl(var(--cal-booking-blue-fg)));
925
+ cursor: not-allowed;
926
+ }
927
+
928
+ .cal-day--booked:hover {
929
+ background: var(--booking-hover, hsl(var(--cal-booking-blue-hover)));
930
+ }
931
+
932
+ /* Blocked */
933
+ .cal-day--blocked {
934
+ background: hsl(var(--cal-bg-muted));
935
+ opacity: 0.4;
936
+ cursor: not-allowed;
937
+ }
938
+
939
+ /* Half-day diagonal (checkout + checkin on same day) */
940
+ .cal-day--half-day {
941
+ background: linear-gradient(135deg,
942
+ var(--half-day-color-out, hsl(var(--cal-booking-blue-bg))) 49.5%,
943
+ hsl(var(--cal-bg)) 49.5%, hsl(var(--cal-bg)) 50.5%,
944
+ var(--half-day-color-in, hsl(var(--cal-booking-green-bg))) 50.5%);
945
+ cursor: not-allowed;
946
+ }
947
+
948
+ /* Checkout-only (last day of a booking — outgoing triangle) */
949
+ .cal-day--checkout-only {
950
+ background: linear-gradient(135deg,
951
+ var(--half-day-color-out, hsl(var(--cal-booking-blue-bg))) 49.5%,
952
+ hsl(var(--cal-bg)) 49.5%);
953
+ }
954
+
955
+ /* Checkin-only (first day of a booking — incoming triangle) */
956
+ .cal-day--checkin-only {
957
+ background: linear-gradient(135deg,
958
+ hsl(var(--cal-bg)) 50.5%,
959
+ var(--half-day-color-in, hsl(var(--cal-booking-blue-bg))) 50.5%);
960
+ }
961
+
962
+ /* Diagonal cells: standard text color for clean contrast */
963
+ .cal-day--half-day,
964
+ .cal-day--checkout-only,
965
+ .cal-day--checkin-only {
966
+ color: hsl(var(--cal-fg));
967
+ }
968
+
969
+ /* ── Diagonal + selection compounds ── */
970
+
971
+ /* Checkout-only — range boundary: accent-subtle fill + refined ring */
972
+ .cal-day--checkout-only.cal-day--range-start,
973
+ .cal-day--checkout-only.cal-day--range-end,
974
+ .cal-day--checkout-only.cal-day--selected {
975
+ background: linear-gradient(135deg,
976
+ var(--half-day-color-out, hsl(var(--cal-booking-blue-bg))) 49.5%,
977
+ hsl(var(--cal-accent-subtle)) 50.5%);
978
+ color: hsl(var(--cal-fg));
979
+ box-shadow: inset 0 0 0 1.5px hsl(var(--cal-accent) / 0.3);
980
+ }
981
+
982
+ /* Checkout-only — in range: accent-subtle fill */
983
+ .cal-day--checkout-only.cal-day--in-range {
984
+ background: linear-gradient(135deg,
985
+ var(--half-day-color-out, hsl(var(--cal-booking-blue-bg))) 49.5%,
986
+ hsl(var(--cal-accent-subtle)) 50.5%);
987
+ }
988
+
989
+ /* Checkin-only — range boundary: accent-subtle fill + refined ring */
990
+ .cal-day--checkin-only.cal-day--range-start,
991
+ .cal-day--checkin-only.cal-day--range-end,
992
+ .cal-day--checkin-only.cal-day--selected {
993
+ background: linear-gradient(135deg,
994
+ hsl(var(--cal-accent-subtle)) 49.5%,
995
+ var(--half-day-color-in, hsl(var(--cal-booking-blue-bg))) 50.5%);
996
+ color: hsl(var(--cal-fg));
997
+ box-shadow: inset 0 0 0 1.5px hsl(var(--cal-accent) / 0.3);
998
+ }
999
+
1000
+ /* Checkin-only — in range: accent-subtle fill */
1001
+ .cal-day--checkin-only.cal-day--in-range {
1002
+ background: linear-gradient(135deg,
1003
+ hsl(var(--cal-accent-subtle)) 49.5%,
1004
+ var(--half-day-color-in, hsl(var(--cal-booking-blue-bg))) 50.5%);
1005
+ }
1006
+
1007
+ /* Half-day in range — accent-subtle stripe between booking triangles */
1008
+ .cal-day--half-day.cal-day--in-range {
1009
+ background: linear-gradient(135deg,
1010
+ var(--half-day-color-out, hsl(var(--cal-booking-blue-bg))) 49.5%,
1011
+ hsl(var(--cal-accent-subtle)) 49.5%, hsl(var(--cal-accent-subtle)) 50.5%,
1012
+ var(--half-day-color-in, hsl(var(--cal-booking-green-bg))) 50.5%);
1013
+ }
1014
+
1015
+ /* Invalid range preview (crosses a booking) */
1016
+ .cal-day--invalid-range {
1017
+ background: hsl(var(--cal-booking-red-bg));
1018
+ border-radius: 0;
1019
+ }
1020
+
1021
+ /* Booked/half-day/diagonal cells stay opaque even when disabled */
1022
+ .cal-day--disabled.cal-day--booked,
1023
+ .cal-day--disabled.cal-day--half-day,
1024
+ .cal-day--disabled.cal-day--checkout-only,
1025
+ .cal-day--disabled.cal-day--checkin-only {
1026
+ opacity: 1;
1027
+ }
1028
+
1029
+ /* Sublabel spans */
1030
+ .cal-day__number {
1031
+ font-size: 13px;
1032
+ font-weight: 500;
1033
+ line-height: 1;
1034
+ }
1035
+
1036
+ .cal-day__label {
1037
+ font-size: 9px;
1038
+ font-weight: 500;
1039
+ line-height: 1;
1040
+ opacity: 0.8;
1041
+ }
1042
+
1043
+ .cal-day--with-label {
1044
+ flex-direction: column;
1045
+ gap: 1px;
1046
+ }
1047
+
1048
+ /* CSS Tooltip */
1049
+ .cal-day[data-booking-label] {
1050
+ overflow: visible;
1051
+ }
1052
+
1053
+ .cal-day[data-booking-label]:hover::after {
1054
+ content: attr(data-booking-label);
1055
+ position: absolute;
1056
+ bottom: calc(100% + 6px);
1057
+ left: 50%;
1058
+ transform: translateX(-50%);
1059
+ padding: 4px 8px;
1060
+ font-size: 11px;
1061
+ font-weight: 500;
1062
+ white-space: nowrap;
1063
+ color: hsl(var(--cal-accent-fg));
1064
+ background: hsl(var(--cal-accent));
1065
+ border-radius: 4px;
1066
+ pointer-events: none;
1067
+ z-index: 10;
1068
+ }
1069
+
1070
+ .cal-day[data-booking-label]:hover::before {
1071
+ content: '';
1072
+ position: absolute;
1073
+ bottom: calc(100% + 2px);
1074
+ left: 50%;
1075
+ transform: translateX(-50%);
1076
+ border: 4px solid transparent;
1077
+ border-top-color: hsl(var(--cal-accent));
1078
+ pointer-events: none;
1079
+ z-index: 10;
1080
+ }
1081
+ `;
1082
+ function Ye(s) {
1083
+ const {
1084
+ slots: e = [],
1085
+ mode: a = "single",
1086
+ format: t = "24h",
1087
+ selected: n,
1088
+ hoverTime: i,
1089
+ rangeStart: r,
1090
+ unavailableTimes: o = [],
1091
+ onSelect: l,
1092
+ onHover: u,
1093
+ durationLabels: m = !1
1094
+ } = s, g = document.createElement("div");
1095
+ g.classList.add("cal-time-grid"), m && g.classList.add("cal-time-grid--duration"), g.setAttribute("role", "listbox"), a === "multi" && g.setAttribute("aria-multiselectable", "true");
1096
+ for (const c of e) {
1097
+ const d = document.createElement("button");
1098
+ d.classList.add("cal-time-slot"), d.setAttribute("role", "option"), d.dataset.time = c.time;
1099
+ const b = N(c.time), E = c.displayText ? c.displayText : b ? K(b.hours, b.minutes, t) : c.time, v = document.createElement("span");
1100
+ if (v.classList.add("cal-time-slot__time"), v.textContent = E, d.appendChild(v), c.label) {
1101
+ const y = document.createElement("span");
1102
+ y.classList.add("cal-time-slot__label"), y.textContent = c.label, d.appendChild(y);
1103
+ }
1104
+ const x = c.available === !1 || o.includes(c.time);
1105
+ if (x && (d.classList.add("cal-time-slot--unavailable"), d.disabled = !0, d.setAttribute("aria-disabled", "true")), ze(c.time, n, a) ? (d.classList.add("cal-time-slot--selected"), d.setAttribute("aria-selected", "true")) : d.setAttribute("aria-selected", "false"), a === "range" && r && !$e(n) && i) {
1106
+ const y = Q(c.time, r, i), _ = c.time === r, S = c.time === i;
1107
+ y && !_ && !S && d.classList.add("cal-time-slot--in-range"), _ && d.classList.add("cal-time-slot--range-start"), S && d.classList.add("cal-time-slot--range-end");
1108
+ } else if (a === "range" && n && typeof n == "object" && n.start && n.end) {
1109
+ const y = Q(c.time, n.start, n.end), _ = c.time === n.start, S = c.time === n.end;
1110
+ _ && d.classList.add("cal-time-slot--range-start", "cal-time-slot--selected"), S && d.classList.add("cal-time-slot--range-end", "cal-time-slot--selected"), y && !_ && !S && d.classList.add("cal-time-slot--in-range");
1111
+ }
1112
+ x || (d.addEventListener("click", () => l == null ? void 0 : l(c.time)), d.addEventListener("mouseenter", () => u == null ? void 0 : u(c.time))), g.appendChild(d);
1113
+ }
1114
+ return g.addEventListener("mouseleave", () => u == null ? void 0 : u(null)), g;
1115
+ }
1116
+ function ze(s, e, a) {
1117
+ return e ? a === "single" ? e === s : a === "multi" ? Array.isArray(e) && e.includes(s) : a === "range" && typeof e == "object" && e.start && e.end ? e.start === s || e.end === s : !1 : !1;
1118
+ }
1119
+ function $e(s) {
1120
+ return s && typeof s == "object" && s.start && s.end;
1121
+ }
1122
+ const Pe = `
1123
+ .cal-time-grid {
1124
+ display: grid;
1125
+ grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
1126
+ gap: 6px;
1127
+ max-height: 280px;
1128
+ overflow-y: auto;
1129
+ padding: 4px;
1130
+ }
1131
+
1132
+ .cal-time-grid::-webkit-scrollbar {
1133
+ width: 6px;
1134
+ }
1135
+
1136
+ .cal-time-grid::-webkit-scrollbar-track {
1137
+ background: transparent;
1138
+ }
1139
+
1140
+ .cal-time-grid::-webkit-scrollbar-thumb {
1141
+ background: hsl(var(--cal-border));
1142
+ border-radius: 3px;
1143
+ }
1144
+
1145
+ .cal-time-slot {
1146
+ display: flex;
1147
+ flex-direction: column;
1148
+ align-items: center;
1149
+ justify-content: center;
1150
+ height: 40px;
1151
+ padding: 0 8px;
1152
+ border-radius: 999px;
1153
+ font-size: 13px;
1154
+ background: hsl(var(--cal-bg-muted));
1155
+ color: hsl(var(--cal-fg));
1156
+ transition: background var(--cal-transition), color var(--cal-transition);
1157
+ gap: 1px;
1158
+ }
1159
+
1160
+ .cal-time-slot:not(.cal-time-slot--unavailable):not(.cal-time-slot--selected):hover {
1161
+ background: hsl(var(--cal-hover));
1162
+ }
1163
+
1164
+ .cal-time-slot__time {
1165
+ font-weight: 500;
1166
+ line-height: 1;
1167
+ }
1168
+
1169
+ .cal-time-slot__label {
1170
+ font-size: 9px;
1171
+ opacity: 0.7;
1172
+ line-height: 1;
1173
+ }
1174
+
1175
+ .cal-time-slot--selected {
1176
+ background: hsl(var(--cal-accent));
1177
+ color: hsl(var(--cal-accent-fg));
1178
+ font-weight: 600;
1179
+ }
1180
+
1181
+ .cal-time-slot--in-range {
1182
+ background: hsl(var(--cal-accent-subtle));
1183
+ }
1184
+
1185
+ .cal-time-slot--range-start,
1186
+ .cal-time-slot--range-end {
1187
+ background: hsl(var(--cal-accent));
1188
+ color: hsl(var(--cal-accent-fg));
1189
+ font-weight: 600;
1190
+ }
1191
+
1192
+ .cal-time-slot--unavailable {
1193
+ opacity: 0.3;
1194
+ cursor: not-allowed;
1195
+ }
1196
+
1197
+ .cal-time-grid--duration {
1198
+ grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
1199
+ }
1200
+
1201
+ .cal-time-grid--duration .cal-time-slot {
1202
+ font-size: 12px;
1203
+ }
1204
+ `;
1205
+ function Be({ columns: s = 3, rows: e = 4, durationLabels: a = !1 } = {}) {
1206
+ const t = document.createElement("div");
1207
+ t.setAttribute("role", "status"), t.setAttribute("aria-label", "Loading..."), t.classList.add("cal-skeleton-time-grid"), a && t.classList.add("cal-skeleton-time-grid--duration");
1208
+ const n = s * e;
1209
+ for (let i = 0; i < n; i++) {
1210
+ const r = document.createElement("div");
1211
+ r.classList.add("cal-skeleton"), t.appendChild(r);
1212
+ }
1213
+ return t;
1214
+ }
1215
+ function Oe({ rows: s = 5 } = {}) {
1216
+ const e = document.createElement("div");
1217
+ e.setAttribute("role", "status"), e.setAttribute("aria-label", "Loading..."), e.classList.add("cal-skeleton-calendar-grid");
1218
+ for (let t = 0; t < 7; t++) {
1219
+ const n = document.createElement("div");
1220
+ n.classList.add("cal-skeleton", "cal-skeleton-calendar-grid__header"), e.appendChild(n);
1221
+ }
1222
+ const a = 7 * s;
1223
+ for (let t = 0; t < a; t++) {
1224
+ const n = document.createElement("div");
1225
+ n.classList.add("cal-skeleton", "cal-skeleton-calendar-grid__day"), e.appendChild(n);
1226
+ }
1227
+ return e;
1228
+ }
1229
+ const Fe = `
1230
+ .cal-skeleton-time-grid {
1231
+ display: grid;
1232
+ grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
1233
+ gap: 6px;
1234
+ padding: 4px;
1235
+ }
1236
+
1237
+ .cal-skeleton-time-grid--duration {
1238
+ grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
1239
+ }
1240
+
1241
+ .cal-skeleton-time-grid .cal-skeleton {
1242
+ height: 40px;
1243
+ }
1244
+
1245
+ .cal-skeleton-calendar-grid {
1246
+ display: grid;
1247
+ grid-template-columns: repeat(7, 1fr);
1248
+ gap: 2px;
1249
+ padding: 4px;
1250
+ }
1251
+
1252
+ .cal-skeleton-calendar-grid__header {
1253
+ height: 20px;
1254
+ margin-bottom: 4px;
1255
+ }
1256
+
1257
+ .cal-skeleton-calendar-grid__day {
1258
+ height: var(--cal-cell-size, 36px);
1259
+ aspect-ratio: 1;
1260
+ border-radius: var(--cal-radius-sm) !important;
1261
+ }
1262
+ `, te = {
1263
+ error: '<svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><circle cx="7" cy="7" r="6"/><path d="M7 4v3M7 9.5v.01"/></svg>',
1264
+ warning: '<svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M7 1.5L1 12.5h12L7 1.5zM7 6v2.5M7 10.5v.01"/></svg>',
1265
+ info: '<svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><circle cx="7" cy="7" r="6"/><path d="M7 6.5V10M7 4.5v.01"/></svg>',
1266
+ success: '<svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><circle cx="7" cy="7" r="6"/><path d="M4.5 7l2 2L9.5 5"/></svg>'
1267
+ };
1268
+ function Re({ type: s = "info", message: e, dismissible: a = !0, onDismiss: t }) {
1269
+ const n = document.createElement("div");
1270
+ n.classList.add("cal-status", `cal-status--${s}`, "cal-animate-slide-up"), n.setAttribute("role", s === "error" ? "alert" : "status"), n.setAttribute("aria-live", s === "error" ? "assertive" : "polite");
1271
+ const i = document.createElement("span");
1272
+ i.classList.add("cal-status__icon"), i.innerHTML = te[s] || te.info, n.appendChild(i);
1273
+ const r = document.createElement("span");
1274
+ if (r.classList.add("cal-status__text"), r.textContent = e, n.appendChild(r), a) {
1275
+ const o = document.createElement("button");
1276
+ o.classList.add("cal-status__close"), o.setAttribute("aria-label", "Dismiss"), o.innerHTML = '<svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M3 3l6 6M9 3l-6 6"/></svg>', o.addEventListener("click", () => t == null ? void 0 : t()), n.appendChild(o);
1277
+ }
1278
+ return n;
1279
+ }
1280
+ const Ie = `
1281
+ .cal-status {
1282
+ display: flex;
1283
+ align-items: center;
1284
+ gap: 8px;
1285
+ padding: 8px 12px;
1286
+ border-radius: var(--cal-radius-sm);
1287
+ font-size: 12px;
1288
+ line-height: 1.4;
1289
+ margin-bottom: 8px;
1290
+ }
1291
+
1292
+ .cal-status__icon {
1293
+ flex-shrink: 0;
1294
+ display: flex;
1295
+ }
1296
+
1297
+ .cal-status__text {
1298
+ flex: 1;
1299
+ min-width: 0;
1300
+ }
1301
+
1302
+ .cal-status__close {
1303
+ flex-shrink: 0;
1304
+ display: flex;
1305
+ align-items: center;
1306
+ justify-content: center;
1307
+ width: 20px;
1308
+ height: 20px;
1309
+ border-radius: 4px;
1310
+ cursor: pointer;
1311
+ opacity: 0.7;
1312
+ transition: opacity var(--cal-transition);
1313
+ }
1314
+
1315
+ .cal-status__close:hover {
1316
+ opacity: 1;
1317
+ }
1318
+
1319
+ .cal-status--error {
1320
+ background: hsl(var(--cal-status-error-bg));
1321
+ color: hsl(var(--cal-status-error-fg));
1322
+ border: 1px solid hsl(var(--cal-status-error-border));
1323
+ }
1324
+
1325
+ .cal-status--warning {
1326
+ background: hsl(var(--cal-status-warning-bg));
1327
+ color: hsl(var(--cal-status-warning-fg));
1328
+ border: 1px solid hsl(var(--cal-status-warning-border));
1329
+ }
1330
+
1331
+ .cal-status--info {
1332
+ background: hsl(var(--cal-status-info-bg));
1333
+ color: hsl(var(--cal-status-info-fg));
1334
+ border: 1px solid hsl(var(--cal-status-info-border));
1335
+ }
1336
+
1337
+ .cal-status--success {
1338
+ background: hsl(var(--cal-status-success-bg));
1339
+ color: hsl(var(--cal-status-success-fg));
1340
+ border: 1px solid hsl(var(--cal-status-success-border));
1341
+ }
1342
+ `, He = '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="12" height="11" rx="2"/><path d="M5 1v3M11 1v3M2 7h12"/></svg>', je = `
1343
+ .cal-picker {
1344
+ background: hsl(var(--cal-bg));
1345
+ border-radius: var(--cal-radius);
1346
+ user-select: none;
1347
+ }
1348
+
1349
+ :host([display="inline"]) .cal-picker {
1350
+ border: 1px solid hsl(var(--cal-border));
1351
+ padding: 12px;
1352
+ }
1353
+
1354
+ .cal-months {
1355
+ display: flex;
1356
+ gap: 16px;
1357
+ }
1358
+
1359
+ .cal-month {
1360
+ flex: 0 0 auto;
1361
+ }
1362
+
1363
+ /* Time section */
1364
+ .cal-booking-time-section {
1365
+ margin-top: 12px;
1366
+ padding-top: 12px;
1367
+ border-top: 1px solid hsl(var(--cal-border));
1368
+ }
1369
+
1370
+ .cal-booking-time-header {
1371
+ font-size: 13px;
1372
+ font-weight: 600;
1373
+ color: hsl(var(--cal-fg));
1374
+ margin-bottom: 8px;
1375
+ }
1376
+ `;
1377
+ class Ne extends ce {
1378
+ static get styles() {
1379
+ return [ve, ye, ke, Ae, Pe, _e, Se, Ee, Fe, Ie, je];
1380
+ }
1381
+ static get observedAttributes() {
1382
+ return [
1383
+ "theme",
1384
+ "display",
1385
+ "min-date",
1386
+ "max-date",
1387
+ "first-day",
1388
+ "placeholder",
1389
+ "dual",
1390
+ "show-labels-on-hover",
1391
+ "time-slots",
1392
+ "time-start",
1393
+ "time-end",
1394
+ "time-interval",
1395
+ "time-format",
1396
+ "duration-labels",
1397
+ "loading"
1398
+ ];
1399
+ }
1400
+ constructor() {
1401
+ super();
1402
+ const e = /* @__PURE__ */ new Date();
1403
+ this._store = de({
1404
+ viewYear: e.getFullYear(),
1405
+ viewMonth: e.getMonth(),
1406
+ rangeStart: null,
1407
+ rangeEnd: null,
1408
+ hoverDate: null,
1409
+ isOpen: !1,
1410
+ focusedDate: ae(),
1411
+ navDirection: null,
1412
+ pickingMonth: !1,
1413
+ pickerYear: e.getFullYear(),
1414
+ // Time state
1415
+ startTime: null,
1416
+ endTime: null,
1417
+ timeSelectPhase: null,
1418
+ // null | 'start' | 'end'
1419
+ // Status
1420
+ statusType: null,
1421
+ statusMessage: null,
1422
+ statusDismissible: !0
1423
+ }), this._bookings = [], this._dayData = {}, this._labelFormula = null, this._timeSlots = null, this._popover = null, this._unsubscribe = null, this._rendering = !1;
1424
+ }
1425
+ // -- Attribute getters --
1426
+ get display() {
1427
+ return this.getAttribute("display") || "inline";
1428
+ }
1429
+ get placeholder() {
1430
+ return this.getAttribute("placeholder") || "Select dates";
1431
+ }
1432
+ get firstDay() {
1433
+ return parseInt(this.getAttribute("first-day") || "0", 10);
1434
+ }
1435
+ get minDate() {
1436
+ return this.getAttribute("min-date") || null;
1437
+ }
1438
+ get maxDate() {
1439
+ return this.getAttribute("max-date") || null;
1440
+ }
1441
+ get showLabelsOnHover() {
1442
+ return this.hasAttribute("show-labels-on-hover");
1443
+ }
1444
+ get timeSlotsEnabled() {
1445
+ return this.hasAttribute("time-slots");
1446
+ }
1447
+ get timeStartTime() {
1448
+ return this.getAttribute("time-start") || "09:00";
1449
+ }
1450
+ get timeEndTime() {
1451
+ return this.getAttribute("time-end") || "17:00";
1452
+ }
1453
+ get timeInterval() {
1454
+ return parseInt(this.getAttribute("time-interval") || "60", 10);
1455
+ }
1456
+ get timeFormat() {
1457
+ return this.getAttribute("time-format") || "24h";
1458
+ }
1459
+ get durationLabels() {
1460
+ return this.hasAttribute("duration-labels");
1461
+ }
1462
+ get loading() {
1463
+ return this.hasAttribute("loading");
1464
+ }
1465
+ set loading(e) {
1466
+ e ? this.setAttribute("loading", "") : this.removeAttribute("loading");
1467
+ }
1468
+ // -- Properties --
1469
+ get bookings() {
1470
+ return this._bookings;
1471
+ }
1472
+ set bookings(e) {
1473
+ this._bookings = Array.isArray(e) ? e : [], this._initialized && this.render();
1474
+ }
1475
+ get dayData() {
1476
+ return this._dayData;
1477
+ }
1478
+ set dayData(e) {
1479
+ this._dayData = e && typeof e == "object" ? e : {}, this._initialized && this.render();
1480
+ }
1481
+ get labelFormula() {
1482
+ return this._labelFormula;
1483
+ }
1484
+ set labelFormula(e) {
1485
+ this._labelFormula = typeof e == "function" ? e : null, this._initialized && this.render();
1486
+ }
1487
+ get timeSlots() {
1488
+ return this._timeSlots;
1489
+ }
1490
+ set timeSlots(e) {
1491
+ this._timeSlots = Array.isArray(e) ? e : null, this._initialized && this.render();
1492
+ }
1493
+ get value() {
1494
+ const e = this._store.getState();
1495
+ if (!e.rangeStart || !e.rangeEnd) return null;
1496
+ const a = { start: e.rangeStart, end: e.rangeEnd };
1497
+ return this.timeSlotsEnabled && (e.startTime && (a.startTime = e.startTime), e.endTime && (a.endTime = e.endTime)), a;
1498
+ }
1499
+ set value(e) {
1500
+ if (e && typeof e == "object" && e.start && e.end) {
1501
+ const a = typeof e.start == "string" ? e.start : T(e.start), t = typeof e.end == "string" ? e.end : T(e.end), n = { rangeStart: a, rangeEnd: t };
1502
+ e.startTime && (n.startTime = e.startTime), e.endTime && (n.endTime = e.endTime), this._store.set(n), this._navigateToDate(a);
1503
+ } else
1504
+ this._store.set({
1505
+ rangeStart: null,
1506
+ rangeEnd: null,
1507
+ startTime: null,
1508
+ endTime: null,
1509
+ timeSelectPhase: null
1510
+ });
1511
+ }
1512
+ _navigateToDate(e) {
1513
+ const a = M(e);
1514
+ a && this._store.set({ viewYear: a.getFullYear(), viewMonth: a.getMonth() });
1515
+ }
1516
+ connectedCallback() {
1517
+ super.connectedCallback(), this._unsubscribe = this._store.subscribe((a, t) => {
1518
+ if (this._rendering) return;
1519
+ a.hoverDate !== t.hoverDate && a.viewYear === t.viewYear && a.viewMonth === t.viewMonth && a.rangeStart === t.rangeStart && a.rangeEnd === t.rangeEnd && a.isOpen === t.isOpen && a.navDirection === t.navDirection && a.pickingMonth === t.pickingMonth && a.pickerYear === t.pickerYear && a.timeSelectPhase === t.timeSelectPhase ? this._updateGridHighlight(a) : this.render();
1520
+ });
1521
+ const e = this.getAttribute("bookings");
1522
+ if (e && !this._bookings.length)
1523
+ try {
1524
+ this._bookings = JSON.parse(e);
1525
+ } catch {
1526
+ }
1527
+ }
1528
+ disconnectedCallback() {
1529
+ var e, a;
1530
+ (e = this._unsubscribe) == null || e.call(this), (a = this._popover) == null || a.destroy(), clearTimeout(this._statusTimer);
1531
+ }
1532
+ attributeChangedCallback(e, a, t) {
1533
+ a !== t && this._initialized && this.render();
1534
+ }
1535
+ // -- Selection --
1536
+ _handleSelect(e) {
1537
+ const a = this._store.getState();
1538
+ if (!a.rangeStart || a.rangeEnd)
1539
+ this._store.set({
1540
+ rangeStart: e,
1541
+ rangeEnd: null,
1542
+ hoverDate: null,
1543
+ focusedDate: e,
1544
+ startTime: null,
1545
+ endTime: null,
1546
+ timeSelectPhase: null
1547
+ });
1548
+ else {
1549
+ let t = a.rangeStart, n = e;
1550
+ if (t > n && ([t, n] = [n, t]), !ie(t, n, this._bookings)) {
1551
+ this.emit("cal:selection-invalid", { start: t, end: n }), this._store.set({
1552
+ rangeStart: null,
1553
+ rangeEnd: null,
1554
+ hoverDate: null,
1555
+ startTime: null,
1556
+ endTime: null,
1557
+ timeSelectPhase: null
1558
+ }), this.showStatus("error", "Selection overlaps an existing booking", { autoDismiss: 4e3 });
1559
+ return;
1560
+ }
1561
+ this.timeSlotsEnabled ? this._store.set({
1562
+ rangeStart: t,
1563
+ rangeEnd: n,
1564
+ hoverDate: null,
1565
+ focusedDate: n,
1566
+ timeSelectPhase: "start"
1567
+ }) : (this._store.set({
1568
+ rangeStart: t,
1569
+ rangeEnd: n,
1570
+ hoverDate: null,
1571
+ focusedDate: n
1572
+ }), this.emit("cal:change", { value: { start: t, end: n } }), this.display === "popover" && this.close());
1573
+ }
1574
+ }
1575
+ _handleTimeSelect(e) {
1576
+ const a = this._store.getState();
1577
+ if (a.timeSelectPhase === "start")
1578
+ this._store.set({ startTime: e, timeSelectPhase: "end" });
1579
+ else if (a.timeSelectPhase === "end") {
1580
+ this._store.set({ endTime: e, timeSelectPhase: null });
1581
+ const t = {
1582
+ start: a.rangeStart,
1583
+ end: a.rangeEnd,
1584
+ startTime: a.startTime,
1585
+ endTime: e
1586
+ };
1587
+ this.emit("cal:change", { value: t }), this.display === "popover" && this.close();
1588
+ }
1589
+ }
1590
+ _handleHover(e) {
1591
+ this._store.set({ hoverDate: e });
1592
+ }
1593
+ // -- Lightweight hover highlight --
1594
+ _updateGridHighlight(e) {
1595
+ const a = this.$$(".cal-day"), { rangeStart: t, hoverDate: n } = e, i = t && !e.rangeEnd && n ? n : e.rangeEnd;
1596
+ let r = !1;
1597
+ if (t && !e.rangeEnd && n) {
1598
+ const o = t < n ? t : n, l = t < n ? n : t;
1599
+ for (const u of this._bookings)
1600
+ if (o < u.end && l > u.start) {
1601
+ r = !0;
1602
+ break;
1603
+ }
1604
+ }
1605
+ for (const o of a) {
1606
+ const l = o.dataset.date;
1607
+ if (!l) continue;
1608
+ const u = l === t && !!i, m = l === i && !!i;
1609
+ let g = !1;
1610
+ if (t && i) {
1611
+ const d = t < i ? t : i, b = t < i ? i : t;
1612
+ g = l >= d && l <= b && !u && !m;
1613
+ }
1614
+ const c = r && t && !e.rangeEnd && n && (() => {
1615
+ const d = t < n ? t : n, b = t < n ? n : t;
1616
+ return l >= d && l <= b;
1617
+ })();
1618
+ o.classList.toggle("cal-day--range-start", u), o.classList.toggle("cal-day--range-end", m), o.classList.toggle("cal-day--in-range", g), o.classList.toggle("cal-day--invalid-range", !!c);
1619
+ }
1620
+ }
1621
+ // -- Navigation --
1622
+ _prevMonth() {
1623
+ const { viewYear: e, viewMonth: a } = this._store.getState(), { year: t, month: n } = B(e, a, -1);
1624
+ this._store.set({ viewYear: t, viewMonth: n, navDirection: "prev" }), this.emit("cal:month-change", { year: t, month: n });
1625
+ }
1626
+ _nextMonth() {
1627
+ const { viewYear: e, viewMonth: a } = this._store.getState(), { year: t, month: n } = B(e, a, 1);
1628
+ this._store.set({ viewYear: t, viewMonth: n, navDirection: "next" }), this.emit("cal:month-change", { year: t, month: n });
1629
+ }
1630
+ // -- Month picker --
1631
+ _toggleMonthPicker() {
1632
+ const e = this._store.getState();
1633
+ this._store.set({
1634
+ pickingMonth: !e.pickingMonth,
1635
+ pickerYear: e.viewYear
1636
+ });
1637
+ }
1638
+ _selectMonthFromPicker(e, a) {
1639
+ this._store.set({
1640
+ viewYear: a,
1641
+ viewMonth: e,
1642
+ pickingMonth: !1
1643
+ }), this.emit("cal:month-change", { year: a, month: e });
1644
+ }
1645
+ // -- Keyboard --
1646
+ _handleKeydown(e) {
1647
+ if (e.key === "Escape" && this._store.get("pickingMonth")) {
1648
+ e.stopPropagation(), this._store.set({ pickingMonth: !1 });
1649
+ return;
1650
+ }
1651
+ const a = this._store.getState(), t = M(a.focusedDate);
1652
+ if (!t) return;
1653
+ let n = null;
1654
+ switch (e.key) {
1655
+ case "ArrowLeft":
1656
+ n = new Date(t), n.setDate(t.getDate() - 1);
1657
+ break;
1658
+ case "ArrowRight":
1659
+ n = new Date(t), n.setDate(t.getDate() + 1);
1660
+ break;
1661
+ case "ArrowUp":
1662
+ n = new Date(t), n.setDate(t.getDate() - 7);
1663
+ break;
1664
+ case "ArrowDown":
1665
+ n = new Date(t), n.setDate(t.getDate() + 7);
1666
+ break;
1667
+ case "Enter":
1668
+ case " ":
1669
+ e.preventDefault(), this._handleSelect(a.focusedDate);
1670
+ return;
1671
+ case "Escape":
1672
+ this.display === "popover" && this.close();
1673
+ return;
1674
+ default:
1675
+ return;
1676
+ }
1677
+ if (n) {
1678
+ e.preventDefault();
1679
+ const i = T(n);
1680
+ n.getMonth() !== a.viewMonth || n.getFullYear() !== a.viewYear ? this._store.set({
1681
+ viewYear: n.getFullYear(),
1682
+ viewMonth: n.getMonth(),
1683
+ focusedDate: i,
1684
+ navDirection: n > t ? "next" : "prev"
1685
+ }) : this._store.set({ focusedDate: i }), requestAnimationFrame(() => {
1686
+ const r = this.$(`[data-date="${i}"]`);
1687
+ r == null || r.focus();
1688
+ });
1689
+ }
1690
+ }
1691
+ // -- Public API --
1692
+ open() {
1693
+ this._popover && (this._popover.open(), this._store.set({ isOpen: !0 }), this.emit("cal:open"));
1694
+ }
1695
+ close() {
1696
+ this._popover && (this._popover.close(), this._store.set({ isOpen: !1 }), this.emit("cal:close"));
1697
+ }
1698
+ goToMonth(e, a) {
1699
+ this._store.set({ viewYear: a, viewMonth: e });
1700
+ }
1701
+ // -- Time slots generation --
1702
+ _getTimeSlotArray() {
1703
+ return this._timeSlots ? this._timeSlots : this.durationLabels ? fe(this.timeStartTime, this.timeEndTime, this.timeInterval, this.timeFormat).map((a) => ({ ...a, available: !0 })) : pe(this.timeStartTime, this.timeEndTime, this.timeInterval).map((a) => ({ time: a, available: !0 }));
1704
+ }
1705
+ // -- Render --
1706
+ _renderCalendarContent() {
1707
+ const e = this._store.getState(), a = document.createElement("div");
1708
+ if (a.classList.add("cal-picker"), e.statusType && e.statusMessage && a.appendChild(Re({
1709
+ type: e.statusType,
1710
+ message: e.statusMessage,
1711
+ dismissible: e.statusDismissible,
1712
+ onDismiss: () => this.clearStatus()
1713
+ })), this.loading) {
1714
+ const r = document.createElement("div");
1715
+ r.classList.add("cal-months");
1716
+ const o = document.createElement("div");
1717
+ if (o.classList.add("cal-month"), o.appendChild(Oe()), r.appendChild(o), a.appendChild(r), this.timeSlotsEnabled) {
1718
+ const l = document.createElement("div");
1719
+ l.classList.add("cal-booking-time-section"), l.appendChild(Be({ durationLabels: this.durationLabels })), a.appendChild(l);
1720
+ }
1721
+ return a.addEventListener("keydown", (l) => this._handleKeydown(l)), a;
1722
+ }
1723
+ const t = document.createElement("div");
1724
+ t.classList.add("cal-months");
1725
+ const n = this.hasAttribute("dual"), i = n ? 2 : 1;
1726
+ for (let r = 0; r < i; r++) {
1727
+ const { year: o, month: l } = r === 0 ? { year: e.viewYear, month: e.viewMonth } : B(e.viewYear, e.viewMonth, 1), u = document.createElement("div");
1728
+ if (u.classList.add("cal-month"), r === 0 && u.appendChild(Z({
1729
+ year: o,
1730
+ month: l,
1731
+ onPrev: e.pickingMonth ? () => {
1732
+ } : () => this._prevMonth(),
1733
+ onNext: e.pickingMonth ? () => {
1734
+ } : () => {
1735
+ n || this._nextMonth();
1736
+ },
1737
+ onTitleClick: () => this._toggleMonthPicker()
1738
+ })), r === 1 && u.appendChild(Z({
1739
+ year: o,
1740
+ month: l,
1741
+ onPrev: () => {
1742
+ },
1743
+ onNext: () => this._nextMonth()
1744
+ })), e.pickingMonth && r === 0) {
1745
+ const m = we({
1746
+ pickerYear: e.pickerYear,
1747
+ viewMonth: e.viewMonth,
1748
+ viewYear: e.viewYear,
1749
+ onMonthSelect: (g, c) => this._selectMonthFromPicker(g, c),
1750
+ onYearPrev: () => this._store.set({ pickerYear: e.pickerYear - 1 }),
1751
+ onYearNext: () => this._store.set({ pickerYear: e.pickerYear + 1 }),
1752
+ onClose: () => this._store.set({ pickingMonth: !1 })
1753
+ });
1754
+ u.appendChild(m);
1755
+ } else {
1756
+ const m = e.navDirection === "next" ? "cal-animate-slide-left" : e.navDirection === "prev" ? "cal-animate-slide-right" : "", g = Ce({
1757
+ year: o,
1758
+ month: l,
1759
+ firstDay: this.firstDay,
1760
+ rangeStart: e.rangeStart,
1761
+ rangeEnd: e.rangeEnd,
1762
+ hoverDate: e.hoverDate,
1763
+ minDate: this.minDate,
1764
+ maxDate: this.maxDate,
1765
+ focusedDate: e.focusedDate,
1766
+ mode: "range",
1767
+ onSelect: (c) => this._handleSelect(c),
1768
+ onHover: (c) => this._handleHover(c),
1769
+ // Booking-specific params
1770
+ bookings: this._bookings,
1771
+ dayData: this._dayData,
1772
+ labelFormula: this._labelFormula,
1773
+ showLabelsOnHover: this.showLabelsOnHover
1774
+ });
1775
+ m && g.classList.add(m), u.appendChild(g);
1776
+ }
1777
+ t.appendChild(u);
1778
+ }
1779
+ if (a.appendChild(t), this.timeSlotsEnabled && e.timeSelectPhase && !e.pickingMonth) {
1780
+ const r = document.createElement("div");
1781
+ r.classList.add("cal-booking-time-section");
1782
+ const o = document.createElement("div");
1783
+ o.classList.add("cal-booking-time-header"), o.textContent = e.timeSelectPhase === "start" ? "Select check-in time" : "Select check-out time", r.appendChild(o);
1784
+ const l = this._getTimeSlotArray(), u = Ye({
1785
+ slots: l,
1786
+ mode: "single",
1787
+ format: this.timeFormat,
1788
+ selected: e.timeSelectPhase === "end" ? e.startTime : null,
1789
+ onSelect: (m) => this._handleTimeSelect(m),
1790
+ onHover: () => {
1791
+ },
1792
+ durationLabels: this.durationLabels
1793
+ });
1794
+ r.appendChild(u), a.appendChild(r);
1795
+ }
1796
+ return a.addEventListener("keydown", (r) => this._handleKeydown(r)), a;
1797
+ }
1798
+ _formatTriggerText() {
1799
+ const e = this._store.getState();
1800
+ if (e.rangeStart && e.rangeEnd) {
1801
+ let a = `${this._formatShortDate(e.rangeStart)} – ${this._formatShortDate(e.rangeEnd)}`;
1802
+ return e.startTime && e.endTime && (a += ` (${e.startTime} – ${e.endTime})`), a;
1803
+ }
1804
+ return null;
1805
+ }
1806
+ _formatShortDate(e) {
1807
+ const a = M(e);
1808
+ return a ? `${J[a.getMonth()].slice(0, 3)} ${a.getDate()}, ${a.getFullYear()}` : e;
1809
+ }
1810
+ render() {
1811
+ var t;
1812
+ if (this._rendering) return;
1813
+ this._rendering = !0;
1814
+ const e = this.shadowRoot, a = [...e.childNodes];
1815
+ for (const n of a)
1816
+ n.nodeName !== "STYLE" && !(n instanceof CSSStyleSheet) && e.removeChild(n);
1817
+ if ((t = this._popover) == null || t.destroy(), this._popover = null, this.display === "popover") {
1818
+ const n = document.createElement("div");
1819
+ n.classList.add("cal-popover-wrapper");
1820
+ const i = document.createElement("button");
1821
+ i.classList.add("cal-trigger");
1822
+ const r = document.createElement("span");
1823
+ r.classList.add("cal-trigger__icon"), r.innerHTML = He, i.appendChild(r);
1824
+ const o = this._formatTriggerText(), l = document.createElement("span");
1825
+ o ? l.textContent = o : (l.textContent = this.placeholder, l.classList.add("cal-trigger--placeholder")), i.appendChild(l), n.appendChild(i);
1826
+ const u = this._renderCalendarContent(), m = Le({
1827
+ trigger: i,
1828
+ content: u,
1829
+ onClose: () => {
1830
+ this._store.set({ isOpen: !1 }), this.emit("cal:close");
1831
+ }
1832
+ });
1833
+ n.appendChild(m.panel), e.appendChild(n), i.addEventListener("click", (g) => {
1834
+ g.stopPropagation(), m.isOpen ? this.close() : this.open();
1835
+ }), this._popover = m, this._store.get("isOpen") && m.open();
1836
+ } else
1837
+ e.appendChild(this._renderCalendarContent());
1838
+ this._store.set({ navDirection: null }), this._rendering = !1;
1839
+ }
1840
+ }
1841
+ customElements.get("cal-booking") || customElements.define("cal-booking", Ne);
1842
+ export {
1843
+ Ne as CalBooking
1844
+ };
1845
+ //# sourceMappingURL=booking.es.js.map