@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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Reservi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/index.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const O=require("preact"),o=require("@reservi/core"),t=require("preact/jsx-runtime");require("@preact/signals");const D=require("preact/hooks");function S(a,e,n){return a?a(e):n}function C(...a){return a.filter(Boolean).join(" ")}const E={prev:"‹",next:"›"},ue=new Set(["","title","today","prev","next"]),ve=/month|year/i,$=a=>String(a).padStart(2,"0");function me(){return t.jsxs("svg",{"data-rsv":"title-icon",width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",stroke:"currentColor","stroke-width":"1.3","stroke-linecap":"round","stroke-linejoin":"round","aria-hidden":"true",children:[t.jsx("rect",{x:"1",y:"2.5",width:"12",height:"10.5",rx:"1.5"}),t.jsx("line",{x1:"1",y1:"5.5",x2:"13",y2:"5.5"}),t.jsx("line",{x1:"4.5",y1:"1",x2:"4.5",y2:"3.5"}),t.jsx("line",{x1:"9.5",y1:"1",x2:"9.5",y2:"3.5"})]})}function he(a){var n;if((n=a.views)!=null&&n.length)return a.views;const e=a.headerToolbar;return e?[e.start,e.center,e.end].filter(r=>!!r).flatMap(r=>r.split(/\s+/)).flatMap(r=>r.split(",")).filter(r=>!ue.has(r)):[]}function W({api:a,title:e,activeView:n,options:r}){var P,H,T,B,_;const s=o.getLocaleText(r.locale),i=(H=(P=r.slots)==null?void 0:P.toolbarStart)==null?void 0:H.call(P),u=(B=(T=r.slots)==null?void 0:T.toolbarEnd)==null?void 0:B.call(T),d=he(r),l=ve.test(n),c=r.firstDay??s.firstDay,m=D.useRef(null),[h,y]=D.useState(!1),x=o.dl.toDate(a.getDate()),g=o.dl.toDate(r.now?o.dl.from(r.now):o.dl.now()),[b,p]=D.useState(x.getFullYear()),[j,k]=D.useState(x.getMonth()),M=new Intl.DateTimeFormat(r.locale,{month:"short"}),de=new Intl.DateTimeFormat(r.locale,{month:"long"}),oe=new Intl.DateTimeFormat(r.locale,{weekday:"short"}),ie=Array.from({length:12},(v,f)=>M.format(new Date(2020,f,1))),V=()=>{const v=o.dl.toDate(a.getDate());p(v.getFullYear()),k(v.getMonth()),y(!0)},Y=v=>{const f=b*12+j+v;p(Math.floor(f/12)),k((f%12+12)%12)},A=v=>{a.gotoDate(v),y(!1)};D.useEffect(()=>{const v=w=>{(w.ctrlKey||w.metaKey)&&(w.key==="m"||w.key==="M")?(w.preventDefault(),V()):w.key==="Escape"&&y(!1)},f=w=>{m.current&&!m.current.contains(w.target)&&y(!1)};return document.addEventListener("keydown",v),document.addEventListener("mousedown",f),()=>{document.removeEventListener("keydown",v),document.removeEventListener("mousedown",f)}},[]);const N=(()=>{if(l)return{cells:[],dows:[]};const v=o.dl.from(`${b}-${$(j+1)}-01`),f=(o.dl.dayOfWeek(v)-c+7)%7,w=o.dl.subtract(v,{days:f}),K=Array.from({length:42},(U,ce)=>o.dl.toDate(o.dl.add(w,{days:ce}))),le=K.slice(0,7).map(U=>oe.format(U));return{cells:K,dows:le}})();return t.jsxs("div",{"data-rsv":"toolbar-wrap",class:C((_=r.classNames)==null?void 0:_.toolbar),ref:m,children:[t.jsxs("div",{"data-rsv":"toolbar",children:[t.jsx("div",{"data-rsv":"toolbar-section","data-rsv-area":"start",children:i}),t.jsxs("div",{"data-rsv":"toolbar-section","data-rsv-area":"nav",children:[t.jsx("button",{type:"button","data-rsv":"button",title:s.today,"aria-label":s.today,onClick:()=>a.today(),children:s.today}),t.jsx("button",{type:"button","data-rsv":"button","data-rsv-nav":"prev",title:s.prev,"aria-label":s.prev,onClick:()=>a.prev(),children:E.prev}),t.jsxs("div",{"data-rsv":"datepicker-anchor",children:[t.jsxs("button",{type:"button","data-rsv":"title","aria-haspopup":"dialog","aria-expanded":h,title:`${e} · Ctrl+M`,onClick:()=>h?y(!1):V(),children:[t.jsx(me,{}),e]}),h&&t.jsxs("div",{"data-rsv":"datepicker","data-rsv-mode":l?"month":"day",role:"dialog","aria-label":e,children:[t.jsxs("div",{"data-rsv":"dp-head",children:[t.jsx("button",{type:"button","data-rsv":"dp-nav","aria-label":s.prev,onClick:()=>l?p(v=>v-1):Y(-1),children:E.prev}),t.jsx("span",{"data-rsv":"dp-label",children:l?b:`${de.format(new Date(b,j,1))} ${b}`}),t.jsx("button",{type:"button","data-rsv":"dp-nav","aria-label":s.next,onClick:()=>l?p(v=>v+1):Y(1),children:E.next})]}),l?t.jsx("div",{"data-rsv":"dp-grid",children:ie.map((v,f)=>t.jsx("button",{type:"button","data-rsv":"dp-month","data-active":String(b===x.getFullYear()&&f===x.getMonth()),"data-today":String(b===g.getFullYear()&&f===g.getMonth()),onClick:()=>A(`${b}-${$(f+1)}-01`),children:v},v))}):t.jsxs("div",{"data-rsv":"dp-days",children:[N.dows.map((v,f)=>t.jsx("div",{"data-rsv":"dp-dow",children:v},`dow-${f}`)),N.cells.map(v=>{const f=`${v.getFullYear()}-${$(v.getMonth()+1)}-${$(v.getDate())}`;return t.jsx("button",{type:"button","data-rsv":"dp-day","data-other":String(v.getMonth()!==j),"data-active":String(v.getFullYear()===x.getFullYear()&&v.getMonth()===x.getMonth()&&v.getDate()===x.getDate()),"data-today":String(v.getFullYear()===g.getFullYear()&&v.getMonth()===g.getMonth()&&v.getDate()===g.getDate()),onClick:()=>A(f),children:v.getDate()},f)})]})]})]}),t.jsx("button",{type:"button","data-rsv":"button","data-rsv-nav":"next",title:s.next,"aria-label":s.next,onClick:()=>a.next(),children:E.next})]}),t.jsxs("div",{"data-rsv":"toolbar-section","data-rsv-area":"end",children:[u,r.onAddClick&&t.jsxs("button",{type:"button","data-rsv":"button","data-rsv-variant":"primary",onClick:r.onAddClick,children:[t.jsx("span",{"data-rsv":"add-icon","aria-hidden":"true",children:"+"}),r.addButtonText]})]})]}),d.length>0&&t.jsx("div",{"data-rsv":"toolbar-views",role:"tablist",children:d.map(v=>t.jsx("button",{type:"button","data-rsv":"view-tab",role:"tab","aria-selected":v===n,"data-active":String(v===n),onClick:()=>a.changeView(v),children:s.views[v]??v},v))})]})}function q(a,e){a.trigger("navLinkDay",{date:e});const n=a.hasView("timeGridDay")?"timeGridDay":a.hasView("dayGridDay")?"dayGridDay":null;n&&(a.gotoDate(o.dl.toISOString(e)),a.changeView(n))}const L=1440;function G(a,e){const{api:n,event:r,kind:s}=e,i=o.timeStringToMinutes(e.snap??"00:30");let u=0;switch(a.key){case"ArrowLeft":u=-L;break;case"ArrowRight":u=L;break;case"ArrowUp":u=s==="timeGrid"?-i:-L*7;break;case"ArrowDown":u=s==="timeGrid"?i:L*7;break;case"Enter":case" ":a.preventDefault(),n.trigger("eventClick",{event:r});return;default:return}a.preventDefault();const d=o.computeDrop(r.start,r.end,u,o.dl);if(n.moveEvent(r.id,d.start,d.end)){const l=n.getEventById(r.id);l&&n.trigger("eventDrop",{event:l})}}const ge=1440,ye=4;function X(a,e){var r;const n=document.elementFromPoint(a,e);return((r=n==null?void 0:n.closest('[data-rsv="day"]'))==null?void 0:r.dataset.date)??null}function xe(a,e){a.stopPropagation();const{api:n,event:r,sourceDate:s}=e,i=a.clientX,u=a.clientY;let d=!1;const l=m=>{!d&&Math.hypot(m.clientX-i,m.clientY-u)>ye&&(d=!0,document.body.style.cursor="grabbing")},c=m=>{var g;if(document.removeEventListener("pointermove",l),document.removeEventListener("pointerup",c),document.body.style.cursor="",!d)return;(g=e.onMoved)==null||g.call(e);const h=X(m.clientX,m.clientY);if(!h)return;const y=o.dl.diff(o.dl.from(s),o.dl.from(h),"day");if(y===0)return;const x=o.computeDrop(r.start,r.end,y*ge,o.dl);if(n.moveEvent(r.id,x.start,x.end)){const b=n.getEventById(r.id);b&&n.trigger("eventDrop",{event:b})}};document.addEventListener("pointermove",l),document.addEventListener("pointerup",c)}function fe(a,e){if(a.target.closest('[data-rsv="event"], [data-rsv="more-anchor"], [data-nav-link="true"]'))return;const{api:r}=e;let s=e.startDate,i=!1;const u=l=>{const c=X(l.clientX,l.clientY);c&&c!==e.startDate&&(i=!0),c&&(s=c)},d=()=>{var y;if(document.removeEventListener("pointermove",u),document.removeEventListener("pointerup",d),!i)return;(y=e.onRangeSelect)==null||y.call(e);const l=o.dl.from(e.startDate),c=o.dl.from(s),[m,h]=o.dl.isBefore(l,c)?[l,c]:[c,l];r.select(o.dl.toISOString(m),o.dl.toISOString(o.dl.add(h,{days:1})))};document.addEventListener("pointermove",u),document.addEventListener("pointerup",d)}function F({api:a,model:e,options:n}){var d;const r=n.locale??"en",s=new Intl.DateTimeFormat(r,{weekday:"short"}),i=((d=e.weeks[0])==null?void 0:d.days)??[],u=n.weekNumbers===!0;return t.jsxs("div",{"data-rsv":"daygrid","data-weeknumbers":String(u),style:`--rsv-cols:${e.columnCount}`,children:[t.jsxs("div",{"data-rsv":"daygrid-header",role:"row",children:[u&&t.jsx("div",{"data-rsv":"daygrid-weeknum-header",role:"columnheader"}),i.map(l=>{var h;const c=o.dl.toDate(l.date),m=s.format(c);return t.jsx("div",{"data-rsv":"daygrid-dow",role:"columnheader",children:S((h=n.slots)==null?void 0:h.dayHeaderContent,{date:c,text:m},m)},l.dayOfWeek)})]}),e.weeks.map((l,c)=>t.jsxs("div",{"data-rsv":"daygrid-week",role:"row",children:[u&&t.jsx("div",{"data-rsv":"daygrid-weeknum",role:"rowheader",children:l.weekNumber}),l.days.map(m=>t.jsx(be,{api:a,cell:m,options:n},o.dl.toISOString(m.date)))]},c))]})}function be({api:a,cell:e,options:n}){var x;const r=o.dl.toDate(e.date),s=o.dl.dayOfMonth(e.date),i=n.navLinks?t.jsx("a",{"data-rsv":"day-number","data-nav-link":"true",role:"link",tabIndex:0,onClick:g=>{g.stopPropagation(),q(a,e.date)},children:s}):t.jsx("span",{"data-rsv":"day-number",children:s}),u=S((x=n.slots)==null?void 0:x.dayCellContent,{date:r,dayNumber:s,isToday:e.isToday,isOther:e.isOther},i),[d,l]=D.useState(!1),c=o.dl.toISOString(e.date),m=D.useRef(!1),h=()=>{if(m.current){m.current=!1;return}a.trigger("dateClick",{date:e.date}),n.selectable&&a.select(c,o.dl.toISOString(o.dl.add(e.date,{days:1})))},y=g=>{g.stopPropagation(),l(!0),a.trigger("moreLinkClick",{date:e.date,allEvents:[...e.events,...e.hiddenEvents],hiddenEvents:e.hiddenEvents})};return t.jsxs("div",{"data-rsv":"day",role:"gridcell","data-date":c,"data-today":String(e.isToday),"data-other":String(e.isOther),"data-weekend":String(e.isWeekend),"data-business":String(e.isBusiness),"data-selected":String(e.isSelected),onClick:h,onPointerDown:n.selectable?g=>fe(g,{api:a,startDate:c,onRangeSelect:()=>{m.current=!0}}):void 0,children:[u,e.events.filter(g=>g.display!=="none").map(g=>t.jsx(z,{api:a,event:g,options:n,sourceDate:c},g.id)),e.moreCount>0&&t.jsxs("div",{"data-rsv":"more-anchor",children:[t.jsx("button",{type:"button","data-rsv":"more-link",onClick:y,children:o.getLocaleText(n.locale).more(e.moreCount)}),d&&t.jsx(pe,{api:a,cell:e,options:n,onClose:()=>l(!1)})]})]})}function pe({api:a,cell:e,options:n,onClose:r}){const s=D.useRef(null),i=new Intl.DateTimeFormat(n.locale??"en",{weekday:"long",day:"numeric",month:"long"}),u=[...e.events,...e.hiddenEvents].filter(d=>d.display!=="none");return D.useEffect(()=>{const d=c=>{s.current&&!s.current.contains(c.target)&&r()},l=c=>{c.key==="Escape"&&r()};return document.addEventListener("mousedown",d),document.addEventListener("keydown",l),()=>{document.removeEventListener("mousedown",d),document.removeEventListener("keydown",l)}},[r]),t.jsxs("div",{"data-rsv":"more-popover",role:"dialog",ref:s,onClick:d=>d.stopPropagation(),children:[t.jsxs("div",{"data-rsv":"more-popover-header",children:[t.jsx("span",{"data-rsv":"more-popover-title",children:i.format(o.dl.toDate(e.date))}),t.jsx("button",{type:"button","data-rsv":"more-popover-close","aria-label":"✕",onClick:r,children:"✕"})]}),t.jsx("div",{"data-rsv":"more-popover-body",children:u.map(d=>t.jsx(z,{api:a,event:d,options:n,sourceDate:o.dl.toISOString(e.date)},d.id))})]})}function z({api:a,event:e,options:n,sourceDate:r}){var l;const s=n.editable===!0&&e.editable!==!1,i=D.useRef(!1),u=e.allDay?"":o.dl.format(e.start,"HH:mm"),d=S((l=n.slots)==null?void 0:l.eventContent,{event:e,isAllDay:e.allDay,timeText:u},t.jsxs("span",{"data-rsv":"event-title",children:[u?`${u} `:"",e.title]}));return t.jsx("div",{"data-rsv":"event",role:"button",tabIndex:0,class:C(...e.classNames),"data-all-day":String(e.allDay),"data-display":e.display,"data-event-id":e.id,"data-editable":String(s),style:`--rsv-event-bg:${e.backgroundColor};--rsv-event-fg:${e.textColor}`,onClick:c=>{if(c.stopPropagation(),i.current){i.current=!1;return}a.trigger("eventClick",{event:e}),e.url&&window.open(e.url,"_self")},onPointerDown:s?c=>xe(c,{api:a,event:e,sourceDate:r,onMoved:()=>{i.current=!0}}):void 0,onKeyDown:s?c=>G(c,{api:a,event:e,kind:"dayGrid"}):void 0,children:d})}function I(a,e){a.preventDefault(),a.stopPropagation();const{api:n,event:r,model:s,columnEl:i,snap:u="00:15",edge:d}=e,l=i.getBoundingClientRect(),c=s.maxMinutes-s.minMinutes,m=l.height===0?0:l.height/c,h=a.clientY,y=x=>{document.removeEventListener("pointerup",y);const g=o.pxToSnappedMinutes(x.clientY-h,m,u);if(g===0)return;const b=d?o.computeResize(r.start,r.end,d,g,o.dl):o.computeDrop(r.start,r.end,g,o.dl);if(n.moveEvent(r.id,b.start,b.end)){const p=n.getEventById(r.id);p&&n.trigger(d?"eventResize":"eventDrop",{event:p})}};document.addEventListener("pointerup",y)}function je(a,e){if(a.target.closest('[data-rsv="event"]'))return;const{api:n,date:r,model:s,columnEl:i,snap:u="00:15"}=e,d=i.getBoundingClientRect(),l=s.maxMinutes-s.minMinutes,c=d.height===0?0:d.height/l,m=o.timeStringToMinutes(u)||15,h=j=>{const k=s.minMinutes+(c===0?0:(j-d.top)/c),M=Math.max(s.minMinutes,Math.min(s.maxMinutes,k));return Math.round(M/m)*m},y=h(a.clientY);let x=y,g=!1;const b=j=>{const k=h(j.clientY);k!==y&&(g=!0),x=k},p=()=>{if(document.removeEventListener("pointermove",b),document.removeEventListener("pointerup",p),!g)return;const j=Math.min(y,x),k=Math.max(y,x),M=o.dl.startOf(r,"day");n.select(o.dl.toISOString(o.dl.add(M,{minutes:j})),o.dl.toISOString(o.dl.add(M,{minutes:k})))};document.addEventListener("pointermove",b),document.addEventListener("pointerup",p)}function J({api:a,model:e,options:n}){const r=n.locale??"en",s=new Intl.DateTimeFormat(r,{weekday:"short",day:"numeric"}),i=n.allDaySlot!==!1,u=`calc(var(--spacing-rsv-slot, 2.5rem) * ${e.slots.length})`;return t.jsxs("div",{"data-rsv":"timegrid",style:`--rsv-tg-days:${e.days.length}`,children:[t.jsxs("div",{"data-rsv":"tg-header",role:"row",children:[t.jsx("div",{"data-rsv":"tg-axis-corner"}),e.days.map(d=>t.jsx("div",{"data-rsv":"tg-col-header",role:"columnheader","data-today":String(d.isToday),"data-nav-link":n.navLinks?"true":void 0,onClick:n.navLinks?()=>q(a,d.date):void 0,children:s.format(o.dl.toDate(d.date))},o.dl.toISOString(d.date)))]}),i&&t.jsxs("div",{"data-rsv":"tg-allday",role:"row",children:[t.jsx("div",{"data-rsv":"tg-axis-label",children:o.getLocaleText(n.locale).allDay}),e.days.map(d=>t.jsx("div",{"data-rsv":"tg-allday-cell",children:d.allDayEvents.filter(l=>l.display!=="none").map(l=>t.jsx("div",{"data-rsv":"event","data-all-day":"true",class:C(...l.classNames),"data-display":l.display,style:`--rsv-event-bg:${l.backgroundColor}`,onClick:()=>{a.trigger("eventClick",{event:l}),l.url&&window.open(l.url,"_self")},children:l.title},l.id))},o.dl.toISOString(d.date)))]}),t.jsxs("div",{"data-rsv":"tg-body",children:[t.jsx("div",{"data-rsv":"tg-axis",style:`height:${u}`,children:e.slots.map(d=>{var l;return t.jsx("div",{"data-rsv":"tg-slot","data-major":String(d.isMajor),children:t.jsx("span",{"data-rsv":"tg-slot-label",children:S((l=n.slots)==null?void 0:l.slotLabelContent,{text:d.label,minutes:d.offsetMin,isMajor:d.isMajor},d.label)})},d.offsetMin)})}),e.days.map((d,l)=>{var c;return t.jsxs("div",{"data-rsv":"tg-col","data-today":String(d.isToday),style:`height:${u}`,onClick:()=>a.trigger("dateClick",{date:d.date}),onPointerDown:n.selectable?m=>je(m,{api:a,date:d.date,model:e,columnEl:m.currentTarget,snap:n.snapDuration??n.slotDuration}):void 0,children:[n.businessHours&&!d.businessPct&&t.jsx("div",{"data-rsv":"tg-nonbusiness",style:"top:0;height:100%"}),d.businessPct&&t.jsxs(t.Fragment,{children:[t.jsx("div",{"data-rsv":"tg-nonbusiness",style:`top:0;height:${d.businessPct.topPct}%`}),t.jsx("div",{"data-rsv":"tg-nonbusiness",style:`top:${d.businessPct.bottomPct}%;height:${100-d.businessPct.bottomPct}%`})]}),d.timedSegs.filter(m=>m.event.display!=="none").map(m=>t.jsx(we,{api:a,seg:m,model:e,options:n},m.event.id)),((c=e.nowIndicator)==null?void 0:c.dayIndex)===l&&t.jsx("div",{"data-rsv":"now-indicator",style:`top:${e.nowIndicator.topPct}%`})]},o.dl.toISOString(d.date))})]})]})}function we({api:a,seg:e,model:n,options:r}){var m;const{event:s}=e,i=r.editable===!0&&s.editable!==!1,u=100/e.colCount,d=o.dl.format(s.start,"HH:mm"),l=S((m=r.slots)==null?void 0:m.eventContent,{event:s,isAllDay:!1,timeText:d},t.jsxs("span",{"data-rsv":"event-title",children:[d," ",s.title]})),c=h=>h.closest('[data-rsv="tg-col"]')??h;return t.jsxs("div",{"data-rsv":"event","data-all-day":"false","data-display":s.display,"data-event-id":s.id,class:C(...s.classNames),role:"button",tabIndex:0,style:`position:absolute;top:${e.topPct}%;height:${e.heightPct}%;left:${e.col*u}%;width:${u}%;--rsv-event-bg:${s.backgroundColor};--rsv-event-fg:${s.textColor}`,onClick:h=>{h.stopPropagation(),a.trigger("eventClick",{event:s}),s.url&&window.open(s.url,"_self")},onKeyDown:i?h=>G(h,{api:a,event:s,kind:"timeGrid",snap:r.snapDuration??r.slotDuration}):void 0,onPointerDown:i?h=>I(h,{api:a,event:s,model:n,columnEl:c(h.currentTarget),snap:r.snapDuration}):void 0,children:[i&&t.jsx("span",{"data-rsv":"resize-handle","data-edge":"start",onPointerDown:h=>I(h,{api:a,event:s,model:n,columnEl:c(h.currentTarget),snap:r.snapDuration,edge:"start"})}),l,i&&t.jsx("span",{"data-rsv":"resize-handle","data-edge":"end",onPointerDown:h=>I(h,{api:a,event:s,model:n,columnEl:c(h.currentTarget),snap:r.snapDuration,edge:"end"})})]})}function Q({api:a,model:e,options:n}){const r=n.locale??"en",s=o.getLocaleText(n.locale),i=new Intl.DateTimeFormat(r,{weekday:"long",day:"numeric",month:"long"});return e.isEmpty?t.jsx("div",{"data-rsv":"list",children:t.jsx("div",{"data-rsv":"list-empty",children:s.noEvents})}):t.jsx("div",{"data-rsv":"list",role:"list",children:e.days.map(u=>t.jsxs("div",{"data-rsv":"list-day","data-today":String(u.isToday),children:[t.jsx("div",{"data-rsv":"list-day-header",role:"heading","aria-level":3,children:i.format(o.dl.toDate(u.date))}),u.events.filter(d=>d.display!=="none").map(d=>{var c;const l=d.allDay?s.allDay:o.dl.format(d.start,"HH:mm");return t.jsxs("div",{"data-rsv":"list-item",role:"listitem",tabIndex:0,class:C(...d.classNames),"data-display":d.display,onClick:()=>{a.trigger("eventClick",{event:d}),d.url&&window.open(d.url,"_self")},children:[t.jsx("span",{"data-rsv":"list-item-time",children:l}),t.jsx("span",{"data-rsv":"list-item-dot",style:`--rsv-event-bg:${d.backgroundColor}`}),t.jsx("span",{"data-rsv":"list-item-title",children:S((c=n.slots)==null?void 0:c.eventContent,{event:d,isAllDay:d.allDay,timeText:l},d.title)})]},d.id)})]},o.dl.toISOString(u.date)))})}function Z({api:a,model:e,options:n}){const r=n.locale??"en",s=new Intl.DateTimeFormat(r,{month:"long"});return t.jsx("div",{"data-rsv":"multimonth",children:e.months.map(i=>t.jsxs("section",{"data-rsv":"mm-month",children:[t.jsx("header",{"data-rsv":"mm-title",children:s.format(o.dl.toDate(i.date))}),t.jsx(F,{api:a,model:i.dayGrid,options:n})]},o.dl.toISOString(i.date)))})}const R=1.6;function ee({api:a,model:e,options:n}){return t.jsxs("div",{"data-rsv":"timeline",children:[t.jsx("div",{"data-rsv":"tl-axis",role:"row",children:e.slots.map(r=>t.jsx("div",{"data-rsv":"tl-slot",style:`left:${r.leftPct}%`,children:r.label},r.leftPct))}),t.jsx("div",{"data-rsv":"tl-body",style:`height:${e.laneCount*R+.5}rem`,children:e.segs.map(r=>t.jsx(te,{api:a,seg:r,options:n},r.event.id))})]})}function te({api:a,seg:e,options:n}){var s;const{event:r}=e;return t.jsx("div",{"data-rsv":"event","data-event-id":r.id,role:"button",tabIndex:0,style:`position:absolute;left:${e.leftPct}%;width:${e.widthPct}%;top:${e.lane*R}rem;height:${R-.2}rem;--rsv-event-bg:${r.backgroundColor};--rsv-event-fg:${r.textColor}`,onClick:()=>a.trigger("eventClick",{event:r}),children:S((s=n.slots)==null?void 0:s.eventContent,{event:r,isAllDay:r.allDay,timeText:""},r.title)})}const De=1.6;function re({api:a,model:e,options:n}){return t.jsxs("div",{"data-rsv":"resource-timeline",children:[t.jsxs("div",{"data-rsv":"rt-header",role:"row",children:[t.jsx("div",{"data-rsv":"resource-area-header",children:n.locale==="es"?"Recursos":"Resources"}),t.jsx("div",{"data-rsv":"tl-axis",children:e.slots.map(r=>t.jsx("div",{"data-rsv":"tl-slot",style:`left:${r.leftPct}%`,children:r.label},r.leftPct))})]}),e.lanes.map(r=>{const s=r.laneCount*De+.4;return t.jsxs("div",{"data-rsv":"resource-row",role:"row",children:[t.jsxs("div",{"data-rsv":"resource-label",style:`padding-inline-start:${.5+r.row.depth*1}rem`,children:[r.row.hasChildren&&t.jsx("button",{type:"button","data-rsv":"resource-toggle","aria-expanded":r.row.expanded,onClick:()=>a.toggleResource(r.row.resource.id),children:r.row.expanded?"▾":"▸"}),t.jsx("span",{"data-rsv":"resource-title",children:r.row.resource.title})]}),t.jsx("div",{"data-rsv":"resource-lane",style:`height:${s}rem`,children:r.segs.map(i=>t.jsx(te,{api:a,seg:i,options:n},i.event.id))})]},r.row.resource.id)})]})}function ne({api:a,model:e,options:n}){const r=`calc(var(--spacing-rsv-slot, 2.5rem) * ${e.slots.length})`;return t.jsxs("div",{"data-rsv":"timegrid",style:`--rsv-tg-days:${e.columns.length}`,children:[t.jsxs("div",{"data-rsv":"tg-header",role:"row",children:[t.jsx("div",{"data-rsv":"tg-axis-corner"}),e.columns.map(s=>t.jsx("div",{"data-rsv":"tg-col-header",role:"columnheader",children:s.row.resource.title},s.row.resource.id))]}),t.jsxs("div",{"data-rsv":"tg-allday",role:"row",children:[t.jsx("div",{"data-rsv":"tg-axis-label",children:o.getLocaleText(n.locale).allDay}),e.columns.map(s=>t.jsx("div",{"data-rsv":"tg-allday-cell",children:s.allDayEvents.map(i=>t.jsx("div",{"data-rsv":"event","data-all-day":"true",style:`--rsv-event-bg:${i.backgroundColor}`,onClick:()=>a.trigger("eventClick",{event:i}),children:i.title},i.id))},s.row.resource.id))]}),t.jsxs("div",{"data-rsv":"tg-body",children:[t.jsx("div",{"data-rsv":"tg-axis",style:`height:${r}`,children:e.slots.map(s=>t.jsx("div",{"data-rsv":"tg-slot","data-major":String(s.isMajor),children:t.jsx("span",{"data-rsv":"tg-slot-label",children:s.label})},s.offsetMin))}),e.columns.map(s=>t.jsxs("div",{"data-rsv":"tg-col","data-rsv-resource-id":s.row.resource.id,style:`height:${r}`,children:[s.timedSegs.map(i=>{const u=100/i.colCount;return t.jsxs("div",{"data-rsv":"event","data-all-day":"false","data-event-id":i.event.id,role:"button",tabIndex:0,style:`position:absolute;top:${i.topPct}%;height:${i.heightPct}%;left:${i.col*u}%;width:${u}%;--rsv-event-bg:${i.event.backgroundColor};--rsv-event-fg:${i.event.textColor}`,onClick:d=>{d.stopPropagation(),a.trigger("eventClick",{event:i.event})},children:[o.dl.format(i.event.start,"HH:mm")," ",i.event.title]},i.event.id)}),e.nowTopPct!=null&&t.jsx("div",{"data-rsv":"now-indicator",style:`top:${e.nowTopPct}%`})]},s.row.resource.id))]})]})}function ae({api:a,model:e}){return t.jsxs("div",{"data-rsv":"resource-daygrid",style:`--rsv-rdg-cols:${e.columns.length}`,children:[t.jsx("div",{"data-rsv":"rdg-header",role:"row",children:e.columns.map(n=>t.jsx("div",{"data-rsv":"rdg-col-header",role:"columnheader",children:n.row.resource.title},n.row.resource.id))}),t.jsx("div",{"data-rsv":"rdg-body",role:"row",children:e.columns.map(n=>t.jsx("div",{"data-rsv":"rdg-col","data-rsv-resource-id":n.row.resource.id,children:n.events.map(r=>t.jsxs("div",{"data-rsv":"event","data-all-day":String(r.allDay),"data-event-id":r.id,role:"button",tabIndex:0,style:`--rsv-event-bg:${r.backgroundColor};--rsv-event-fg:${r.textColor}`,onClick:()=>a.trigger("eventClick",{event:r}),children:[r.allDay?"":o.dl.format(r.start,"HH:mm")+" ",r.title]},r.id))},n.row.resource.id))})]})}function se({api:a,options:e}){var i;const n=a.viewModel.value,r=e.direction??o.getLocaleText(e.locale).direction,s=e.themeTokens?o.themeToStyle(e.themeTokens):void 0;return t.jsxs("div",{"data-rsv":"root",dir:r,"data-rsv-theme":e.theme,style:s,class:C((i=e.classNames)==null?void 0:i.root),children:[e.headerToolbar!==!1&&t.jsx(W,{api:a,title:n.title,activeView:n.type,options:e}),t.jsx("div",{"data-rsv":"view","data-view":n.type,children:n.dayGrid?t.jsx(F,{api:a,model:n.dayGrid,options:e}):n.timeGrid?t.jsx(J,{api:a,model:n.timeGrid,options:e}):n.list?t.jsx(Q,{api:a,model:n.list,options:e}):n.multiMonth?t.jsx(Z,{api:a,model:n.multiMonth,options:e}):n.resourceTimeGrid?t.jsx(ne,{api:a,model:n.resourceTimeGrid,options:e}):n.resourceDayGrid?t.jsx(ae,{api:a,model:n.resourceDayGrid,options:e}):n.resourceTimeline?t.jsx(re,{api:a,model:n.resourceTimeline,options:e}):n.timeline?t.jsx(ee,{api:a,model:n.timeline,options:e}):t.jsxs("div",{"data-rsv":"unsupported",children:['La vista "',n.type,'" se implementa en una fase posterior.']})})]})}function ke(a,e){const n=new o.CalendarApi(e);return O.render(O.h(se,{api:n,options:e}),a),{api:n,destroy(){O.render(null,a),n.destroy()}}}function Se(a,e="calendar.ics"){if(typeof document>"u")return;const n=o.eventsToICS(a),r=new Blob([n],{type:"text/calendar;charset=utf-8"}),s=URL.createObjectURL(r),i=document.createElement("a");i.href=s,i.download=e,document.body.appendChild(i),i.click(),i.remove(),URL.revokeObjectURL(s)}Object.defineProperty(exports,"dayGridPlugin",{enumerable:!0,get:()=>o.dayGridPlugin});Object.defineProperty(exports,"definePlugin",{enumerable:!0,get:()=>o.definePlugin});Object.defineProperty(exports,"defineTheme",{enumerable:!0,get:()=>o.defineTheme});Object.defineProperty(exports,"eventsToICS",{enumerable:!0,get:()=>o.eventsToICS});Object.defineProperty(exports,"listPlugin",{enumerable:!0,get:()=>o.listPlugin});Object.defineProperty(exports,"multiMonthPlugin",{enumerable:!0,get:()=>o.multiMonthPlugin});Object.defineProperty(exports,"parseICS",{enumerable:!0,get:()=>o.parseICS});Object.defineProperty(exports,"resourcePlugin",{enumerable:!0,get:()=>o.resourcePlugin});Object.defineProperty(exports,"themeToStyle",{enumerable:!0,get:()=>o.themeToStyle});Object.defineProperty(exports,"timeGridPlugin",{enumerable:!0,get:()=>o.timeGridPlugin});Object.defineProperty(exports,"timelinePlugin",{enumerable:!0,get:()=>o.timelinePlugin});exports.Calendar=se;exports.DayGridView=F;exports.ListView=Q;exports.MultiMonthView=Z;exports.ResourceDayGridView=ae;exports.ResourceTimeGridView=ne;exports.ResourceTimelineView=re;exports.TimeGridView=J;exports.TimelineView=ee;exports.Toolbar=W;exports.cx=C;exports.downloadICS=Se;exports.handleEventKeydown=G;exports.mount=ke;exports.renderSlot=S;exports.startEventDrag=I;
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","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","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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"}
@@ -0,0 +1,299 @@
1
+ import { CalendarApi } from '@reservi/core';
2
+ import { CalendarOptions } from '@reservi/core';
3
+ import { ComponentChildren } from 'preact';
4
+ import { DayGridModel } from '@reservi/core';
5
+ import { dayGridPlugin } from '@reservi/core';
6
+ import { definePlugin } from '@reservi/core';
7
+ import { defineTheme } from '@reservi/core';
8
+ import { EventDef } from '@reservi/core';
9
+ import { EventInput } from '@reservi/core';
10
+ import { eventsToICS } from '@reservi/core';
11
+ import { ListModel } from '@reservi/core';
12
+ import { listPlugin } from '@reservi/core';
13
+ import { MultiMonthModel } from '@reservi/core';
14
+ import { multiMonthPlugin } from '@reservi/core';
15
+ import { parseICS } from '@reservi/core';
16
+ import { ReserviThemeTokens } from '@reservi/core';
17
+ import { ResizeEdge } from '@reservi/core';
18
+ import { ResourceDayGridModel } from '@reservi/core';
19
+ import { ResourceInput } from '@reservi/core';
20
+ import { resourcePlugin } from '@reservi/core';
21
+ import { ResourceTimeGridModel } from '@reservi/core';
22
+ import { ResourceTimelineModel } from '@reservi/core';
23
+ import { themeToStyle } from '@reservi/core';
24
+ import { TimeGridModel } from '@reservi/core';
25
+ import { timeGridPlugin } from '@reservi/core';
26
+ import { TimelineModel } from '@reservi/core';
27
+ import { timelinePlugin } from '@reservi/core';
28
+ import { VNode } from 'preact';
29
+
30
+ /** Componente raíz: lee el ViewModel reactivo y delega en la vista activa. */
31
+ export declare function Calendar({ api, options }: CalendarProps): VNode;
32
+
33
+ export { CalendarApi }
34
+
35
+ export { CalendarOptions }
36
+
37
+ declare interface CalendarProps {
38
+ api: CalendarApi;
39
+ options: ReserviCalendarOptions;
40
+ }
41
+
42
+ /** Une clases base con las del usuario (filtra vacíos). */
43
+ export declare function cx(...classes: (string | undefined | false)[]): string;
44
+
45
+ /** Argumento del slot de celda de día. */
46
+ export declare interface DayCellContentArg {
47
+ date: Date;
48
+ dayNumber: number;
49
+ isToday: boolean;
50
+ isOther: boolean;
51
+ }
52
+
53
+ export { dayGridPlugin }
54
+
55
+ /** Vista de cuadrícula por días (mes/semana/día/año). */
56
+ export declare function DayGridView({ api, model, options }: DayGridViewProps): VNode;
57
+
58
+ declare interface DayGridViewProps {
59
+ api: CalendarApi;
60
+ model: DayGridModel;
61
+ options: ReserviCalendarOptions;
62
+ }
63
+
64
+ /** Argumento del slot de cabecera de día (nombre del día de la semana). */
65
+ export declare interface DayHeaderContentArg {
66
+ date: Date;
67
+ text: string;
68
+ }
69
+
70
+ export { definePlugin }
71
+
72
+ export { defineTheme }
73
+
74
+ /**
75
+ * Exporta eventos a un archivo `.ics` y dispara la descarga en el navegador.
76
+ * Capa de UI (usa DOM); la serialización pura vive en `@reservi/core`.
77
+ */
78
+ export declare function downloadICS(events: EventInput[], filename?: string): void;
79
+
80
+ declare interface DragOptions {
81
+ api: CalendarApi;
82
+ event: EventDef;
83
+ model: TimeGridModel;
84
+ columnEl: HTMLElement;
85
+ snap?: string | undefined;
86
+ /** Si se indica, redimensiona por ese borde; si no, mueve el evento. */
87
+ edge?: ResizeEdge | undefined;
88
+ }
89
+
90
+ /** Argumento del slot de contenido de evento. */
91
+ export declare interface EventContentArg {
92
+ event: EventDef;
93
+ isAllDay: boolean;
94
+ /** Texto de hora ya formateado (vacío si allDay). */
95
+ timeText: string;
96
+ }
97
+
98
+ export { EventDef }
99
+
100
+ export { EventInput }
101
+
102
+ export { eventsToICS }
103
+
104
+ export declare type GridKind = "dayGrid" | "timeGrid";
105
+
106
+ export declare function handleEventKeydown(e: KeyboardEvent, opts: KeydownOptions): void;
107
+
108
+ declare interface KeydownOptions {
109
+ api: CalendarApi;
110
+ event: EventDef;
111
+ kind: GridKind;
112
+ snap?: string | undefined;
113
+ }
114
+
115
+ export { listPlugin }
116
+
117
+ /** Vista de agenda en lista (listDay/Week/Month/Year). */
118
+ export declare function ListView({ api, model, options }: ListViewProps): VNode;
119
+
120
+ declare interface ListViewProps {
121
+ api: CalendarApi;
122
+ model: ListModel;
123
+ options: ReserviCalendarOptions;
124
+ }
125
+
126
+ /**
127
+ * Monta un calendario Reservi en un elemento del DOM. API agnóstica usada
128
+ * directamente (vanilla/Preact) y por los wrappers de framework.
129
+ */
130
+ export declare function mount(el: HTMLElement, options: ReserviCalendarOptions): ReserviCalendarHandle;
131
+
132
+ export { multiMonthPlugin }
133
+
134
+ /** Vista de varios meses (año): rejilla responsive de cuadrículas mensuales. */
135
+ export declare function MultiMonthView({ api, model, options }: MultiMonthViewProps): VNode;
136
+
137
+ declare interface MultiMonthViewProps {
138
+ api: CalendarApi;
139
+ model: MultiMonthModel;
140
+ options: ReserviCalendarOptions;
141
+ }
142
+
143
+ export { parseICS }
144
+
145
+ declare interface Props {
146
+ api: CalendarApi;
147
+ model: ResourceTimeGridModel;
148
+ options: ReserviCalendarOptions;
149
+ }
150
+
151
+ declare interface Props_2 {
152
+ api: CalendarApi;
153
+ model: ResourceDayGridModel;
154
+ options: ReserviCalendarOptions;
155
+ }
156
+
157
+ /**
158
+ * Resuelve un slot de contenido: si el usuario aportó una función, usa su
159
+ * resultado; si no, usa el contenido por defecto. Unifica el contrato de los
160
+ * render hooks para todos los frameworks (en wrappers se adapta a su idioma).
161
+ */
162
+ export declare function renderSlot<Arg>(slot: ((arg: Arg) => SlotResult) | undefined, arg: Arg, fallback: ComponentChildren): ComponentChildren;
163
+
164
+ export declare interface ReserviCalendarHandle {
165
+ /** API del calendario (navegación, eventos, callbacks). */
166
+ readonly api: CalendarApi;
167
+ /** Desmonta el calendario y libera recursos. */
168
+ destroy(): void;
169
+ }
170
+
171
+ /** Opciones de la capa Preact = opciones de núcleo + presentación. */
172
+ export declare interface ReserviCalendarOptions extends CalendarOptions {
173
+ slots?: ReserviSlots;
174
+ classNames?: ReserviClassNames;
175
+ /**
176
+ * Vistas a mostrar como pestañas en la segunda fila de la toolbar
177
+ * (p. ej. ["dayGridMonth", "timeGridWeek", "listWeek"]). Si se omite, se
178
+ * derivan de los tokens de `headerToolbar`; si tampoco hay, no se muestra la fila.
179
+ */
180
+ views?: string[];
181
+ /**
182
+ * Callback del botón "Añadir". Solo si se define se renderiza el botón; el
183
+ * anfitrión decide qué ocurre al pulsarlo (abrir un modal, navegar, etc.).
184
+ */
185
+ onAddClick?: () => void;
186
+ /** Texto del botón "Añadir" (def. "+" sin etiqueta). */
187
+ addButtonText?: string;
188
+ }
189
+
190
+ /** Clases por slot, fusionadas con las base. */
191
+ export declare interface ReserviClassNames {
192
+ root?: string;
193
+ toolbar?: string;
194
+ day?: string;
195
+ event?: string;
196
+ }
197
+
198
+ /**
199
+ * Slots de render (patrón de "content" de FullCalendar). En fases posteriores
200
+ * se añaden los hooks *DidMount/*WillUnmount y el resto de elementos (PARITY §11).
201
+ */
202
+ export declare interface ReserviSlots {
203
+ eventContent?: (arg: EventContentArg) => SlotResult;
204
+ dayCellContent?: (arg: DayCellContentArg) => SlotResult;
205
+ dayHeaderContent?: (arg: DayHeaderContentArg) => SlotResult;
206
+ /** Personaliza la etiqueta del eje horario (timeGrid). */
207
+ slotLabelContent?: (arg: SlotLabelContentArg) => SlotResult;
208
+ /**
209
+ * Contenido libre al inicio de la toolbar (zona "Filtrar/Personal" del diseño).
210
+ * El usuario decide qué botones poner y qué hacen; si no se define, no se
211
+ * renderiza nada en esa zona.
212
+ */
213
+ toolbarStart?: () => SlotResult;
214
+ /**
215
+ * Contenido libre al final de la toolbar, antes del botón "Añadir".
216
+ * Útil para acciones extra propias del anfitrión.
217
+ */
218
+ toolbarEnd?: () => SlotResult;
219
+ }
220
+
221
+ export { ReserviThemeTokens }
222
+
223
+ /** Recursos como columnas en cuadrícula de día (eventos apilados por recurso). */
224
+ export declare function ResourceDayGridView({ api, model }: Props_2): VNode;
225
+
226
+ export { ResourceInput }
227
+
228
+ export { resourcePlugin }
229
+
230
+ /** Vista vertical de recursos: recursos como columnas sobre un eje de tiempo. */
231
+ export declare function ResourceTimeGridView({ api, model, options }: Props): VNode;
232
+
233
+ /** Vista resource-timeline (Scheduler): filas de recursos × eje temporal. */
234
+ export declare function ResourceTimelineView({ api, model, options }: ResourceTimelineViewProps): VNode;
235
+
236
+ declare interface ResourceTimelineViewProps {
237
+ api: CalendarApi;
238
+ model: ResourceTimelineModel;
239
+ options: ReserviCalendarOptions;
240
+ }
241
+
242
+ /** Argumento del slot de etiqueta del eje horario (timeGrid). */
243
+ export declare interface SlotLabelContentArg {
244
+ /** Texto ya formateado (p. ej. "09:00"). */
245
+ text: string;
246
+ /** Minutos desde medianoche del slot. */
247
+ minutes: number;
248
+ /** Si es una marca mayor (etiquetada). */
249
+ isMajor: boolean;
250
+ }
251
+
252
+ export declare type SlotResult = ComponentChildren | string;
253
+
254
+ export declare function startEventDrag(ev: PointerEvent, options: DragOptions): void;
255
+
256
+ export { themeToStyle }
257
+
258
+ export { timeGridPlugin }
259
+
260
+ /** Vista con eje temporal vertical (semana/día). */
261
+ export declare function TimeGridView({ api, model, options }: TimeGridViewProps): VNode;
262
+
263
+ declare interface TimeGridViewProps {
264
+ api: CalendarApi;
265
+ model: TimeGridModel;
266
+ options: ReserviCalendarOptions;
267
+ }
268
+
269
+ export { timelinePlugin }
270
+
271
+ /** Vista timeline: eje temporal horizontal con eventos apilados en carriles. */
272
+ export declare function TimelineView({ api, model, options }: TimelineViewProps): VNode;
273
+
274
+ declare interface TimelineViewProps {
275
+ api: CalendarApi;
276
+ model: TimelineModel;
277
+ options: ReserviCalendarOptions;
278
+ }
279
+
280
+ /**
281
+ * Toolbar de dos filas:
282
+ * - Fila 1: slot de inicio (Filtrar/Personal del anfitrión) · navegación
283
+ * (hoy ‹ título ›) · slot de fin + botón "Añadir" (opcional, vía props).
284
+ * - Fila 2: pestañas de vista.
285
+ *
286
+ * El título abre un datepicker para saltar de fecha. En vistas de mes/año la
287
+ * rejilla elige MES; en el resto (semana/día/lista) elige DÍA. Se abre también
288
+ * con Ctrl+M y se cierra con Esc o clic fuera.
289
+ */
290
+ export declare function Toolbar({ api, title, activeView, options }: ToolbarProps): VNode;
291
+
292
+ declare interface ToolbarProps {
293
+ api: CalendarApi;
294
+ title: string;
295
+ activeView: string;
296
+ options: ReserviCalendarOptions;
297
+ }
298
+
299
+ export { }