kalendly 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +155 -20
- package/dist/core/index.d.mts +16 -2
- package/dist/core/index.d.ts +16 -2
- package/dist/core/index.js +153 -5
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +142 -5
- package/dist/core/index.mjs.map +1 -1
- package/dist/index.d.mts +24 -2
- package/dist/index.d.ts +24 -2
- package/dist/index.js +297 -31
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +286 -31
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +274 -30
- package/dist/index.umd.js.map +1 -1
- package/dist/styles/calendar.css +33 -1
- package/package.json +1 -1
package/dist/index.umd.js
CHANGED
|
@@ -78,12 +78,76 @@ var Kalendly = (() => {
|
|
|
78
78
|
const max = maxYear ?? currentYear + 10;
|
|
79
79
|
return Array.from({ length: max - min + 1 }, (_, i) => min + i);
|
|
80
80
|
}
|
|
81
|
-
function
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
function parseHourRanges(value, slotDuration) {
|
|
82
|
+
const parts = value.split(",").map((part) => part.trim()).filter(Boolean);
|
|
83
|
+
if (parts.length === 0) {
|
|
84
|
+
throw new Error(
|
|
85
|
+
`<kal-calendar> available-hours is empty. Omit the attribute to allow every hour, or name at least one HH:MM-HH:MM range.`
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
const ranges = parts.map((part) => {
|
|
89
|
+
const halves = part.split("-");
|
|
90
|
+
if (halves.length !== 2) {
|
|
91
|
+
throw new Error(
|
|
92
|
+
`<kal-calendar> available-hours range "${part}" is not HH:MM-HH:MM.`
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
const [start, end] = halves.map((half) => parseTimeToMinutes(half.trim()));
|
|
96
|
+
if (start === null || end === null) {
|
|
97
|
+
throw new Error(
|
|
98
|
+
`<kal-calendar> available-hours range "${part}" has an unreadable time. Use 24-hour HH:MM.`
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
if (start >= end) {
|
|
102
|
+
throw new Error(
|
|
103
|
+
`<kal-calendar> available-hours range "${part}" starts at or after it ends.`
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
if (start % slotDuration !== 0 || end % slotDuration !== 0) {
|
|
107
|
+
throw new Error(
|
|
108
|
+
`<kal-calendar> available-hours range "${part}" does not land on a ${slotDuration}-minute slot boundary.`
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
return [start, end];
|
|
86
112
|
});
|
|
113
|
+
if (mergeIntervals(ranges).length !== ranges.length) {
|
|
114
|
+
throw new Error(
|
|
115
|
+
`<kal-calendar> available-hours ranges overlap or touch: "${value}". Write each bookable window once.`
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
return ranges;
|
|
119
|
+
}
|
|
120
|
+
function isDateWithinWindow(date, min, max) {
|
|
121
|
+
const target = normalizeDate(date).getTime();
|
|
122
|
+
if (min && target < normalizeDate(min).getTime()) return false;
|
|
123
|
+
if (max && target > normalizeDate(max).getTime()) return false;
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
function isDayAllowed(date, days) {
|
|
127
|
+
return days === null || days.includes(date.getDay());
|
|
128
|
+
}
|
|
129
|
+
function eventCoversDate(event, date) {
|
|
130
|
+
const start = normalizeDate(new Date(event.date)).getTime();
|
|
131
|
+
const target = normalizeDate(date).getTime();
|
|
132
|
+
if (Number.isNaN(start)) return false;
|
|
133
|
+
if (event.endDate === void 0 || event.endDate === null) {
|
|
134
|
+
return start === target;
|
|
135
|
+
}
|
|
136
|
+
const end = normalizeDate(new Date(event.endDate)).getTime();
|
|
137
|
+
if (Number.isNaN(end)) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
`<kal-calendar> event ${event.id} has an unreadable endDate: ${String(event.endDate)}.`
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
if (end < start) {
|
|
143
|
+
throw new Error(
|
|
144
|
+
`<kal-calendar> event ${event.id} has an endDate before its date: ${String(event.endDate)} < ${String(event.date)}.`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
return target >= start && target <= end;
|
|
148
|
+
}
|
|
149
|
+
function getEventsForDate(events, date) {
|
|
150
|
+
return events.filter((event) => eventCoversDate(event, date));
|
|
87
151
|
}
|
|
88
152
|
function generateCalendarDates(year, month, events = [], weekStartsOn = 0) {
|
|
89
153
|
const firstDay = new Date(year, month, 1);
|
|
@@ -222,6 +286,68 @@ var Kalendly = (() => {
|
|
|
222
286
|
const trimmed = String(value).trim();
|
|
223
287
|
return isValidHexColor(trimmed) || /^[a-z]+$/i.test(trimmed) ? trimmed : "#3b82f6";
|
|
224
288
|
}
|
|
289
|
+
var MINUTES_PER_DAY = 1440;
|
|
290
|
+
var DEFAULT_SLOT_DURATION = 60;
|
|
291
|
+
function parseTimeToMinutes(time) {
|
|
292
|
+
if (typeof time !== "string") return null;
|
|
293
|
+
const match = /^(\d{1,2}):(\d{2})$/.exec(time.trim());
|
|
294
|
+
if (!match) return null;
|
|
295
|
+
const hours = Number(match[1]);
|
|
296
|
+
const mins = Number(match[2]);
|
|
297
|
+
if (hours > 24 || mins > 59 || hours === 24 && mins > 0) return null;
|
|
298
|
+
return hours * 60 + mins;
|
|
299
|
+
}
|
|
300
|
+
function formatMinutes(total) {
|
|
301
|
+
const hours = Math.floor(total / 60);
|
|
302
|
+
const mins = total % 60;
|
|
303
|
+
return `${String(hours).padStart(2, "0")}:${String(mins).padStart(2, "0")}`;
|
|
304
|
+
}
|
|
305
|
+
function eventInterval(event, slotDuration, onDay) {
|
|
306
|
+
const day = normalizeDate(onDay).getTime();
|
|
307
|
+
if (Number.isNaN(day)) return null;
|
|
308
|
+
const base = day / 6e4;
|
|
309
|
+
const wholeDay = [base, base + MINUTES_PER_DAY];
|
|
310
|
+
if (event.allDay || !event.startTime) return wholeDay;
|
|
311
|
+
const from = parseTimeToMinutes(event.startTime);
|
|
312
|
+
if (from === null) return wholeDay;
|
|
313
|
+
if (event.endTime === void 0 || event.endTime === null) {
|
|
314
|
+
return [base + from, base + from + slotDuration];
|
|
315
|
+
}
|
|
316
|
+
const to = parseTimeToMinutes(event.endTime);
|
|
317
|
+
if (to === null) return wholeDay;
|
|
318
|
+
return [base + from, base + (to <= from ? to + MINUTES_PER_DAY : to)];
|
|
319
|
+
}
|
|
320
|
+
function mergeIntervals(intervals) {
|
|
321
|
+
const sorted = [...intervals].sort((a, b) => a[0] - b[0]);
|
|
322
|
+
return sorted.reduce((merged, [start, end]) => {
|
|
323
|
+
const last = merged[merged.length - 1];
|
|
324
|
+
if (last && start <= last[1]) last[1] = Math.max(last[1], end);
|
|
325
|
+
else merged.push([start, end]);
|
|
326
|
+
return merged;
|
|
327
|
+
}, []);
|
|
328
|
+
}
|
|
329
|
+
function bookedSlots(events, date, slotDuration = DEFAULT_SLOT_DURATION) {
|
|
330
|
+
const base = normalizeDate(date).getTime() / 6e4;
|
|
331
|
+
const previousDay = new Date(date);
|
|
332
|
+
previousDay.setDate(previousDay.getDate() - 1);
|
|
333
|
+
const intervals = [];
|
|
334
|
+
for (const event of new Set(events)) {
|
|
335
|
+
for (const day of [previousDay, date]) {
|
|
336
|
+
if (!eventCoversDate(event, day)) continue;
|
|
337
|
+
const interval = eventInterval(event, slotDuration, day);
|
|
338
|
+
if (interval) intervals.push(interval);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
const merged = mergeIntervals(intervals);
|
|
342
|
+
return Array.from(
|
|
343
|
+
{ length: Math.floor(MINUTES_PER_DAY / slotDuration) },
|
|
344
|
+
(_, index) => {
|
|
345
|
+
const start = base + index * slotDuration;
|
|
346
|
+
const end = start + slotDuration;
|
|
347
|
+
return merged.some(([from, to]) => start < to && end > from);
|
|
348
|
+
}
|
|
349
|
+
);
|
|
350
|
+
}
|
|
225
351
|
|
|
226
352
|
// src/core/calendar-engine.ts
|
|
227
353
|
var CalendarEngine = class {
|
|
@@ -600,6 +726,29 @@ var Kalendly = (() => {
|
|
|
600
726
|
}
|
|
601
727
|
return title;
|
|
602
728
|
}
|
|
729
|
+
get slotDuration() {
|
|
730
|
+
const raw = this.getAttribute("slot-duration");
|
|
731
|
+
if (raw === null) return DEFAULT_SLOT_DURATION;
|
|
732
|
+
const minutes = Number(raw);
|
|
733
|
+
if (Number.isInteger(minutes) && minutes > 0 && MINUTES_PER_DAY % minutes === 0) {
|
|
734
|
+
return minutes;
|
|
735
|
+
}
|
|
736
|
+
console.warn(
|
|
737
|
+
`<kal-calendar> slot-duration="${raw}" must be a positive whole number of minutes that divides ${MINUTES_PER_DAY} \u2014 falling back to ${DEFAULT_SLOT_DURATION}.`
|
|
738
|
+
);
|
|
739
|
+
return DEFAULT_SLOT_DURATION;
|
|
740
|
+
}
|
|
741
|
+
warnMissingEndTime(events) {
|
|
742
|
+
for (const event of events) {
|
|
743
|
+
if (!event.startTime || event.endTime) continue;
|
|
744
|
+
const key = String(event.id);
|
|
745
|
+
if (_CalendarElement.warnedMissingEnd.has(key)) continue;
|
|
746
|
+
_CalendarElement.warnedMissingEnd.add(key);
|
|
747
|
+
console.warn(
|
|
748
|
+
`<kal-calendar> event ${key} has startTime but no endTime \u2014 occupying one ${this.slotDuration}-minute slot. Send an endTime to say how long it runs.`
|
|
749
|
+
);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
603
752
|
get monthCount() {
|
|
604
753
|
const requested = Number(this.getAttribute("months") ?? 1);
|
|
605
754
|
if (!Number.isInteger(requested) || requested < 1) return 1;
|
|
@@ -613,6 +762,41 @@ var Kalendly = (() => {
|
|
|
613
762
|
const val = this.getAttribute("max-year");
|
|
614
763
|
return val ? parseInt(val, 10) : (/* @__PURE__ */ new Date()).getFullYear() + 10;
|
|
615
764
|
}
|
|
765
|
+
boundaryDate(attr) {
|
|
766
|
+
const val = this.getAttribute(attr);
|
|
767
|
+
if (!val) return null;
|
|
768
|
+
const parsed = new Date(val);
|
|
769
|
+
if (Number.isNaN(parsed.getTime())) {
|
|
770
|
+
throw new Error(
|
|
771
|
+
`<kal-calendar> ${attr} is unreadable: "${val}". Use a value Date can parse, the same as initial-date.`
|
|
772
|
+
);
|
|
773
|
+
}
|
|
774
|
+
return parsed;
|
|
775
|
+
}
|
|
776
|
+
get availableDays() {
|
|
777
|
+
const val = this.getAttribute("available-days");
|
|
778
|
+
if (val === null) return null;
|
|
779
|
+
const parts = val.split(",").map((part) => part.trim()).filter(Boolean);
|
|
780
|
+
if (parts.length === 0) {
|
|
781
|
+
throw new Error(
|
|
782
|
+
`<kal-calendar> available-days is empty. Omit the attribute to allow every day, or name at least one weekday.`
|
|
783
|
+
);
|
|
784
|
+
}
|
|
785
|
+
return parts.map((part) => {
|
|
786
|
+
const day = Number(part);
|
|
787
|
+
if (!Number.isInteger(day) || day < 0 || day > 6) {
|
|
788
|
+
throw new Error(
|
|
789
|
+
`<kal-calendar> available-days must list integers 0-6, 0 = Sunday. Got "${part}".`
|
|
790
|
+
);
|
|
791
|
+
}
|
|
792
|
+
return day;
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
get availableHours() {
|
|
796
|
+
const val = this.getAttribute("available-hours");
|
|
797
|
+
if (val === null) return null;
|
|
798
|
+
return parseHourRanges(val, this.slotDuration);
|
|
799
|
+
}
|
|
616
800
|
initEngine() {
|
|
617
801
|
const initialDateAttr = this.getAttribute("initial-date");
|
|
618
802
|
const initialDate = initialDateAttr ? new Date(initialDateAttr) : void 0;
|
|
@@ -731,8 +915,26 @@ var Kalendly = (() => {
|
|
|
731
915
|
if (declared.size === 0) return "open";
|
|
732
916
|
return this.knownBuckets.find((bucket) => declared.has(bucket));
|
|
733
917
|
}
|
|
918
|
+
assertHorizonOrdered() {
|
|
919
|
+
const min = this.boundaryDate("min-date");
|
|
920
|
+
const max = this.boundaryDate("max-date");
|
|
921
|
+
if (min && max && min.getTime() > max.getTime()) {
|
|
922
|
+
throw new Error(
|
|
923
|
+
`<kal-calendar> min-date is after max-date: "${this.getAttribute("min-date")}" > "${this.getAttribute("max-date")}".`
|
|
924
|
+
);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
// Whether the vendor offers this day at all, before any event is considered.
|
|
928
|
+
isDateOffered(date) {
|
|
929
|
+
return isDateWithinWindow(
|
|
930
|
+
date,
|
|
931
|
+
this.boundaryDate("min-date"),
|
|
932
|
+
this.boundaryDate("max-date")
|
|
933
|
+
) && isDayAllowed(date, this.availableDays);
|
|
934
|
+
}
|
|
734
935
|
isDateSelectable(date) {
|
|
735
936
|
if (!this.engine) return false;
|
|
937
|
+
if (!this.isDateOffered(date)) return false;
|
|
736
938
|
if (this._selectableStatuses) {
|
|
737
939
|
return this._selectableStatuses.includes(this.resolveBucket(date));
|
|
738
940
|
}
|
|
@@ -752,6 +954,11 @@ var Kalendly = (() => {
|
|
|
752
954
|
this.assertStatusesDeclared();
|
|
753
955
|
this.assertStatusesKnown();
|
|
754
956
|
}
|
|
957
|
+
this.boundaryDate("min-date");
|
|
958
|
+
this.boundaryDate("max-date");
|
|
959
|
+
void this.availableDays;
|
|
960
|
+
void this.availableHours;
|
|
961
|
+
this.assertHorizonOrdered();
|
|
755
962
|
const today = /* @__PURE__ */ new Date();
|
|
756
963
|
const todayMonth = today.getMonth();
|
|
757
964
|
const todayYear = today.getFullYear();
|
|
@@ -795,7 +1002,7 @@ var Kalendly = (() => {
|
|
|
795
1002
|
return `
|
|
796
1003
|
<div class="event-card" style="border-left-color: ${borderColor}">
|
|
797
1004
|
<div class="event-header">
|
|
798
|
-
|
|
1005
|
+
${event.name ? `<div class="event-title">${escapeHtml(event.name)}</div>` : ""}
|
|
799
1006
|
<div class="event-badges">
|
|
800
1007
|
${event.category ? `<span class="badge category category-${slugifyToken(event.category)}">${escapeHtml(getCategoryLabel(event.category))}</span>` : ""}
|
|
801
1008
|
${event.priority ? `<span class="badge priority priority-${slugifyToken(event.priority)}">${escapeHtml(getPriorityLabel(event.priority))}</span>` : ""}
|
|
@@ -861,42 +1068,45 @@ var Kalendly = (() => {
|
|
|
861
1068
|
const defaultRenderNoEvents = () => '<div class="no-events-message">No events scheduled for this day.</div>';
|
|
862
1069
|
const renderEvent = this._renderEvent || defaultRenderEvent;
|
|
863
1070
|
const renderNoEvents = this._renderNoEvents || defaultRenderNoEvents;
|
|
864
|
-
const renderTimeGrid = (
|
|
865
|
-
const
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
const startTime =
|
|
879
|
-
const endTime =
|
|
880
|
-
const
|
|
881
|
-
const inTimeRange = !
|
|
1071
|
+
const renderTimeGrid = (date) => {
|
|
1072
|
+
const slotDuration = this.slotDuration;
|
|
1073
|
+
const previousDay = new Date(date);
|
|
1074
|
+
previousDay.setDate(previousDay.getDate() - 1);
|
|
1075
|
+
const events = [
|
|
1076
|
+
...this.engine.getEventsForDate(previousDay),
|
|
1077
|
+
...this.engine.getEventsForDate(date)
|
|
1078
|
+
];
|
|
1079
|
+
this.warnMissingEndTime(events);
|
|
1080
|
+
const booked = bookedSlots(events, date, slotDuration);
|
|
1081
|
+
const hours = this.availableHours;
|
|
1082
|
+
const slots = booked.map((isBooked, index) => {
|
|
1083
|
+
const slotStart = index * slotDuration;
|
|
1084
|
+
const slotEnd = slotStart + slotDuration;
|
|
1085
|
+
const startTime = formatMinutes(slotStart);
|
|
1086
|
+
const endTime = formatMinutes(slotEnd);
|
|
1087
|
+
const offered = hours === null || hours.some(([from, to]) => slotStart >= from && slotEnd <= to);
|
|
1088
|
+
const inTimeRange = offered && !isBooked && selectable && this._timeRangeStart !== null && this._timeRangeEnd !== null && isSameDay2(this._timeRangeDate, date) && startTime >= this._timeRangeStart && endTime <= this._timeRangeEnd;
|
|
882
1089
|
const isRangeStart = inTimeRange && startTime === this._timeRangeStart;
|
|
883
1090
|
const isRangeEnd = inTimeRange && endTime === this._timeRangeEnd;
|
|
884
1091
|
const isInRange = inTimeRange && !isRangeStart && !isRangeEnd;
|
|
885
1092
|
const slotClasses = [
|
|
886
1093
|
"time-grid-slot",
|
|
887
|
-
|
|
1094
|
+
offered ? "" : "time-grid-slot-out-of-range",
|
|
1095
|
+
isBooked ? "time-grid-slot-blocked" : "time-grid-slot-open",
|
|
888
1096
|
isRangeStart ? "time-grid-slot-range-start" : "",
|
|
889
1097
|
isRangeEnd ? "time-grid-slot-range-end" : "",
|
|
890
1098
|
isInRange ? "time-grid-slot-in-range" : ""
|
|
891
1099
|
].filter(Boolean).join(" ");
|
|
892
|
-
const slotAttrs =
|
|
1100
|
+
const slotAttrs = `${offered ? 'data-action="select-slot" ' : ""}data-start-time="${startTime}" data-end-time="${endTime}" data-date="${date.toISOString()}" data-booked="${isBooked}"`;
|
|
1101
|
+
const status = !offered ? "Closed" : isBooked ? "Booked" : "Available";
|
|
893
1102
|
return `
|
|
894
1103
|
<div class="${slotClasses}" ${slotAttrs}>
|
|
895
1104
|
<span class="time-grid-label">${startTime}</span>
|
|
896
|
-
<span class="time-grid-status">${
|
|
1105
|
+
<span class="time-grid-status">${status}</span>
|
|
897
1106
|
</div>`;
|
|
898
1107
|
});
|
|
899
|
-
|
|
1108
|
+
const gridClasses = selectable ? "time-grid time-grid-selectable" : "time-grid";
|
|
1109
|
+
return `<div class="${gridClasses}">${slots.join("")}</div>`;
|
|
900
1110
|
};
|
|
901
1111
|
const multiMonth = viewModel.panes.length > 1;
|
|
902
1112
|
const renderPane = (pane) => `
|
|
@@ -921,6 +1131,12 @@ var Kalendly = (() => {
|
|
|
921
1131
|
${week.map((calendarDate, dayIndex) => {
|
|
922
1132
|
const classes = getCellClasses(calendarDate);
|
|
923
1133
|
const cellAttrs = [];
|
|
1134
|
+
if (viewModel.selectedDate && isSameDay2(
|
|
1135
|
+
calendarDate.date,
|
|
1136
|
+
viewModel.selectedDate
|
|
1137
|
+
)) {
|
|
1138
|
+
classes.push("calendar-cell-selected");
|
|
1139
|
+
}
|
|
924
1140
|
if (availabilityMode && calendarDate.isCurrentMonth) {
|
|
925
1141
|
const bucket = this.resolveBucket(
|
|
926
1142
|
calendarDate.date
|
|
@@ -954,12 +1170,18 @@ var Kalendly = (() => {
|
|
|
954
1170
|
}
|
|
955
1171
|
}
|
|
956
1172
|
const dateString = calendarDate.date.toISOString();
|
|
1173
|
+
const offered = this.isDateOffered(
|
|
1174
|
+
calendarDate.date
|
|
1175
|
+
);
|
|
1176
|
+
if (!offered) {
|
|
1177
|
+
classes.push("calendar-cell-out-of-range");
|
|
1178
|
+
}
|
|
957
1179
|
return `
|
|
958
1180
|
<td
|
|
959
1181
|
class="${classes.join(" ")}"
|
|
960
1182
|
data-date="${dateString}"
|
|
961
1183
|
data-day-index="${dayIndex}"
|
|
962
|
-
data-clickable="true"
|
|
1184
|
+
${offered ? 'data-clickable="true"' : ""}
|
|
963
1185
|
${cellAttrs.join(" ")}
|
|
964
1186
|
>
|
|
965
1187
|
${calendarDate.date.getDate()}
|
|
@@ -1073,7 +1295,7 @@ var Kalendly = (() => {
|
|
|
1073
1295
|
` : ""}
|
|
1074
1296
|
|
|
1075
1297
|
<div class="events-container">
|
|
1076
|
-
${availabilityMode === "time" ? renderTimeGrid(viewModel.
|
|
1298
|
+
${availabilityMode === "time" ? renderTimeGrid(viewModel.selectedDate) : viewModel.tasks.length > 0 ? viewModel.tasks.map((event) => renderEvent(event)).join("") : renderNoEvents()}
|
|
1077
1299
|
</div>
|
|
1078
1300
|
</div>
|
|
1079
1301
|
` : ""}
|
|
@@ -1234,6 +1456,20 @@ var Kalendly = (() => {
|
|
|
1234
1456
|
const slotStart = actionEl.dataset.startTime;
|
|
1235
1457
|
const slotEnd = actionEl.dataset.endTime;
|
|
1236
1458
|
const slotDate = new Date(actionEl.dataset.date);
|
|
1459
|
+
const slotBooked = actionEl.dataset.booked === "true";
|
|
1460
|
+
this.dispatchEvent(
|
|
1461
|
+
new CustomEvent("cal-slot-select", {
|
|
1462
|
+
bubbles: true,
|
|
1463
|
+
composed: true,
|
|
1464
|
+
detail: {
|
|
1465
|
+
date: slotDate,
|
|
1466
|
+
startTime: slotStart,
|
|
1467
|
+
endTime: slotEnd,
|
|
1468
|
+
booked: slotBooked
|
|
1469
|
+
}
|
|
1470
|
+
})
|
|
1471
|
+
);
|
|
1472
|
+
if (slotBooked || !this.hasAttribute("selectable")) break;
|
|
1237
1473
|
if (this._timeRangeComplete) {
|
|
1238
1474
|
this._timeRangeDate = slotDate;
|
|
1239
1475
|
this._timeRangeStart = slotStart;
|
|
@@ -1371,9 +1607,14 @@ var Kalendly = (() => {
|
|
|
1371
1607
|
"initial-date",
|
|
1372
1608
|
"min-year",
|
|
1373
1609
|
"max-year",
|
|
1610
|
+
"min-date",
|
|
1611
|
+
"max-date",
|
|
1612
|
+
"available-days",
|
|
1613
|
+
"available-hours",
|
|
1374
1614
|
"week-starts-on",
|
|
1375
1615
|
"heading",
|
|
1376
1616
|
"months",
|
|
1617
|
+
"slot-duration",
|
|
1377
1618
|
"title",
|
|
1378
1619
|
"use-short-month-names",
|
|
1379
1620
|
"availability-mode",
|
|
@@ -1391,6 +1632,8 @@ var Kalendly = (() => {
|
|
|
1391
1632
|
borderColor: "--calendar-border-color",
|
|
1392
1633
|
todayOutline: "--calendar-today-outline",
|
|
1393
1634
|
selectedBg: "--calendar-selected-bg",
|
|
1635
|
+
outOfRangeBg: "--calendar-out-of-range-bg",
|
|
1636
|
+
outOfRangeFg: "--calendar-out-of-range-fg",
|
|
1394
1637
|
headerBg: "--calendar-header-bg",
|
|
1395
1638
|
popupBg: "--calendar-popup-bg",
|
|
1396
1639
|
pickerBg: "--calendar-picker-bg",
|
|
@@ -1425,6 +1668,7 @@ var Kalendly = (() => {
|
|
|
1425
1668
|
badgeTentativeBg: "--calendar-badge-tentative-bg",
|
|
1426
1669
|
badgeTentativeText: "--calendar-badge-tentative-text"
|
|
1427
1670
|
};
|
|
1671
|
+
_CalendarElement.warnedMissingEnd = /* @__PURE__ */ new Set();
|
|
1428
1672
|
_CalendarElement.BUILT_IN_BUCKETS = ["blocked", "conditional", "open"];
|
|
1429
1673
|
_CalendarElement.titleDeprecationWarned = false;
|
|
1430
1674
|
var CalendarElement = _CalendarElement;
|