kalendly 0.1.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.
@@ -0,0 +1,558 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/react/index.tsx
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Calendar: () => Calendar,
24
+ CalendarEngine: () => CalendarEngine,
25
+ DAYS: () => DAYS,
26
+ DatePopup: () => DatePopup,
27
+ MONTHS: () => MONTHS,
28
+ formatDateForDisplay: () => formatDateForDisplay,
29
+ generateCalendarDates: () => generateCalendarDates,
30
+ generateYears: () => generateYears,
31
+ getCellClasses: () => getCellClasses,
32
+ getEventsForDate: () => getEventsForDate,
33
+ getMonthYearText: () => getMonthYearText,
34
+ getPopupPositionClass: () => getPopupPositionClass,
35
+ hasEvents: () => hasEvents,
36
+ isSameDay: () => isSameDay,
37
+ isToday: () => isToday,
38
+ normalizeDate: () => normalizeDate
39
+ });
40
+ module.exports = __toCommonJS(index_exports);
41
+
42
+ // src/react/components/Calendar.tsx
43
+ var import_react = require("react");
44
+
45
+ // src/core/utils.ts
46
+ var MONTHS = [
47
+ "Jan",
48
+ "Feb",
49
+ "Mar",
50
+ "Apr",
51
+ "May",
52
+ "Jun",
53
+ "Jul",
54
+ "Aug",
55
+ "Sep",
56
+ "Oct",
57
+ "Nov",
58
+ "Dec"
59
+ ];
60
+ var DAYS = [
61
+ "Sunday",
62
+ "Monday",
63
+ "Tuesday",
64
+ "Wednesday",
65
+ "Thursday",
66
+ "Friday",
67
+ "Saturday"
68
+ ];
69
+ function normalizeDate(date) {
70
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
71
+ }
72
+ function isSameDay(date1, date2) {
73
+ return normalizeDate(date1).getTime() === normalizeDate(date2).getTime();
74
+ }
75
+ function isToday(date) {
76
+ return isSameDay(date, /* @__PURE__ */ new Date());
77
+ }
78
+ function generateYears(minYear, maxYear) {
79
+ const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
80
+ const min = minYear ?? currentYear - 30;
81
+ const max = maxYear ?? currentYear + 10;
82
+ return Array.from({ length: max - min + 1 }, (_, i) => min + i);
83
+ }
84
+ function getEventsForDate(events, date) {
85
+ const normalizedTargetDate = normalizeDate(date);
86
+ return events.filter((event) => {
87
+ const eventDate = normalizeDate(new Date(event.date));
88
+ return eventDate.getTime() === normalizedTargetDate.getTime();
89
+ });
90
+ }
91
+ function hasEvents(events, date) {
92
+ return getEventsForDate(events, date).length > 0;
93
+ }
94
+ function generateCalendarDates(year, month, events = [], weekStartsOn = 0) {
95
+ const firstDay = new Date(year, month, 1);
96
+ const lastDay = new Date(year, month + 1, 0);
97
+ const daysInMonth = lastDay.getDate();
98
+ let firstDayOfWeek = firstDay.getDay();
99
+ if (weekStartsOn === 1) {
100
+ firstDayOfWeek = firstDayOfWeek === 0 ? 6 : firstDayOfWeek - 1;
101
+ }
102
+ const dates = [];
103
+ let day = 1;
104
+ for (let week = 0; week < 6; week++) {
105
+ const weekDates = [];
106
+ for (let dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++) {
107
+ if (week === 0 && dayOfWeek < firstDayOfWeek) {
108
+ weekDates.push(null);
109
+ } else if (day > daysInMonth) {
110
+ weekDates.push(null);
111
+ } else {
112
+ const currentDate = new Date(year, month, day);
113
+ const dateEvents = getEventsForDate(events, currentDate);
114
+ weekDates.push({
115
+ date: currentDate,
116
+ isCurrentMonth: true,
117
+ isToday: isToday(currentDate),
118
+ hasEvents: dateEvents.length > 0,
119
+ events: dateEvents
120
+ });
121
+ day++;
122
+ }
123
+ }
124
+ dates.push(weekDates);
125
+ if (day > daysInMonth && weekDates.every((date) => date === null)) {
126
+ break;
127
+ }
128
+ }
129
+ return dates;
130
+ }
131
+ function getPopupPositionClass(selectedDayIndex) {
132
+ if (selectedDayIndex === null) return "popup-center-bottom";
133
+ if (selectedDayIndex < 3) {
134
+ return "popup-right";
135
+ } else if (selectedDayIndex > 4) {
136
+ return "popup-left";
137
+ } else {
138
+ return "popup-center-bottom";
139
+ }
140
+ }
141
+ function getCellClasses(calendarDate) {
142
+ if (!calendarDate) return [];
143
+ const classes = [];
144
+ if (calendarDate.isToday) {
145
+ classes.push("schedule--current--exam");
146
+ }
147
+ if (calendarDate.hasEvents) {
148
+ classes.push("has--event");
149
+ }
150
+ return classes;
151
+ }
152
+ function formatDateForDisplay(date) {
153
+ return `${DAYS[date.getDay()]} ${date.getDate()}`;
154
+ }
155
+ function getMonthYearText(year, month) {
156
+ return `${MONTHS[month]} ${year}`;
157
+ }
158
+
159
+ // src/core/calendar-engine.ts
160
+ var CalendarEngine = class {
161
+ constructor(config) {
162
+ this.listeners = /* @__PURE__ */ new Set();
163
+ this.config = config;
164
+ const initialDate = config.initialDate || /* @__PURE__ */ new Date();
165
+ this.state = {
166
+ currentYear: initialDate.getFullYear(),
167
+ currentMonth: initialDate.getMonth(),
168
+ currentDate: initialDate.getDate(),
169
+ selectedDate: null,
170
+ selectedDayIndex: null,
171
+ tasks: []
172
+ };
173
+ }
174
+ /**
175
+ * Subscribe to state changes
176
+ */
177
+ subscribe(listener) {
178
+ this.listeners.add(listener);
179
+ return () => this.listeners.delete(listener);
180
+ }
181
+ /**
182
+ * Notify all listeners of state changes
183
+ */
184
+ notify() {
185
+ this.listeners.forEach((listener) => listener());
186
+ }
187
+ /**
188
+ * Get current state
189
+ */
190
+ getState() {
191
+ return { ...this.state };
192
+ }
193
+ /**
194
+ * Get view model with computed properties
195
+ */
196
+ getViewModel() {
197
+ const calendarDates = generateCalendarDates(
198
+ this.state.currentYear,
199
+ this.state.currentMonth,
200
+ this.config.events,
201
+ this.config.weekStartsOn
202
+ );
203
+ return {
204
+ ...this.state,
205
+ months: MONTHS,
206
+ days: DAYS,
207
+ years: generateYears(this.config.minYear, this.config.maxYear),
208
+ monthAndYearText: getMonthYearText(
209
+ this.state.currentYear,
210
+ this.state.currentMonth
211
+ ),
212
+ scheduleDay: this.state.selectedDate ? formatDateForDisplay(this.state.selectedDate) : "",
213
+ calendarDates,
214
+ popupPositionClass: getPopupPositionClass(this.state.selectedDayIndex)
215
+ };
216
+ }
217
+ /**
218
+ * Get actions object
219
+ */
220
+ getActions() {
221
+ return {
222
+ next: this.next.bind(this),
223
+ previous: this.previous.bind(this),
224
+ jump: this.jump.bind(this),
225
+ selectDate: this.selectDate.bind(this),
226
+ updateTasks: this.updateTasks.bind(this)
227
+ };
228
+ }
229
+ /**
230
+ * Navigate to next month
231
+ */
232
+ next() {
233
+ if (this.state.currentMonth === 11) {
234
+ this.state.currentMonth = 0;
235
+ this.state.currentYear++;
236
+ } else {
237
+ this.state.currentMonth++;
238
+ }
239
+ this.state.selectedDate = null;
240
+ this.state.selectedDayIndex = null;
241
+ this.updateTasks();
242
+ this.notify();
243
+ }
244
+ /**
245
+ * Navigate to previous month
246
+ */
247
+ previous() {
248
+ if (this.state.currentMonth === 0) {
249
+ this.state.currentMonth = 11;
250
+ this.state.currentYear--;
251
+ } else {
252
+ this.state.currentMonth--;
253
+ }
254
+ this.state.selectedDate = null;
255
+ this.state.selectedDayIndex = null;
256
+ this.updateTasks();
257
+ this.notify();
258
+ }
259
+ /**
260
+ * Jump to specific month and year
261
+ */
262
+ jump(year, month) {
263
+ this.state.currentYear = year;
264
+ this.state.currentMonth = month;
265
+ this.state.selectedDate = null;
266
+ this.state.selectedDayIndex = null;
267
+ this.updateTasks();
268
+ this.notify();
269
+ }
270
+ /**
271
+ * Select a specific date
272
+ */
273
+ selectDate(date, dayIndex) {
274
+ this.state.selectedDate = date;
275
+ this.state.selectedDayIndex = dayIndex ?? null;
276
+ this.state.currentDate = date.getDate();
277
+ this.state.currentMonth = date.getMonth();
278
+ this.state.currentYear = date.getFullYear();
279
+ this.updateTasks();
280
+ this.notify();
281
+ }
282
+ /**
283
+ * Update tasks for the currently selected date
284
+ */
285
+ updateTasks() {
286
+ if (!this.state.selectedDate) {
287
+ this.state.tasks = [];
288
+ return;
289
+ }
290
+ this.state.tasks = getEventsForDate(
291
+ this.config.events,
292
+ this.state.selectedDate
293
+ );
294
+ }
295
+ /**
296
+ * Update events configuration
297
+ */
298
+ updateEvents(events) {
299
+ this.config.events = events;
300
+ this.updateTasks();
301
+ this.notify();
302
+ }
303
+ /**
304
+ * Handle date cell click
305
+ */
306
+ handleDateClick(date, dayIndex) {
307
+ this.selectDate(date, dayIndex);
308
+ }
309
+ /**
310
+ * Check if date has events
311
+ */
312
+ hasEventsForDate(date) {
313
+ return getEventsForDate(this.config.events, date).length > 0;
314
+ }
315
+ /**
316
+ * Get events for a specific date
317
+ */
318
+ getEventsForDate(date) {
319
+ return getEventsForDate(this.config.events, date);
320
+ }
321
+ /**
322
+ * Clear selected date
323
+ */
324
+ clearSelection() {
325
+ this.state.selectedDate = null;
326
+ this.state.selectedDayIndex = null;
327
+ this.state.tasks = [];
328
+ this.notify();
329
+ }
330
+ /**
331
+ * Destroy the engine and cleanup listeners
332
+ */
333
+ destroy() {
334
+ this.listeners.clear();
335
+ }
336
+ };
337
+
338
+ // src/react/components/DatePopup.tsx
339
+ var import_jsx_runtime = require("react/jsx-runtime");
340
+ var DatePopup = ({
341
+ isVisible,
342
+ selectedDate,
343
+ events,
344
+ scheduleDay,
345
+ popupPositionClass,
346
+ onEventClick,
347
+ onClose,
348
+ renderEvent,
349
+ renderNoEvents
350
+ }) => {
351
+ if (!isVisible || !selectedDate) return null;
352
+ const handleEventClick = (event) => {
353
+ onEventClick?.(event);
354
+ };
355
+ const defaultRenderEvent = (event) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
356
+ "li",
357
+ {
358
+ className: `event--item${onEventClick ? " clickable" : ""}`,
359
+ onClick: () => handleEventClick(event),
360
+ children: event.name
361
+ },
362
+ event.id || event.name
363
+ );
364
+ const defaultRenderNoEvents = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "no-events-message", children: "No events scheduled for this day." });
365
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: `date-popup ${popupPositionClass}`, children: [
366
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
367
+ "button",
368
+ {
369
+ type: "button",
370
+ className: "popup-close",
371
+ onClick: onClose,
372
+ "aria-label": "Close",
373
+ children: "\u2715"
374
+ }
375
+ ),
376
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "schedule--wrapper", children: [
377
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "schedule--block", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "schedule--day", children: scheduleDay }) }),
378
+ events.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "event--wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { children: events.map(
379
+ (event) => renderEvent ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
380
+ "li",
381
+ {
382
+ className: `event--item${onEventClick ? " clickable" : ""}`,
383
+ onClick: () => handleEventClick(event),
384
+ children: renderEvent(event)
385
+ },
386
+ event.id || event.name
387
+ ) : defaultRenderEvent(event)
388
+ ) }) }) : renderNoEvents ? renderNoEvents() : defaultRenderNoEvents()
389
+ ] })
390
+ ] });
391
+ };
392
+
393
+ // src/react/components/Calendar.tsx
394
+ var import_jsx_runtime2 = require("react/jsx-runtime");
395
+ var Calendar = ({
396
+ events,
397
+ initialDate,
398
+ minYear,
399
+ maxYear,
400
+ weekStartsOn = 0,
401
+ onDateSelect,
402
+ onEventClick,
403
+ onMonthChange,
404
+ className = "",
405
+ style,
406
+ renderEvent,
407
+ renderNoEvents,
408
+ title = "Event Schedule"
409
+ }) => {
410
+ const engine = (0, import_react.useMemo)(
411
+ () => new CalendarEngine({
412
+ events,
413
+ initialDate,
414
+ minYear,
415
+ maxYear,
416
+ weekStartsOn
417
+ }),
418
+ []
419
+ );
420
+ const [, forceUpdate] = (0, import_react.useState)({});
421
+ const rerender = (0, import_react.useCallback)(() => forceUpdate({}), []);
422
+ (0, import_react.useEffect)(() => {
423
+ const unsubscribe = engine.subscribe(rerender);
424
+ return unsubscribe;
425
+ }, [engine, rerender]);
426
+ (0, import_react.useEffect)(() => {
427
+ engine.updateEvents(events);
428
+ }, [engine, events]);
429
+ (0, import_react.useEffect)(() => {
430
+ return () => {
431
+ engine.destroy();
432
+ };
433
+ }, [engine]);
434
+ const viewModel = engine.getViewModel();
435
+ const actions = engine.getActions();
436
+ const { selectedDate, tasks, selectedDayIndex } = viewModel;
437
+ const handleDateClick = (event) => {
438
+ const td = event.target.closest("td");
439
+ if (!td) return;
440
+ const cellContent = td.textContent?.trim();
441
+ if (!cellContent) return;
442
+ const clickedDate = new Date(
443
+ viewModel.currentYear,
444
+ viewModel.currentMonth,
445
+ parseInt(cellContent)
446
+ );
447
+ const dayIndex = td.parentNode ? Array.from(td.parentNode.children).indexOf(td) : 0;
448
+ engine.handleDateClick(clickedDate, dayIndex);
449
+ onDateSelect?.(clickedDate);
450
+ };
451
+ const handleMonthChange = () => {
452
+ onMonthChange?.(viewModel.currentYear, viewModel.currentMonth);
453
+ };
454
+ const handleYearChange = (event) => {
455
+ const year = parseInt(event.target.value);
456
+ actions.jump(year, viewModel.currentMonth);
457
+ handleMonthChange();
458
+ };
459
+ const handleMonthSelectChange = (event) => {
460
+ const month = parseInt(event.target.value);
461
+ actions.jump(viewModel.currentYear, month);
462
+ handleMonthChange();
463
+ };
464
+ const handleNext = () => {
465
+ actions.next();
466
+ handleMonthChange();
467
+ };
468
+ const handlePrevious = () => {
469
+ actions.previous();
470
+ handleMonthChange();
471
+ };
472
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `kalendly-calendar ${className}`, style, children: [
473
+ title && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "page--title", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h1", { children: title }) }),
474
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "calendar--content", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "calendar--card", children: [
475
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { className: "calendar--card--header", children: viewModel.monthAndYearText }),
476
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("table", { className: "calendar--table calendar--table--bordered", children: [
477
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tr", { children: viewModel.days.map((day) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { children: day.slice(0, 3) }, day)) }) }),
478
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tbody", { onClick: handleDateClick, children: viewModel.calendarDates.map((week, weekIndex) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tr", { children: week.map((calendarDate, dayIndex) => {
479
+ const cellClasses = getCellClasses(calendarDate);
480
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
481
+ "td",
482
+ {
483
+ className: cellClasses.join(" "),
484
+ children: calendarDate?.date.getDate() || ""
485
+ },
486
+ `${weekIndex}-${dayIndex}`
487
+ );
488
+ }) }, weekIndex)) })
489
+ ] }),
490
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "calendar--navigation--buttons", children: [
491
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
492
+ "button",
493
+ {
494
+ className: "calendar--navigation--btn",
495
+ onClick: handlePrevious,
496
+ children: "Previous"
497
+ }
498
+ ),
499
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "calendar--navigation--btn", onClick: handleNext, children: "Next" })
500
+ ] }),
501
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { className: "calendar--form--jump", children: [
502
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "calendar--lead", children: "Jump To:" }),
503
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "calendar--form--jump--item", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
504
+ "select",
505
+ {
506
+ value: viewModel.currentMonth,
507
+ onChange: handleMonthSelectChange,
508
+ "aria-label": "Select month",
509
+ children: viewModel.months.map((month, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: index, children: month }, index))
510
+ }
511
+ ) }) }),
512
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "calendar--form--jump--item", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
513
+ "select",
514
+ {
515
+ value: viewModel.currentYear,
516
+ onChange: handleYearChange,
517
+ "aria-label": "Select year",
518
+ children: viewModel.years.map((year) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: year, children: year }, year))
519
+ }
520
+ ) }) })
521
+ ] }),
522
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
523
+ DatePopup,
524
+ {
525
+ isVisible: !!selectedDate,
526
+ selectedDate,
527
+ events: tasks,
528
+ scheduleDay: viewModel.scheduleDay,
529
+ popupPositionClass: viewModel.popupPositionClass,
530
+ onClose: () => engine.clearSelection(),
531
+ onEventClick,
532
+ renderEvent,
533
+ renderNoEvents
534
+ }
535
+ )
536
+ ] }) })
537
+ ] });
538
+ };
539
+ // Annotate the CommonJS export names for ESM import in node:
540
+ 0 && (module.exports = {
541
+ Calendar,
542
+ CalendarEngine,
543
+ DAYS,
544
+ DatePopup,
545
+ MONTHS,
546
+ formatDateForDisplay,
547
+ generateCalendarDates,
548
+ generateYears,
549
+ getCellClasses,
550
+ getEventsForDate,
551
+ getMonthYearText,
552
+ getPopupPositionClass,
553
+ hasEvents,
554
+ isSameDay,
555
+ isToday,
556
+ normalizeDate
557
+ });
558
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/react/index.tsx","../../src/react/components/Calendar.tsx","../../src/core/utils.ts","../../src/core/calendar-engine.ts","../../src/react/components/DatePopup.tsx"],"sourcesContent":["export { Calendar } from './components/Calendar';\nexport { DatePopup } from './components/DatePopup';\nexport * from './types';\n\n// Re-export core types and utilities for convenience\nexport * from '../core';\n","import React, { useEffect, useState, useCallback, useMemo } from 'react';\nimport { CalendarEngine, getCellClasses } from '../../core';\nimport { CalendarComponentProps } from '../types';\nimport { DatePopup } from './DatePopup';\n\nexport const Calendar: React.FC<CalendarComponentProps> = ({\n events,\n initialDate,\n minYear,\n maxYear,\n weekStartsOn = 0,\n onDateSelect,\n onEventClick,\n onMonthChange,\n className = '',\n style,\n renderEvent,\n renderNoEvents,\n title = 'Event Schedule',\n}) => {\n const engine = useMemo(\n () =>\n new CalendarEngine({\n events,\n initialDate,\n minYear,\n maxYear,\n weekStartsOn,\n }),\n []\n );\n\n const [, forceUpdate] = useState({});\n const rerender = useCallback(() => forceUpdate({}), []);\n\n useEffect(() => {\n const unsubscribe = engine.subscribe(rerender);\n return unsubscribe;\n }, [engine, rerender]);\n\n useEffect(() => {\n engine.updateEvents(events);\n }, [engine, events]);\n\n useEffect(() => {\n return () => {\n engine.destroy();\n };\n }, [engine]);\n\n const viewModel = engine.getViewModel();\n const actions = engine.getActions();\n const { selectedDate, tasks, selectedDayIndex } = viewModel;\n\n const handleDateClick = (\n event: React.MouseEvent<HTMLTableSectionElement>\n ) => {\n const td = (event.target as HTMLElement).closest('td');\n if (!td) return;\n\n const cellContent = td.textContent?.trim();\n if (!cellContent) return;\n\n const clickedDate = new Date(\n viewModel.currentYear,\n viewModel.currentMonth,\n parseInt(cellContent)\n );\n\n const dayIndex = td.parentNode\n ? Array.from(td.parentNode.children).indexOf(td)\n : 0;\n engine.handleDateClick(clickedDate, dayIndex);\n\n onDateSelect?.(clickedDate);\n };\n\n const handleMonthChange = () => {\n onMonthChange?.(viewModel.currentYear, viewModel.currentMonth);\n };\n\n const handleYearChange = (event: React.ChangeEvent<HTMLSelectElement>) => {\n const year = parseInt(event.target.value);\n actions.jump(year, viewModel.currentMonth);\n handleMonthChange();\n };\n\n const handleMonthSelectChange = (\n event: React.ChangeEvent<HTMLSelectElement>\n ) => {\n const month = parseInt(event.target.value);\n actions.jump(viewModel.currentYear, month);\n handleMonthChange();\n };\n\n const handleNext = () => {\n actions.next();\n handleMonthChange();\n };\n\n const handlePrevious = () => {\n actions.previous();\n handleMonthChange();\n };\n\n return (\n <div className={`kalendly-calendar ${className}`} style={style}>\n {title && (\n <div className=\"page--title\">\n <h1>{title}</h1>\n </div>\n )}\n\n <div className=\"calendar--content\">\n <div className=\"calendar--card\">\n <h3 className=\"calendar--card--header\">\n {viewModel.monthAndYearText}\n </h3>\n\n <table className=\"calendar--table calendar--table--bordered\">\n <thead>\n <tr>\n {viewModel.days.map(day => (\n <th key={day}>{day.slice(0, 3)}</th>\n ))}\n </tr>\n </thead>\n <tbody onClick={handleDateClick}>\n {viewModel.calendarDates.map((week, weekIndex) => (\n <tr key={weekIndex}>\n {week.map((calendarDate, dayIndex) => {\n const cellClasses = getCellClasses(calendarDate);\n return (\n <td\n key={`${weekIndex}-${dayIndex}`}\n className={cellClasses.join(' ')}\n >\n {calendarDate?.date.getDate() || ''}\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n\n <div className=\"calendar--navigation--buttons\">\n <button\n className=\"calendar--navigation--btn\"\n onClick={handlePrevious}\n >\n Previous\n </button>\n <button className=\"calendar--navigation--btn\" onClick={handleNext}>\n Next\n </button>\n </div>\n\n <form className=\"calendar--form--jump\">\n <div className=\"calendar--lead\">Jump To:</div>\n <div>\n <label className=\"calendar--form--jump--item\">\n <select\n value={viewModel.currentMonth}\n onChange={handleMonthSelectChange}\n aria-label=\"Select month\"\n >\n {viewModel.months.map((month, index) => (\n <option key={index} value={index}>\n {month}\n </option>\n ))}\n </select>\n </label>\n </div>\n <div>\n <label className=\"calendar--form--jump--item\">\n <select\n value={viewModel.currentYear}\n onChange={handleYearChange}\n aria-label=\"Select year\"\n >\n {viewModel.years.map(year => (\n <option key={year} value={year}>\n {year}\n </option>\n ))}\n </select>\n </label>\n </div>\n </form>\n\n <DatePopup\n isVisible={!!selectedDate}\n selectedDate={selectedDate}\n events={tasks}\n scheduleDay={viewModel.scheduleDay}\n popupPositionClass={viewModel.popupPositionClass}\n onClose={() => engine.clearSelection()}\n onEventClick={onEventClick}\n renderEvent={renderEvent}\n renderNoEvents={renderNoEvents}\n />\n </div>\n </div>\n </div>\n );\n};\n","import { CalendarEvent, CalendarDate } from './types';\n\nexport const MONTHS = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n];\n\nexport const DAYS = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n];\n\n/**\n * Normalizes a date to midnight (00:00:00) for comparison purposes\n */\nexport function normalizeDate(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);\n}\n\n/**\n * Checks if two dates are the same day\n */\nexport function isSameDay(date1: Date, date2: Date): boolean {\n return normalizeDate(date1).getTime() === normalizeDate(date2).getTime();\n}\n\n/**\n * Checks if a date is today\n */\nexport function isToday(date: Date): boolean {\n return isSameDay(date, new Date());\n}\n\n/**\n * Generates an array of years for the year selector\n */\nexport function generateYears(minYear?: number, maxYear?: number): number[] {\n const currentYear = new Date().getFullYear();\n const min = minYear ?? currentYear - 30;\n const max = maxYear ?? currentYear + 10;\n\n return Array.from({ length: max - min + 1 }, (_, i) => min + i);\n}\n\n/**\n * Gets events for a specific date\n */\nexport function getEventsForDate(\n events: CalendarEvent[],\n date: Date\n): CalendarEvent[] {\n const normalizedTargetDate = normalizeDate(date);\n\n return events.filter(event => {\n const eventDate = normalizeDate(new Date(event.date));\n return eventDate.getTime() === normalizedTargetDate.getTime();\n });\n}\n\n/**\n * Checks if a date has any events\n */\nexport function hasEvents(events: CalendarEvent[], date: Date): boolean {\n return getEventsForDate(events, date).length > 0;\n}\n\n/**\n * Generates calendar dates for a given month and year\n */\nexport function generateCalendarDates(\n year: number,\n month: number,\n events: CalendarEvent[] = [],\n weekStartsOn: 0 | 1 = 0\n): (CalendarDate | null)[][] {\n const firstDay = new Date(year, month, 1);\n const lastDay = new Date(year, month + 1, 0);\n const daysInMonth = lastDay.getDate();\n\n // Adjust first day based on week start preference\n let firstDayOfWeek = firstDay.getDay();\n if (weekStartsOn === 1) {\n firstDayOfWeek = firstDayOfWeek === 0 ? 6 : firstDayOfWeek - 1;\n }\n\n const dates: (CalendarDate | null)[][] = [];\n let day = 1;\n\n for (let week = 0; week < 6; week++) {\n const weekDates: (CalendarDate | null)[] = [];\n\n for (let dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++) {\n if (week === 0 && dayOfWeek < firstDayOfWeek) {\n weekDates.push(null);\n } else if (day > daysInMonth) {\n weekDates.push(null);\n } else {\n const currentDate = new Date(year, month, day);\n const dateEvents = getEventsForDate(events, currentDate);\n\n weekDates.push({\n date: currentDate,\n isCurrentMonth: true,\n isToday: isToday(currentDate),\n hasEvents: dateEvents.length > 0,\n events: dateEvents,\n });\n day++;\n }\n }\n\n dates.push(weekDates);\n\n // Break early if we've filled all days and the rest of the row is empty\n if (day > daysInMonth && weekDates.every(date => date === null)) {\n break;\n }\n }\n\n return dates;\n}\n\n/**\n * Gets the popup position class based on the selected day index\n */\nexport function getPopupPositionClass(selectedDayIndex: number | null): string {\n if (selectedDayIndex === null) return 'popup-center-bottom';\n\n if (selectedDayIndex < 3) {\n return 'popup-right';\n } else if (selectedDayIndex > 4) {\n return 'popup-left';\n } else {\n return 'popup-center-bottom';\n }\n}\n\n/**\n * Gets CSS classes for a calendar cell\n */\nexport function getCellClasses(calendarDate: CalendarDate | null): string[] {\n if (!calendarDate) return [];\n\n const classes: string[] = [];\n\n if (calendarDate.isToday) {\n classes.push('schedule--current--exam');\n }\n\n if (calendarDate.hasEvents) {\n classes.push('has--event');\n }\n\n return classes;\n}\n\n/**\n * Formats a date for display\n */\nexport function formatDateForDisplay(date: Date): string {\n return `${DAYS[date.getDay()]} ${date.getDate()}`;\n}\n\n/**\n * Gets month and year text for display\n */\nexport function getMonthYearText(year: number, month: number): string {\n return `${MONTHS[month]} ${year}`;\n}\n","import {\n CalendarEvent,\n CalendarState,\n CalendarConfig,\n CalendarActions,\n CalendarViewModel,\n} from './types';\nimport {\n generateCalendarDates,\n getEventsForDate,\n generateYears,\n getPopupPositionClass,\n getMonthYearText,\n formatDateForDisplay,\n MONTHS,\n DAYS,\n} from './utils';\n\nexport class CalendarEngine {\n private state: CalendarState;\n private config: CalendarConfig;\n private listeners: Set<() => void> = new Set();\n\n constructor(config: CalendarConfig) {\n this.config = config;\n\n const initialDate = config.initialDate || new Date();\n this.state = {\n currentYear: initialDate.getFullYear(),\n currentMonth: initialDate.getMonth(),\n currentDate: initialDate.getDate(),\n selectedDate: null,\n selectedDayIndex: null,\n tasks: [],\n };\n }\n\n /**\n * Subscribe to state changes\n */\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Notify all listeners of state changes\n */\n private notify(): void {\n this.listeners.forEach(listener => listener());\n }\n\n /**\n * Get current state\n */\n getState(): CalendarState {\n return { ...this.state };\n }\n\n /**\n * Get view model with computed properties\n */\n getViewModel(): CalendarViewModel {\n const calendarDates = generateCalendarDates(\n this.state.currentYear,\n this.state.currentMonth,\n this.config.events,\n this.config.weekStartsOn\n );\n\n return {\n ...this.state,\n months: MONTHS,\n days: DAYS,\n years: generateYears(this.config.minYear, this.config.maxYear),\n monthAndYearText: getMonthYearText(\n this.state.currentYear,\n this.state.currentMonth\n ),\n scheduleDay: this.state.selectedDate\n ? formatDateForDisplay(this.state.selectedDate)\n : '',\n calendarDates,\n popupPositionClass: getPopupPositionClass(this.state.selectedDayIndex),\n };\n }\n\n /**\n * Get actions object\n */\n getActions(): CalendarActions {\n return {\n next: this.next.bind(this),\n previous: this.previous.bind(this),\n jump: this.jump.bind(this),\n selectDate: this.selectDate.bind(this),\n updateTasks: this.updateTasks.bind(this),\n };\n }\n\n /**\n * Navigate to next month\n */\n private next(): void {\n if (this.state.currentMonth === 11) {\n this.state.currentMonth = 0;\n this.state.currentYear++;\n } else {\n this.state.currentMonth++;\n }\n\n this.state.selectedDate = null;\n this.state.selectedDayIndex = null;\n this.updateTasks();\n this.notify();\n }\n\n /**\n * Navigate to previous month\n */\n private previous(): void {\n if (this.state.currentMonth === 0) {\n this.state.currentMonth = 11;\n this.state.currentYear--;\n } else {\n this.state.currentMonth--;\n }\n\n this.state.selectedDate = null;\n this.state.selectedDayIndex = null;\n this.updateTasks();\n this.notify();\n }\n\n /**\n * Jump to specific month and year\n */\n private jump(year: number, month: number): void {\n this.state.currentYear = year;\n this.state.currentMonth = month;\n this.state.selectedDate = null;\n this.state.selectedDayIndex = null;\n this.updateTasks();\n this.notify();\n }\n\n /**\n * Select a specific date\n */\n private selectDate(date: Date, dayIndex?: number): void {\n this.state.selectedDate = date;\n this.state.selectedDayIndex = dayIndex ?? null;\n this.state.currentDate = date.getDate();\n this.state.currentMonth = date.getMonth();\n this.state.currentYear = date.getFullYear();\n this.updateTasks();\n this.notify();\n }\n\n /**\n * Update tasks for the currently selected date\n */\n private updateTasks(): void {\n if (!this.state.selectedDate) {\n this.state.tasks = [];\n return;\n }\n\n this.state.tasks = getEventsForDate(\n this.config.events,\n this.state.selectedDate\n );\n }\n\n /**\n * Update events configuration\n */\n updateEvents(events: CalendarEvent[]): void {\n this.config.events = events;\n this.updateTasks();\n this.notify();\n }\n\n /**\n * Handle date cell click\n */\n handleDateClick(date: Date, dayIndex?: number): void {\n this.selectDate(date, dayIndex);\n }\n\n /**\n * Check if date has events\n */\n hasEventsForDate(date: Date): boolean {\n return getEventsForDate(this.config.events, date).length > 0;\n }\n\n /**\n * Get events for a specific date\n */\n getEventsForDate(date: Date): CalendarEvent[] {\n return getEventsForDate(this.config.events, date);\n }\n\n /**\n * Clear selected date\n */\n clearSelection(): void {\n this.state.selectedDate = null;\n this.state.selectedDayIndex = null;\n this.state.tasks = [];\n this.notify();\n }\n\n /**\n * Destroy the engine and cleanup listeners\n */\n destroy(): void {\n this.listeners.clear();\n }\n}\n","import React from 'react';\nimport { DatePopupProps } from '../types';\n\nexport const DatePopup: React.FC<DatePopupProps> = ({\n isVisible,\n selectedDate,\n events,\n scheduleDay,\n popupPositionClass,\n onEventClick,\n onClose,\n renderEvent,\n renderNoEvents,\n}) => {\n if (!isVisible || !selectedDate) return null;\n\n const handleEventClick = (event: any) => {\n onEventClick?.(event);\n };\n\n const defaultRenderEvent = (event: any) => (\n <li\n key={event.id || event.name}\n className={`event--item${onEventClick ? ' clickable' : ''}`}\n onClick={() => handleEventClick(event)}\n >\n {event.name}\n </li>\n );\n\n const defaultRenderNoEvents = () => (\n <div className=\"no-events-message\">No events scheduled for this day.</div>\n );\n\n return (\n <div className={`date-popup ${popupPositionClass}`}>\n <button\n type=\"button\"\n className=\"popup-close\"\n onClick={onClose}\n aria-label=\"Close\"\n >\n ✕\n </button>\n <div className=\"schedule--wrapper\">\n <div className=\"schedule--block\">\n <h2 className=\"schedule--day\">{scheduleDay}</h2>\n </div>\n\n {events.length > 0 ? (\n <div className=\"event--wrapper\">\n <ul>\n {events.map(event =>\n renderEvent ? (\n <li\n key={event.id || event.name}\n className={`event--item${onEventClick ? ' clickable' : ''}`}\n onClick={() => handleEventClick(event)}\n >\n {renderEvent(event)}\n </li>\n ) : (\n defaultRenderEvent(event)\n )\n )}\n </ul>\n </div>\n ) : renderNoEvents ? (\n renderNoEvents()\n ) : (\n defaultRenderNoEvents()\n )}\n </div>\n </div>\n );\n};\n"],"mappings":"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","names":["import_jsx_runtime"]}