kalendly 0.1.7 → 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 +317 -681
- package/dist/core/index.js +3 -3
- package/dist/index.d.mts +48 -602
- package/dist/index.d.ts +48 -602
- package/dist/index.js +753 -2359
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +727 -2348
- package/dist/index.mjs.map +1 -1
- package/dist/{vanilla/index.umd.js → index.umd.js} +218 -218
- 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 -271
- package/dist/vanilla/index.d.ts +0 -271
- package/dist/vanilla/index.js +0 -1064
- package/dist/vanilla/index.js.map +0 -1
- package/dist/vanilla/index.mjs +0 -1013
- 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
package/dist/vanilla/index.mjs
DELETED
|
@@ -1,1013 +0,0 @@
|
|
|
1
|
-
// src/core/utils.ts
|
|
2
|
-
var MONTHS = [
|
|
3
|
-
"Jan",
|
|
4
|
-
"Feb",
|
|
5
|
-
"Mar",
|
|
6
|
-
"Apr",
|
|
7
|
-
"May",
|
|
8
|
-
"Jun",
|
|
9
|
-
"Jul",
|
|
10
|
-
"Aug",
|
|
11
|
-
"Sep",
|
|
12
|
-
"Oct",
|
|
13
|
-
"Nov",
|
|
14
|
-
"Dec"
|
|
15
|
-
];
|
|
16
|
-
var MONTHS_FULL = [
|
|
17
|
-
"January",
|
|
18
|
-
"February",
|
|
19
|
-
"March",
|
|
20
|
-
"April",
|
|
21
|
-
"May",
|
|
22
|
-
"June",
|
|
23
|
-
"July",
|
|
24
|
-
"August",
|
|
25
|
-
"September",
|
|
26
|
-
"October",
|
|
27
|
-
"November",
|
|
28
|
-
"December"
|
|
29
|
-
];
|
|
30
|
-
var DAYS = [
|
|
31
|
-
"Sunday",
|
|
32
|
-
"Monday",
|
|
33
|
-
"Tuesday",
|
|
34
|
-
"Wednesday",
|
|
35
|
-
"Thursday",
|
|
36
|
-
"Friday",
|
|
37
|
-
"Saturday"
|
|
38
|
-
];
|
|
39
|
-
function normalizeDate(date) {
|
|
40
|
-
return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
|
|
41
|
-
}
|
|
42
|
-
function isSameDay(date1, date2) {
|
|
43
|
-
return normalizeDate(date1).getTime() === normalizeDate(date2).getTime();
|
|
44
|
-
}
|
|
45
|
-
function isToday(date) {
|
|
46
|
-
return isSameDay(date, /* @__PURE__ */ new Date());
|
|
47
|
-
}
|
|
48
|
-
function generateYears(minYear, maxYear) {
|
|
49
|
-
const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
|
|
50
|
-
const min = minYear ?? currentYear - 30;
|
|
51
|
-
const max = maxYear ?? currentYear + 10;
|
|
52
|
-
return Array.from({ length: max - min + 1 }, (_, i) => min + i);
|
|
53
|
-
}
|
|
54
|
-
function getEventsForDate(events, date) {
|
|
55
|
-
const normalizedTargetDate = normalizeDate(date);
|
|
56
|
-
return events.filter((event) => {
|
|
57
|
-
const eventDate = normalizeDate(new Date(event.date));
|
|
58
|
-
return eventDate.getTime() === normalizedTargetDate.getTime();
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
function hasEvents(events, date) {
|
|
62
|
-
return getEventsForDate(events, date).length > 0;
|
|
63
|
-
}
|
|
64
|
-
function generateCalendarDates(year, month, events = [], weekStartsOn = 0) {
|
|
65
|
-
const firstDay = new Date(year, month, 1);
|
|
66
|
-
const lastDay = new Date(year, month + 1, 0);
|
|
67
|
-
const daysInMonth = lastDay.getDate();
|
|
68
|
-
const prevMonthLastDay = new Date(year, month, 0).getDate();
|
|
69
|
-
let firstDayOfWeek = firstDay.getDay();
|
|
70
|
-
if (weekStartsOn === 1) {
|
|
71
|
-
firstDayOfWeek = firstDayOfWeek === 0 ? 6 : firstDayOfWeek - 1;
|
|
72
|
-
}
|
|
73
|
-
const dates = [];
|
|
74
|
-
let day = 1;
|
|
75
|
-
let nextMonthDay = 1;
|
|
76
|
-
for (let week = 0; week < 6; week++) {
|
|
77
|
-
const weekDates = [];
|
|
78
|
-
for (let dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++) {
|
|
79
|
-
if (week === 0 && dayOfWeek < firstDayOfWeek) {
|
|
80
|
-
const prevDay = prevMonthLastDay - firstDayOfWeek + dayOfWeek + 1;
|
|
81
|
-
const prevDate = new Date(year, month - 1, prevDay);
|
|
82
|
-
const dateEvents = getEventsForDate(events, prevDate);
|
|
83
|
-
weekDates.push({
|
|
84
|
-
date: prevDate,
|
|
85
|
-
isCurrentMonth: false,
|
|
86
|
-
isToday: isToday(prevDate),
|
|
87
|
-
hasEvents: dateEvents.length > 0,
|
|
88
|
-
events: dateEvents
|
|
89
|
-
});
|
|
90
|
-
} else if (day > daysInMonth) {
|
|
91
|
-
const nextDate = new Date(year, month + 1, nextMonthDay);
|
|
92
|
-
const dateEvents = getEventsForDate(events, nextDate);
|
|
93
|
-
weekDates.push({
|
|
94
|
-
date: nextDate,
|
|
95
|
-
isCurrentMonth: false,
|
|
96
|
-
isToday: isToday(nextDate),
|
|
97
|
-
hasEvents: dateEvents.length > 0,
|
|
98
|
-
events: dateEvents
|
|
99
|
-
});
|
|
100
|
-
nextMonthDay++;
|
|
101
|
-
} else {
|
|
102
|
-
const currentDate = new Date(year, month, day);
|
|
103
|
-
const dateEvents = getEventsForDate(events, currentDate);
|
|
104
|
-
weekDates.push({
|
|
105
|
-
date: currentDate,
|
|
106
|
-
isCurrentMonth: true,
|
|
107
|
-
isToday: isToday(currentDate),
|
|
108
|
-
hasEvents: dateEvents.length > 0,
|
|
109
|
-
events: dateEvents
|
|
110
|
-
});
|
|
111
|
-
day++;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
dates.push(weekDates);
|
|
115
|
-
}
|
|
116
|
-
return dates;
|
|
117
|
-
}
|
|
118
|
-
function getPopupPositionClass(selectedDayIndex) {
|
|
119
|
-
if (selectedDayIndex === null) return "popup-center-bottom";
|
|
120
|
-
if (selectedDayIndex < 3) {
|
|
121
|
-
return "popup-right";
|
|
122
|
-
} else if (selectedDayIndex > 4) {
|
|
123
|
-
return "popup-left";
|
|
124
|
-
} else {
|
|
125
|
-
return "popup-center-bottom";
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
function getCellClasses(calendarDate) {
|
|
129
|
-
const classes = [];
|
|
130
|
-
if (!calendarDate.isCurrentMonth) {
|
|
131
|
-
classes.push("other-month");
|
|
132
|
-
}
|
|
133
|
-
if (calendarDate.isToday) {
|
|
134
|
-
classes.push("schedule--current--exam");
|
|
135
|
-
}
|
|
136
|
-
if (calendarDate.hasEvents) {
|
|
137
|
-
classes.push("has--event");
|
|
138
|
-
}
|
|
139
|
-
return classes;
|
|
140
|
-
}
|
|
141
|
-
function formatDateForDisplay(date) {
|
|
142
|
-
return `${DAYS[date.getDay()]} ${date.getDate()}`;
|
|
143
|
-
}
|
|
144
|
-
function getMonthYearText(year, month) {
|
|
145
|
-
return `${MONTHS_FULL[month]} ${year}`;
|
|
146
|
-
}
|
|
147
|
-
function formatTimeRange(event) {
|
|
148
|
-
if (event.allDay || !event.startTime && !event.endTime) {
|
|
149
|
-
return "All day";
|
|
150
|
-
}
|
|
151
|
-
if (event.startTime && event.endTime) {
|
|
152
|
-
return `${event.startTime} - ${event.endTime}`;
|
|
153
|
-
}
|
|
154
|
-
if (event.startTime) {
|
|
155
|
-
return `${event.startTime}`;
|
|
156
|
-
}
|
|
157
|
-
return "";
|
|
158
|
-
}
|
|
159
|
-
function formatAttendees(attendees) {
|
|
160
|
-
if (!attendees || attendees.length === 0) return "";
|
|
161
|
-
if (attendees.length === 1) return attendees[0];
|
|
162
|
-
if (attendees.length === 2) return attendees.join(" and ");
|
|
163
|
-
return `${attendees.slice(0, -1).join(", ")}, and ${attendees[attendees.length - 1]}`;
|
|
164
|
-
}
|
|
165
|
-
function sortEventsByTime(events) {
|
|
166
|
-
return [...events].sort((a, b) => {
|
|
167
|
-
const aAllDay = a.allDay || !a.startTime && !a.endTime;
|
|
168
|
-
const bAllDay = b.allDay || !b.startTime && !b.endTime;
|
|
169
|
-
if (aAllDay && !bAllDay) return -1;
|
|
170
|
-
if (!aAllDay && bAllDay) return 1;
|
|
171
|
-
if (!a.startTime || !b.startTime) return 0;
|
|
172
|
-
return a.startTime.localeCompare(b.startTime);
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
var DEFAULT_CATEGORY_COLORS = {
|
|
176
|
-
work: "#3b82f6",
|
|
177
|
-
personal: "#8b5cf6",
|
|
178
|
-
meeting: "#10b981",
|
|
179
|
-
deadline: "#ef4444",
|
|
180
|
-
appointment: "#f59e0b",
|
|
181
|
-
other: "#6b7280"
|
|
182
|
-
};
|
|
183
|
-
function getDefaultEventColor(category, customColors) {
|
|
184
|
-
const colorMap = customColors || DEFAULT_CATEGORY_COLORS;
|
|
185
|
-
if (category && colorMap[category]) {
|
|
186
|
-
return colorMap[category];
|
|
187
|
-
}
|
|
188
|
-
return "#fc8917";
|
|
189
|
-
}
|
|
190
|
-
function mergeCategoryColors(customColors) {
|
|
191
|
-
return {
|
|
192
|
-
...DEFAULT_CATEGORY_COLORS,
|
|
193
|
-
...customColors
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
function isValidHexColor(color) {
|
|
197
|
-
return /^#([0-9A-F]{3}){1,2}$/i.test(color);
|
|
198
|
-
}
|
|
199
|
-
function getCategoryColor(category, customColors) {
|
|
200
|
-
const colorMap = mergeCategoryColors(customColors);
|
|
201
|
-
const color = colorMap[category] || colorMap.other || "#fc8917";
|
|
202
|
-
return isValidHexColor(color) ? color : "#fc8917";
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// src/core/calendar-engine.ts
|
|
206
|
-
var CalendarEngine = class {
|
|
207
|
-
constructor(config) {
|
|
208
|
-
this.listeners = /* @__PURE__ */ new Set();
|
|
209
|
-
this.config = config;
|
|
210
|
-
this.categoryColors = mergeCategoryColors(config.categoryColors);
|
|
211
|
-
const initialDate = config.initialDate || /* @__PURE__ */ new Date();
|
|
212
|
-
this.state = {
|
|
213
|
-
currentYear: initialDate.getFullYear(),
|
|
214
|
-
currentMonth: initialDate.getMonth(),
|
|
215
|
-
currentDate: initialDate.getDate(),
|
|
216
|
-
selectedDate: null,
|
|
217
|
-
selectedDayIndex: null,
|
|
218
|
-
tasks: []
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Subscribe to state changes
|
|
223
|
-
*/
|
|
224
|
-
subscribe(listener) {
|
|
225
|
-
this.listeners.add(listener);
|
|
226
|
-
return () => this.listeners.delete(listener);
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Notify all listeners of state changes
|
|
230
|
-
*/
|
|
231
|
-
notify() {
|
|
232
|
-
this.listeners.forEach((listener) => listener());
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* Get current state
|
|
236
|
-
*/
|
|
237
|
-
getState() {
|
|
238
|
-
return { ...this.state };
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Get view model with computed properties
|
|
242
|
-
*/
|
|
243
|
-
getViewModel() {
|
|
244
|
-
const calendarDates = generateCalendarDates(
|
|
245
|
-
this.state.currentYear,
|
|
246
|
-
this.state.currentMonth,
|
|
247
|
-
this.config.events,
|
|
248
|
-
this.config.weekStartsOn
|
|
249
|
-
);
|
|
250
|
-
return {
|
|
251
|
-
...this.state,
|
|
252
|
-
months: MONTHS,
|
|
253
|
-
days: DAYS,
|
|
254
|
-
years: generateYears(this.config.minYear, this.config.maxYear),
|
|
255
|
-
monthAndYearText: getMonthYearText(
|
|
256
|
-
this.state.currentYear,
|
|
257
|
-
this.state.currentMonth
|
|
258
|
-
),
|
|
259
|
-
scheduleDay: this.state.selectedDate ? formatDateForDisplay(this.state.selectedDate) : "",
|
|
260
|
-
calendarDates,
|
|
261
|
-
popupPositionClass: getPopupPositionClass(this.state.selectedDayIndex)
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Get actions object
|
|
266
|
-
*/
|
|
267
|
-
getActions() {
|
|
268
|
-
return {
|
|
269
|
-
next: this.next.bind(this),
|
|
270
|
-
previous: this.previous.bind(this),
|
|
271
|
-
jump: this.jump.bind(this),
|
|
272
|
-
goToToday: this.goToToday.bind(this),
|
|
273
|
-
isCurrentMonth: this.isCurrentMonth.bind(this),
|
|
274
|
-
selectDate: this.selectDate.bind(this),
|
|
275
|
-
updateTasks: this.updateTasks.bind(this)
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
/**
|
|
279
|
-
* Navigate to next month
|
|
280
|
-
*/
|
|
281
|
-
next() {
|
|
282
|
-
if (this.state.currentMonth === 11) {
|
|
283
|
-
this.state.currentMonth = 0;
|
|
284
|
-
this.state.currentYear++;
|
|
285
|
-
} else {
|
|
286
|
-
this.state.currentMonth++;
|
|
287
|
-
}
|
|
288
|
-
this.state.selectedDate = null;
|
|
289
|
-
this.state.selectedDayIndex = null;
|
|
290
|
-
this.updateTasks();
|
|
291
|
-
this.notify();
|
|
292
|
-
}
|
|
293
|
-
/**
|
|
294
|
-
* Navigate to previous month
|
|
295
|
-
*/
|
|
296
|
-
previous() {
|
|
297
|
-
if (this.state.currentMonth === 0) {
|
|
298
|
-
this.state.currentMonth = 11;
|
|
299
|
-
this.state.currentYear--;
|
|
300
|
-
} else {
|
|
301
|
-
this.state.currentMonth--;
|
|
302
|
-
}
|
|
303
|
-
this.state.selectedDate = null;
|
|
304
|
-
this.state.selectedDayIndex = null;
|
|
305
|
-
this.updateTasks();
|
|
306
|
-
this.notify();
|
|
307
|
-
}
|
|
308
|
-
/**
|
|
309
|
-
* Jump to specific month and year
|
|
310
|
-
*/
|
|
311
|
-
jump(year, month) {
|
|
312
|
-
this.state.currentYear = year;
|
|
313
|
-
this.state.currentMonth = month;
|
|
314
|
-
this.state.selectedDate = null;
|
|
315
|
-
this.state.selectedDayIndex = null;
|
|
316
|
-
this.updateTasks();
|
|
317
|
-
this.notify();
|
|
318
|
-
}
|
|
319
|
-
/**
|
|
320
|
-
* Navigate to current month (today)
|
|
321
|
-
*/
|
|
322
|
-
goToToday() {
|
|
323
|
-
const today = /* @__PURE__ */ new Date();
|
|
324
|
-
this.state.currentYear = today.getFullYear();
|
|
325
|
-
this.state.currentMonth = today.getMonth();
|
|
326
|
-
this.state.selectedDate = null;
|
|
327
|
-
this.state.selectedDayIndex = null;
|
|
328
|
-
this.updateTasks();
|
|
329
|
-
this.notify();
|
|
330
|
-
}
|
|
331
|
-
/**
|
|
332
|
-
* Check if currently viewing today's month
|
|
333
|
-
*/
|
|
334
|
-
isCurrentMonth() {
|
|
335
|
-
const today = /* @__PURE__ */ new Date();
|
|
336
|
-
return this.state.currentYear === today.getFullYear() && this.state.currentMonth === today.getMonth();
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Select a specific date
|
|
340
|
-
*/
|
|
341
|
-
selectDate(date, dayIndex) {
|
|
342
|
-
this.state.selectedDate = date;
|
|
343
|
-
this.state.selectedDayIndex = dayIndex ?? null;
|
|
344
|
-
this.state.currentDate = date.getDate();
|
|
345
|
-
this.state.currentMonth = date.getMonth();
|
|
346
|
-
this.state.currentYear = date.getFullYear();
|
|
347
|
-
this.updateTasks();
|
|
348
|
-
this.notify();
|
|
349
|
-
}
|
|
350
|
-
/**
|
|
351
|
-
* Update tasks for the currently selected date
|
|
352
|
-
*/
|
|
353
|
-
updateTasks() {
|
|
354
|
-
if (!this.state.selectedDate) {
|
|
355
|
-
this.state.tasks = [];
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
this.state.tasks = getEventsForDate(
|
|
359
|
-
this.config.events,
|
|
360
|
-
this.state.selectedDate
|
|
361
|
-
);
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* Update events configuration
|
|
365
|
-
*/
|
|
366
|
-
updateEvents(events) {
|
|
367
|
-
this.config.events = events;
|
|
368
|
-
this.updateTasks();
|
|
369
|
-
this.notify();
|
|
370
|
-
}
|
|
371
|
-
/**
|
|
372
|
-
* Handle date cell click
|
|
373
|
-
*/
|
|
374
|
-
handleDateClick(date, dayIndex) {
|
|
375
|
-
this.selectDate(date, dayIndex);
|
|
376
|
-
}
|
|
377
|
-
/**
|
|
378
|
-
* Check if date has events
|
|
379
|
-
*/
|
|
380
|
-
hasEventsForDate(date) {
|
|
381
|
-
return getEventsForDate(this.config.events, date).length > 0;
|
|
382
|
-
}
|
|
383
|
-
/**
|
|
384
|
-
* Get events for a specific date
|
|
385
|
-
*/
|
|
386
|
-
getEventsForDate(date) {
|
|
387
|
-
return getEventsForDate(this.config.events, date);
|
|
388
|
-
}
|
|
389
|
-
/**
|
|
390
|
-
* Clear selected date
|
|
391
|
-
*/
|
|
392
|
-
clearSelection() {
|
|
393
|
-
this.state.selectedDate = null;
|
|
394
|
-
this.state.selectedDayIndex = null;
|
|
395
|
-
this.state.tasks = [];
|
|
396
|
-
this.notify();
|
|
397
|
-
}
|
|
398
|
-
/**
|
|
399
|
-
* Get category color (with custom colors support)
|
|
400
|
-
*/
|
|
401
|
-
getCategoryColor(category) {
|
|
402
|
-
if (!category) return "#fc8917";
|
|
403
|
-
return getCategoryColor(category, this.categoryColors);
|
|
404
|
-
}
|
|
405
|
-
/**
|
|
406
|
-
* Update category colors dynamically
|
|
407
|
-
*/
|
|
408
|
-
updateCategoryColors(colors) {
|
|
409
|
-
this.categoryColors = mergeCategoryColors(colors);
|
|
410
|
-
this.notify();
|
|
411
|
-
}
|
|
412
|
-
/**
|
|
413
|
-
* Get all category colors
|
|
414
|
-
*/
|
|
415
|
-
getCategoryColors() {
|
|
416
|
-
return { ...this.categoryColors };
|
|
417
|
-
}
|
|
418
|
-
/**
|
|
419
|
-
* Register a new category with color
|
|
420
|
-
*/
|
|
421
|
-
registerCategory(name, color) {
|
|
422
|
-
this.categoryColors[name] = color;
|
|
423
|
-
this.notify();
|
|
424
|
-
}
|
|
425
|
-
/**
|
|
426
|
-
* Destroy the engine and cleanup listeners
|
|
427
|
-
*/
|
|
428
|
-
destroy() {
|
|
429
|
-
this.listeners.clear();
|
|
430
|
-
}
|
|
431
|
-
};
|
|
432
|
-
|
|
433
|
-
// src/vanilla/Calendar.ts
|
|
434
|
-
var VanillaCalendar = class {
|
|
435
|
-
constructor(props) {
|
|
436
|
-
this.unsubscribe = null;
|
|
437
|
-
this.pickerOpen = false;
|
|
438
|
-
this.yearInput = "";
|
|
439
|
-
this.yearInputValid = true;
|
|
440
|
-
this.clickOutsideHandler = null;
|
|
441
|
-
this.delegatedClickHandler = null;
|
|
442
|
-
this.delegatedInputHandler = null;
|
|
443
|
-
this.delegatedBlurHandler = null;
|
|
444
|
-
this.delegatedKeydownHandler = null;
|
|
445
|
-
this.listenersAttached = false;
|
|
446
|
-
this.props = props;
|
|
447
|
-
if (typeof props.container === "string") {
|
|
448
|
-
const element = document.querySelector(props.container);
|
|
449
|
-
if (!element) {
|
|
450
|
-
throw new Error(`Container element "${props.container}" not found`);
|
|
451
|
-
}
|
|
452
|
-
this.container = element;
|
|
453
|
-
} else {
|
|
454
|
-
this.container = props.container;
|
|
455
|
-
}
|
|
456
|
-
this.engine = new CalendarEngine({
|
|
457
|
-
events: props.events,
|
|
458
|
-
initialDate: props.initialDate,
|
|
459
|
-
minYear: props.minYear,
|
|
460
|
-
maxYear: props.maxYear,
|
|
461
|
-
weekStartsOn: props.weekStartsOn
|
|
462
|
-
});
|
|
463
|
-
this.actions = this.engine.getActions();
|
|
464
|
-
this.applyTheme();
|
|
465
|
-
this.init();
|
|
466
|
-
}
|
|
467
|
-
applyTheme() {
|
|
468
|
-
if (this.props.theme) {
|
|
469
|
-
const root = document.documentElement;
|
|
470
|
-
const theme = this.props.theme;
|
|
471
|
-
if (theme.primary)
|
|
472
|
-
root.style.setProperty("--calendar-primary-color", theme.primary);
|
|
473
|
-
if (theme.secondary)
|
|
474
|
-
root.style.setProperty("--calendar-secondary-color", theme.secondary);
|
|
475
|
-
if (theme.tertiary)
|
|
476
|
-
root.style.setProperty("--calendar-tertiary-color", theme.tertiary);
|
|
477
|
-
if (theme.textColor)
|
|
478
|
-
root.style.setProperty("--calendar-text-color", theme.textColor);
|
|
479
|
-
if (theme.textLight)
|
|
480
|
-
root.style.setProperty("--calendar-text-light", theme.textLight);
|
|
481
|
-
if (theme.background)
|
|
482
|
-
root.style.setProperty("--calendar-background", theme.background);
|
|
483
|
-
if (theme.cellHover)
|
|
484
|
-
root.style.setProperty("--calendar-cell-hover", theme.cellHover);
|
|
485
|
-
if (theme.borderColor)
|
|
486
|
-
root.style.setProperty("--calendar-border-color", theme.borderColor);
|
|
487
|
-
if (theme.todayOutline)
|
|
488
|
-
root.style.setProperty("--calendar-today-outline", theme.todayOutline);
|
|
489
|
-
if (theme.selectedBg)
|
|
490
|
-
root.style.setProperty("--calendar-selected-bg", theme.selectedBg);
|
|
491
|
-
if (theme.eventIndicator)
|
|
492
|
-
root.style.setProperty(
|
|
493
|
-
"--calendar-event-indicator",
|
|
494
|
-
theme.eventIndicator
|
|
495
|
-
);
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
init() {
|
|
499
|
-
this.container.classList.add("kalendly-calendar");
|
|
500
|
-
if (this.props.className) {
|
|
501
|
-
this.container.classList.add(this.props.className);
|
|
502
|
-
}
|
|
503
|
-
this.unsubscribe = this.engine.subscribe(() => {
|
|
504
|
-
this.render();
|
|
505
|
-
});
|
|
506
|
-
this.render();
|
|
507
|
-
}
|
|
508
|
-
render() {
|
|
509
|
-
const viewModel = this.engine.getViewModel();
|
|
510
|
-
const defaultRenderEvent = (event) => {
|
|
511
|
-
const timeRange = formatTimeRange(event);
|
|
512
|
-
const attendeesList = formatAttendees(event.attendees);
|
|
513
|
-
let borderColor = event.color || "#3b82f6";
|
|
514
|
-
if (event.category) {
|
|
515
|
-
borderColor = this.engine.getCategoryColor(event.category);
|
|
516
|
-
}
|
|
517
|
-
const getCategoryLabel = (category) => {
|
|
518
|
-
const labels = {
|
|
519
|
-
work: "WORK",
|
|
520
|
-
personal: "PERSONAL",
|
|
521
|
-
meeting: "MEETING",
|
|
522
|
-
deadline: "DEADLINE",
|
|
523
|
-
appointment: "APPOINTMENT",
|
|
524
|
-
other: "OTHER"
|
|
525
|
-
};
|
|
526
|
-
return category ? labels[category] || category.toUpperCase() : "";
|
|
527
|
-
};
|
|
528
|
-
const getPriorityLabel = (priority) => {
|
|
529
|
-
const labels = {
|
|
530
|
-
high: "HIGH",
|
|
531
|
-
medium: "MEDIUM",
|
|
532
|
-
low: "LOW"
|
|
533
|
-
};
|
|
534
|
-
return priority ? labels[priority] || priority.toUpperCase() : "";
|
|
535
|
-
};
|
|
536
|
-
const getStatusLabel = (status) => {
|
|
537
|
-
const labels = {
|
|
538
|
-
completed: "COMPLETED",
|
|
539
|
-
cancelled: "CANCELLED",
|
|
540
|
-
tentative: "TENTATIVE",
|
|
541
|
-
scheduled: "SCHEDULED"
|
|
542
|
-
};
|
|
543
|
-
return status ? labels[status] || status.toUpperCase() : "";
|
|
544
|
-
};
|
|
545
|
-
return `
|
|
546
|
-
<div class="event-card" style="border-left-color: ${borderColor}">
|
|
547
|
-
<div class="event-header">
|
|
548
|
-
<div class="event-title">${event.name}</div>
|
|
549
|
-
<div class="event-badges">
|
|
550
|
-
${event.category ? `<span class="badge category-${event.category}">${getCategoryLabel(event.category)}</span>` : ""}
|
|
551
|
-
${event.priority ? `<span class="badge priority-${event.priority}">${getPriorityLabel(event.priority)}</span>` : ""}
|
|
552
|
-
${event.status && event.status !== "scheduled" ? `<span class="badge status-${event.status}">${getStatusLabel(event.status)}</span>` : ""}
|
|
553
|
-
</div>
|
|
554
|
-
</div>
|
|
555
|
-
|
|
556
|
-
${timeRange ? `
|
|
557
|
-
<div class="event-time">
|
|
558
|
-
<span class="event-time-label">Time:</span>
|
|
559
|
-
<span class="event-time-value">${timeRange}</span>
|
|
560
|
-
</div>
|
|
561
|
-
` : ""}
|
|
562
|
-
|
|
563
|
-
${event.description ? `
|
|
564
|
-
<div class="event-description">${event.description}</div>
|
|
565
|
-
` : ""}
|
|
566
|
-
|
|
567
|
-
${event.location ? `
|
|
568
|
-
<div class="event-time">
|
|
569
|
-
<span class="event-time-label">Location:</span>
|
|
570
|
-
<span class="event-time-value">${event.location}</span>
|
|
571
|
-
</div>
|
|
572
|
-
` : ""}
|
|
573
|
-
|
|
574
|
-
${attendeesList ? `
|
|
575
|
-
<div class="event-time">
|
|
576
|
-
<span class="event-time-label">Attendees:</span>
|
|
577
|
-
<span class="event-time-value">${attendeesList}</span>
|
|
578
|
-
</div>
|
|
579
|
-
` : ""}
|
|
580
|
-
|
|
581
|
-
${event.organizer ? `
|
|
582
|
-
<div class="event-time">
|
|
583
|
-
<span class="event-time-label">Organizer:</span>
|
|
584
|
-
<span class="event-time-value">${event.organizer}</span>
|
|
585
|
-
</div>
|
|
586
|
-
` : ""}
|
|
587
|
-
|
|
588
|
-
${event.notes ? `
|
|
589
|
-
<div class="event-time">
|
|
590
|
-
<span class="event-time-label">Notes:</span>
|
|
591
|
-
<span class="event-time-value">${event.notes}</span>
|
|
592
|
-
</div>
|
|
593
|
-
` : ""}
|
|
594
|
-
|
|
595
|
-
${event.url ? `
|
|
596
|
-
<div class="event-time">
|
|
597
|
-
<a href="${event.url}" target="_blank" rel="noopener noreferrer" class="event-link">
|
|
598
|
-
View Details \u2192
|
|
599
|
-
</a>
|
|
600
|
-
</div>
|
|
601
|
-
` : ""}
|
|
602
|
-
|
|
603
|
-
${event.tags && event.tags.length > 0 ? `
|
|
604
|
-
<div class="event-tags">
|
|
605
|
-
${event.tags.map((tag) => `<span class="event-tag">${tag}</span>`).join("")}
|
|
606
|
-
</div>
|
|
607
|
-
` : ""}
|
|
608
|
-
</div>
|
|
609
|
-
`;
|
|
610
|
-
};
|
|
611
|
-
const defaultRenderNoEvents = () => '<div class="no-events-message">No events scheduled for this day.</div>';
|
|
612
|
-
const renderEvent = this.props.renderEvent || defaultRenderEvent;
|
|
613
|
-
const renderNoEvents = this.props.renderNoEvents || defaultRenderNoEvents;
|
|
614
|
-
const showScrollHint = viewModel.tasks.length > 3;
|
|
615
|
-
const today = /* @__PURE__ */ new Date();
|
|
616
|
-
const todayMonth = today.getMonth();
|
|
617
|
-
const todayYear = today.getFullYear();
|
|
618
|
-
const minYear = this.props.minYear ?? todayYear - 30;
|
|
619
|
-
const maxYear = this.props.maxYear ?? todayYear + 10;
|
|
620
|
-
const isCurrentMonth = viewModel.currentYear === todayYear && viewModel.currentMonth === todayMonth;
|
|
621
|
-
const html = `
|
|
622
|
-
${this.props.title ? `
|
|
623
|
-
<div class="page--title">
|
|
624
|
-
<h1>${this.props.title}</h1>
|
|
625
|
-
</div>
|
|
626
|
-
` : ""}
|
|
627
|
-
|
|
628
|
-
<div class="calendar--content">
|
|
629
|
-
<div class="calendar--card">
|
|
630
|
-
<!-- Navigation Header -->
|
|
631
|
-
<div class="calendar--nav-header">
|
|
632
|
-
<button type="button" class="calendar--nav-arrow" data-action="previous" aria-label="Previous month">
|
|
633
|
-
‹
|
|
634
|
-
</button>
|
|
635
|
-
|
|
636
|
-
<div class="calendar--picker-container" data-picker-container>
|
|
637
|
-
<button
|
|
638
|
-
type="button"
|
|
639
|
-
class="calendar--picker-btn"
|
|
640
|
-
data-action="toggle-picker"
|
|
641
|
-
aria-expanded="${this.pickerOpen ? "true" : "false"}"
|
|
642
|
-
aria-haspopup="true"
|
|
643
|
-
>
|
|
644
|
-
${this.props.useShortMonthNames ? `${MONTHS[viewModel.currentMonth]} ${viewModel.currentYear}` : viewModel.monthAndYearText}
|
|
645
|
-
<span class="calendar--picker-chevron">▾</span>
|
|
646
|
-
</button>
|
|
647
|
-
|
|
648
|
-
${this.pickerOpen ? `
|
|
649
|
-
<div class="calendar--picker-dropdown">
|
|
650
|
-
<div class="calendar--picker-year-row">
|
|
651
|
-
<button
|
|
652
|
-
type="button"
|
|
653
|
-
class="calendar--picker-year-arrow"
|
|
654
|
-
data-action="year-prev"
|
|
655
|
-
${viewModel.currentYear <= minYear ? "disabled" : ""}
|
|
656
|
-
aria-label="Previous year"
|
|
657
|
-
>‹</button>
|
|
658
|
-
<input
|
|
659
|
-
type="text"
|
|
660
|
-
class="calendar--picker-year-input${!this.yearInputValid ? " invalid" : ""}"
|
|
661
|
-
value="${this.yearInput || viewModel.currentYear}"
|
|
662
|
-
data-year-input
|
|
663
|
-
aria-label="Year"
|
|
664
|
-
/>
|
|
665
|
-
<button
|
|
666
|
-
type="button"
|
|
667
|
-
class="calendar--picker-year-arrow"
|
|
668
|
-
data-action="year-next"
|
|
669
|
-
${viewModel.currentYear >= maxYear ? "disabled" : ""}
|
|
670
|
-
aria-label="Next year"
|
|
671
|
-
>›</button>
|
|
672
|
-
</div>
|
|
673
|
-
|
|
674
|
-
<div class="calendar--picker-months">
|
|
675
|
-
${(this.props.useShortMonthNames ? MONTHS : MONTHS_FULL).map((month, index) => {
|
|
676
|
-
const isSelected = index === viewModel.currentMonth;
|
|
677
|
-
const isCurrent = index === todayMonth && viewModel.currentYear === todayYear;
|
|
678
|
-
return `
|
|
679
|
-
<button
|
|
680
|
-
type="button"
|
|
681
|
-
class="calendar--picker-month${isSelected ? " selected" : ""}${isCurrent ? " current-month" : ""}"
|
|
682
|
-
data-action="select-month"
|
|
683
|
-
data-month="${index}"
|
|
684
|
-
>${month}</button>
|
|
685
|
-
`;
|
|
686
|
-
}).join("")}
|
|
687
|
-
</div>
|
|
688
|
-
</div>
|
|
689
|
-
` : ""}
|
|
690
|
-
</div>
|
|
691
|
-
|
|
692
|
-
<button
|
|
693
|
-
type="button"
|
|
694
|
-
class="calendar--today-btn"
|
|
695
|
-
data-action="today"
|
|
696
|
-
${isCurrentMonth ? "disabled" : ""}
|
|
697
|
-
>Today</button>
|
|
698
|
-
|
|
699
|
-
<button type="button" class="calendar--nav-arrow" data-action="next" aria-label="Next month">
|
|
700
|
-
›
|
|
701
|
-
</button>
|
|
702
|
-
</div>
|
|
703
|
-
|
|
704
|
-
<table class="calendar--table calendar--table--bordered">
|
|
705
|
-
<thead>
|
|
706
|
-
<tr>
|
|
707
|
-
${viewModel.days.map((day) => `<th>${day.slice(0, 3)}</th>`).join("")}
|
|
708
|
-
</tr>
|
|
709
|
-
</thead>
|
|
710
|
-
<tbody data-calendar-body>
|
|
711
|
-
${viewModel.calendarDates.map(
|
|
712
|
-
(week) => `
|
|
713
|
-
<tr>
|
|
714
|
-
${week.map((calendarDate, dayIndex) => {
|
|
715
|
-
const classes = getCellClasses(calendarDate);
|
|
716
|
-
const dateString = calendarDate.date.toISOString();
|
|
717
|
-
return `
|
|
718
|
-
<td
|
|
719
|
-
class="${classes.join(" ")}"
|
|
720
|
-
data-date="${dateString}"
|
|
721
|
-
data-day-index="${dayIndex}"
|
|
722
|
-
data-clickable="true"
|
|
723
|
-
>
|
|
724
|
-
${calendarDate.date.getDate()}
|
|
725
|
-
</td>
|
|
726
|
-
`;
|
|
727
|
-
}).join("")}
|
|
728
|
-
</tr>
|
|
729
|
-
`
|
|
730
|
-
).join("")}
|
|
731
|
-
</tbody>
|
|
732
|
-
</table>
|
|
733
|
-
|
|
734
|
-
${viewModel.selectedDate ? `
|
|
735
|
-
<div class="date-popup ${viewModel.popupPositionClass}">
|
|
736
|
-
<div class="popup-header">
|
|
737
|
-
<h2>${viewModel.scheduleDay}</h2>
|
|
738
|
-
<button type="button" class="popup-close" data-action="close-popup" aria-label="Close">\u2715</button>
|
|
739
|
-
</div>
|
|
740
|
-
|
|
741
|
-
${showScrollHint ? `
|
|
742
|
-
<div class="scroll-hint">
|
|
743
|
-
\u2193 Scroll to see more events \u2193
|
|
744
|
-
</div>
|
|
745
|
-
` : ""}
|
|
746
|
-
|
|
747
|
-
<div class="events-container">
|
|
748
|
-
${viewModel.tasks.length > 0 ? `
|
|
749
|
-
${viewModel.tasks.map((event) => renderEvent(event)).join("")}
|
|
750
|
-
` : renderNoEvents()}
|
|
751
|
-
</div>
|
|
752
|
-
</div>
|
|
753
|
-
` : ""}
|
|
754
|
-
</div>
|
|
755
|
-
</div>
|
|
756
|
-
`;
|
|
757
|
-
this.container.innerHTML = html;
|
|
758
|
-
this.attachEventListeners();
|
|
759
|
-
}
|
|
760
|
-
attachEventListeners() {
|
|
761
|
-
if (this.listenersAttached) return;
|
|
762
|
-
this.listenersAttached = true;
|
|
763
|
-
const today = /* @__PURE__ */ new Date();
|
|
764
|
-
const todayYear = today.getFullYear();
|
|
765
|
-
const todayMonth = today.getMonth();
|
|
766
|
-
const minYear = this.props.minYear ?? todayYear - 30;
|
|
767
|
-
const maxYear = this.props.maxYear ?? todayYear + 10;
|
|
768
|
-
this.delegatedClickHandler = (e) => {
|
|
769
|
-
const target = e.target;
|
|
770
|
-
const cell = target.closest('td[data-clickable="true"]');
|
|
771
|
-
if (cell && cell.dataset.date) {
|
|
772
|
-
e.stopPropagation();
|
|
773
|
-
const date = new Date(cell.dataset.date);
|
|
774
|
-
const dayIndex = parseInt(cell.dataset.dayIndex || "0");
|
|
775
|
-
this.engine.handleDateClick(date, dayIndex);
|
|
776
|
-
this.container.dispatchEvent(
|
|
777
|
-
new CustomEvent("dateSelect", { detail: { date, dayIndex } })
|
|
778
|
-
);
|
|
779
|
-
return;
|
|
780
|
-
}
|
|
781
|
-
const actionEl = target.closest("[data-action]");
|
|
782
|
-
if (!actionEl) return;
|
|
783
|
-
const action = actionEl.dataset.action;
|
|
784
|
-
e.stopPropagation();
|
|
785
|
-
switch (action) {
|
|
786
|
-
case "previous":
|
|
787
|
-
this.actions.previous();
|
|
788
|
-
this.dispatchMonthChange();
|
|
789
|
-
break;
|
|
790
|
-
case "next":
|
|
791
|
-
this.actions.next();
|
|
792
|
-
this.dispatchMonthChange();
|
|
793
|
-
break;
|
|
794
|
-
case "today":
|
|
795
|
-
this.actions.goToToday();
|
|
796
|
-
this.pickerOpen = false;
|
|
797
|
-
this.container.dispatchEvent(
|
|
798
|
-
new CustomEvent("monthChange", {
|
|
799
|
-
detail: { year: todayYear, month: todayMonth }
|
|
800
|
-
})
|
|
801
|
-
);
|
|
802
|
-
break;
|
|
803
|
-
case "toggle-picker":
|
|
804
|
-
this.pickerOpen = !this.pickerOpen;
|
|
805
|
-
if (this.pickerOpen) {
|
|
806
|
-
this.yearInput = String(this.engine.getViewModel().currentYear);
|
|
807
|
-
this.yearInputValid = true;
|
|
808
|
-
}
|
|
809
|
-
this.render();
|
|
810
|
-
break;
|
|
811
|
-
case "year-prev": {
|
|
812
|
-
const vm = this.engine.getViewModel();
|
|
813
|
-
if (vm.currentYear > minYear) {
|
|
814
|
-
const newYear = vm.currentYear - 1;
|
|
815
|
-
this.yearInput = String(newYear);
|
|
816
|
-
this.updatePickerYear(newYear);
|
|
817
|
-
this.actions.jump(newYear, vm.currentMonth);
|
|
818
|
-
this.dispatchMonthChange();
|
|
819
|
-
}
|
|
820
|
-
break;
|
|
821
|
-
}
|
|
822
|
-
case "year-next": {
|
|
823
|
-
const vm = this.engine.getViewModel();
|
|
824
|
-
if (vm.currentYear < maxYear) {
|
|
825
|
-
const newYear = vm.currentYear + 1;
|
|
826
|
-
this.yearInput = String(newYear);
|
|
827
|
-
this.updatePickerYear(newYear);
|
|
828
|
-
this.actions.jump(newYear, vm.currentMonth);
|
|
829
|
-
this.dispatchMonthChange();
|
|
830
|
-
}
|
|
831
|
-
break;
|
|
832
|
-
}
|
|
833
|
-
case "select-month": {
|
|
834
|
-
const month = parseInt(actionEl.dataset.month || "0", 10);
|
|
835
|
-
this.actions.jump(this.engine.getViewModel().currentYear, month);
|
|
836
|
-
this.pickerOpen = false;
|
|
837
|
-
this.dispatchMonthChange();
|
|
838
|
-
break;
|
|
839
|
-
}
|
|
840
|
-
case "close-popup":
|
|
841
|
-
this.engine.clearSelection();
|
|
842
|
-
break;
|
|
843
|
-
}
|
|
844
|
-
};
|
|
845
|
-
this.delegatedInputHandler = (e) => {
|
|
846
|
-
const target = e.target;
|
|
847
|
-
if (!target.matches("[data-year-input]")) return;
|
|
848
|
-
const value = target.value;
|
|
849
|
-
if (value === "" || /^\d+$/.test(value)) {
|
|
850
|
-
this.yearInput = value;
|
|
851
|
-
const year = parseInt(value, 10);
|
|
852
|
-
this.yearInputValid = value === "" || year >= minYear && year <= maxYear;
|
|
853
|
-
target.classList.toggle("invalid", !this.yearInputValid);
|
|
854
|
-
}
|
|
855
|
-
};
|
|
856
|
-
this.delegatedBlurHandler = (e) => {
|
|
857
|
-
const target = e.target;
|
|
858
|
-
if (!target.matches("[data-year-input]")) return;
|
|
859
|
-
const year = parseInt(this.yearInput, 10);
|
|
860
|
-
const vm = this.engine.getViewModel();
|
|
861
|
-
if (isNaN(year) || year < minYear || year > maxYear) {
|
|
862
|
-
this.yearInput = String(vm.currentYear);
|
|
863
|
-
this.yearInputValid = true;
|
|
864
|
-
target.value = this.yearInput;
|
|
865
|
-
target.classList.remove("invalid");
|
|
866
|
-
} else if (year !== vm.currentYear) {
|
|
867
|
-
this.actions.jump(year, vm.currentMonth);
|
|
868
|
-
this.dispatchMonthChange();
|
|
869
|
-
}
|
|
870
|
-
};
|
|
871
|
-
this.delegatedKeydownHandler = (e) => {
|
|
872
|
-
const target = e.target;
|
|
873
|
-
if (!target.matches("[data-year-input]")) return;
|
|
874
|
-
if (e.key === "Enter") {
|
|
875
|
-
target.blur();
|
|
876
|
-
}
|
|
877
|
-
};
|
|
878
|
-
this.container.addEventListener("click", this.delegatedClickHandler);
|
|
879
|
-
this.container.addEventListener("input", this.delegatedInputHandler);
|
|
880
|
-
this.container.addEventListener("blur", this.delegatedBlurHandler, true);
|
|
881
|
-
this.container.addEventListener("keydown", this.delegatedKeydownHandler);
|
|
882
|
-
this.clickOutsideHandler = (e) => {
|
|
883
|
-
const target = e.target;
|
|
884
|
-
if (this.container.contains(target)) return;
|
|
885
|
-
if (this.pickerOpen) {
|
|
886
|
-
this.pickerOpen = false;
|
|
887
|
-
this.render();
|
|
888
|
-
return;
|
|
889
|
-
}
|
|
890
|
-
const popup = this.container.querySelector(".date-popup");
|
|
891
|
-
if (popup) {
|
|
892
|
-
this.engine.clearSelection();
|
|
893
|
-
}
|
|
894
|
-
};
|
|
895
|
-
document.addEventListener("click", this.clickOutsideHandler);
|
|
896
|
-
}
|
|
897
|
-
// Targeted update for picker year - avoids full DOM rebuild
|
|
898
|
-
updatePickerYear(year) {
|
|
899
|
-
const input = this.container.querySelector(
|
|
900
|
-
"[data-year-input]"
|
|
901
|
-
);
|
|
902
|
-
if (input) {
|
|
903
|
-
input.value = String(year);
|
|
904
|
-
}
|
|
905
|
-
const today = /* @__PURE__ */ new Date();
|
|
906
|
-
const todayYear = today.getFullYear();
|
|
907
|
-
const minYear = this.props.minYear ?? todayYear - 30;
|
|
908
|
-
const maxYear = this.props.maxYear ?? todayYear + 10;
|
|
909
|
-
const prevBtn = this.container.querySelector(
|
|
910
|
-
'[data-action="year-prev"]'
|
|
911
|
-
);
|
|
912
|
-
const nextBtn = this.container.querySelector(
|
|
913
|
-
'[data-action="year-next"]'
|
|
914
|
-
);
|
|
915
|
-
if (prevBtn) prevBtn.disabled = year <= minYear;
|
|
916
|
-
if (nextBtn) nextBtn.disabled = year >= maxYear;
|
|
917
|
-
}
|
|
918
|
-
dispatchMonthChange() {
|
|
919
|
-
const vm = this.engine.getViewModel();
|
|
920
|
-
this.container.dispatchEvent(
|
|
921
|
-
new CustomEvent("monthChange", {
|
|
922
|
-
detail: { year: vm.currentYear, month: vm.currentMonth }
|
|
923
|
-
})
|
|
924
|
-
);
|
|
925
|
-
}
|
|
926
|
-
updateEvents(events) {
|
|
927
|
-
this.engine.updateEvents(events);
|
|
928
|
-
}
|
|
929
|
-
updateTheme(theme) {
|
|
930
|
-
this.props.theme = theme;
|
|
931
|
-
this.applyTheme();
|
|
932
|
-
}
|
|
933
|
-
getCurrentDate() {
|
|
934
|
-
return this.engine.getViewModel().selectedDate;
|
|
935
|
-
}
|
|
936
|
-
goToDate(date) {
|
|
937
|
-
this.actions.jump(date.getFullYear(), date.getMonth());
|
|
938
|
-
}
|
|
939
|
-
getEngine() {
|
|
940
|
-
return this.engine;
|
|
941
|
-
}
|
|
942
|
-
destroy() {
|
|
943
|
-
if (this.unsubscribe) {
|
|
944
|
-
this.unsubscribe();
|
|
945
|
-
this.unsubscribe = null;
|
|
946
|
-
}
|
|
947
|
-
if (this.delegatedClickHandler) {
|
|
948
|
-
this.container.removeEventListener("click", this.delegatedClickHandler);
|
|
949
|
-
this.delegatedClickHandler = null;
|
|
950
|
-
}
|
|
951
|
-
if (this.delegatedInputHandler) {
|
|
952
|
-
this.container.removeEventListener("input", this.delegatedInputHandler);
|
|
953
|
-
this.delegatedInputHandler = null;
|
|
954
|
-
}
|
|
955
|
-
if (this.delegatedBlurHandler) {
|
|
956
|
-
this.container.removeEventListener(
|
|
957
|
-
"blur",
|
|
958
|
-
this.delegatedBlurHandler,
|
|
959
|
-
true
|
|
960
|
-
);
|
|
961
|
-
this.delegatedBlurHandler = null;
|
|
962
|
-
}
|
|
963
|
-
if (this.delegatedKeydownHandler) {
|
|
964
|
-
this.container.removeEventListener(
|
|
965
|
-
"keydown",
|
|
966
|
-
this.delegatedKeydownHandler
|
|
967
|
-
);
|
|
968
|
-
this.delegatedKeydownHandler = null;
|
|
969
|
-
}
|
|
970
|
-
if (this.clickOutsideHandler) {
|
|
971
|
-
document.removeEventListener("click", this.clickOutsideHandler);
|
|
972
|
-
this.clickOutsideHandler = null;
|
|
973
|
-
}
|
|
974
|
-
this.listenersAttached = false;
|
|
975
|
-
this.engine.destroy();
|
|
976
|
-
this.container.innerHTML = "";
|
|
977
|
-
this.container.classList.remove("kalendly-calendar");
|
|
978
|
-
if (this.props.className) {
|
|
979
|
-
this.container.classList.remove(this.props.className);
|
|
980
|
-
}
|
|
981
|
-
}
|
|
982
|
-
};
|
|
983
|
-
function createCalendar(props) {
|
|
984
|
-
return new VanillaCalendar(props);
|
|
985
|
-
}
|
|
986
|
-
export {
|
|
987
|
-
CalendarEngine,
|
|
988
|
-
DAYS,
|
|
989
|
-
DEFAULT_CATEGORY_COLORS,
|
|
990
|
-
MONTHS,
|
|
991
|
-
MONTHS_FULL,
|
|
992
|
-
VanillaCalendar,
|
|
993
|
-
createCalendar,
|
|
994
|
-
formatAttendees,
|
|
995
|
-
formatDateForDisplay,
|
|
996
|
-
formatTimeRange,
|
|
997
|
-
generateCalendarDates,
|
|
998
|
-
generateYears,
|
|
999
|
-
getCategoryColor,
|
|
1000
|
-
getCellClasses,
|
|
1001
|
-
getDefaultEventColor,
|
|
1002
|
-
getEventsForDate,
|
|
1003
|
-
getMonthYearText,
|
|
1004
|
-
getPopupPositionClass,
|
|
1005
|
-
hasEvents,
|
|
1006
|
-
isSameDay,
|
|
1007
|
-
isToday,
|
|
1008
|
-
isValidHexColor,
|
|
1009
|
-
mergeCategoryColors,
|
|
1010
|
-
normalizeDate,
|
|
1011
|
-
sortEventsByTime
|
|
1012
|
-
};
|
|
1013
|
-
//# sourceMappingURL=index.mjs.map
|