kalendly 0.1.6 → 0.2.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 +318 -680
- package/dist/core/index.js +3 -3
- package/dist/index.d.mts +53 -601
- package/dist/index.d.ts +53 -601
- package/dist/index.js +760 -2350
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +734 -2339
- package/dist/index.mjs.map +1 -1
- package/dist/{vanilla/index.umd.js → index.umd.js} +323 -307
- package/dist/index.umd.js.map +1 -0
- package/package.json +41 -91
- package/dist/react/index.d.mts +0 -251
- package/dist/react/index.d.ts +0 -251
- package/dist/react/index.js +0 -969
- package/dist/react/index.js.map +0 -1
- package/dist/react/index.mjs +0 -924
- package/dist/react/index.mjs.map +0 -1
- package/dist/react-native/index.d.mts +0 -642
- package/dist/react-native/index.d.ts +0 -642
- package/dist/react-native/index.js +0 -1649
- package/dist/react-native/index.js.map +0 -1
- package/dist/react-native/index.mjs +0 -1615
- package/dist/react-native/index.mjs.map +0 -1
- package/dist/vanilla/index.d.mts +0 -265
- package/dist/vanilla/index.d.ts +0 -265
- package/dist/vanilla/index.js +0 -1048
- package/dist/vanilla/index.js.map +0 -1
- package/dist/vanilla/index.mjs +0 -997
- package/dist/vanilla/index.mjs.map +0 -1
- package/dist/vanilla/index.umd.js.map +0 -1
- package/dist/vue/components/Calendar.vue.d.ts +0 -43
- package/dist/vue/components/Calendar.vue.d.ts.map +0 -1
- package/dist/vue/index.d.ts +0 -134
- package/dist/vue/index.d.ts.map +0 -1
- package/dist/vue/index.js +0 -1
- package/dist/vue/index.mjs +0 -717
- package/dist/vue/types.d.ts +0 -21
- package/dist/vue/types.d.ts.map +0 -1
|
@@ -18,34 +18,11 @@ var Kalendly = (() => {
|
|
|
18
18
|
};
|
|
19
19
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
20
|
|
|
21
|
-
// src/
|
|
22
|
-
var
|
|
23
|
-
__export(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
DEFAULT_CATEGORY_COLORS: () => DEFAULT_CATEGORY_COLORS,
|
|
27
|
-
MONTHS: () => MONTHS,
|
|
28
|
-
MONTHS_FULL: () => MONTHS_FULL,
|
|
29
|
-
VanillaCalendar: () => VanillaCalendar,
|
|
30
|
-
createCalendar: () => createCalendar,
|
|
31
|
-
formatAttendees: () => formatAttendees,
|
|
32
|
-
formatDateForDisplay: () => formatDateForDisplay,
|
|
33
|
-
formatTimeRange: () => formatTimeRange,
|
|
34
|
-
generateCalendarDates: () => generateCalendarDates,
|
|
35
|
-
generateYears: () => generateYears,
|
|
36
|
-
getCategoryColor: () => getCategoryColor,
|
|
37
|
-
getCellClasses: () => getCellClasses,
|
|
38
|
-
getDefaultEventColor: () => getDefaultEventColor,
|
|
39
|
-
getEventsForDate: () => getEventsForDate,
|
|
40
|
-
getMonthYearText: () => getMonthYearText,
|
|
41
|
-
getPopupPositionClass: () => getPopupPositionClass,
|
|
42
|
-
hasEvents: () => hasEvents,
|
|
43
|
-
isSameDay: () => isSameDay,
|
|
44
|
-
isToday: () => isToday,
|
|
45
|
-
isValidHexColor: () => isValidHexColor,
|
|
46
|
-
mergeCategoryColors: () => mergeCategoryColors,
|
|
47
|
-
normalizeDate: () => normalizeDate,
|
|
48
|
-
sortEventsByTime: () => sortEventsByTime
|
|
21
|
+
// src/web-components/CalendarElement.ts
|
|
22
|
+
var CalendarElement_exports = {};
|
|
23
|
+
__export(CalendarElement_exports, {
|
|
24
|
+
CalendarElement: () => CalendarElement,
|
|
25
|
+
defineCalendarElement: () => defineCalendarElement
|
|
49
26
|
});
|
|
50
27
|
|
|
51
28
|
// src/core/utils.ts
|
|
@@ -108,9 +85,6 @@ var Kalendly = (() => {
|
|
|
108
85
|
return eventDate.getTime() === normalizedTargetDate.getTime();
|
|
109
86
|
});
|
|
110
87
|
}
|
|
111
|
-
function hasEvents(events, date) {
|
|
112
|
-
return getEventsForDate(events, date).length > 0;
|
|
113
|
-
}
|
|
114
88
|
function generateCalendarDates(year, month, events = [], weekStartsOn = 0) {
|
|
115
89
|
const firstDay = new Date(year, month, 1);
|
|
116
90
|
const lastDay = new Date(year, month + 1, 0);
|
|
@@ -212,16 +186,6 @@ var Kalendly = (() => {
|
|
|
212
186
|
if (attendees.length === 2) return attendees.join(" and ");
|
|
213
187
|
return `${attendees.slice(0, -1).join(", ")}, and ${attendees[attendees.length - 1]}`;
|
|
214
188
|
}
|
|
215
|
-
function sortEventsByTime(events) {
|
|
216
|
-
return [...events].sort((a, b) => {
|
|
217
|
-
const aAllDay = a.allDay || !a.startTime && !a.endTime;
|
|
218
|
-
const bAllDay = b.allDay || !b.startTime && !b.endTime;
|
|
219
|
-
if (aAllDay && !bAllDay) return -1;
|
|
220
|
-
if (!aAllDay && bAllDay) return 1;
|
|
221
|
-
if (!a.startTime || !b.startTime) return 0;
|
|
222
|
-
return a.startTime.localeCompare(b.startTime);
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
189
|
var DEFAULT_CATEGORY_COLORS = {
|
|
226
190
|
work: "#3b82f6",
|
|
227
191
|
personal: "#8b5cf6",
|
|
@@ -230,13 +194,6 @@ var Kalendly = (() => {
|
|
|
230
194
|
appointment: "#f59e0b",
|
|
231
195
|
other: "#6b7280"
|
|
232
196
|
};
|
|
233
|
-
function getDefaultEventColor(category, customColors) {
|
|
234
|
-
const colorMap = customColors || DEFAULT_CATEGORY_COLORS;
|
|
235
|
-
if (category && colorMap[category]) {
|
|
236
|
-
return colorMap[category];
|
|
237
|
-
}
|
|
238
|
-
return "#fc8917";
|
|
239
|
-
}
|
|
240
197
|
function mergeCategoryColors(customColors) {
|
|
241
198
|
return {
|
|
242
199
|
...DEFAULT_CATEGORY_COLORS,
|
|
@@ -480,78 +437,174 @@ var Kalendly = (() => {
|
|
|
480
437
|
}
|
|
481
438
|
};
|
|
482
439
|
|
|
483
|
-
// src/
|
|
484
|
-
var
|
|
485
|
-
constructor(
|
|
440
|
+
// src/web-components/CalendarElement.ts
|
|
441
|
+
var CalendarElement = class extends HTMLElement {
|
|
442
|
+
constructor() {
|
|
443
|
+
super(...arguments);
|
|
444
|
+
this.engine = null;
|
|
486
445
|
this.unsubscribe = null;
|
|
446
|
+
this.actions = null;
|
|
487
447
|
this.pickerOpen = false;
|
|
488
448
|
this.yearInput = "";
|
|
489
449
|
this.yearInputValid = true;
|
|
450
|
+
this.listenersAttached = false;
|
|
490
451
|
this.clickOutsideHandler = null;
|
|
491
|
-
this.
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
452
|
+
this.delegatedClickHandler = null;
|
|
453
|
+
this.delegatedInputHandler = null;
|
|
454
|
+
this.delegatedBlurHandler = null;
|
|
455
|
+
this.delegatedKeydownHandler = null;
|
|
456
|
+
// Rich property backing fields
|
|
457
|
+
this._events = [];
|
|
458
|
+
this._theme = null;
|
|
459
|
+
this._categoryColors = null;
|
|
460
|
+
this._renderEvent = null;
|
|
461
|
+
this._renderNoEvents = null;
|
|
462
|
+
}
|
|
463
|
+
get events() {
|
|
464
|
+
return this._events;
|
|
465
|
+
}
|
|
466
|
+
set events(val) {
|
|
467
|
+
this._events = val;
|
|
468
|
+
if (this.engine) {
|
|
469
|
+
this.engine.updateEvents(val);
|
|
500
470
|
}
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
minYear: props.minYear,
|
|
505
|
-
maxYear: props.maxYear,
|
|
506
|
-
weekStartsOn: props.weekStartsOn
|
|
507
|
-
});
|
|
508
|
-
this.actions = this.engine.getActions();
|
|
471
|
+
}
|
|
472
|
+
set theme(val) {
|
|
473
|
+
this._theme = val;
|
|
509
474
|
this.applyTheme();
|
|
510
|
-
this.init();
|
|
511
475
|
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
if (theme.primary)
|
|
517
|
-
root.style.setProperty("--calendar-primary-color", theme.primary);
|
|
518
|
-
if (theme.secondary)
|
|
519
|
-
root.style.setProperty("--calendar-secondary-color", theme.secondary);
|
|
520
|
-
if (theme.tertiary)
|
|
521
|
-
root.style.setProperty("--calendar-tertiary-color", theme.tertiary);
|
|
522
|
-
if (theme.textColor)
|
|
523
|
-
root.style.setProperty("--calendar-text-color", theme.textColor);
|
|
524
|
-
if (theme.textLight)
|
|
525
|
-
root.style.setProperty("--calendar-text-light", theme.textLight);
|
|
526
|
-
if (theme.background)
|
|
527
|
-
root.style.setProperty("--calendar-background", theme.background);
|
|
528
|
-
if (theme.cellHover)
|
|
529
|
-
root.style.setProperty("--calendar-cell-hover", theme.cellHover);
|
|
530
|
-
if (theme.borderColor)
|
|
531
|
-
root.style.setProperty("--calendar-border-color", theme.borderColor);
|
|
532
|
-
if (theme.todayOutline)
|
|
533
|
-
root.style.setProperty("--calendar-today-outline", theme.todayOutline);
|
|
534
|
-
if (theme.selectedBg)
|
|
535
|
-
root.style.setProperty("--calendar-selected-bg", theme.selectedBg);
|
|
536
|
-
if (theme.eventIndicator)
|
|
537
|
-
root.style.setProperty(
|
|
538
|
-
"--calendar-event-indicator",
|
|
539
|
-
theme.eventIndicator
|
|
540
|
-
);
|
|
476
|
+
set categoryColors(val) {
|
|
477
|
+
this._categoryColors = val;
|
|
478
|
+
if (this.engine) {
|
|
479
|
+
this.engine.updateCategoryColors(val);
|
|
541
480
|
}
|
|
542
481
|
}
|
|
543
|
-
|
|
544
|
-
this.
|
|
545
|
-
if (this.
|
|
546
|
-
|
|
547
|
-
|
|
482
|
+
set renderEvent(val) {
|
|
483
|
+
this._renderEvent = val;
|
|
484
|
+
if (this.engine) this.render();
|
|
485
|
+
}
|
|
486
|
+
set renderNoEvents(val) {
|
|
487
|
+
this._renderNoEvents = val;
|
|
488
|
+
if (this.engine) this.render();
|
|
489
|
+
}
|
|
490
|
+
connectedCallback() {
|
|
491
|
+
this.classList.add("kalendly-calendar");
|
|
492
|
+
this.initEngine();
|
|
493
|
+
this.render();
|
|
494
|
+
}
|
|
495
|
+
disconnectedCallback() {
|
|
496
|
+
this.cleanup();
|
|
497
|
+
this.classList.remove("kalendly-calendar");
|
|
498
|
+
this.innerHTML = "";
|
|
499
|
+
}
|
|
500
|
+
attributeChangedCallback(_name, oldVal, newVal) {
|
|
501
|
+
if (oldVal === newVal) return;
|
|
502
|
+
this.reinit();
|
|
503
|
+
}
|
|
504
|
+
get minYear() {
|
|
505
|
+
const val = this.getAttribute("min-year");
|
|
506
|
+
return val ? parseInt(val, 10) : (/* @__PURE__ */ new Date()).getFullYear() - 30;
|
|
507
|
+
}
|
|
508
|
+
get maxYear() {
|
|
509
|
+
const val = this.getAttribute("max-year");
|
|
510
|
+
return val ? parseInt(val, 10) : (/* @__PURE__ */ new Date()).getFullYear() + 10;
|
|
511
|
+
}
|
|
512
|
+
initEngine() {
|
|
513
|
+
const initialDateAttr = this.getAttribute("initial-date");
|
|
514
|
+
const initialDate = initialDateAttr ? new Date(initialDateAttr) : void 0;
|
|
515
|
+
const weekStartsOnAttr = this.getAttribute("week-starts-on");
|
|
516
|
+
const weekStartsOn = weekStartsOnAttr === "1" ? 1 : 0;
|
|
517
|
+
this.engine = new CalendarEngine({
|
|
518
|
+
events: this._events,
|
|
519
|
+
initialDate,
|
|
520
|
+
minYear: this.minYear,
|
|
521
|
+
maxYear: this.maxYear,
|
|
522
|
+
weekStartsOn,
|
|
523
|
+
categoryColors: this._categoryColors ?? void 0
|
|
524
|
+
});
|
|
525
|
+
this.actions = this.engine.getActions();
|
|
526
|
+
this.applyTheme();
|
|
548
527
|
this.unsubscribe = this.engine.subscribe(() => {
|
|
549
528
|
this.render();
|
|
550
529
|
});
|
|
530
|
+
}
|
|
531
|
+
reinit() {
|
|
532
|
+
if (!this.engine) return;
|
|
533
|
+
this.cleanup();
|
|
534
|
+
this.initEngine();
|
|
551
535
|
this.render();
|
|
552
536
|
}
|
|
537
|
+
cleanup() {
|
|
538
|
+
if (this.unsubscribe) {
|
|
539
|
+
this.unsubscribe();
|
|
540
|
+
this.unsubscribe = null;
|
|
541
|
+
}
|
|
542
|
+
if (this.delegatedClickHandler) {
|
|
543
|
+
this.removeEventListener("click", this.delegatedClickHandler);
|
|
544
|
+
this.delegatedClickHandler = null;
|
|
545
|
+
}
|
|
546
|
+
if (this.delegatedInputHandler) {
|
|
547
|
+
this.removeEventListener("input", this.delegatedInputHandler);
|
|
548
|
+
this.delegatedInputHandler = null;
|
|
549
|
+
}
|
|
550
|
+
if (this.delegatedBlurHandler) {
|
|
551
|
+
this.removeEventListener("blur", this.delegatedBlurHandler, true);
|
|
552
|
+
this.delegatedBlurHandler = null;
|
|
553
|
+
}
|
|
554
|
+
if (this.delegatedKeydownHandler) {
|
|
555
|
+
this.removeEventListener("keydown", this.delegatedKeydownHandler);
|
|
556
|
+
this.delegatedKeydownHandler = null;
|
|
557
|
+
}
|
|
558
|
+
if (this.clickOutsideHandler) {
|
|
559
|
+
document.removeEventListener("click", this.clickOutsideHandler);
|
|
560
|
+
this.clickOutsideHandler = null;
|
|
561
|
+
}
|
|
562
|
+
this.listenersAttached = false;
|
|
563
|
+
if (this.engine) {
|
|
564
|
+
this.engine.destroy();
|
|
565
|
+
this.engine = null;
|
|
566
|
+
}
|
|
567
|
+
this.actions = null;
|
|
568
|
+
}
|
|
569
|
+
applyTheme() {
|
|
570
|
+
if (!this._theme) return;
|
|
571
|
+
const root = document.documentElement;
|
|
572
|
+
const t = this._theme;
|
|
573
|
+
if (t.primary)
|
|
574
|
+
root.style.setProperty("--calendar-primary-color", t.primary);
|
|
575
|
+
if (t.secondary)
|
|
576
|
+
root.style.setProperty("--calendar-secondary-color", t.secondary);
|
|
577
|
+
if (t.tertiary)
|
|
578
|
+
root.style.setProperty("--calendar-tertiary-color", t.tertiary);
|
|
579
|
+
if (t.textColor)
|
|
580
|
+
root.style.setProperty("--calendar-text-color", t.textColor);
|
|
581
|
+
if (t.textLight)
|
|
582
|
+
root.style.setProperty("--calendar-text-light", t.textLight);
|
|
583
|
+
if (t.background)
|
|
584
|
+
root.style.setProperty("--calendar-background", t.background);
|
|
585
|
+
if (t.cellHover)
|
|
586
|
+
root.style.setProperty("--calendar-cell-hover", t.cellHover);
|
|
587
|
+
if (t.borderColor)
|
|
588
|
+
root.style.setProperty("--calendar-border-color", t.borderColor);
|
|
589
|
+
if (t.todayOutline)
|
|
590
|
+
root.style.setProperty("--calendar-today-outline", t.todayOutline);
|
|
591
|
+
if (t.selectedBg)
|
|
592
|
+
root.style.setProperty("--calendar-selected-bg", t.selectedBg);
|
|
593
|
+
if (t.eventIndicator)
|
|
594
|
+
root.style.setProperty("--calendar-event-indicator", t.eventIndicator);
|
|
595
|
+
}
|
|
553
596
|
render() {
|
|
597
|
+
if (!this.engine) return;
|
|
554
598
|
const viewModel = this.engine.getViewModel();
|
|
599
|
+
const useShortMonths = this.hasAttribute("use-short-month-names");
|
|
600
|
+
const title = this.getAttribute("title");
|
|
601
|
+
const minYear = this.minYear;
|
|
602
|
+
const maxYear = this.maxYear;
|
|
603
|
+
const today = /* @__PURE__ */ new Date();
|
|
604
|
+
const todayMonth = today.getMonth();
|
|
605
|
+
const todayYear = today.getFullYear();
|
|
606
|
+
const isCurrentMonth = viewModel.currentYear === todayYear && viewModel.currentMonth === todayMonth;
|
|
607
|
+
const showScrollHint = viewModel.tasks.length > 3;
|
|
555
608
|
const defaultRenderEvent = (event) => {
|
|
556
609
|
const timeRange = formatTimeRange(event);
|
|
557
610
|
const attendeesList = formatAttendees(event.attendees);
|
|
@@ -597,46 +650,46 @@ var Kalendly = (() => {
|
|
|
597
650
|
${event.status && event.status !== "scheduled" ? `<span class="badge status-${event.status}">${getStatusLabel(event.status)}</span>` : ""}
|
|
598
651
|
</div>
|
|
599
652
|
</div>
|
|
600
|
-
|
|
653
|
+
|
|
601
654
|
${timeRange ? `
|
|
602
655
|
<div class="event-time">
|
|
603
656
|
<span class="event-time-label">Time:</span>
|
|
604
657
|
<span class="event-time-value">${timeRange}</span>
|
|
605
658
|
</div>
|
|
606
659
|
` : ""}
|
|
607
|
-
|
|
660
|
+
|
|
608
661
|
${event.description ? `
|
|
609
662
|
<div class="event-description">${event.description}</div>
|
|
610
663
|
` : ""}
|
|
611
|
-
|
|
664
|
+
|
|
612
665
|
${event.location ? `
|
|
613
666
|
<div class="event-time">
|
|
614
667
|
<span class="event-time-label">Location:</span>
|
|
615
668
|
<span class="event-time-value">${event.location}</span>
|
|
616
669
|
</div>
|
|
617
670
|
` : ""}
|
|
618
|
-
|
|
671
|
+
|
|
619
672
|
${attendeesList ? `
|
|
620
673
|
<div class="event-time">
|
|
621
674
|
<span class="event-time-label">Attendees:</span>
|
|
622
675
|
<span class="event-time-value">${attendeesList}</span>
|
|
623
676
|
</div>
|
|
624
677
|
` : ""}
|
|
625
|
-
|
|
678
|
+
|
|
626
679
|
${event.organizer ? `
|
|
627
680
|
<div class="event-time">
|
|
628
681
|
<span class="event-time-label">Organizer:</span>
|
|
629
682
|
<span class="event-time-value">${event.organizer}</span>
|
|
630
683
|
</div>
|
|
631
684
|
` : ""}
|
|
632
|
-
|
|
685
|
+
|
|
633
686
|
${event.notes ? `
|
|
634
687
|
<div class="event-time">
|
|
635
688
|
<span class="event-time-label">Notes:</span>
|
|
636
689
|
<span class="event-time-value">${event.notes}</span>
|
|
637
690
|
</div>
|
|
638
691
|
` : ""}
|
|
639
|
-
|
|
692
|
+
|
|
640
693
|
${event.url ? `
|
|
641
694
|
<div class="event-time">
|
|
642
695
|
<a href="${event.url}" target="_blank" rel="noopener noreferrer" class="event-link">
|
|
@@ -644,7 +697,7 @@ var Kalendly = (() => {
|
|
|
644
697
|
</a>
|
|
645
698
|
</div>
|
|
646
699
|
` : ""}
|
|
647
|
-
|
|
700
|
+
|
|
648
701
|
${event.tags && event.tags.length > 0 ? `
|
|
649
702
|
<div class="event-tags">
|
|
650
703
|
${event.tags.map((tag) => `<span class="event-tag">${tag}</span>`).join("")}
|
|
@@ -654,25 +707,17 @@ var Kalendly = (() => {
|
|
|
654
707
|
`;
|
|
655
708
|
};
|
|
656
709
|
const defaultRenderNoEvents = () => '<div class="no-events-message">No events scheduled for this day.</div>';
|
|
657
|
-
const renderEvent = this.
|
|
658
|
-
const renderNoEvents = this.
|
|
659
|
-
const showScrollHint = viewModel.tasks.length > 3;
|
|
660
|
-
const today = /* @__PURE__ */ new Date();
|
|
661
|
-
const todayMonth = today.getMonth();
|
|
662
|
-
const todayYear = today.getFullYear();
|
|
663
|
-
const minYear = this.props.minYear ?? todayYear - 30;
|
|
664
|
-
const maxYear = this.props.maxYear ?? todayYear + 10;
|
|
665
|
-
const isCurrentMonth = viewModel.currentYear === todayYear && viewModel.currentMonth === todayMonth;
|
|
710
|
+
const renderEvent = this._renderEvent || defaultRenderEvent;
|
|
711
|
+
const renderNoEvents = this._renderNoEvents || defaultRenderNoEvents;
|
|
666
712
|
const html = `
|
|
667
|
-
${
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
713
|
+
${title ? `
|
|
714
|
+
<div class="page--title">
|
|
715
|
+
<h1>${title}</h1>
|
|
716
|
+
</div>
|
|
671
717
|
` : ""}
|
|
672
718
|
|
|
673
719
|
<div class="calendar--content">
|
|
674
720
|
<div class="calendar--card">
|
|
675
|
-
<!-- Navigation Header -->
|
|
676
721
|
<div class="calendar--nav-header">
|
|
677
722
|
<button type="button" class="calendar--nav-arrow" data-action="previous" aria-label="Previous month">
|
|
678
723
|
‹
|
|
@@ -686,7 +731,7 @@ var Kalendly = (() => {
|
|
|
686
731
|
aria-expanded="${this.pickerOpen ? "true" : "false"}"
|
|
687
732
|
aria-haspopup="true"
|
|
688
733
|
>
|
|
689
|
-
${
|
|
734
|
+
${useShortMonths ? `${MONTHS[viewModel.currentMonth]} ${viewModel.currentYear}` : viewModel.monthAndYearText}
|
|
690
735
|
<span class="calendar--picker-chevron">▾</span>
|
|
691
736
|
</button>
|
|
692
737
|
|
|
@@ -717,7 +762,7 @@ var Kalendly = (() => {
|
|
|
717
762
|
</div>
|
|
718
763
|
|
|
719
764
|
<div class="calendar--picker-months">
|
|
720
|
-
${(
|
|
765
|
+
${(useShortMonths ? MONTHS : MONTHS_FULL).map((month, index) => {
|
|
721
766
|
const isSelected = index === viewModel.currentMonth;
|
|
722
767
|
const isCurrent = index === todayMonth && viewModel.currentYear === todayYear;
|
|
723
768
|
return `
|
|
@@ -790,233 +835,204 @@ var Kalendly = (() => {
|
|
|
790
835
|
` : ""}
|
|
791
836
|
|
|
792
837
|
<div class="events-container">
|
|
793
|
-
${viewModel.tasks.length > 0 ?
|
|
794
|
-
${viewModel.tasks.map((event) => renderEvent(event)).join("")}
|
|
795
|
-
` : renderNoEvents()}
|
|
838
|
+
${viewModel.tasks.length > 0 ? viewModel.tasks.map((event) => renderEvent(event)).join("") : renderNoEvents()}
|
|
796
839
|
</div>
|
|
797
840
|
</div>
|
|
798
841
|
` : ""}
|
|
799
842
|
</div>
|
|
800
843
|
</div>
|
|
801
844
|
`;
|
|
802
|
-
this.
|
|
845
|
+
this.innerHTML = html;
|
|
803
846
|
this.attachEventListeners();
|
|
804
847
|
}
|
|
805
848
|
attachEventListeners() {
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
const
|
|
809
|
-
const
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
const
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
})
|
|
824
|
-
);
|
|
825
|
-
}
|
|
826
|
-
});
|
|
827
|
-
}
|
|
828
|
-
const prevBtn = this.container.querySelector('[data-action="previous"]');
|
|
829
|
-
const nextBtn = this.container.querySelector('[data-action="next"]');
|
|
830
|
-
if (prevBtn) {
|
|
831
|
-
prevBtn.addEventListener("click", () => {
|
|
832
|
-
this.actions.previous();
|
|
833
|
-
this.dispatchMonthChange();
|
|
834
|
-
});
|
|
835
|
-
}
|
|
836
|
-
if (nextBtn) {
|
|
837
|
-
nextBtn.addEventListener("click", () => {
|
|
838
|
-
this.actions.next();
|
|
839
|
-
this.dispatchMonthChange();
|
|
840
|
-
});
|
|
841
|
-
}
|
|
842
|
-
const todayBtn = this.container.querySelector('[data-action="today"]');
|
|
843
|
-
if (todayBtn) {
|
|
844
|
-
todayBtn.addEventListener("click", () => {
|
|
845
|
-
this.actions.goToToday();
|
|
846
|
-
this.pickerOpen = false;
|
|
847
|
-
this.container.dispatchEvent(
|
|
848
|
-
new CustomEvent("monthChange", {
|
|
849
|
-
detail: { year: todayYear, month: todayMonth }
|
|
849
|
+
if (this.listenersAttached) return;
|
|
850
|
+
this.listenersAttached = true;
|
|
851
|
+
const minYear = this.minYear;
|
|
852
|
+
const maxYear = this.maxYear;
|
|
853
|
+
this.delegatedClickHandler = (e) => {
|
|
854
|
+
const target = e.target;
|
|
855
|
+
const cell = target.closest('td[data-clickable="true"]');
|
|
856
|
+
if (cell && cell.dataset.date) {
|
|
857
|
+
e.stopPropagation();
|
|
858
|
+
const date = new Date(cell.dataset.date);
|
|
859
|
+
const dayIndex = parseInt(cell.dataset.dayIndex || "0");
|
|
860
|
+
this.engine.handleDateClick(date, dayIndex);
|
|
861
|
+
this.dispatchEvent(
|
|
862
|
+
new CustomEvent("cal-date-select", {
|
|
863
|
+
bubbles: true,
|
|
864
|
+
composed: true,
|
|
865
|
+
detail: { date, events: this.engine.getEventsForDate(date) }
|
|
850
866
|
})
|
|
851
867
|
);
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
if (this.pickerOpen) {
|
|
862
|
-
this.yearInput = String(this.engine.getViewModel().currentYear);
|
|
863
|
-
this.yearInputValid = true;
|
|
864
|
-
}
|
|
865
|
-
this.render();
|
|
866
|
-
});
|
|
867
|
-
}
|
|
868
|
-
const yearPrevBtn = this.container.querySelector(
|
|
869
|
-
'[data-action="year-prev"]'
|
|
870
|
-
);
|
|
871
|
-
const yearNextBtn = this.container.querySelector(
|
|
872
|
-
'[data-action="year-next"]'
|
|
873
|
-
);
|
|
874
|
-
if (yearPrevBtn) {
|
|
875
|
-
yearPrevBtn.addEventListener("click", (e) => {
|
|
876
|
-
e.stopPropagation();
|
|
877
|
-
const vm = this.engine.getViewModel();
|
|
878
|
-
if (vm.currentYear > minYear) {
|
|
879
|
-
this.actions.jump(vm.currentYear - 1, vm.currentMonth);
|
|
880
|
-
this.yearInput = String(vm.currentYear - 1);
|
|
868
|
+
return;
|
|
869
|
+
}
|
|
870
|
+
const actionEl = target.closest("[data-action]");
|
|
871
|
+
if (!actionEl) return;
|
|
872
|
+
const action = actionEl.dataset.action;
|
|
873
|
+
e.stopPropagation();
|
|
874
|
+
switch (action) {
|
|
875
|
+
case "previous":
|
|
876
|
+
this.actions.previous();
|
|
881
877
|
this.dispatchMonthChange();
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
if (yearNextBtn) {
|
|
886
|
-
yearNextBtn.addEventListener("click", (e) => {
|
|
887
|
-
e.stopPropagation();
|
|
888
|
-
const vm = this.engine.getViewModel();
|
|
889
|
-
if (vm.currentYear < maxYear) {
|
|
890
|
-
this.actions.jump(vm.currentYear + 1, vm.currentMonth);
|
|
891
|
-
this.yearInput = String(vm.currentYear + 1);
|
|
878
|
+
break;
|
|
879
|
+
case "next":
|
|
880
|
+
this.actions.next();
|
|
892
881
|
this.dispatchMonthChange();
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
const year = parseInt(value, 10);
|
|
906
|
-
this.yearInputValid = value === "" || year >= minYear && year <= maxYear;
|
|
882
|
+
break;
|
|
883
|
+
case "today":
|
|
884
|
+
this.actions.goToToday();
|
|
885
|
+
this.pickerOpen = false;
|
|
886
|
+
this.dispatchMonthChange();
|
|
887
|
+
break;
|
|
888
|
+
case "toggle-picker":
|
|
889
|
+
this.pickerOpen = !this.pickerOpen;
|
|
890
|
+
if (this.pickerOpen) {
|
|
891
|
+
this.yearInput = String(this.engine.getViewModel().currentYear);
|
|
892
|
+
this.yearInputValid = true;
|
|
893
|
+
}
|
|
907
894
|
this.render();
|
|
895
|
+
break;
|
|
896
|
+
case "year-prev": {
|
|
897
|
+
const vm = this.engine.getViewModel();
|
|
898
|
+
if (vm.currentYear > minYear) {
|
|
899
|
+
const newYear = vm.currentYear - 1;
|
|
900
|
+
this.yearInput = String(newYear);
|
|
901
|
+
this.updatePickerYear(newYear);
|
|
902
|
+
this.actions.jump(newYear, vm.currentMonth);
|
|
903
|
+
this.dispatchMonthChange();
|
|
904
|
+
}
|
|
905
|
+
break;
|
|
908
906
|
}
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
this.dispatchMonthChange();
|
|
907
|
+
case "year-next": {
|
|
908
|
+
const vm = this.engine.getViewModel();
|
|
909
|
+
if (vm.currentYear < maxYear) {
|
|
910
|
+
const newYear = vm.currentYear + 1;
|
|
911
|
+
this.yearInput = String(newYear);
|
|
912
|
+
this.updatePickerYear(newYear);
|
|
913
|
+
this.actions.jump(newYear, vm.currentMonth);
|
|
914
|
+
this.dispatchMonthChange();
|
|
915
|
+
}
|
|
916
|
+
break;
|
|
920
917
|
}
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
918
|
+
case "select-month": {
|
|
919
|
+
const month = parseInt(actionEl.dataset.month || "0", 10);
|
|
920
|
+
this.actions.jump(this.engine.getViewModel().currentYear, month);
|
|
921
|
+
this.pickerOpen = false;
|
|
922
|
+
this.dispatchMonthChange();
|
|
923
|
+
break;
|
|
926
924
|
}
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
this.
|
|
925
|
+
case "close-popup":
|
|
926
|
+
this.engine.clearSelection();
|
|
927
|
+
break;
|
|
928
|
+
}
|
|
929
|
+
};
|
|
930
|
+
this.delegatedInputHandler = (e) => {
|
|
931
|
+
const target = e.target;
|
|
932
|
+
if (!target.matches("[data-year-input]")) return;
|
|
933
|
+
const value = target.value;
|
|
934
|
+
if (value === "" || /^\d+$/.test(value)) {
|
|
935
|
+
this.yearInput = value;
|
|
936
|
+
const year = parseInt(value, 10);
|
|
937
|
+
this.yearInputValid = value === "" || year >= minYear && year <= maxYear;
|
|
938
|
+
target.classList.toggle("invalid", !this.yearInputValid);
|
|
939
|
+
}
|
|
940
|
+
};
|
|
941
|
+
this.delegatedBlurHandler = (e) => {
|
|
942
|
+
const target = e.target;
|
|
943
|
+
if (!target.matches("[data-year-input]")) return;
|
|
944
|
+
const year = parseInt(this.yearInput, 10);
|
|
945
|
+
const vm = this.engine.getViewModel();
|
|
946
|
+
if (isNaN(year) || year < minYear || year > maxYear) {
|
|
947
|
+
this.yearInput = String(vm.currentYear);
|
|
948
|
+
this.yearInputValid = true;
|
|
949
|
+
target.value = this.yearInput;
|
|
950
|
+
target.classList.remove("invalid");
|
|
951
|
+
} else if (year !== vm.currentYear) {
|
|
952
|
+
this.actions.jump(year, vm.currentMonth);
|
|
938
953
|
this.dispatchMonthChange();
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
if (this.clickOutsideHandler) {
|
|
951
|
-
document.removeEventListener("click", this.clickOutsideHandler);
|
|
952
|
-
}
|
|
954
|
+
}
|
|
955
|
+
};
|
|
956
|
+
this.delegatedKeydownHandler = (e) => {
|
|
957
|
+
const target = e.target;
|
|
958
|
+
if (!target.matches("[data-year-input]")) return;
|
|
959
|
+
if (e.key === "Enter") target.blur();
|
|
960
|
+
};
|
|
961
|
+
this.addEventListener("click", this.delegatedClickHandler);
|
|
962
|
+
this.addEventListener("input", this.delegatedInputHandler);
|
|
963
|
+
this.addEventListener("blur", this.delegatedBlurHandler, true);
|
|
964
|
+
this.addEventListener("keydown", this.delegatedKeydownHandler);
|
|
953
965
|
this.clickOutsideHandler = (e) => {
|
|
954
966
|
const target = e.target;
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
);
|
|
958
|
-
if (pickerBtn2 && (target === pickerBtn2 || pickerBtn2.contains(target))) {
|
|
959
|
-
return;
|
|
960
|
-
}
|
|
961
|
-
const pickerContainer = this.container.querySelector(
|
|
962
|
-
"[data-picker-container]"
|
|
963
|
-
);
|
|
964
|
-
if (this.pickerOpen && pickerContainer && !pickerContainer.contains(target)) {
|
|
967
|
+
if (this.contains(target)) return;
|
|
968
|
+
if (this.pickerOpen) {
|
|
965
969
|
this.pickerOpen = false;
|
|
966
970
|
this.render();
|
|
967
971
|
return;
|
|
968
972
|
}
|
|
969
|
-
const popup = this.
|
|
970
|
-
if (popup
|
|
973
|
+
const popup = this.querySelector(".date-popup");
|
|
974
|
+
if (popup) {
|
|
971
975
|
this.engine.clearSelection();
|
|
972
976
|
}
|
|
973
977
|
};
|
|
974
978
|
document.addEventListener("click", this.clickOutsideHandler);
|
|
975
979
|
}
|
|
980
|
+
updatePickerYear(year) {
|
|
981
|
+
const input = this.querySelector("[data-year-input]");
|
|
982
|
+
if (input) input.value = String(year);
|
|
983
|
+
const prevBtn = this.querySelector(
|
|
984
|
+
'[data-action="year-prev"]'
|
|
985
|
+
);
|
|
986
|
+
const nextBtn = this.querySelector(
|
|
987
|
+
'[data-action="year-next"]'
|
|
988
|
+
);
|
|
989
|
+
if (prevBtn) prevBtn.disabled = year <= this.minYear;
|
|
990
|
+
if (nextBtn) nextBtn.disabled = year >= this.maxYear;
|
|
991
|
+
}
|
|
976
992
|
dispatchMonthChange() {
|
|
993
|
+
if (!this.engine) return;
|
|
977
994
|
const vm = this.engine.getViewModel();
|
|
978
|
-
this.
|
|
979
|
-
new CustomEvent("
|
|
995
|
+
this.dispatchEvent(
|
|
996
|
+
new CustomEvent("cal-month-change", {
|
|
997
|
+
bubbles: true,
|
|
998
|
+
composed: true,
|
|
980
999
|
detail: { year: vm.currentYear, month: vm.currentMonth }
|
|
981
1000
|
})
|
|
982
1001
|
);
|
|
983
1002
|
}
|
|
1003
|
+
// Public API
|
|
984
1004
|
updateEvents(events) {
|
|
985
|
-
this.
|
|
1005
|
+
this.events = events;
|
|
986
1006
|
}
|
|
987
1007
|
updateTheme(theme) {
|
|
988
|
-
this.
|
|
989
|
-
this.applyTheme();
|
|
1008
|
+
this.theme = theme;
|
|
990
1009
|
}
|
|
991
1010
|
getCurrentDate() {
|
|
992
|
-
return this.engine
|
|
1011
|
+
return this.engine?.getViewModel().selectedDate ?? null;
|
|
993
1012
|
}
|
|
994
1013
|
goToDate(date) {
|
|
995
|
-
this.actions
|
|
1014
|
+
this.actions?.jump(date.getFullYear(), date.getMonth());
|
|
996
1015
|
}
|
|
997
1016
|
getEngine() {
|
|
1017
|
+
if (!this.engine)
|
|
1018
|
+
throw new Error("CalendarElement is not connected to the DOM");
|
|
998
1019
|
return this.engine;
|
|
999
1020
|
}
|
|
1000
|
-
destroy() {
|
|
1001
|
-
if (this.unsubscribe) {
|
|
1002
|
-
this.unsubscribe();
|
|
1003
|
-
this.unsubscribe = null;
|
|
1004
|
-
}
|
|
1005
|
-
if (this.clickOutsideHandler) {
|
|
1006
|
-
document.removeEventListener("click", this.clickOutsideHandler);
|
|
1007
|
-
this.clickOutsideHandler = null;
|
|
1008
|
-
}
|
|
1009
|
-
this.engine.destroy();
|
|
1010
|
-
this.container.innerHTML = "";
|
|
1011
|
-
this.container.classList.remove("kalendly-calendar");
|
|
1012
|
-
if (this.props.className) {
|
|
1013
|
-
this.container.classList.remove(this.props.className);
|
|
1014
|
-
}
|
|
1015
|
-
}
|
|
1016
1021
|
};
|
|
1017
|
-
|
|
1018
|
-
|
|
1022
|
+
CalendarElement.observedAttributes = [
|
|
1023
|
+
"initial-date",
|
|
1024
|
+
"min-year",
|
|
1025
|
+
"max-year",
|
|
1026
|
+
"week-starts-on",
|
|
1027
|
+
"title",
|
|
1028
|
+
"use-short-month-names"
|
|
1029
|
+
];
|
|
1030
|
+
function defineCalendarElement(tagName = "kal-calendar") {
|
|
1031
|
+
if (typeof customElements !== "undefined" && !customElements.get(tagName)) {
|
|
1032
|
+
customElements.define(tagName, CalendarElement);
|
|
1033
|
+
}
|
|
1019
1034
|
}
|
|
1020
|
-
return __toCommonJS(
|
|
1035
|
+
return __toCommonJS(CalendarElement_exports);
|
|
1021
1036
|
})();
|
|
1037
|
+
if (typeof customElements !== 'undefined' && !customElements.get('kal-calendar')) { customElements.define('kal-calendar', Kalendly.CalendarElement); }
|
|
1022
1038
|
//# sourceMappingURL=index.umd.js.map
|