kalendly 0.2.1 → 0.2.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/web-components/CalendarElement.ts","../src/core/utils.ts","../src/core/calendar-engine.ts"],"sourcesContent":["import {\n CalendarEngine,\n getCellClasses,\n formatTimeRange,\n formatAttendees,\n MONTHS_FULL,\n MONTHS,\n} from '../core';\nimport type { CalendarEvent, CalendarTheme, CategoryColorMap } from '../core';\n\nconst isSameDay = (a: Date, b: Date): boolean =>\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate();\n\nexport class CalendarElement extends HTMLElement {\n static observedAttributes = [\n 'initial-date',\n 'min-year',\n 'max-year',\n 'week-starts-on',\n 'title',\n 'use-short-month-names',\n 'availability-mode',\n 'selectable',\n 'loading',\n ];\n\n private engine: CalendarEngine | null = null;\n private unsubscribe: (() => void) | null = null;\n private actions: ReturnType<CalendarEngine['getActions']> | null = null;\n private pickerOpen = false;\n private yearInput = '';\n private yearInputValid = true;\n private listenersAttached = false;\n\n private clickOutsideHandler: ((e: MouseEvent) => void) | null = null;\n private delegatedClickHandler: ((e: MouseEvent) => void) | null = null;\n private delegatedInputHandler: ((e: Event) => void) | null = null;\n private delegatedBlurHandler: ((e: FocusEvent) => void) | null = null;\n private delegatedKeydownHandler: ((e: KeyboardEvent) => void) | null = null;\n\n // Rich property backing fields\n private _events: CalendarEvent[] = [];\n private _theme: CalendarTheme | null = null;\n private _categoryColors: CategoryColorMap | null = null;\n private _renderEvent: ((e: CalendarEvent) => string) | null = null;\n private _renderNoEvents: (() => string) | null = null;\n\n // Selection state (availability mode — range)\n private _rangeStart: Date | null = null;\n private _rangeEnd: Date | null = null;\n private _timeRangeDate: Date | null = null;\n private _timeRangeStart: string | null = null;\n private _timeRangeEnd: string | null = null;\n private _timeRangeComplete = false;\n\n get events(): CalendarEvent[] {\n return this._events;\n }\n\n set events(val: CalendarEvent[]) {\n this._events = val;\n if (this.engine) {\n this.engine.updateEvents(val);\n }\n }\n\n set theme(val: CalendarTheme) {\n this._theme = val;\n this.applyTheme();\n }\n\n set categoryColors(val: CategoryColorMap) {\n this._categoryColors = val;\n if (this.engine) {\n this.engine.updateCategoryColors(val);\n }\n }\n\n set renderEvent(val: (e: CalendarEvent) => string) {\n this._renderEvent = val;\n if (this.engine) this.render();\n // ignored when availability-mode attribute is set\n }\n\n set renderNoEvents(val: () => string) {\n this._renderNoEvents = val;\n if (this.engine) this.render();\n // ignored when availability-mode attribute is set\n }\n\n get loading(): boolean {\n return this.hasAttribute('loading');\n }\n\n set loading(val: boolean) {\n if (val) this.setAttribute('loading', '');\n else this.removeAttribute('loading');\n }\n\n connectedCallback(): void {\n this.classList.add('kalendly-calendar');\n this.initEngine();\n this.render();\n }\n\n disconnectedCallback(): void {\n this.cleanup();\n this.classList.remove('kalendly-calendar');\n this.innerHTML = '';\n }\n\n attributeChangedCallback(\n name: string,\n oldVal: string | null,\n newVal: string | null\n ): void {\n if (oldVal === newVal) return;\n if (name === 'loading') {\n this.render();\n return;\n }\n if (name === 'selectable' && newVal === null) {\n this._rangeStart = null;\n this._rangeEnd = null;\n this._timeRangeDate = null;\n this._timeRangeStart = null;\n this._timeRangeEnd = null;\n this._timeRangeComplete = false;\n }\n this.reinit();\n }\n\n private get minYear(): number {\n const val = this.getAttribute('min-year');\n return val ? parseInt(val, 10) : new Date().getFullYear() - 30;\n }\n\n private get maxYear(): number {\n const val = this.getAttribute('max-year');\n return val ? parseInt(val, 10) : new Date().getFullYear() + 10;\n }\n\n private initEngine(): void {\n const initialDateAttr = this.getAttribute('initial-date');\n const initialDate = initialDateAttr ? new Date(initialDateAttr) : undefined;\n const weekStartsOnAttr = this.getAttribute('week-starts-on');\n const weekStartsOn: 0 | 1 = weekStartsOnAttr === '1' ? 1 : 0;\n\n this.engine = new CalendarEngine({\n events: this._events,\n initialDate,\n minYear: this.minYear,\n maxYear: this.maxYear,\n weekStartsOn,\n categoryColors: this._categoryColors ?? undefined,\n });\n\n this.actions = this.engine.getActions();\n this.applyTheme();\n\n this.unsubscribe = this.engine.subscribe(() => {\n this.render();\n });\n }\n\n private reinit(): void {\n if (!this.engine) return;\n this.cleanup();\n this.initEngine();\n this.render();\n }\n\n private cleanup(): void {\n if (this.unsubscribe) {\n this.unsubscribe();\n this.unsubscribe = null;\n }\n\n if (this.delegatedClickHandler) {\n this.removeEventListener('click', this.delegatedClickHandler);\n this.delegatedClickHandler = null;\n }\n if (this.delegatedInputHandler) {\n this.removeEventListener('input', this.delegatedInputHandler);\n this.delegatedInputHandler = null;\n }\n if (this.delegatedBlurHandler) {\n this.removeEventListener('blur', this.delegatedBlurHandler, true);\n this.delegatedBlurHandler = null;\n }\n if (this.delegatedKeydownHandler) {\n this.removeEventListener('keydown', this.delegatedKeydownHandler);\n this.delegatedKeydownHandler = null;\n }\n if (this.clickOutsideHandler) {\n document.removeEventListener('click', this.clickOutsideHandler);\n this.clickOutsideHandler = null;\n }\n\n this.listenersAttached = false;\n\n if (this.engine) {\n this.engine.destroy();\n this.engine = null;\n }\n\n this.actions = null;\n }\n\n private applyTheme(): void {\n if (!this._theme) return;\n const root = document.documentElement;\n const t = this._theme;\n if (t.primary)\n root.style.setProperty('--calendar-primary-color', t.primary);\n if (t.secondary)\n root.style.setProperty('--calendar-secondary-color', t.secondary);\n if (t.tertiary)\n root.style.setProperty('--calendar-tertiary-color', t.tertiary);\n if (t.textColor)\n root.style.setProperty('--calendar-text-color', t.textColor);\n if (t.textLight)\n root.style.setProperty('--calendar-text-light', t.textLight);\n if (t.background)\n root.style.setProperty('--calendar-background', t.background);\n if (t.cellHover)\n root.style.setProperty('--calendar-cell-hover', t.cellHover);\n if (t.borderColor)\n root.style.setProperty('--calendar-border-color', t.borderColor);\n if (t.todayOutline)\n root.style.setProperty('--calendar-today-outline', t.todayOutline);\n if (t.selectedBg)\n root.style.setProperty('--calendar-selected-bg', t.selectedBg);\n if (t.eventIndicator)\n root.style.setProperty('--calendar-event-indicator', t.eventIndicator);\n }\n\n private render(): void {\n if (!this.engine) return;\n\n const viewModel = this.engine.getViewModel();\n const useShortMonths = this.hasAttribute('use-short-month-names');\n const title = this.getAttribute('title');\n const minYear = this.minYear;\n const maxYear = this.maxYear;\n const availabilityMode = this.getAttribute('availability-mode');\n const selectable = this.hasAttribute('selectable');\n const isLoading = this.loading;\n\n const today = new Date();\n const todayMonth = today.getMonth();\n const todayYear = today.getFullYear();\n const isCurrentMonth =\n viewModel.currentYear === todayYear &&\n viewModel.currentMonth === todayMonth;\n\n const showScrollHint = viewModel.tasks.length > 3;\n\n const defaultRenderEvent = (event: CalendarEvent) => {\n const timeRange = formatTimeRange(event);\n const attendeesList = formatAttendees(event.attendees);\n\n let borderColor = event.color || '#3b82f6';\n if (event.category) {\n borderColor = this.engine!.getCategoryColor(event.category);\n }\n\n const getCategoryLabel = (category?: string) => {\n const labels: Record<string, string> = {\n work: 'WORK',\n personal: 'PERSONAL',\n meeting: 'MEETING',\n deadline: 'DEADLINE',\n appointment: 'APPOINTMENT',\n other: 'OTHER',\n };\n return category ? labels[category] || category.toUpperCase() : '';\n };\n\n const getPriorityLabel = (priority?: string) => {\n const labels: Record<string, string> = {\n high: 'HIGH',\n medium: 'MEDIUM',\n low: 'LOW',\n };\n return priority ? labels[priority] || priority.toUpperCase() : '';\n };\n\n const getStatusLabel = (status?: string) => {\n const labels: Record<string, string> = {\n completed: 'COMPLETED',\n cancelled: 'CANCELLED',\n tentative: 'TENTATIVE',\n scheduled: 'SCHEDULED',\n };\n return status ? labels[status] || status.toUpperCase() : '';\n };\n\n return `\n <div class=\"event-card\" style=\"border-left-color: ${borderColor}\">\n <div class=\"event-header\">\n <div class=\"event-title\">${event.name}</div>\n <div class=\"event-badges\">\n ${event.category ? `<span class=\"badge category-${event.category}\">${getCategoryLabel(event.category)}</span>` : ''}\n ${event.priority ? `<span class=\"badge priority-${event.priority}\">${getPriorityLabel(event.priority)}</span>` : ''}\n ${event.status && event.status !== 'scheduled' ? `<span class=\"badge status-${event.status}\">${getStatusLabel(event.status)}</span>` : ''}\n </div>\n </div>\n\n ${\n timeRange\n ? `\n <div class=\"event-time\">\n <span class=\"event-time-label\">Time:</span>\n <span class=\"event-time-value\">${timeRange}</span>\n </div>\n `\n : ''\n }\n\n ${\n event.description\n ? `\n <div class=\"event-description\">${event.description}</div>\n `\n : ''\n }\n\n ${\n event.location\n ? `\n <div class=\"event-time\">\n <span class=\"event-time-label\">Location:</span>\n <span class=\"event-time-value\">${event.location}</span>\n </div>\n `\n : ''\n }\n\n ${\n attendeesList\n ? `\n <div class=\"event-time\">\n <span class=\"event-time-label\">Attendees:</span>\n <span class=\"event-time-value\">${attendeesList}</span>\n </div>\n `\n : ''\n }\n\n ${\n event.organizer\n ? `\n <div class=\"event-time\">\n <span class=\"event-time-label\">Organizer:</span>\n <span class=\"event-time-value\">${event.organizer}</span>\n </div>\n `\n : ''\n }\n\n ${\n event.notes\n ? `\n <div class=\"event-time\">\n <span class=\"event-time-label\">Notes:</span>\n <span class=\"event-time-value\">${event.notes}</span>\n </div>\n `\n : ''\n }\n\n ${\n event.url\n ? `\n <div class=\"event-time\">\n <a href=\"${event.url}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"event-link\">\n View Details →\n </a>\n </div>\n `\n : ''\n }\n\n ${\n event.tags && event.tags.length > 0\n ? `\n <div class=\"event-tags\">\n ${event.tags.map((tag: string) => `<span class=\"event-tag\">${tag}</span>`).join('')}\n </div>\n `\n : ''\n }\n </div>\n `;\n };\n\n const defaultRenderNoEvents = () =>\n '<div class=\"no-events-message\">No events scheduled for this day.</div>';\n\n const renderEvent = this._renderEvent || defaultRenderEvent;\n const renderNoEvents = this._renderNoEvents || defaultRenderNoEvents;\n\n const renderTimeGrid = (events: CalendarEvent[], date: Date): string => {\n const isHourBooked = (hour: number): boolean =>\n events.some(event => {\n if (!event.startTime || !event.endTime) return true;\n const [startH] = (event.startTime as string).split(':').map(Number);\n const [endH] = (event.endTime as string).split(':').map(Number);\n return hour >= startH && hour < endH;\n });\n\n const slots = Array.from({ length: 24 }, (_, hour) => {\n const startTime = `${String(hour).padStart(2, '0')}:00`;\n const endTime = `${String(hour + 1).padStart(2, '0')}:00`;\n const booked = isHourBooked(hour);\n\n const inTimeRange =\n !booked &&\n selectable &&\n this._timeRangeStart !== null &&\n this._timeRangeEnd !== null &&\n isSameDay(this._timeRangeDate!, date) &&\n startTime >= this._timeRangeStart &&\n endTime <= this._timeRangeEnd;\n\n const isRangeStart = inTimeRange && startTime === this._timeRangeStart;\n const isRangeEnd = inTimeRange && endTime === this._timeRangeEnd;\n const isInRange = inTimeRange && !isRangeStart && !isRangeEnd;\n\n const slotClasses = [\n 'time-grid__slot',\n booked ? 'time-grid__slot--booked' : 'time-grid__slot--free',\n isRangeStart ? 'time-grid__slot--range-start' : '',\n isRangeEnd ? 'time-grid__slot--range-end' : '',\n isInRange ? 'time-grid__slot--in-range' : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n const slotAttrs =\n !booked && selectable\n ? `data-action=\"select-slot\" data-start-time=\"${startTime}\" data-end-time=\"${endTime}\" data-date=\"${date.toISOString()}\"`\n : '';\n\n return `\n <div class=\"${slotClasses}\" ${slotAttrs}>\n <span class=\"time-grid__label\">${startTime}</span>\n <span class=\"time-grid__status\">${booked ? 'Booked' : 'Available'}</span>\n </div>`;\n });\n\n return `<div class=\"time-grid\">${slots.join('')}</div>`;\n };\n\n const html = `\n ${\n title\n ? `\n <div class=\"page--title\">\n <h1>${title}</h1>\n </div>\n `\n : ''\n }\n\n <div class=\"calendar--content\">\n <div class=\"calendar--card\">\n <div class=\"calendar--nav-header\">\n <button type=\"button\" class=\"calendar--nav-arrow\" data-action=\"previous\" aria-label=\"Previous month\">\n &#8249;\n </button>\n\n <div class=\"calendar--picker-container\" data-picker-container>\n <button\n type=\"button\"\n class=\"calendar--picker-btn\"\n data-action=\"toggle-picker\"\n aria-expanded=\"${this.pickerOpen ? 'true' : 'false'}\"\n aria-haspopup=\"true\"\n >\n ${\n useShortMonths\n ? `${MONTHS[viewModel.currentMonth]} ${viewModel.currentYear}`\n : viewModel.monthAndYearText\n }\n <span class=\"calendar--picker-chevron\">&#9662;</span>\n </button>\n\n ${\n this.pickerOpen\n ? `\n <div class=\"calendar--picker-dropdown\">\n <div class=\"calendar--picker-year-row\">\n <button\n type=\"button\"\n class=\"calendar--picker-year-arrow\"\n data-action=\"year-prev\"\n ${viewModel.currentYear <= minYear ? 'disabled' : ''}\n aria-label=\"Previous year\"\n >&#8249;</button>\n <input\n type=\"text\"\n class=\"calendar--picker-year-input${!this.yearInputValid ? ' invalid' : ''}\"\n value=\"${this.yearInput || viewModel.currentYear}\"\n data-year-input\n aria-label=\"Year\"\n />\n <button\n type=\"button\"\n class=\"calendar--picker-year-arrow\"\n data-action=\"year-next\"\n ${viewModel.currentYear >= maxYear ? 'disabled' : ''}\n aria-label=\"Next year\"\n >&#8250;</button>\n </div>\n\n <div class=\"calendar--picker-months\">\n ${(useShortMonths ? MONTHS : MONTHS_FULL)\n .map((month, index) => {\n const isSelected = index === viewModel.currentMonth;\n const isCurrent =\n index === todayMonth &&\n viewModel.currentYear === todayYear;\n return `\n <button\n type=\"button\"\n class=\"calendar--picker-month${isSelected ? ' selected' : ''}${isCurrent ? ' current-month' : ''}\"\n data-action=\"select-month\"\n data-month=\"${index}\"\n >${month}</button>\n `;\n })\n .join('')}\n </div>\n </div>\n `\n : ''\n }\n </div>\n\n <button\n type=\"button\"\n class=\"calendar--today-btn\"\n data-action=\"today\"\n ${isCurrentMonth ? 'disabled' : ''}\n >Today</button>\n\n <button type=\"button\" class=\"calendar--nav-arrow\" data-action=\"next\" aria-label=\"Next month\">\n &#8250;\n </button>\n </div>\n\n <table class=\"calendar--table calendar--table--bordered\">\n <thead>\n <tr>\n ${viewModel.days.map(day => `<th>${day.slice(0, 3)}</th>`).join('')}\n </tr>\n </thead>\n <tbody data-calendar-body>\n ${\n isLoading\n ? Array.from(\n { length: 6 },\n () =>\n `<tr>${Array.from(\n { length: 7 },\n () =>\n `<td class=\"calendar--skeleton\" aria-hidden=\"true\"></td>`\n ).join('')}</tr>`\n ).join('')\n : viewModel.calendarDates\n .map(\n week => `\n <tr>\n ${week\n .map((calendarDate, dayIndex) => {\n const classes = getCellClasses(calendarDate);\n if (availabilityMode && calendarDate.isCurrentMonth) {\n classes.push(\n calendarDate.hasEvents\n ? 'availability--booked'\n : 'availability--free'\n );\n }\n if (\n availabilityMode === 'day' &&\n selectable &&\n calendarDate.isCurrentMonth\n ) {\n const d = calendarDate.date;\n if (\n this._rangeStart &&\n isSameDay(d, this._rangeStart)\n )\n classes.push('availability--range-start');\n if (this._rangeEnd && isSameDay(d, this._rangeEnd))\n classes.push('availability--range-end');\n if (this._rangeStart && this._rangeEnd) {\n if (d > this._rangeStart && d < this._rangeEnd)\n classes.push('availability--in-range');\n }\n }\n const dateString = calendarDate.date.toISOString();\n return `\n <td\n class=\"${classes.join(' ')}\"\n data-date=\"${dateString}\"\n data-day-index=\"${dayIndex}\"\n data-clickable=\"true\"\n >\n ${calendarDate.date.getDate()}\n </td>\n `;\n })\n .join('')}\n </tr>\n `\n )\n .join('')\n }\n </tbody>\n </table>\n\n ${\n !isLoading && availabilityMode !== 'day' && viewModel.selectedDate\n ? `\n <div class=\"date-popup ${viewModel.popupPositionClass}\">\n <div class=\"popup-header\">\n <h2>${viewModel.scheduleDay}</h2>\n <button type=\"button\" class=\"popup-close\" data-action=\"close-popup\" aria-label=\"Close\">✕</button>\n </div>\n\n ${\n showScrollHint\n ? `\n <div class=\"scroll-hint\">\n ↓ Scroll to see more events ↓\n </div>\n `\n : ''\n }\n\n <div class=\"events-container\">\n ${\n availabilityMode === 'time'\n ? renderTimeGrid(viewModel.tasks, viewModel.selectedDate!)\n : viewModel.tasks.length > 0\n ? viewModel.tasks\n .map(event => renderEvent(event))\n .join('')\n : renderNoEvents()\n }\n </div>\n </div>\n `\n : ''\n }\n </div>\n </div>\n `;\n\n this.innerHTML = html;\n this.attachEventListeners();\n }\n\n private attachEventListeners(): void {\n if (this.listenersAttached) return;\n this.listenersAttached = true;\n\n const minYear = this.minYear;\n const maxYear = this.maxYear;\n\n this.delegatedClickHandler = (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n\n const cell = target.closest('td[data-clickable=\"true\"]') as HTMLElement;\n if (cell && cell.dataset.date) {\n e.stopPropagation();\n const date = new Date(cell.dataset.date);\n const dayIndex = parseInt(cell.dataset.dayIndex || '0');\n const availMode = this.getAttribute('availability-mode');\n const isSelectable = this.hasAttribute('selectable');\n\n if (availMode === 'day' && isSelectable) {\n const isBooked = cell.classList.contains('availability--booked');\n if (!isBooked) {\n let startDate: Date;\n let endDate: Date;\n if (this._rangeEnd !== null) {\n // State 2 (complete) → reset, start fresh\n this._rangeStart = date;\n this._rangeEnd = null;\n startDate = date;\n endDate = date;\n } else if (this._rangeStart === null) {\n // State 0 → first click\n this._rangeStart = date;\n startDate = date;\n endDate = date;\n } else {\n // State 1 → second click, complete the range if no booked day inside\n const [s, e] =\n this._rangeStart <= date\n ? [this._rangeStart, date]\n : [date, this._rangeStart];\n const cursor = new Date(s);\n cursor.setDate(cursor.getDate() + 1);\n let blocked = false;\n while (cursor < e) {\n if (this.engine!.getEventsForDate(cursor).length > 0) {\n blocked = true;\n break;\n }\n cursor.setDate(cursor.getDate() + 1);\n }\n if (blocked) {\n // Booked day inside range — reset, start fresh from this click\n this._rangeStart = date;\n this._rangeEnd = null;\n } else {\n this._rangeStart = s;\n this._rangeEnd = e;\n }\n startDate = this._rangeStart;\n endDate = this._rangeEnd ?? this._rangeStart;\n }\n this.dispatchEvent(\n new CustomEvent('cal-availability-select', {\n bubbles: true,\n composed: true,\n detail: { startDate, endDate },\n })\n );\n }\n }\n\n if (availMode === 'time') {\n // Reset time range when a new day is opened\n this._timeRangeDate = null;\n this._timeRangeStart = null;\n this._timeRangeEnd = null;\n this._timeRangeComplete = false;\n }\n\n this.engine!.handleDateClick(date, dayIndex);\n this.dispatchEvent(\n new CustomEvent('cal-date-select', {\n bubbles: true,\n composed: true,\n detail: { date, events: this.engine!.getEventsForDate(date) },\n })\n );\n return;\n }\n\n const actionEl = target.closest('[data-action]') as HTMLElement;\n if (!actionEl) return;\n\n const action = actionEl.dataset.action;\n e.stopPropagation();\n\n switch (action) {\n case 'previous': {\n const vm = this.engine!.getViewModel();\n const tMonth = vm.currentMonth === 0 ? 11 : vm.currentMonth - 1;\n const tYear =\n vm.currentMonth === 0 ? vm.currentYear - 1 : vm.currentYear;\n this.dispatchMonthChange(tYear, tMonth);\n this.actions!.previous();\n break;\n }\n\n case 'next': {\n const vm = this.engine!.getViewModel();\n const tMonth = vm.currentMonth === 11 ? 0 : vm.currentMonth + 1;\n const tYear =\n vm.currentMonth === 11 ? vm.currentYear + 1 : vm.currentYear;\n this.dispatchMonthChange(tYear, tMonth);\n this.actions!.next();\n break;\n }\n\n case 'today': {\n const t = new Date();\n this.dispatchMonthChange(t.getFullYear(), t.getMonth());\n this.actions!.goToToday();\n this.pickerOpen = false;\n break;\n }\n\n case 'toggle-picker':\n this.pickerOpen = !this.pickerOpen;\n if (this.pickerOpen) {\n this.yearInput = String(this.engine!.getViewModel().currentYear);\n this.yearInputValid = true;\n }\n this.render();\n break;\n\n case 'year-prev': {\n const vm = this.engine!.getViewModel();\n if (vm.currentYear > minYear) {\n const newYear = vm.currentYear - 1;\n this.yearInput = String(newYear);\n this.updatePickerYear(newYear);\n this.dispatchMonthChange(newYear, vm.currentMonth);\n this.actions!.jump(newYear, vm.currentMonth);\n }\n break;\n }\n\n case 'year-next': {\n const vm = this.engine!.getViewModel();\n if (vm.currentYear < maxYear) {\n const newYear = vm.currentYear + 1;\n this.yearInput = String(newYear);\n this.updatePickerYear(newYear);\n this.dispatchMonthChange(newYear, vm.currentMonth);\n this.actions!.jump(newYear, vm.currentMonth);\n }\n break;\n }\n\n case 'select-month': {\n const month = parseInt(actionEl.dataset.month || '0', 10);\n const year = this.engine!.getViewModel().currentYear;\n this.dispatchMonthChange(year, month);\n this.actions!.jump(year, month);\n this.pickerOpen = false;\n break;\n }\n\n case 'close-popup':\n this._timeRangeDate = null;\n this._timeRangeStart = null;\n this._timeRangeEnd = null;\n this._timeRangeComplete = false;\n this.engine!.clearSelection();\n break;\n\n case 'select-slot': {\n const slotStart = actionEl.dataset.startTime!;\n const slotEnd = actionEl.dataset.endTime!;\n const slotDate = new Date(actionEl.dataset.date!);\n if (this._timeRangeComplete) {\n // State 2 → reset, start fresh\n this._timeRangeDate = slotDate;\n this._timeRangeStart = slotStart;\n this._timeRangeEnd = slotEnd;\n this._timeRangeComplete = false;\n } else if (this._timeRangeStart === null) {\n // State 0 → first click\n this._timeRangeDate = slotDate;\n this._timeRangeStart = slotStart;\n this._timeRangeEnd = slotEnd;\n } else {\n // State 1 → second click, extend range\n const newStart =\n slotStart < this._timeRangeStart\n ? slotStart\n : this._timeRangeStart;\n const newEnd =\n slotEnd > this._timeRangeEnd! ? slotEnd : this._timeRangeEnd!;\n this._timeRangeStart = newStart;\n this._timeRangeEnd = newEnd;\n this._timeRangeComplete = true;\n }\n this.render();\n this.dispatchEvent(\n new CustomEvent('cal-availability-select', {\n bubbles: true,\n composed: true,\n detail: {\n date: this._timeRangeDate,\n startTime: this._timeRangeStart,\n endTime: this._timeRangeEnd,\n },\n })\n );\n break;\n }\n }\n };\n\n this.delegatedInputHandler = (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (!target.matches('[data-year-input]')) return;\n\n const value = target.value;\n if (value === '' || /^\\d+$/.test(value)) {\n this.yearInput = value;\n const year = parseInt(value, 10);\n this.yearInputValid =\n value === '' || (year >= minYear && year <= maxYear);\n target.classList.toggle('invalid', !this.yearInputValid);\n }\n };\n\n this.delegatedBlurHandler = (e: FocusEvent) => {\n const target = e.target as HTMLInputElement;\n if (!target.matches('[data-year-input]')) return;\n\n const year = parseInt(this.yearInput, 10);\n const vm = this.engine!.getViewModel();\n if (isNaN(year) || year < minYear || year > maxYear) {\n this.yearInput = String(vm.currentYear);\n this.yearInputValid = true;\n target.value = this.yearInput;\n target.classList.remove('invalid');\n } else if (year !== vm.currentYear) {\n this.dispatchMonthChange(year, vm.currentMonth);\n this.actions!.jump(year, vm.currentMonth);\n }\n };\n\n this.delegatedKeydownHandler = (e: KeyboardEvent) => {\n const target = e.target as HTMLInputElement;\n if (!target.matches('[data-year-input]')) return;\n if (e.key === 'Enter') target.blur();\n };\n\n this.addEventListener('click', this.delegatedClickHandler);\n this.addEventListener('input', this.delegatedInputHandler);\n this.addEventListener('blur', this.delegatedBlurHandler, true);\n this.addEventListener('keydown', this.delegatedKeydownHandler);\n\n this.clickOutsideHandler = (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n if (this.contains(target)) return;\n\n if (this.pickerOpen) {\n this.pickerOpen = false;\n this.render();\n return;\n }\n\n const popup = this.querySelector('.date-popup');\n if (popup) {\n this.engine!.clearSelection();\n }\n };\n\n document.addEventListener('click', this.clickOutsideHandler);\n }\n\n private updatePickerYear(year: number): void {\n const input = this.querySelector('[data-year-input]') as HTMLInputElement;\n if (input) input.value = String(year);\n\n const prevBtn = this.querySelector(\n '[data-action=\"year-prev\"]'\n ) as HTMLButtonElement;\n const nextBtn = this.querySelector(\n '[data-action=\"year-next\"]'\n ) as HTMLButtonElement;\n if (prevBtn) prevBtn.disabled = year <= this.minYear;\n if (nextBtn) nextBtn.disabled = year >= this.maxYear;\n }\n\n private dispatchMonthChange(year?: number, month?: number): void {\n if (!this.engine) return;\n const vm = this.engine.getViewModel();\n this.dispatchEvent(\n new CustomEvent('cal-month-change', {\n bubbles: true,\n composed: true,\n detail: {\n year: year ?? vm.currentYear,\n month: month ?? vm.currentMonth,\n },\n })\n );\n }\n\n // Public API\n updateEvents(events: CalendarEvent[]): void {\n this.events = events;\n }\n\n updateTheme(theme: CalendarTheme): void {\n this.theme = theme;\n }\n\n getCurrentDate(): Date | null {\n return this.engine?.getViewModel().selectedDate ?? null;\n }\n\n goToDate(date: Date): void {\n const year = date.getFullYear();\n const month = date.getMonth();\n this.dispatchMonthChange(year, month);\n this.actions?.jump(year, month);\n }\n\n getEngine(): CalendarEngine {\n if (!this.engine)\n throw new Error('CalendarElement is not connected to the DOM');\n return this.engine;\n }\n}\n\nexport function defineCalendarElement(tagName = 'kal-calendar'): void {\n if (typeof customElements !== 'undefined' && !customElements.get(tagName)) {\n customElements.define(tagName, CalendarElement);\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kal-calendar': CalendarElement;\n }\n}\n","import { CalendarEvent, CalendarDate, CategoryColorMap } 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 MONTHS_FULL = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n];\n\nexport const DAYS = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n];\n\nexport function normalizeDate(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);\n}\n\nexport function isSameDay(date1: Date, date2: Date): boolean {\n return normalizeDate(date1).getTime() === normalizeDate(date2).getTime();\n}\n\nexport function isToday(date: Date): boolean {\n return isSameDay(date, new Date());\n}\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\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\nexport function hasEvents(events: CalendarEvent[], date: Date): boolean {\n return getEventsForDate(events, date).length > 0;\n}\n\nexport function generateCalendarDates(\n year: number,\n month: number,\n events: CalendarEvent[] = [],\n weekStartsOn: 0 | 1 = 0\n): CalendarDate[][] {\n const firstDay = new Date(year, month, 1);\n const lastDay = new Date(year, month + 1, 0);\n const daysInMonth = lastDay.getDate();\n const prevMonthLastDay = new Date(year, month, 0).getDate();\n\n let firstDayOfWeek = firstDay.getDay();\n if (weekStartsOn === 1) {\n firstDayOfWeek = firstDayOfWeek === 0 ? 6 : firstDayOfWeek - 1;\n }\n\n const dates: CalendarDate[][] = [];\n let day = 1;\n let nextMonthDay = 1;\n\n for (let week = 0; week < 6; week++) {\n const weekDates: CalendarDate[] = [];\n\n for (let dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++) {\n if (week === 0 && dayOfWeek < firstDayOfWeek) {\n // Previous month days\n const prevDay = prevMonthLastDay - firstDayOfWeek + dayOfWeek + 1;\n const prevDate = new Date(year, month - 1, prevDay);\n const dateEvents = getEventsForDate(events, prevDate);\n weekDates.push({\n date: prevDate,\n isCurrentMonth: false,\n isToday: isToday(prevDate),\n hasEvents: dateEvents.length > 0,\n events: dateEvents,\n });\n } else if (day > daysInMonth) {\n // Next month days\n const nextDate = new Date(year, month + 1, nextMonthDay);\n const dateEvents = getEventsForDate(events, nextDate);\n weekDates.push({\n date: nextDate,\n isCurrentMonth: false,\n isToday: isToday(nextDate),\n hasEvents: dateEvents.length > 0,\n events: dateEvents,\n });\n nextMonthDay++;\n } else {\n // Current month days\n const currentDate = new Date(year, month, day);\n const dateEvents = getEventsForDate(events, currentDate);\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\n return dates;\n}\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\nexport function getCellClasses(calendarDate: CalendarDate): string[] {\n const classes: string[] = [];\n\n if (!calendarDate.isCurrentMonth) {\n classes.push('other-month');\n }\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\nexport function formatDateForDisplay(date: Date): string {\n return `${DAYS[date.getDay()]} ${date.getDate()}`;\n}\n\nexport function getMonthYearText(year: number, month: number): string {\n return `${MONTHS_FULL[month]} ${year}`;\n}\n\nexport function formatTimeRange(event: CalendarEvent): string {\n if (event.allDay || (!event.startTime && !event.endTime)) {\n return 'All day';\n }\n\n if (event.startTime && event.endTime) {\n return `${event.startTime} - ${event.endTime}`;\n }\n\n if (event.startTime) {\n return `${event.startTime}`;\n }\n\n return '';\n}\n\nexport function formatAttendees(attendees?: string[]): string {\n if (!attendees || attendees.length === 0) return '';\n\n if (attendees.length === 1) return attendees[0];\n if (attendees.length === 2) return attendees.join(' and ');\n\n return `${attendees.slice(0, -1).join(', ')}, and ${attendees[attendees.length - 1]}`;\n}\n\nexport function sortEventsByTime(events: CalendarEvent[]): CalendarEvent[] {\n return [...events].sort((a, b) => {\n const aAllDay = a.allDay || (!a.startTime && !a.endTime);\n const bAllDay = b.allDay || (!b.startTime && !b.endTime);\n\n if (aAllDay && !bAllDay) return -1;\n if (!aAllDay && bAllDay) return 1;\n\n if (!a.startTime || !b.startTime) return 0;\n return a.startTime.localeCompare(b.startTime);\n });\n}\n\nexport const DEFAULT_CATEGORY_COLORS: CategoryColorMap = {\n work: '#3b82f6',\n personal: '#8b5cf6',\n meeting: '#10b981',\n deadline: '#ef4444',\n appointment: '#f59e0b',\n other: '#6b7280',\n};\n\n// Dynamic function that accepts custom colors\nexport function getDefaultEventColor(\n category?: string,\n customColors?: CategoryColorMap\n): string {\n const colorMap = customColors || DEFAULT_CATEGORY_COLORS;\n\n if (category && colorMap[category]) {\n return colorMap[category];\n }\n\n // Default fallback color\n return '#fc8917';\n}\n\n// Helper to merge custom colors with defaults\nexport function mergeCategoryColors(\n customColors?: CategoryColorMap\n): CategoryColorMap {\n return {\n ...DEFAULT_CATEGORY_COLORS,\n ...customColors,\n };\n}\n\n// Validate if a color is a valid hex color\nexport function isValidHexColor(color: string): boolean {\n return /^#([0-9A-F]{3}){1,2}$/i.test(color);\n}\n\n// Get color for a category with validation\nexport function getCategoryColor(\n category: string,\n customColors?: CategoryColorMap\n): string {\n const colorMap = mergeCategoryColors(customColors);\n const color = colorMap[category] || colorMap.other || '#fc8917';\n\n return isValidHexColor(color) ? color : '#fc8917';\n}\n","import {\n CalendarEvent,\n CalendarState,\n CalendarConfig,\n CalendarActions,\n CalendarViewModel,\n CategoryColorMap,\n} from './types';\nimport {\n generateCalendarDates,\n getEventsForDate,\n generateYears,\n getPopupPositionClass,\n getMonthYearText,\n formatDateForDisplay,\n mergeCategoryColors,\n getCategoryColor,\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 private categoryColors: CategoryColorMap;\n\n constructor(config: CalendarConfig) {\n this.config = config;\n this.categoryColors = mergeCategoryColors(config.categoryColors);\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 goToToday: this.goToToday.bind(this),\n isCurrentMonth: this.isCurrentMonth.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 * Navigate to current month (today)\n */\n private goToToday(): void {\n const today = new Date();\n this.state.currentYear = today.getFullYear();\n this.state.currentMonth = today.getMonth();\n this.state.selectedDate = null;\n this.state.selectedDayIndex = null;\n this.updateTasks();\n this.notify();\n }\n\n /**\n * Check if currently viewing today's month\n */\n private isCurrentMonth(): boolean {\n const today = new Date();\n return (\n this.state.currentYear === today.getFullYear() &&\n this.state.currentMonth === today.getMonth()\n );\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 * Get category color (with custom colors support)\n */\n getCategoryColor(category?: string): string {\n if (!category) return '#fc8917';\n return getCategoryColor(category, this.categoryColors);\n }\n\n /**\n * Update category colors dynamically\n */\n updateCategoryColors(colors: CategoryColorMap): void {\n this.categoryColors = mergeCategoryColors(colors);\n this.notify();\n }\n\n /**\n * Get all category colors\n */\n getCategoryColors(): CategoryColorMap {\n return { ...this.categoryColors };\n }\n\n /**\n * Register a new category with color\n */\n registerCategory(name: string, color: string): void {\n this.categoryColors[name] = color;\n this.notify();\n }\n\n /**\n * Destroy the engine and cleanup listeners\n */\n destroy(): void {\n this.listeners.clear();\n }\n}\n"],"mappings":"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","names":["isSameDay","e"]}
1
+ {"version":3,"sources":["../src/web-components/CalendarElement.ts","../src/core/utils.ts","../src/core/calendar-engine.ts"],"sourcesContent":["import {\n CalendarEngine,\n getCellClasses,\n formatTimeRange,\n formatAttendees,\n MONTHS_FULL,\n MONTHS,\n} from '../core';\nimport type { CalendarEvent, CalendarTheme, CategoryColorMap } from '../core';\n\nconst isSameDay = (a: Date, b: Date): boolean =>\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate();\n\nexport class CalendarElement extends HTMLElement {\n static observedAttributes = [\n 'initial-date',\n 'min-year',\n 'max-year',\n 'week-starts-on',\n 'title',\n 'use-short-month-names',\n 'availability-mode',\n 'selectable',\n 'loading',\n ];\n\n private engine: CalendarEngine | null = null;\n private unsubscribe: (() => void) | null = null;\n private actions: ReturnType<CalendarEngine['getActions']> | null = null;\n private pickerOpen = false;\n private yearInput = '';\n private yearInputValid = true;\n private listenersAttached = false;\n\n private clickOutsideHandler: ((e: MouseEvent) => void) | null = null;\n private delegatedClickHandler: ((e: MouseEvent) => void) | null = null;\n private delegatedInputHandler: ((e: Event) => void) | null = null;\n private delegatedBlurHandler: ((e: FocusEvent) => void) | null = null;\n private delegatedKeydownHandler: ((e: KeyboardEvent) => void) | null = null;\n\n // Rich property backing fields\n private _events: CalendarEvent[] = [];\n private _theme: CalendarTheme | null = null;\n private _categoryColors: CategoryColorMap | null = null;\n private _renderEvent: ((e: CalendarEvent) => string) | null = null;\n private _renderNoEvents: (() => string) | null = null;\n\n // Selection state (availability mode — range)\n private _rangeStart: Date | null = null;\n private _rangeEnd: Date | null = null;\n private _timeRangeDate: Date | null = null;\n private _timeRangeStart: string | null = null;\n private _timeRangeEnd: string | null = null;\n private _timeRangeComplete = false;\n\n get events(): CalendarEvent[] {\n return this._events;\n }\n\n set events(val: CalendarEvent[]) {\n this._events = val;\n if (this.engine) {\n this.engine.updateEvents(val);\n }\n }\n\n set theme(val: CalendarTheme) {\n this._theme = val;\n this.applyTheme();\n }\n\n set categoryColors(val: CategoryColorMap) {\n this._categoryColors = val;\n if (this.engine) {\n this.engine.updateCategoryColors(val);\n }\n }\n\n set renderEvent(val: (e: CalendarEvent) => string) {\n this._renderEvent = val;\n if (this.engine) this.render();\n // ignored when availability-mode attribute is set\n }\n\n set renderNoEvents(val: () => string) {\n this._renderNoEvents = val;\n if (this.engine) this.render();\n // ignored when availability-mode attribute is set\n }\n\n get loading(): boolean {\n return this.hasAttribute('loading');\n }\n\n set loading(val: boolean) {\n if (val) this.setAttribute('loading', '');\n else this.removeAttribute('loading');\n }\n\n connectedCallback(): void {\n this.classList.add('kalendly-calendar');\n this.initEngine();\n this.render();\n }\n\n disconnectedCallback(): void {\n this.cleanup();\n this.classList.remove('kalendly-calendar');\n this.innerHTML = '';\n }\n\n attributeChangedCallback(\n name: string,\n oldVal: string | null,\n newVal: string | null\n ): void {\n if (oldVal === newVal) return;\n if (name === 'loading') {\n this.render();\n return;\n }\n if (name === 'selectable' && newVal === null) {\n this._rangeStart = null;\n this._rangeEnd = null;\n this._timeRangeDate = null;\n this._timeRangeStart = null;\n this._timeRangeEnd = null;\n this._timeRangeComplete = false;\n }\n this.reinit();\n }\n\n private get minYear(): number {\n const val = this.getAttribute('min-year');\n return val ? parseInt(val, 10) : new Date().getFullYear() - 30;\n }\n\n private get maxYear(): number {\n const val = this.getAttribute('max-year');\n return val ? parseInt(val, 10) : new Date().getFullYear() + 10;\n }\n\n private initEngine(): void {\n const initialDateAttr = this.getAttribute('initial-date');\n const initialDate = initialDateAttr ? new Date(initialDateAttr) : undefined;\n const weekStartsOnAttr = this.getAttribute('week-starts-on');\n const weekStartsOn: 0 | 1 = weekStartsOnAttr === '1' ? 1 : 0;\n\n this.engine = new CalendarEngine({\n events: this._events,\n initialDate,\n minYear: this.minYear,\n maxYear: this.maxYear,\n weekStartsOn,\n categoryColors: this._categoryColors ?? undefined,\n });\n\n this.actions = this.engine.getActions();\n this.applyTheme();\n\n this.unsubscribe = this.engine.subscribe(() => {\n this.render();\n });\n }\n\n private reinit(): void {\n if (!this.engine) return;\n this.cleanup();\n this.initEngine();\n this.render();\n }\n\n private cleanup(): void {\n if (this.unsubscribe) {\n this.unsubscribe();\n this.unsubscribe = null;\n }\n\n if (this.delegatedClickHandler) {\n this.removeEventListener('click', this.delegatedClickHandler);\n this.delegatedClickHandler = null;\n }\n if (this.delegatedInputHandler) {\n this.removeEventListener('input', this.delegatedInputHandler);\n this.delegatedInputHandler = null;\n }\n if (this.delegatedBlurHandler) {\n this.removeEventListener('blur', this.delegatedBlurHandler, true);\n this.delegatedBlurHandler = null;\n }\n if (this.delegatedKeydownHandler) {\n this.removeEventListener('keydown', this.delegatedKeydownHandler);\n this.delegatedKeydownHandler = null;\n }\n if (this.clickOutsideHandler) {\n document.removeEventListener('click', this.clickOutsideHandler);\n this.clickOutsideHandler = null;\n }\n\n this.listenersAttached = false;\n\n if (this.engine) {\n this.engine.destroy();\n this.engine = null;\n }\n\n this.actions = null;\n }\n\n private applyTheme(): void {\n if (!this._theme) return;\n const root = document.documentElement;\n const t = this._theme;\n if (t.primary)\n root.style.setProperty('--calendar-primary-color', t.primary);\n if (t.secondary)\n root.style.setProperty('--calendar-secondary-color', t.secondary);\n if (t.tertiary)\n root.style.setProperty('--calendar-tertiary-color', t.tertiary);\n if (t.textColor)\n root.style.setProperty('--calendar-text-color', t.textColor);\n if (t.textLight)\n root.style.setProperty('--calendar-text-light', t.textLight);\n if (t.background)\n root.style.setProperty('--calendar-background', t.background);\n if (t.cellHover)\n root.style.setProperty('--calendar-cell-hover', t.cellHover);\n if (t.borderColor)\n root.style.setProperty('--calendar-border-color', t.borderColor);\n if (t.todayOutline)\n root.style.setProperty('--calendar-today-outline', t.todayOutline);\n if (t.selectedBg)\n root.style.setProperty('--calendar-selected-bg', t.selectedBg);\n if (t.headerBg) root.style.setProperty('--calendar-header-bg', t.headerBg);\n if (t.popupBg) root.style.setProperty('--calendar-popup-bg', t.popupBg);\n if (t.eventIndicator)\n root.style.setProperty('--calendar-event-indicator', t.eventIndicator);\n }\n\n private render(): void {\n if (!this.engine) return;\n\n const viewModel = this.engine.getViewModel();\n const useShortMonths = this.hasAttribute('use-short-month-names');\n const title = this.getAttribute('title');\n const minYear = this.minYear;\n const maxYear = this.maxYear;\n const availabilityMode = this.getAttribute('availability-mode');\n const selectable = this.hasAttribute('selectable');\n const isLoading = this.loading;\n\n const today = new Date();\n const todayMonth = today.getMonth();\n const todayYear = today.getFullYear();\n const isCurrentMonth =\n viewModel.currentYear === todayYear &&\n viewModel.currentMonth === todayMonth;\n\n const showScrollHint = viewModel.tasks.length > 3;\n\n const defaultRenderEvent = (event: CalendarEvent) => {\n const timeRange = formatTimeRange(event);\n const attendeesList = formatAttendees(event.attendees);\n\n let borderColor = event.color || '#3b82f6';\n if (event.category) {\n borderColor = this.engine!.getCategoryColor(event.category);\n }\n\n const getCategoryLabel = (category?: string) => {\n const labels: Record<string, string> = {\n work: 'WORK',\n personal: 'PERSONAL',\n meeting: 'MEETING',\n deadline: 'DEADLINE',\n appointment: 'APPOINTMENT',\n other: 'OTHER',\n };\n return category ? labels[category] || category.toUpperCase() : '';\n };\n\n const getPriorityLabel = (priority?: string) => {\n const labels: Record<string, string> = {\n high: 'HIGH',\n medium: 'MEDIUM',\n low: 'LOW',\n };\n return priority ? labels[priority] || priority.toUpperCase() : '';\n };\n\n const getStatusLabel = (status?: string) => {\n const labels: Record<string, string> = {\n completed: 'COMPLETED',\n cancelled: 'CANCELLED',\n tentative: 'TENTATIVE',\n scheduled: 'SCHEDULED',\n };\n return status ? labels[status] || status.toUpperCase() : '';\n };\n\n return `\n <div class=\"event-card\" style=\"border-left-color: ${borderColor}\">\n <div class=\"event-header\">\n <div class=\"event-title\">${event.name}</div>\n <div class=\"event-badges\">\n ${event.category ? `<span class=\"badge category-${event.category}\">${getCategoryLabel(event.category)}</span>` : ''}\n ${event.priority ? `<span class=\"badge priority-${event.priority}\">${getPriorityLabel(event.priority)}</span>` : ''}\n ${event.status && event.status !== 'scheduled' ? `<span class=\"badge status-${event.status}\">${getStatusLabel(event.status)}</span>` : ''}\n </div>\n </div>\n\n ${\n timeRange\n ? `\n <div class=\"event-time\">\n <span class=\"event-time-label\">Time:</span>\n <span class=\"event-time-value\">${timeRange}</span>\n </div>\n `\n : ''\n }\n\n ${\n event.description\n ? `\n <div class=\"event-description\">${event.description}</div>\n `\n : ''\n }\n\n ${\n event.location\n ? `\n <div class=\"event-time\">\n <span class=\"event-time-label\">Location:</span>\n <span class=\"event-time-value\">${event.location}</span>\n </div>\n `\n : ''\n }\n\n ${\n attendeesList\n ? `\n <div class=\"event-time\">\n <span class=\"event-time-label\">Attendees:</span>\n <span class=\"event-time-value\">${attendeesList}</span>\n </div>\n `\n : ''\n }\n\n ${\n event.organizer\n ? `\n <div class=\"event-time\">\n <span class=\"event-time-label\">Organizer:</span>\n <span class=\"event-time-value\">${event.organizer}</span>\n </div>\n `\n : ''\n }\n\n ${\n event.notes\n ? `\n <div class=\"event-time\">\n <span class=\"event-time-label\">Notes:</span>\n <span class=\"event-time-value\">${event.notes}</span>\n </div>\n `\n : ''\n }\n\n ${\n event.url\n ? `\n <div class=\"event-time\">\n <a href=\"${event.url}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"event-link\">\n View Details →\n </a>\n </div>\n `\n : ''\n }\n\n ${\n event.tags && event.tags.length > 0\n ? `\n <div class=\"event-tags\">\n ${event.tags.map((tag: string) => `<span class=\"event-tag\">${tag}</span>`).join('')}\n </div>\n `\n : ''\n }\n </div>\n `;\n };\n\n const defaultRenderNoEvents = () =>\n '<div class=\"no-events-message\">No events scheduled for this day.</div>';\n\n const renderEvent = this._renderEvent || defaultRenderEvent;\n const renderNoEvents = this._renderNoEvents || defaultRenderNoEvents;\n\n const renderTimeGrid = (events: CalendarEvent[], date: Date): string => {\n const isHourBooked = (hour: number): boolean =>\n events.some(event => {\n if (!event.startTime || !event.endTime) return true;\n const [startH] = (event.startTime as string).split(':').map(Number);\n const [endH] = (event.endTime as string).split(':').map(Number);\n return hour >= startH && hour < endH;\n });\n\n const slots = Array.from({ length: 24 }, (_, hour) => {\n const startTime = `${String(hour).padStart(2, '0')}:00`;\n const endTime = `${String(hour + 1).padStart(2, '0')}:00`;\n const booked = isHourBooked(hour);\n\n const inTimeRange =\n !booked &&\n selectable &&\n this._timeRangeStart !== null &&\n this._timeRangeEnd !== null &&\n isSameDay(this._timeRangeDate!, date) &&\n startTime >= this._timeRangeStart &&\n endTime <= this._timeRangeEnd;\n\n const isRangeStart = inTimeRange && startTime === this._timeRangeStart;\n const isRangeEnd = inTimeRange && endTime === this._timeRangeEnd;\n const isInRange = inTimeRange && !isRangeStart && !isRangeEnd;\n\n const slotClasses = [\n 'time-grid__slot',\n booked ? 'time-grid__slot--booked' : 'time-grid__slot--free',\n isRangeStart ? 'time-grid__slot--range-start' : '',\n isRangeEnd ? 'time-grid__slot--range-end' : '',\n isInRange ? 'time-grid__slot--in-range' : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n const slotAttrs =\n !booked && selectable\n ? `data-action=\"select-slot\" data-start-time=\"${startTime}\" data-end-time=\"${endTime}\" data-date=\"${date.toISOString()}\"`\n : '';\n\n return `\n <div class=\"${slotClasses}\" ${slotAttrs}>\n <span class=\"time-grid__label\">${startTime}</span>\n <span class=\"time-grid__status\">${booked ? 'Booked' : 'Available'}</span>\n </div>`;\n });\n\n return `<div class=\"time-grid\">${slots.join('')}</div>`;\n };\n\n const html = `\n ${\n title\n ? `\n <div class=\"page--title\">\n <h1>${title}</h1>\n </div>\n `\n : ''\n }\n\n <div class=\"calendar--content\">\n <div class=\"calendar--card\">\n <div class=\"calendar--nav-header\">\n <button type=\"button\" class=\"calendar--nav-arrow\" data-action=\"previous\" aria-label=\"Previous month\">\n &#8249;\n </button>\n\n <div class=\"calendar--picker-container\" data-picker-container>\n <button\n type=\"button\"\n class=\"calendar--picker-btn\"\n data-action=\"toggle-picker\"\n aria-expanded=\"${this.pickerOpen ? 'true' : 'false'}\"\n aria-haspopup=\"true\"\n >\n ${\n useShortMonths\n ? `${MONTHS[viewModel.currentMonth]} ${viewModel.currentYear}`\n : viewModel.monthAndYearText\n }\n <span class=\"calendar--picker-chevron\">&#9662;</span>\n </button>\n\n ${\n this.pickerOpen\n ? `\n <div class=\"calendar--picker-dropdown\">\n <div class=\"calendar--picker-year-row\">\n <button\n type=\"button\"\n class=\"calendar--picker-year-arrow\"\n data-action=\"year-prev\"\n ${viewModel.currentYear <= minYear ? 'disabled' : ''}\n aria-label=\"Previous year\"\n >&#8249;</button>\n <input\n type=\"text\"\n class=\"calendar--picker-year-input${!this.yearInputValid ? ' invalid' : ''}\"\n value=\"${this.yearInput || viewModel.currentYear}\"\n data-year-input\n aria-label=\"Year\"\n />\n <button\n type=\"button\"\n class=\"calendar--picker-year-arrow\"\n data-action=\"year-next\"\n ${viewModel.currentYear >= maxYear ? 'disabled' : ''}\n aria-label=\"Next year\"\n >&#8250;</button>\n </div>\n\n <div class=\"calendar--picker-months\">\n ${(useShortMonths ? MONTHS : MONTHS_FULL)\n .map((month, index) => {\n const isSelected = index === viewModel.currentMonth;\n const isCurrent =\n index === todayMonth &&\n viewModel.currentYear === todayYear;\n return `\n <button\n type=\"button\"\n class=\"calendar--picker-month${isSelected ? ' selected' : ''}${isCurrent ? ' current-month' : ''}\"\n data-action=\"select-month\"\n data-month=\"${index}\"\n >${month}</button>\n `;\n })\n .join('')}\n </div>\n </div>\n `\n : ''\n }\n </div>\n\n <button\n type=\"button\"\n class=\"calendar--today-btn\"\n data-action=\"today\"\n ${isCurrentMonth ? 'disabled' : ''}\n >Today</button>\n\n <button type=\"button\" class=\"calendar--nav-arrow\" data-action=\"next\" aria-label=\"Next month\">\n &#8250;\n </button>\n </div>\n\n <table class=\"calendar--table calendar--table--bordered\">\n <thead>\n <tr>\n ${viewModel.days.map(day => `<th>${day.slice(0, 3)}</th>`).join('')}\n </tr>\n </thead>\n <tbody data-calendar-body>\n ${\n isLoading\n ? Array.from(\n { length: 6 },\n () =>\n `<tr>${Array.from(\n { length: 7 },\n () =>\n `<td class=\"calendar--skeleton\" aria-hidden=\"true\"></td>`\n ).join('')}</tr>`\n ).join('')\n : viewModel.calendarDates\n .map(\n week => `\n <tr>\n ${week\n .map((calendarDate, dayIndex) => {\n const classes = getCellClasses(calendarDate);\n if (availabilityMode && calendarDate.isCurrentMonth) {\n classes.push(\n calendarDate.hasEvents\n ? 'availability--booked'\n : 'availability--free'\n );\n }\n if (\n availabilityMode === 'day' &&\n selectable &&\n calendarDate.isCurrentMonth\n ) {\n const d = calendarDate.date;\n if (\n this._rangeStart &&\n isSameDay(d, this._rangeStart)\n )\n classes.push('availability--range-start');\n if (this._rangeEnd && isSameDay(d, this._rangeEnd))\n classes.push('availability--range-end');\n if (this._rangeStart && this._rangeEnd) {\n if (d > this._rangeStart && d < this._rangeEnd)\n classes.push('availability--in-range');\n }\n }\n const dateString = calendarDate.date.toISOString();\n return `\n <td\n class=\"${classes.join(' ')}\"\n data-date=\"${dateString}\"\n data-day-index=\"${dayIndex}\"\n data-clickable=\"true\"\n >\n ${calendarDate.date.getDate()}\n </td>\n `;\n })\n .join('')}\n </tr>\n `\n )\n .join('')\n }\n </tbody>\n </table>\n\n ${\n !isLoading && availabilityMode !== 'day' && viewModel.selectedDate\n ? `\n <div class=\"date-popup ${viewModel.popupPositionClass}\">\n <div class=\"popup-header\">\n <h2>${viewModel.scheduleDay}</h2>\n <button type=\"button\" class=\"popup-close\" data-action=\"close-popup\" aria-label=\"Close\">✕</button>\n </div>\n\n ${\n showScrollHint\n ? `\n <div class=\"scroll-hint\">\n ↓ Scroll to see more events ↓\n </div>\n `\n : ''\n }\n\n <div class=\"events-container\">\n ${\n availabilityMode === 'time'\n ? renderTimeGrid(viewModel.tasks, viewModel.selectedDate!)\n : viewModel.tasks.length > 0\n ? viewModel.tasks\n .map(event => renderEvent(event))\n .join('')\n : renderNoEvents()\n }\n </div>\n </div>\n `\n : ''\n }\n </div>\n </div>\n `;\n\n this.innerHTML = html;\n this.attachEventListeners();\n }\n\n private attachEventListeners(): void {\n if (this.listenersAttached) return;\n this.listenersAttached = true;\n\n const minYear = this.minYear;\n const maxYear = this.maxYear;\n\n this.delegatedClickHandler = (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n\n const cell = target.closest('td[data-clickable=\"true\"]') as HTMLElement;\n if (cell && cell.dataset.date) {\n e.stopPropagation();\n const date = new Date(cell.dataset.date);\n const dayIndex = parseInt(cell.dataset.dayIndex || '0');\n const availMode = this.getAttribute('availability-mode');\n const isSelectable = this.hasAttribute('selectable');\n\n if (availMode === 'day' && isSelectable) {\n const isBooked = cell.classList.contains('availability--booked');\n if (!isBooked) {\n let startDate: Date;\n let endDate: Date;\n if (this._rangeEnd !== null) {\n // State 2 (complete) → reset, start fresh\n this._rangeStart = date;\n this._rangeEnd = null;\n startDate = date;\n endDate = date;\n } else if (this._rangeStart === null) {\n // State 0 → first click\n this._rangeStart = date;\n startDate = date;\n endDate = date;\n } else {\n // State 1 → second click, complete the range if no booked day inside\n const [s, e] =\n this._rangeStart <= date\n ? [this._rangeStart, date]\n : [date, this._rangeStart];\n const cursor = new Date(s);\n cursor.setDate(cursor.getDate() + 1);\n let blocked = false;\n while (cursor < e) {\n if (this.engine!.getEventsForDate(cursor).length > 0) {\n blocked = true;\n break;\n }\n cursor.setDate(cursor.getDate() + 1);\n }\n if (blocked) {\n // Booked day inside range — reset, start fresh from this click\n this._rangeStart = date;\n this._rangeEnd = null;\n } else {\n this._rangeStart = s;\n this._rangeEnd = e;\n }\n startDate = this._rangeStart;\n endDate = this._rangeEnd ?? this._rangeStart;\n }\n this.dispatchEvent(\n new CustomEvent('cal-availability-select', {\n bubbles: true,\n composed: true,\n detail: { startDate, endDate },\n })\n );\n }\n }\n\n if (availMode === 'time') {\n // Reset time range when a new day is opened\n this._timeRangeDate = null;\n this._timeRangeStart = null;\n this._timeRangeEnd = null;\n this._timeRangeComplete = false;\n }\n\n this.engine!.handleDateClick(date, dayIndex);\n this.dispatchEvent(\n new CustomEvent('cal-date-select', {\n bubbles: true,\n composed: true,\n detail: { date, events: this.engine!.getEventsForDate(date) },\n })\n );\n return;\n }\n\n const actionEl = target.closest('[data-action]') as HTMLElement;\n if (!actionEl) return;\n\n const action = actionEl.dataset.action;\n e.stopPropagation();\n\n switch (action) {\n case 'previous': {\n const vm = this.engine!.getViewModel();\n const tMonth = vm.currentMonth === 0 ? 11 : vm.currentMonth - 1;\n const tYear =\n vm.currentMonth === 0 ? vm.currentYear - 1 : vm.currentYear;\n this.dispatchMonthChange(tYear, tMonth);\n this.actions!.previous();\n break;\n }\n\n case 'next': {\n const vm = this.engine!.getViewModel();\n const tMonth = vm.currentMonth === 11 ? 0 : vm.currentMonth + 1;\n const tYear =\n vm.currentMonth === 11 ? vm.currentYear + 1 : vm.currentYear;\n this.dispatchMonthChange(tYear, tMonth);\n this.actions!.next();\n break;\n }\n\n case 'today': {\n const t = new Date();\n this.dispatchMonthChange(t.getFullYear(), t.getMonth());\n this.actions!.goToToday();\n this.pickerOpen = false;\n break;\n }\n\n case 'toggle-picker':\n this.pickerOpen = !this.pickerOpen;\n if (this.pickerOpen) {\n this.yearInput = String(this.engine!.getViewModel().currentYear);\n this.yearInputValid = true;\n }\n this.render();\n break;\n\n case 'year-prev': {\n const vm = this.engine!.getViewModel();\n if (vm.currentYear > minYear) {\n const newYear = vm.currentYear - 1;\n this.yearInput = String(newYear);\n this.updatePickerYear(newYear);\n this.dispatchMonthChange(newYear, vm.currentMonth);\n this.actions!.jump(newYear, vm.currentMonth);\n }\n break;\n }\n\n case 'year-next': {\n const vm = this.engine!.getViewModel();\n if (vm.currentYear < maxYear) {\n const newYear = vm.currentYear + 1;\n this.yearInput = String(newYear);\n this.updatePickerYear(newYear);\n this.dispatchMonthChange(newYear, vm.currentMonth);\n this.actions!.jump(newYear, vm.currentMonth);\n }\n break;\n }\n\n case 'select-month': {\n const month = parseInt(actionEl.dataset.month || '0', 10);\n const year = this.engine!.getViewModel().currentYear;\n this.dispatchMonthChange(year, month);\n this.actions!.jump(year, month);\n this.pickerOpen = false;\n break;\n }\n\n case 'close-popup':\n this._timeRangeDate = null;\n this._timeRangeStart = null;\n this._timeRangeEnd = null;\n this._timeRangeComplete = false;\n this.engine!.clearSelection();\n break;\n\n case 'select-slot': {\n const slotStart = actionEl.dataset.startTime!;\n const slotEnd = actionEl.dataset.endTime!;\n const slotDate = new Date(actionEl.dataset.date!);\n if (this._timeRangeComplete) {\n // State 2 → reset, start fresh\n this._timeRangeDate = slotDate;\n this._timeRangeStart = slotStart;\n this._timeRangeEnd = slotEnd;\n this._timeRangeComplete = false;\n } else if (this._timeRangeStart === null) {\n // State 0 → first click\n this._timeRangeDate = slotDate;\n this._timeRangeStart = slotStart;\n this._timeRangeEnd = slotEnd;\n } else {\n // State 1 → second click, extend range\n const newStart =\n slotStart < this._timeRangeStart\n ? slotStart\n : this._timeRangeStart;\n const newEnd =\n slotEnd > this._timeRangeEnd! ? slotEnd : this._timeRangeEnd!;\n this._timeRangeStart = newStart;\n this._timeRangeEnd = newEnd;\n this._timeRangeComplete = true;\n }\n this.render();\n this.dispatchEvent(\n new CustomEvent('cal-availability-select', {\n bubbles: true,\n composed: true,\n detail: {\n date: this._timeRangeDate,\n startTime: this._timeRangeStart,\n endTime: this._timeRangeEnd,\n },\n })\n );\n break;\n }\n }\n };\n\n this.delegatedInputHandler = (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (!target.matches('[data-year-input]')) return;\n\n const value = target.value;\n if (value === '' || /^\\d+$/.test(value)) {\n this.yearInput = value;\n const year = parseInt(value, 10);\n this.yearInputValid =\n value === '' || (year >= minYear && year <= maxYear);\n target.classList.toggle('invalid', !this.yearInputValid);\n }\n };\n\n this.delegatedBlurHandler = (e: FocusEvent) => {\n const target = e.target as HTMLInputElement;\n if (!target.matches('[data-year-input]')) return;\n\n const year = parseInt(this.yearInput, 10);\n const vm = this.engine!.getViewModel();\n if (isNaN(year) || year < minYear || year > maxYear) {\n this.yearInput = String(vm.currentYear);\n this.yearInputValid = true;\n target.value = this.yearInput;\n target.classList.remove('invalid');\n } else if (year !== vm.currentYear) {\n this.dispatchMonthChange(year, vm.currentMonth);\n this.actions!.jump(year, vm.currentMonth);\n }\n };\n\n this.delegatedKeydownHandler = (e: KeyboardEvent) => {\n const target = e.target as HTMLInputElement;\n if (!target.matches('[data-year-input]')) return;\n if (e.key === 'Enter') target.blur();\n };\n\n this.addEventListener('click', this.delegatedClickHandler);\n this.addEventListener('input', this.delegatedInputHandler);\n this.addEventListener('blur', this.delegatedBlurHandler, true);\n this.addEventListener('keydown', this.delegatedKeydownHandler);\n\n this.clickOutsideHandler = (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n if (this.contains(target)) return;\n\n if (this.pickerOpen) {\n this.pickerOpen = false;\n this.render();\n return;\n }\n\n const popup = this.querySelector('.date-popup');\n if (popup) {\n this.engine!.clearSelection();\n }\n };\n\n document.addEventListener('click', this.clickOutsideHandler);\n }\n\n private updatePickerYear(year: number): void {\n const input = this.querySelector('[data-year-input]') as HTMLInputElement;\n if (input) input.value = String(year);\n\n const prevBtn = this.querySelector(\n '[data-action=\"year-prev\"]'\n ) as HTMLButtonElement;\n const nextBtn = this.querySelector(\n '[data-action=\"year-next\"]'\n ) as HTMLButtonElement;\n if (prevBtn) prevBtn.disabled = year <= this.minYear;\n if (nextBtn) nextBtn.disabled = year >= this.maxYear;\n }\n\n private dispatchMonthChange(year?: number, month?: number): void {\n if (!this.engine) return;\n const vm = this.engine.getViewModel();\n this.dispatchEvent(\n new CustomEvent('cal-month-change', {\n bubbles: true,\n composed: true,\n detail: {\n year: year ?? vm.currentYear,\n month: month ?? vm.currentMonth,\n },\n })\n );\n }\n\n // Public API\n updateEvents(events: CalendarEvent[]): void {\n this.events = events;\n }\n\n updateTheme(theme: CalendarTheme): void {\n this.theme = theme;\n }\n\n getCurrentDate(): Date | null {\n return this.engine?.getViewModel().selectedDate ?? null;\n }\n\n goToDate(date: Date): void {\n const year = date.getFullYear();\n const month = date.getMonth();\n this.dispatchMonthChange(year, month);\n this.actions?.jump(year, month);\n }\n\n getEngine(): CalendarEngine {\n if (!this.engine)\n throw new Error('CalendarElement is not connected to the DOM');\n return this.engine;\n }\n}\n\nexport function defineCalendarElement(tagName = 'kal-calendar'): void {\n if (typeof customElements !== 'undefined' && !customElements.get(tagName)) {\n customElements.define(tagName, CalendarElement);\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kal-calendar': CalendarElement;\n }\n}\n","import { CalendarEvent, CalendarDate, CategoryColorMap } 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 MONTHS_FULL = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n];\n\nexport const DAYS = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n];\n\nexport function normalizeDate(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);\n}\n\nexport function isSameDay(date1: Date, date2: Date): boolean {\n return normalizeDate(date1).getTime() === normalizeDate(date2).getTime();\n}\n\nexport function isToday(date: Date): boolean {\n return isSameDay(date, new Date());\n}\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\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\nexport function hasEvents(events: CalendarEvent[], date: Date): boolean {\n return getEventsForDate(events, date).length > 0;\n}\n\nexport function generateCalendarDates(\n year: number,\n month: number,\n events: CalendarEvent[] = [],\n weekStartsOn: 0 | 1 = 0\n): CalendarDate[][] {\n const firstDay = new Date(year, month, 1);\n const lastDay = new Date(year, month + 1, 0);\n const daysInMonth = lastDay.getDate();\n const prevMonthLastDay = new Date(year, month, 0).getDate();\n\n let firstDayOfWeek = firstDay.getDay();\n if (weekStartsOn === 1) {\n firstDayOfWeek = firstDayOfWeek === 0 ? 6 : firstDayOfWeek - 1;\n }\n\n const dates: CalendarDate[][] = [];\n let day = 1;\n let nextMonthDay = 1;\n\n for (let week = 0; week < 6; week++) {\n const weekDates: CalendarDate[] = [];\n\n for (let dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++) {\n if (week === 0 && dayOfWeek < firstDayOfWeek) {\n // Previous month days\n const prevDay = prevMonthLastDay - firstDayOfWeek + dayOfWeek + 1;\n const prevDate = new Date(year, month - 1, prevDay);\n const dateEvents = getEventsForDate(events, prevDate);\n weekDates.push({\n date: prevDate,\n isCurrentMonth: false,\n isToday: isToday(prevDate),\n hasEvents: dateEvents.length > 0,\n events: dateEvents,\n });\n } else if (day > daysInMonth) {\n // Next month days\n const nextDate = new Date(year, month + 1, nextMonthDay);\n const dateEvents = getEventsForDate(events, nextDate);\n weekDates.push({\n date: nextDate,\n isCurrentMonth: false,\n isToday: isToday(nextDate),\n hasEvents: dateEvents.length > 0,\n events: dateEvents,\n });\n nextMonthDay++;\n } else {\n // Current month days\n const currentDate = new Date(year, month, day);\n const dateEvents = getEventsForDate(events, currentDate);\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\n return dates;\n}\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\nexport function getCellClasses(calendarDate: CalendarDate): string[] {\n const classes: string[] = [];\n\n if (!calendarDate.isCurrentMonth) {\n classes.push('other-month');\n }\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\nexport function formatDateForDisplay(date: Date): string {\n return `${DAYS[date.getDay()]} ${date.getDate()}`;\n}\n\nexport function getMonthYearText(year: number, month: number): string {\n return `${MONTHS_FULL[month]} ${year}`;\n}\n\nexport function formatTimeRange(event: CalendarEvent): string {\n if (event.allDay || (!event.startTime && !event.endTime)) {\n return 'All day';\n }\n\n if (event.startTime && event.endTime) {\n return `${event.startTime} - ${event.endTime}`;\n }\n\n if (event.startTime) {\n return `${event.startTime}`;\n }\n\n return '';\n}\n\nexport function formatAttendees(attendees?: string[]): string {\n if (!attendees || attendees.length === 0) return '';\n\n if (attendees.length === 1) return attendees[0];\n if (attendees.length === 2) return attendees.join(' and ');\n\n return `${attendees.slice(0, -1).join(', ')}, and ${attendees[attendees.length - 1]}`;\n}\n\nexport function sortEventsByTime(events: CalendarEvent[]): CalendarEvent[] {\n return [...events].sort((a, b) => {\n const aAllDay = a.allDay || (!a.startTime && !a.endTime);\n const bAllDay = b.allDay || (!b.startTime && !b.endTime);\n\n if (aAllDay && !bAllDay) return -1;\n if (!aAllDay && bAllDay) return 1;\n\n if (!a.startTime || !b.startTime) return 0;\n return a.startTime.localeCompare(b.startTime);\n });\n}\n\nexport const DEFAULT_CATEGORY_COLORS: CategoryColorMap = {\n work: '#3b82f6',\n personal: '#8b5cf6',\n meeting: '#10b981',\n deadline: '#ef4444',\n appointment: '#f59e0b',\n other: '#6b7280',\n};\n\n// Dynamic function that accepts custom colors\nexport function getDefaultEventColor(\n category?: string,\n customColors?: CategoryColorMap\n): string {\n const colorMap = customColors || DEFAULT_CATEGORY_COLORS;\n\n if (category && colorMap[category]) {\n return colorMap[category];\n }\n\n // Default fallback color\n return '#fc8917';\n}\n\n// Helper to merge custom colors with defaults\nexport function mergeCategoryColors(\n customColors?: CategoryColorMap\n): CategoryColorMap {\n return {\n ...DEFAULT_CATEGORY_COLORS,\n ...customColors,\n };\n}\n\n// Validate if a color is a valid hex color\nexport function isValidHexColor(color: string): boolean {\n return /^#([0-9A-F]{3}){1,2}$/i.test(color);\n}\n\n// Get color for a category with validation\nexport function getCategoryColor(\n category: string,\n customColors?: CategoryColorMap\n): string {\n const colorMap = mergeCategoryColors(customColors);\n const color = colorMap[category] || colorMap.other || '#fc8917';\n\n return isValidHexColor(color) ? color : '#fc8917';\n}\n","import {\n CalendarEvent,\n CalendarState,\n CalendarConfig,\n CalendarActions,\n CalendarViewModel,\n CategoryColorMap,\n} from './types';\nimport {\n generateCalendarDates,\n getEventsForDate,\n generateYears,\n getPopupPositionClass,\n getMonthYearText,\n formatDateForDisplay,\n mergeCategoryColors,\n getCategoryColor,\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 private categoryColors: CategoryColorMap;\n\n constructor(config: CalendarConfig) {\n this.config = config;\n this.categoryColors = mergeCategoryColors(config.categoryColors);\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 goToToday: this.goToToday.bind(this),\n isCurrentMonth: this.isCurrentMonth.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 * Navigate to current month (today)\n */\n private goToToday(): void {\n const today = new Date();\n this.state.currentYear = today.getFullYear();\n this.state.currentMonth = today.getMonth();\n this.state.selectedDate = null;\n this.state.selectedDayIndex = null;\n this.updateTasks();\n this.notify();\n }\n\n /**\n * Check if currently viewing today's month\n */\n private isCurrentMonth(): boolean {\n const today = new Date();\n return (\n this.state.currentYear === today.getFullYear() &&\n this.state.currentMonth === today.getMonth()\n );\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 * Get category color (with custom colors support)\n */\n getCategoryColor(category?: string): string {\n if (!category) return '#fc8917';\n return getCategoryColor(category, this.categoryColors);\n }\n\n /**\n * Update category colors dynamically\n */\n updateCategoryColors(colors: CategoryColorMap): void {\n this.categoryColors = mergeCategoryColors(colors);\n this.notify();\n }\n\n /**\n * Get all category colors\n */\n getCategoryColors(): CategoryColorMap {\n return { ...this.categoryColors };\n }\n\n /**\n * Register a new category with color\n */\n registerCategory(name: string, color: string): void {\n this.categoryColors[name] = color;\n this.notify();\n }\n\n /**\n * Destroy the engine and cleanup listeners\n */\n destroy(): void {\n this.listeners.clear();\n }\n}\n"],"mappings":"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","names":["isSameDay","e"]}
@@ -15,6 +15,13 @@
15
15
  --calendar-picker-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
16
16
  --calendar-btn-disabled-opacity: 0.5;
17
17
  --calendar-input-invalid: #ef4444;
18
+ --calendar-text-light: #6b7280;
19
+ --calendar-cell-hover: #f3f4f6;
20
+ --calendar-header-bg: #f8f9fa;
21
+ --calendar-selected-bg: #eff6ff;
22
+ --calendar-popup-bg: #ffffff;
23
+ --calendar-skeleton-base: #f0f0f0;
24
+ --calendar-skeleton-highlight: #e8e8e8;
18
25
 
19
26
  --primary-color: #fc8917;
20
27
  --secondary-color: #fca045;
@@ -67,7 +74,7 @@
67
74
  .calendar--card--header {
68
75
  padding: 1rem 1.25rem;
69
76
  margin-bottom: 0;
70
- background-color: #f8f9fa;
77
+ background-color: var(--calendar-header-bg);
71
78
  border-bottom: 2px solid var(--calendar-border-color);
72
79
  font-size: 1.5rem;
73
80
  font-weight: 600;
@@ -81,7 +88,7 @@
81
88
  justify-content: center;
82
89
  gap: 8px;
83
90
  padding: 12px 16px;
84
- background-color: #f8f9fa;
91
+ background-color: var(--calendar-header-bg);
85
92
  border-bottom: 2px solid var(--calendar-border-color);
86
93
  }
87
94
 
@@ -211,7 +218,7 @@
211
218
  height: 32px;
212
219
  border: none;
213
220
  border-radius: 6px;
214
- background: #f3f4f6;
221
+ background: var(--calendar-cell-hover);
215
222
  cursor: pointer;
216
223
  font-size: 16px;
217
224
  font-weight: 600;
@@ -249,7 +256,7 @@
249
256
 
250
257
  .calendar--picker-year-input.invalid {
251
258
  border-color: var(--calendar-input-invalid);
252
- background-color: #fef2f2;
259
+ background-color: rgba(239, 68, 68, 0.1);
253
260
  }
254
261
 
255
262
  .calendar--picker-months {
@@ -262,7 +269,7 @@
262
269
  padding: 10px 8px;
263
270
  border: 1px solid transparent;
264
271
  border-radius: 6px;
265
- background: #f9fafb;
272
+ background: var(--calendar-cell-hover);
266
273
  cursor: pointer;
267
274
  font-size: 0.875rem;
268
275
  font-weight: 500;
@@ -324,12 +331,12 @@
324
331
  }
325
332
 
326
333
  .calendar--table td.other-month {
327
- color: #9ca3af;
328
- background-color: #f9fafb;
334
+ color: var(--calendar-text-light);
335
+ background-color: var(--calendar-header-bg);
329
336
  }
330
337
 
331
338
  .calendar--table td.other-month:hover {
332
- background-color: #f3f4f6;
339
+ background-color: var(--calendar-cell-hover);
333
340
  }
334
341
 
335
342
  .calendar--table td.has--event {
@@ -430,7 +437,7 @@
430
437
  vertical-align: bottom;
431
438
  border-bottom: 2px solid var(--calendar-border-color);
432
439
  font-weight: 600;
433
- background-color: #f8f9fa;
440
+ background-color: var(--calendar-header-bg);
434
441
  padding: 0.75rem;
435
442
  }
436
443
 
@@ -516,7 +523,7 @@
516
523
  .date-popup {
517
524
  position: absolute;
518
525
  z-index: 1000;
519
- background-color: white;
526
+ background-color: var(--calendar-popup-bg);
520
527
  width: 500px;
521
528
  max-width: 90vw;
522
529
  border-radius: 8px;
@@ -571,10 +578,10 @@
571
578
  }
572
579
 
573
580
  .scroll-hint {
574
- background: #fff3e0;
581
+ background: rgba(var(--calendar-primary-color-rgb), 0.1);
575
582
  padding: 10px 20px;
576
583
  text-align: center;
577
- color: #f59e0b;
584
+ color: var(--calendar-primary-color);
578
585
  font-size: 13px;
579
586
  font-weight: 500;
580
587
  flex-shrink: 0;
@@ -591,21 +598,21 @@
591
598
  }
592
599
 
593
600
  .events-container::-webkit-scrollbar-track {
594
- background: #f1f1f1;
601
+ background: var(--calendar-border-color);
595
602
  }
596
603
 
597
604
  .events-container::-webkit-scrollbar-thumb {
598
- background: #cbd5e0;
605
+ background: var(--calendar-text-light);
599
606
  border-radius: 3px;
600
607
  }
601
608
 
602
609
  .events-container::-webkit-scrollbar-thumb:hover {
603
- background: #a0aec0;
610
+ background: var(--calendar-text-color);
604
611
  }
605
612
 
606
613
  .event-card {
607
- background: white;
608
- border: 1px solid #e5e7eb;
614
+ background: var(--calendar-popup-bg);
615
+ border: 1px solid var(--calendar-border-color);
609
616
  border-left: 4px solid var(--calendar-primary-color);
610
617
  border-radius: 6px;
611
618
  padding: 14px;
@@ -628,7 +635,7 @@
628
635
  .event-title {
629
636
  font-size: 16px;
630
637
  font-weight: 600;
631
- color: #1f2937;
638
+ color: var(--calendar-text-color);
632
639
  flex: 1;
633
640
  word-break: break-word;
634
641
  }
@@ -719,28 +726,28 @@
719
726
 
720
727
  .event-time-label {
721
728
  font-weight: 600;
722
- color: #6b7280;
729
+ color: var(--calendar-text-light);
723
730
  min-width: 70px;
724
731
  flex-shrink: 0;
725
732
  text-align: left;
726
733
  }
727
734
 
728
735
  .event-time-value {
729
- color: #374151;
736
+ color: var(--calendar-text-color);
730
737
  font-weight: 400;
731
738
  word-break: break-word;
732
739
  }
733
740
 
734
741
  .event-description {
735
742
  display: block;
736
- color: #4b5563;
743
+ color: var(--calendar-text-light);
737
744
  font-size: 13px;
738
745
  line-height: 1.6;
739
746
  margin-top: 10px;
740
747
  margin-bottom: 10px;
741
748
  padding: 8px 12px;
742
- background: #f9fafb;
743
- border-left: 2px solid #e5e7eb;
749
+ background: var(--calendar-header-bg);
750
+ border-left: 2px solid var(--calendar-border-color);
744
751
  border-radius: 4px;
745
752
  word-break: break-word;
746
753
  text-align: left;
@@ -767,18 +774,18 @@
767
774
  .event-tag {
768
775
  display: inline-block;
769
776
  padding: 3px 10px;
770
- background-color: #e0f2fe;
771
- color: #0369a1;
777
+ background-color: rgba(var(--calendar-primary-color-rgb), 0.1);
778
+ color: var(--calendar-primary-color);
772
779
  border-radius: 12px;
773
780
  font-size: 11px;
774
781
  font-weight: 500;
775
782
  }
776
783
 
777
784
  .no-events-message {
778
- background: white;
785
+ background: var(--calendar-popup-bg);
779
786
  padding: 30px 20px;
780
787
  text-align: center;
781
- color: #6b7280;
788
+ color: var(--calendar-text-light);
782
789
  font-size: 14px;
783
790
  }
784
791
 
@@ -1056,7 +1063,12 @@
1056
1063
  }
1057
1064
 
1058
1065
  .calendar--table td.calendar--skeleton {
1059
- background: linear-gradient(90deg, #f0f0f0 25%, #e8e8e8 50%, #f0f0f0 75%);
1066
+ background: linear-gradient(
1067
+ 90deg,
1068
+ var(--calendar-skeleton-base) 25%,
1069
+ var(--calendar-skeleton-highlight) 50%,
1070
+ var(--calendar-skeleton-base) 75%
1071
+ );
1060
1072
  background-size: 200% 100%;
1061
1073
  animation: skeleton-shimmer 1.5s ease-in-out infinite;
1062
1074
  border-radius: 4px;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kalendly",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "A universal calendar web component — works in React, Vue, Angular, Svelte, Solid.js, and plain HTML with no framework dependency",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",