kalendly 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +263 -32
- package/dist/core/index.d.mts +50 -10
- package/dist/core/index.d.ts +50 -10
- package/dist/core/index.js +60 -26
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +56 -25
- package/dist/core/index.mjs.map +1 -1
- package/dist/index.d.mts +76 -10
- package/dist/index.d.ts +76 -10
- package/dist/index.js +373 -160
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +369 -159
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +363 -156
- package/dist/index.umd.js.map +1 -1
- package/dist/styles/calendar.css +477 -415
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -107,26 +107,16 @@ function generateCalendarDates(year, month, events = [], weekStartsOn = 0) {
|
|
|
107
107
|
}
|
|
108
108
|
return dates;
|
|
109
109
|
}
|
|
110
|
-
function getPopupPositionClass(selectedDayIndex) {
|
|
111
|
-
if (selectedDayIndex === null) return "popup-center-bottom";
|
|
112
|
-
if (selectedDayIndex < 3) {
|
|
113
|
-
return "popup-right";
|
|
114
|
-
} else if (selectedDayIndex > 4) {
|
|
115
|
-
return "popup-left";
|
|
116
|
-
} else {
|
|
117
|
-
return "popup-center-bottom";
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
110
|
function getCellClasses(calendarDate) {
|
|
121
111
|
const classes = [];
|
|
122
112
|
if (!calendarDate.isCurrentMonth) {
|
|
123
|
-
classes.push("other-month");
|
|
113
|
+
classes.push("calendar-cell-other-month");
|
|
124
114
|
}
|
|
125
115
|
if (calendarDate.isToday) {
|
|
126
|
-
classes.push("
|
|
116
|
+
classes.push("calendar-cell-today");
|
|
127
117
|
}
|
|
128
118
|
if (calendarDate.hasEvents) {
|
|
129
|
-
classes.push("has
|
|
119
|
+
classes.push("calendar-cell-has-event");
|
|
130
120
|
}
|
|
131
121
|
return classes;
|
|
132
122
|
}
|
|
@@ -185,7 +175,24 @@ function getCategoryColor(category, customColors) {
|
|
|
185
175
|
const color = colorMap[category] || colorMap.other || "#fc8917";
|
|
186
176
|
return isValidHexColor(color) ? color : "#fc8917";
|
|
187
177
|
}
|
|
188
|
-
|
|
178
|
+
function escapeHtml(value) {
|
|
179
|
+
if (value === null || value === void 0) return "";
|
|
180
|
+
return String(value).replace(/[&<>"']/g, (char) => HTML_ESCAPES[char]);
|
|
181
|
+
}
|
|
182
|
+
function slugifyToken(value) {
|
|
183
|
+
return String(value).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
184
|
+
}
|
|
185
|
+
function safeUrl(value) {
|
|
186
|
+
const normalized = String(value).split("").filter((char) => char.charCodeAt(0) > 32).join("");
|
|
187
|
+
if (/^(?:https?:|mailto:)/i.test(normalized)) return normalized;
|
|
188
|
+
const schemeless = !/^[^/?#]*:/.test(normalized);
|
|
189
|
+
return schemeless ? normalized : "#";
|
|
190
|
+
}
|
|
191
|
+
function safeColor(value) {
|
|
192
|
+
const trimmed = String(value).trim();
|
|
193
|
+
return isValidHexColor(trimmed) || /^[a-z]+$/i.test(trimmed) ? trimmed : "#3b82f6";
|
|
194
|
+
}
|
|
195
|
+
var MONTHS, MONTHS_FULL, DAYS, DEFAULT_CATEGORY_COLORS, HTML_ESCAPES;
|
|
189
196
|
var init_utils = __esm({
|
|
190
197
|
"src/core/utils.ts"() {
|
|
191
198
|
"use strict";
|
|
@@ -234,6 +241,13 @@ var init_utils = __esm({
|
|
|
234
241
|
appointment: "#f59e0b",
|
|
235
242
|
other: "#6b7280"
|
|
236
243
|
};
|
|
244
|
+
HTML_ESCAPES = {
|
|
245
|
+
"&": "&",
|
|
246
|
+
"<": "<",
|
|
247
|
+
">": ">",
|
|
248
|
+
'"': """,
|
|
249
|
+
"'": "'"
|
|
250
|
+
};
|
|
237
251
|
}
|
|
238
252
|
});
|
|
239
253
|
|
|
@@ -281,24 +295,38 @@ var init_calendar_engine = __esm({
|
|
|
281
295
|
* Get view model with computed properties
|
|
282
296
|
*/
|
|
283
297
|
getViewModel() {
|
|
284
|
-
const
|
|
285
|
-
this.
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
298
|
+
const panes = Array.from(
|
|
299
|
+
{ length: Math.max(1, this.config.monthCount ?? 1) },
|
|
300
|
+
(_, offset) => {
|
|
301
|
+
const anchor = new Date(
|
|
302
|
+
this.state.currentYear,
|
|
303
|
+
this.state.currentMonth + offset,
|
|
304
|
+
1
|
|
305
|
+
);
|
|
306
|
+
const year = anchor.getFullYear();
|
|
307
|
+
const month = anchor.getMonth();
|
|
308
|
+
return {
|
|
309
|
+
year,
|
|
310
|
+
month,
|
|
311
|
+
monthAndYearText: getMonthYearText(year, month),
|
|
312
|
+
calendarDates: generateCalendarDates(
|
|
313
|
+
year,
|
|
314
|
+
month,
|
|
315
|
+
this.config.events,
|
|
316
|
+
this.config.weekStartsOn
|
|
317
|
+
)
|
|
318
|
+
};
|
|
319
|
+
}
|
|
289
320
|
);
|
|
290
321
|
return {
|
|
291
322
|
...this.state,
|
|
292
323
|
months: MONTHS,
|
|
293
324
|
days: DAYS,
|
|
294
325
|
years: generateYears(this.config.minYear, this.config.maxYear),
|
|
295
|
-
monthAndYearText:
|
|
296
|
-
this.state.currentYear,
|
|
297
|
-
this.state.currentMonth
|
|
298
|
-
),
|
|
326
|
+
monthAndYearText: panes[0].monthAndYearText,
|
|
299
327
|
scheduleDay: this.state.selectedDate ? formatDateForDisplay(this.state.selectedDate) : "",
|
|
300
|
-
|
|
301
|
-
|
|
328
|
+
panes,
|
|
329
|
+
calendarDates: panes[0].calendarDates
|
|
302
330
|
};
|
|
303
331
|
}
|
|
304
332
|
/**
|
|
@@ -494,13 +522,13 @@ function defineCalendarElement(tagName = "kal-calendar") {
|
|
|
494
522
|
customElements.define(tagName, CalendarElement);
|
|
495
523
|
}
|
|
496
524
|
}
|
|
497
|
-
var isSameDay2, CalendarElement;
|
|
525
|
+
var isSameDay2, _CalendarElement, CalendarElement;
|
|
498
526
|
var init_CalendarElement = __esm({
|
|
499
527
|
"src/web-components/CalendarElement.ts"() {
|
|
500
528
|
"use strict";
|
|
501
529
|
init_core();
|
|
502
530
|
isSameDay2 = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
503
|
-
|
|
531
|
+
_CalendarElement = class _CalendarElement extends HTMLElement {
|
|
504
532
|
constructor() {
|
|
505
533
|
super(...arguments);
|
|
506
534
|
this.engine = null;
|
|
@@ -521,6 +549,10 @@ var init_CalendarElement = __esm({
|
|
|
521
549
|
this._categoryColors = null;
|
|
522
550
|
this._renderEvent = null;
|
|
523
551
|
this._renderNoEvents = null;
|
|
552
|
+
this._availabilityColors = null;
|
|
553
|
+
this._selectableStatuses = null;
|
|
554
|
+
this._initError = null;
|
|
555
|
+
this.pendingUpdate = null;
|
|
524
556
|
// Selection state (availability mode — range)
|
|
525
557
|
this._rangeStart = null;
|
|
526
558
|
this._rangeEnd = null;
|
|
@@ -533,6 +565,7 @@ var init_CalendarElement = __esm({
|
|
|
533
565
|
return this._events;
|
|
534
566
|
}
|
|
535
567
|
set events(val) {
|
|
568
|
+
this._initError = null;
|
|
536
569
|
this._events = val;
|
|
537
570
|
if (this.engine) {
|
|
538
571
|
this.engine.updateEvents(val);
|
|
@@ -548,13 +581,28 @@ var init_CalendarElement = __esm({
|
|
|
548
581
|
this.engine.updateCategoryColors(val);
|
|
549
582
|
}
|
|
550
583
|
}
|
|
584
|
+
get availabilityColors() {
|
|
585
|
+
return this._availabilityColors ?? {};
|
|
586
|
+
}
|
|
587
|
+
set availabilityColors(val) {
|
|
588
|
+
this._initError = null;
|
|
589
|
+
this._availabilityColors = val;
|
|
590
|
+
if (this.engine) this.scheduleRender();
|
|
591
|
+
}
|
|
592
|
+
get selectableStatuses() {
|
|
593
|
+
return this._selectableStatuses ?? [];
|
|
594
|
+
}
|
|
595
|
+
set selectableStatuses(val) {
|
|
596
|
+
this._selectableStatuses = val;
|
|
597
|
+
if (this.engine) this.scheduleRender();
|
|
598
|
+
}
|
|
551
599
|
set renderEvent(val) {
|
|
552
600
|
this._renderEvent = val;
|
|
553
|
-
if (this.engine) this.
|
|
601
|
+
if (this.engine) this.scheduleRender();
|
|
554
602
|
}
|
|
555
603
|
set renderNoEvents(val) {
|
|
556
604
|
this._renderNoEvents = val;
|
|
557
|
-
if (this.engine) this.
|
|
605
|
+
if (this.engine) this.scheduleRender();
|
|
558
606
|
}
|
|
559
607
|
get loading() {
|
|
560
608
|
return this.hasAttribute("loading");
|
|
@@ -563,10 +611,22 @@ var init_CalendarElement = __esm({
|
|
|
563
611
|
if (val) this.setAttribute("loading", "");
|
|
564
612
|
else this.removeAttribute("loading");
|
|
565
613
|
}
|
|
614
|
+
// Custom element reactions report rather than propagate, so a failure here
|
|
615
|
+
// is kept and resurfaced at the next call the integrator makes
|
|
616
|
+
reaction(run) {
|
|
617
|
+
try {
|
|
618
|
+
run();
|
|
619
|
+
} catch (error) {
|
|
620
|
+
this._initError = error;
|
|
621
|
+
throw error;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
566
624
|
connectedCallback() {
|
|
567
625
|
this.classList.add("kalendly-calendar");
|
|
568
|
-
this.
|
|
569
|
-
|
|
626
|
+
this.reaction(() => {
|
|
627
|
+
this.initEngine();
|
|
628
|
+
this.render();
|
|
629
|
+
});
|
|
570
630
|
}
|
|
571
631
|
disconnectedCallback() {
|
|
572
632
|
this.cleanup();
|
|
@@ -576,7 +636,7 @@ var init_CalendarElement = __esm({
|
|
|
576
636
|
attributeChangedCallback(name, oldVal, newVal) {
|
|
577
637
|
if (oldVal === newVal) return;
|
|
578
638
|
if (name === "loading") {
|
|
579
|
-
this.
|
|
639
|
+
this.scheduleRender();
|
|
580
640
|
return;
|
|
581
641
|
}
|
|
582
642
|
if (name === "selectable" && newVal === null) {
|
|
@@ -589,6 +649,23 @@ var init_CalendarElement = __esm({
|
|
|
589
649
|
}
|
|
590
650
|
this.reinit();
|
|
591
651
|
}
|
|
652
|
+
get headingText() {
|
|
653
|
+
const heading = this.getAttribute("heading");
|
|
654
|
+
if (heading !== null) return heading;
|
|
655
|
+
const title = this.getAttribute("title");
|
|
656
|
+
if (title !== null && !_CalendarElement.titleDeprecationWarned) {
|
|
657
|
+
_CalendarElement.titleDeprecationWarned = true;
|
|
658
|
+
console.warn(
|
|
659
|
+
`<kal-calendar> the title attribute is deprecated and will be removed in a future release \u2014 use heading instead. title is a global HTML attribute, so the browser also renders it as a tooltip over the whole calendar.`
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
return title;
|
|
663
|
+
}
|
|
664
|
+
get monthCount() {
|
|
665
|
+
const requested = Number(this.getAttribute("months") ?? 1);
|
|
666
|
+
if (!Number.isInteger(requested) || requested < 1) return 1;
|
|
667
|
+
return Math.min(requested, 2);
|
|
668
|
+
}
|
|
592
669
|
get minYear() {
|
|
593
670
|
const val = this.getAttribute("min-year");
|
|
594
671
|
return val ? parseInt(val, 10) : (/* @__PURE__ */ new Date()).getFullYear() - 30;
|
|
@@ -608,19 +685,20 @@ var init_CalendarElement = __esm({
|
|
|
608
685
|
minYear: this.minYear,
|
|
609
686
|
maxYear: this.maxYear,
|
|
610
687
|
weekStartsOn,
|
|
611
|
-
categoryColors: this._categoryColors ?? void 0
|
|
688
|
+
categoryColors: this._categoryColors ?? void 0,
|
|
689
|
+
monthCount: this.monthCount
|
|
612
690
|
});
|
|
613
691
|
this.actions = this.engine.getActions();
|
|
614
692
|
this.applyTheme();
|
|
615
693
|
this.unsubscribe = this.engine.subscribe(() => {
|
|
616
|
-
this.
|
|
694
|
+
this.scheduleRender();
|
|
617
695
|
});
|
|
618
696
|
}
|
|
619
697
|
reinit() {
|
|
620
698
|
if (!this.engine) return;
|
|
621
699
|
this.cleanup();
|
|
622
700
|
this.initEngine();
|
|
623
|
-
this.
|
|
701
|
+
this.scheduleRender();
|
|
624
702
|
}
|
|
625
703
|
cleanup() {
|
|
626
704
|
if (this.unsubscribe) {
|
|
@@ -657,40 +735,84 @@ var init_CalendarElement = __esm({
|
|
|
657
735
|
applyTheme() {
|
|
658
736
|
if (!this._theme) return;
|
|
659
737
|
const root = document.documentElement;
|
|
660
|
-
const
|
|
661
|
-
|
|
662
|
-
root.style.setProperty(
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
if (
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
738
|
+
for (const key of Object.keys(_CalendarElement.themeMap)) {
|
|
739
|
+
const value = this._theme[key];
|
|
740
|
+
if (value) root.style.setProperty(_CalendarElement.themeMap[key], value);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
get knownBuckets() {
|
|
744
|
+
return [
|
|
745
|
+
..._CalendarElement.BUILT_IN_BUCKETS,
|
|
746
|
+
...Object.keys(this._availabilityColors ?? {})
|
|
747
|
+
];
|
|
748
|
+
}
|
|
749
|
+
get updateComplete() {
|
|
750
|
+
return this.pendingUpdate ?? Promise.resolve();
|
|
751
|
+
}
|
|
752
|
+
scheduleRender() {
|
|
753
|
+
if (this.pendingUpdate) return;
|
|
754
|
+
this.pendingUpdate = Promise.resolve().then(() => {
|
|
755
|
+
this.pendingUpdate = null;
|
|
756
|
+
try {
|
|
757
|
+
this.render();
|
|
758
|
+
} catch (error) {
|
|
759
|
+
this._initError = error;
|
|
760
|
+
throw error;
|
|
761
|
+
}
|
|
762
|
+
});
|
|
763
|
+
}
|
|
764
|
+
rethrowInitError() {
|
|
765
|
+
if (this._initError) throw this._initError;
|
|
766
|
+
}
|
|
767
|
+
assertStatusesDeclared() {
|
|
768
|
+
if (!this.getAttribute("availability-mode")) return;
|
|
769
|
+
const missing = this._events.filter(
|
|
770
|
+
(event) => typeof event.availabilityStatus !== "string" || event.availabilityStatus === ""
|
|
771
|
+
).map((event) => String(event.id));
|
|
772
|
+
if (missing.length) {
|
|
773
|
+
throw new Error(
|
|
774
|
+
`<kal-calendar> availability-mode requires availabilityStatus on every event. Missing on: ${missing.join(", ")}.`
|
|
775
|
+
);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
assertStatusesKnown() {
|
|
779
|
+
const known = new Set(this.knownBuckets);
|
|
780
|
+
const unknown = this._events.filter((event) => !known.has(event.availabilityStatus)).map((event) => `${event.id} (${event.availabilityStatus})`);
|
|
781
|
+
if (unknown.length) {
|
|
782
|
+
throw new Error(
|
|
783
|
+
`<kal-calendar> availabilityStatus must name a built-in bucket (${_CalendarElement.BUILT_IN_BUCKETS.join(", ")}) or a key of availabilityColors. Unrecognised on: ${unknown.join(", ")}.`
|
|
784
|
+
);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
resolveBucket(date) {
|
|
788
|
+
if (!this.engine) return "open";
|
|
789
|
+
const declared = new Set(
|
|
790
|
+
this.engine.getEventsForDate(date).map((event) => event.availabilityStatus)
|
|
791
|
+
);
|
|
792
|
+
if (declared.size === 0) return "open";
|
|
793
|
+
return this.knownBuckets.find((bucket) => declared.has(bucket));
|
|
794
|
+
}
|
|
795
|
+
isDateSelectable(date) {
|
|
796
|
+
if (!this.engine) return false;
|
|
797
|
+
if (this._selectableStatuses) {
|
|
798
|
+
return this._selectableStatuses.includes(this.resolveBucket(date));
|
|
799
|
+
}
|
|
800
|
+
return this.engine.getEventsForDate(date).length === 0;
|
|
683
801
|
}
|
|
684
802
|
render() {
|
|
685
803
|
if (!this.engine) return;
|
|
686
804
|
const viewModel = this.engine.getViewModel();
|
|
687
805
|
const useShortMonths = this.hasAttribute("use-short-month-names");
|
|
688
|
-
const title = this.
|
|
806
|
+
const title = this.headingText;
|
|
689
807
|
const minYear = this.minYear;
|
|
690
808
|
const maxYear = this.maxYear;
|
|
691
809
|
const availabilityMode = this.getAttribute("availability-mode");
|
|
692
810
|
const selectable = this.hasAttribute("selectable");
|
|
693
811
|
const isLoading = this.loading;
|
|
812
|
+
if (availabilityMode) {
|
|
813
|
+
this.assertStatusesDeclared();
|
|
814
|
+
this.assertStatusesKnown();
|
|
815
|
+
}
|
|
694
816
|
const today = /* @__PURE__ */ new Date();
|
|
695
817
|
const todayMonth = today.getMonth();
|
|
696
818
|
const todayYear = today.getFullYear();
|
|
@@ -699,7 +821,7 @@ var init_CalendarElement = __esm({
|
|
|
699
821
|
const defaultRenderEvent = (event) => {
|
|
700
822
|
const timeRange = formatTimeRange(event);
|
|
701
823
|
const attendeesList = formatAttendees(event.attendees);
|
|
702
|
-
let borderColor = event.color || "#3b82f6";
|
|
824
|
+
let borderColor = safeColor(event.color || "#3b82f6");
|
|
703
825
|
if (event.category) {
|
|
704
826
|
borderColor = this.engine.getCategoryColor(event.category);
|
|
705
827
|
}
|
|
@@ -734,56 +856,56 @@ var init_CalendarElement = __esm({
|
|
|
734
856
|
return `
|
|
735
857
|
<div class="event-card" style="border-left-color: ${borderColor}">
|
|
736
858
|
<div class="event-header">
|
|
737
|
-
<div class="event-title">${event.name}</div>
|
|
859
|
+
<div class="event-title">${escapeHtml(event.name)}</div>
|
|
738
860
|
<div class="event-badges">
|
|
739
|
-
${event.category ? `<span class="badge category-${event.category}">${getCategoryLabel(event.category)}</span>` : ""}
|
|
740
|
-
${event.priority ? `<span class="badge priority-${event.priority}">${getPriorityLabel(event.priority)}</span>` : ""}
|
|
741
|
-
${event.status && event.status !== "scheduled" ? `<span class="badge status-${event.status}">${getStatusLabel(event.status)}</span>` : ""}
|
|
861
|
+
${event.category ? `<span class="badge category category-${slugifyToken(event.category)}">${escapeHtml(getCategoryLabel(event.category))}</span>` : ""}
|
|
862
|
+
${event.priority ? `<span class="badge priority priority-${slugifyToken(event.priority)}">${escapeHtml(getPriorityLabel(event.priority))}</span>` : ""}
|
|
863
|
+
${event.status && event.status !== "scheduled" ? `<span class="badge status status-${slugifyToken(event.status)}">${escapeHtml(getStatusLabel(event.status))}</span>` : ""}
|
|
742
864
|
</div>
|
|
743
865
|
</div>
|
|
744
866
|
|
|
745
867
|
${timeRange ? `
|
|
746
868
|
<div class="event-time">
|
|
747
869
|
<span class="event-time-label">Time:</span>
|
|
748
|
-
<span class="event-time-value">${timeRange}</span>
|
|
870
|
+
<span class="event-time-value">${escapeHtml(timeRange)}</span>
|
|
749
871
|
</div>
|
|
750
872
|
` : ""}
|
|
751
873
|
|
|
752
874
|
${event.description ? `
|
|
753
|
-
<div class="event-description">${event.description}</div>
|
|
875
|
+
<div class="event-description">${escapeHtml(event.description)}</div>
|
|
754
876
|
` : ""}
|
|
755
877
|
|
|
756
878
|
${event.location ? `
|
|
757
879
|
<div class="event-time">
|
|
758
880
|
<span class="event-time-label">Location:</span>
|
|
759
|
-
<span class="event-time-value">${event.location}</span>
|
|
881
|
+
<span class="event-time-value">${escapeHtml(event.location)}</span>
|
|
760
882
|
</div>
|
|
761
883
|
` : ""}
|
|
762
884
|
|
|
763
885
|
${attendeesList ? `
|
|
764
886
|
<div class="event-time">
|
|
765
887
|
<span class="event-time-label">Attendees:</span>
|
|
766
|
-
<span class="event-time-value">${attendeesList}</span>
|
|
888
|
+
<span class="event-time-value">${escapeHtml(attendeesList)}</span>
|
|
767
889
|
</div>
|
|
768
890
|
` : ""}
|
|
769
891
|
|
|
770
892
|
${event.organizer ? `
|
|
771
893
|
<div class="event-time">
|
|
772
894
|
<span class="event-time-label">Organizer:</span>
|
|
773
|
-
<span class="event-time-value">${event.organizer}</span>
|
|
895
|
+
<span class="event-time-value">${escapeHtml(event.organizer)}</span>
|
|
774
896
|
</div>
|
|
775
897
|
` : ""}
|
|
776
898
|
|
|
777
899
|
${event.notes ? `
|
|
778
900
|
<div class="event-time">
|
|
779
901
|
<span class="event-time-label">Notes:</span>
|
|
780
|
-
<span class="event-time-value">${event.notes}</span>
|
|
902
|
+
<span class="event-time-value">${escapeHtml(event.notes)}</span>
|
|
781
903
|
</div>
|
|
782
904
|
` : ""}
|
|
783
905
|
|
|
784
906
|
${event.url ? `
|
|
785
907
|
<div class="event-time">
|
|
786
|
-
<a href="${event.url}" target="_blank" rel="noopener noreferrer" class="event-link">
|
|
908
|
+
<a href="${escapeHtml(safeUrl(event.url))}" target="_blank" rel="noopener noreferrer" class="event-link">
|
|
787
909
|
View Details \u2192
|
|
788
910
|
</a>
|
|
789
911
|
</div>
|
|
@@ -791,7 +913,7 @@ var init_CalendarElement = __esm({
|
|
|
791
913
|
|
|
792
914
|
${event.tags && event.tags.length > 0 ? `
|
|
793
915
|
<div class="event-tags">
|
|
794
|
-
${event.tags.map((tag) => `<span class="event-tag">${tag}</span>`).join("")}
|
|
916
|
+
${event.tags.map((tag) => `<span class="event-tag">${escapeHtml(tag)}</span>`).join("")}
|
|
795
917
|
</div>
|
|
796
918
|
` : ""}
|
|
797
919
|
</div>
|
|
@@ -801,11 +923,17 @@ var init_CalendarElement = __esm({
|
|
|
801
923
|
const renderEvent = this._renderEvent || defaultRenderEvent;
|
|
802
924
|
const renderNoEvents = this._renderNoEvents || defaultRenderNoEvents;
|
|
803
925
|
const renderTimeGrid = (events, date) => {
|
|
926
|
+
const startHour = (time) => {
|
|
927
|
+
if (typeof time !== "string") return null;
|
|
928
|
+
const hour = Number(time.split(":")[0]);
|
|
929
|
+
return Number.isInteger(hour) && hour >= 0 && hour <= 24 ? hour : null;
|
|
930
|
+
};
|
|
804
931
|
const isHourBooked = (hour) => events.some((event) => {
|
|
805
|
-
if (!event.startTime
|
|
806
|
-
const
|
|
807
|
-
const
|
|
808
|
-
|
|
932
|
+
if (!event.startTime) return true;
|
|
933
|
+
const from = startHour(event.startTime);
|
|
934
|
+
const to = event.endTime ? startHour(event.endTime) : 24;
|
|
935
|
+
if (from === null || to === null) return true;
|
|
936
|
+
return hour >= from && hour < to;
|
|
809
937
|
});
|
|
810
938
|
const slots = Array.from({ length: 24 }, (_, hour) => {
|
|
811
939
|
const startTime = `${String(hour).padStart(2, "0")}:00`;
|
|
@@ -816,81 +944,156 @@ var init_CalendarElement = __esm({
|
|
|
816
944
|
const isRangeEnd = inTimeRange && endTime === this._timeRangeEnd;
|
|
817
945
|
const isInRange = inTimeRange && !isRangeStart && !isRangeEnd;
|
|
818
946
|
const slotClasses = [
|
|
819
|
-
"time-
|
|
820
|
-
booked ? "time-
|
|
821
|
-
isRangeStart ? "time-
|
|
822
|
-
isRangeEnd ? "time-
|
|
823
|
-
isInRange ? "time-
|
|
947
|
+
"time-grid-slot",
|
|
948
|
+
booked ? "time-grid-slot-blocked" : "time-grid-slot-open",
|
|
949
|
+
isRangeStart ? "time-grid-slot-range-start" : "",
|
|
950
|
+
isRangeEnd ? "time-grid-slot-range-end" : "",
|
|
951
|
+
isInRange ? "time-grid-slot-in-range" : ""
|
|
824
952
|
].filter(Boolean).join(" ");
|
|
825
953
|
const slotAttrs = !booked && selectable ? `data-action="select-slot" data-start-time="${startTime}" data-end-time="${endTime}" data-date="${date.toISOString()}"` : "";
|
|
826
954
|
return `
|
|
827
955
|
<div class="${slotClasses}" ${slotAttrs}>
|
|
828
|
-
<span class="time-
|
|
829
|
-
<span class="time-
|
|
956
|
+
<span class="time-grid-label">${startTime}</span>
|
|
957
|
+
<span class="time-grid-status">${booked ? "Booked" : "Available"}</span>
|
|
830
958
|
</div>`;
|
|
831
959
|
});
|
|
832
960
|
return `<div class="time-grid">${slots.join("")}</div>`;
|
|
833
961
|
};
|
|
962
|
+
const multiMonth = viewModel.panes.length > 1;
|
|
963
|
+
const renderPane = (pane) => `
|
|
964
|
+
<div class="calendar-pane">
|
|
965
|
+
${multiMonth ? `<div class="calendar-pane-caption">${escapeHtml(pane.monthAndYearText)}</div>` : ""}
|
|
966
|
+
<table class="calendar-table calendar-table-bordered">
|
|
967
|
+
<thead>
|
|
968
|
+
<tr>
|
|
969
|
+
${viewModel.days.map((day) => `<th>${day.slice(0, 3)}</th>`).join("")}
|
|
970
|
+
</tr>
|
|
971
|
+
</thead>
|
|
972
|
+
<tbody data-calendar-body>
|
|
973
|
+
${isLoading ? Array.from(
|
|
974
|
+
{ length: 6 },
|
|
975
|
+
() => `<tr>${Array.from(
|
|
976
|
+
{ length: 7 },
|
|
977
|
+
() => `<td class="calendar-skeleton" aria-hidden="true"></td>`
|
|
978
|
+
).join("")}</tr>`
|
|
979
|
+
).join("") : pane.calendarDates.map(
|
|
980
|
+
(week) => `
|
|
981
|
+
<tr>
|
|
982
|
+
${week.map((calendarDate, dayIndex) => {
|
|
983
|
+
const classes = getCellClasses(calendarDate);
|
|
984
|
+
const cellAttrs = [];
|
|
985
|
+
if (availabilityMode && calendarDate.isCurrentMonth) {
|
|
986
|
+
const bucket = this.resolveBucket(
|
|
987
|
+
calendarDate.date
|
|
988
|
+
);
|
|
989
|
+
const custom = (this._availabilityColors ?? {})[bucket];
|
|
990
|
+
classes.push(
|
|
991
|
+
`availability-${slugifyToken(bucket)}`
|
|
992
|
+
);
|
|
993
|
+
if (custom) {
|
|
994
|
+
classes.push("availability-status");
|
|
995
|
+
cellAttrs.push(
|
|
996
|
+
`style="--availability-color: ${escapeHtml(safeColor(custom))}"`
|
|
997
|
+
);
|
|
998
|
+
}
|
|
999
|
+
if (!this.isDateSelectable(calendarDate.date)) {
|
|
1000
|
+
classes.push("availability-unselectable");
|
|
1001
|
+
}
|
|
1002
|
+
cellAttrs.push(
|
|
1003
|
+
`aria-label="${escapeHtml(bucket)}"`
|
|
1004
|
+
);
|
|
1005
|
+
}
|
|
1006
|
+
if (availabilityMode === "day" && selectable && calendarDate.isCurrentMonth) {
|
|
1007
|
+
const d = calendarDate.date;
|
|
1008
|
+
if (this._rangeStart && isSameDay2(d, this._rangeStart))
|
|
1009
|
+
classes.push("availability-range-start");
|
|
1010
|
+
if (this._rangeEnd && isSameDay2(d, this._rangeEnd))
|
|
1011
|
+
classes.push("availability-range-end");
|
|
1012
|
+
if (this._rangeStart && this._rangeEnd) {
|
|
1013
|
+
if (d > this._rangeStart && d < this._rangeEnd)
|
|
1014
|
+
classes.push("availability-in-range");
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
const dateString = calendarDate.date.toISOString();
|
|
1018
|
+
return `
|
|
1019
|
+
<td
|
|
1020
|
+
class="${classes.join(" ")}"
|
|
1021
|
+
data-date="${dateString}"
|
|
1022
|
+
data-day-index="${dayIndex}"
|
|
1023
|
+
data-clickable="true"
|
|
1024
|
+
${cellAttrs.join(" ")}
|
|
1025
|
+
>
|
|
1026
|
+
${calendarDate.date.getDate()}
|
|
1027
|
+
</td>
|
|
1028
|
+
`;
|
|
1029
|
+
}).join("")}
|
|
1030
|
+
</tr>
|
|
1031
|
+
`
|
|
1032
|
+
).join("")}
|
|
1033
|
+
</tbody>
|
|
1034
|
+
</table>
|
|
1035
|
+
</div>
|
|
1036
|
+
`;
|
|
834
1037
|
const html = `
|
|
835
1038
|
${title ? `
|
|
836
|
-
<div class="
|
|
837
|
-
<h1>${title}</h1>
|
|
1039
|
+
<div class="calendar-title">
|
|
1040
|
+
<h1>${escapeHtml(title)}</h1>
|
|
838
1041
|
</div>
|
|
839
1042
|
` : ""}
|
|
840
1043
|
|
|
841
|
-
<div class="calendar
|
|
842
|
-
<div class="calendar
|
|
843
|
-
<div class="calendar
|
|
844
|
-
<button type="button" class="calendar
|
|
1044
|
+
<div class="calendar-content">
|
|
1045
|
+
<div class="calendar-card">
|
|
1046
|
+
<div class="calendar-nav-header">
|
|
1047
|
+
<button type="button" class="calendar-nav-arrow" data-action="previous" aria-label="Previous month">
|
|
845
1048
|
‹
|
|
846
1049
|
</button>
|
|
847
1050
|
|
|
848
|
-
<div class="calendar
|
|
1051
|
+
<div class="calendar-picker-container" data-picker-container>
|
|
849
1052
|
<button
|
|
850
1053
|
type="button"
|
|
851
|
-
class="calendar
|
|
1054
|
+
class="calendar-picker-btn"
|
|
852
1055
|
data-action="toggle-picker"
|
|
853
1056
|
aria-expanded="${this.pickerOpen ? "true" : "false"}"
|
|
854
1057
|
aria-haspopup="true"
|
|
855
1058
|
>
|
|
856
1059
|
${useShortMonths ? `${MONTHS[viewModel.currentMonth]} ${viewModel.currentYear}` : viewModel.monthAndYearText}
|
|
857
|
-
<span class="calendar
|
|
1060
|
+
<span class="calendar-picker-chevron">▾</span>
|
|
858
1061
|
</button>
|
|
859
1062
|
|
|
860
1063
|
${this.pickerOpen ? `
|
|
861
|
-
<div class="calendar
|
|
862
|
-
<div class="calendar
|
|
1064
|
+
<div class="calendar-picker-dropdown">
|
|
1065
|
+
<div class="calendar-picker-year-row">
|
|
863
1066
|
<button
|
|
864
1067
|
type="button"
|
|
865
|
-
class="calendar
|
|
1068
|
+
class="calendar-picker-year-arrow"
|
|
866
1069
|
data-action="year-prev"
|
|
867
1070
|
${viewModel.currentYear <= minYear ? "disabled" : ""}
|
|
868
1071
|
aria-label="Previous year"
|
|
869
1072
|
>‹</button>
|
|
870
1073
|
<input
|
|
871
1074
|
type="text"
|
|
872
|
-
class="calendar
|
|
873
|
-
value="${this.yearInput || viewModel.currentYear}"
|
|
1075
|
+
class="calendar-picker-year-input${!this.yearInputValid ? " invalid" : ""}"
|
|
1076
|
+
value="${escapeHtml(this.yearInput || viewModel.currentYear)}"
|
|
874
1077
|
data-year-input
|
|
875
1078
|
aria-label="Year"
|
|
876
1079
|
/>
|
|
877
1080
|
<button
|
|
878
1081
|
type="button"
|
|
879
|
-
class="calendar
|
|
1082
|
+
class="calendar-picker-year-arrow"
|
|
880
1083
|
data-action="year-next"
|
|
881
1084
|
${viewModel.currentYear >= maxYear ? "disabled" : ""}
|
|
882
1085
|
aria-label="Next year"
|
|
883
1086
|
>›</button>
|
|
884
1087
|
</div>
|
|
885
1088
|
|
|
886
|
-
<div class="calendar
|
|
1089
|
+
<div class="calendar-picker-months">
|
|
887
1090
|
${(useShortMonths ? MONTHS : MONTHS_FULL).map((month, index) => {
|
|
888
1091
|
const isSelected = index === viewModel.currentMonth;
|
|
889
1092
|
const isCurrent = index === todayMonth && viewModel.currentYear === todayYear;
|
|
890
1093
|
return `
|
|
891
1094
|
<button
|
|
892
1095
|
type="button"
|
|
893
|
-
class="calendar
|
|
1096
|
+
class="calendar-picker-month${isSelected ? " selected" : ""}${isCurrent ? " current-month" : ""}"
|
|
894
1097
|
data-action="select-month"
|
|
895
1098
|
data-month="${index}"
|
|
896
1099
|
>${month}</button>
|
|
@@ -903,70 +1106,22 @@ var init_CalendarElement = __esm({
|
|
|
903
1106
|
|
|
904
1107
|
<button
|
|
905
1108
|
type="button"
|
|
906
|
-
class="calendar
|
|
1109
|
+
class="calendar-today-btn"
|
|
907
1110
|
data-action="today"
|
|
908
1111
|
${isCurrentMonth ? "disabled" : ""}
|
|
909
1112
|
>Today</button>
|
|
910
1113
|
|
|
911
|
-
<button type="button" class="calendar
|
|
1114
|
+
<button type="button" class="calendar-nav-arrow" data-action="next" aria-label="Next month">
|
|
912
1115
|
›
|
|
913
1116
|
</button>
|
|
914
1117
|
</div>
|
|
915
1118
|
|
|
916
|
-
<
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
${viewModel.days.map((day) => `<th>${day.slice(0, 3)}</th>`).join("")}
|
|
920
|
-
</tr>
|
|
921
|
-
</thead>
|
|
922
|
-
<tbody data-calendar-body>
|
|
923
|
-
${isLoading ? Array.from(
|
|
924
|
-
{ length: 6 },
|
|
925
|
-
() => `<tr>${Array.from(
|
|
926
|
-
{ length: 7 },
|
|
927
|
-
() => `<td class="calendar--skeleton" aria-hidden="true"></td>`
|
|
928
|
-
).join("")}</tr>`
|
|
929
|
-
).join("") : viewModel.calendarDates.map(
|
|
930
|
-
(week) => `
|
|
931
|
-
<tr>
|
|
932
|
-
${week.map((calendarDate, dayIndex) => {
|
|
933
|
-
const classes = getCellClasses(calendarDate);
|
|
934
|
-
if (availabilityMode && calendarDate.isCurrentMonth) {
|
|
935
|
-
classes.push(
|
|
936
|
-
calendarDate.hasEvents ? "availability--booked" : "availability--free"
|
|
937
|
-
);
|
|
938
|
-
}
|
|
939
|
-
if (availabilityMode === "day" && selectable && calendarDate.isCurrentMonth) {
|
|
940
|
-
const d = calendarDate.date;
|
|
941
|
-
if (this._rangeStart && isSameDay2(d, this._rangeStart))
|
|
942
|
-
classes.push("availability--range-start");
|
|
943
|
-
if (this._rangeEnd && isSameDay2(d, this._rangeEnd))
|
|
944
|
-
classes.push("availability--range-end");
|
|
945
|
-
if (this._rangeStart && this._rangeEnd) {
|
|
946
|
-
if (d > this._rangeStart && d < this._rangeEnd)
|
|
947
|
-
classes.push("availability--in-range");
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
const dateString = calendarDate.date.toISOString();
|
|
951
|
-
return `
|
|
952
|
-
<td
|
|
953
|
-
class="${classes.join(" ")}"
|
|
954
|
-
data-date="${dateString}"
|
|
955
|
-
data-day-index="${dayIndex}"
|
|
956
|
-
data-clickable="true"
|
|
957
|
-
>
|
|
958
|
-
${calendarDate.date.getDate()}
|
|
959
|
-
</td>
|
|
960
|
-
`;
|
|
961
|
-
}).join("")}
|
|
962
|
-
</tr>
|
|
963
|
-
`
|
|
964
|
-
).join("")}
|
|
965
|
-
</tbody>
|
|
966
|
-
</table>
|
|
1119
|
+
<div class="calendar-panes">
|
|
1120
|
+
${viewModel.panes.map(renderPane).join("")}
|
|
1121
|
+
</div>
|
|
967
1122
|
|
|
968
1123
|
${!isLoading && availabilityMode !== "day" && viewModel.selectedDate ? `
|
|
969
|
-
<div class="date-popup
|
|
1124
|
+
<div class="date-popup">
|
|
970
1125
|
<div class="popup-header">
|
|
971
1126
|
<h2>${viewModel.scheduleDay}</h2>
|
|
972
1127
|
<button type="button" class="popup-close" data-action="close-popup" aria-label="Close">\u2715</button>
|
|
@@ -1004,8 +1159,7 @@ var init_CalendarElement = __esm({
|
|
|
1004
1159
|
const availMode = this.getAttribute("availability-mode");
|
|
1005
1160
|
const isSelectable = this.hasAttribute("selectable");
|
|
1006
1161
|
if (availMode === "day" && isSelectable) {
|
|
1007
|
-
|
|
1008
|
-
if (!isBooked) {
|
|
1162
|
+
if (this.isDateSelectable(date)) {
|
|
1009
1163
|
let startDate;
|
|
1010
1164
|
let endDate;
|
|
1011
1165
|
if (this._rangeEnd !== null) {
|
|
@@ -1023,7 +1177,7 @@ var init_CalendarElement = __esm({
|
|
|
1023
1177
|
cursor.setDate(cursor.getDate() + 1);
|
|
1024
1178
|
let blocked = false;
|
|
1025
1179
|
while (cursor < e2) {
|
|
1026
|
-
if (this.
|
|
1180
|
+
if (!this.isDateSelectable(cursor)) {
|
|
1027
1181
|
blocked = true;
|
|
1028
1182
|
break;
|
|
1029
1183
|
}
|
|
@@ -1257,31 +1411,84 @@ var init_CalendarElement = __esm({
|
|
|
1257
1411
|
this.theme = theme;
|
|
1258
1412
|
}
|
|
1259
1413
|
getCurrentDate() {
|
|
1414
|
+
this.rethrowInitError();
|
|
1260
1415
|
return this.engine?.getViewModel().selectedDate ?? null;
|
|
1261
1416
|
}
|
|
1262
1417
|
goToDate(date) {
|
|
1418
|
+
this.rethrowInitError();
|
|
1263
1419
|
const year = date.getFullYear();
|
|
1264
1420
|
const month = date.getMonth();
|
|
1265
1421
|
this.dispatchMonthChange(year, month);
|
|
1266
1422
|
this.actions?.jump(year, month);
|
|
1267
1423
|
}
|
|
1268
1424
|
getEngine() {
|
|
1425
|
+
this.rethrowInitError();
|
|
1269
1426
|
if (!this.engine)
|
|
1270
1427
|
throw new Error("CalendarElement is not connected to the DOM");
|
|
1271
1428
|
return this.engine;
|
|
1272
1429
|
}
|
|
1273
1430
|
};
|
|
1274
|
-
|
|
1431
|
+
_CalendarElement.observedAttributes = [
|
|
1275
1432
|
"initial-date",
|
|
1276
1433
|
"min-year",
|
|
1277
1434
|
"max-year",
|
|
1278
1435
|
"week-starts-on",
|
|
1436
|
+
"heading",
|
|
1437
|
+
"months",
|
|
1279
1438
|
"title",
|
|
1280
1439
|
"use-short-month-names",
|
|
1281
1440
|
"availability-mode",
|
|
1282
1441
|
"selectable",
|
|
1283
1442
|
"loading"
|
|
1284
1443
|
];
|
|
1444
|
+
_CalendarElement.themeMap = {
|
|
1445
|
+
primary: "--calendar-primary-color",
|
|
1446
|
+
secondary: "--calendar-secondary-color",
|
|
1447
|
+
tertiary: "--calendar-tertiary-color",
|
|
1448
|
+
textColor: "--calendar-text-color",
|
|
1449
|
+
textLight: "--calendar-text-light",
|
|
1450
|
+
background: "--calendar-background",
|
|
1451
|
+
cellHover: "--calendar-cell-hover",
|
|
1452
|
+
borderColor: "--calendar-border-color",
|
|
1453
|
+
todayOutline: "--calendar-today-outline",
|
|
1454
|
+
selectedBg: "--calendar-selected-bg",
|
|
1455
|
+
headerBg: "--calendar-header-bg",
|
|
1456
|
+
popupBg: "--calendar-popup-bg",
|
|
1457
|
+
pickerBg: "--calendar-picker-bg",
|
|
1458
|
+
pickerShadow: "--calendar-picker-shadow",
|
|
1459
|
+
eventIndicator: "--calendar-event-indicator",
|
|
1460
|
+
onAccent: "--calendar-on-accent",
|
|
1461
|
+
link: "--calendar-link",
|
|
1462
|
+
openBg: "--calendar-open-bg",
|
|
1463
|
+
openFg: "--calendar-open-fg",
|
|
1464
|
+
conditionalBg: "--calendar-conditional-bg",
|
|
1465
|
+
conditionalFg: "--calendar-conditional-fg",
|
|
1466
|
+
blockedBg: "--calendar-blocked-bg",
|
|
1467
|
+
blockedFg: "--calendar-blocked-fg",
|
|
1468
|
+
rangeBg: "--calendar-range-bg",
|
|
1469
|
+
rangeOutline: "--calendar-range-outline",
|
|
1470
|
+
inRangeBg: "--calendar-in-range-bg",
|
|
1471
|
+
inRangeOutline: "--calendar-in-range-outline",
|
|
1472
|
+
badgeBg: "--calendar-badge-bg",
|
|
1473
|
+
badgeText: "--calendar-badge-text",
|
|
1474
|
+
badgeSuccessBg: "--calendar-badge-success-bg",
|
|
1475
|
+
badgeSuccessText: "--calendar-badge-success-text",
|
|
1476
|
+
badgeInfoBg: "--calendar-badge-info-bg",
|
|
1477
|
+
badgeInfoText: "--calendar-badge-info-text",
|
|
1478
|
+
badgeWarningBg: "--calendar-badge-warning-bg",
|
|
1479
|
+
badgeWarningText: "--calendar-badge-warning-text",
|
|
1480
|
+
badgeDangerBg: "--calendar-badge-danger-bg",
|
|
1481
|
+
badgeDangerText: "--calendar-badge-danger-text",
|
|
1482
|
+
badgeNeutralBg: "--calendar-badge-neutral-bg",
|
|
1483
|
+
badgeNeutralText: "--calendar-badge-neutral-text",
|
|
1484
|
+
badgePositiveBg: "--calendar-badge-positive-bg",
|
|
1485
|
+
badgePositiveText: "--calendar-badge-positive-text",
|
|
1486
|
+
badgeTentativeBg: "--calendar-badge-tentative-bg",
|
|
1487
|
+
badgeTentativeText: "--calendar-badge-tentative-text"
|
|
1488
|
+
};
|
|
1489
|
+
_CalendarElement.BUILT_IN_BUCKETS = ["blocked", "conditional", "open"];
|
|
1490
|
+
_CalendarElement.titleDeprecationWarned = false;
|
|
1491
|
+
CalendarElement = _CalendarElement;
|
|
1285
1492
|
}
|
|
1286
1493
|
});
|
|
1287
1494
|
|
|
@@ -1295,6 +1502,7 @@ __export(web_components_exports, {
|
|
|
1295
1502
|
MONTHS: () => MONTHS,
|
|
1296
1503
|
MONTHS_FULL: () => MONTHS_FULL,
|
|
1297
1504
|
defineCalendarElement: () => defineCalendarElement,
|
|
1505
|
+
escapeHtml: () => escapeHtml,
|
|
1298
1506
|
formatAttendees: () => formatAttendees,
|
|
1299
1507
|
formatDateForDisplay: () => formatDateForDisplay,
|
|
1300
1508
|
formatTimeRange: () => formatTimeRange,
|
|
@@ -1305,13 +1513,15 @@ __export(web_components_exports, {
|
|
|
1305
1513
|
getDefaultEventColor: () => getDefaultEventColor,
|
|
1306
1514
|
getEventsForDate: () => getEventsForDate,
|
|
1307
1515
|
getMonthYearText: () => getMonthYearText,
|
|
1308
|
-
getPopupPositionClass: () => getPopupPositionClass,
|
|
1309
1516
|
hasEvents: () => hasEvents,
|
|
1310
1517
|
isSameDay: () => isSameDay,
|
|
1311
1518
|
isToday: () => isToday,
|
|
1312
1519
|
isValidHexColor: () => isValidHexColor,
|
|
1313
1520
|
mergeCategoryColors: () => mergeCategoryColors,
|
|
1314
1521
|
normalizeDate: () => normalizeDate,
|
|
1522
|
+
safeColor: () => safeColor,
|
|
1523
|
+
safeUrl: () => safeUrl,
|
|
1524
|
+
slugifyToken: () => slugifyToken,
|
|
1315
1525
|
sortEventsByTime: () => sortEventsByTime
|
|
1316
1526
|
});
|
|
1317
1527
|
module.exports = __toCommonJS(web_components_exports);
|
|
@@ -1333,6 +1543,7 @@ if (typeof customElements !== "undefined" && !customElements.get("kal-calendar")
|
|
|
1333
1543
|
MONTHS,
|
|
1334
1544
|
MONTHS_FULL,
|
|
1335
1545
|
defineCalendarElement,
|
|
1546
|
+
escapeHtml,
|
|
1336
1547
|
formatAttendees,
|
|
1337
1548
|
formatDateForDisplay,
|
|
1338
1549
|
formatTimeRange,
|
|
@@ -1343,13 +1554,15 @@ if (typeof customElements !== "undefined" && !customElements.get("kal-calendar")
|
|
|
1343
1554
|
getDefaultEventColor,
|
|
1344
1555
|
getEventsForDate,
|
|
1345
1556
|
getMonthYearText,
|
|
1346
|
-
getPopupPositionClass,
|
|
1347
1557
|
hasEvents,
|
|
1348
1558
|
isSameDay,
|
|
1349
1559
|
isToday,
|
|
1350
1560
|
isValidHexColor,
|
|
1351
1561
|
mergeCategoryColors,
|
|
1352
1562
|
normalizeDate,
|
|
1563
|
+
safeColor,
|
|
1564
|
+
safeUrl,
|
|
1565
|
+
slugifyToken,
|
|
1353
1566
|
sortEventsByTime
|
|
1354
1567
|
});
|
|
1355
1568
|
//# sourceMappingURL=index.js.map
|