calkit 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 @@
1
+ {"version":3,"file":"timepicker.es.js","sources":["../src/core/base-component.js","../src/core/state.js","../src/core/times.js","../src/styles/tokens.js","../src/styles/reset.js","../src/styles/animations.js","../src/components/datepicker/popover.js","../src/components/timepicker/time-grid.js","../src/components/shared/loading-skeleton.js","../src/components/shared/status-message.js","../src/components/timepicker/index.js","../src/entries/timepicker.js"],"sourcesContent":["/**\n * Shared base class for all calendar web components.\n * Provides Shadow DOM setup, style injection, render lifecycle, and helpers.\n */\nexport class CalendarBase extends HTMLElement {\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\n this._initialized = false;\n }\n\n /** Override in subclass — return array of CSSStyleSheet or CSS strings. */\n static get styles() {\n return [];\n }\n\n connectedCallback() {\n if (!this._initialized) {\n this._adoptStyles();\n this._initialized = true;\n }\n this.render();\n }\n\n _adoptStyles() {\n const sheets = this.constructor.styles;\n if (!sheets.length) return;\n\n // Try constructable stylesheets first\n if ('adoptedStyleSheets' in this.shadowRoot) {\n this.shadowRoot.adoptedStyleSheets = sheets.map((s) => {\n if (s instanceof CSSStyleSheet) return s;\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(s);\n return sheet;\n });\n } else {\n // Fallback: inject <style> tags\n for (const s of sheets) {\n const el = document.createElement('style');\n el.textContent = s instanceof CSSStyleSheet ? '' : s;\n this.shadowRoot.prepend(el);\n }\n }\n }\n\n /** Subclasses override to update Shadow DOM. */\n render() {}\n\n /** Dispatch a composed, bubbling custom event. */\n emit(name, detail = {}) {\n this.dispatchEvent(\n new CustomEvent(name, { detail, bubbles: true, composed: true })\n );\n }\n\n /** Show an inline status banner. */\n showStatus(type, message, opts = {}) {\n if (!this._store) return;\n const { autoDismiss, dismissible = true } = opts;\n clearTimeout(this._statusTimer);\n this._store.set({ statusType: type, statusMessage: message, statusDismissible: dismissible });\n this.emit('cal:status', { type, message });\n if (autoDismiss && autoDismiss > 0) {\n this._statusTimer = setTimeout(() => this.clearStatus(), autoDismiss);\n }\n }\n\n /** Clear the status banner. */\n clearStatus() {\n if (!this._store) return;\n clearTimeout(this._statusTimer);\n this._store.set({ statusType: null, statusMessage: null, statusDismissible: true });\n this.emit('cal:status', { type: null, message: null });\n }\n\n /** Query within shadow root. */\n $(selector) {\n return this.shadowRoot.querySelector(selector);\n }\n\n $$(selector) {\n return this.shadowRoot.querySelectorAll(selector);\n }\n}\n","/**\n * Minimal pub/sub reactive store.\n * Usage:\n * const store = createStore({ count: 0 });\n * store.subscribe((state) => console.log(state.count));\n * store.set({ count: 1 });\n */\nexport function createStore(initial) {\n let state = { ...initial };\n const listeners = new Set();\n\n return {\n get(key) {\n return state[key];\n },\n\n set(partial) {\n const prev = state;\n state = { ...state, ...partial };\n // Only notify if something actually changed\n let changed = false;\n for (const key of Object.keys(partial)) {\n if (prev[key] !== state[key]) {\n changed = true;\n break;\n }\n }\n if (changed) {\n for (const fn of listeners) fn(state, prev);\n }\n },\n\n getState() {\n return state;\n },\n\n subscribe(fn) {\n listeners.add(fn);\n return () => listeners.delete(fn);\n },\n };\n}\n","/**\n * Time utility functions for the time picker component.\n */\n\n/**\n * Parse a time string into { hours, minutes }.\n * Handles \"09:00\", \"9:00 AM\", \"14:30\", \"2:30 PM\".\n */\nexport function parseTime(str) {\n if (!str || typeof str !== 'string') return null;\n const trimmed = str.trim().toUpperCase();\n const ampmMatch = trimmed.match(/^(\\d{1,2}):(\\d{2})\\s*(AM|PM)$/);\n if (ampmMatch) {\n let hours = parseInt(ampmMatch[1], 10);\n const minutes = parseInt(ampmMatch[2], 10);\n const period = ampmMatch[3];\n if (period === 'AM' && hours === 12) hours = 0;\n if (period === 'PM' && hours !== 12) hours += 12;\n return { hours, minutes };\n }\n const match24 = trimmed.match(/^(\\d{1,2}):(\\d{2})$/);\n if (match24) {\n return { hours: parseInt(match24[1], 10), minutes: parseInt(match24[2], 10) };\n }\n return null;\n}\n\n/**\n * Format hours/minutes into a display string.\n * @param {number} hours\n * @param {number} minutes\n * @param {'12h'|'24h'} format\n */\nexport function formatTime(hours, minutes, format = '24h') {\n const mm = String(minutes).padStart(2, '0');\n if (format === '12h') {\n const period = hours >= 12 ? 'PM' : 'AM';\n const h = hours % 12 || 12;\n return `${h}:${mm} ${period}`;\n }\n return `${String(hours).padStart(2, '0')}:${mm}`;\n}\n\n/** Convert a time string (HH:MM or h:MM AM/PM) to minutes since midnight. */\nexport function timeToMinutes(str) {\n const t = parseTime(str);\n if (!t) return 0;\n return t.hours * 60 + t.minutes;\n}\n\n/** Convert minutes since midnight back to \"HH:MM\". */\nexport function minutesToTime(n) {\n const hours = Math.floor(n / 60) % 24;\n const minutes = n % 60;\n return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`;\n}\n\n/**\n * Generate time slots between start and end times.\n * @param {string} startTime - e.g. \"09:00\"\n * @param {string} endTime - e.g. \"17:00\"\n * @param {number} intervalMinutes - e.g. 30\n * @returns {string[]} - e.g. [\"09:00\", \"09:30\", \"10:00\", ...]\n */\nexport function generateSlots(startTime, endTime, intervalMinutes) {\n const slots = [];\n const startMin = timeToMinutes(startTime);\n const endMin = timeToMinutes(endTime);\n for (let m = startMin; m <= endMin; m += intervalMinutes) {\n slots.push(minutesToTime(m));\n }\n return slots;\n}\n\n/**\n * Generate time slots with duration labels (e.g. \"09:00–09:30\").\n * @param {string} startTime - e.g. \"09:00\"\n * @param {string} endTime - e.g. \"17:00\"\n * @param {number} intervalMinutes - e.g. 30\n * @param {'12h'|'24h'} format\n * @returns {Array<{time: string, displayText: string}>}\n */\nexport function generateDurationSlots(startTime, endTime, intervalMinutes, format = '24h') {\n const slots = [];\n const startMin = timeToMinutes(startTime);\n const endMin = timeToMinutes(endTime);\n for (let m = startMin; m <= endMin; m += intervalMinutes) {\n const time = minutesToTime(m);\n const nextMin = m + intervalMinutes;\n const endSlotTime = minutesToTime(Math.min(nextMin, endMin + intervalMinutes));\n const parsed = parseTime(time);\n const parsedEnd = parseTime(endSlotTime);\n const fromText = parsed ? formatTime(parsed.hours, parsed.minutes, format) : time;\n const toText = parsedEnd ? formatTime(parsedEnd.hours, parsedEnd.minutes, format) : endSlotTime;\n slots.push({ time, displayText: `${fromText}\\u2013${toText}` });\n }\n return slots;\n}\n\n/** Returns true if time A is strictly before time B. */\nexport function isTimeBefore(a, b) {\n return timeToMinutes(a) < timeToMinutes(b);\n}\n\n/**\n * Check if two time ranges overlap (exclusive boundaries).\n * @param {string} startA - \"HH:MM\"\n * @param {string} endA - \"HH:MM\"\n * @param {string} startB - \"HH:MM\"\n * @param {string} endB - \"HH:MM\"\n * @returns {boolean}\n */\nexport function timeRangesOverlap(startA, endA, startB, endB) {\n const a0 = timeToMinutes(startA);\n const a1 = timeToMinutes(endA);\n const b0 = timeToMinutes(startB);\n const b1 = timeToMinutes(endB);\n return a0 < b1 && a1 > b0;\n}\n\n/**\n * Get the current time as \"HH:MM\".\n * @returns {string}\n */\nexport function currentTime() {\n const now = new Date();\n return `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;\n}\n\n/** Returns true if time is within [start, end] inclusive. */\nexport function isTimeInRange(time, start, end) {\n const t = timeToMinutes(time);\n const s = timeToMinutes(start);\n const e = timeToMinutes(end);\n const lo = Math.min(s, e);\n const hi = Math.max(s, e);\n return t >= lo && t <= hi;\n}\n","export const tokens = `\n :host {\n /* Light theme (default) */\n --cal-bg: 0 0% 100%;\n --cal-bg-muted: 240 5% 96%;\n --cal-fg: 240 6% 10%;\n --cal-fg-muted: 240 4% 46%;\n --cal-border: 240 6% 90%;\n --cal-accent: 240 6% 10%;\n --cal-accent-fg: 0 0% 100%;\n --cal-accent-subtle: 240 5% 96%;\n --cal-hover: 240 5% 93%;\n --cal-ring: 240 6% 10%;\n --cal-radius: 8px;\n --cal-radius-sm: 6px;\n --cal-cell-size: 36px;\n --cal-transition: 150ms ease;\n\n /* Booking color palette (softer / less saturated) */\n --cal-booking-blue-bg: 217 55% 94%;\n --cal-booking-blue-fg: 217 60% 35%;\n --cal-booking-green-bg: 152 45% 93%;\n --cal-booking-green-fg: 152 55% 28%;\n --cal-booking-red-bg: 4 50% 94%;\n --cal-booking-red-fg: 4 55% 40%;\n --cal-booking-orange-bg: 30 55% 93%;\n --cal-booking-orange-fg: 30 60% 35%;\n --cal-booking-gray-bg: 240 8% 94%;\n --cal-booking-gray-fg: 240 8% 38%;\n\n /* Booking hover tokens */\n --cal-booking-blue-hover: 217 55% 88%;\n --cal-booking-green-hover: 152 45% 87%;\n --cal-booking-red-hover: 4 50% 88%;\n --cal-booking-orange-hover: 30 55% 87%;\n --cal-booking-gray-hover: 240 8% 88%;\n\n /* Scheduler tokens */\n --cal-sched-grid-line: 240 6% 94%;\n --cal-sched-now-line: 4 70% 55%;\n --cal-sched-slot-hover: 240 5% 97%;\n --cal-sched-header-bg: 240 5% 98%;\n\n /* Status tokens */\n --cal-status-error-bg: 4 50% 95%;\n --cal-status-error-fg: 4 55% 40%;\n --cal-status-error-border: 4 50% 85%;\n --cal-status-warning-bg: 40 55% 95%;\n --cal-status-warning-fg: 40 60% 35%;\n --cal-status-warning-border: 40 50% 85%;\n --cal-status-info-bg: 217 55% 95%;\n --cal-status-info-fg: 217 60% 35%;\n --cal-status-info-border: 217 50% 85%;\n --cal-status-success-bg: 152 45% 95%;\n --cal-status-success-fg: 152 55% 28%;\n --cal-status-success-border: 152 45% 85%;\n }\n\n :host([theme=\"dark\"]) {\n --cal-bg: 240 6% 10%;\n --cal-bg-muted: 240 4% 16%;\n --cal-fg: 0 0% 98%;\n --cal-fg-muted: 240 4% 54%;\n --cal-border: 240 4% 20%;\n --cal-accent: 0 0% 98%;\n --cal-accent-fg: 240 6% 10%;\n --cal-accent-subtle: 240 4% 16%;\n --cal-hover: 240 4% 20%;\n --cal-ring: 0 0% 98%;\n\n --cal-booking-blue-bg: 217 50% 25%;\n --cal-booking-blue-fg: 217 80% 75%;\n --cal-booking-green-bg: 142 40% 22%;\n --cal-booking-green-fg: 142 70% 70%;\n --cal-booking-red-bg: 4 45% 25%;\n --cal-booking-red-fg: 4 70% 75%;\n --cal-booking-orange-bg: 30 45% 25%;\n --cal-booking-orange-fg: 30 80% 75%;\n --cal-booking-gray-bg: 240 5% 22%;\n --cal-booking-gray-fg: 240 5% 65%;\n\n --cal-booking-blue-hover: 217 50% 30%;\n --cal-booking-green-hover: 142 40% 27%;\n --cal-booking-red-hover: 4 45% 30%;\n --cal-booking-orange-hover: 30 45% 30%;\n --cal-booking-gray-hover: 240 5% 27%;\n\n --cal-sched-grid-line: 240 4% 18%;\n --cal-sched-now-line: 4 55% 55%;\n --cal-sched-slot-hover: 240 4% 14%;\n --cal-sched-header-bg: 240 5% 12%;\n\n --cal-status-error-bg: 4 45% 20%;\n --cal-status-error-fg: 4 70% 75%;\n --cal-status-error-border: 4 45% 30%;\n --cal-status-warning-bg: 40 45% 20%;\n --cal-status-warning-fg: 40 80% 75%;\n --cal-status-warning-border: 40 45% 30%;\n --cal-status-info-bg: 217 50% 20%;\n --cal-status-info-fg: 217 80% 75%;\n --cal-status-info-border: 217 50% 30%;\n --cal-status-success-bg: 152 40% 18%;\n --cal-status-success-fg: 152 70% 70%;\n --cal-status-success-border: 152 40% 28%;\n }\n\n :host([theme=\"auto\"]) {\n --cal-bg: 0 0% 100%;\n --cal-bg-muted: 240 5% 96%;\n --cal-fg: 240 6% 10%;\n --cal-fg-muted: 240 4% 46%;\n --cal-border: 240 6% 90%;\n --cal-accent: 240 6% 10%;\n --cal-accent-fg: 0 0% 100%;\n --cal-accent-subtle: 240 5% 96%;\n --cal-hover: 240 5% 93%;\n --cal-ring: 240 6% 10%;\n }\n\n @media (prefers-color-scheme: dark) {\n :host([theme=\"auto\"]) {\n --cal-bg: 240 6% 10%;\n --cal-bg-muted: 240 4% 16%;\n --cal-fg: 0 0% 98%;\n --cal-fg-muted: 240 4% 54%;\n --cal-border: 240 4% 20%;\n --cal-accent: 0 0% 98%;\n --cal-accent-fg: 240 6% 10%;\n --cal-accent-subtle: 240 4% 16%;\n --cal-hover: 240 4% 20%;\n --cal-ring: 0 0% 98%;\n\n --cal-booking-blue-bg: 217 50% 25%;\n --cal-booking-blue-fg: 217 80% 75%;\n --cal-booking-green-bg: 142 40% 22%;\n --cal-booking-green-fg: 142 70% 70%;\n --cal-booking-red-bg: 4 45% 25%;\n --cal-booking-red-fg: 4 70% 75%;\n --cal-booking-orange-bg: 30 45% 25%;\n --cal-booking-orange-fg: 30 80% 75%;\n --cal-booking-gray-bg: 240 5% 22%;\n --cal-booking-gray-fg: 240 5% 65%;\n\n --cal-booking-blue-hover: 217 50% 30%;\n --cal-booking-green-hover: 142 40% 27%;\n --cal-booking-red-hover: 4 45% 30%;\n --cal-booking-orange-hover: 30 45% 30%;\n --cal-booking-gray-hover: 240 5% 27%;\n\n --cal-sched-grid-line: 240 4% 18%;\n --cal-sched-now-line: 4 55% 55%;\n --cal-sched-slot-hover: 240 4% 14%;\n --cal-sched-header-bg: 240 5% 12%;\n\n --cal-status-error-bg: 4 45% 20%;\n --cal-status-error-fg: 4 70% 75%;\n --cal-status-error-border: 4 45% 30%;\n --cal-status-warning-bg: 40 45% 20%;\n --cal-status-warning-fg: 40 80% 75%;\n --cal-status-warning-border: 40 45% 30%;\n --cal-status-info-bg: 217 50% 20%;\n --cal-status-info-fg: 217 80% 75%;\n --cal-status-info-border: 217 50% 30%;\n --cal-status-success-bg: 152 40% 18%;\n --cal-status-success-fg: 152 70% 70%;\n --cal-status-success-border: 152 40% 28%;\n }\n }\n`;\n","export const reset = `\n :host {\n display: inline-block;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n color: hsl(var(--cal-fg));\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n }\n\n :host([display=\"inline\"]) {\n display: inline-block;\n }\n\n *,\n *::before,\n *::after {\n box-sizing: border-box;\n }\n\n button {\n font: inherit;\n color: inherit;\n background: none;\n border: none;\n padding: 0;\n margin: 0;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n }\n\n button:focus-visible {\n outline: 2px solid hsl(var(--cal-ring));\n outline-offset: 2px;\n border-radius: var(--cal-radius-sm);\n }\n\n [hidden] {\n display: none !important;\n }\n`;\n","export const animations = `\n @keyframes cal-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n\n @keyframes cal-slide-up {\n from {\n opacity: 0;\n transform: translateY(4px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n @keyframes cal-slide-left {\n from {\n opacity: 0;\n transform: translateX(16px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n }\n\n @keyframes cal-slide-right {\n from {\n opacity: 0;\n transform: translateX(-16px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n }\n\n .cal-animate-fade { animation: cal-fade-in 150ms cubic-bezier(0.16, 1, 0.3, 1); }\n .cal-animate-slide-up { animation: cal-slide-up 200ms cubic-bezier(0.16, 1, 0.3, 1); }\n .cal-animate-slide-left { animation: cal-slide-left 200ms cubic-bezier(0.16, 1, 0.3, 1); }\n .cal-animate-slide-right { animation: cal-slide-right 200ms cubic-bezier(0.16, 1, 0.3, 1); }\n\n @keyframes cal-shimmer {\n 0% { background-position: -200% 0; }\n 100% { background-position: 200% 0; }\n }\n\n .cal-skeleton {\n background: linear-gradient(\n 90deg,\n hsl(var(--cal-bg-muted)) 25%,\n hsl(var(--cal-hover)) 50%,\n hsl(var(--cal-bg-muted)) 75%\n );\n background-size: 200% 100%;\n animation: cal-shimmer 1.5s infinite ease-in-out;\n border-radius: 999px;\n }\n\n .cal-skeleton--rect {\n border-radius: var(--cal-radius-sm);\n }\n`;\n","/**\n * Creates a popover panel anchored to a trigger element.\n * @param {object} options\n * @param {HTMLElement} options.trigger - the element that opens the popover\n * @param {HTMLElement} options.content - the popover body\n * @param {function} options.onClose\n * @returns {{ panel: HTMLElement, open: function, close: function, destroy: function }}\n */\nexport function createPopover({ trigger, content, onClose }) {\n const panel = document.createElement('div');\n panel.classList.add('cal-popover');\n panel.setAttribute('role', 'dialog');\n panel.setAttribute('aria-modal', 'false');\n panel.style.display = 'none';\n panel.appendChild(content);\n\n let isOpen = false;\n\n function position() {\n // Reset position classes\n panel.classList.remove('cal-popover--above');\n\n const triggerRect = trigger.getBoundingClientRect();\n const panelHeight = panel.offsetHeight;\n const spaceBelow = window.innerHeight - triggerRect.bottom;\n const spaceAbove = triggerRect.top;\n\n // Prefer below, flip above if not enough space\n if (spaceBelow < panelHeight + 8 && spaceAbove > spaceBelow) {\n panel.classList.add('cal-popover--above');\n panel.style.top = 'auto';\n panel.style.bottom = '100%';\n panel.style.marginBottom = '4px';\n panel.style.marginTop = '0';\n } else {\n panel.style.top = '100%';\n panel.style.bottom = 'auto';\n panel.style.marginTop = '4px';\n panel.style.marginBottom = '0';\n }\n }\n\n function open() {\n if (isOpen) return;\n isOpen = true;\n panel.style.display = '';\n panel.classList.add('cal-animate-slide-up');\n // Measure after display\n requestAnimationFrame(() => position());\n document.addEventListener('click', outsideClick, true);\n document.addEventListener('keydown', escapeKey, true);\n }\n\n function close() {\n if (!isOpen) return;\n isOpen = false;\n panel.style.display = 'none';\n panel.classList.remove('cal-animate-slide-up');\n document.removeEventListener('click', outsideClick, true);\n document.removeEventListener('keydown', escapeKey, true);\n onClose?.();\n }\n\n function outsideClick(e) {\n // Check if click is inside the shadow host that contains our trigger/panel\n const host = trigger.getRootNode()?.host;\n if (host && !host.contains(e.target) && e.target !== host) {\n close();\n }\n }\n\n function escapeKey(e) {\n if (e.key === 'Escape') {\n e.stopPropagation();\n close();\n }\n }\n\n function destroy() {\n // Teardown without firing onClose (which would mutate store during render)\n if (isOpen) {\n isOpen = false;\n panel.style.display = 'none';\n panel.classList.remove('cal-animate-slide-up');\n }\n document.removeEventListener('click', outsideClick, true);\n document.removeEventListener('keydown', escapeKey, true);\n }\n\n return { panel, open, close, destroy, get isOpen() { return isOpen; } };\n}\n\nexport const popoverStyles = `\n .cal-popover-wrapper {\n position: relative;\n display: inline-block;\n }\n\n .cal-popover {\n position: absolute;\n left: 0;\n z-index: 50;\n background: hsl(var(--cal-bg));\n border: 1px solid hsl(var(--cal-border));\n border-radius: var(--cal-radius);\n box-shadow: 0 4px 16px -2px rgba(0, 0, 0, 0.08), 0 2px 6px -2px rgba(0, 0, 0, 0.04);\n padding: 12px;\n }\n\n .cal-trigger {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n height: 36px;\n padding: 0 12px;\n font-size: 14px;\n border: 1px solid hsl(var(--cal-border));\n border-radius: var(--cal-radius-sm);\n background: hsl(var(--cal-bg));\n color: hsl(var(--cal-fg));\n cursor: pointer;\n transition: border-color var(--cal-transition);\n white-space: nowrap;\n }\n\n .cal-trigger:hover {\n border-color: hsl(var(--cal-fg-muted));\n }\n\n .cal-trigger--placeholder {\n color: hsl(var(--cal-fg-muted));\n }\n\n .cal-trigger__icon {\n display: flex;\n color: hsl(var(--cal-fg-muted));\n }\n`;\n","/**\n * Time slot grid renderer — pill-shaped slot buttons in a responsive grid.\n */\nimport { formatTime, parseTime, isTimeInRange } from '../../core/times.js';\n\n/**\n * @param {object} options\n * @param {Array<{time: string, label?: string, available?: boolean}>} options.slots\n * @param {string} options.mode - single|multi|range\n * @param {string|null} options.format - '12h'|'24h'\n * @param {string|string[]|{start,end}|null} options.selected\n * @param {string|null} options.hoverTime - for range preview\n * @param {string|null} options.rangeStart - for range mode in-progress\n * @param {string[]} options.unavailableTimes\n * @param {function} options.onSelect\n * @param {function} options.onHover\n * @returns {HTMLElement}\n */\nexport function renderTimeGrid(options) {\n const {\n slots = [], mode = 'single', format = '24h',\n selected, hoverTime, rangeStart,\n unavailableTimes = [],\n onSelect, onHover,\n durationLabels = false,\n } = options;\n\n const grid = document.createElement('div');\n grid.classList.add('cal-time-grid');\n if (durationLabels) grid.classList.add('cal-time-grid--duration');\n grid.setAttribute('role', 'listbox');\n if (mode === 'multi') grid.setAttribute('aria-multiselectable', 'true');\n\n for (const slot of slots) {\n const btn = document.createElement('button');\n btn.classList.add('cal-time-slot');\n btn.setAttribute('role', 'option');\n btn.dataset.time = slot.time;\n\n // Format display text — slot.displayText takes priority\n const parsed = parseTime(slot.time);\n const displayTime = slot.displayText\n ? slot.displayText\n : (parsed ? formatTime(parsed.hours, parsed.minutes, format) : slot.time);\n\n const timeSpan = document.createElement('span');\n timeSpan.classList.add('cal-time-slot__time');\n timeSpan.textContent = displayTime;\n btn.appendChild(timeSpan);\n\n if (slot.label) {\n const labelSpan = document.createElement('span');\n labelSpan.classList.add('cal-time-slot__label');\n labelSpan.textContent = slot.label;\n btn.appendChild(labelSpan);\n }\n\n // Available/unavailable\n const isUnavailable = slot.available === false || unavailableTimes.includes(slot.time);\n if (isUnavailable) {\n btn.classList.add('cal-time-slot--unavailable');\n btn.disabled = true;\n btn.setAttribute('aria-disabled', 'true');\n }\n\n // Selected state\n const isSelected = isSlotSelected(slot.time, selected, mode);\n if (isSelected) {\n btn.classList.add('cal-time-slot--selected');\n btn.setAttribute('aria-selected', 'true');\n } else {\n btn.setAttribute('aria-selected', 'false');\n }\n\n // Range in-progress preview\n if (mode === 'range' && rangeStart && !isRangeComplete(selected) && hoverTime) {\n const inRange = isTimeInRange(slot.time, rangeStart, hoverTime);\n const isStart = slot.time === rangeStart;\n const isEnd = slot.time === hoverTime;\n if (inRange && !isStart && !isEnd) {\n btn.classList.add('cal-time-slot--in-range');\n }\n if (isStart) btn.classList.add('cal-time-slot--range-start');\n if (isEnd) btn.classList.add('cal-time-slot--range-end');\n } else if (mode === 'range' && selected && typeof selected === 'object' && selected.start && selected.end) {\n // Completed range\n const inRange = isTimeInRange(slot.time, selected.start, selected.end);\n const isStart = slot.time === selected.start;\n const isEnd = slot.time === selected.end;\n if (isStart) btn.classList.add('cal-time-slot--range-start', 'cal-time-slot--selected');\n if (isEnd) btn.classList.add('cal-time-slot--range-end', 'cal-time-slot--selected');\n if (inRange && !isStart && !isEnd) btn.classList.add('cal-time-slot--in-range');\n }\n\n // Events\n if (!isUnavailable) {\n btn.addEventListener('click', () => onSelect?.(slot.time));\n btn.addEventListener('mouseenter', () => onHover?.(slot.time));\n }\n\n grid.appendChild(btn);\n }\n\n grid.addEventListener('mouseleave', () => onHover?.(null));\n\n return grid;\n}\n\nfunction isSlotSelected(time, selected, mode) {\n if (!selected) return false;\n if (mode === 'single') return selected === time;\n if (mode === 'multi') return Array.isArray(selected) && selected.includes(time);\n if (mode === 'range') {\n if (typeof selected === 'object' && selected.start && selected.end) {\n return selected.start === time || selected.end === time;\n }\n }\n return false;\n}\n\nfunction isRangeComplete(selected) {\n return selected && typeof selected === 'object' && selected.start && selected.end;\n}\n\nexport const timeGridStyles = `\n .cal-time-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));\n gap: 6px;\n max-height: 280px;\n overflow-y: auto;\n padding: 4px;\n }\n\n .cal-time-grid::-webkit-scrollbar {\n width: 6px;\n }\n\n .cal-time-grid::-webkit-scrollbar-track {\n background: transparent;\n }\n\n .cal-time-grid::-webkit-scrollbar-thumb {\n background: hsl(var(--cal-border));\n border-radius: 3px;\n }\n\n .cal-time-slot {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 40px;\n padding: 0 8px;\n border-radius: 999px;\n font-size: 13px;\n background: hsl(var(--cal-bg-muted));\n color: hsl(var(--cal-fg));\n transition: background var(--cal-transition), color var(--cal-transition);\n gap: 1px;\n }\n\n .cal-time-slot:not(.cal-time-slot--unavailable):not(.cal-time-slot--selected):hover {\n background: hsl(var(--cal-hover));\n }\n\n .cal-time-slot__time {\n font-weight: 500;\n line-height: 1;\n }\n\n .cal-time-slot__label {\n font-size: 9px;\n opacity: 0.7;\n line-height: 1;\n }\n\n .cal-time-slot--selected {\n background: hsl(var(--cal-accent));\n color: hsl(var(--cal-accent-fg));\n font-weight: 600;\n }\n\n .cal-time-slot--in-range {\n background: hsl(var(--cal-accent-subtle));\n }\n\n .cal-time-slot--range-start,\n .cal-time-slot--range-end {\n background: hsl(var(--cal-accent));\n color: hsl(var(--cal-accent-fg));\n font-weight: 600;\n }\n\n .cal-time-slot--unavailable {\n opacity: 0.3;\n cursor: not-allowed;\n }\n\n .cal-time-grid--duration {\n grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));\n }\n\n .cal-time-grid--duration .cal-time-slot {\n font-size: 12px;\n }\n`;\n","/**\n * Loading skeleton renderers for shimmer placeholders.\n */\n\n/**\n * Render a skeleton matching the time grid layout.\n * @param {object} options\n * @param {number} options.columns - grid columns (default 3)\n * @param {number} options.rows - number of rows (default 4)\n * @param {boolean} options.durationLabels - wider pills for duration labels\n * @returns {HTMLElement}\n */\nexport function renderTimeGridSkeleton({ columns = 3, rows = 4, durationLabels = false } = {}) {\n const wrapper = document.createElement('div');\n wrapper.setAttribute('role', 'status');\n wrapper.setAttribute('aria-label', 'Loading...');\n wrapper.classList.add('cal-skeleton-time-grid');\n if (durationLabels) wrapper.classList.add('cal-skeleton-time-grid--duration');\n\n const count = columns * rows;\n for (let i = 0; i < count; i++) {\n const pill = document.createElement('div');\n pill.classList.add('cal-skeleton');\n wrapper.appendChild(pill);\n }\n return wrapper;\n}\n\n/**\n * Render a skeleton matching the calendar day grid layout.\n * @param {object} options\n * @param {number} options.rows - number of week rows (default 5)\n * @returns {HTMLElement}\n */\nexport function renderCalendarGridSkeleton({ rows = 5 } = {}) {\n const wrapper = document.createElement('div');\n wrapper.setAttribute('role', 'status');\n wrapper.setAttribute('aria-label', 'Loading...');\n wrapper.classList.add('cal-skeleton-calendar-grid');\n\n // Header row (7 day labels)\n for (let i = 0; i < 7; i++) {\n const label = document.createElement('div');\n label.classList.add('cal-skeleton', 'cal-skeleton-calendar-grid__header');\n wrapper.appendChild(label);\n }\n\n // Day cells\n const count = 7 * rows;\n for (let i = 0; i < count; i++) {\n const cell = document.createElement('div');\n cell.classList.add('cal-skeleton', 'cal-skeleton-calendar-grid__day');\n wrapper.appendChild(cell);\n }\n return wrapper;\n}\n\nexport const loadingSkeletonStyles = `\n .cal-skeleton-time-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));\n gap: 6px;\n padding: 4px;\n }\n\n .cal-skeleton-time-grid--duration {\n grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));\n }\n\n .cal-skeleton-time-grid .cal-skeleton {\n height: 40px;\n }\n\n .cal-skeleton-calendar-grid {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n gap: 2px;\n padding: 4px;\n }\n\n .cal-skeleton-calendar-grid__header {\n height: 20px;\n margin-bottom: 4px;\n }\n\n .cal-skeleton-calendar-grid__day {\n height: var(--cal-cell-size, 36px);\n aspect-ratio: 1;\n border-radius: var(--cal-radius-sm) !important;\n }\n`;\n","/**\n * Status message renderer — inline banners with type-specific icons and colors.\n */\n\nconst icons = {\n error: `<svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"><circle cx=\"7\" cy=\"7\" r=\"6\"/><path d=\"M7 4v3M7 9.5v.01\"/></svg>`,\n warning: `<svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"><path d=\"M7 1.5L1 12.5h12L7 1.5zM7 6v2.5M7 10.5v.01\"/></svg>`,\n info: `<svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"><circle cx=\"7\" cy=\"7\" r=\"6\"/><path d=\"M7 6.5V10M7 4.5v.01\"/></svg>`,\n success: `<svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"><circle cx=\"7\" cy=\"7\" r=\"6\"/><path d=\"M4.5 7l2 2L9.5 5\"/></svg>`,\n};\n\n/**\n * Render a status message banner.\n * @param {object} options\n * @param {'error'|'warning'|'info'|'success'} options.type\n * @param {string} options.message\n * @param {boolean} options.dismissible\n * @param {function} options.onDismiss\n * @returns {HTMLElement}\n */\nexport function renderStatusMessage({ type = 'info', message, dismissible = true, onDismiss }) {\n const banner = document.createElement('div');\n banner.classList.add('cal-status', `cal-status--${type}`, 'cal-animate-slide-up');\n banner.setAttribute('role', type === 'error' ? 'alert' : 'status');\n banner.setAttribute('aria-live', type === 'error' ? 'assertive' : 'polite');\n\n const icon = document.createElement('span');\n icon.classList.add('cal-status__icon');\n icon.innerHTML = icons[type] || icons.info;\n banner.appendChild(icon);\n\n const text = document.createElement('span');\n text.classList.add('cal-status__text');\n text.textContent = message;\n banner.appendChild(text);\n\n if (dismissible) {\n const closeBtn = document.createElement('button');\n closeBtn.classList.add('cal-status__close');\n closeBtn.setAttribute('aria-label', 'Dismiss');\n closeBtn.innerHTML = `<svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"><path d=\"M3 3l6 6M9 3l-6 6\"/></svg>`;\n closeBtn.addEventListener('click', () => onDismiss?.());\n banner.appendChild(closeBtn);\n }\n\n return banner;\n}\n\nexport const statusMessageStyles = `\n .cal-status {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-radius: var(--cal-radius-sm);\n font-size: 12px;\n line-height: 1.4;\n margin-bottom: 8px;\n }\n\n .cal-status__icon {\n flex-shrink: 0;\n display: flex;\n }\n\n .cal-status__text {\n flex: 1;\n min-width: 0;\n }\n\n .cal-status__close {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 4px;\n cursor: pointer;\n opacity: 0.7;\n transition: opacity var(--cal-transition);\n }\n\n .cal-status__close:hover {\n opacity: 1;\n }\n\n .cal-status--error {\n background: hsl(var(--cal-status-error-bg));\n color: hsl(var(--cal-status-error-fg));\n border: 1px solid hsl(var(--cal-status-error-border));\n }\n\n .cal-status--warning {\n background: hsl(var(--cal-status-warning-bg));\n color: hsl(var(--cal-status-warning-fg));\n border: 1px solid hsl(var(--cal-status-warning-border));\n }\n\n .cal-status--info {\n background: hsl(var(--cal-status-info-bg));\n color: hsl(var(--cal-status-info-fg));\n border: 1px solid hsl(var(--cal-status-info-border));\n }\n\n .cal-status--success {\n background: hsl(var(--cal-status-success-bg));\n color: hsl(var(--cal-status-success-fg));\n border: 1px solid hsl(var(--cal-status-success-border));\n }\n`;\n","import { CalendarBase } from '../../core/base-component.js';\nimport { createStore } from '../../core/state.js';\nimport { generateSlots, generateDurationSlots, timeToMinutes } from '../../core/times.js';\nimport { tokens } from '../../styles/tokens.js';\nimport { reset } from '../../styles/reset.js';\nimport { animations } from '../../styles/animations.js';\nimport { createPopover, popoverStyles } from '../datepicker/popover.js';\nimport { renderTimeGrid, timeGridStyles } from './time-grid.js';\nimport { renderTimeGridSkeleton, loadingSkeletonStyles } from '../shared/loading-skeleton.js';\nimport { renderStatusMessage, statusMessageStyles } from '../shared/status-message.js';\n\nconst clockIcon = `<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"8\" cy=\"8\" r=\"6\"/><path d=\"M8 4.5V8l2.5 1.5\"/></svg>`;\n\nconst componentStyles = `\n .cal-timepicker {\n background: hsl(var(--cal-bg));\n border-radius: var(--cal-radius);\n user-select: none;\n min-width: 200px;\n }\n\n :host([display=\"inline\"]) .cal-timepicker {\n border: 1px solid hsl(var(--cal-border));\n padding: 12px;\n }\n\n .cal-timepicker__header {\n font-size: 14px;\n font-weight: 600;\n color: hsl(var(--cal-fg));\n margin-bottom: 8px;\n padding: 0 4px;\n }\n`;\n\nexport class CalTimepicker extends CalendarBase {\n static get styles() {\n return [tokens, reset, animations, timeGridStyles, popoverStyles, loadingSkeletonStyles, statusMessageStyles, componentStyles];\n }\n\n static get observedAttributes() {\n return ['mode', 'display', 'theme', 'start-time', 'end-time', 'interval', 'format', 'placeholder', 'value', 'duration-labels', 'loading'];\n }\n\n constructor() {\n super();\n\n this._store = createStore({\n selected: null, // string | string[] | {start, end}\n rangeStart: null, // for range mode in-progress\n hoverTime: null,\n isOpen: false,\n statusType: null,\n statusMessage: null,\n statusDismissible: true,\n });\n\n this._slots = null; // explicit slots (highest priority)\n this._unavailableTimes = [];\n this._popover = null;\n this._unsubscribe = null;\n this._rendering = false;\n }\n\n // -- Attribute getters --\n get mode() { return this.getAttribute('mode') || 'single'; }\n get display() { return this.getAttribute('display') || 'inline'; }\n get placeholder() { return this.getAttribute('placeholder') || 'Select time'; }\n get startTime() { return this.getAttribute('start-time') || '09:00'; }\n get endTime() { return this.getAttribute('end-time') || '17:00'; }\n get interval() { return parseInt(this.getAttribute('interval') || '30', 10); }\n get format() { return this.getAttribute('format') || '24h'; }\n get durationLabels() { return this.hasAttribute('duration-labels'); }\n get loading() { return this.hasAttribute('loading'); }\n set loading(val) { val ? this.setAttribute('loading', '') : this.removeAttribute('loading'); }\n\n // -- Properties --\n get slots() { return this._slots; }\n set slots(val) {\n this._slots = Array.isArray(val) ? val : null;\n if (this._initialized) this.render();\n }\n\n get unavailableTimes() { return this._unavailableTimes; }\n set unavailableTimes(val) {\n this._unavailableTimes = Array.isArray(val) ? val : [];\n if (this._initialized) this.render();\n }\n\n get value() {\n const state = this._store.getState();\n return state.selected;\n }\n\n set value(val) {\n if (this.mode === 'single' && typeof val === 'string') {\n this._store.set({ selected: val, rangeStart: null });\n } else if (this.mode === 'multi' && Array.isArray(val)) {\n this._store.set({ selected: [...val].sort((a, b) => timeToMinutes(a) - timeToMinutes(b)), rangeStart: null });\n } else if (this.mode === 'range' && val && typeof val === 'object') {\n this._store.set({ selected: { start: val.start, end: val.end }, rangeStart: null });\n } else {\n this._store.set({ selected: null, rangeStart: null });\n }\n }\n\n _getEffectiveSlots() {\n // Priority 1: explicit slots property\n if (this._slots) return this._slots;\n // Priority 2: auto-generate from attributes\n if (this.durationLabels) {\n const durationSlots = generateDurationSlots(this.startTime, this.endTime, this.interval, this.format);\n return durationSlots.map((slot) => ({\n ...slot,\n available: !this._unavailableTimes.includes(slot.time),\n }));\n }\n const times = generateSlots(this.startTime, this.endTime, this.interval);\n return times.map((time) => ({\n time,\n available: !this._unavailableTimes.includes(time),\n }));\n }\n\n connectedCallback() {\n super.connectedCallback();\n this._unsubscribe = this._store.subscribe((state, prev) => {\n if (this._rendering) return;\n // Hover-only → lightweight update\n const hoverOnly = state.hoverTime !== prev.hoverTime\n && state.selected === prev.selected\n && state.rangeStart === prev.rangeStart\n && state.isOpen === prev.isOpen;\n hoverOnly ? this._updateSlotHighlight(state) : this.render();\n });\n\n // Parse initial value attribute\n const valueAttr = this.getAttribute('value');\n if (valueAttr) {\n if (this.mode === 'multi' && valueAttr.includes(',')) {\n this.value = valueAttr.split(',').map((t) => t.trim());\n } else if (this.mode === 'range' && valueAttr.includes('/')) {\n const [start, end] = valueAttr.split('/');\n this.value = { start: start.trim(), end: end.trim() };\n } else {\n this.value = valueAttr;\n }\n }\n }\n\n disconnectedCallback() {\n this._unsubscribe?.();\n this._popover?.destroy();\n clearTimeout(this._statusTimer);\n }\n\n attributeChangedCallback(name, oldVal, newVal) {\n if (oldVal === newVal) return;\n if (name === 'value' && this._initialized) {\n if (this.mode === 'multi' && newVal && newVal.includes(',')) {\n this.value = newVal.split(',').map((t) => t.trim());\n } else if (this.mode === 'range' && newVal && newVal.includes('/')) {\n const [start, end] = newVal.split('/');\n this.value = { start: start.trim(), end: end.trim() };\n } else {\n this.value = newVal;\n }\n }\n if (this._initialized) this.render();\n }\n\n // -- Selection --\n _handleSelect(time) {\n const state = this._store.getState();\n\n if (this.mode === 'single') {\n this._store.set({ selected: time });\n this.emit('cal:time-change', { value: time });\n if (this.display === 'popover') this.close();\n } else if (this.mode === 'multi') {\n const current = Array.isArray(state.selected) ? [...state.selected] : [];\n const idx = current.indexOf(time);\n if (idx >= 0) {\n current.splice(idx, 1);\n } else {\n current.push(time);\n }\n current.sort((a, b) => timeToMinutes(a) - timeToMinutes(b));\n this._store.set({ selected: current });\n this.emit('cal:time-change', { value: current });\n } else if (this.mode === 'range') {\n if (!state.rangeStart || (state.selected && typeof state.selected === 'object' && state.selected.start && state.selected.end)) {\n // Start new range\n this._store.set({ rangeStart: time, selected: null, hoverTime: null });\n } else {\n // Complete range\n let start = state.rangeStart;\n let end = time;\n if (timeToMinutes(start) > timeToMinutes(end)) [start, end] = [end, start];\n const value = { start, end };\n this._store.set({ selected: value, rangeStart: null, hoverTime: null });\n this.emit('cal:time-change', { value });\n if (this.display === 'popover') this.close();\n }\n }\n }\n\n _handleHover(time) {\n if (this.mode === 'range') {\n this._store.set({ hoverTime: time });\n }\n }\n\n // -- Lightweight hover highlight --\n _updateSlotHighlight(state) {\n const buttons = this.$$('.cal-time-slot');\n const { rangeStart, hoverTime, selected } = state;\n const rangeComplete = selected && typeof selected === 'object' && selected.start && selected.end;\n\n for (const btn of buttons) {\n const time = btn.dataset.time;\n if (!time || btn.disabled) continue;\n\n if (rangeStart && !rangeComplete && hoverTime) {\n const lo = timeToMinutes(rangeStart) < timeToMinutes(hoverTime) ? rangeStart : hoverTime;\n const hi = timeToMinutes(rangeStart) < timeToMinutes(hoverTime) ? hoverTime : rangeStart;\n const t = timeToMinutes(time);\n const inRange = t > timeToMinutes(lo) && t < timeToMinutes(hi);\n const isStart = time === rangeStart;\n const isEnd = time === hoverTime;\n\n btn.classList.toggle('cal-time-slot--range-start', isStart);\n btn.classList.toggle('cal-time-slot--range-end', isEnd);\n btn.classList.toggle('cal-time-slot--in-range', inRange);\n } else if (!rangeStart) {\n btn.classList.remove('cal-time-slot--range-start', 'cal-time-slot--range-end', 'cal-time-slot--in-range');\n }\n }\n }\n\n // -- Public API --\n open() {\n if (this._popover) {\n this._popover.open();\n this._store.set({ isOpen: true });\n this.emit('cal:open');\n }\n }\n\n close() {\n if (this._popover) {\n this._popover.close();\n this._store.set({ isOpen: false });\n this.emit('cal:close');\n }\n }\n\n // -- Render --\n _renderTimepickerContent() {\n const state = this._store.getState();\n const container = document.createElement('div');\n container.classList.add('cal-timepicker');\n\n // Status banner\n if (state.statusType && state.statusMessage) {\n container.appendChild(renderStatusMessage({\n type: state.statusType,\n message: state.statusMessage,\n dismissible: state.statusDismissible,\n onDismiss: () => this.clearStatus(),\n }));\n }\n\n const header = document.createElement('div');\n header.classList.add('cal-timepicker__header');\n header.textContent = 'Select Time';\n container.appendChild(header);\n\n if (this.loading) {\n container.appendChild(renderTimeGridSkeleton({ durationLabels: this.durationLabels }));\n } else {\n const slots = this._getEffectiveSlots();\n const grid = renderTimeGrid({\n slots,\n mode: this.mode,\n format: this.format,\n selected: state.selected,\n hoverTime: state.hoverTime,\n rangeStart: state.rangeStart,\n unavailableTimes: this._unavailableTimes,\n onSelect: (t) => this._handleSelect(t),\n onHover: (t) => this._handleHover(t),\n durationLabels: this.durationLabels,\n });\n container.appendChild(grid);\n }\n\n return container;\n }\n\n _formatTriggerText() {\n const state = this._store.getState();\n if (!state.selected) return null;\n if (this.mode === 'single' && typeof state.selected === 'string') {\n return state.selected;\n }\n if (this.mode === 'multi' && Array.isArray(state.selected) && state.selected.length) {\n return `${state.selected.length} time${state.selected.length > 1 ? 's' : ''} selected`;\n }\n if (this.mode === 'range' && typeof state.selected === 'object' && state.selected.start) {\n return `${state.selected.start} – ${state.selected.end}`;\n }\n return null;\n }\n\n render() {\n if (this._rendering) return;\n this._rendering = true;\n\n const root = this.shadowRoot;\n\n // Clear non-style children\n const children = [...root.childNodes];\n for (const child of children) {\n if (child.nodeName !== 'STYLE' && !(child instanceof CSSStyleSheet)) {\n root.removeChild(child);\n }\n }\n\n this._popover?.destroy();\n this._popover = null;\n\n if (this.display === 'popover') {\n const wrapper = document.createElement('div');\n wrapper.classList.add('cal-popover-wrapper');\n\n const trigger = document.createElement('button');\n trigger.classList.add('cal-trigger');\n\n const icon = document.createElement('span');\n icon.classList.add('cal-trigger__icon');\n icon.innerHTML = clockIcon;\n trigger.appendChild(icon);\n\n const text = this._formatTriggerText();\n const label = document.createElement('span');\n if (text) {\n label.textContent = text;\n } else {\n label.textContent = this.placeholder;\n label.classList.add('cal-trigger--placeholder');\n }\n trigger.appendChild(label);\n wrapper.appendChild(trigger);\n\n const content = this._renderTimepickerContent();\n const popover = createPopover({\n trigger,\n content,\n onClose: () => {\n this._store.set({ isOpen: false });\n this.emit('cal:close');\n },\n });\n\n wrapper.appendChild(popover.panel);\n root.appendChild(wrapper);\n\n trigger.addEventListener('click', (e) => {\n e.stopPropagation();\n if (popover.isOpen) {\n this.close();\n } else {\n this.open();\n }\n });\n\n this._popover = popover;\n if (this._store.get('isOpen')) {\n popover.open();\n }\n } else {\n root.appendChild(this._renderTimepickerContent());\n }\n\n this._rendering = false;\n }\n}\n","import { CalTimepicker } from '../components/timepicker/index.js';\n\nif (!customElements.get('cal-timepicker')) {\n customElements.define('cal-timepicker', CalTimepicker);\n}\n\nexport { CalTimepicker };\n"],"names":["CalendarBase","sheets","sheet","el","name","detail","type","message","opts","autoDismiss","dismissible","selector","createStore","initial","state","listeners","key","partial","prev","changed","fn","parseTime","str","trimmed","ampmMatch","hours","minutes","period","match24","formatTime","format","mm","timeToMinutes","t","minutesToTime","n","generateSlots","startTime","endTime","intervalMinutes","slots","startMin","endMin","m","generateDurationSlots","time","nextMin","endSlotTime","parsed","parsedEnd","fromText","toText","isTimeInRange","start","end","s","e","lo","hi","tokens","reset","animations","createPopover","trigger","content","onClose","panel","isOpen","position","triggerRect","panelHeight","spaceBelow","spaceAbove","open","outsideClick","escapeKey","close","_a","host","destroy","popoverStyles","renderTimeGrid","options","mode","selected","hoverTime","rangeStart","unavailableTimes","onSelect","onHover","durationLabels","grid","slot","btn","displayTime","timeSpan","labelSpan","isUnavailable","isSlotSelected","isRangeComplete","inRange","isStart","isEnd","timeGridStyles","renderTimeGridSkeleton","columns","rows","wrapper","count","pill","loadingSkeletonStyles","icons","renderStatusMessage","onDismiss","banner","icon","text","closeBtn","statusMessageStyles","clockIcon","componentStyles","CalTimepicker","val","a","b","valueAttr","_b","oldVal","newVal","current","idx","value","buttons","rangeComplete","container","header","root","children","child","label","popover"],"mappings":"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"}