ape-calendar 0.2.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/README.md +43 -0
- package/dist/index.cjs +2 -0
- package/dist/index.d.cts +330 -0
- package/dist/index.d.ts +330 -0
- package/dist/index.js +2 -0
- package/dist/style.css +2 -0
- package/package.json +81 -0
package/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# ape-calendar
|
|
2
|
+
|
|
3
|
+
FullCalendar + react-day-picker based React calendar suite. Self-contained: ships its own Radix Popover primitive, no external UI library required.
|
|
4
|
+
|
|
5
|
+
> **Status:** scaffold. Components are migrated package-by-package from `cms-portal`. See the monorepo README for progress.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install ape-calendar
|
|
11
|
+
# peer deps
|
|
12
|
+
npm install react react-dom
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Import the stylesheet once at the app root:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import 'ape-calendar/style.css'
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage (planned)
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { MacroCalendar, MiniMonthCalendar, useCalendarState } from 'ape-calendar'
|
|
25
|
+
|
|
26
|
+
const { state, actions } = useCalendarState()
|
|
27
|
+
|
|
28
|
+
<MacroCalendar
|
|
29
|
+
events={events}
|
|
30
|
+
activeView={state.activeView}
|
|
31
|
+
selectedDate={state.selectedDate}
|
|
32
|
+
locale="es-CO"
|
|
33
|
+
onEditEvent={openForm}
|
|
34
|
+
onDeleteEvent={confirmDelete}
|
|
35
|
+
onEventTimeChange={({ event, startAt, endAt, revert }) =>
|
|
36
|
+
updateApi(event.id, { startAt, endAt }).catch(revert)
|
|
37
|
+
}
|
|
38
|
+
/>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Companion package
|
|
42
|
+
|
|
43
|
+
For event creation/edit forms, install [`ape-calendar-form`](https://www.npmjs.com/package/ape-calendar-form).
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var Ce=Object.create;var tt=Object.defineProperty;var Se=Object.getOwnPropertyDescriptor;var Pe=Object.getOwnPropertyNames;var be=Object.getPrototypeOf,De=Object.prototype.hasOwnProperty;var xe=(t,e)=>{for(var a in e)tt(t,a,{get:e[a],enumerable:!0})},St=(t,e,a,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Pe(e))!De.call(t,r)&&r!==a&&tt(t,r,{get:()=>e[r],enumerable:!(n=Se(e,r))||n.enumerable});return t};var h=(t,e,a)=>(a=t!=null?Ce(be(t)):{},St(e||!t||!t.__esModule?tt(a,"default",{value:t,enumerable:!0}):a,t)),_e=t=>St(tt({},"__esModule",{value:!0}),t);var $e={};xe($e,{APE_CALENDAR_ROOT_CLASS:()=>N,Button:()=>z,CalendarToolbar:()=>te,DayEventDot:()=>pt,EmptyEventsState:()=>se,EventBlockContent:()=>nt,EventChipMonth:()=>it,EventChipPopover:()=>st,EventStatusBadge:()=>G,EventTypeChip:()=>ae,MacroCalendar:()=>Ut,MiniMonthCalendar:()=>Xt,MoreEventsPopover:()=>lt,Popover:()=>w,PopoverAnchor:()=>K,PopoverClose:()=>wt,PopoverContent:()=>T,PopoverPortal:()=>Lt,PopoverTrigger:()=>rt,SlotContextActions:()=>ee,formatDurationLabel:()=>xt,formatHourLabel:()=>P,getEventDayKeys:()=>bt,getEventDayStatuses:()=>Dt,isSameDay:()=>Pt,mapEventToCalendarInput:()=>et,toDayKey:()=>A});module.exports=_e($e);var f=require("react"),Ot=h(require("@fullcalendar/react"),1),It=h(require("@fullcalendar/daygrid"),1),Ft=h(require("@fullcalendar/timegrid"),1),zt=h(require("@fullcalendar/interaction"),1),Ht=h(require("@fullcalendar/core/locales/es"),1),$t=require("motion/react"),Vt=require("lucide-react"),Gt=h(require("clsx"),1);var A=t=>{let e=t.getFullYear(),a=`${t.getMonth()+1}`.padStart(2,"0"),n=`${t.getDate()}`.padStart(2,"0");return`${e}-${a}-${n}`},Pt=(t,e)=>A(t)===A(e),bt=t=>new Set(t.map(e=>A(e.startDate))),Dt=t=>t.reduce((e,a)=>{if(!a.status)return e;let n=A(a.startDate),r=e.get(n)??[];return r.includes(a.status)||e.set(n,[...r,a.status]),e},new Map),et=t=>({id:t.id,title:t.title,start:t.startAt,end:t.endAt,allDay:t.isAllDay??!1,extendedProps:{status:t.status,location:t.location,description:t.description,durationMinutes:t.durationMinutes}}),P=(t,e="es-CO",a={hour:"2-digit",minute:"2-digit",hour12:!1})=>t.toLocaleTimeString(e,a),xt=(t,e={})=>{let a=e.min??"min",n=e.h??"h";if(t<60)return`${t} ${a}`;let r=Math.floor(t/60),s=t%60;return s===0?`${r} ${n}`:`${r} ${n} ${s} ${a}`};var N="ape-calendar";var L=require("react");var Nt=require("react/jsx-runtime"),_t=(0,L.createContext)(null),Mt=()=>(0,L.useContext)(_t);function ot({children:t}){let[e,a]=(0,L.useState)(null);return(0,L.useEffect)(()=>{if(typeof document>"u")return;let n=document.createElement("div");return n.className=N,n.dataset.apeCalendarPortalRoot="true",document.body.appendChild(n),a(n),()=>{n.parentNode&&n.parentNode.removeChild(n)}},[]),(0,Nt.jsx)(_t.Provider,{value:e,children:t})}var U=require("lucide-react");var at=require("lucide-react"),At=h(require("clsx"),1),I=require("react/jsx-runtime"),Me={draft:(0,I.jsx)("span",{className:"cal-status-badge__dot","data-status":"draft"}),published:(0,I.jsx)(at.Rocket,{size:11,"aria-hidden":!0}),scheduled:(0,I.jsx)(at.CalendarClock,{size:11,"aria-hidden":!0}),archived:(0,I.jsx)("span",{className:"cal-status-badge__dot","data-status":"archived"})},Ne=t=>t.charAt(0).toUpperCase()+t.slice(1),G=({status:t,labels:e,icons:a,className:n})=>{let r=e?.[t]??Ne(t),s=a?.[t]??Me[t];return(0,I.jsxs)("span",{className:(0,At.default)("cal-status-badge",n),"data-status":t,children:[s,r]})};var C=require("react/jsx-runtime"),Ae={edit:t=>`Edit event ${t}`,delete:t=>`Delete event ${t}`},nt=({event:t,onEdit:e,onDelete:a,locale:n="es-CO",statusLabels:r,messages:s})=>{let i={...Ae,...s},g=t.status??"";return(0,C.jsxs)("article",{className:"cal-event-block","data-status":g,children:[(0,C.jsx)("div",{className:"cal-event-block__header",children:t.status&&(0,C.jsx)(G,{status:t.status,labels:r})}),(0,C.jsx)("p",{className:"cal-event-block__title",children:t.title}),(0,C.jsxs)("p",{className:"cal-event-block__time",children:[(0,C.jsx)(U.Clock,{size:10,"aria-hidden":!0}),(0,C.jsxs)("span",{children:[P(t.startDate,n)," -"," ",P(t.endDate,n)]})]}),(0,C.jsxs)("div",{className:"cal-event-block__actions",children:[(0,C.jsx)("button",{type:"button","aria-label":i.edit(t.title),onClick:c=>{c.stopPropagation(),e(t)},className:"cal-event-block__action-button",children:(0,C.jsx)(U.SquarePen,{size:11})}),(0,C.jsx)("button",{type:"button","aria-label":i.delete(t.title),onClick:c=>{c.stopPropagation(),a(t)},className:"cal-event-block__action-button cal-event-block__action-button--danger",children:(0,C.jsx)(U.Trash2,{size:11})})]})]})};var R=require("lucide-react");var b=h(require("@radix-ui/react-popover"),1),Tt=require("react"),kt=h(require("clsx"),1);var ft=require("react/jsx-runtime"),w=b.Root,rt=b.Trigger,K=b.Anchor,Lt=b.Portal,wt=b.Close,T=(0,Tt.forwardRef)(({className:t,align:e="center",sideOffset:a=4,...n},r)=>{let s=Mt();return(0,ft.jsx)(b.Portal,{container:s??void 0,children:(0,ft.jsx)(b.Content,{ref:r,align:e,sideOffset:a,className:(0,kt.default)("cal-popover-content",t),...n})})});T.displayName="PopoverContent";var p=require("react/jsx-runtime"),Te={weekday:"long",day:"2-digit",month:"long"},ke={edit:"Edit",delete:"Delete",editAria:t=>`Edit event ${t}`,deleteAria:t=>`Delete event ${t}`},st=({event:t,onEdit:e,onDelete:a,children:n,locale:r="es-CO",statusLabels:s,renderEventMeta:i,messages:g,dayHeaderOptions:c})=>{let E={...ke,...g},M=new Intl.DateTimeFormat(r,c??Te).format(t.startDate),O=`${P(t.startDate,r)} \u2013 ${P(t.endDate,r)}`;return(0,p.jsxs)(w,{children:[(0,p.jsx)(rt,{asChild:!0,children:n}),(0,p.jsxs)(T,{align:"start",sideOffset:6,collisionPadding:12,className:"cal-chip-popover",onClick:d=>d.stopPropagation(),children:[(0,p.jsxs)("header",{className:"cal-chip-popover__header",children:[(0,p.jsxs)("div",{className:"cal-chip-popover__header-info",children:[(0,p.jsx)("p",{className:"cal-chip-popover__day",children:M}),(0,p.jsx)("h3",{className:"cal-chip-popover__title",children:t.title})]}),t.status&&(0,p.jsx)(G,{status:t.status,labels:s})]}),(0,p.jsxs)("dl",{className:"cal-chip-popover__meta",children:[(0,p.jsxs)("div",{className:"cal-chip-popover__meta-row",children:[(0,p.jsx)(R.Clock,{size:12,"aria-hidden":!0}),(0,p.jsx)("span",{children:O})]}),i&&(0,p.jsx)("div",{className:"cal-chip-popover__meta-row cal-chip-popover__meta-row--wrap",children:i(t)}),t.location&&(0,p.jsxs)("div",{className:"cal-chip-popover__meta-row cal-chip-popover__meta-row--start",children:[(0,p.jsx)(R.MapPin,{size:12,"aria-hidden":!0}),(0,p.jsx)("span",{className:"cal-chip-popover__clamp-2",children:t.location})]})]}),t.description&&(0,p.jsx)("p",{className:"cal-chip-popover__description",children:t.description}),(0,p.jsxs)("footer",{className:"cal-chip-popover__footer",children:[(0,p.jsxs)("button",{type:"button","aria-label":E.editAria(t.title),onClick:d=>{d.stopPropagation(),e(t)},className:"cal-chip-popover__action",children:[(0,p.jsx)(R.SquarePen,{size:12}),E.edit]}),(0,p.jsxs)("button",{type:"button","aria-label":E.deleteAria(t.title),onClick:d=>{d.stopPropagation(),a(t)},className:"cal-chip-popover__action cal-chip-popover__action--danger",children:[(0,p.jsx)(R.Trash2,{size:12}),E.delete]})]})]})]})};var F=require("react/jsx-runtime"),it=({event:t,onEdit:e,onDelete:a,locale:n="es-CO",statusLabels:r,renderEventMeta:s,messages:i,triggerAria:g=c=>`Show event details ${c}`})=>{let c=P(t.startDate,n),E=t.status??"";return(0,F.jsx)(st,{event:t,onEdit:e,onDelete:a,locale:n,statusLabels:r,renderEventMeta:s,messages:i,children:(0,F.jsxs)("button",{type:"button","aria-label":g(t.title),onClick:D=>D.stopPropagation(),className:"cal-chip-month","data-status":E,children:[(0,F.jsx)("span",{className:"cal-chip-month__dot","aria-hidden":!0}),(0,F.jsx)("span",{className:"cal-chip-month__time",children:c}),(0,F.jsx)("span",{className:"cal-chip-month__title",children:t.title})]})})};var Rt=require("react"),q=require("lucide-react");var v=require("react/jsx-runtime"),Le={weekday:"long",day:"2-digit",month:"long"},we={header:t=>`${t} events in this slot`,editAria:t=>`Edit event ${t}`,deleteAria:t=>`Delete event ${t}`},Re=({events:t,anchor:e,open:a,onOpenChange:n,onEdit:r,onDelete:s,locale:i="es-CO",messages:g,dayHeaderOptions:c})=>{let E=(0,Rt.useMemo)(()=>({current:e}),[e]),D={...we,...g},O=new Intl.DateTimeFormat(i,c??Le).format(t[0].startDate);return(0,v.jsxs)(w,{open:a,onOpenChange:n,children:[(0,v.jsx)(K,{virtualRef:E}),(0,v.jsxs)(T,{align:"start",sideOffset:6,collisionPadding:12,className:"cal-more-popover",onClick:d=>d.stopPropagation(),children:[(0,v.jsxs)("header",{className:"cal-more-popover__header",children:[(0,v.jsx)("p",{className:"cal-more-popover__day",children:O}),(0,v.jsx)("h3",{className:"cal-more-popover__title",children:D.header(t.length)})]}),(0,v.jsx)("ul",{className:"cal-more-popover__list",children:t.map(d=>(0,v.jsxs)("li",{className:"cal-more-popover__item",children:[(0,v.jsx)("span",{className:"cal-more-popover__dot","data-status":d.status??"","aria-hidden":!0}),(0,v.jsxs)("div",{className:"cal-more-popover__item-body",children:[(0,v.jsx)("p",{className:"cal-more-popover__item-title",children:d.title}),(0,v.jsxs)("p",{className:"cal-more-popover__item-time",children:[(0,v.jsx)(q.Clock,{size:10,"aria-hidden":!0}),P(d.startDate,i)," \u2013"," ",P(d.endDate,i)]})]}),(0,v.jsxs)("div",{className:"cal-more-popover__item-actions",children:[(0,v.jsx)("button",{type:"button","aria-label":D.editAria(d.title),onClick:k=>{k.stopPropagation(),n(!1),r(d)},className:"cal-more-popover__action",children:(0,v.jsx)(q.SquarePen,{size:12})}),(0,v.jsx)("button",{type:"button","aria-label":D.deleteAria(d.title),onClick:k=>{k.stopPropagation(),n(!1),s(d)},className:"cal-more-popover__action cal-more-popover__action--danger",children:(0,v.jsx)(q.Trash2,{size:12})})]})]},d.id))})]})]})},lt=t=>!t.anchor||t.events.length===0?null:(0,v.jsx)(Re,{...t,anchor:t.anchor});var y=require("react/jsx-runtime"),Bt={day:"timeGridDay",week:"timeGridWeek",month:"dayGridMonth"},Be=220,Oe={moreLink:t=>`+${t} more`,allDayText:"All day",todayHeaderAria:"Today"},Ut=({events:t,activeView:e,selectedDate:a,highlightEventIds:n=[],onDeleteEvent:r,onEditEvent:s,onEventTimeChange:i,onDateClick:g,onDateSelected:c,onVisibleRangeChange:E,onSwitchToDay:D,locale:M="es-CO",fullCalendarLocale:O=Ht.default,firstDay:d=1,statusLabels:k,renderEventMeta:ut,messages:J,immutableStatuses:m,className:$})=>{let V=(0,f.useRef)(null),X=(0,f.useRef)(null),Z=(0,f.useRef)(!0),[vt,Et]=(0,f.useState)(null),Ct=(0,$t.useReducedMotion)(),gt=(0,f.useMemo)(()=>({...Oe,...J}),[J]),ie=(0,f.useMemo)(()=>new Set(n),[n]),j=(0,f.useMemo)(()=>new Map(t.map(o=>[o.id,o])),[t]),le=(0,f.useMemo)(()=>t.map(et),[t]),pe=(0,f.useMemo)(()=>new Intl.DateTimeFormat(M,{weekday:"short"}),[M]),ce=(0,f.useMemo)(()=>new Set(m??["archived"]),[m]);(0,f.useEffect)(()=>{Et(null);let o=V.current?.getApi();if(!o)return;let l=!1;return queueMicrotask(()=>{if(l)return;let u=Bt[e];o.view.type!==u&&o.changeView(u),o.getDate().toDateString()!==a.toDateString()&&o.gotoDate(a)}),()=>{l=!0}},[e,a]),(0,f.useEffect)(()=>{if(Z.current){Z.current=!1;return}Ct||!X.current||X.current.animate([{opacity:.88,transform:"translateY(5px)"},{opacity:1,transform:"translateY(0)"}],{duration:Be,easing:"cubic-bezier(0.22, 1, 0.36, 1)",fill:"both"})},[e,Ct]);let de=o=>E(o.start,o.end),me=o=>{c(o.date),g(o.date,{x:o.jsEvent.clientX,y:o.jsEvent.clientY})},ue=o=>{let l=o.jsEvent?{x:o.jsEvent.clientX,y:o.jsEvent.clientY}:{x:window.innerWidth/2,y:window.innerHeight/2};c(o.start),g(o.start,l)},ve=o=>{let l=j.get(o.event.id);return l?o.view.type==="dayGridMonth"||o.event.allDay?(0,y.jsx)(it,{event:l,onEdit:s,onDelete:r,locale:M,statusLabels:k,renderEventMeta:ut}):(0,y.jsx)(nt,{event:l,onEdit:s,onDelete:r,locale:M,statusLabels:k}):(0,y.jsx)("p",{className:"cal-event-fallback",children:o.event.title})},Ee=o=>{ie.has(o.event.id)&&(o.el.classList.add("cal-event-highlight-enter"),window.setTimeout(()=>o.el.classList.remove("cal-event-highlight-enter"),650))},ge=(o,l,u)=>{if(u)return u.toISOString();let x=new Date(l),Q=o.durationMinutes??60;return x.setMinutes(x.getMinutes()+Q),x.toISOString()},fe=o=>{let l=j.get(o.event.id),u=o.event.start;if(!l||!u){o.revert();return}i({event:l,startAt:u.toISOString(),endAt:ge(l,u,o.event.end),revert:o.revert})},he=o=>{let l=j.get(o.event.id),u=o.event.start,x=o.event.end;if(!l||!u||!x){o.revert();return}if(x<=u){o.revert();return}i({event:l,startAt:u.toISOString(),endAt:x.toISOString(),revert:o.revert})},ye=({date:o,isToday:l})=>{let u=pe.format(o).replace(".","");return(0,y.jsxs)("div",{className:"cal-day-header",children:[(0,y.jsx)("span",{className:"cal-day-header__number","data-today":l,"aria-label":l?gt.todayHeaderAria:void 0,children:o.getDate()}),(0,y.jsx)("span",{className:"cal-day-header__weekday",children:u})]})};return(0,y.jsx)(ot,{children:(0,y.jsx)("div",{className:(0,Gt.default)(N,"cal-macro-root",$),children:(0,y.jsxs)("div",{ref:X,className:"cal-macro-surface",children:[(0,y.jsx)(Vt.CalendarDays,{className:"cal-macro-corner-icon",size:20,"aria-hidden":!0}),(0,y.jsx)(Ot.default,{ref:V,plugins:[It.default,Ft.default,zt.default],locale:O,initialView:Bt[e],height:"100%",expandRows:!0,firstDay:d,allDaySlot:!1,allDayText:gt.allDayText,selectable:!0,selectMirror:!0,editable:!0,eventStartEditable:!0,eventDurationEditable:!0,eventResizableFromStart:!0,dayMaxEvents:!0,eventMaxStack:3,moreLinkContent:o=>(0,y.jsx)("span",{className:"cal-more-link",children:gt.moreLink(o.num)}),moreLinkClick:o=>{if(o.view.type==="dayGridMonth")return D(o.date),"none";let l=o.allSegs.map(Q=>j.get(Q.event.id)).filter(Q=>!!Q),u=o.jsEvent.target,x=u instanceof Element?u.closest(".fc-more-link"):null;return x&&l.length>0&&Et({events:l,anchor:x}),"none"},nowIndicator:!0,slotDuration:"01:00:00",slotLabelInterval:"01:00:00",slotLabelFormat:{hour:"2-digit",minute:"2-digit",hour12:!1},slotMinTime:"00:00:00",slotMaxTime:"24:00:00",slotEventOverlap:!1,eventMinHeight:28,eventShortHeight:48,headerToolbar:!1,events:le,eventDrop:fe,eventResize:he,eventDidMount:Ee,dragScroll:!0,eventDragMinDistance:8,dragRevertDuration:420,longPressDelay:380,selectLongPressDelay:380,eventAllow:(o,l)=>{if(!l)return!1;let u=l.extendedProps.status;return typeof u=="string"?!ce.has(u):!0},datesSet:de,dateClick:me,select:ue,dayHeaderContent:ye,eventContent:ve}),(0,y.jsx)(lt,{events:vt?.events??[],anchor:vt?.anchor??null,open:!!vt,onOpenChange:o=>{o||Et(null)},onEdit:s,onDelete:r,locale:M})]})})})};var Kt=require("react"),qt=require("react-day-picker"),Wt=require("react-day-picker/locale"),ct=require("lucide-react"),Yt=h(require("clsx"),1);var ht=h(require("clsx"),1),W=require("react/jsx-runtime"),pt=({statuses:t,isSelected:e=!1,statusColors:a,className:n,maxDots:r=2})=>t.length===0&&!e?(0,W.jsx)("span",{className:(0,ht.default)("cal-day-dot-empty",n),"aria-hidden":!0}):(0,W.jsxs)("span",{className:(0,ht.default)("cal-day-dot-row",n),"aria-hidden":!0,children:[e&&(0,W.jsx)("span",{className:"cal-day-dot cal-day-dot--selected"}),t.slice(0,r).map(s=>{let i=a?.[s];return(0,W.jsx)("span",{className:"cal-day-dot","data-status":s,style:i?{backgroundColor:i}:void 0},s)})]});var S=require("react/jsx-runtime"),Ie={previousMonth:"Previous month",nextMonth:"Next month"},Xt=({selectedDate:t,visibleMonth:e,eventDayStatuses:a,onSelectDate:n,onMonthChange:r,locale:s="es-CO",pickerLocale:i=Wt.es,messages:g,statusColors:c,className:E})=>{let D={...Ie,...g},{monthNameFormat:M,yearFormat:O,weekdayFormat:d}=(0,Kt.useMemo)(()=>({monthNameFormat:new Intl.DateTimeFormat(s,{month:"long"}),yearFormat:new Intl.DateTimeFormat(s,{year:"numeric"}),weekdayFormat:new Intl.DateTimeFormat(s,{weekday:"short"})}),[s]),k=m=>{let $=M.format(m);return`${$.charAt(0).toUpperCase()+$.slice(1)} ${O.format(m)}`},ut=()=>{let m=new Date(e);m.setMonth(m.getMonth()-1),r(m)},J=()=>{let m=new Date(e);m.setMonth(m.getMonth()+1),r(m)};return(0,S.jsx)(ot,{children:(0,S.jsxs)("div",{className:(0,Yt.default)(N,"cal-mini-root",E),children:[(0,S.jsxs)("div",{className:"cal-mini-header",children:[(0,S.jsx)("button",{type:"button","aria-label":D.previousMonth,onClick:ut,className:"cal-mini-nav-button",children:(0,S.jsx)(ct.ChevronLeft,{size:14,"aria-hidden":!0})}),(0,S.jsx)("h2",{className:"cal-mini-caption",children:k(e)}),(0,S.jsx)("button",{type:"button","aria-label":D.nextMonth,onClick:J,className:"cal-mini-nav-button",children:(0,S.jsx)(ct.ChevronRight,{size:14,"aria-hidden":!0})})]}),(0,S.jsx)(qt.DayPicker,{mode:"single",locale:i,selected:t,month:e,onMonthChange:r,formatters:{formatWeekdayName:m=>d.format(m).charAt(0).toUpperCase()},onSelect:m=>{m&&n(m)},hideNavigation:!0,captionLayout:"label",className:"cal-mini-grid",classNames:{months:"cal-mini-months",month:"cal-mini-month",month_caption:"cal-mini-month-caption",caption_label:"cal-mini-caption-label",month_grid:"cal-mini-month-grid",weekdays:"cal-mini-weekdays",weekday:"cal-mini-weekday",week:"cal-mini-week",day:"cal-mini-day",day_button:"cal-mini-day-button",outside:"cal-mini-day--outside",today:"cal-mini-day--today"},components:{DayButton:({day:m,...$})=>{let V=A(m.date),X=a.get(V)??[],Z=A(t)===V;return(0,S.jsxs)("button",{...$,children:[(0,S.jsx)("span",{children:m.date.getDate()}),(0,S.jsx)(pt,{statuses:X,isSelected:Z,statusColors:c})]})}}})]})})};var dt=require("motion/react"),yt=require("lucide-react"),jt=h(require("clsx"),1);var Qt=require("react"),Jt=h(require("clsx"),1),Y=require("react/jsx-runtime"),z=(0,Qt.forwardRef)(({variant:t="primary",size:e="md",rounded:a="md",leftIcon:n,rightIcon:r,className:s,children:i,type:g="button",...c},E)=>(0,Y.jsxs)("button",{ref:E,type:g,"data-variant":t,"data-size":e,"data-rounded":a,className:(0,Jt.default)("cal-button",s),...c,children:[n&&(0,Y.jsx)("span",{className:"cal-button__icon",children:n}),i&&(0,Y.jsx)("span",{className:"cal-button__label",children:i}),r&&(0,Y.jsx)("span",{className:"cal-button__icon",children:r})]}));z.displayName="Button";var _=require("react/jsx-runtime"),Fe={day:"Day",week:"Week",month:"Month"},Zt={groupAriaLabel:"Calendar view",newEvent:"New event"},ze=["day","week","month"],te=({activeView:t,onChangeView:e,onNewEvent:a,messages:n,className:r})=>{let s={...Fe,...n?.views},i=n?.groupAriaLabel??Zt.groupAriaLabel,g=n?.newEvent??Zt.newEvent;return(0,_.jsxs)("div",{className:(0,jt.default)(N,"cal-toolbar",r),children:[(0,_.jsx)(dt.LayoutGroup,{id:"cal-toolbar-view-tabs",children:(0,_.jsx)("div",{className:"cal-toolbar__tabs",role:"group","aria-label":i,children:ze.map(c=>{let E=t===c;return(0,_.jsxs)("button",{type:"button",onClick:()=>e(c),className:"cal-toolbar__tab","data-active":E,children:[E&&(0,_.jsx)(dt.motion.span,{layoutId:"cal-toolbar-indicator",className:"cal-toolbar__indicator",transition:{type:"spring",stiffness:380,damping:34}}),(0,_.jsxs)("span",{className:"cal-toolbar__tab-label",children:[(0,_.jsx)(yt.CalendarDays,{size:14,className:"cal-toolbar__tab-icon","aria-hidden":!0}),s[c]]})]},c)})})}),a&&(0,_.jsx)(z,{variant:"primary",size:"md",rounded:"full",onClick:a,leftIcon:(0,_.jsx)(yt.CalendarDays,{size:18,"aria-hidden":!0}),children:g})]})};var B=require("react/jsx-runtime"),He={heading:"Event actions"},ee=({state:t,actions:e,onClose:a,onSelectAction:n,messages:r})=>{if(!t.point||!t.date)return null;let s={...He,...r};return(0,B.jsxs)(w,{open:t.isOpen,onOpenChange:i=>!i&&a(),children:[(0,B.jsx)(K,{asChild:!0,children:(0,B.jsx)("span",{className:"cal-slot-anchor",style:{left:t.point.x,top:t.point.y},"aria-hidden":!0})}),(0,B.jsxs)(T,{align:"start",sideOffset:8,className:"cal-slot-popover",onEscapeKeyDown:a,children:[(0,B.jsx)("p",{className:"cal-slot-popover__heading",children:s.heading}),e.map(i=>(0,B.jsx)(z,{type:"button",variant:"ghost",size:"sm",leftIcon:i.icon,className:"cal-slot-popover__action",onClick:()=>n({type:i.type,date:t.date}),children:i.label},i.type))]})]})};var oe=h(require("clsx"),1),mt=require("react/jsx-runtime"),ae=({label:t,icon:e,className:a})=>(0,mt.jsxs)("span",{className:(0,oe.default)("cal-type-chip",a),children:[e&&(0,mt.jsx)("span",{className:"cal-type-chip__icon",children:e}),t]});var ne=require("lucide-react"),re=h(require("clsx"),1),H=require("react/jsx-runtime"),se=({title:t="No events to display",description:e="Adjust filters or create a new event to populate the calendar.",icon:a,className:n})=>(0,H.jsxs)("div",{className:(0,re.default)("cal-empty-state",n),children:[(0,H.jsx)("span",{className:"cal-empty-state__icon","aria-hidden":!0,children:a??(0,H.jsx)(ne.CalendarDays,{size:20})}),(0,H.jsx)("p",{className:"cal-empty-state__title",children:t}),(0,H.jsx)("p",{className:"cal-empty-state__description",children:e})]});0&&(module.exports={APE_CALENDAR_ROOT_CLASS,Button,CalendarToolbar,DayEventDot,EmptyEventsState,EventBlockContent,EventChipMonth,EventChipPopover,EventStatusBadge,EventTypeChip,MacroCalendar,MiniMonthCalendar,MoreEventsPopover,Popover,PopoverAnchor,PopoverClose,PopoverContent,PopoverPortal,PopoverTrigger,SlotContextActions,formatDurationLabel,formatHourLabel,getEventDayKeys,getEventDayStatuses,isSameDay,mapEventToCalendarInput,toDayKey});
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as react from 'react';
|
|
3
|
+
import { ReactNode, ButtonHTMLAttributes } from 'react';
|
|
4
|
+
import { LocaleInput, EventInput } from '@fullcalendar/core';
|
|
5
|
+
import { Locale } from 'react-day-picker';
|
|
6
|
+
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Default event status union. Consumers can pass their own string union as a
|
|
10
|
+
* generic parameter to override.
|
|
11
|
+
*/
|
|
12
|
+
type DefaultEventStatus = 'draft' | 'published' | 'scheduled' | 'archived';
|
|
13
|
+
/**
|
|
14
|
+
* Minimum shape a calendar event must satisfy. Consumers extend this interface
|
|
15
|
+
* with their own domain fields (eventType, modalities, audience, etc.) and pass
|
|
16
|
+
* the extended type as the generic parameter to calendar components.
|
|
17
|
+
*
|
|
18
|
+
* Domain-specific rendering (event type chips, modality labels) is delegated to
|
|
19
|
+
* consumer render props — the library never reads custom fields directly.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* interface MyEvent extends BaseCalendarEvent {
|
|
23
|
+
* eventType: 'workshop' | 'webinar'
|
|
24
|
+
* modalities: Array<'virtual' | 'presencial'>
|
|
25
|
+
* }
|
|
26
|
+
*/
|
|
27
|
+
interface BaseCalendarEvent<Status extends string = DefaultEventStatus> {
|
|
28
|
+
id: string;
|
|
29
|
+
title: string;
|
|
30
|
+
/** ISO 8601 timestamp */
|
|
31
|
+
startAt: string;
|
|
32
|
+
/** ISO 8601 timestamp */
|
|
33
|
+
endAt: string;
|
|
34
|
+
/** Parsed start date (for sorting, calendar rendering). */
|
|
35
|
+
startDate: Date;
|
|
36
|
+
/** Parsed end date. */
|
|
37
|
+
endDate: Date;
|
|
38
|
+
status?: Status;
|
|
39
|
+
description?: string;
|
|
40
|
+
location?: string;
|
|
41
|
+
durationMinutes?: number;
|
|
42
|
+
isAllDay?: boolean;
|
|
43
|
+
}
|
|
44
|
+
type CalendarView = 'day' | 'week' | 'month';
|
|
45
|
+
interface CalendarVisibleRange {
|
|
46
|
+
start: Date;
|
|
47
|
+
end: Date;
|
|
48
|
+
}
|
|
49
|
+
type CalendarUpdateSource = 'mini' | 'macro' | 'system';
|
|
50
|
+
interface SlotActionState {
|
|
51
|
+
isOpen: boolean;
|
|
52
|
+
date: Date | null;
|
|
53
|
+
point: {
|
|
54
|
+
x: number;
|
|
55
|
+
y: number;
|
|
56
|
+
} | null;
|
|
57
|
+
}
|
|
58
|
+
interface SlotActionPayload {
|
|
59
|
+
type: string;
|
|
60
|
+
date: Date;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Day key format `YYYY-MM-DD` used as keys for status maps.
|
|
64
|
+
*/
|
|
65
|
+
type DayKey = string;
|
|
66
|
+
/**
|
|
67
|
+
* Payload emitted when a user drags/resizes an event in the macro calendar.
|
|
68
|
+
*/
|
|
69
|
+
interface EventTimeChangePayload<E> {
|
|
70
|
+
event: E;
|
|
71
|
+
startAt: string;
|
|
72
|
+
endAt: string;
|
|
73
|
+
/** Reverts the visual change in FullCalendar. Call this if the API update fails. */
|
|
74
|
+
revert: () => void;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
interface MacroCalendarMessages {
|
|
78
|
+
moreLink?: (count: number) => string;
|
|
79
|
+
allDayText?: string;
|
|
80
|
+
todayHeaderAria?: string;
|
|
81
|
+
}
|
|
82
|
+
interface MacroCalendarProps<Status extends string, E extends BaseCalendarEvent<Status>> {
|
|
83
|
+
events: E[];
|
|
84
|
+
activeView: CalendarView;
|
|
85
|
+
selectedDate: Date;
|
|
86
|
+
/** Event IDs to briefly highlight (e.g. just-created). */
|
|
87
|
+
highlightEventIds?: string[];
|
|
88
|
+
onDeleteEvent: (event: E) => void;
|
|
89
|
+
onEditEvent: (event: E) => void;
|
|
90
|
+
onEventTimeChange: (payload: EventTimeChangePayload<E>) => void;
|
|
91
|
+
onDateClick: (date: Date, point: {
|
|
92
|
+
x: number;
|
|
93
|
+
y: number;
|
|
94
|
+
}) => void;
|
|
95
|
+
onDateSelected: (date: Date) => void;
|
|
96
|
+
onVisibleRangeChange: (start: Date, end: Date) => void;
|
|
97
|
+
onSwitchToDay: (date: Date) => void;
|
|
98
|
+
/** BCP-47 locale string (for chip/popover formatters). Default: `es-CO`. */
|
|
99
|
+
locale?: string;
|
|
100
|
+
/** FullCalendar locale object. Default: Spanish (`esLocale`). */
|
|
101
|
+
fullCalendarLocale?: LocaleInput;
|
|
102
|
+
/** First day of the week (0=Sunday, 1=Monday, etc.). Default: 1. */
|
|
103
|
+
firstDay?: number;
|
|
104
|
+
statusLabels?: Partial<Record<Status, string>>;
|
|
105
|
+
renderEventMeta?: (event: E) => ReactNode;
|
|
106
|
+
messages?: MacroCalendarMessages;
|
|
107
|
+
/** Status values that cannot be dragged. Default: `['archived']`. */
|
|
108
|
+
immutableStatuses?: Status[];
|
|
109
|
+
className?: string;
|
|
110
|
+
}
|
|
111
|
+
declare const MacroCalendar: <Status extends string, E extends BaseCalendarEvent<Status>>({ events, activeView, selectedDate, highlightEventIds, onDeleteEvent, onEditEvent, onEventTimeChange, onDateClick, onDateSelected, onVisibleRangeChange, onSwitchToDay, locale, fullCalendarLocale, firstDay, statusLabels, renderEventMeta, messages, immutableStatuses, className, }: MacroCalendarProps<Status, E>) => react_jsx_runtime.JSX.Element;
|
|
112
|
+
|
|
113
|
+
interface MiniMonthCalendarMessages {
|
|
114
|
+
previousMonth?: string;
|
|
115
|
+
nextMonth?: string;
|
|
116
|
+
}
|
|
117
|
+
interface MiniMonthCalendarProps<Status extends string = string> {
|
|
118
|
+
selectedDate: Date;
|
|
119
|
+
visibleMonth: Date;
|
|
120
|
+
/** Map of `YYYY-MM-DD` day keys to the unique statuses present that day. */
|
|
121
|
+
eventDayStatuses: Map<string, Status[]>;
|
|
122
|
+
onSelectDate: (date: Date) => void;
|
|
123
|
+
onMonthChange: (month: Date) => void;
|
|
124
|
+
/** BCP-47 locale tag for Intl date formatting (caption, weekdays). Default: `es-CO`. */
|
|
125
|
+
locale?: string;
|
|
126
|
+
/**
|
|
127
|
+
* react-day-picker locale object (different from BCP-47 string — controls
|
|
128
|
+
* the internal DayPicker rendering). Default: Spanish (`es`).
|
|
129
|
+
*/
|
|
130
|
+
pickerLocale?: Locale;
|
|
131
|
+
/** UI strings — accessibility labels for navigation buttons. */
|
|
132
|
+
messages?: MiniMonthCalendarMessages;
|
|
133
|
+
/** Optional map of status → CSS color override. Falls back to CSS vars. */
|
|
134
|
+
statusColors?: Partial<Record<Status, string>>;
|
|
135
|
+
className?: string;
|
|
136
|
+
}
|
|
137
|
+
declare const MiniMonthCalendar: <Status extends string = string>({ selectedDate, visibleMonth, eventDayStatuses, onSelectDate, onMonthChange, locale, pickerLocale, messages, statusColors, className, }: MiniMonthCalendarProps<Status>) => react_jsx_runtime.JSX.Element;
|
|
138
|
+
|
|
139
|
+
interface CalendarToolbarMessages {
|
|
140
|
+
groupAriaLabel?: string;
|
|
141
|
+
newEvent?: string;
|
|
142
|
+
views?: Partial<Record<CalendarView, string>>;
|
|
143
|
+
}
|
|
144
|
+
interface CalendarToolbarProps {
|
|
145
|
+
activeView: CalendarView;
|
|
146
|
+
onChangeView: (view: CalendarView) => void;
|
|
147
|
+
onNewEvent?: () => void;
|
|
148
|
+
messages?: CalendarToolbarMessages;
|
|
149
|
+
className?: string;
|
|
150
|
+
}
|
|
151
|
+
declare const CalendarToolbar: ({ activeView, onChangeView, onNewEvent, messages, className, }: CalendarToolbarProps) => react_jsx_runtime.JSX.Element;
|
|
152
|
+
|
|
153
|
+
interface EventChipPopoverMessages {
|
|
154
|
+
edit?: string;
|
|
155
|
+
delete?: string;
|
|
156
|
+
editAria?: (title: string) => string;
|
|
157
|
+
deleteAria?: (title: string) => string;
|
|
158
|
+
}
|
|
159
|
+
interface EventChipPopoverProps<Status extends string, E extends BaseCalendarEvent<Status>> {
|
|
160
|
+
event: E;
|
|
161
|
+
onEdit: (event: E) => void;
|
|
162
|
+
onDelete: (event: E) => void;
|
|
163
|
+
children: ReactNode;
|
|
164
|
+
locale?: string;
|
|
165
|
+
statusLabels?: Partial<Record<Status, string>>;
|
|
166
|
+
/** Optional render slot for domain-specific meta (event type, modality, etc.). */
|
|
167
|
+
renderEventMeta?: (event: E) => ReactNode;
|
|
168
|
+
messages?: EventChipPopoverMessages;
|
|
169
|
+
/**
|
|
170
|
+
* Day header format. Defaults to `{ weekday: 'long', day: '2-digit', month: 'long' }`.
|
|
171
|
+
*/
|
|
172
|
+
dayHeaderOptions?: Intl.DateTimeFormatOptions;
|
|
173
|
+
}
|
|
174
|
+
declare const EventChipPopover: <Status extends string, E extends BaseCalendarEvent<Status>>({ event, onEdit, onDelete, children, locale, statusLabels, renderEventMeta, messages, dayHeaderOptions, }: EventChipPopoverProps<Status, E>) => react_jsx_runtime.JSX.Element;
|
|
175
|
+
|
|
176
|
+
interface EventChipMonthProps<Status extends string, E extends BaseCalendarEvent<Status>> {
|
|
177
|
+
event: E;
|
|
178
|
+
onEdit: (event: E) => void;
|
|
179
|
+
onDelete: (event: E) => void;
|
|
180
|
+
locale?: string;
|
|
181
|
+
statusLabels?: Partial<Record<Status, string>>;
|
|
182
|
+
renderEventMeta?: (event: E) => ReactNode;
|
|
183
|
+
messages?: EventChipPopoverMessages;
|
|
184
|
+
/** Aria label builder for the chip button. */
|
|
185
|
+
triggerAria?: (title: string) => string;
|
|
186
|
+
}
|
|
187
|
+
declare const EventChipMonth: <Status extends string, E extends BaseCalendarEvent<Status>>({ event, onEdit, onDelete, locale, statusLabels, renderEventMeta, messages, triggerAria, }: EventChipMonthProps<Status, E>) => react_jsx_runtime.JSX.Element;
|
|
188
|
+
|
|
189
|
+
interface EventBlockContentMessages {
|
|
190
|
+
edit?: (title: string) => string;
|
|
191
|
+
delete?: (title: string) => string;
|
|
192
|
+
}
|
|
193
|
+
interface EventBlockContentProps<Status extends string, E extends BaseCalendarEvent<Status>> {
|
|
194
|
+
event: E;
|
|
195
|
+
onEdit: (event: E) => void;
|
|
196
|
+
onDelete: (event: E) => void;
|
|
197
|
+
locale?: string;
|
|
198
|
+
/** Map of status → label override for the EventStatusBadge. */
|
|
199
|
+
statusLabels?: Partial<Record<Status, string>>;
|
|
200
|
+
messages?: EventBlockContentMessages;
|
|
201
|
+
}
|
|
202
|
+
declare const EventBlockContent: <Status extends string, E extends BaseCalendarEvent<Status>>({ event, onEdit, onDelete, locale, statusLabels, messages, }: EventBlockContentProps<Status, E>) => react_jsx_runtime.JSX.Element;
|
|
203
|
+
|
|
204
|
+
interface MoreEventsPopoverMessages {
|
|
205
|
+
header?: (count: number) => string;
|
|
206
|
+
editAria?: (title: string) => string;
|
|
207
|
+
deleteAria?: (title: string) => string;
|
|
208
|
+
}
|
|
209
|
+
interface MoreEventsPopoverProps<Status extends string, E extends BaseCalendarEvent<Status>> {
|
|
210
|
+
events: E[];
|
|
211
|
+
anchor: HTMLElement | null;
|
|
212
|
+
open: boolean;
|
|
213
|
+
onOpenChange: (open: boolean) => void;
|
|
214
|
+
onEdit: (event: E) => void;
|
|
215
|
+
onDelete: (event: E) => void;
|
|
216
|
+
locale?: string;
|
|
217
|
+
messages?: MoreEventsPopoverMessages;
|
|
218
|
+
/** Day header format. Default: `{ weekday: 'long', day: '2-digit', month: 'long' }`. */
|
|
219
|
+
dayHeaderOptions?: Intl.DateTimeFormatOptions;
|
|
220
|
+
}
|
|
221
|
+
declare const MoreEventsPopover: <Status extends string, E extends BaseCalendarEvent<Status>>(props: MoreEventsPopoverProps<Status, E>) => react_jsx_runtime.JSX.Element | null;
|
|
222
|
+
|
|
223
|
+
interface SlotAction<ActionType extends string = string> {
|
|
224
|
+
/** Unique identifier for the action — emitted in the payload. */
|
|
225
|
+
type: ActionType;
|
|
226
|
+
label: string;
|
|
227
|
+
icon?: ReactNode;
|
|
228
|
+
}
|
|
229
|
+
interface SlotContextActionsMessages {
|
|
230
|
+
heading?: string;
|
|
231
|
+
}
|
|
232
|
+
interface SlotContextActionsProps<ActionType extends string = string> {
|
|
233
|
+
state: SlotActionState;
|
|
234
|
+
/** List of actions to render. Consumers define their own action set. */
|
|
235
|
+
actions: SlotAction<ActionType>[];
|
|
236
|
+
onClose: () => void;
|
|
237
|
+
onSelectAction: (payload: {
|
|
238
|
+
type: ActionType;
|
|
239
|
+
date: Date;
|
|
240
|
+
}) => void;
|
|
241
|
+
messages?: SlotContextActionsMessages;
|
|
242
|
+
}
|
|
243
|
+
declare const SlotContextActions: <ActionType extends string = string>({ state, actions, onClose, onSelectAction, messages, }: SlotContextActionsProps<ActionType>) => react_jsx_runtime.JSX.Element | null;
|
|
244
|
+
|
|
245
|
+
interface DayEventDotProps<Status extends string = string> {
|
|
246
|
+
statuses: Status[];
|
|
247
|
+
isSelected?: boolean;
|
|
248
|
+
/**
|
|
249
|
+
* Optional map of status → inline color (CSS color string). When provided,
|
|
250
|
+
* overrides the default CSS variables (`--cal-status-<status>`).
|
|
251
|
+
*/
|
|
252
|
+
statusColors?: Partial<Record<Status, string>>;
|
|
253
|
+
className?: string;
|
|
254
|
+
/** Maximum number of status dots to render (extras are omitted). Default: 2. */
|
|
255
|
+
maxDots?: number;
|
|
256
|
+
}
|
|
257
|
+
declare const DayEventDot: <Status extends string = string>({ statuses, isSelected, statusColors, className, maxDots, }: DayEventDotProps<Status>) => react_jsx_runtime.JSX.Element;
|
|
258
|
+
|
|
259
|
+
interface EventStatusBadgeProps<Status extends string = string> {
|
|
260
|
+
status: Status;
|
|
261
|
+
/** Map of status → label string. Defaults to capitalized status key. */
|
|
262
|
+
labels?: Partial<Record<Status, string>>;
|
|
263
|
+
/** Map of status → icon override. */
|
|
264
|
+
icons?: Partial<Record<Status, ReactNode>>;
|
|
265
|
+
className?: string;
|
|
266
|
+
}
|
|
267
|
+
declare const EventStatusBadge: <Status extends string = string>({ status, labels, icons, className, }: EventStatusBadgeProps<Status>) => react_jsx_runtime.JSX.Element;
|
|
268
|
+
|
|
269
|
+
interface EventTypeChipProps {
|
|
270
|
+
label: string;
|
|
271
|
+
icon?: ReactNode;
|
|
272
|
+
className?: string;
|
|
273
|
+
}
|
|
274
|
+
declare const EventTypeChip: ({ label, icon, className }: EventTypeChipProps) => react_jsx_runtime.JSX.Element;
|
|
275
|
+
|
|
276
|
+
interface EmptyEventsStateProps {
|
|
277
|
+
title?: string;
|
|
278
|
+
description?: string;
|
|
279
|
+
icon?: ReactNode;
|
|
280
|
+
className?: string;
|
|
281
|
+
}
|
|
282
|
+
declare const EmptyEventsState: ({ title, description, icon, className, }: EmptyEventsStateProps) => react_jsx_runtime.JSX.Element;
|
|
283
|
+
|
|
284
|
+
declare const Popover: react.FC<PopoverPrimitive.PopoverProps>;
|
|
285
|
+
declare const PopoverTrigger: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverTriggerProps & react.RefAttributes<HTMLButtonElement>>;
|
|
286
|
+
declare const PopoverAnchor: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverAnchorProps & react.RefAttributes<HTMLDivElement>>;
|
|
287
|
+
declare const PopoverPortal: react.FC<PopoverPrimitive.PopoverPortalProps>;
|
|
288
|
+
declare const PopoverClose: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverCloseProps & react.RefAttributes<HTMLButtonElement>>;
|
|
289
|
+
declare const PopoverContent: react.ForwardRefExoticComponent<Omit<PopoverPrimitive.PopoverContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
|
|
290
|
+
|
|
291
|
+
type ButtonVariant = 'primary' | 'secondary' | 'ghost';
|
|
292
|
+
type ButtonSize = 'sm' | 'md' | 'lg';
|
|
293
|
+
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
294
|
+
variant?: ButtonVariant;
|
|
295
|
+
size?: ButtonSize;
|
|
296
|
+
leftIcon?: ReactNode;
|
|
297
|
+
rightIcon?: ReactNode;
|
|
298
|
+
rounded?: 'md' | 'full';
|
|
299
|
+
}
|
|
300
|
+
declare const Button: react.ForwardRefExoticComponent<ButtonProps & react.RefAttributes<HTMLButtonElement>>;
|
|
301
|
+
|
|
302
|
+
declare const APE_CALENDAR_ROOT_CLASS = "ape-calendar";
|
|
303
|
+
|
|
304
|
+
declare const toDayKey: (date: Date) => DayKey;
|
|
305
|
+
declare const isSameDay: (left: Date, right: Date) => boolean;
|
|
306
|
+
/**
|
|
307
|
+
* Returns a set of day keys (YYYY-MM-DD) where at least one event starts.
|
|
308
|
+
*/
|
|
309
|
+
declare const getEventDayKeys: <E extends BaseCalendarEvent<string>>(events: E[]) => Set<DayKey>;
|
|
310
|
+
/**
|
|
311
|
+
* Returns a map of day key → unique statuses present that day. Used by the
|
|
312
|
+
* mini calendar to render status indicator dots.
|
|
313
|
+
*/
|
|
314
|
+
declare const getEventDayStatuses: <Status extends string, E extends BaseCalendarEvent<Status>>(events: E[]) => Map<DayKey, Status[]>;
|
|
315
|
+
/**
|
|
316
|
+
* Maps a calendar event to FullCalendar's EventInput shape. The full event is
|
|
317
|
+
* placed under `extendedProps.source` so handlers can recover it later via the
|
|
318
|
+
* `eventsById` map.
|
|
319
|
+
*/
|
|
320
|
+
declare const mapEventToCalendarInput: <E extends BaseCalendarEvent<string>>(event: E) => EventInput;
|
|
321
|
+
/**
|
|
322
|
+
* Locale-aware hour label (HH:MM, 24h by default).
|
|
323
|
+
*/
|
|
324
|
+
declare const formatHourLabel: (date: Date, locale?: string, options?: Intl.DateTimeFormatOptions) => string;
|
|
325
|
+
declare const formatDurationLabel: (durationMinutes: number, messages?: {
|
|
326
|
+
min?: string;
|
|
327
|
+
h?: string;
|
|
328
|
+
}) => string;
|
|
329
|
+
|
|
330
|
+
export { APE_CALENDAR_ROOT_CLASS, type BaseCalendarEvent, Button, type ButtonProps, type ButtonSize, type ButtonVariant, CalendarToolbar, type CalendarToolbarMessages, type CalendarToolbarProps, type CalendarUpdateSource, type CalendarView, type CalendarVisibleRange, DayEventDot, type DayEventDotProps, type DayKey, type DefaultEventStatus, EmptyEventsState, type EmptyEventsStateProps, EventBlockContent, type EventBlockContentMessages, type EventBlockContentProps, EventChipMonth, type EventChipMonthProps, EventChipPopover, type EventChipPopoverMessages, type EventChipPopoverProps, EventStatusBadge, type EventStatusBadgeProps, type EventTimeChangePayload, EventTypeChip, type EventTypeChipProps, MacroCalendar, type MacroCalendarMessages, type MacroCalendarProps, MiniMonthCalendar, type MiniMonthCalendarMessages, type MiniMonthCalendarProps, MoreEventsPopover, type MoreEventsPopoverMessages, type MoreEventsPopoverProps, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverPortal, PopoverTrigger, type SlotAction, type SlotActionPayload, type SlotActionState, SlotContextActions, type SlotContextActionsMessages, type SlotContextActionsProps, formatDurationLabel, formatHourLabel, getEventDayKeys, getEventDayStatuses, isSameDay, mapEventToCalendarInput, toDayKey };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as react from 'react';
|
|
3
|
+
import { ReactNode, ButtonHTMLAttributes } from 'react';
|
|
4
|
+
import { LocaleInput, EventInput } from '@fullcalendar/core';
|
|
5
|
+
import { Locale } from 'react-day-picker';
|
|
6
|
+
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Default event status union. Consumers can pass their own string union as a
|
|
10
|
+
* generic parameter to override.
|
|
11
|
+
*/
|
|
12
|
+
type DefaultEventStatus = 'draft' | 'published' | 'scheduled' | 'archived';
|
|
13
|
+
/**
|
|
14
|
+
* Minimum shape a calendar event must satisfy. Consumers extend this interface
|
|
15
|
+
* with their own domain fields (eventType, modalities, audience, etc.) and pass
|
|
16
|
+
* the extended type as the generic parameter to calendar components.
|
|
17
|
+
*
|
|
18
|
+
* Domain-specific rendering (event type chips, modality labels) is delegated to
|
|
19
|
+
* consumer render props — the library never reads custom fields directly.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* interface MyEvent extends BaseCalendarEvent {
|
|
23
|
+
* eventType: 'workshop' | 'webinar'
|
|
24
|
+
* modalities: Array<'virtual' | 'presencial'>
|
|
25
|
+
* }
|
|
26
|
+
*/
|
|
27
|
+
interface BaseCalendarEvent<Status extends string = DefaultEventStatus> {
|
|
28
|
+
id: string;
|
|
29
|
+
title: string;
|
|
30
|
+
/** ISO 8601 timestamp */
|
|
31
|
+
startAt: string;
|
|
32
|
+
/** ISO 8601 timestamp */
|
|
33
|
+
endAt: string;
|
|
34
|
+
/** Parsed start date (for sorting, calendar rendering). */
|
|
35
|
+
startDate: Date;
|
|
36
|
+
/** Parsed end date. */
|
|
37
|
+
endDate: Date;
|
|
38
|
+
status?: Status;
|
|
39
|
+
description?: string;
|
|
40
|
+
location?: string;
|
|
41
|
+
durationMinutes?: number;
|
|
42
|
+
isAllDay?: boolean;
|
|
43
|
+
}
|
|
44
|
+
type CalendarView = 'day' | 'week' | 'month';
|
|
45
|
+
interface CalendarVisibleRange {
|
|
46
|
+
start: Date;
|
|
47
|
+
end: Date;
|
|
48
|
+
}
|
|
49
|
+
type CalendarUpdateSource = 'mini' | 'macro' | 'system';
|
|
50
|
+
interface SlotActionState {
|
|
51
|
+
isOpen: boolean;
|
|
52
|
+
date: Date | null;
|
|
53
|
+
point: {
|
|
54
|
+
x: number;
|
|
55
|
+
y: number;
|
|
56
|
+
} | null;
|
|
57
|
+
}
|
|
58
|
+
interface SlotActionPayload {
|
|
59
|
+
type: string;
|
|
60
|
+
date: Date;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Day key format `YYYY-MM-DD` used as keys for status maps.
|
|
64
|
+
*/
|
|
65
|
+
type DayKey = string;
|
|
66
|
+
/**
|
|
67
|
+
* Payload emitted when a user drags/resizes an event in the macro calendar.
|
|
68
|
+
*/
|
|
69
|
+
interface EventTimeChangePayload<E> {
|
|
70
|
+
event: E;
|
|
71
|
+
startAt: string;
|
|
72
|
+
endAt: string;
|
|
73
|
+
/** Reverts the visual change in FullCalendar. Call this if the API update fails. */
|
|
74
|
+
revert: () => void;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
interface MacroCalendarMessages {
|
|
78
|
+
moreLink?: (count: number) => string;
|
|
79
|
+
allDayText?: string;
|
|
80
|
+
todayHeaderAria?: string;
|
|
81
|
+
}
|
|
82
|
+
interface MacroCalendarProps<Status extends string, E extends BaseCalendarEvent<Status>> {
|
|
83
|
+
events: E[];
|
|
84
|
+
activeView: CalendarView;
|
|
85
|
+
selectedDate: Date;
|
|
86
|
+
/** Event IDs to briefly highlight (e.g. just-created). */
|
|
87
|
+
highlightEventIds?: string[];
|
|
88
|
+
onDeleteEvent: (event: E) => void;
|
|
89
|
+
onEditEvent: (event: E) => void;
|
|
90
|
+
onEventTimeChange: (payload: EventTimeChangePayload<E>) => void;
|
|
91
|
+
onDateClick: (date: Date, point: {
|
|
92
|
+
x: number;
|
|
93
|
+
y: number;
|
|
94
|
+
}) => void;
|
|
95
|
+
onDateSelected: (date: Date) => void;
|
|
96
|
+
onVisibleRangeChange: (start: Date, end: Date) => void;
|
|
97
|
+
onSwitchToDay: (date: Date) => void;
|
|
98
|
+
/** BCP-47 locale string (for chip/popover formatters). Default: `es-CO`. */
|
|
99
|
+
locale?: string;
|
|
100
|
+
/** FullCalendar locale object. Default: Spanish (`esLocale`). */
|
|
101
|
+
fullCalendarLocale?: LocaleInput;
|
|
102
|
+
/** First day of the week (0=Sunday, 1=Monday, etc.). Default: 1. */
|
|
103
|
+
firstDay?: number;
|
|
104
|
+
statusLabels?: Partial<Record<Status, string>>;
|
|
105
|
+
renderEventMeta?: (event: E) => ReactNode;
|
|
106
|
+
messages?: MacroCalendarMessages;
|
|
107
|
+
/** Status values that cannot be dragged. Default: `['archived']`. */
|
|
108
|
+
immutableStatuses?: Status[];
|
|
109
|
+
className?: string;
|
|
110
|
+
}
|
|
111
|
+
declare const MacroCalendar: <Status extends string, E extends BaseCalendarEvent<Status>>({ events, activeView, selectedDate, highlightEventIds, onDeleteEvent, onEditEvent, onEventTimeChange, onDateClick, onDateSelected, onVisibleRangeChange, onSwitchToDay, locale, fullCalendarLocale, firstDay, statusLabels, renderEventMeta, messages, immutableStatuses, className, }: MacroCalendarProps<Status, E>) => react_jsx_runtime.JSX.Element;
|
|
112
|
+
|
|
113
|
+
interface MiniMonthCalendarMessages {
|
|
114
|
+
previousMonth?: string;
|
|
115
|
+
nextMonth?: string;
|
|
116
|
+
}
|
|
117
|
+
interface MiniMonthCalendarProps<Status extends string = string> {
|
|
118
|
+
selectedDate: Date;
|
|
119
|
+
visibleMonth: Date;
|
|
120
|
+
/** Map of `YYYY-MM-DD` day keys to the unique statuses present that day. */
|
|
121
|
+
eventDayStatuses: Map<string, Status[]>;
|
|
122
|
+
onSelectDate: (date: Date) => void;
|
|
123
|
+
onMonthChange: (month: Date) => void;
|
|
124
|
+
/** BCP-47 locale tag for Intl date formatting (caption, weekdays). Default: `es-CO`. */
|
|
125
|
+
locale?: string;
|
|
126
|
+
/**
|
|
127
|
+
* react-day-picker locale object (different from BCP-47 string — controls
|
|
128
|
+
* the internal DayPicker rendering). Default: Spanish (`es`).
|
|
129
|
+
*/
|
|
130
|
+
pickerLocale?: Locale;
|
|
131
|
+
/** UI strings — accessibility labels for navigation buttons. */
|
|
132
|
+
messages?: MiniMonthCalendarMessages;
|
|
133
|
+
/** Optional map of status → CSS color override. Falls back to CSS vars. */
|
|
134
|
+
statusColors?: Partial<Record<Status, string>>;
|
|
135
|
+
className?: string;
|
|
136
|
+
}
|
|
137
|
+
declare const MiniMonthCalendar: <Status extends string = string>({ selectedDate, visibleMonth, eventDayStatuses, onSelectDate, onMonthChange, locale, pickerLocale, messages, statusColors, className, }: MiniMonthCalendarProps<Status>) => react_jsx_runtime.JSX.Element;
|
|
138
|
+
|
|
139
|
+
interface CalendarToolbarMessages {
|
|
140
|
+
groupAriaLabel?: string;
|
|
141
|
+
newEvent?: string;
|
|
142
|
+
views?: Partial<Record<CalendarView, string>>;
|
|
143
|
+
}
|
|
144
|
+
interface CalendarToolbarProps {
|
|
145
|
+
activeView: CalendarView;
|
|
146
|
+
onChangeView: (view: CalendarView) => void;
|
|
147
|
+
onNewEvent?: () => void;
|
|
148
|
+
messages?: CalendarToolbarMessages;
|
|
149
|
+
className?: string;
|
|
150
|
+
}
|
|
151
|
+
declare const CalendarToolbar: ({ activeView, onChangeView, onNewEvent, messages, className, }: CalendarToolbarProps) => react_jsx_runtime.JSX.Element;
|
|
152
|
+
|
|
153
|
+
interface EventChipPopoverMessages {
|
|
154
|
+
edit?: string;
|
|
155
|
+
delete?: string;
|
|
156
|
+
editAria?: (title: string) => string;
|
|
157
|
+
deleteAria?: (title: string) => string;
|
|
158
|
+
}
|
|
159
|
+
interface EventChipPopoverProps<Status extends string, E extends BaseCalendarEvent<Status>> {
|
|
160
|
+
event: E;
|
|
161
|
+
onEdit: (event: E) => void;
|
|
162
|
+
onDelete: (event: E) => void;
|
|
163
|
+
children: ReactNode;
|
|
164
|
+
locale?: string;
|
|
165
|
+
statusLabels?: Partial<Record<Status, string>>;
|
|
166
|
+
/** Optional render slot for domain-specific meta (event type, modality, etc.). */
|
|
167
|
+
renderEventMeta?: (event: E) => ReactNode;
|
|
168
|
+
messages?: EventChipPopoverMessages;
|
|
169
|
+
/**
|
|
170
|
+
* Day header format. Defaults to `{ weekday: 'long', day: '2-digit', month: 'long' }`.
|
|
171
|
+
*/
|
|
172
|
+
dayHeaderOptions?: Intl.DateTimeFormatOptions;
|
|
173
|
+
}
|
|
174
|
+
declare const EventChipPopover: <Status extends string, E extends BaseCalendarEvent<Status>>({ event, onEdit, onDelete, children, locale, statusLabels, renderEventMeta, messages, dayHeaderOptions, }: EventChipPopoverProps<Status, E>) => react_jsx_runtime.JSX.Element;
|
|
175
|
+
|
|
176
|
+
interface EventChipMonthProps<Status extends string, E extends BaseCalendarEvent<Status>> {
|
|
177
|
+
event: E;
|
|
178
|
+
onEdit: (event: E) => void;
|
|
179
|
+
onDelete: (event: E) => void;
|
|
180
|
+
locale?: string;
|
|
181
|
+
statusLabels?: Partial<Record<Status, string>>;
|
|
182
|
+
renderEventMeta?: (event: E) => ReactNode;
|
|
183
|
+
messages?: EventChipPopoverMessages;
|
|
184
|
+
/** Aria label builder for the chip button. */
|
|
185
|
+
triggerAria?: (title: string) => string;
|
|
186
|
+
}
|
|
187
|
+
declare const EventChipMonth: <Status extends string, E extends BaseCalendarEvent<Status>>({ event, onEdit, onDelete, locale, statusLabels, renderEventMeta, messages, triggerAria, }: EventChipMonthProps<Status, E>) => react_jsx_runtime.JSX.Element;
|
|
188
|
+
|
|
189
|
+
interface EventBlockContentMessages {
|
|
190
|
+
edit?: (title: string) => string;
|
|
191
|
+
delete?: (title: string) => string;
|
|
192
|
+
}
|
|
193
|
+
interface EventBlockContentProps<Status extends string, E extends BaseCalendarEvent<Status>> {
|
|
194
|
+
event: E;
|
|
195
|
+
onEdit: (event: E) => void;
|
|
196
|
+
onDelete: (event: E) => void;
|
|
197
|
+
locale?: string;
|
|
198
|
+
/** Map of status → label override for the EventStatusBadge. */
|
|
199
|
+
statusLabels?: Partial<Record<Status, string>>;
|
|
200
|
+
messages?: EventBlockContentMessages;
|
|
201
|
+
}
|
|
202
|
+
declare const EventBlockContent: <Status extends string, E extends BaseCalendarEvent<Status>>({ event, onEdit, onDelete, locale, statusLabels, messages, }: EventBlockContentProps<Status, E>) => react_jsx_runtime.JSX.Element;
|
|
203
|
+
|
|
204
|
+
interface MoreEventsPopoverMessages {
|
|
205
|
+
header?: (count: number) => string;
|
|
206
|
+
editAria?: (title: string) => string;
|
|
207
|
+
deleteAria?: (title: string) => string;
|
|
208
|
+
}
|
|
209
|
+
interface MoreEventsPopoverProps<Status extends string, E extends BaseCalendarEvent<Status>> {
|
|
210
|
+
events: E[];
|
|
211
|
+
anchor: HTMLElement | null;
|
|
212
|
+
open: boolean;
|
|
213
|
+
onOpenChange: (open: boolean) => void;
|
|
214
|
+
onEdit: (event: E) => void;
|
|
215
|
+
onDelete: (event: E) => void;
|
|
216
|
+
locale?: string;
|
|
217
|
+
messages?: MoreEventsPopoverMessages;
|
|
218
|
+
/** Day header format. Default: `{ weekday: 'long', day: '2-digit', month: 'long' }`. */
|
|
219
|
+
dayHeaderOptions?: Intl.DateTimeFormatOptions;
|
|
220
|
+
}
|
|
221
|
+
declare const MoreEventsPopover: <Status extends string, E extends BaseCalendarEvent<Status>>(props: MoreEventsPopoverProps<Status, E>) => react_jsx_runtime.JSX.Element | null;
|
|
222
|
+
|
|
223
|
+
interface SlotAction<ActionType extends string = string> {
|
|
224
|
+
/** Unique identifier for the action — emitted in the payload. */
|
|
225
|
+
type: ActionType;
|
|
226
|
+
label: string;
|
|
227
|
+
icon?: ReactNode;
|
|
228
|
+
}
|
|
229
|
+
interface SlotContextActionsMessages {
|
|
230
|
+
heading?: string;
|
|
231
|
+
}
|
|
232
|
+
interface SlotContextActionsProps<ActionType extends string = string> {
|
|
233
|
+
state: SlotActionState;
|
|
234
|
+
/** List of actions to render. Consumers define their own action set. */
|
|
235
|
+
actions: SlotAction<ActionType>[];
|
|
236
|
+
onClose: () => void;
|
|
237
|
+
onSelectAction: (payload: {
|
|
238
|
+
type: ActionType;
|
|
239
|
+
date: Date;
|
|
240
|
+
}) => void;
|
|
241
|
+
messages?: SlotContextActionsMessages;
|
|
242
|
+
}
|
|
243
|
+
declare const SlotContextActions: <ActionType extends string = string>({ state, actions, onClose, onSelectAction, messages, }: SlotContextActionsProps<ActionType>) => react_jsx_runtime.JSX.Element | null;
|
|
244
|
+
|
|
245
|
+
interface DayEventDotProps<Status extends string = string> {
|
|
246
|
+
statuses: Status[];
|
|
247
|
+
isSelected?: boolean;
|
|
248
|
+
/**
|
|
249
|
+
* Optional map of status → inline color (CSS color string). When provided,
|
|
250
|
+
* overrides the default CSS variables (`--cal-status-<status>`).
|
|
251
|
+
*/
|
|
252
|
+
statusColors?: Partial<Record<Status, string>>;
|
|
253
|
+
className?: string;
|
|
254
|
+
/** Maximum number of status dots to render (extras are omitted). Default: 2. */
|
|
255
|
+
maxDots?: number;
|
|
256
|
+
}
|
|
257
|
+
declare const DayEventDot: <Status extends string = string>({ statuses, isSelected, statusColors, className, maxDots, }: DayEventDotProps<Status>) => react_jsx_runtime.JSX.Element;
|
|
258
|
+
|
|
259
|
+
interface EventStatusBadgeProps<Status extends string = string> {
|
|
260
|
+
status: Status;
|
|
261
|
+
/** Map of status → label string. Defaults to capitalized status key. */
|
|
262
|
+
labels?: Partial<Record<Status, string>>;
|
|
263
|
+
/** Map of status → icon override. */
|
|
264
|
+
icons?: Partial<Record<Status, ReactNode>>;
|
|
265
|
+
className?: string;
|
|
266
|
+
}
|
|
267
|
+
declare const EventStatusBadge: <Status extends string = string>({ status, labels, icons, className, }: EventStatusBadgeProps<Status>) => react_jsx_runtime.JSX.Element;
|
|
268
|
+
|
|
269
|
+
interface EventTypeChipProps {
|
|
270
|
+
label: string;
|
|
271
|
+
icon?: ReactNode;
|
|
272
|
+
className?: string;
|
|
273
|
+
}
|
|
274
|
+
declare const EventTypeChip: ({ label, icon, className }: EventTypeChipProps) => react_jsx_runtime.JSX.Element;
|
|
275
|
+
|
|
276
|
+
interface EmptyEventsStateProps {
|
|
277
|
+
title?: string;
|
|
278
|
+
description?: string;
|
|
279
|
+
icon?: ReactNode;
|
|
280
|
+
className?: string;
|
|
281
|
+
}
|
|
282
|
+
declare const EmptyEventsState: ({ title, description, icon, className, }: EmptyEventsStateProps) => react_jsx_runtime.JSX.Element;
|
|
283
|
+
|
|
284
|
+
declare const Popover: react.FC<PopoverPrimitive.PopoverProps>;
|
|
285
|
+
declare const PopoverTrigger: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverTriggerProps & react.RefAttributes<HTMLButtonElement>>;
|
|
286
|
+
declare const PopoverAnchor: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverAnchorProps & react.RefAttributes<HTMLDivElement>>;
|
|
287
|
+
declare const PopoverPortal: react.FC<PopoverPrimitive.PopoverPortalProps>;
|
|
288
|
+
declare const PopoverClose: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverCloseProps & react.RefAttributes<HTMLButtonElement>>;
|
|
289
|
+
declare const PopoverContent: react.ForwardRefExoticComponent<Omit<PopoverPrimitive.PopoverContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
|
|
290
|
+
|
|
291
|
+
type ButtonVariant = 'primary' | 'secondary' | 'ghost';
|
|
292
|
+
type ButtonSize = 'sm' | 'md' | 'lg';
|
|
293
|
+
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
294
|
+
variant?: ButtonVariant;
|
|
295
|
+
size?: ButtonSize;
|
|
296
|
+
leftIcon?: ReactNode;
|
|
297
|
+
rightIcon?: ReactNode;
|
|
298
|
+
rounded?: 'md' | 'full';
|
|
299
|
+
}
|
|
300
|
+
declare const Button: react.ForwardRefExoticComponent<ButtonProps & react.RefAttributes<HTMLButtonElement>>;
|
|
301
|
+
|
|
302
|
+
declare const APE_CALENDAR_ROOT_CLASS = "ape-calendar";
|
|
303
|
+
|
|
304
|
+
declare const toDayKey: (date: Date) => DayKey;
|
|
305
|
+
declare const isSameDay: (left: Date, right: Date) => boolean;
|
|
306
|
+
/**
|
|
307
|
+
* Returns a set of day keys (YYYY-MM-DD) where at least one event starts.
|
|
308
|
+
*/
|
|
309
|
+
declare const getEventDayKeys: <E extends BaseCalendarEvent<string>>(events: E[]) => Set<DayKey>;
|
|
310
|
+
/**
|
|
311
|
+
* Returns a map of day key → unique statuses present that day. Used by the
|
|
312
|
+
* mini calendar to render status indicator dots.
|
|
313
|
+
*/
|
|
314
|
+
declare const getEventDayStatuses: <Status extends string, E extends BaseCalendarEvent<Status>>(events: E[]) => Map<DayKey, Status[]>;
|
|
315
|
+
/**
|
|
316
|
+
* Maps a calendar event to FullCalendar's EventInput shape. The full event is
|
|
317
|
+
* placed under `extendedProps.source` so handlers can recover it later via the
|
|
318
|
+
* `eventsById` map.
|
|
319
|
+
*/
|
|
320
|
+
declare const mapEventToCalendarInput: <E extends BaseCalendarEvent<string>>(event: E) => EventInput;
|
|
321
|
+
/**
|
|
322
|
+
* Locale-aware hour label (HH:MM, 24h by default).
|
|
323
|
+
*/
|
|
324
|
+
declare const formatHourLabel: (date: Date, locale?: string, options?: Intl.DateTimeFormatOptions) => string;
|
|
325
|
+
declare const formatDurationLabel: (durationMinutes: number, messages?: {
|
|
326
|
+
min?: string;
|
|
327
|
+
h?: string;
|
|
328
|
+
}) => string;
|
|
329
|
+
|
|
330
|
+
export { APE_CALENDAR_ROOT_CLASS, type BaseCalendarEvent, Button, type ButtonProps, type ButtonSize, type ButtonVariant, CalendarToolbar, type CalendarToolbarMessages, type CalendarToolbarProps, type CalendarUpdateSource, type CalendarView, type CalendarVisibleRange, DayEventDot, type DayEventDotProps, type DayKey, type DefaultEventStatus, EmptyEventsState, type EmptyEventsStateProps, EventBlockContent, type EventBlockContentMessages, type EventBlockContentProps, EventChipMonth, type EventChipMonthProps, EventChipPopover, type EventChipPopoverMessages, type EventChipPopoverProps, EventStatusBadge, type EventStatusBadgeProps, type EventTimeChangePayload, EventTypeChip, type EventTypeChipProps, MacroCalendar, type MacroCalendarMessages, type MacroCalendarProps, MiniMonthCalendar, type MiniMonthCalendarMessages, type MiniMonthCalendarProps, MoreEventsPopover, type MoreEventsPopoverMessages, type MoreEventsPopoverProps, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverPortal, PopoverTrigger, type SlotAction, type SlotActionPayload, type SlotActionState, SlotContextActions, type SlotContextActionsMessages, type SlotContextActionsProps, formatDurationLabel, formatHourLabel, getEventDayKeys, getEventDayStatuses, isSameDay, mapEventToCalendarInput, toDayKey };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{useEffect as ft,useMemo as B,useRef as it,useState as Ce}from"react";import Se from"@fullcalendar/react";import Pe from"@fullcalendar/daygrid";import be from"@fullcalendar/timegrid";import De from"@fullcalendar/interaction";import xe from"@fullcalendar/core/locales/es";import{useReducedMotion as _e}from"motion/react";import{CalendarDays as Me}from"lucide-react";import Ne from"clsx";var M=t=>{let o=t.getFullYear(),n=`${t.getMonth()+1}`.padStart(2,"0"),a=`${t.getDate()}`.padStart(2,"0");return`${o}-${n}-${a}`},It=(t,o)=>M(t)===M(o),Ft=t=>new Set(t.map(o=>M(o.startDate))),zt=t=>t.reduce((o,n)=>{if(!n.status)return o;let a=M(n.startDate),r=o.get(a)??[];return r.includes(n.status)||o.set(a,[...r,n.status]),o},new Map),et=t=>({id:t.id,title:t.title,start:t.startAt,end:t.endAt,allDay:t.isAllDay??!1,extendedProps:{status:t.status,location:t.location,description:t.description,durationMinutes:t.durationMinutes}}),g=(t,o="es-CO",n={hour:"2-digit",minute:"2-digit",hour12:!1})=>t.toLocaleTimeString(o,n),Ht=(t,o={})=>{let n=o.min??"min",a=o.h??"h";if(t<60)return`${t} ${n}`;let r=Math.floor(t/60),s=t%60;return s===0?`${r} ${a}`:`${r} ${a} ${s} ${n}`};var D="ape-calendar";import{createContext as $t,useContext as Vt,useEffect as Gt,useState as Ut}from"react";import{jsx as Kt}from"react/jsx-runtime";var vt=$t(null),Et=()=>Vt(vt);function K({children:t}){let[o,n]=Ut(null);return Gt(()=>{if(typeof document>"u")return;let a=document.createElement("div");return a.className=D,a.dataset.apeCalendarPortalRoot="true",document.body.appendChild(a),n(a),()=>{a.parentNode&&a.parentNode.removeChild(a)}},[]),Kt(vt.Provider,{value:o,children:t})}import{Clock as Zt,SquarePen as jt,Trash2 as te}from"lucide-react";import{CalendarClock as qt,Rocket as Wt}from"lucide-react";import Yt from"clsx";import{jsx as q,jsxs as Jt}from"react/jsx-runtime";var Xt={draft:q("span",{className:"cal-status-badge__dot","data-status":"draft"}),published:q(Wt,{size:11,"aria-hidden":!0}),scheduled:q(qt,{size:11,"aria-hidden":!0}),archived:q("span",{className:"cal-status-badge__dot","data-status":"archived"})},Qt=t=>t.charAt(0).toUpperCase()+t.slice(1),H=({status:t,labels:o,icons:n,className:a})=>{let r=o?.[t]??Qt(t),s=n?.[t]??Xt[t];return Jt("span",{className:Yt("cal-status-badge",a),"data-status":t,children:[s,r]})};import{jsx as N,jsxs as W}from"react/jsx-runtime";var ee={edit:t=>`Edit event ${t}`,delete:t=>`Delete event ${t}`},ot=({event:t,onEdit:o,onDelete:n,locale:a="es-CO",statusLabels:r,messages:s})=>{let i={...ee,...s},v=t.status??"";return W("article",{className:"cal-event-block","data-status":v,children:[N("div",{className:"cal-event-block__header",children:t.status&&N(H,{status:t.status,labels:r})}),N("p",{className:"cal-event-block__title",children:t.title}),W("p",{className:"cal-event-block__time",children:[N(Zt,{size:10,"aria-hidden":!0}),W("span",{children:[g(t.startDate,a)," -"," ",g(t.endDate,a)]})]}),W("div",{className:"cal-event-block__actions",children:[N("button",{type:"button","aria-label":i.edit(t.title),onClick:p=>{p.stopPropagation(),o(t)},className:"cal-event-block__action-button",children:N(jt,{size:11})}),N("button",{type:"button","aria-label":i.delete(t.title),onClick:p=>{p.stopPropagation(),n(t)},className:"cal-event-block__action-button cal-event-block__action-button--danger",children:N(te,{size:11})})]})]})};import{Clock as se,MapPin as ie,SquarePen as le,Trash2 as pe}from"lucide-react";import*as E from"@radix-ui/react-popover";import{forwardRef as oe}from"react";import ae from"clsx";import{jsx as gt}from"react/jsx-runtime";var k=E.Root,at=E.Trigger,$=E.Anchor,ne=E.Portal,re=E.Close,A=oe(({className:t,align:o="center",sideOffset:n=4,...a},r)=>{let s=Et();return gt(E.Portal,{container:s??void 0,children:gt(E.Content,{ref:r,align:o,sideOffset:n,className:ae("cal-popover-content",t),...a})})});A.displayName="PopoverContent";import{jsx as f,jsxs as b}from"react/jsx-runtime";var ce={weekday:"long",day:"2-digit",month:"long"},de={edit:"Edit",delete:"Delete",editAria:t=>`Edit event ${t}`,deleteAria:t=>`Delete event ${t}`},nt=({event:t,onEdit:o,onDelete:n,children:a,locale:r="es-CO",statusLabels:s,renderEventMeta:i,messages:v,dayHeaderOptions:p})=>{let u={...de,...v},P=new Intl.DateTimeFormat(r,p??ce).format(t.startDate),T=`${g(t.startDate,r)} \u2013 ${g(t.endDate,r)}`;return b(k,{children:[f(at,{asChild:!0,children:a}),b(A,{align:"start",sideOffset:6,collisionPadding:12,className:"cal-chip-popover",onClick:c=>c.stopPropagation(),children:[b("header",{className:"cal-chip-popover__header",children:[b("div",{className:"cal-chip-popover__header-info",children:[f("p",{className:"cal-chip-popover__day",children:P}),f("h3",{className:"cal-chip-popover__title",children:t.title})]}),t.status&&f(H,{status:t.status,labels:s})]}),b("dl",{className:"cal-chip-popover__meta",children:[b("div",{className:"cal-chip-popover__meta-row",children:[f(se,{size:12,"aria-hidden":!0}),f("span",{children:T})]}),i&&f("div",{className:"cal-chip-popover__meta-row cal-chip-popover__meta-row--wrap",children:i(t)}),t.location&&b("div",{className:"cal-chip-popover__meta-row cal-chip-popover__meta-row--start",children:[f(ie,{size:12,"aria-hidden":!0}),f("span",{className:"cal-chip-popover__clamp-2",children:t.location})]})]}),t.description&&f("p",{className:"cal-chip-popover__description",children:t.description}),b("footer",{className:"cal-chip-popover__footer",children:[b("button",{type:"button","aria-label":u.editAria(t.title),onClick:c=>{c.stopPropagation(),o(t)},className:"cal-chip-popover__action",children:[f(le,{size:12}),u.edit]}),b("button",{type:"button","aria-label":u.deleteAria(t.title),onClick:c=>{c.stopPropagation(),n(t)},className:"cal-chip-popover__action cal-chip-popover__action--danger",children:[f(pe,{size:12}),u.delete]})]})]})]})};import{jsx as Y,jsxs as me}from"react/jsx-runtime";var rt=({event:t,onEdit:o,onDelete:n,locale:a="es-CO",statusLabels:r,renderEventMeta:s,messages:i,triggerAria:v=p=>`Show event details ${p}`})=>{let p=g(t.startDate,a),u=t.status??"";return Y(nt,{event:t,onEdit:o,onDelete:n,locale:a,statusLabels:r,renderEventMeta:s,messages:i,children:me("button",{type:"button","aria-label":v(t.title),onClick:y=>y.stopPropagation(),className:"cal-chip-month","data-status":u,children:[Y("span",{className:"cal-chip-month__dot","aria-hidden":!0}),Y("span",{className:"cal-chip-month__time",children:p}),Y("span",{className:"cal-chip-month__title",children:t.title})]})})};import{useMemo as ue}from"react";import{Clock as ve,SquarePen as Ee,Trash2 as ge}from"lucide-react";import{jsx as h,jsxs as L}from"react/jsx-runtime";var fe={weekday:"long",day:"2-digit",month:"long"},he={header:t=>`${t} events in this slot`,editAria:t=>`Edit event ${t}`,deleteAria:t=>`Delete event ${t}`},ye=({events:t,anchor:o,open:n,onOpenChange:a,onEdit:r,onDelete:s,locale:i="es-CO",messages:v,dayHeaderOptions:p})=>{let u=ue(()=>({current:o}),[o]),y={...he,...v},T=new Intl.DateTimeFormat(i,p??fe).format(t[0].startDate);return L(k,{open:n,onOpenChange:a,children:[h($,{virtualRef:u}),L(A,{align:"start",sideOffset:6,collisionPadding:12,className:"cal-more-popover",onClick:c=>c.stopPropagation(),children:[L("header",{className:"cal-more-popover__header",children:[h("p",{className:"cal-more-popover__day",children:T}),h("h3",{className:"cal-more-popover__title",children:y.header(t.length)})]}),h("ul",{className:"cal-more-popover__list",children:t.map(c=>L("li",{className:"cal-more-popover__item",children:[h("span",{className:"cal-more-popover__dot","data-status":c.status??"","aria-hidden":!0}),L("div",{className:"cal-more-popover__item-body",children:[h("p",{className:"cal-more-popover__item-title",children:c.title}),L("p",{className:"cal-more-popover__item-time",children:[h(ve,{size:10,"aria-hidden":!0}),g(c.startDate,i)," \u2013"," ",g(c.endDate,i)]})]}),L("div",{className:"cal-more-popover__item-actions",children:[h("button",{type:"button","aria-label":y.editAria(c.title),onClick:_=>{_.stopPropagation(),a(!1),r(c)},className:"cal-more-popover__action",children:h(Ee,{size:12})}),h("button",{type:"button","aria-label":y.deleteAria(c.title),onClick:_=>{_.stopPropagation(),a(!1),s(c)},className:"cal-more-popover__action cal-more-popover__action--danger",children:h(ge,{size:12})})]})]},c.id))})]})]})},st=t=>!t.anchor||t.events.length===0?null:h(ye,{...t,anchor:t.anchor});import{jsx as S,jsxs as yt}from"react/jsx-runtime";var ht={day:"timeGridDay",week:"timeGridWeek",month:"dayGridMonth"},Ae=220,Te={moreLink:t=>`+${t} more`,allDayText:"All day",todayHeaderAria:"Today"},ke=({events:t,activeView:o,selectedDate:n,highlightEventIds:a=[],onDeleteEvent:r,onEditEvent:s,onEventTimeChange:i,onDateClick:v,onDateSelected:p,onVisibleRangeChange:u,onSwitchToDay:y,locale:P="es-CO",fullCalendarLocale:T=xe,firstDay:c=1,statusLabels:_,renderEventMeta:J,messages:V,immutableStatuses:d,className:w})=>{let R=it(null),F=it(null),G=it(!0),[Z,j]=Ce(null),ut=_e(),tt=B(()=>({...Te,...V}),[V]),Dt=B(()=>new Set(a),[a]),U=B(()=>new Map(t.map(e=>[e.id,e])),[t]),xt=B(()=>t.map(et),[t]),_t=B(()=>new Intl.DateTimeFormat(P,{weekday:"short"}),[P]),Mt=B(()=>new Set(d??["archived"]),[d]);ft(()=>{j(null);let e=R.current?.getApi();if(!e)return;let l=!1;return queueMicrotask(()=>{if(l)return;let m=ht[o];e.view.type!==m&&e.changeView(m),e.getDate().toDateString()!==n.toDateString()&&e.gotoDate(n)}),()=>{l=!0}},[o,n]),ft(()=>{if(G.current){G.current=!1;return}ut||!F.current||F.current.animate([{opacity:.88,transform:"translateY(5px)"},{opacity:1,transform:"translateY(0)"}],{duration:Ae,easing:"cubic-bezier(0.22, 1, 0.36, 1)",fill:"both"})},[o,ut]);let Nt=e=>u(e.start,e.end),At=e=>{p(e.date),v(e.date,{x:e.jsEvent.clientX,y:e.jsEvent.clientY})},Tt=e=>{let l=e.jsEvent?{x:e.jsEvent.clientX,y:e.jsEvent.clientY}:{x:window.innerWidth/2,y:window.innerHeight/2};p(e.start),v(e.start,l)},kt=e=>{let l=U.get(e.event.id);return l?e.view.type==="dayGridMonth"||e.event.allDay?S(rt,{event:l,onEdit:s,onDelete:r,locale:P,statusLabels:_,renderEventMeta:J}):S(ot,{event:l,onEdit:s,onDelete:r,locale:P,statusLabels:_}):S("p",{className:"cal-event-fallback",children:e.event.title})},Lt=e=>{Dt.has(e.event.id)&&(e.el.classList.add("cal-event-highlight-enter"),window.setTimeout(()=>e.el.classList.remove("cal-event-highlight-enter"),650))},wt=(e,l,m)=>{if(m)return m.toISOString();let C=new Date(l),z=e.durationMinutes??60;return C.setMinutes(C.getMinutes()+z),C.toISOString()},Rt=e=>{let l=U.get(e.event.id),m=e.event.start;if(!l||!m){e.revert();return}i({event:l,startAt:m.toISOString(),endAt:wt(l,m,e.event.end),revert:e.revert})},Bt=e=>{let l=U.get(e.event.id),m=e.event.start,C=e.event.end;if(!l||!m||!C){e.revert();return}if(C<=m){e.revert();return}i({event:l,startAt:m.toISOString(),endAt:C.toISOString(),revert:e.revert})},Ot=({date:e,isToday:l})=>{let m=_t.format(e).replace(".","");return yt("div",{className:"cal-day-header",children:[S("span",{className:"cal-day-header__number","data-today":l,"aria-label":l?tt.todayHeaderAria:void 0,children:e.getDate()}),S("span",{className:"cal-day-header__weekday",children:m})]})};return S(K,{children:S("div",{className:Ne(D,"cal-macro-root",w),children:yt("div",{ref:F,className:"cal-macro-surface",children:[S(Me,{className:"cal-macro-corner-icon",size:20,"aria-hidden":!0}),S(Se,{ref:R,plugins:[Pe,be,De],locale:T,initialView:ht[o],height:"100%",expandRows:!0,firstDay:c,allDaySlot:!1,allDayText:tt.allDayText,selectable:!0,selectMirror:!0,editable:!0,eventStartEditable:!0,eventDurationEditable:!0,eventResizableFromStart:!0,dayMaxEvents:!0,eventMaxStack:3,moreLinkContent:e=>S("span",{className:"cal-more-link",children:tt.moreLink(e.num)}),moreLinkClick:e=>{if(e.view.type==="dayGridMonth")return y(e.date),"none";let l=e.allSegs.map(z=>U.get(z.event.id)).filter(z=>!!z),m=e.jsEvent.target,C=m instanceof Element?m.closest(".fc-more-link"):null;return C&&l.length>0&&j({events:l,anchor:C}),"none"},nowIndicator:!0,slotDuration:"01:00:00",slotLabelInterval:"01:00:00",slotLabelFormat:{hour:"2-digit",minute:"2-digit",hour12:!1},slotMinTime:"00:00:00",slotMaxTime:"24:00:00",slotEventOverlap:!1,eventMinHeight:28,eventShortHeight:48,headerToolbar:!1,events:xt,eventDrop:Rt,eventResize:Bt,eventDidMount:Lt,dragScroll:!0,eventDragMinDistance:8,dragRevertDuration:420,longPressDelay:380,selectLongPressDelay:380,eventAllow:(e,l)=>{if(!l)return!1;let m=l.extendedProps.status;return typeof m=="string"?!Mt.has(m):!0},datesSet:Nt,dateClick:At,select:Tt,dayHeaderContent:Ot,eventContent:kt}),S(st,{events:Z?.events??[],anchor:Z?.anchor??null,open:!!Z,onOpenChange:e=>{e||j(null)},onEdit:s,onDelete:r,locale:P})]})})})};import{useMemo as we}from"react";import{DayPicker as Re}from"react-day-picker";import{es as Be}from"react-day-picker/locale";import{ChevronLeft as Oe,ChevronRight as Ie}from"lucide-react";import Fe from"clsx";import Ct from"clsx";import{jsx as lt,jsxs as Le}from"react/jsx-runtime";var pt=({statuses:t,isSelected:o=!1,statusColors:n,className:a,maxDots:r=2})=>t.length===0&&!o?lt("span",{className:Ct("cal-day-dot-empty",a),"aria-hidden":!0}):Le("span",{className:Ct("cal-day-dot-row",a),"aria-hidden":!0,children:[o&<("span",{className:"cal-day-dot cal-day-dot--selected"}),t.slice(0,r).map(s=>{let i=n?.[s];return lt("span",{className:"cal-day-dot","data-status":s,style:i?{backgroundColor:i}:void 0},s)})]});import{jsx as x,jsxs as ct}from"react/jsx-runtime";var ze={previousMonth:"Previous month",nextMonth:"Next month"},He=({selectedDate:t,visibleMonth:o,eventDayStatuses:n,onSelectDate:a,onMonthChange:r,locale:s="es-CO",pickerLocale:i=Be,messages:v,statusColors:p,className:u})=>{let y={...ze,...v},{monthNameFormat:P,yearFormat:T,weekdayFormat:c}=we(()=>({monthNameFormat:new Intl.DateTimeFormat(s,{month:"long"}),yearFormat:new Intl.DateTimeFormat(s,{year:"numeric"}),weekdayFormat:new Intl.DateTimeFormat(s,{weekday:"short"})}),[s]),_=d=>{let w=P.format(d);return`${w.charAt(0).toUpperCase()+w.slice(1)} ${T.format(d)}`},J=()=>{let d=new Date(o);d.setMonth(d.getMonth()-1),r(d)},V=()=>{let d=new Date(o);d.setMonth(d.getMonth()+1),r(d)};return x(K,{children:ct("div",{className:Fe(D,"cal-mini-root",u),children:[ct("div",{className:"cal-mini-header",children:[x("button",{type:"button","aria-label":y.previousMonth,onClick:J,className:"cal-mini-nav-button",children:x(Oe,{size:14,"aria-hidden":!0})}),x("h2",{className:"cal-mini-caption",children:_(o)}),x("button",{type:"button","aria-label":y.nextMonth,onClick:V,className:"cal-mini-nav-button",children:x(Ie,{size:14,"aria-hidden":!0})})]}),x(Re,{mode:"single",locale:i,selected:t,month:o,onMonthChange:r,formatters:{formatWeekdayName:d=>c.format(d).charAt(0).toUpperCase()},onSelect:d=>{d&&a(d)},hideNavigation:!0,captionLayout:"label",className:"cal-mini-grid",classNames:{months:"cal-mini-months",month:"cal-mini-month",month_caption:"cal-mini-month-caption",caption_label:"cal-mini-caption-label",month_grid:"cal-mini-month-grid",weekdays:"cal-mini-weekdays",weekday:"cal-mini-weekday",week:"cal-mini-week",day:"cal-mini-day",day_button:"cal-mini-day-button",outside:"cal-mini-day--outside",today:"cal-mini-day--today"},components:{DayButton:({day:d,...w})=>{let R=M(d.date),F=n.get(R)??[],G=M(t)===R;return ct("button",{...w,children:[x("span",{children:d.date.getDate()}),x(pt,{statuses:F,isSelected:G,statusColors:p})]})}}})]})})};import{LayoutGroup as Ue,motion as Ke}from"motion/react";import{CalendarDays as St}from"lucide-react";import qe from"clsx";import{forwardRef as $e}from"react";import Ve from"clsx";import{jsx as dt,jsxs as Ge}from"react/jsx-runtime";var O=$e(({variant:t="primary",size:o="md",rounded:n="md",leftIcon:a,rightIcon:r,className:s,children:i,type:v="button",...p},u)=>Ge("button",{ref:u,type:v,"data-variant":t,"data-size":o,"data-rounded":n,className:Ve("cal-button",s),...p,children:[a&&dt("span",{className:"cal-button__icon",children:a}),i&&dt("span",{className:"cal-button__label",children:i}),r&&dt("span",{className:"cal-button__icon",children:r})]}));O.displayName="Button";import{jsx as I,jsxs as mt}from"react/jsx-runtime";var We={day:"Day",week:"Week",month:"Month"},Pt={groupAriaLabel:"Calendar view",newEvent:"New event"},Ye=["day","week","month"],Xe=({activeView:t,onChangeView:o,onNewEvent:n,messages:a,className:r})=>{let s={...We,...a?.views},i=a?.groupAriaLabel??Pt.groupAriaLabel,v=a?.newEvent??Pt.newEvent;return mt("div",{className:qe(D,"cal-toolbar",r),children:[I(Ue,{id:"cal-toolbar-view-tabs",children:I("div",{className:"cal-toolbar__tabs",role:"group","aria-label":i,children:Ye.map(p=>{let u=t===p;return mt("button",{type:"button",onClick:()=>o(p),className:"cal-toolbar__tab","data-active":u,children:[u&&I(Ke.span,{layoutId:"cal-toolbar-indicator",className:"cal-toolbar__indicator",transition:{type:"spring",stiffness:380,damping:34}}),mt("span",{className:"cal-toolbar__tab-label",children:[I(St,{size:14,className:"cal-toolbar__tab-icon","aria-hidden":!0}),s[p]]})]},p)})})}),n&&I(O,{variant:"primary",size:"md",rounded:"full",onClick:n,leftIcon:I(St,{size:18,"aria-hidden":!0}),children:v})]})};import{jsx as X,jsxs as bt}from"react/jsx-runtime";var Qe={heading:"Event actions"},Je=({state:t,actions:o,onClose:n,onSelectAction:a,messages:r})=>{if(!t.point||!t.date)return null;let s={...Qe,...r};return bt(k,{open:t.isOpen,onOpenChange:i=>!i&&n(),children:[X($,{asChild:!0,children:X("span",{className:"cal-slot-anchor",style:{left:t.point.x,top:t.point.y},"aria-hidden":!0})}),bt(A,{align:"start",sideOffset:8,className:"cal-slot-popover",onEscapeKeyDown:n,children:[X("p",{className:"cal-slot-popover__heading",children:s.heading}),o.map(i=>X(O,{type:"button",variant:"ghost",size:"sm",leftIcon:i.icon,className:"cal-slot-popover__action",onClick:()=>a({type:i.type,date:t.date}),children:i.label},i.type))]})]})};import Ze from"clsx";import{jsx as to,jsxs as eo}from"react/jsx-runtime";var je=({label:t,icon:o,className:n})=>eo("span",{className:Ze("cal-type-chip",n),children:[o&&to("span",{className:"cal-type-chip__icon",children:o}),t]});import{CalendarDays as oo}from"lucide-react";import ao from"clsx";import{jsx as Q,jsxs as ro}from"react/jsx-runtime";var no=({title:t="No events to display",description:o="Adjust filters or create a new event to populate the calendar.",icon:n,className:a})=>ro("div",{className:ao("cal-empty-state",a),children:[Q("span",{className:"cal-empty-state__icon","aria-hidden":!0,children:n??Q(oo,{size:20})}),Q("p",{className:"cal-empty-state__title",children:t}),Q("p",{className:"cal-empty-state__description",children:o})]});export{D as APE_CALENDAR_ROOT_CLASS,O as Button,Xe as CalendarToolbar,pt as DayEventDot,no as EmptyEventsState,ot as EventBlockContent,rt as EventChipMonth,nt as EventChipPopover,H as EventStatusBadge,je as EventTypeChip,ke as MacroCalendar,He as MiniMonthCalendar,st as MoreEventsPopover,k as Popover,$ as PopoverAnchor,re as PopoverClose,A as PopoverContent,ne as PopoverPortal,at as PopoverTrigger,Je as SlotContextActions,Ht as formatDurationLabel,g as formatHourLabel,Ft as getEventDayKeys,zt as getEventDayStatuses,It as isSameDay,et as mapEventToCalendarInput,M as toDayKey};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
package/dist/style.css
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){.ape-calendar *,.ape-calendar :before,.ape-calendar :after,.ape-calendar ::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial}}}.ape-calendar,.ape-calendar{--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}:where(.ape-calendar) .container{width:100%}@media (min-width:40rem){:where(.ape-calendar) .container{max-width:40rem}}@media (min-width:48rem){:where(.ape-calendar) .container{max-width:48rem}}@media (min-width:64rem){:where(.ape-calendar) .container{max-width:64rem}}@media (min-width:80rem){:where(.ape-calendar) .container{max-width:80rem}}@media (min-width:96rem){:where(.ape-calendar) .container{max-width:96rem}}:where(.ape-calendar) .inline{display:inline}:where(.ape-calendar) .transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}:where(.ape-calendar) .rounded{border-radius:.25rem}:where(.ape-calendar) .capitalize{text-transform:capitalize}:where(.ape-calendar) .transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.ape-calendar{--cal-status-draft:#94a3b8;--cal-status-published:#22c55e;--cal-status-scheduled:#f59e0b;--cal-status-archived:#71717a;--cal-status-selected:#2563eb;--cal-status-draft-bg:#f8fafc;--cal-status-draft-bg-hover:#f1f5f9;--cal-status-draft-text:#334155;--cal-status-published-bg:#f0fdf4;--cal-status-published-bg-hover:#dcfce7;--cal-status-published-text:#14532d;--cal-status-scheduled-bg:#fffbeb;--cal-status-scheduled-bg-hover:#fef3c7;--cal-status-scheduled-text:#78350f;--cal-status-archived-bg:#fafafa;--cal-status-archived-bg-hover:#f4f4f5;--cal-status-archived-text:#71717a;--cal-surface:#fff;--cal-surface-subtle:#f8fafc;--cal-mini-surface:#f1f5f9;--cal-macro-surface:var(--cal-surface);--cal-border:#e2e8f0;--cal-text:#0f172a;--cal-text-muted:#64748b;--cal-text-faint:#94a3b8;--cal-primary:#1d4ed8;--cal-primary-hover:#1e40af;--cal-danger:#dc2626;--cal-danger-bg:#fef2f2;--cal-focus-ring:#93c5fd;--cal-fc-border:#e6effa;--cal-fc-slot-height:52px;--cal-fc-text:#334155;--cal-fc-font-size:.75rem;--cal-fc-small-font-size:.7rem}:where(.ape-calendar) .cal-day-dot-empty{height:.375rem;margin-top:.125rem;display:block}:where(.ape-calendar) .cal-day-dot-row{justify-content:center;align-items:center;gap:.125rem;height:.375rem;margin-top:.125rem;display:flex}:where(.ape-calendar) .cal-day-dot{background-color:var(--cal-status-default,#cbd5e1);border-radius:9999px;width:.375rem;height:.375rem}:where(.ape-calendar) .cal-day-dot[data-status=draft]{background-color:var(--cal-status-draft)}:where(.ape-calendar) .cal-day-dot[data-status=published]{background-color:var(--cal-status-published)}:where(.ape-calendar) .cal-day-dot[data-status=scheduled]{background-color:var(--cal-status-scheduled)}:where(.ape-calendar) .cal-day-dot[data-status=archived]{background-color:var(--cal-status-archived)}:where(.ape-calendar) .cal-day-dot--selected{background-color:var(--cal-status-selected)}:where(.ape-calendar) .cal-mini-root{background-color:var(--cal-mini-surface);border-radius:1rem;padding:.75rem 1rem 1rem;box-shadow:0 1px 2px #0000000d}:where(.ape-calendar) .cal-mini-header{justify-content:space-between;align-items:center;margin-bottom:1rem;display:flex}:where(.ape-calendar) .cal-mini-nav-button{cursor:pointer;width:2rem;height:2rem;color:var(--cal-primary);background:0 0;border:none;border-radius:9999px;justify-content:center;align-items:center;transition:background-color .15s;display:inline-flex}:where(.ape-calendar) .cal-mini-nav-button:hover{background-color:#eff6ff}:where(.ape-calendar) .cal-mini-nav-button:focus{box-shadow:0 0 0 2px var(--cal-focus-ring);outline:none}:where(.ape-calendar) .cal-mini-caption{background-color:var(--cal-surface);text-transform:capitalize;color:#1e293b;border-radius:.375rem;margin:0;padding:.25rem .75rem;font-size:1rem;font-weight:600;box-shadow:0 1px 1px #0000000a}:where(.ape-calendar) .cal-mini-grid,:where(.ape-calendar) .cal-mini-months,:where(.ape-calendar) .cal-mini-month{width:100%}:where(.ape-calendar) .cal-mini-month-caption{clip:rect(0,0,0,0);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}:where(.ape-calendar) .cal-mini-caption-label{text-transform:capitalize}:where(.ape-calendar) .cal-mini-month-grid{border-collapse:separate;border-spacing:.5rem;width:100%}:where(.ape-calendar) .cal-mini-weekday{text-align:center;text-transform:uppercase;letter-spacing:.025em;color:#334155;height:1.75rem;font-size:.875rem;font-weight:700}:where(.ape-calendar) .cal-mini-day{text-align:center;vertical-align:middle;width:2rem;height:2rem}:where(.ape-calendar) .cal-mini-day-button{cursor:pointer;background-color:var(--cal-surface);color:#334155;border:none;border-radius:.375rem;flex-direction:column;justify-content:center;align-items:center;width:2rem;height:2rem;margin:0 auto;font-size:.75rem;font-weight:600;transition:background-color .15s;display:flex;position:relative;box-shadow:0 1px 1px #0000000a}:where(.ape-calendar) .cal-mini-day-button:hover{background-color:var(--cal-surface-subtle)}:where(.ape-calendar) .cal-mini-day-button:focus-visible{outline:none;box-shadow:0 0 0 2px #0ea5e9}:where(.ape-calendar) .cal-mini-day-button[aria-selected=true]{background-color:var(--cal-surface-subtle);color:var(--cal-text)}:where(.ape-calendar) .cal-mini-day--outside{color:#cbd5e1}:where(.ape-calendar) .cal-mini-day--today{color:#0369a1}:where(.ape-calendar) .cal-popover-content{z-index:60;background-color:var(--cal-surface);border:1px solid var(--cal-border);border-radius:.5rem;outline:none;animation:.12s cubic-bezier(.16,1,.3,1) cal-popover-in;box-shadow:0 10px 25px -10px #0003,0 4px 6px -4px #0000001a}@keyframes cal-popover-in{0%{opacity:0;transform:translateY(-4px)scale(.98)}to{opacity:1;transform:translateY(0)scale(1)}}:where(.ape-calendar) .cal-button{cursor:pointer;border:none;align-items:center;gap:.5rem;font-weight:600;transition:background-color .15s,transform .1s;display:inline-flex}:where(.ape-calendar) .cal-button:focus-visible{box-shadow:0 0 0 2px var(--cal-focus-ring);outline:none}:where(.ape-calendar) .cal-button[data-rounded=md]{border-radius:.5rem}:where(.ape-calendar) .cal-button[data-rounded=full]{border-radius:9999px}:where(.ape-calendar) .cal-button[data-size=sm]{padding:.375rem .75rem;font-size:.75rem}:where(.ape-calendar) .cal-button[data-size=md]{padding:.5rem 1rem;font-size:.875rem}:where(.ape-calendar) .cal-button[data-size=lg]{padding:.625rem 1.25rem;font-size:1rem}:where(.ape-calendar) .cal-button[data-variant=primary]{background-color:var(--cal-primary);color:#fff}:where(.ape-calendar) .cal-button[data-variant=primary]:hover{background-color:var(--cal-primary-hover)}:where(.ape-calendar) .cal-button[data-variant=secondary]{background-color:var(--cal-surface-subtle);color:var(--cal-text);border:1px solid var(--cal-border)}:where(.ape-calendar) .cal-button[data-variant=secondary]:hover{background-color:#e2e8f0}:where(.ape-calendar) .cal-button[data-variant=ghost]{color:var(--cal-text);background:0 0}:where(.ape-calendar) .cal-button[data-variant=ghost]:hover{background-color:var(--cal-surface-subtle)}:where(.ape-calendar) .cal-button__icon{justify-content:center;align-items:center;display:inline-flex}:where(.ape-calendar) .cal-toolbar{background-color:var(--cal-surface);border-bottom:1px solid #f1f5f9;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:.75rem;padding:.75rem 1rem;display:flex}:where(.ape-calendar) .cal-toolbar__tabs{border:1px solid var(--cal-border);background-color:#f8fafce6;border-radius:9999px;padding:.25rem;display:inline-flex;box-shadow:inset 0 2px 4px #0000000a}:where(.ape-calendar) .cal-toolbar__tab{cursor:pointer;color:var(--cal-text-muted);background:0 0;border:none;border-radius:9999px;padding:.375rem .75rem;font-size:.75rem;font-weight:600;transition:all .2s cubic-bezier(0,0,.2,1);position:relative}:where(.ape-calendar) .cal-toolbar__tab:hover{color:var(--cal-text);transform:scale(1.05)}:where(.ape-calendar) .cal-toolbar__tab[data-active=true]{color:#fff}:where(.ape-calendar) .cal-toolbar__tab:focus-visible{box-shadow:0 0 0 2px var(--cal-focus-ring);outline:none}:where(.ape-calendar) .cal-toolbar__indicator{background-color:var(--cal-primary);border-radius:9999px;position:absolute;inset:0;box-shadow:0 1px 2px #0000000d}:where(.ape-calendar) .cal-toolbar__tab-label{z-index:10;align-items:center;gap:.375rem;display:inline-flex;position:relative}:where(.ape-calendar) .cal-toolbar__tab-icon{flex-shrink:0}:where(.ape-calendar) .cal-event-block{border:1px solid;border-radius:.5rem;flex-direction:column;gap:.125rem;width:100%;min-width:0;height:100%;padding:.375rem;transition:box-shadow .15s;display:flex;overflow:hidden;box-shadow:0 1px 2px #0000000d}:where(.ape-calendar) .cal-event-block:hover{box-shadow:0 2px 4px #0000001a}:where(.ape-calendar) .cal-event-block[data-status=draft]{background-color:#f8fafc1a;border-color:#cbd5e1}:where(.ape-calendar) .cal-event-block[data-status=published]{background-color:#f0fdf41a;border-color:#86efac}:where(.ape-calendar) .cal-event-block[data-status=scheduled]{background-color:#fffbeb1a;border-color:#fcd34d}:where(.ape-calendar) .cal-event-block[data-status=archived]{background-color:#fafafa1a;border-color:#d4d4d8}:where(.ape-calendar) .cal-event-block__header{justify-content:flex-end;display:flex}:where(.ape-calendar) .cal-event-block__title{color:var(--cal-text);text-overflow:ellipsis;white-space:nowrap;margin:0;font-size:.6875rem;font-weight:700;line-height:1.1;overflow:hidden}:where(.ape-calendar) .cal-event-block__time{color:var(--cal-text-muted);text-overflow:ellipsis;white-space:nowrap;align-items:center;gap:.25rem;margin:0;font-size:.625rem;font-weight:600;display:flex;overflow:hidden}:where(.ape-calendar) .cal-event-block__time>span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}:where(.ape-calendar) .cal-event-block__actions{color:var(--cal-text-muted);justify-content:flex-end;align-items:center;gap:.5rem;margin-top:auto;padding-top:.25rem;display:flex}:where(.ape-calendar) .cal-event-block__action-button{cursor:pointer;background:0 0;border:none;border-radius:.375rem;justify-content:center;align-items:center;width:1.5rem;height:1.5rem;transition:background-color .15s,transform .1s;display:inline-flex}:where(.ape-calendar) .cal-event-block__action-button:hover{background-color:#ffffffb3;transform:scale(1.05)}:where(.ape-calendar) .cal-event-block__action-button:focus{box-shadow:0 0 0 2px var(--cal-focus-ring);outline:none}:where(.ape-calendar) .cal-event-block__action-button--danger:focus{box-shadow:0 0 0 2px #fca5a5}:where(.ape-calendar) .cal-event-block[data-status=draft] .cal-event-block__title{color:var(--cal-status-draft-text)}:where(.ape-calendar) .cal-event-block[data-status=published] .cal-event-block__title{color:var(--cal-status-published-text)}:where(.ape-calendar) .cal-event-block[data-status=scheduled] .cal-event-block__title{color:var(--cal-status-scheduled-text)}:where(.ape-calendar) .cal-event-block[data-status=archived] .cal-event-block__title{color:var(--cal-status-archived-text)}:where(.ape-calendar) .cal-event-block[data-status=draft] .cal-event-block__time{color:var(--cal-status-draft-text)}:where(.ape-calendar) .cal-event-block[data-status=published] .cal-event-block__time{color:var(--cal-status-published-text)}:where(.ape-calendar) .cal-event-block[data-status=scheduled] .cal-event-block__time{color:var(--cal-status-scheduled-text)}:where(.ape-calendar) .cal-event-block[data-status=archived] .cal-event-block__time{color:var(--cal-status-archived-text)}:where(.ape-calendar) .cal-chip-month{cursor:pointer;text-align:left;background-color:var(--cal-surface-subtle);width:100%;height:1.5rem;color:var(--cal-text);border:none;border-radius:.25rem;align-items:center;gap:.375rem;padding:0 .375rem;font-size:.6875rem;line-height:1;transition:background-color .15s;display:flex;overflow:hidden}:where(.ape-calendar) .cal-chip-month:focus{box-shadow:0 0 0 1px var(--cal-focus-ring);outline:none}:where(.ape-calendar) .cal-chip-month[data-status=draft]{background-color:var(--cal-status-draft-bg);color:var(--cal-status-draft-text)}:where(.ape-calendar) .cal-chip-month[data-status=draft]:hover{background-color:var(--cal-status-draft-bg-hover)}:where(.ape-calendar) .cal-chip-month[data-status=published]{background-color:var(--cal-status-published-bg);color:var(--cal-status-published-text)}:where(.ape-calendar) .cal-chip-month[data-status=published]:hover{background-color:var(--cal-status-published-bg-hover)}:where(.ape-calendar) .cal-chip-month[data-status=scheduled]{background-color:var(--cal-status-scheduled-bg);color:var(--cal-status-scheduled-text)}:where(.ape-calendar) .cal-chip-month[data-status=scheduled]:hover{background-color:var(--cal-status-scheduled-bg-hover)}:where(.ape-calendar) .cal-chip-month[data-status=archived]{background-color:var(--cal-status-archived-bg);color:var(--cal-status-archived-text);text-decoration:line-through}:where(.ape-calendar) .cal-chip-month[data-status=archived]:hover{background-color:var(--cal-status-archived-bg-hover)}:where(.ape-calendar) .cal-chip-month__dot{border-radius:9999px;flex-shrink:0;width:.375rem;height:.375rem}:where(.ape-calendar) .cal-chip-month[data-status=draft] .cal-chip-month__dot{background-color:var(--cal-status-draft)}:where(.ape-calendar) .cal-chip-month[data-status=published] .cal-chip-month__dot{background-color:var(--cal-status-published)}:where(.ape-calendar) .cal-chip-month[data-status=scheduled] .cal-chip-month__dot{background-color:var(--cal-status-scheduled)}:where(.ape-calendar) .cal-chip-month[data-status=archived] .cal-chip-month__dot{background-color:var(--cal-status-archived)}:where(.ape-calendar) .cal-chip-month__time{flex-shrink:0;font-weight:600}:where(.ape-calendar) .cal-chip-month__title{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}:where(.ape-calendar) .cal-chip-popover{flex-direction:column;gap:.75rem;width:18rem;padding:1rem;display:flex}:where(.ape-calendar) .cal-chip-popover__header{justify-content:space-between;align-items:flex-start;gap:.5rem;display:flex}:where(.ape-calendar) .cal-chip-popover__header-info{min-width:0}:where(.ape-calendar) .cal-chip-popover__day{text-transform:uppercase;letter-spacing:.025em;color:var(--cal-text-faint);margin:0;font-size:.625rem;font-weight:600}:where(.ape-calendar) .cal-chip-popover__title{color:#1e293b;margin:0;font-size:.875rem;font-weight:700;line-height:1.2}:where(.ape-calendar) .cal-chip-popover__meta{color:var(--cal-text-muted);flex-direction:column;gap:.375rem;margin:0;padding:0;font-size:.75rem;display:flex}:where(.ape-calendar) .cal-chip-popover__meta-row{align-items:center;gap:.375rem;display:flex}:where(.ape-calendar) .cal-chip-popover__meta-row--wrap{flex-wrap:wrap}:where(.ape-calendar) .cal-chip-popover__meta-row--start{align-items:flex-start}:where(.ape-calendar) .cal-chip-popover__clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}:where(.ape-calendar) .cal-chip-popover__description{color:var(--cal-text-muted);-webkit-line-clamp:3;-webkit-box-orient:vertical;margin:0;font-size:.75rem;line-height:1.6;display:-webkit-box;overflow:hidden}:where(.ape-calendar) .cal-chip-popover__footer{border-top:1px solid #f1f5f9;justify-content:flex-end;align-items:center;gap:.5rem;padding-top:.5rem;display:flex}:where(.ape-calendar) .cal-chip-popover__action{cursor:pointer;color:#334155;background:0 0;border:none;border-radius:.375rem;align-items:center;gap:.25rem;height:1.75rem;padding:0 .5rem;font-size:.75rem;font-weight:600;transition:background-color .15s;display:inline-flex}:where(.ape-calendar) .cal-chip-popover__action:hover{background-color:#f1f5f9}:where(.ape-calendar) .cal-chip-popover__action:focus{box-shadow:0 0 0 2px var(--cal-focus-ring);outline:none}:where(.ape-calendar) .cal-chip-popover__action--danger{color:var(--cal-danger)}:where(.ape-calendar) .cal-chip-popover__action--danger:hover{background-color:var(--cal-danger-bg)}:where(.ape-calendar) .cal-more-popover{flex-direction:column;width:20rem;max-height:24rem;padding:0;display:flex;overflow:hidden}:where(.ape-calendar) .cal-more-popover__header{border-bottom:1px solid #f1f5f9;padding:1rem 1rem .5rem}:where(.ape-calendar) .cal-more-popover__day{text-transform:uppercase;letter-spacing:.025em;color:var(--cal-text-faint);margin:0;font-size:.625rem;font-weight:600}:where(.ape-calendar) .cal-more-popover__title{color:#1e293b;margin:0;font-size:.875rem;font-weight:700}:where(.ape-calendar) .cal-more-popover__list{flex-direction:column;flex:1;gap:.25rem;margin:0;padding:.5rem;list-style:none;display:flex;overflow-y:auto}:where(.ape-calendar) .cal-more-popover__item{border-radius:.375rem;align-items:center;gap:.5rem;padding:.375rem .5rem;display:flex}:where(.ape-calendar) .cal-more-popover__item:hover{background-color:var(--cal-surface-subtle)}:where(.ape-calendar) .cal-more-popover__dot{background-color:var(--cal-status-draft);border-radius:9999px;flex-shrink:0;width:.5rem;height:.5rem}:where(.ape-calendar) .cal-more-popover__dot[data-status=draft]{background-color:var(--cal-status-draft)}:where(.ape-calendar) .cal-more-popover__dot[data-status=published]{background-color:var(--cal-status-published)}:where(.ape-calendar) .cal-more-popover__dot[data-status=scheduled]{background-color:var(--cal-status-scheduled)}:where(.ape-calendar) .cal-more-popover__dot[data-status=archived]{background-color:var(--cal-status-archived)}:where(.ape-calendar) .cal-more-popover__item-body{flex:1;min-width:0}:where(.ape-calendar) .cal-more-popover__item-title{color:#1e293b;text-overflow:ellipsis;white-space:nowrap;margin:0;font-size:.75rem;font-weight:600;overflow:hidden}:where(.ape-calendar) .cal-more-popover__item-time{color:var(--cal-text-muted);align-items:center;gap:.25rem;margin:0;font-size:.625rem;display:flex}:where(.ape-calendar) .cal-more-popover__item-actions{flex-shrink:0;align-items:center;gap:.25rem;display:flex}:where(.ape-calendar) .cal-more-popover__action{cursor:pointer;width:1.5rem;height:1.5rem;color:var(--cal-text-muted);background:0 0;border:none;border-radius:.375rem;justify-content:center;align-items:center;transition:background-color .15s;display:inline-flex}:where(.ape-calendar) .cal-more-popover__action:hover{background-color:#f1f5f9}:where(.ape-calendar) .cal-more-popover__action--danger{color:var(--cal-danger)}:where(.ape-calendar) .cal-more-popover__action--danger:hover{background-color:var(--cal-danger-bg)}:where(.ape-calendar) .cal-slot-anchor{pointer-events:none;width:4px;height:4px;position:fixed}:where(.ape-calendar) .cal-slot-popover{flex-direction:column;gap:.5rem;width:14rem;padding:.5rem;display:flex}:where(.ape-calendar) .cal-slot-popover__heading{text-transform:uppercase;letter-spacing:.025em;color:var(--cal-text-faint);margin:0;padding:.25rem .5rem 0;font-size:.75rem;font-weight:600}:where(.ape-calendar) .cal-slot-popover__action{width:100%;border-radius:.375rem!important;justify-content:flex-start!important}:where(.ape-calendar) .cal-status-badge{border:1px solid;border-radius:9999px;flex-shrink:0;align-items:center;gap:.25rem;padding:.125rem .5rem;font-size:.625rem;font-weight:700;line-height:1;display:inline-flex}:where(.ape-calendar) .cal-status-badge[data-status=draft]{color:#334155;background-color:#f1f5f9;border-color:#e2e8f0}:where(.ape-calendar) .cal-status-badge[data-status=published]{color:#15803d;background-color:#f0fdf4;border-color:#bbf7d0}:where(.ape-calendar) .cal-status-badge[data-status=scheduled]{color:#b45309;background-color:#fffbeb;border-color:#fde68a}:where(.ape-calendar) .cal-status-badge[data-status=archived]{color:#3f3f46;background-color:#f4f4f5;border-color:#e4e4e7}:where(.ape-calendar) .cal-status-badge__dot{border-radius:9999px;width:.375rem;height:.375rem}:where(.ape-calendar) .cal-status-badge__dot[data-status=draft]{background-color:#64748b}:where(.ape-calendar) .cal-status-badge__dot[data-status=archived]{background-color:#71717a}:where(.ape-calendar) .cal-type-chip{height:1.5rem;color:var(--cal-text-muted);background-color:#f1f5f9;border-radius:9999px;align-items:center;gap:.25rem;padding:.25rem .625rem;font-size:.75rem;font-weight:500;line-height:1;display:inline-flex}:where(.ape-calendar) .cal-type-chip__icon{flex-shrink:0;display:inline-flex}:where(.ape-calendar) .cal-empty-state{background-color:var(--cal-surface);text-align:center;border:2px dashed #d1d5db;border-radius:1rem;flex-direction:column;justify-content:center;align-items:center;gap:.75rem;min-height:200px;padding:2.5rem 1.5rem;display:flex}:where(.ape-calendar) .cal-empty-state__icon{width:3rem;height:3rem;color:var(--cal-primary);background-color:#dbeafe;border-radius:9999px;justify-content:center;align-items:center;display:inline-flex}:where(.ape-calendar) .cal-empty-state__title{color:#111827;margin:0;font-size:1rem;font-weight:600}:where(.ape-calendar) .cal-empty-state__description{color:#6b7280;max-width:24rem;margin:0;font-size:.875rem}:where(.ape-calendar) .cal-macro-root{background-color:var(--cal-macro-surface);border-radius:1rem;height:100%;overflow:hidden}:where(.ape-calendar) .cal-macro-surface{height:100%;position:relative}:where(.ape-calendar) .cal-macro-corner-icon{pointer-events:none;z-index:10;color:var(--cal-text-faint);position:absolute;top:1.25rem;left:.75rem}:where(.ape-calendar) .cal-more-link{font-size:.625rem;font-weight:600}:where(.ape-calendar) .cal-event-fallback{text-overflow:ellipsis;white-space:nowrap;margin:0;font-size:.75rem;overflow:hidden}:where(.ape-calendar) .cal-day-header{flex-direction:column;align-items:center;gap:.25rem;padding:.25rem 0;display:flex}:where(.ape-calendar) .cal-day-header__number{width:1.5rem;height:1.5rem;color:var(--cal-text-faint);background-color:#f1f5f9;border-radius:9999px;justify-content:center;align-items:center;font-size:.625rem;font-weight:700;display:flex}:where(.ape-calendar) .cal-day-header__number[data-today=true]{background-color:var(--cal-primary);color:#fff}:where(.ape-calendar) .cal-day-header__weekday{text-transform:lowercase;color:var(--cal-text-muted);font-size:.625rem;font-weight:600}:where(.ape-calendar) .cal-event-highlight-enter{animation:.65s ease-out cal-event-highlight}@keyframes cal-event-highlight{0%{box-shadow:0 0 0 4px #2563eb66}to{box-shadow:0 0 #2563eb00}}:where(.ape-calendar) .cal-macro-root .fc{--fc-border-color:var(--cal-fc-border);--fc-page-bg-color:var(--cal-macro-surface);--fc-small-font-size:var(--cal-fc-small-font-size);color:var(--cal-fc-text);font-size:var(--cal-fc-font-size)}:where(.ape-calendar) .cal-macro-root .fc .fc-timegrid-slot{height:var(--cal-fc-slot-height)}:where(.ape-calendar) .cal-macro-root .fc .fc-timegrid-col{border-color:var(--cal-fc-border)}:where(.ape-calendar) .cal-macro-root .fc .fc-daygrid-day,:where(.ape-calendar) .cal-macro-root .fc .fc-timegrid-col-frame{cursor:pointer}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}
|
package/package.json
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ape-calendar",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "FullCalendar + react-day-picker based React calendar suite (macro + mini calendar, popovers, hooks). Self-contained with own Radix primitives.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.cjs",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
},
|
|
15
|
+
"./style.css": "./dist/style.css"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist/index.js",
|
|
19
|
+
"dist/index.cjs",
|
|
20
|
+
"dist/index.d.ts",
|
|
21
|
+
"dist/index.d.cts",
|
|
22
|
+
"dist/style.css",
|
|
23
|
+
"README.md"
|
|
24
|
+
],
|
|
25
|
+
"sideEffects": [
|
|
26
|
+
"**/*.css"
|
|
27
|
+
],
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "git+https://github.com/APE-SENA-2025/ape-calendar.git",
|
|
31
|
+
"directory": "packages/calendar"
|
|
32
|
+
},
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"keywords": [
|
|
37
|
+
"calendar",
|
|
38
|
+
"fullcalendar",
|
|
39
|
+
"react-day-picker",
|
|
40
|
+
"react",
|
|
41
|
+
"events",
|
|
42
|
+
"scheduling"
|
|
43
|
+
],
|
|
44
|
+
"license": "UNLICENSED",
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"react": ">=18.0.0",
|
|
47
|
+
"react-dom": ">=18.0.0"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@fullcalendar/core": "^6.1.20",
|
|
51
|
+
"@fullcalendar/daygrid": "^6.1.20",
|
|
52
|
+
"@fullcalendar/interaction": "^6.1.20",
|
|
53
|
+
"@fullcalendar/react": "^6.1.20",
|
|
54
|
+
"@fullcalendar/timegrid": "^6.1.20",
|
|
55
|
+
"@radix-ui/react-popover": "^1.1.6",
|
|
56
|
+
"clsx": "^2.1.1",
|
|
57
|
+
"lucide-react": "^0.469.0",
|
|
58
|
+
"motion": "^12.0.0",
|
|
59
|
+
"react-day-picker": "^9.4.0"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@tailwindcss/cli": "^4.1.18",
|
|
63
|
+
"@tailwindcss/vite": "^4.2.2",
|
|
64
|
+
"@types/react": "^19.2.3",
|
|
65
|
+
"@types/react-dom": "^19.2.3",
|
|
66
|
+
"@vitejs/plugin-react": "^6.0.1",
|
|
67
|
+
"react": "^19.1.0",
|
|
68
|
+
"react-dom": "^19.1.0",
|
|
69
|
+
"tailwindcss": "^4.1.18",
|
|
70
|
+
"tsup": "^8.5.1",
|
|
71
|
+
"typescript": "^5.9.3",
|
|
72
|
+
"vite": "^8.0.7"
|
|
73
|
+
},
|
|
74
|
+
"scripts": {
|
|
75
|
+
"build:css": "tailwindcss -i src/styles/input.css -o dist/style.css --minify && node ../../scripts/scope-css.mjs dist/style.css .ape-calendar",
|
|
76
|
+
"build": "tsup && pnpm run build:css",
|
|
77
|
+
"dev": "vite --config dev/vite.config.ts",
|
|
78
|
+
"type-check": "tsc --noEmit",
|
|
79
|
+
"clean": "rm -rf dist .turbo"
|
|
80
|
+
}
|
|
81
|
+
}
|