@reservi/preact 1.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":"index.js","sources":["../src/render/slots.ts","../src/components/Toolbar.tsx","../src/render/nav.ts","../src/interaction/keyboard.ts","../src/interaction/daygrid-drag.ts","../src/views/daygrid/DayGridView.tsx","../src/interaction/drag.ts","../src/views/timegrid/TimeGridView.tsx","../src/views/list/ListView.tsx","../src/views/multimonth/MultiMonthView.tsx","../src/views/timeline/TimelineView.tsx","../src/views/resource/ResourceTimelineView.tsx","../src/views/resource/ResourceTimeGridView.tsx","../src/views/resource/ResourceDayGridView.tsx","../src/components/Calendar.tsx","../src/mount.ts","../src/ical.ts"],"sourcesContent":["import type { ComponentChildren } from \"preact\";\nimport type { SlotResult } from \"../types.js\";\n\n/**\n * Resuelve un slot de contenido: si el usuario aportó una función, usa su\n * resultado; si no, usa el contenido por defecto. Unifica el contrato de los\n * render hooks para todos los frameworks (en wrappers se adapta a su idioma).\n */\nexport function renderSlot<Arg>(\n slot: ((arg: Arg) => SlotResult) | undefined,\n arg: Arg,\n fallback: ComponentChildren,\n): ComponentChildren {\n if (!slot) return fallback;\n return slot(arg) as ComponentChildren;\n}\n\n/** Une clases base con las del usuario (filtra vacíos). */\nexport function cx(...classes: (string | undefined | false)[]): string {\n return classes.filter(Boolean).join(\" \");\n}\n","import { dl, getLocaleText, type CalendarApi } from \"@reservi/core\";\nimport type { VNode } from \"preact\";\nimport { useEffect, useRef, useState } from \"preact/hooks\";\nimport type { ReserviCalendarOptions } from \"../types.js\";\nimport { cx } from \"../render/slots.js\";\n\nconst NAV_SYMBOLS = { prev: \"‹\", next: \"›\" } as const;\n/** Tokens que NO son vistas (no aparecen como pestañas). */\nconst NON_VIEW_TOKENS = new Set([\"\", \"title\", \"today\", \"prev\", \"next\"]);\n/** Vistas cuyo datepicker elige MES (resto: elige DÍA). */\nconst MONTH_VIEW_RE = /month|year/i;\n\nconst pad2 = (n: number): string => String(n).padStart(2, \"0\");\n\n/** Icono de calendario junto al título. */\nfunction CalendarIcon(): VNode {\n return (\n <svg\n data-rsv=\"title-icon\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect x=\"1\" y=\"2.5\" width=\"12\" height=\"10.5\" rx=\"1.5\" />\n <line x1=\"1\" y1=\"5.5\" x2=\"13\" y2=\"5.5\" />\n <line x1=\"4.5\" y1=\"1\" x2=\"4.5\" y2=\"3.5\" />\n <line x1=\"9.5\" y1=\"1\" x2=\"9.5\" y2=\"3.5\" />\n </svg>\n );\n}\n\ninterface ToolbarProps {\n api: CalendarApi;\n title: string;\n activeView: string;\n options: ReserviCalendarOptions;\n}\n\n/** Vistas para la fila de pestañas: prop `views` o, en su defecto, tokens de `headerToolbar`. */\nfunction resolveViews(options: ReserviCalendarOptions): string[] {\n if (options.views?.length) return options.views;\n const tb = options.headerToolbar;\n if (!tb) return [];\n return [tb.start, tb.center, tb.end]\n .filter((s): s is string => Boolean(s))\n .flatMap((s) => s.split(/\\s+/))\n .flatMap((g) => g.split(\",\"))\n .filter((t) => !NON_VIEW_TOKENS.has(t));\n}\n\n/**\n * Toolbar de dos filas:\n * - Fila 1: slot de inicio (Filtrar/Personal del anfitrión) · navegación\n * (hoy ‹ título ›) · slot de fin + botón \"Añadir\" (opcional, vía props).\n * - Fila 2: pestañas de vista.\n *\n * El título abre un datepicker para saltar de fecha. En vistas de mes/año la\n * rejilla elige MES; en el resto (semana/día/lista) elige DÍA. Se abre también\n * con Ctrl+M y se cierra con Esc o clic fuera.\n */\nexport function Toolbar({ api, title, activeView, options }: ToolbarProps): VNode {\n const text = getLocaleText(options.locale);\n const startSlot = options.slots?.toolbarStart?.();\n const endSlot = options.slots?.toolbarEnd?.();\n const views = resolveViews(options);\n const monthMode = MONTH_VIEW_RE.test(activeView);\n const firstDay = options.firstDay ?? text.firstDay;\n\n const wrapRef = useRef<HTMLDivElement>(null);\n const [open, setOpen] = useState(false);\n\n // Fecha seleccionada (para resaltar). Reactivo vía signals.\n const selected = dl.toDate(api.getDate());\n const nowRef = dl.toDate(options.now ? dl.from(options.now) : dl.now());\n\n // El mes/año mostrados en la rejilla (independientes de la navegación principal).\n const [viewYear, setViewYear] = useState(selected.getFullYear());\n const [viewMonth, setViewMonth] = useState(selected.getMonth());\n\n const monthShortFmt = new Intl.DateTimeFormat(options.locale, { month: \"short\" });\n const monthLongFmt = new Intl.DateTimeFormat(options.locale, { month: \"long\" });\n const dowFmt = new Intl.DateTimeFormat(options.locale, { weekday: \"short\" });\n const monthNames = Array.from({ length: 12 }, (_, i) => monthShortFmt.format(new Date(2020, i, 1)));\n\n const openPicker = (): void => {\n const d = dl.toDate(api.getDate());\n setViewYear(d.getFullYear());\n setViewMonth(d.getMonth());\n setOpen(true);\n };\n const shiftMonth = (delta: number): void => {\n const total = viewYear * 12 + viewMonth + delta;\n setViewYear(Math.floor(total / 12));\n setViewMonth(((total % 12) + 12) % 12);\n };\n const goto = (iso: string): void => {\n api.gotoDate(iso);\n setOpen(false);\n };\n\n // Ctrl+M abre · Esc cierra · clic fuera cierra.\n useEffect(() => {\n const onKey = (e: KeyboardEvent): void => {\n if ((e.ctrlKey || e.metaKey) && (e.key === \"m\" || e.key === \"M\")) {\n e.preventDefault();\n openPicker();\n } else if (e.key === \"Escape\") {\n setOpen(false);\n }\n };\n const onPointer = (e: MouseEvent): void => {\n if (wrapRef.current && !wrapRef.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener(\"keydown\", onKey);\n document.addEventListener(\"mousedown\", onPointer);\n return () => {\n document.removeEventListener(\"keydown\", onKey);\n document.removeEventListener(\"mousedown\", onPointer);\n };\n }, []);\n\n // Celdas (6×7) para el modo DÍA, alineadas a firstDay.\n const dayGrid = ((): { cells: Date[]; dows: string[] } => {\n if (monthMode) return { cells: [], dows: [] };\n const first = dl.from(`${viewYear}-${pad2(viewMonth + 1)}-01`);\n const offset = (dl.dayOfWeek(first) - firstDay + 7) % 7;\n const start = dl.subtract(first, { days: offset });\n const cells = Array.from({ length: 42 }, (_, i) => dl.toDate(dl.add(start, { days: i })));\n const dows = cells.slice(0, 7).map((d) => dowFmt.format(d));\n return { cells, dows };\n })();\n\n return (\n <div data-rsv=\"toolbar-wrap\" class={cx(options.classNames?.toolbar)} ref={wrapRef}>\n <div data-rsv=\"toolbar\">\n {/* Inicio: slot libre del anfitrión (Filtrar / Personal …) */}\n <div data-rsv=\"toolbar-section\" data-rsv-area=\"start\">\n {startSlot}\n </div>\n\n {/* Navegación: hoy · ‹ título › */}\n <div data-rsv=\"toolbar-section\" data-rsv-area=\"nav\">\n <button\n type=\"button\"\n data-rsv=\"button\"\n title={text.today}\n aria-label={text.today}\n onClick={() => api.today()}\n >\n {text.today}\n </button>\n <button\n type=\"button\"\n data-rsv=\"button\"\n data-rsv-nav=\"prev\"\n title={text.prev}\n aria-label={text.prev}\n onClick={() => api.prev()}\n >\n {NAV_SYMBOLS.prev}\n </button>\n\n {/* Título = disparador del datepicker */}\n <div data-rsv=\"datepicker-anchor\">\n <button\n type=\"button\"\n data-rsv=\"title\"\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n title={`${title} · Ctrl+M`}\n onClick={() => (open ? setOpen(false) : openPicker())}\n >\n <CalendarIcon />\n {title}\n </button>\n\n {open && (\n <div data-rsv=\"datepicker\" data-rsv-mode={monthMode ? \"month\" : \"day\"} role=\"dialog\" aria-label={title}>\n <div data-rsv=\"dp-head\">\n <button\n type=\"button\"\n data-rsv=\"dp-nav\"\n aria-label={text.prev}\n onClick={() => (monthMode ? setViewYear((y) => y - 1) : shiftMonth(-1))}\n >\n {NAV_SYMBOLS.prev}\n </button>\n <span data-rsv=\"dp-label\">\n {monthMode\n ? viewYear\n : `${monthLongFmt.format(new Date(viewYear, viewMonth, 1))} ${viewYear}`}\n </span>\n <button\n type=\"button\"\n data-rsv=\"dp-nav\"\n aria-label={text.next}\n onClick={() => (monthMode ? setViewYear((y) => y + 1) : shiftMonth(1))}\n >\n {NAV_SYMBOLS.next}\n </button>\n </div>\n\n {monthMode ? (\n <div data-rsv=\"dp-grid\">\n {monthNames.map((label, i) => (\n <button\n type=\"button\"\n data-rsv=\"dp-month\"\n key={label}\n data-active={String(\n viewYear === selected.getFullYear() && i === selected.getMonth(),\n )}\n data-today={String(viewYear === nowRef.getFullYear() && i === nowRef.getMonth())}\n onClick={() => goto(`${viewYear}-${pad2(i + 1)}-01`)}\n >\n {label}\n </button>\n ))}\n </div>\n ) : (\n <div data-rsv=\"dp-days\">\n {dayGrid.dows.map((d, i) => (\n <div data-rsv=\"dp-dow\" key={`dow-${i}`}>\n {d}\n </div>\n ))}\n {dayGrid.cells.map((d) => {\n const iso = `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}`;\n return (\n <button\n type=\"button\"\n data-rsv=\"dp-day\"\n key={iso}\n data-other={String(d.getMonth() !== viewMonth)}\n data-active={String(\n d.getFullYear() === selected.getFullYear() &&\n d.getMonth() === selected.getMonth() &&\n d.getDate() === selected.getDate(),\n )}\n data-today={String(\n d.getFullYear() === nowRef.getFullYear() &&\n d.getMonth() === nowRef.getMonth() &&\n d.getDate() === nowRef.getDate(),\n )}\n onClick={() => goto(iso)}\n >\n {d.getDate()}\n </button>\n );\n })}\n </div>\n )}\n </div>\n )}\n </div>\n\n <button\n type=\"button\"\n data-rsv=\"button\"\n data-rsv-nav=\"next\"\n title={text.next}\n aria-label={text.next}\n onClick={() => api.next()}\n >\n {NAV_SYMBOLS.next}\n </button>\n </div>\n\n {/* Fin: slot libre + botón \"Añadir\" (solo si se pasa onAddClick) */}\n <div data-rsv=\"toolbar-section\" data-rsv-area=\"end\">\n {endSlot}\n {options.onAddClick && (\n <button\n type=\"button\"\n data-rsv=\"button\"\n data-rsv-variant=\"primary\"\n onClick={options.onAddClick}\n >\n <span data-rsv=\"add-icon\" aria-hidden=\"true\">\n +\n </span>\n {options.addButtonText}\n </button>\n )}\n </div>\n </div>\n\n {/* Fila 2: pestañas de vista */}\n {views.length > 0 && (\n <div data-rsv=\"toolbar-views\" role=\"tablist\">\n {views.map((v) => (\n <button\n type=\"button\"\n data-rsv=\"view-tab\"\n key={v}\n role=\"tab\"\n aria-selected={v === activeView}\n data-active={String(v === activeView)}\n onClick={() => api.changeView(v)}\n >\n {text.views[v] ?? v}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n","import { dl, type CalendarApi, type RsvDate } from \"@reservi/core\";\n\n/**\n * Navegación de \"nav links\": dispara `navLinkDay` y, por defecto, va a la vista\n * de día (timeGridDay o dayGridDay, la que esté registrada) en esa fecha.\n */\nexport function navLinkToDay(api: CalendarApi, date: RsvDate): void {\n api.trigger(\"navLinkDay\", { date });\n const target = api.hasView(\"timeGridDay\")\n ? \"timeGridDay\"\n : api.hasView(\"dayGridDay\")\n ? \"dayGridDay\"\n : null;\n if (target) {\n api.gotoDate(dl.toISOString(date));\n api.changeView(target);\n }\n}\n","/**\n * Movimiento de eventos por teclado (accesibilidad WCAG). No necesita geometría\n * de píxeles: mueve por incrementos fijos (días o snap de minutos), por lo que\n * es plenamente testeable. Usa moveEvent (validado) del núcleo.\n */\nimport { computeDrop, dl, timeStringToMinutes, type CalendarApi, type EventDef } from \"@reservi/core\";\n\nexport type GridKind = \"dayGrid\" | \"timeGrid\";\n\nconst DAY = 1440;\n\ninterface KeydownOptions {\n api: CalendarApi;\n event: EventDef;\n kind: GridKind;\n snap?: string | undefined;\n}\n\nexport function handleEventKeydown(e: KeyboardEvent, opts: KeydownOptions): void {\n const { api, event, kind } = opts;\n const snapMin = timeStringToMinutes(opts.snap ?? \"00:30\");\n\n let deltaMin = 0;\n switch (e.key) {\n case \"ArrowLeft\":\n deltaMin = -DAY;\n break;\n case \"ArrowRight\":\n deltaMin = DAY;\n break;\n case \"ArrowUp\":\n deltaMin = kind === \"timeGrid\" ? -snapMin : -DAY * 7;\n break;\n case \"ArrowDown\":\n deltaMin = kind === \"timeGrid\" ? snapMin : DAY * 7;\n break;\n case \"Enter\":\n case \" \":\n e.preventDefault();\n api.trigger(\"eventClick\", { event });\n return;\n default:\n return; // tecla no gestionada\n }\n\n e.preventDefault();\n const next = computeDrop(event.start, event.end, deltaMin, dl);\n if (api.moveEvent(event.id, next.start, next.end)) {\n const updated = api.getEventById(event.id);\n if (updated) api.trigger(\"eventDrop\", { event: updated });\n }\n}\n","/**\n * Drag por puntero para dayGrid/mes: mover un evento entre días y seleccionar\n * un rango de días arrastrando. El cálculo de fechas usa el núcleo (computeDrop\n * + dl); aquí solo se hace hit-testing del DOM para saber sobre qué día se está.\n */\nimport { computeDrop, dl, type CalendarApi, type EventDef } from \"@reservi/core\";\n\nconst DAY = 1440;\nconst THRESHOLD = 4;\n\n/** Fecha (ISO) de la celda de día bajo el punto, o null. */\nfunction dateAtPoint(x: number, y: number): string | null {\n const el = document.elementFromPoint(x, y) as HTMLElement | null;\n return el?.closest<HTMLElement>('[data-rsv=\"day\"]')?.dataset.date ?? null;\n}\n\ninterface EventDragOptions {\n api: CalendarApi;\n event: EventDef;\n /** Fecha (ISO) de la celda donde empezó el arrastre. */\n sourceDate: string;\n /** Se llama si hubo arrastre real (para suprimir el click posterior). */\n onMoved?: () => void;\n}\n\n/** Arrastra un evento entre días (dayGrid/mes). */\nexport function startDayGridEventDrag(ev: PointerEvent, opts: EventDragOptions): void {\n ev.stopPropagation();\n const { api, event, sourceDate } = opts;\n const startX = ev.clientX;\n const startY = ev.clientY;\n let dragging = false;\n\n const onMove = (e: PointerEvent): void => {\n if (!dragging && Math.hypot(e.clientX - startX, e.clientY - startY) > THRESHOLD) {\n dragging = true;\n document.body.style.cursor = \"grabbing\";\n }\n };\n const onUp = (e: PointerEvent): void => {\n document.removeEventListener(\"pointermove\", onMove);\n document.removeEventListener(\"pointerup\", onUp);\n document.body.style.cursor = \"\";\n if (!dragging) return;\n opts.onMoved?.();\n const target = dateAtPoint(e.clientX, e.clientY);\n if (!target) return;\n const deltaDays = dl.diff(dl.from(sourceDate), dl.from(target), \"day\");\n if (deltaDays === 0) return;\n const next = computeDrop(event.start, event.end, deltaDays * DAY, dl);\n if (api.moveEvent(event.id, next.start, next.end)) {\n const updated = api.getEventById(event.id);\n if (updated) api.trigger(\"eventDrop\", { event: updated });\n }\n };\n document.addEventListener(\"pointermove\", onMove);\n document.addEventListener(\"pointerup\", onUp);\n}\n\n/**\n * Selecciona un rango de días arrastrando. Solo actúa si hay arrastre real\n * (varios días); un click simple lo gestiona el `onClick` de la celda. Llama a\n * `onRangeSelect` cuando selecciona, para suprimir el click posterior.\n */\nexport function startDayRangeSelect(\n ev: PointerEvent,\n opts: { api: CalendarApi; startDate: string; onRangeSelect?: () => void },\n): void {\n const target = ev.target as HTMLElement;\n // No iniciar selección si se pulsa sobre un evento, el \"+N more\" o un nav-link.\n if (target.closest('[data-rsv=\"event\"], [data-rsv=\"more-anchor\"], [data-nav-link=\"true\"]')) {\n return;\n }\n const { api } = opts;\n let endStr = opts.startDate;\n let moved = false;\n\n const onMove = (e: PointerEvent): void => {\n const d = dateAtPoint(e.clientX, e.clientY);\n if (d && d !== opts.startDate) moved = true;\n if (d) endStr = d;\n };\n const onUp = (): void => {\n document.removeEventListener(\"pointermove\", onMove);\n document.removeEventListener(\"pointerup\", onUp);\n if (!moved) return; // click simple → lo gestiona onClick\n opts.onRangeSelect?.();\n const a = dl.from(opts.startDate);\n const b = dl.from(endStr);\n const [lo, hi] = dl.isBefore(a, b) ? [a, b] : [b, a];\n // Fin exclusivo (+1 día), como FullCalendar.\n api.select(dl.toISOString(lo), dl.toISOString(dl.add(hi, { days: 1 })));\n };\n document.addEventListener(\"pointermove\", onMove);\n document.addEventListener(\"pointerup\", onUp);\n}\n","import {\n dl,\n getLocaleText,\n type CalendarApi,\n type DayGridCell,\n type DayGridModel,\n type EventDef,\n} from \"@reservi/core\";\nimport type { VNode } from \"preact\";\nimport { useEffect, useRef, useState } from \"preact/hooks\";\nimport type { ReserviCalendarOptions } from \"../../types.js\";\nimport { renderSlot, cx } from \"../../render/slots.js\";\nimport { navLinkToDay } from \"../../render/nav.js\";\nimport { handleEventKeydown } from \"../../interaction/keyboard.js\";\nimport { startDayGridEventDrag, startDayRangeSelect } from \"../../interaction/daygrid-drag.js\";\n\ninterface DayGridViewProps {\n api: CalendarApi;\n model: DayGridModel;\n options: ReserviCalendarOptions;\n}\n\n/** Vista de cuadrícula por días (mes/semana/día/año). */\nexport function DayGridView({ api, model, options }: DayGridViewProps): VNode {\n const locale = options.locale ?? \"en\";\n const dowFmt = new Intl.DateTimeFormat(locale, { weekday: \"short\" });\n const headerDays = model.weeks[0]?.days ?? [];\n const showWeekNums = options.weekNumbers === true;\n\n return (\n <div\n data-rsv=\"daygrid\"\n data-weeknumbers={String(showWeekNums)}\n style={`--rsv-cols:${model.columnCount}`}\n >\n <div data-rsv=\"daygrid-header\" role=\"row\">\n {showWeekNums && <div data-rsv=\"daygrid-weeknum-header\" role=\"columnheader\" />}\n {headerDays.map((cell) => {\n const date = dl.toDate(cell.date);\n const text = dowFmt.format(date);\n return (\n <div data-rsv=\"daygrid-dow\" role=\"columnheader\" key={cell.dayOfWeek}>\n {renderSlot(options.slots?.dayHeaderContent, { date, text }, text)}\n </div>\n );\n })}\n </div>\n\n {model.weeks.map((week, wi) => (\n <div data-rsv=\"daygrid-week\" role=\"row\" key={wi}>\n {showWeekNums && (\n <div data-rsv=\"daygrid-weeknum\" role=\"rowheader\">\n {week.weekNumber}\n </div>\n )}\n {week.days.map((cell) => (\n <DayCell api={api} cell={cell} options={options} key={dl.toISOString(cell.date)} />\n ))}\n </div>\n ))}\n </div>\n );\n}\n\nfunction DayCell({\n api,\n cell,\n options,\n}: {\n api: CalendarApi;\n cell: DayGridCell;\n options: ReserviCalendarOptions;\n}): VNode {\n const date = dl.toDate(cell.date);\n const dayNumber = dl.dayOfMonth(cell.date);\n const defaultNumber = options.navLinks ? (\n <a\n data-rsv=\"day-number\"\n data-nav-link=\"true\"\n role=\"link\"\n tabIndex={0}\n onClick={(e) => {\n e.stopPropagation();\n navLinkToDay(api, cell.date);\n }}\n >\n {dayNumber}\n </a>\n ) : (\n <span data-rsv=\"day-number\">{dayNumber}</span>\n );\n const numberNode = renderSlot(\n options.slots?.dayCellContent,\n { date, dayNumber, isToday: cell.isToday, isOther: cell.isOther },\n defaultNumber,\n );\n\n const [moreOpen, setMoreOpen] = useState(false);\n\n const dateStr = dl.toISOString(cell.date);\n const rangeSelectedRef = useRef(false);\n\n const onDayClick = () => {\n // Suprime el click que sigue a una selección por arrastre.\n if (rangeSelectedRef.current) {\n rangeSelectedRef.current = false;\n return;\n }\n api.trigger(\"dateClick\", { date: cell.date });\n if (options.selectable) {\n api.select(dateStr, dl.toISOString(dl.add(cell.date, { days: 1 })));\n }\n };\n\n const openMore = (e: Event) => {\n e.stopPropagation();\n setMoreOpen(true);\n api.trigger(\"moreLinkClick\", {\n date: cell.date,\n allEvents: [...cell.events, ...cell.hiddenEvents],\n hiddenEvents: cell.hiddenEvents,\n });\n };\n\n return (\n <div\n data-rsv=\"day\"\n role=\"gridcell\"\n data-date={dateStr}\n data-today={String(cell.isToday)}\n data-other={String(cell.isOther)}\n data-weekend={String(cell.isWeekend)}\n data-business={String(cell.isBusiness)}\n data-selected={String(cell.isSelected)}\n onClick={onDayClick}\n onPointerDown={\n options.selectable\n ? (e) =>\n startDayRangeSelect(e, {\n api,\n startDate: dateStr,\n onRangeSelect: () => {\n rangeSelectedRef.current = true;\n },\n })\n : undefined\n }\n >\n {numberNode}\n {cell.events\n .filter((event) => event.display !== \"none\")\n .map((event) => (\n <EventChip api={api} event={event} options={options} sourceDate={dateStr} key={event.id} />\n ))}\n {cell.moreCount > 0 && (\n <div data-rsv=\"more-anchor\">\n <button type=\"button\" data-rsv=\"more-link\" onClick={openMore}>\n {getLocaleText(options.locale).more(cell.moreCount)}\n </button>\n {moreOpen && (\n <DayMorePopover\n api={api}\n cell={cell}\n options={options}\n onClose={() => setMoreOpen(false)}\n />\n )}\n </div>\n )}\n </div>\n );\n}\n\n/** Popover de \"+N more\": lista todos los eventos del día (visibles + ocultos). */\nfunction DayMorePopover({\n api,\n cell,\n options,\n onClose,\n}: {\n api: CalendarApi;\n cell: DayGridCell;\n options: ReserviCalendarOptions;\n onClose: () => void;\n}): VNode {\n const ref = useRef<HTMLDivElement>(null);\n const dayFmt = new Intl.DateTimeFormat(options.locale ?? \"en\", {\n weekday: \"long\",\n day: \"numeric\",\n month: \"long\",\n });\n const allEvents = [...cell.events, ...cell.hiddenEvents].filter((e) => e.display !== \"none\");\n\n useEffect(() => {\n const onPointer = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) onClose();\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"mousedown\", onPointer);\n document.addEventListener(\"keydown\", onKey);\n return () => {\n document.removeEventListener(\"mousedown\", onPointer);\n document.removeEventListener(\"keydown\", onKey);\n };\n }, [onClose]);\n\n return (\n <div data-rsv=\"more-popover\" role=\"dialog\" ref={ref} onClick={(e) => e.stopPropagation()}>\n <div data-rsv=\"more-popover-header\">\n <span data-rsv=\"more-popover-title\">{dayFmt.format(dl.toDate(cell.date))}</span>\n <button type=\"button\" data-rsv=\"more-popover-close\" aria-label=\"✕\" onClick={onClose}>\n ✕\n </button>\n </div>\n <div data-rsv=\"more-popover-body\">\n {allEvents.map((event) => (\n <EventChip\n api={api}\n event={event}\n options={options}\n sourceDate={dl.toISOString(cell.date)}\n key={event.id}\n />\n ))}\n </div>\n </div>\n );\n}\n\nfunction EventChip({\n api,\n event,\n options,\n sourceDate,\n}: {\n api: CalendarApi;\n event: EventDef;\n options: ReserviCalendarOptions;\n sourceDate: string;\n}): VNode {\n const editable = options.editable === true && event.editable !== false;\n const draggedRef = useRef(false);\n const timeText = event.allDay ? \"\" : dl.format(event.start, \"HH:mm\");\n const content = renderSlot(\n options.slots?.eventContent,\n { event, isAllDay: event.allDay, timeText },\n <span data-rsv=\"event-title\">\n {timeText ? `${timeText} ` : \"\"}\n {event.title}\n </span>,\n );\n\n return (\n <div\n data-rsv=\"event\"\n role=\"button\"\n tabIndex={0}\n class={cx(...event.classNames)}\n data-all-day={String(event.allDay)}\n data-display={event.display}\n data-event-id={event.id}\n data-editable={String(editable)}\n style={`--rsv-event-bg:${event.backgroundColor};--rsv-event-fg:${event.textColor}`}\n onClick={(e) => {\n e.stopPropagation();\n // Suprime el click que sigue a un arrastre.\n if (draggedRef.current) {\n draggedRef.current = false;\n return;\n }\n api.trigger(\"eventClick\", { event });\n if (event.url) window.open(event.url, \"_self\");\n }}\n onPointerDown={\n editable\n ? (e) =>\n startDayGridEventDrag(e, {\n api,\n event,\n sourceDate,\n onMoved: () => {\n draggedRef.current = true;\n },\n })\n : undefined\n }\n onKeyDown={\n editable ? (e) => handleEventKeydown(e, { api, event, kind: \"dayGrid\" }) : undefined\n }\n >\n {content}\n </div>\n );\n}\n","/**\n * Controlador de drag/resize por puntero para timeGrid. Usa la geometría pura\n * del núcleo (testeada en @reservi/core) y mide la columna del DOM para obtener\n * px/min. El cálculo de fechas NO vive aquí (vive en core/interaction).\n */\nimport {\n computeDrop,\n computeResize,\n dl,\n pxToSnappedMinutes,\n timeStringToMinutes,\n type CalendarApi,\n type EventDef,\n type ResizeEdge,\n type RsvDate,\n type TimeGridModel,\n} from \"@reservi/core\";\n\ninterface DragOptions {\n api: CalendarApi;\n event: EventDef;\n model: TimeGridModel;\n columnEl: HTMLElement;\n snap?: string | undefined;\n /** Si se indica, redimensiona por ese borde; si no, mueve el evento. */\n edge?: ResizeEdge | undefined;\n}\n\nexport function startEventDrag(ev: PointerEvent, options: DragOptions): void {\n ev.preventDefault();\n ev.stopPropagation();\n const { api, event, model, columnEl, snap = \"00:15\", edge } = options;\n\n const rect = columnEl.getBoundingClientRect();\n const totalMinutes = model.maxMinutes - model.minMinutes;\n const ppm = rect.height === 0 ? 0 : rect.height / totalMinutes;\n const startY = ev.clientY;\n\n const onUp = (e: PointerEvent) => {\n document.removeEventListener(\"pointerup\", onUp);\n const deltaMin = pxToSnappedMinutes(e.clientY - startY, ppm, snap);\n if (deltaMin === 0) return;\n\n const next = edge\n ? computeResize(event.start, event.end, edge, deltaMin, dl)\n : computeDrop(event.start, event.end, deltaMin, dl);\n\n // moveEvent valida overlap/constraint/allow; si no es válido, se revierte.\n if (api.moveEvent(event.id, next.start, next.end)) {\n const updated = api.getEventById(event.id);\n if (updated) api.trigger(edge ? \"eventResize\" : \"eventDrop\", { event: updated });\n }\n };\n\n document.addEventListener(\"pointerup\", onUp);\n}\n\ninterface RangeSelectOptions {\n api: CalendarApi;\n date: RsvDate;\n model: TimeGridModel;\n columnEl: HTMLElement;\n snap?: string | undefined;\n}\n\n/** Selección de rango horario por arrastre en una columna de timeGrid. */\nexport function startTimeRangeSelect(ev: PointerEvent, options: RangeSelectOptions): void {\n // No iniciar si se pulsa sobre un evento existente.\n if ((ev.target as HTMLElement).closest('[data-rsv=\"event\"]')) return;\n const { api, date, model, columnEl, snap = \"00:15\" } = options;\n\n const rect = columnEl.getBoundingClientRect();\n const total = model.maxMinutes - model.minMinutes;\n const ppm = rect.height === 0 ? 0 : rect.height / total;\n const snapMin = timeStringToMinutes(snap) || 15;\n\n const yToMin = (clientY: number): number => {\n const raw = model.minMinutes + (ppm === 0 ? 0 : (clientY - rect.top) / ppm);\n const clamped = Math.max(model.minMinutes, Math.min(model.maxMinutes, raw));\n return Math.round(clamped / snapMin) * snapMin;\n };\n\n const startMin = yToMin(ev.clientY);\n let endMin = startMin;\n let moved = false;\n\n const onMove = (e: PointerEvent): void => {\n const m = yToMin(e.clientY);\n if (m !== startMin) moved = true;\n endMin = m;\n };\n const onUp = (): void => {\n document.removeEventListener(\"pointermove\", onMove);\n document.removeEventListener(\"pointerup\", onUp);\n if (!moved) return; // un click simple lo gestiona dateClick\n const lo = Math.min(startMin, endMin);\n const hi = Math.max(startMin, endMin);\n const dayStart = dl.startOf(date, \"day\");\n api.select(\n dl.toISOString(dl.add(dayStart, { minutes: lo })),\n dl.toISOString(dl.add(dayStart, { minutes: hi })),\n );\n };\n document.addEventListener(\"pointermove\", onMove);\n document.addEventListener(\"pointerup\", onUp);\n}\n","import {\n dl,\n getLocaleText,\n type CalendarApi,\n type TimeGridModel,\n type TimeGridSeg,\n} from \"@reservi/core\";\nimport type { VNode } from \"preact\";\nimport type { ReserviCalendarOptions } from \"../../types.js\";\nimport { renderSlot, cx } from \"../../render/slots.js\";\nimport { navLinkToDay } from \"../../render/nav.js\";\nimport { startEventDrag, startTimeRangeSelect } from \"../../interaction/drag.js\";\nimport { handleEventKeydown } from \"../../interaction/keyboard.js\";\n\ninterface TimeGridViewProps {\n api: CalendarApi;\n model: TimeGridModel;\n options: ReserviCalendarOptions;\n}\n\n/** Vista con eje temporal vertical (semana/día). */\nexport function TimeGridView({ api, model, options }: TimeGridViewProps): VNode {\n const locale = options.locale ?? \"en\";\n const dowFmt = new Intl.DateTimeFormat(locale, { weekday: \"short\", day: \"numeric\" });\n const showAllDay = options.allDaySlot !== false;\n const bodyHeight = `calc(var(--spacing-rsv-slot, 2.5rem) * ${model.slots.length})`;\n\n return (\n <div data-rsv=\"timegrid\" style={`--rsv-tg-days:${model.days.length}`}>\n {/* Cabecera de días */}\n <div data-rsv=\"tg-header\" role=\"row\">\n <div data-rsv=\"tg-axis-corner\" />\n {model.days.map((d) => (\n <div\n data-rsv=\"tg-col-header\"\n role=\"columnheader\"\n data-today={String(d.isToday)}\n data-nav-link={options.navLinks ? \"true\" : undefined}\n key={dl.toISOString(d.date)}\n onClick={options.navLinks ? () => navLinkToDay(api, d.date) : undefined}\n >\n {dowFmt.format(dl.toDate(d.date))}\n </div>\n ))}\n </div>\n\n {/* Franja de todo el día */}\n {showAllDay && (\n <div data-rsv=\"tg-allday\" role=\"row\">\n <div data-rsv=\"tg-axis-label\">{getLocaleText(options.locale).allDay}</div>\n {model.days.map((d) => (\n <div data-rsv=\"tg-allday-cell\" key={dl.toISOString(d.date)}>\n {d.allDayEvents\n .filter((event) => event.display !== \"none\")\n .map((event) => (\n <div\n data-rsv=\"event\"\n data-all-day=\"true\"\n class={cx(...event.classNames)}\n data-display={event.display}\n key={event.id}\n style={`--rsv-event-bg:${event.backgroundColor}`}\n onClick={() => {\n api.trigger(\"eventClick\", { event });\n if (event.url) window.open(event.url, \"_self\");\n }}\n >\n {event.title}\n </div>\n ))}\n </div>\n ))}\n </div>\n )}\n\n {/* Cuerpo: eje + columnas de día */}\n <div data-rsv=\"tg-body\">\n <div data-rsv=\"tg-axis\" style={`height:${bodyHeight}`}>\n {model.slots.map((slot) => (\n <div data-rsv=\"tg-slot\" data-major={String(slot.isMajor)} key={slot.offsetMin}>\n <span data-rsv=\"tg-slot-label\">\n {renderSlot(\n options.slots?.slotLabelContent,\n { text: slot.label, minutes: slot.offsetMin, isMajor: slot.isMajor },\n slot.label,\n )}\n </span>\n </div>\n ))}\n </div>\n\n {model.days.map((d, dayIndex) => (\n <div\n data-rsv=\"tg-col\"\n data-today={String(d.isToday)}\n style={`height:${bodyHeight}`}\n key={dl.toISOString(d.date)}\n onClick={() => api.trigger(\"dateClick\", { date: d.date })}\n onPointerDown={\n options.selectable\n ? (e) =>\n startTimeRangeSelect(e, {\n api,\n date: d.date,\n model,\n columnEl: e.currentTarget as HTMLElement,\n snap: options.snapDuration ?? options.slotDuration,\n })\n : undefined\n }\n >\n {options.businessHours && !d.businessPct && (\n <div data-rsv=\"tg-nonbusiness\" style=\"top:0;height:100%\" />\n )}\n {d.businessPct && (\n <>\n <div data-rsv=\"tg-nonbusiness\" style={`top:0;height:${d.businessPct.topPct}%`} />\n <div\n data-rsv=\"tg-nonbusiness\"\n style={`top:${d.businessPct.bottomPct}%;height:${100 - d.businessPct.bottomPct}%`}\n />\n </>\n )}\n {d.timedSegs\n .filter((seg) => seg.event.display !== \"none\")\n .map((seg) => (\n <TimedEvent api={api} seg={seg} model={model} options={options} key={seg.event.id} />\n ))}\n {model.nowIndicator?.dayIndex === dayIndex && (\n <div data-rsv=\"now-indicator\" style={`top:${model.nowIndicator.topPct}%`} />\n )}\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nfunction TimedEvent({\n api,\n seg,\n model,\n options,\n}: {\n api: CalendarApi;\n seg: TimeGridSeg;\n model: TimeGridModel;\n options: ReserviCalendarOptions;\n}): VNode {\n const { event } = seg;\n const editable = options.editable === true && event.editable !== false;\n const widthPct = 100 / seg.colCount;\n const timeText = dl.format(event.start, \"HH:mm\");\n const content = renderSlot(\n options.slots?.eventContent,\n { event, isAllDay: false, timeText },\n <span data-rsv=\"event-title\">\n {timeText} {event.title}\n </span>,\n );\n\n const getColumn = (el: HTMLElement): HTMLElement =>\n (el.closest('[data-rsv=\"tg-col\"]') as HTMLElement | null) ?? el;\n\n return (\n <div\n data-rsv=\"event\"\n data-all-day=\"false\"\n data-display={event.display}\n data-event-id={event.id}\n class={cx(...event.classNames)}\n role=\"button\"\n tabIndex={0}\n style={\n `position:absolute;` +\n `top:${seg.topPct}%;height:${seg.heightPct}%;` +\n `left:${seg.col * widthPct}%;width:${widthPct}%;` +\n `--rsv-event-bg:${event.backgroundColor};--rsv-event-fg:${event.textColor}`\n }\n onClick={(e) => {\n e.stopPropagation();\n api.trigger(\"eventClick\", { event });\n if (event.url) window.open(event.url, \"_self\");\n }}\n onKeyDown={\n editable\n ? (e) =>\n handleEventKeydown(e, {\n api,\n event,\n kind: \"timeGrid\",\n snap: options.snapDuration ?? options.slotDuration,\n })\n : undefined\n }\n onPointerDown={\n editable\n ? (e) =>\n startEventDrag(e, {\n api,\n event,\n model,\n columnEl: getColumn(e.currentTarget as HTMLElement),\n snap: options.snapDuration,\n })\n : undefined\n }\n >\n {editable && (\n <span\n data-rsv=\"resize-handle\"\n data-edge=\"start\"\n onPointerDown={(e) =>\n startEventDrag(e, {\n api,\n event,\n model,\n columnEl: getColumn(e.currentTarget as HTMLElement),\n snap: options.snapDuration,\n edge: \"start\",\n })\n }\n />\n )}\n {content}\n {editable && (\n <span\n data-rsv=\"resize-handle\"\n data-edge=\"end\"\n onPointerDown={(e) =>\n startEventDrag(e, {\n api,\n event,\n model,\n columnEl: getColumn(e.currentTarget as HTMLElement),\n snap: options.snapDuration,\n edge: \"end\",\n })\n }\n />\n )}\n </div>\n );\n}\n","import { dl, getLocaleText, type CalendarApi, type ListModel } from \"@reservi/core\";\nimport type { VNode } from \"preact\";\nimport type { ReserviCalendarOptions } from \"../../types.js\";\nimport { renderSlot, cx } from \"../../render/slots.js\";\n\ninterface ListViewProps {\n api: CalendarApi;\n model: ListModel;\n options: ReserviCalendarOptions;\n}\n\n/** Vista de agenda en lista (listDay/Week/Month/Year). */\nexport function ListView({ api, model, options }: ListViewProps): VNode {\n const locale = options.locale ?? \"en\";\n const text = getLocaleText(options.locale);\n const dayFmt = new Intl.DateTimeFormat(locale, {\n weekday: \"long\",\n day: \"numeric\",\n month: \"long\",\n });\n\n if (model.isEmpty) {\n return (\n <div data-rsv=\"list\">\n <div data-rsv=\"list-empty\">{text.noEvents}</div>\n </div>\n );\n }\n\n return (\n <div data-rsv=\"list\" role=\"list\">\n {model.days.map((day) => (\n <div data-rsv=\"list-day\" data-today={String(day.isToday)} key={dl.toISOString(day.date)}>\n <div data-rsv=\"list-day-header\" role=\"heading\" aria-level={3}>\n {dayFmt.format(dl.toDate(day.date))}\n </div>\n {day.events\n .filter((event) => event.display !== \"none\")\n .map((event) => {\n const timeText = event.allDay ? text.allDay : dl.format(event.start, \"HH:mm\");\n return (\n <div\n data-rsv=\"list-item\"\n role=\"listitem\"\n tabIndex={0}\n key={event.id}\n class={cx(...event.classNames)}\n data-display={event.display}\n onClick={() => {\n api.trigger(\"eventClick\", { event });\n if (event.url) window.open(event.url, \"_self\");\n }}\n >\n <span data-rsv=\"list-item-time\">{timeText}</span>\n <span\n data-rsv=\"list-item-dot\"\n style={`--rsv-event-bg:${event.backgroundColor}`}\n />\n <span data-rsv=\"list-item-title\">\n {renderSlot(\n options.slots?.eventContent,\n { event, isAllDay: event.allDay, timeText },\n event.title,\n )}\n </span>\n </div>\n );\n })}\n </div>\n ))}\n </div>\n );\n}\n","import { dl, type CalendarApi, type MultiMonthModel } from \"@reservi/core\";\nimport type { VNode } from \"preact\";\nimport type { ReserviCalendarOptions } from \"../../types.js\";\nimport { DayGridView } from \"../daygrid/DayGridView.js\";\n\ninterface MultiMonthViewProps {\n api: CalendarApi;\n model: MultiMonthModel;\n options: ReserviCalendarOptions;\n}\n\n/** Vista de varios meses (año): rejilla responsive de cuadrículas mensuales. */\nexport function MultiMonthView({ api, model, options }: MultiMonthViewProps): VNode {\n const locale = options.locale ?? \"en\";\n const monthFmt = new Intl.DateTimeFormat(locale, { month: \"long\" });\n\n return (\n <div data-rsv=\"multimonth\">\n {model.months.map((month) => (\n <section data-rsv=\"mm-month\" key={dl.toISOString(month.date)}>\n <header data-rsv=\"mm-title\">{monthFmt.format(dl.toDate(month.date))}</header>\n <DayGridView api={api} model={month.dayGrid} options={options} />\n </section>\n ))}\n </div>\n );\n}\n","import { type CalendarApi, type TimelineModel, type TimelineSeg } from \"@reservi/core\";\nimport type { VNode } from \"preact\";\nimport type { ReserviCalendarOptions } from \"../../types.js\";\nimport { renderSlot } from \"../../render/slots.js\";\n\nconst LANE_REM = 1.6;\n\ninterface TimelineViewProps {\n api: CalendarApi;\n model: TimelineModel;\n options: ReserviCalendarOptions;\n}\n\n/** Vista timeline: eje temporal horizontal con eventos apilados en carriles. */\nexport function TimelineView({ api, model, options }: TimelineViewProps): VNode {\n return (\n <div data-rsv=\"timeline\">\n <div data-rsv=\"tl-axis\" role=\"row\">\n {model.slots.map((slot) => (\n <div data-rsv=\"tl-slot\" style={`left:${slot.leftPct}%`} key={slot.leftPct}>\n {slot.label}\n </div>\n ))}\n </div>\n <div data-rsv=\"tl-body\" style={`height:${model.laneCount * LANE_REM + 0.5}rem`}>\n {model.segs.map((seg) => (\n <TimelineEvent api={api} seg={seg} options={options} key={seg.event.id} />\n ))}\n </div>\n </div>\n );\n}\n\nexport function TimelineEvent({\n api,\n seg,\n options,\n}: {\n api: CalendarApi;\n seg: TimelineSeg;\n options: ReserviCalendarOptions;\n}): VNode {\n const { event } = seg;\n return (\n <div\n data-rsv=\"event\"\n data-event-id={event.id}\n role=\"button\"\n tabIndex={0}\n style={\n `position:absolute;left:${seg.leftPct}%;width:${seg.widthPct}%;` +\n `top:${seg.lane * LANE_REM}rem;height:${LANE_REM - 0.2}rem;` +\n `--rsv-event-bg:${event.backgroundColor};--rsv-event-fg:${event.textColor}`\n }\n onClick={() => api.trigger(\"eventClick\", { event })}\n >\n {renderSlot(options.slots?.eventContent, { event, isAllDay: event.allDay, timeText: \"\" }, event.title)}\n </div>\n );\n}\n","import { type CalendarApi, type ResourceTimelineModel } from \"@reservi/core\";\nimport type { VNode } from \"preact\";\nimport type { ReserviCalendarOptions } from \"../../types.js\";\nimport { TimelineEvent } from \"../timeline/TimelineView.js\";\n\nconst LANE_REM = 1.6;\n\ninterface ResourceTimelineViewProps {\n api: CalendarApi;\n model: ResourceTimelineModel;\n options: ReserviCalendarOptions;\n}\n\n/** Vista resource-timeline (Scheduler): filas de recursos × eje temporal. */\nexport function ResourceTimelineView({ api, model, options }: ResourceTimelineViewProps): VNode {\n return (\n <div data-rsv=\"resource-timeline\">\n {/* Cabecera: área de recursos + eje temporal */}\n <div data-rsv=\"rt-header\" role=\"row\">\n <div data-rsv=\"resource-area-header\">{options.locale === \"es\" ? \"Recursos\" : \"Resources\"}</div>\n <div data-rsv=\"tl-axis\">\n {model.slots.map((slot) => (\n <div data-rsv=\"tl-slot\" style={`left:${slot.leftPct}%`} key={slot.leftPct}>\n {slot.label}\n </div>\n ))}\n </div>\n </div>\n\n {/* Filas de recursos */}\n {model.lanes.map((lane) => {\n const rowHeight = lane.laneCount * LANE_REM + 0.4;\n return (\n <div data-rsv=\"resource-row\" role=\"row\" key={lane.row.resource.id}>\n <div\n data-rsv=\"resource-label\"\n style={`padding-inline-start:${0.5 + lane.row.depth * 1}rem`}\n >\n {lane.row.hasChildren && (\n <button\n type=\"button\"\n data-rsv=\"resource-toggle\"\n aria-expanded={lane.row.expanded}\n onClick={() => api.toggleResource(lane.row.resource.id)}\n >\n {lane.row.expanded ? \"▾\" : \"▸\"}\n </button>\n )}\n <span data-rsv=\"resource-title\">{lane.row.resource.title}</span>\n </div>\n <div data-rsv=\"resource-lane\" style={`height:${rowHeight}rem`}>\n {lane.segs.map((seg) => (\n <TimelineEvent api={api} seg={seg} options={options} key={seg.event.id} />\n ))}\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n","import {\n dl,\n getLocaleText,\n type CalendarApi,\n type ResourceTimeGridModel,\n} from \"@reservi/core\";\nimport type { VNode } from \"preact\";\nimport type { ReserviCalendarOptions } from \"../../types.js\";\n\ninterface Props {\n api: CalendarApi;\n model: ResourceTimeGridModel;\n options: ReserviCalendarOptions;\n}\n\n/** Vista vertical de recursos: recursos como columnas sobre un eje de tiempo. */\nexport function ResourceTimeGridView({ api, model, options }: Props): VNode {\n const bodyHeight = `calc(var(--spacing-rsv-slot, 2.5rem) * ${model.slots.length})`;\n\n return (\n <div data-rsv=\"timegrid\" style={`--rsv-tg-days:${model.columns.length}`}>\n <div data-rsv=\"tg-header\" role=\"row\">\n <div data-rsv=\"tg-axis-corner\" />\n {model.columns.map((col) => (\n <div data-rsv=\"tg-col-header\" role=\"columnheader\" key={col.row.resource.id}>\n {col.row.resource.title}\n </div>\n ))}\n </div>\n\n <div data-rsv=\"tg-allday\" role=\"row\">\n <div data-rsv=\"tg-axis-label\">{getLocaleText(options.locale).allDay}</div>\n {model.columns.map((col) => (\n <div data-rsv=\"tg-allday-cell\" key={col.row.resource.id}>\n {col.allDayEvents.map((event) => (\n <div\n data-rsv=\"event\"\n data-all-day=\"true\"\n key={event.id}\n style={`--rsv-event-bg:${event.backgroundColor}`}\n onClick={() => api.trigger(\"eventClick\", { event })}\n >\n {event.title}\n </div>\n ))}\n </div>\n ))}\n </div>\n\n <div data-rsv=\"tg-body\">\n <div data-rsv=\"tg-axis\" style={`height:${bodyHeight}`}>\n {model.slots.map((slot) => (\n <div data-rsv=\"tg-slot\" data-major={String(slot.isMajor)} key={slot.offsetMin}>\n <span data-rsv=\"tg-slot-label\">{slot.label}</span>\n </div>\n ))}\n </div>\n\n {model.columns.map((col) => (\n <div\n data-rsv=\"tg-col\"\n data-rsv-resource-id={col.row.resource.id}\n style={`height:${bodyHeight}`}\n key={col.row.resource.id}\n >\n {col.timedSegs.map((seg) => {\n const widthPct = 100 / seg.colCount;\n return (\n <div\n data-rsv=\"event\"\n data-all-day=\"false\"\n data-event-id={seg.event.id}\n role=\"button\"\n tabIndex={0}\n key={seg.event.id}\n style={\n `position:absolute;top:${seg.topPct}%;height:${seg.heightPct}%;` +\n `left:${seg.col * widthPct}%;width:${widthPct}%;` +\n `--rsv-event-bg:${seg.event.backgroundColor};--rsv-event-fg:${seg.event.textColor}`\n }\n onClick={(e) => {\n e.stopPropagation();\n api.trigger(\"eventClick\", { event: seg.event });\n }}\n >\n {dl.format(seg.event.start, \"HH:mm\")} {seg.event.title}\n </div>\n );\n })}\n {model.nowTopPct != null && (\n <div data-rsv=\"now-indicator\" style={`top:${model.nowTopPct}%`} />\n )}\n </div>\n ))}\n </div>\n </div>\n );\n}\n","import { dl, type CalendarApi, type ResourceDayGridModel } from \"@reservi/core\";\nimport type { VNode } from \"preact\";\nimport type { ReserviCalendarOptions } from \"../../types.js\";\n\ninterface Props {\n api: CalendarApi;\n model: ResourceDayGridModel;\n options: ReserviCalendarOptions;\n}\n\n/** Recursos como columnas en cuadrícula de día (eventos apilados por recurso). */\nexport function ResourceDayGridView({ api, model }: Props): VNode {\n return (\n <div data-rsv=\"resource-daygrid\" style={`--rsv-rdg-cols:${model.columns.length}`}>\n <div data-rsv=\"rdg-header\" role=\"row\">\n {model.columns.map((col) => (\n <div data-rsv=\"rdg-col-header\" role=\"columnheader\" key={col.row.resource.id}>\n {col.row.resource.title}\n </div>\n ))}\n </div>\n <div data-rsv=\"rdg-body\" role=\"row\">\n {model.columns.map((col) => (\n <div data-rsv=\"rdg-col\" data-rsv-resource-id={col.row.resource.id} key={col.row.resource.id}>\n {col.events.map((event) => (\n <div\n data-rsv=\"event\"\n data-all-day={String(event.allDay)}\n data-event-id={event.id}\n role=\"button\"\n tabIndex={0}\n key={event.id}\n style={`--rsv-event-bg:${event.backgroundColor};--rsv-event-fg:${event.textColor}`}\n onClick={() => api.trigger(\"eventClick\", { event })}\n >\n {event.allDay ? \"\" : dl.format(event.start, \"HH:mm\") + \" \"}\n {event.title}\n </div>\n ))}\n </div>\n ))}\n </div>\n </div>\n );\n}\n","// Importar @preact/signals activa el seguimiento automático de signals en los\n// componentes: leer `api.viewModel.value` re-renderiza de forma granular.\nimport \"@preact/signals\";\nimport { getLocaleText, themeToStyle, type CalendarApi } from \"@reservi/core\";\nimport type { VNode } from \"preact\";\nimport type { ReserviCalendarOptions } from \"../types.js\";\nimport { cx } from \"../render/slots.js\";\nimport { Toolbar } from \"./Toolbar.js\";\nimport { DayGridView } from \"../views/daygrid/DayGridView.js\";\nimport { TimeGridView } from \"../views/timegrid/TimeGridView.js\";\nimport { ListView } from \"../views/list/ListView.js\";\nimport { MultiMonthView } from \"../views/multimonth/MultiMonthView.js\";\nimport { TimelineView } from \"../views/timeline/TimelineView.js\";\nimport { ResourceTimelineView } from \"../views/resource/ResourceTimelineView.js\";\nimport { ResourceTimeGridView } from \"../views/resource/ResourceTimeGridView.js\";\nimport { ResourceDayGridView } from \"../views/resource/ResourceDayGridView.js\";\n\ninterface CalendarProps {\n api: CalendarApi;\n options: ReserviCalendarOptions;\n}\n\n/** Componente raíz: lee el ViewModel reactivo y delega en la vista activa. */\nexport function Calendar({ api, options }: CalendarProps): VNode {\n const vm = api.viewModel.value; // reactivo (signals)\n const dir = options.direction ?? getLocaleText(options.locale).direction;\n const themeStyle = options.themeTokens ? themeToStyle(options.themeTokens) : undefined;\n\n return (\n <div\n data-rsv=\"root\"\n dir={dir}\n data-rsv-theme={options.theme}\n style={themeStyle}\n class={cx(options.classNames?.root)}\n >\n {options.headerToolbar !== false && (\n <Toolbar api={api} title={vm.title} activeView={vm.type} options={options} />\n )}\n <div data-rsv=\"view\" data-view={vm.type}>\n {vm.dayGrid ? (\n <DayGridView api={api} model={vm.dayGrid} options={options} />\n ) : vm.timeGrid ? (\n <TimeGridView api={api} model={vm.timeGrid} options={options} />\n ) : vm.list ? (\n <ListView api={api} model={vm.list} options={options} />\n ) : vm.multiMonth ? (\n <MultiMonthView api={api} model={vm.multiMonth} options={options} />\n ) : vm.resourceTimeGrid ? (\n <ResourceTimeGridView api={api} model={vm.resourceTimeGrid} options={options} />\n ) : vm.resourceDayGrid ? (\n <ResourceDayGridView api={api} model={vm.resourceDayGrid} options={options} />\n ) : vm.resourceTimeline ? (\n <ResourceTimelineView api={api} model={vm.resourceTimeline} options={options} />\n ) : vm.timeline ? (\n <TimelineView api={api} model={vm.timeline} options={options} />\n ) : (\n <div data-rsv=\"unsupported\">\n La vista \"{vm.type}\" se implementa en una fase posterior.\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { h, render } from \"preact\";\nimport { CalendarApi } from \"@reservi/core\";\nimport { Calendar } from \"./components/Calendar.js\";\nimport type { ReserviCalendarOptions } from \"./types.js\";\n\nexport interface ReserviCalendarHandle {\n /** API del calendario (navegación, eventos, callbacks). */\n readonly api: CalendarApi;\n /** Desmonta el calendario y libera recursos. */\n destroy(): void;\n}\n\n/**\n * Monta un calendario Reservi en un elemento del DOM. API agnóstica usada\n * directamente (vanilla/Preact) y por los wrappers de framework.\n */\nexport function mount(el: HTMLElement, options: ReserviCalendarOptions): ReserviCalendarHandle {\n const api = new CalendarApi(options);\n render(h(Calendar, { api, options }), el);\n\n return {\n api,\n destroy() {\n render(null, el);\n api.destroy();\n },\n };\n}\n","import { eventsToICS, type EventInput } from \"@reservi/core\";\n\n/**\n * Exporta eventos a un archivo `.ics` y dispara la descarga en el navegador.\n * Capa de UI (usa DOM); la serialización pura vive en `@reservi/core`.\n */\nexport function downloadICS(events: EventInput[], filename = \"calendar.ics\"): void {\n if (typeof document === \"undefined\") return;\n const ics = eventsToICS(events);\n const blob = new Blob([ics], { type: \"text/calendar;charset=utf-8\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = filename;\n document.body.appendChild(a);\n a.click();\n a.remove();\n URL.revokeObjectURL(url);\n}\n\nexport { parseICS, eventsToICS } from \"@reservi/core\";\n"],"names":["renderSlot","slot","arg","fallback","cx","classes","NAV_SYMBOLS","NON_VIEW_TOKENS","MONTH_VIEW_RE","pad2","n","CalendarIcon","jsxs","jsx","resolveViews","options","_a","tb","s","g","t","Toolbar","api","title","activeView","text","getLocaleText","startSlot","_b","endSlot","_d","_c","views","monthMode","firstDay","wrapRef","useRef","open","setOpen","useState","selected","dl","nowRef","viewYear","setViewYear","viewMonth","setViewMonth","monthShortFmt","monthLongFmt","dowFmt","monthNames","_","i","openPicker","d","shiftMonth","delta","total","goto","iso","useEffect","onKey","e","onPointer","dayGrid","first","offset","start","cells","dows","_e","y","label","v","navLinkToDay","date","target","DAY","handleEventKeydown","opts","event","kind","snapMin","timeStringToMinutes","deltaMin","next","computeDrop","updated","THRESHOLD","dateAtPoint","x","el","startDayGridEventDrag","ev","sourceDate","startX","startY","dragging","onMove","onUp","deltaDays","startDayRangeSelect","endStr","moved","a","b","lo","hi","DayGridView","model","locale","headerDays","showWeekNums","cell","week","wi","DayCell","dayNumber","defaultNumber","numberNode","moreOpen","setMoreOpen","dateStr","rangeSelectedRef","onDayClick","openMore","EventChip","DayMorePopover","onClose","ref","dayFmt","allEvents","editable","draggedRef","timeText","content","startEventDrag","columnEl","snap","edge","rect","totalMinutes","ppm","pxToSnappedMinutes","computeResize","startTimeRangeSelect","yToMin","clientY","raw","clamped","startMin","endMin","m","dayStart","TimeGridView","showAllDay","bodyHeight","dayIndex","Fragment","seg","TimedEvent","widthPct","getColumn","ListView","day","MultiMonthView","monthFmt","month","LANE_REM","TimelineView","TimelineEvent","ResourceTimelineView","lane","rowHeight","ResourceTimeGridView","col","ResourceDayGridView","Calendar","vm","dir","themeStyle","themeToStyle","mount","CalendarApi","render","h","downloadICS","events","filename","ics","eventsToICS","blob","url"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@reservi/preact",
3
+ "version": "1.1.0",
4
+ "description": "Capa de UI agnóstica de Reservi Calendar, construida con Preact.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "main": "./dist/index.cjs",
12
+ "module": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.js",
18
+ "require": "./dist/index.cjs"
19
+ }
20
+ },
21
+ "dependencies": {
22
+ "@reservi/core": "1.1.0"
23
+ },
24
+ "peerDependencies": {
25
+ "@preact/signals": "^2.0.0",
26
+ "preact": "^10.25.0"
27
+ },
28
+ "devDependencies": {
29
+ "@preact/signals": "^2.0.1",
30
+ "@testing-library/preact": "^3.2.4",
31
+ "jsdom": "^25.0.1",
32
+ "preact": "^10.25.4",
33
+ "typescript": "^5.7.2",
34
+ "vite": "^6.0.0",
35
+ "vite-plugin-dts": "^4.3.0",
36
+ "vitest": "^2.1.8",
37
+ "@reservi/eslint-config": "1.1.0",
38
+ "@reservi/tsconfig": "1.1.0"
39
+ },
40
+ "scripts": {
41
+ "build": "vite build",
42
+ "dev": "vite build --watch",
43
+ "test": "vitest run",
44
+ "test:watch": "vitest",
45
+ "lint": "eslint src",
46
+ "typecheck": "tsc --noEmit"
47
+ }
48
+ }