@forcecalendar/interface 1.0.47 → 1.0.48
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.
|
@@ -52,8 +52,8 @@ class M extends HTMLElement {
|
|
|
52
52
|
console.warn("addListener called with invalid parameters", { element: t, event: e, handler: r });
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
|
-
const
|
|
56
|
-
t.addEventListener(e,
|
|
55
|
+
const i = r.bind(this);
|
|
56
|
+
t.addEventListener(e, i), this._listeners.push({ element: t, event: e, handler: i });
|
|
57
57
|
}
|
|
58
58
|
emit(t, e = {}) {
|
|
59
59
|
this.dispatchEvent(
|
|
@@ -123,16 +123,16 @@ class T {
|
|
|
123
123
|
* @returns {Function} Unsubscribe function
|
|
124
124
|
*/
|
|
125
125
|
on(t, e, r = {}) {
|
|
126
|
-
const { once:
|
|
126
|
+
const { once: i = !1, priority: s = 0 } = r;
|
|
127
127
|
if (t.includes("*")) {
|
|
128
|
-
const
|
|
129
|
-
return this.wildcardHandlers.add(
|
|
128
|
+
const o = { pattern: t, handler: e, once: i, priority: s };
|
|
129
|
+
return this.wildcardHandlers.add(o), () => this.wildcardHandlers.delete(o);
|
|
130
130
|
}
|
|
131
131
|
this.events.has(t) || this.events.set(t, []);
|
|
132
|
-
const n = { handler: e, once:
|
|
133
|
-
return
|
|
134
|
-
const
|
|
135
|
-
|
|
132
|
+
const n = { handler: e, once: i, priority: s }, a = this.events.get(t);
|
|
133
|
+
return a.push(n), a.sort((o, c) => c.priority - o.priority), () => {
|
|
134
|
+
const o = a.indexOf(n);
|
|
135
|
+
o > -1 && a.splice(o, 1);
|
|
136
136
|
};
|
|
137
137
|
}
|
|
138
138
|
/**
|
|
@@ -146,16 +146,16 @@ class T {
|
|
|
146
146
|
*/
|
|
147
147
|
off(t, e) {
|
|
148
148
|
if (t.includes("*")) {
|
|
149
|
-
for (const
|
|
150
|
-
if (
|
|
151
|
-
this.wildcardHandlers.delete(
|
|
149
|
+
for (const s of this.wildcardHandlers)
|
|
150
|
+
if (s.pattern === t && s.handler === e) {
|
|
151
|
+
this.wildcardHandlers.delete(s);
|
|
152
152
|
return;
|
|
153
153
|
}
|
|
154
154
|
return;
|
|
155
155
|
}
|
|
156
156
|
if (!this.events.has(t)) return;
|
|
157
|
-
const r = this.events.get(t),
|
|
158
|
-
|
|
157
|
+
const r = this.events.get(t), i = r.findIndex((s) => s.handler === e);
|
|
158
|
+
i > -1 && r.splice(i, 1), r.length === 0 && this.events.delete(t);
|
|
159
159
|
}
|
|
160
160
|
/**
|
|
161
161
|
* Remove all wildcard handlers matching a pattern
|
|
@@ -172,8 +172,8 @@ class T {
|
|
|
172
172
|
*/
|
|
173
173
|
offAll(t) {
|
|
174
174
|
for (const [e, r] of this.events) {
|
|
175
|
-
const
|
|
176
|
-
|
|
175
|
+
const i = r.findIndex((s) => s.handler === t);
|
|
176
|
+
i > -1 && r.splice(i, 1), r.length === 0 && this.events.delete(e);
|
|
177
177
|
}
|
|
178
178
|
for (const e of [...this.wildcardHandlers])
|
|
179
179
|
e.handler === t && this.wildcardHandlers.delete(e);
|
|
@@ -185,29 +185,29 @@ class T {
|
|
|
185
185
|
*/
|
|
186
186
|
emit(t, e) {
|
|
187
187
|
if (this.events.has(t)) {
|
|
188
|
-
const
|
|
189
|
-
for (const
|
|
190
|
-
const { handler: n, once:
|
|
191
|
-
|
|
188
|
+
const i = [...this.events.get(t)];
|
|
189
|
+
for (const s of i) {
|
|
190
|
+
const { handler: n, once: a } = s;
|
|
191
|
+
a && this.off(t, n);
|
|
192
192
|
try {
|
|
193
193
|
n(e, t);
|
|
194
|
-
} catch (
|
|
195
|
-
console.error(`Error in event handler for ${t}:`,
|
|
194
|
+
} catch (o) {
|
|
195
|
+
console.error(`Error in event handler for ${t}:`, o);
|
|
196
196
|
}
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
const r = [];
|
|
200
|
-
for (const
|
|
201
|
-
if (this.matchesPattern(t,
|
|
202
|
-
const { handler:
|
|
203
|
-
n && r.push(
|
|
200
|
+
for (const i of [...this.wildcardHandlers])
|
|
201
|
+
if (this.matchesPattern(t, i.pattern)) {
|
|
202
|
+
const { handler: s, once: n } = i;
|
|
203
|
+
n && r.push(i);
|
|
204
204
|
try {
|
|
205
|
-
|
|
206
|
-
} catch (
|
|
207
|
-
console.error(`Error in wildcard handler for ${t}:`,
|
|
205
|
+
s(e, t);
|
|
206
|
+
} catch (a) {
|
|
207
|
+
console.error(`Error in wildcard handler for ${t}:`, a);
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
|
-
r.forEach((
|
|
210
|
+
r.forEach((i) => this.wildcardHandlers.delete(i));
|
|
211
211
|
}
|
|
212
212
|
/**
|
|
213
213
|
* Check if event name matches a pattern
|
|
@@ -291,8 +291,8 @@ class V {
|
|
|
291
291
|
*/
|
|
292
292
|
_eventsMatch(t, e) {
|
|
293
293
|
if (t.length !== e.length) return !1;
|
|
294
|
-
const r = new Set(t.map((
|
|
295
|
-
return e.every((
|
|
294
|
+
const r = new Set(t.map((i) => i.id));
|
|
295
|
+
return e.every((i) => r.has(i.id));
|
|
296
296
|
}
|
|
297
297
|
// State management
|
|
298
298
|
getState() {
|
|
@@ -303,8 +303,8 @@ class V {
|
|
|
303
303
|
};
|
|
304
304
|
}
|
|
305
305
|
setState(t, e = {}) {
|
|
306
|
-
const { silent: r = !1 } = e,
|
|
307
|
-
return this.state = { ...this.state, ...t }, r || (this.notifySubscribers(
|
|
306
|
+
const { silent: r = !1 } = e, i = { ...this.state };
|
|
307
|
+
return this.state = { ...this.state, ...t }, r || (this.notifySubscribers(i, this.state), this.emitStateChange(i, this.state)), this.state;
|
|
308
308
|
}
|
|
309
309
|
subscribe(t, e = null) {
|
|
310
310
|
return this.subscribers.add(t), e && (this._subscriberIds || (this._subscriberIds = /* @__PURE__ */ new Map()), this._subscriberIds.set(e, t)), () => this.unsubscribe(t, e);
|
|
@@ -331,17 +331,17 @@ class V {
|
|
|
331
331
|
this.subscribers.forEach((r) => {
|
|
332
332
|
try {
|
|
333
333
|
r(e, t);
|
|
334
|
-
} catch (
|
|
335
|
-
console.error("Error in state subscriber:",
|
|
334
|
+
} catch (i) {
|
|
335
|
+
console.error("Error in state subscriber:", i);
|
|
336
336
|
}
|
|
337
337
|
});
|
|
338
338
|
}
|
|
339
339
|
emitStateChange(t, e) {
|
|
340
|
-
const r = Object.keys(e).filter((
|
|
341
|
-
r.forEach((
|
|
342
|
-
this.eventBus.emit(`state:${
|
|
343
|
-
oldValue: t[
|
|
344
|
-
newValue: e[
|
|
340
|
+
const r = Object.keys(e).filter((i) => t[i] !== e[i]);
|
|
341
|
+
r.forEach((i) => {
|
|
342
|
+
this.eventBus.emit(`state:${i}:changed`, {
|
|
343
|
+
oldValue: t[i],
|
|
344
|
+
newValue: e[i],
|
|
345
345
|
state: e
|
|
346
346
|
});
|
|
347
347
|
}), r.length > 0 && this.eventBus.emit("state:changed", { oldState: t, newState: e, changedKeys: r });
|
|
@@ -412,28 +412,28 @@ class V {
|
|
|
412
412
|
return this.enrichViewData(t);
|
|
413
413
|
}
|
|
414
414
|
enrichViewData(t) {
|
|
415
|
-
var
|
|
416
|
-
const e = { ...t }, r = (
|
|
417
|
-
if (e.weeks && (e.weeks = e.weeks.map((
|
|
418
|
-
...
|
|
419
|
-
days:
|
|
420
|
-
const
|
|
415
|
+
var i;
|
|
416
|
+
const e = { ...t }, r = (i = this.state.selectedDate) == null ? void 0 : i.toDateString();
|
|
417
|
+
if (e.weeks && (e.weeks = e.weeks.map((s) => ({
|
|
418
|
+
...s,
|
|
419
|
+
days: s.days.map((n) => {
|
|
420
|
+
const a = new Date(n.date);
|
|
421
421
|
return {
|
|
422
422
|
...n,
|
|
423
|
-
isSelected:
|
|
424
|
-
events: n.events || this.getEventsForDate(
|
|
423
|
+
isSelected: a.toDateString() === r,
|
|
424
|
+
events: n.events || this.getEventsForDate(a)
|
|
425
425
|
};
|
|
426
426
|
})
|
|
427
|
-
}))), e.days && (e.days = e.days.map((
|
|
428
|
-
const n = new Date(
|
|
427
|
+
}))), e.days && (e.days = e.days.map((s) => {
|
|
428
|
+
const n = new Date(s.date);
|
|
429
429
|
return {
|
|
430
|
-
...
|
|
430
|
+
...s,
|
|
431
431
|
isSelected: n.toDateString() === r,
|
|
432
|
-
events:
|
|
432
|
+
events: s.events || this.getEventsForDate(n)
|
|
433
433
|
};
|
|
434
434
|
})), e.date && !e.days && !e.weeks) {
|
|
435
|
-
const
|
|
436
|
-
e.isSelected =
|
|
435
|
+
const s = new Date(e.date);
|
|
436
|
+
e.isSelected = s.toDateString() === r, e.events = e.events || this.getEventsForDate(s);
|
|
437
437
|
}
|
|
438
438
|
return e;
|
|
439
439
|
}
|
|
@@ -492,7 +492,7 @@ class p extends L {
|
|
|
492
492
|
*/
|
|
493
493
|
static formatDate(t, e = "default", r = "en-US") {
|
|
494
494
|
if (!t) return "";
|
|
495
|
-
const
|
|
495
|
+
const i = {
|
|
496
496
|
default: { year: "numeric", month: "long", day: "numeric" },
|
|
497
497
|
short: { year: "numeric", month: "short", day: "numeric" },
|
|
498
498
|
long: { weekday: "long", year: "numeric", month: "long", day: "numeric" },
|
|
@@ -509,20 +509,20 @@ class p extends L {
|
|
|
509
509
|
hour: "numeric",
|
|
510
510
|
minute: "2-digit"
|
|
511
511
|
}
|
|
512
|
-
},
|
|
513
|
-
return new Intl.DateTimeFormat(r,
|
|
512
|
+
}, s = i[e] || i.default;
|
|
513
|
+
return new Intl.DateTimeFormat(r, s).format(t);
|
|
514
514
|
}
|
|
515
515
|
/**
|
|
516
516
|
* Format time for display
|
|
517
517
|
*/
|
|
518
|
-
static formatTime(t, e = !0, r = !1,
|
|
518
|
+
static formatTime(t, e = !0, r = !1, i = "en-US") {
|
|
519
519
|
if (!t) return "";
|
|
520
|
-
const
|
|
520
|
+
const s = {
|
|
521
521
|
hour: "numeric",
|
|
522
522
|
minute: e ? "2-digit" : void 0,
|
|
523
523
|
hour12: !r
|
|
524
524
|
};
|
|
525
|
-
return new Intl.DateTimeFormat(
|
|
525
|
+
return new Intl.DateTimeFormat(i, s).format(t);
|
|
526
526
|
}
|
|
527
527
|
/**
|
|
528
528
|
* Format date range for display
|
|
@@ -531,25 +531,25 @@ class p extends L {
|
|
|
531
531
|
if (!t) return "";
|
|
532
532
|
if (!e || this.isSameDay(t, e))
|
|
533
533
|
return this.formatDate(t, "default", r);
|
|
534
|
-
const
|
|
535
|
-
return `${this.formatDate(t,
|
|
534
|
+
const i = this.isSameYear(t, e) ? "short" : "default";
|
|
535
|
+
return `${this.formatDate(t, i, r)} - ${this.formatDate(e, "default", r)}`;
|
|
536
536
|
}
|
|
537
537
|
/**
|
|
538
538
|
* Format time range for display
|
|
539
539
|
*/
|
|
540
540
|
static formatTimeRange(t, e, r = "en-US") {
|
|
541
541
|
if (!t) return "";
|
|
542
|
-
const
|
|
543
|
-
if (!e) return
|
|
544
|
-
const
|
|
545
|
-
return `${
|
|
542
|
+
const i = this.formatTime(t, !0, !1, r);
|
|
543
|
+
if (!e) return i;
|
|
544
|
+
const s = this.formatTime(e, !0, !1, r);
|
|
545
|
+
return `${i} - ${s}`;
|
|
546
546
|
}
|
|
547
547
|
/**
|
|
548
548
|
* Get relative time string (e.g., "2 hours ago", "in 3 days")
|
|
549
549
|
*/
|
|
550
550
|
static getRelativeTime(t, e = /* @__PURE__ */ new Date(), r = "en-US") {
|
|
551
|
-
const
|
|
552
|
-
return Math.abs(n) < 60 ?
|
|
551
|
+
const i = new Intl.RelativeTimeFormat(r, { numeric: "auto" }), s = t - e, n = Math.floor(s / 1e3), a = Math.floor(n / 60), o = Math.floor(a / 60), c = Math.floor(o / 24), d = Math.floor(c / 7), l = Math.floor(c / 30), u = Math.floor(c / 365);
|
|
552
|
+
return Math.abs(n) < 60 ? i.format(n, "second") : Math.abs(a) < 60 ? i.format(a, "minute") : Math.abs(o) < 24 ? i.format(o, "hour") : Math.abs(c) < 7 ? i.format(c, "day") : Math.abs(d) < 4 ? i.format(d, "week") : Math.abs(l) < 12 ? i.format(l, "month") : i.format(u, "year");
|
|
553
553
|
}
|
|
554
554
|
/**
|
|
555
555
|
* Check if date is today
|
|
@@ -588,16 +588,16 @@ class p extends L {
|
|
|
588
588
|
* Get month name
|
|
589
589
|
*/
|
|
590
590
|
static getMonthName(t, e = "long", r = "en-US") {
|
|
591
|
-
const
|
|
592
|
-
return new Intl.DateTimeFormat(r, { month: e }).format(
|
|
591
|
+
const i = new Date(2024, t, 1);
|
|
592
|
+
return new Intl.DateTimeFormat(r, { month: e }).format(i);
|
|
593
593
|
}
|
|
594
594
|
/**
|
|
595
595
|
* Parse time string (e.g., "14:30" or "2:30 PM")
|
|
596
596
|
*/
|
|
597
597
|
static parseTimeString(t, e = /* @__PURE__ */ new Date()) {
|
|
598
|
-
const r = new Date(e), [
|
|
599
|
-
let
|
|
600
|
-
return
|
|
598
|
+
const r = new Date(e), [i, s] = t.split(/\s+/), [n, a] = i.split(":").map(Number);
|
|
599
|
+
let o = n;
|
|
600
|
+
return s && (s.toLowerCase() === "pm" && n < 12 ? o = n + 12 : s.toLowerCase() === "am" && n === 12 && (o = 0)), r.setHours(o, a || 0, 0, 0), r;
|
|
601
601
|
}
|
|
602
602
|
}
|
|
603
603
|
class D {
|
|
@@ -605,44 +605,44 @@ class D {
|
|
|
605
605
|
* Create element with attributes and children
|
|
606
606
|
*/
|
|
607
607
|
static createElement(t, e = {}, r = []) {
|
|
608
|
-
const
|
|
609
|
-
return Object.entries(e).forEach(([
|
|
610
|
-
if (
|
|
611
|
-
|
|
612
|
-
else if (
|
|
613
|
-
Object.assign(
|
|
614
|
-
else if (
|
|
615
|
-
|
|
616
|
-
else if (
|
|
617
|
-
const
|
|
618
|
-
|
|
608
|
+
const i = document.createElement(t);
|
|
609
|
+
return Object.entries(e).forEach(([s, n]) => {
|
|
610
|
+
if (s === "className")
|
|
611
|
+
i.className = n;
|
|
612
|
+
else if (s === "style" && typeof n == "object")
|
|
613
|
+
Object.assign(i.style, n);
|
|
614
|
+
else if (s.startsWith("data-"))
|
|
615
|
+
i.setAttribute(s, n);
|
|
616
|
+
else if (s.startsWith("on") && typeof n == "function") {
|
|
617
|
+
const a = s.slice(2).toLowerCase();
|
|
618
|
+
i.addEventListener(a, n);
|
|
619
619
|
} else
|
|
620
|
-
s
|
|
621
|
-
}), r.forEach((
|
|
622
|
-
typeof
|
|
623
|
-
}),
|
|
620
|
+
i[s] = n;
|
|
621
|
+
}), r.forEach((s) => {
|
|
622
|
+
typeof s == "string" ? i.appendChild(document.createTextNode(s)) : s instanceof Node && i.appendChild(s);
|
|
623
|
+
}), i;
|
|
624
624
|
}
|
|
625
625
|
/**
|
|
626
626
|
* Add multiple event listeners
|
|
627
627
|
*/
|
|
628
628
|
static addEventListeners(t, e) {
|
|
629
|
-
return Object.entries(e).forEach(([r,
|
|
630
|
-
t.addEventListener(r,
|
|
629
|
+
return Object.entries(e).forEach(([r, i]) => {
|
|
630
|
+
t.addEventListener(r, i);
|
|
631
631
|
}), () => {
|
|
632
|
-
Object.entries(e).forEach(([r,
|
|
633
|
-
t.removeEventListener(r,
|
|
632
|
+
Object.entries(e).forEach(([r, i]) => {
|
|
633
|
+
t.removeEventListener(r, i);
|
|
634
634
|
});
|
|
635
635
|
};
|
|
636
636
|
}
|
|
637
637
|
/**
|
|
638
638
|
* Delegate event handling
|
|
639
639
|
*/
|
|
640
|
-
static delegate(t, e, r,
|
|
641
|
-
const
|
|
642
|
-
const
|
|
643
|
-
|
|
640
|
+
static delegate(t, e, r, i) {
|
|
641
|
+
const s = (n) => {
|
|
642
|
+
const a = n.target.closest(e);
|
|
643
|
+
a && t.contains(a) && i.call(a, n);
|
|
644
644
|
};
|
|
645
|
-
return t.addEventListener(r,
|
|
645
|
+
return t.addEventListener(r, s), () => t.removeEventListener(r, s);
|
|
646
646
|
}
|
|
647
647
|
/**
|
|
648
648
|
* Get element position relative to viewport
|
|
@@ -669,8 +669,8 @@ class D {
|
|
|
669
669
|
* Smooth scroll to element
|
|
670
670
|
*/
|
|
671
671
|
static scrollToElement(t, e = {}) {
|
|
672
|
-
const { behavior: r = "smooth", block:
|
|
673
|
-
t.scrollIntoView({ behavior: r, block:
|
|
672
|
+
const { behavior: r = "smooth", block: i = "start", inline: s = "nearest" } = e;
|
|
673
|
+
t.scrollIntoView({ behavior: r, block: i, inline: s });
|
|
674
674
|
}
|
|
675
675
|
/**
|
|
676
676
|
* Get computed style value
|
|
@@ -695,10 +695,10 @@ class D {
|
|
|
695
695
|
*/
|
|
696
696
|
static waitForAnimation(t, e = "animationend") {
|
|
697
697
|
return new Promise((r) => {
|
|
698
|
-
const
|
|
699
|
-
t.removeEventListener(e,
|
|
698
|
+
const i = () => {
|
|
699
|
+
t.removeEventListener(e, i), r();
|
|
700
700
|
};
|
|
701
|
-
t.addEventListener(e,
|
|
701
|
+
t.addEventListener(e, i);
|
|
702
702
|
});
|
|
703
703
|
}
|
|
704
704
|
/**
|
|
@@ -726,9 +726,9 @@ class D {
|
|
|
726
726
|
*/
|
|
727
727
|
static debounce(t, e = 250) {
|
|
728
728
|
let r;
|
|
729
|
-
return function(...
|
|
729
|
+
return function(...s) {
|
|
730
730
|
const n = () => {
|
|
731
|
-
clearTimeout(r), t(...
|
|
731
|
+
clearTimeout(r), t(...s);
|
|
732
732
|
};
|
|
733
733
|
clearTimeout(r), r = setTimeout(n, e);
|
|
734
734
|
};
|
|
@@ -738,8 +738,8 @@ class D {
|
|
|
738
738
|
*/
|
|
739
739
|
static throttle(t, e = 250) {
|
|
740
740
|
let r;
|
|
741
|
-
return function(...
|
|
742
|
-
r || (t.apply(this,
|
|
741
|
+
return function(...i) {
|
|
742
|
+
r || (t.apply(this, i), r = !0, setTimeout(() => r = !1, e));
|
|
743
743
|
};
|
|
744
744
|
}
|
|
745
745
|
/**
|
|
@@ -753,9 +753,9 @@ class D {
|
|
|
753
753
|
*/
|
|
754
754
|
static parents(t, e) {
|
|
755
755
|
const r = [];
|
|
756
|
-
let
|
|
757
|
-
for (;
|
|
758
|
-
|
|
756
|
+
let i = t.parentElement;
|
|
757
|
+
for (; i; )
|
|
758
|
+
i.matches(e) && r.push(i), i = i.parentElement;
|
|
759
759
|
return r;
|
|
760
760
|
}
|
|
761
761
|
/**
|
|
@@ -789,10 +789,10 @@ class D {
|
|
|
789
789
|
);
|
|
790
790
|
if (e.length === 0)
|
|
791
791
|
return t.setAttribute("tabindex", "-1"), t.focus(), () => t.removeAttribute("tabindex");
|
|
792
|
-
const r = e[0],
|
|
793
|
-
n.key === "Tab" && (n.shiftKey ? document.activeElement === r && (
|
|
792
|
+
const r = e[0], i = e[e.length - 1], s = (n) => {
|
|
793
|
+
n.key === "Tab" && (n.shiftKey ? document.activeElement === r && (i == null || i.focus(), n.preventDefault()) : document.activeElement === i && (r == null || r.focus(), n.preventDefault()));
|
|
794
794
|
};
|
|
795
|
-
return t.addEventListener("keydown",
|
|
795
|
+
return t.addEventListener("keydown", s), r == null || r.focus(), () => t.removeEventListener("keydown", s);
|
|
796
796
|
}
|
|
797
797
|
}
|
|
798
798
|
class f {
|
|
@@ -806,8 +806,8 @@ class f {
|
|
|
806
806
|
* Set CSS variables
|
|
807
807
|
*/
|
|
808
808
|
static setCSSVariables(t, e = document.documentElement) {
|
|
809
|
-
Object.entries(t).forEach(([r,
|
|
810
|
-
e.style.setProperty(r,
|
|
809
|
+
Object.entries(t).forEach(([r, i]) => {
|
|
810
|
+
e.style.setProperty(r, i);
|
|
811
811
|
});
|
|
812
812
|
}
|
|
813
813
|
/**
|
|
@@ -963,22 +963,22 @@ class f {
|
|
|
963
963
|
* Darken color by percentage
|
|
964
964
|
*/
|
|
965
965
|
static darken(t, e) {
|
|
966
|
-
const r = parseInt(t.replace("#", ""), 16),
|
|
967
|
-
return "#" + (16777216 + (
|
|
966
|
+
const r = parseInt(t.replace("#", ""), 16), i = Math.round(2.55 * e), s = (r >> 16) - i, n = (r >> 8 & 255) - i, a = (r & 255) - i;
|
|
967
|
+
return "#" + (16777216 + (s < 255 ? s < 1 ? 0 : s : 255) * 65536 + (n < 255 ? n < 1 ? 0 : n : 255) * 256 + (a < 255 ? a < 1 ? 0 : a : 255)).toString(16).slice(1);
|
|
968
968
|
}
|
|
969
969
|
/**
|
|
970
970
|
* Lighten color by percentage
|
|
971
971
|
*/
|
|
972
972
|
static lighten(t, e) {
|
|
973
|
-
const r = parseInt(t.replace("#", ""), 16),
|
|
974
|
-
return "#" + (16777216 + (
|
|
973
|
+
const r = parseInt(t.replace("#", ""), 16), i = Math.round(2.55 * e), s = (r >> 16) + i, n = (r >> 8 & 255) + i, a = (r & 255) + i;
|
|
974
|
+
return "#" + (16777216 + (s < 255 ? s < 1 ? 0 : s : 255) * 65536 + (n < 255 ? n < 1 ? 0 : n : 255) * 256 + (a < 255 ? a < 1 ? 0 : a : 255)).toString(16).slice(1);
|
|
975
975
|
}
|
|
976
976
|
/**
|
|
977
977
|
* Get contrast color (black or white) for background
|
|
978
978
|
*/
|
|
979
979
|
static getContrastColor(t) {
|
|
980
|
-
const e = t.replace("#", ""), r = parseInt(e.substr(0, 2), 16),
|
|
981
|
-
return (r * 299 +
|
|
980
|
+
const e = t.replace("#", ""), r = parseInt(e.substr(0, 2), 16), i = parseInt(e.substr(2, 2), 16), s = parseInt(e.substr(4, 2), 16);
|
|
981
|
+
return (r * 299 + i * 587 + s * 114) / 1e3 >= 128 ? "#000000" : "#FFFFFF";
|
|
982
982
|
}
|
|
983
983
|
/**
|
|
984
984
|
* Sanitize color value to prevent CSS injection
|
|
@@ -1020,8 +1020,8 @@ class f {
|
|
|
1020
1020
|
* Convert hex to rgba
|
|
1021
1021
|
*/
|
|
1022
1022
|
static hexToRgba(t, e = 1) {
|
|
1023
|
-
const r = t.replace("#", ""),
|
|
1024
|
-
return `rgba(${
|
|
1023
|
+
const r = t.replace("#", ""), i = parseInt(r.substr(0, 2), 16), s = parseInt(r.substr(2, 2), 16), n = parseInt(r.substr(4, 2), 16);
|
|
1024
|
+
return `rgba(${i}, ${s}, ${n}, ${e})`;
|
|
1025
1025
|
}
|
|
1026
1026
|
/**
|
|
1027
1027
|
* Generate grid styles
|
|
@@ -1271,8 +1271,8 @@ class E {
|
|
|
1271
1271
|
* @param {Function} handler
|
|
1272
1272
|
*/
|
|
1273
1273
|
addListener(t, e, r) {
|
|
1274
|
-
const
|
|
1275
|
-
t.addEventListener(e,
|
|
1274
|
+
const i = r.bind(this);
|
|
1275
|
+
t.addEventListener(e, i), this._listeners.push({ element: t, event: e, handler: i });
|
|
1276
1276
|
}
|
|
1277
1277
|
/**
|
|
1278
1278
|
* Escape HTML to prevent XSS
|
|
@@ -1315,25 +1315,17 @@ class E {
|
|
|
1315
1315
|
* @returns {string}
|
|
1316
1316
|
*/
|
|
1317
1317
|
formatTime(t) {
|
|
1318
|
-
const e = t.getHours(), r = t.getMinutes(),
|
|
1319
|
-
return r === 0 ? `${
|
|
1318
|
+
const e = t.getHours(), r = t.getMinutes(), i = e >= 12 ? "PM" : "AM", s = e % 12 || 12;
|
|
1319
|
+
return r === 0 ? `${s} ${i}` : `${s}:${r.toString().padStart(2, "0")} ${i}`;
|
|
1320
1320
|
}
|
|
1321
1321
|
/**
|
|
1322
|
-
* Get contrasting text color for a background color
|
|
1323
|
-
*
|
|
1322
|
+
* Get contrasting text color for a background color.
|
|
1323
|
+
* Delegates to StyleUtils.getContrastColor() as the single implementation.
|
|
1324
1324
|
* @param {string} bgColor - Hex color string
|
|
1325
|
-
* @returns {string} '
|
|
1325
|
+
* @returns {string} '#000000' or '#FFFFFF'
|
|
1326
1326
|
*/
|
|
1327
1327
|
getContrastingTextColor(t) {
|
|
1328
|
-
|
|
1329
|
-
const e = t.charAt(0) === "#" ? t.substring(1) : t;
|
|
1330
|
-
if (!/^[0-9A-Fa-f]{3}$|^[0-9A-Fa-f]{6}$/.test(e))
|
|
1331
|
-
return "white";
|
|
1332
|
-
const r = e.length === 3 ? e[0] + e[0] + e[1] + e[1] + e[2] + e[2] : e, s = parseInt(r.substring(0, 2), 16), i = parseInt(r.substring(2, 4), 16), n = parseInt(r.substring(4, 6), 16);
|
|
1333
|
-
if (isNaN(s) || isNaN(i) || isNaN(n))
|
|
1334
|
-
return "white";
|
|
1335
|
-
const a = [s / 255, i / 255, n / 255].map((d) => d <= 0.03928 ? d / 12.92 : Math.pow((d + 0.055) / 1.055, 2.4));
|
|
1336
|
-
return 0.2126 * a[0] + 0.7152 * a[1] + 0.0722 * a[2] > 0.179 ? "black" : "white";
|
|
1328
|
+
return !t || typeof t != "string" || t.charAt(0) !== "#" ? "white" : f.getContrastColor(t);
|
|
1337
1329
|
}
|
|
1338
1330
|
/**
|
|
1339
1331
|
* Render the "now" indicator line for time-based views
|
|
@@ -1352,32 +1344,32 @@ class E {
|
|
|
1352
1344
|
*/
|
|
1353
1345
|
computeOverlapLayout(t) {
|
|
1354
1346
|
if (!t || t.length === 0) return /* @__PURE__ */ new Map();
|
|
1355
|
-
const e = t.map((
|
|
1356
|
-
const c = new Date(
|
|
1357
|
-
return { id:
|
|
1347
|
+
const e = t.map((o) => {
|
|
1348
|
+
const c = new Date(o.start), d = new Date(o.end), l = c.getHours() * 60 + c.getMinutes(), u = Math.max(l + 1, d.getHours() * 60 + d.getMinutes());
|
|
1349
|
+
return { id: o.id, startMin: l, endMin: u };
|
|
1358
1350
|
});
|
|
1359
|
-
e.sort((
|
|
1360
|
-
const r = [],
|
|
1361
|
-
for (const
|
|
1351
|
+
e.sort((o, c) => o.startMin - c.startMin || c.endMin - c.startMin - (o.endMin - o.startMin));
|
|
1352
|
+
const r = [], i = /* @__PURE__ */ new Map();
|
|
1353
|
+
for (const o of e) {
|
|
1362
1354
|
let c = !1;
|
|
1363
1355
|
for (let d = 0; d < r.length; d++)
|
|
1364
|
-
if (r[d] <=
|
|
1365
|
-
r[d] =
|
|
1356
|
+
if (r[d] <= o.startMin) {
|
|
1357
|
+
r[d] = o.endMin, i.set(o.id, { column: d, totalColumns: 0 }), c = !0;
|
|
1366
1358
|
break;
|
|
1367
1359
|
}
|
|
1368
|
-
c || (
|
|
1360
|
+
c || (i.set(o.id, { column: r.length, totalColumns: 0 }), r.push(o.endMin));
|
|
1369
1361
|
}
|
|
1370
|
-
const
|
|
1371
|
-
let n = [],
|
|
1372
|
-
for (const
|
|
1373
|
-
n.length === 0 ||
|
|
1374
|
-
n.length > 0 &&
|
|
1375
|
-
for (const
|
|
1376
|
-
const c = Math.max(...
|
|
1377
|
-
for (const d of
|
|
1378
|
-
|
|
1362
|
+
const s = [];
|
|
1363
|
+
let n = [], a = 0;
|
|
1364
|
+
for (const o of e)
|
|
1365
|
+
n.length === 0 || o.startMin < a ? (n.push(o), a = Math.max(a, o.endMin)) : (s.push(n), n = [o], a = o.endMin);
|
|
1366
|
+
n.length > 0 && s.push(n);
|
|
1367
|
+
for (const o of s) {
|
|
1368
|
+
const c = Math.max(...o.map((d) => i.get(d.id).column)) + 1;
|
|
1369
|
+
for (const d of o)
|
|
1370
|
+
i.get(d.id).totalColumns = c;
|
|
1379
1371
|
}
|
|
1380
|
-
return
|
|
1372
|
+
return i;
|
|
1381
1373
|
}
|
|
1382
1374
|
/**
|
|
1383
1375
|
* Render a timed event block
|
|
@@ -1388,16 +1380,16 @@ class E {
|
|
|
1388
1380
|
* @returns {string} HTML string
|
|
1389
1381
|
*/
|
|
1390
1382
|
renderTimedEvent(t, e = {}) {
|
|
1391
|
-
const { compact: r = !0, overlapLayout:
|
|
1383
|
+
const { compact: r = !0, overlapLayout: i = null } = e, s = new Date(t.start), n = new Date(t.end), a = s.getHours() * 60 + s.getMinutes(), o = Math.max((n - s) / (1e3 * 60), r ? 20 : 30), c = this.getEventColor(t), d = r ? "4px 8px" : "8px 12px", l = r ? "11px" : "13px", u = r ? 2 : 12, m = r ? 2 : 24, b = r ? "4px" : "6px";
|
|
1392
1384
|
let y, x;
|
|
1393
|
-
if (
|
|
1394
|
-
const { column: S, totalColumns: _ } =
|
|
1385
|
+
if (i && i.has(t.id)) {
|
|
1386
|
+
const { column: S, totalColumns: _ } = i.get(t.id), $ = `(100% - ${u + m}px)`;
|
|
1395
1387
|
y = `calc(${u}px + ${S} * ${$} / ${_})`, x = `calc(${$} / ${_})`;
|
|
1396
1388
|
} else
|
|
1397
1389
|
y = `${u}px`, x = `calc(100% - ${u + m}px)`;
|
|
1398
1390
|
return `
|
|
1399
1391
|
<div class="fc-event fc-timed-event" data-event-id="${this.escapeHTML(t.id)}"
|
|
1400
|
-
style="position: absolute; top: ${
|
|
1392
|
+
style="position: absolute; top: ${a}px; height: ${o}px;
|
|
1401
1393
|
left: ${y}; width: ${x};
|
|
1402
1394
|
background-color: ${c}; border-radius: ${b};
|
|
1403
1395
|
padding: ${d}; font-size: ${l};
|
|
@@ -1408,7 +1400,7 @@ class E {
|
|
|
1408
1400
|
${this.escapeHTML(t.title)}
|
|
1409
1401
|
</div>
|
|
1410
1402
|
<div style="font-size: ${r ? "10px" : "11px"}; opacity: 0.9;">
|
|
1411
|
-
${this.formatTime(
|
|
1403
|
+
${this.formatTime(s)}${r ? "" : " - " + this.formatTime(n)}
|
|
1412
1404
|
</div>
|
|
1413
1405
|
</div>
|
|
1414
1406
|
`;
|
|
@@ -1429,8 +1421,8 @@ class E {
|
|
|
1429
1421
|
const e = t.target.closest(".fc-event");
|
|
1430
1422
|
if (!e || !this.container.contains(e)) return;
|
|
1431
1423
|
t.stopPropagation();
|
|
1432
|
-
const r = e.dataset.eventId,
|
|
1433
|
-
|
|
1424
|
+
const r = e.dataset.eventId, i = this.stateManager.getEvents().find((s) => s.id === r);
|
|
1425
|
+
i && this.stateManager.selectEvent(i);
|
|
1434
1426
|
});
|
|
1435
1427
|
}
|
|
1436
1428
|
}
|
|
@@ -1451,7 +1443,7 @@ class w extends E {
|
|
|
1451
1443
|
}
|
|
1452
1444
|
_renderMonthView(t, e) {
|
|
1453
1445
|
const r = e.weekStartsOn || 0;
|
|
1454
|
-
let
|
|
1446
|
+
let s = `
|
|
1455
1447
|
<div class="fc-month-view" style="display: flex; flex-direction: column; height: 100%; min-height: 400px; background: var(--fc-background); border: 1px solid var(--fc-border-color);">
|
|
1456
1448
|
<div class="fc-month-header" style="display: grid; grid-template-columns: repeat(7, 1fr); border-bottom: 1px solid var(--fc-border-color); background: var(--fc-background-alt);">
|
|
1457
1449
|
${this._getDayNames(r).map((n) => `<div class="fc-month-header-cell" style="padding: 12px 8px; text-align: center; font-size: 11px; font-weight: 600; color: var(--fc-text-light); text-transform: uppercase;">${n}</div>`).join("")}
|
|
@@ -1459,14 +1451,14 @@ class w extends E {
|
|
|
1459
1451
|
<div class="fc-month-body" style="display: flex; flex-direction: column; flex: 1;">
|
|
1460
1452
|
`;
|
|
1461
1453
|
return t.weeks.forEach((n) => {
|
|
1462
|
-
|
|
1463
|
-
}),
|
|
1454
|
+
s += this._renderWeek(n);
|
|
1455
|
+
}), s += "</div></div>", s;
|
|
1464
1456
|
}
|
|
1465
1457
|
_getDayNames(t) {
|
|
1466
1458
|
const e = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], r = [];
|
|
1467
|
-
for (let
|
|
1468
|
-
const
|
|
1469
|
-
r.push(e[
|
|
1459
|
+
for (let i = 0; i < 7; i++) {
|
|
1460
|
+
const s = (t + i) % 7;
|
|
1461
|
+
r.push(e[s]);
|
|
1470
1462
|
}
|
|
1471
1463
|
return r;
|
|
1472
1464
|
}
|
|
@@ -1477,15 +1469,15 @@ class w extends E {
|
|
|
1477
1469
|
}), e += "</div>", e;
|
|
1478
1470
|
}
|
|
1479
1471
|
_renderDay(t) {
|
|
1480
|
-
const e = !t.isCurrentMonth, r = t.isToday,
|
|
1472
|
+
const e = !t.isCurrentMonth, r = t.isToday, i = e ? "var(--fc-background-hover)" : "var(--fc-background)", s = e ? "var(--fc-text-light)" : "var(--fc-text-color)", n = r ? "background: var(--fc-primary-color); color: white; border-radius: 50%; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;" : "", a = t.events || [], o = a.slice(0, this.maxEventsToShow), c = a.length - this.maxEventsToShow;
|
|
1481
1473
|
return `
|
|
1482
1474
|
<div class="fc-month-day" data-date="${t.date}"
|
|
1483
|
-
style="background: ${
|
|
1484
|
-
<div class="fc-day-number" style="font-size: 13px; font-weight: 500; color: ${
|
|
1475
|
+
style="background: ${i}; border-right: 1px solid var(--fc-border-color); border-bottom: 1px solid var(--fc-border-color); padding: 4px; min-height: 80px; cursor: pointer; display: flex; flex-direction: column;">
|
|
1476
|
+
<div class="fc-day-number" style="font-size: 13px; font-weight: 500; color: ${s}; padding: 2px 4px; margin-bottom: 4px; ${n}">
|
|
1485
1477
|
${t.dayOfMonth}
|
|
1486
1478
|
</div>
|
|
1487
1479
|
<div class="fc-day-events" style="display: flex; flex-direction: column; gap: 2px; flex: 1; overflow: hidden;">
|
|
1488
|
-
${
|
|
1480
|
+
${o.map((d) => this._renderEvent(d)).join("")}
|
|
1489
1481
|
${c > 0 ? `<div class="fc-more-events" style="font-size: 10px; color: var(--fc-text-light); padding: 2px 4px; font-weight: 500;">+${c} more</div>` : ""}
|
|
1490
1482
|
</div>
|
|
1491
1483
|
</div>
|
|
@@ -1525,14 +1517,14 @@ class I extends E {
|
|
|
1525
1517
|
this.container.innerHTML = r, this._attachEventHandlers(), this._scrollToCurrentTime();
|
|
1526
1518
|
}
|
|
1527
1519
|
_renderWeekView(t, e) {
|
|
1528
|
-
const r = t.days,
|
|
1529
|
-
const
|
|
1520
|
+
const r = t.days, i = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], s = Array.from({ length: 24 }, (a, o) => o), n = r.map((a) => {
|
|
1521
|
+
const o = new Date(a.date), c = a.events || [];
|
|
1530
1522
|
return {
|
|
1531
|
-
...
|
|
1532
|
-
date:
|
|
1533
|
-
dayName:
|
|
1534
|
-
dayOfMonth:
|
|
1535
|
-
isToday: this.isToday(
|
|
1523
|
+
...a,
|
|
1524
|
+
date: o,
|
|
1525
|
+
dayName: i[o.getDay()],
|
|
1526
|
+
dayOfMonth: o.getDate(),
|
|
1527
|
+
isToday: this.isToday(o),
|
|
1536
1528
|
timedEvents: c.filter((d) => !d.allDay),
|
|
1537
1529
|
allDayEvents: c.filter((d) => d.allDay)
|
|
1538
1530
|
};
|
|
@@ -1541,7 +1533,7 @@ class I extends E {
|
|
|
1541
1533
|
<div class="fc-week-view" style="display: flex; flex-direction: column; height: 100%; background: var(--fc-background); overflow: hidden;">
|
|
1542
1534
|
${this._renderHeader(n)}
|
|
1543
1535
|
${this._renderAllDayRow(n)}
|
|
1544
|
-
${this._renderTimeGrid(n,
|
|
1536
|
+
${this._renderTimeGrid(n, s)}
|
|
1545
1537
|
</div>
|
|
1546
1538
|
`;
|
|
1547
1539
|
}
|
|
@@ -1622,7 +1614,7 @@ class I extends E {
|
|
|
1622
1614
|
<!-- Timed events -->
|
|
1623
1615
|
${(() => {
|
|
1624
1616
|
const r = this.computeOverlapLayout(t.timedEvents);
|
|
1625
|
-
return t.timedEvents.map((
|
|
1617
|
+
return t.timedEvents.map((i) => this.renderTimedEvent(i, { compact: !0, overlapLayout: r })).join("");
|
|
1626
1618
|
})()}
|
|
1627
1619
|
</div>
|
|
1628
1620
|
`;
|
|
@@ -1631,10 +1623,10 @@ class I extends E {
|
|
|
1631
1623
|
this.addListener(this.container, "click", (t) => {
|
|
1632
1624
|
const e = t.target.closest(".fc-week-day-column");
|
|
1633
1625
|
if (!e || !this.container.contains(e) || t.target.closest(".fc-event")) return;
|
|
1634
|
-
const r = new Date(e.dataset.date),
|
|
1626
|
+
const r = new Date(e.dataset.date), i = this.container.querySelector("#week-scroll-container"), s = e.offsetTop, n = t.clientY - e.getBoundingClientRect().top + (i ? i.scrollTop : 0) - s, a = Math.max(0, Math.min(n + s, this.totalHeight));
|
|
1635
1627
|
r.setHours(
|
|
1636
|
-
Math.floor(
|
|
1637
|
-
Math.floor(
|
|
1628
|
+
Math.floor(a / this.hourHeight),
|
|
1629
|
+
Math.floor(a % this.hourHeight / (this.hourHeight / 60)),
|
|
1638
1630
|
0,
|
|
1639
1631
|
0
|
|
1640
1632
|
), this.stateManager.selectDate(r);
|
|
@@ -1663,39 +1655,39 @@ class z extends E {
|
|
|
1663
1655
|
}
|
|
1664
1656
|
_renderDayView(t, e) {
|
|
1665
1657
|
var l, u;
|
|
1666
|
-
const r = ((u = (l = this.stateManager) == null ? void 0 : l.getState()) == null ? void 0 : u.currentDate) || /* @__PURE__ */ new Date(),
|
|
1667
|
-
if (!
|
|
1658
|
+
const r = ((u = (l = this.stateManager) == null ? void 0 : l.getState()) == null ? void 0 : u.currentDate) || /* @__PURE__ */ new Date(), i = this._extractDayData(t, r);
|
|
1659
|
+
if (!i)
|
|
1668
1660
|
return '<div style="padding: 20px; text-align: center; color: var(--fc-text-secondary);">No data available for day view.</div>';
|
|
1669
|
-
const { dayDate:
|
|
1661
|
+
const { dayDate: s, dayName: n, isToday: a, allDayEvents: o, timedEvents: c } = i, d = Array.from({ length: 24 }, (m, b) => b);
|
|
1670
1662
|
return `
|
|
1671
1663
|
<div class="fc-day-view" style="display: flex; flex-direction: column; height: 100%; background: var(--fc-background); overflow: hidden;">
|
|
1672
|
-
${this._renderHeader(
|
|
1673
|
-
${this._renderAllDayRow(
|
|
1674
|
-
${this._renderTimeGrid(c,
|
|
1664
|
+
${this._renderHeader(s, n, a)}
|
|
1665
|
+
${this._renderAllDayRow(o, s)}
|
|
1666
|
+
${this._renderTimeGrid(c, a, s, d)}
|
|
1675
1667
|
</div>
|
|
1676
1668
|
`;
|
|
1677
1669
|
}
|
|
1678
1670
|
_extractDayData(t, e) {
|
|
1679
|
-
let r,
|
|
1680
|
-
const
|
|
1671
|
+
let r, i, s, n, a;
|
|
1672
|
+
const o = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
|
1681
1673
|
if (t.type === "day" && t.date)
|
|
1682
|
-
if (r = new Date(t.date),
|
|
1674
|
+
if (r = new Date(t.date), i = t.dayName || o[r.getDay()], s = t.isToday !== void 0 ? t.isToday : this.isToday(r), n = t.allDayEvents || [], t.hours && Array.isArray(t.hours)) {
|
|
1683
1675
|
const c = /* @__PURE__ */ new Map();
|
|
1684
1676
|
t.hours.forEach((d) => {
|
|
1685
1677
|
(d.events || []).forEach((l) => {
|
|
1686
1678
|
c.has(l.id) || c.set(l.id, l);
|
|
1687
1679
|
});
|
|
1688
|
-
}),
|
|
1680
|
+
}), a = Array.from(c.values());
|
|
1689
1681
|
} else
|
|
1690
|
-
|
|
1682
|
+
a = [];
|
|
1691
1683
|
else if (t.days && t.days.length > 0) {
|
|
1692
1684
|
const c = t.days.find((l) => this.isSameDay(new Date(l.date), e)) || t.days[0];
|
|
1693
|
-
r = new Date(c.date),
|
|
1685
|
+
r = new Date(c.date), i = o[r.getDay()], s = this.isToday(r);
|
|
1694
1686
|
const d = c.events || [];
|
|
1695
|
-
n = d.filter((l) => l.allDay),
|
|
1687
|
+
n = d.filter((l) => l.allDay), a = d.filter((l) => !l.allDay);
|
|
1696
1688
|
} else
|
|
1697
1689
|
return null;
|
|
1698
|
-
return { dayDate: r, dayName:
|
|
1690
|
+
return { dayDate: r, dayName: i, isToday: s, allDayEvents: n, timedEvents: a };
|
|
1699
1691
|
}
|
|
1700
1692
|
_renderHeader(t, e, r) {
|
|
1701
1693
|
return `
|
|
@@ -1731,12 +1723,12 @@ class z extends E {
|
|
|
1731
1723
|
</div>
|
|
1732
1724
|
`;
|
|
1733
1725
|
}
|
|
1734
|
-
_renderTimeGrid(t, e, r,
|
|
1726
|
+
_renderTimeGrid(t, e, r, i) {
|
|
1735
1727
|
return `
|
|
1736
1728
|
<div id="day-scroll-container" class="fc-time-grid-container" style="flex: 1; overflow-y: auto; overflow-x: hidden; position: relative;">
|
|
1737
1729
|
<div class="fc-time-grid" style="display: grid; grid-template-columns: 60px 1fr; position: relative; height: ${this.totalHeight}px;">
|
|
1738
|
-
${this._renderTimeGutter(
|
|
1739
|
-
${this._renderDayColumn(t, e, r,
|
|
1730
|
+
${this._renderTimeGutter(i)}
|
|
1731
|
+
${this._renderDayColumn(t, e, r, i)}
|
|
1740
1732
|
</div>
|
|
1741
1733
|
</div>
|
|
1742
1734
|
`;
|
|
@@ -1754,19 +1746,19 @@ class z extends E {
|
|
|
1754
1746
|
</div>
|
|
1755
1747
|
`;
|
|
1756
1748
|
}
|
|
1757
|
-
_renderDayColumn(t, e, r,
|
|
1749
|
+
_renderDayColumn(t, e, r, i) {
|
|
1758
1750
|
return `
|
|
1759
1751
|
<div class="fc-day-column" data-date="${r.toISOString()}" style="position: relative; cursor: pointer;">
|
|
1760
1752
|
<!-- Hour grid lines -->
|
|
1761
|
-
${
|
|
1753
|
+
${i.map(() => `<div style="height: ${this.hourHeight}px; border-bottom: 1px solid var(--fc-background-hover);"></div>`).join("")}
|
|
1762
1754
|
|
|
1763
1755
|
<!-- Now indicator for today -->
|
|
1764
1756
|
${e ? this.renderNowIndicator() : ""}
|
|
1765
1757
|
|
|
1766
1758
|
<!-- Timed events -->
|
|
1767
1759
|
${(() => {
|
|
1768
|
-
const
|
|
1769
|
-
return t.map((n) => this.renderTimedEvent(n, { compact: !1, overlapLayout:
|
|
1760
|
+
const s = this.computeOverlapLayout(t);
|
|
1761
|
+
return t.map((n) => this.renderTimedEvent(n, { compact: !1, overlapLayout: s })).join("");
|
|
1770
1762
|
})()}
|
|
1771
1763
|
</div>
|
|
1772
1764
|
`;
|
|
@@ -1775,10 +1767,10 @@ class z extends E {
|
|
|
1775
1767
|
this.addListener(this.container, "click", (t) => {
|
|
1776
1768
|
const e = t.target.closest(".fc-day-column");
|
|
1777
1769
|
if (!e || !this.container.contains(e) || t.target.closest(".fc-event")) return;
|
|
1778
|
-
const r = new Date(e.dataset.date),
|
|
1770
|
+
const r = new Date(e.dataset.date), i = this.container.querySelector("#day-scroll-container"), s = e.offsetTop, n = t.clientY - e.getBoundingClientRect().top + (i ? i.scrollTop : 0) - s, a = Math.max(0, Math.min(n + s, this.totalHeight));
|
|
1779
1771
|
r.setHours(
|
|
1780
|
-
Math.floor(
|
|
1781
|
-
Math.floor(
|
|
1772
|
+
Math.floor(a / this.hourHeight),
|
|
1773
|
+
Math.floor(a % this.hourHeight / (this.hourHeight / 60)),
|
|
1782
1774
|
0,
|
|
1783
1775
|
0
|
|
1784
1776
|
), this.stateManager.selectDate(r);
|
|
@@ -2088,8 +2080,8 @@ class B extends M {
|
|
|
2088
2080
|
this.emit("save", t), this.close();
|
|
2089
2081
|
}
|
|
2090
2082
|
formatDateForInput(t) {
|
|
2091
|
-
const e = (
|
|
2092
|
-
return `${r}-${
|
|
2083
|
+
const e = (o) => String(o).padStart(2, "0"), r = t.getFullYear(), i = e(t.getMonth() + 1), s = e(t.getDate()), n = e(t.getHours()), a = e(t.getMinutes());
|
|
2084
|
+
return `${r}-${i}-${s}T${n}:${a}`;
|
|
2093
2085
|
}
|
|
2094
2086
|
unmount() {
|
|
2095
2087
|
this._cleanupFocusTrap && this._cleanupFocusTrap(), this._handleKeyDown && (window.removeEventListener("keydown", this._handleKeyDown), this._handleKeyDown = null, this._keydownListenerAdded = !1);
|
|
@@ -2117,16 +2109,16 @@ const v = class v extends M {
|
|
|
2117
2109
|
this._busUnsubscribers.forEach((r) => r()), this._busUnsubscribers = [];
|
|
2118
2110
|
const t = this.stateManager.eventBus;
|
|
2119
2111
|
this._busUnsubscribers.push(
|
|
2120
|
-
t.on("navigation:*", (r,
|
|
2121
|
-
this.emit("calendar-navigate", { action:
|
|
2112
|
+
t.on("navigation:*", (r, i) => {
|
|
2113
|
+
this.emit("calendar-navigate", { action: i.split(":")[1], ...r });
|
|
2122
2114
|
})
|
|
2123
2115
|
), this._busUnsubscribers.push(
|
|
2124
2116
|
t.on("view:changed", (r) => {
|
|
2125
2117
|
this.emit("calendar-view-change", r);
|
|
2126
2118
|
})
|
|
2127
2119
|
);
|
|
2128
|
-
const e = (r,
|
|
2129
|
-
this.emit(`calendar-event-${r}`,
|
|
2120
|
+
const e = (r, i) => {
|
|
2121
|
+
this.emit(`calendar-event-${r}`, i);
|
|
2130
2122
|
};
|
|
2131
2123
|
this._busUnsubscribers.push(
|
|
2132
2124
|
t.on("event:add", (r) => {
|
|
@@ -2159,10 +2151,10 @@ const v = class v extends M {
|
|
|
2159
2151
|
);
|
|
2160
2152
|
}
|
|
2161
2153
|
handleStateChange(t, e) {
|
|
2162
|
-
var
|
|
2154
|
+
var o, c;
|
|
2163
2155
|
if (!this._hasRendered)
|
|
2164
2156
|
return;
|
|
2165
|
-
const r = t.view !== (e == null ? void 0 : e.view),
|
|
2157
|
+
const r = t.view !== (e == null ? void 0 : e.view), i = ((o = t.currentDate) == null ? void 0 : o.getTime()) !== ((c = e == null ? void 0 : e.currentDate) == null ? void 0 : c.getTime()), s = t.events !== (e == null ? void 0 : e.events), n = t.loading !== (e == null ? void 0 : e.loading);
|
|
2166
2158
|
if (t.error !== (e == null ? void 0 : e.error)) {
|
|
2167
2159
|
this.render();
|
|
2168
2160
|
return;
|
|
@@ -2171,7 +2163,7 @@ const v = class v extends M {
|
|
|
2171
2163
|
this._updateLoadingState(t.loading);
|
|
2172
2164
|
return;
|
|
2173
2165
|
}
|
|
2174
|
-
r && (this.currentView = t.view), r ? (this._updateTitle(), this._updateViewButtons(), this._switchView()) :
|
|
2166
|
+
r && (this.currentView = t.view), r ? (this._updateTitle(), this._updateViewButtons(), this._switchView()) : i ? (this._updateTitle(), this._updateViewContent()) : s && this._updateViewContent();
|
|
2175
2167
|
}
|
|
2176
2168
|
/**
|
|
2177
2169
|
* Update only the title text (no DOM recreation)
|
|
@@ -2617,12 +2609,12 @@ const v = class v extends M {
|
|
|
2617
2609
|
`;
|
|
2618
2610
|
}
|
|
2619
2611
|
template() {
|
|
2620
|
-
const t = this.stateManager.getState(), { currentDate: e, view: r, loading:
|
|
2621
|
-
if (
|
|
2612
|
+
const t = this.stateManager.getState(), { currentDate: e, view: r, loading: i, error: s } = t;
|
|
2613
|
+
if (s)
|
|
2622
2614
|
return `
|
|
2623
2615
|
<div class="force-calendar">
|
|
2624
2616
|
<div class="fc-error">
|
|
2625
|
-
<p><strong>Error:</strong> ${D.escapeHTML(
|
|
2617
|
+
<p><strong>Error:</strong> ${D.escapeHTML(s.message || "An error occurred")}</p>
|
|
2626
2618
|
</div>
|
|
2627
2619
|
</div>
|
|
2628
2620
|
`;
|
|
@@ -2662,11 +2654,11 @@ const v = class v extends M {
|
|
|
2662
2654
|
</header>
|
|
2663
2655
|
|
|
2664
2656
|
<div class="fc-body">
|
|
2665
|
-
<div class="fc-loading" style="display: ${
|
|
2657
|
+
<div class="fc-loading" style="display: ${i ? "flex" : "none"};">
|
|
2666
2658
|
<div class="fc-spinner"></div>
|
|
2667
2659
|
<span>Loading...</span>
|
|
2668
2660
|
</div>
|
|
2669
|
-
<div class="fc-view-container" style="display: ${
|
|
2661
|
+
<div class="fc-view-container" style="display: ${i ? "none" : "flex"};">
|
|
2670
2662
|
${this.renderView()}
|
|
2671
2663
|
</div>
|
|
2672
2664
|
</div>
|
|
@@ -2685,27 +2677,27 @@ const v = class v extends M {
|
|
|
2685
2677
|
return;
|
|
2686
2678
|
this._currentViewInstance && (this._currentViewInstance.cleanup && this._currentViewInstance.cleanup(), this._viewUnsubscribe && (this._viewUnsubscribe(), this._viewUnsubscribe = null));
|
|
2687
2679
|
try {
|
|
2688
|
-
const
|
|
2689
|
-
|
|
2690
|
-
} catch (
|
|
2691
|
-
console.error("[ForceCalendar] Error creating/rendering view:",
|
|
2680
|
+
const i = v.RENDERERS[this.currentView] || w, s = new i(t, this.stateManager);
|
|
2681
|
+
s._viewType = this.currentView, this._currentViewInstance = s, s.render();
|
|
2682
|
+
} catch (i) {
|
|
2683
|
+
console.error("[ForceCalendar] Error creating/rendering view:", i);
|
|
2692
2684
|
}
|
|
2693
2685
|
}
|
|
2694
|
-
this.$$("[data-action]").forEach((
|
|
2695
|
-
this.addListener(
|
|
2696
|
-
}), this.$$("[data-view]").forEach((
|
|
2697
|
-
this.addListener(
|
|
2686
|
+
this.$$("[data-action]").forEach((i) => {
|
|
2687
|
+
this.addListener(i, "click", this.handleNavigation);
|
|
2688
|
+
}), this.$$("[data-view]").forEach((i) => {
|
|
2689
|
+
this.addListener(i, "click", this.handleViewChange);
|
|
2698
2690
|
});
|
|
2699
2691
|
const e = this.$("#event-modal"), r = this.$("#create-event-btn");
|
|
2700
2692
|
r && e && this.addListener(r, "click", () => {
|
|
2701
2693
|
e.open(/* @__PURE__ */ new Date());
|
|
2702
|
-
}), this.addListener(this.shadowRoot, "day-click", (
|
|
2703
|
-
e && e.open(
|
|
2704
|
-
}), e && this.addListener(e, "save", (
|
|
2705
|
-
const
|
|
2694
|
+
}), this.addListener(this.shadowRoot, "day-click", (i) => {
|
|
2695
|
+
e && e.open(i.detail.date);
|
|
2696
|
+
}), e && this.addListener(e, "save", (i) => {
|
|
2697
|
+
const s = i.detail, n = window.crypto && typeof window.crypto.randomUUID == "function" ? window.crypto.randomUUID() : Math.random().toString(36).substring(2, 15);
|
|
2706
2698
|
this.stateManager.addEvent({
|
|
2707
2699
|
id: n,
|
|
2708
|
-
...
|
|
2700
|
+
...s
|
|
2709
2701
|
});
|
|
2710
2702
|
}), this._hasRendered = !0;
|
|
2711
2703
|
}
|
|
@@ -2732,8 +2724,8 @@ const v = class v extends M {
|
|
|
2732
2724
|
case "month":
|
|
2733
2725
|
return p.formatDate(t, "month", r);
|
|
2734
2726
|
case "week": {
|
|
2735
|
-
const
|
|
2736
|
-
return p.formatDateRange(
|
|
2727
|
+
const i = p.startOfWeek(t), s = p.endOfWeek(t);
|
|
2728
|
+
return p.formatDateRange(i, s, r);
|
|
2737
2729
|
}
|
|
2738
2730
|
case "day":
|
|
2739
2731
|
return p.formatDate(t, "long", r);
|