@marco.colia/react-fast-scheduler 3.1.0 → 3.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 CHANGED
@@ -8,7 +8,7 @@ A lightweight React day scheduler for resource-based booking UIs.
8
8
  - drag and resize interactions
9
9
  - date navigation with a built-in toolbar and date picker
10
10
  - customizable appointment rendering
11
- - a simple adapter layer for your backend data
11
+ - a simple field adapter layer for your backend data
12
12
 
13
13
  ![Scheduler demo](https://res.cloudinary.com/dt74zb1rv/image/upload/v1774457086/Video_del_2026-03-25_17-35-51_kuflee.gif)
14
14
 
@@ -48,7 +48,7 @@ import {
48
48
  Scheduler,
49
49
  applySchedulerAppointmentChange,
50
50
  type BaseSchedulerResource,
51
- type SchedulerAppointmentChangeArgs,
51
+ type SchedulerAppointmentChangeEvent,
52
52
  } from "@marco.colia/react-fast-scheduler";
53
53
  import "@marco.colia/react-fast-scheduler/styles.css";
54
54
 
@@ -103,13 +103,14 @@ export const SchedulerExample = () => {
103
103
  };
104
104
 
105
105
  const handleAppointmentChange = async (
106
- change: SchedulerAppointmentChangeArgs<Appointment, number>
106
+ change: SchedulerAppointmentChangeEvent<Appointment, number>
107
107
  ) => {
108
108
  const optimisticAppointments = applySchedulerAppointmentChange(appointments, change, {
109
- getId: (item) => item.id,
110
- setResourceId: (item, resourceId) => ({ ...item, staffId: resourceId }),
111
- setStart: (item, start) => ({ ...item, start: start.toISOString() }),
112
- setEnd: (item, end) => ({ ...item, end: end.toISOString() }),
109
+ id: "id",
110
+ resourceId: "staffId",
111
+ start: "start",
112
+ end: "end",
113
+ dateValue: (date) => date.toISOString(),
113
114
  });
114
115
 
115
116
  setAppointments(optimisticAppointments);
@@ -144,11 +145,11 @@ export const SchedulerExample = () => {
144
145
  selectedDate={selectedDate}
145
146
  onSelectedDateChange={setSelectedDate}
146
147
  adapter={{
147
- getId: (item) => item.id,
148
- getResourceId: (item) => item.staffId,
149
- getStart: (item) => item.start,
150
- getEnd: (item) => item.end,
151
- getTitle: (item) => `${item.customerName} - ${item.title}`,
148
+ id: "id",
149
+ resourceId: "staffId",
150
+ start: "start",
151
+ end: "end",
152
+ title: (item) => `${item.customerName} - ${item.title}`,
152
153
  }}
153
154
  onAppointmentChange={handleAppointmentChange}
154
155
  dayStart="09:00"
@@ -210,7 +211,33 @@ Appointments stay in your own shape. The scheduler reads them through the `adapt
210
211
 
211
212
  ### `adapter`
212
213
 
213
- The adapter maps your appointment structure into scheduler fields:
214
+ The simplest adapter maps appointment object fields by key:
215
+
216
+ ```tsx
217
+ adapter={{
218
+ id: "id",
219
+ resourceId: "staffId",
220
+ start: "start",
221
+ end: "end",
222
+ title: "title",
223
+ }}
224
+ ```
225
+
226
+ Each field can also be a function when you need to derive a value:
227
+
228
+ ```tsx
229
+ adapter={{
230
+ id: "id",
231
+ resourceId: "staffId",
232
+ start: "start",
233
+ end: "end",
234
+ title: (item) => `${item.customerName} - ${item.title}`,
235
+ }}
236
+ ```
237
+
238
+ Start and end fields can resolve to either a `Date` or a date string.
239
+
240
+ The older getter adapter is still supported:
214
241
 
215
242
  ```tsx
216
243
  adapter={{
@@ -222,8 +249,6 @@ adapter={{
222
249
  }}
223
250
  ```
224
251
 
225
- `getStart` and `getEnd` can return either a `Date` or a date string.
226
-
227
252
  ## Drag, Resize, and Persistence
228
253
 
229
254
  Use `onAppointmentChange` as the main integration point for move and resize operations.
@@ -231,6 +256,8 @@ Use `onAppointmentChange` as the main integration point for move and resize oper
231
256
  It receives:
232
257
 
233
258
  - `appointment`: the original raw appointment
259
+ - `resourceId`, `start`, and `end`: the new values after drop
260
+ - `previousResourceId`, `previousStart`, and `previousEnd`: the values before drag or resize
234
261
  - `previous`: the previous resource and time range
235
262
  - `next`: the new resource and time range after drop
236
263
  - `kind`: `"move"` or `"resize"`
@@ -240,12 +267,12 @@ Example:
240
267
  ```tsx
241
268
  <Scheduler
242
269
  // ...other props
243
- onAppointmentChange={async ({ appointment, next }) => {
270
+ onAppointmentChange={async ({ appointment, resourceId, start, end }) => {
244
271
  const nextAppointment = {
245
272
  ...appointment,
246
- staffId: next.resourceId,
247
- start: next.start.toISOString(),
248
- end: next.end.toISOString(),
273
+ staffId: resourceId,
274
+ start: start.toISOString(),
275
+ end: end.toISOString(),
249
276
  };
250
277
 
251
278
  await fetch(`/api/appointments/${appointment.id}`, {
@@ -261,13 +288,16 @@ If you want a small helper for optimistic local state updates, use `applySchedul
261
288
 
262
289
  ```tsx
263
290
  const nextAppointments = applySchedulerAppointmentChange(appointments, change, {
264
- getId: (item) => item.id,
265
- setResourceId: (item, resourceId) => ({ ...item, staffId: resourceId }),
266
- setStart: (item, start) => ({ ...item, start: start.toISOString() }),
267
- setEnd: (item, end) => ({ ...item, end: end.toISOString() }),
291
+ id: "id",
292
+ resourceId: "staffId",
293
+ start: "start",
294
+ end: "end",
295
+ dateValue: (date) => date.toISOString(),
268
296
  });
269
297
  ```
270
298
 
299
+ The previous setter-based helper options are still supported for non-object data or custom immutable updates.
300
+
271
301
  `onPersistMoveResize` is still available as a legacy callback, but `onAppointmentChange` is the recommended API.
272
302
 
273
303
  If you want to render the scheduler in read-only mode, use `editable={false}`:
@@ -451,11 +481,11 @@ If you want to keep the default toolbar but swap the date picker UI, use `render
451
481
  - `appointments`: array of raw appointment objects
452
482
  - `selectedDate`: currently visible day
453
483
  - `onSelectedDateChange`: controlled date change handler
454
- - `adapter`: mapper between your appointment shape and scheduler fields
484
+ - `adapter`: key-based or getter-based mapper between your appointment shape and scheduler fields
455
485
 
456
486
  ### Common optional props
457
487
 
458
- - `onAppointmentChange`: async or sync handler for move and resize persistence
488
+ - `onAppointmentChange`: async or sync handler for move and resize persistence; receives both flat next values and the nested `previous`/`next` objects
459
489
  - `editable`: enables or disables move and resize interactions, defaults to `true`
460
490
  - `renderToolbar`: replace the full toolbar
461
491
  - `renderDatePicker`: replace only the date picker slot used by the default toolbar
@@ -476,6 +506,7 @@ If you want to keep the default toolbar but swap the date picker UI, use `render
476
506
  - Keep `selectedDate` in application state and fetch data when it changes.
477
507
  - Prefer formatting dates in local time for day-based API queries. `toISOString().slice(0, 10)` can shift the day around midnight because it uses UTC.
478
508
  - If persistence fails after a drag or resize, either roll back local state or refetch the visible day.
509
+ - For large schedules, keep `resources`, `appointments`, adapter objects, and render callbacks stable when their data has not changed so React can reuse scheduler calculations.
479
510
  - Import the package CSS once at app startup.
480
511
 
481
512
  ## Development
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- 'use strict';var jsxRuntime=require('react/jsx-runtime'),dateFns=require('date-fns'),h=require('react');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var h__namespace=/*#__PURE__*/_interopNamespace(h);var it=e=>{let{isDropInvalid:t,description:r,title:o}=e;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[t&&jsxRuntime.jsx("div",{className:"rfs:absolute rfs:right-1 rfs:top-1 rfs:flex rfs:h-4 rfs:w-4 rfs:items-center rfs:justify-center rfs:rounded-full rfs:bg-red-600 rfs:text-[10px] rfs:font-bold rfs:text-white",children:"X"}),jsxRuntime.jsx("div",{className:"rfs:text-xs rfs:font-semibold",children:o}),r&&jsxRuntime.jsx("div",{className:"rfs:mt-1 rfs:text-[10px] rfs:font-medium",children:r})]})},me=it;function oe({appointment:e,onResizePointerDown:t}){return jsxRuntime.jsx("div",{role:"button","aria-label":"Resize appointment",onPointerDown:r=>{e.visualState!=="ghost"&&(r.stopPropagation(),t(r));},className:"rfs:absolute rfs:inset-x-1 rfs:bottom-1 rfs:h-2 rfs:cursor-ns-resize rfs:rounded-full rfs:bg-border/90 rfs:transition-colors rfs:hover:bg-border"})}function G({appointment:e,isDropInvalid:t,onPointerDown:r,onResizePointerDown:o,appointmentAppearance:n,appointmentBackgroundColor:i}){let c=e.raw,a=typeof c.description=="string"?c.description:void 0,s=typeof i=="string"?i:void 0,d=n?.className??s??"rfs:bg-muted/40 rfs:dark:bg-muted/30",f=t?"rfs:bg-red-100/80 rfs:text-red-950 rfs:dark:bg-red-950/40 rfs:dark:text-red-100":"",l=e.visualState==="ghost"?"rfs:cursor-grab rfs:opacity-35":e.visualState==="dragging"?"rfs:cursor-grabbing rfs:opacity-55 rfs:shadow-xl":"rfs:cursor-grab",g=`rfs:relative rfs:h-full rfs:overflow-hidden rfs:rounded-md rfs:p-2 rfs:pb-5 rfs:text-foreground ${d} ${f} ${l}`;return jsxRuntime.jsxs("div",{onPointerDown:r,className:g,children:[jsxRuntime.jsx(me,{isDropInvalid:t,title:e.title,description:a}),jsxRuntime.jsx(oe,{onResizePointerDown:o,appointment:e})]})}function he(e){if(!e||typeof e!="object")return false;let t=e;return typeof t.firstName=="string"||typeof t.lastName=="string"}var Te={slate:"bg-slate-100 dark:bg-slate-900/40",gray:"bg-gray-100 dark:bg-gray-900/40",zinc:"bg-zinc-100 dark:bg-zinc-900/40",neutral:"bg-neutral-100 dark:bg-neutral-900/40",stone:"bg-stone-100 dark:bg-stone-900/40",red:"bg-red-100 dark:bg-red-950/40",orange:"bg-orange-100 dark:bg-orange-950/40",amber:"bg-amber-100 dark:bg-amber-950/40",yellow:"bg-yellow-100 dark:bg-yellow-950/40",lime:"bg-lime-100 dark:bg-lime-950/40",green:"bg-green-100 dark:bg-green-950/40",emerald:"bg-emerald-100 dark:bg-emerald-950/40",teal:"bg-teal-100 dark:bg-teal-950/40",cyan:"bg-cyan-100 dark:bg-cyan-950/40",sky:"bg-sky-100 dark:bg-sky-950/40",blue:"bg-blue-100 dark:bg-blue-950/40",indigo:"bg-indigo-100 dark:bg-indigo-950/40",violet:"bg-violet-100 dark:bg-violet-950/40",purple:"bg-purple-100 dark:bg-purple-950/40",fuchsia:"bg-fuchsia-100 dark:bg-fuchsia-950/40",pink:"bg-pink-100 dark:bg-pink-950/40",rose:"bg-rose-100 dark:bg-rose-950/40"};function D(e,t,r){return Math.max(t,Math.min(r,e))}function U(e,t=15){return Math.round(e/t)*t}function se(e){let[t,r]=e.split(":").map(Number);return t*60+r}function Ie(e){return `${e.firstName??""} ${e.lastName??""}`.trim()}function K(e){return dateFns.format(e,"yyyy-MM-dd")}function ie(e,t){return new Date(e.getFullYear(),e.getMonth(),e.getDate()+t)}function z(e,t,r){let o=new Date(e.getFullYear(),e.getMonth(),e.getDate(),0,0,0,0),n=t+r,i=Math.floor(n/60),c=n%60;return o.setHours(i,c,0,0),o}function ae(e,t){return t.getHours()*60+t.getMinutes()-e}function ce(e,t){return e.startMin<t.endMin&&t.startMin<e.endMin}function Se(e){let t=[...e].sort((c,a)=>c.startMin-a.startMin||c.endMin-a.endMin),r=[],o=[],n=[];for(let c of t)o=o.filter(s=>s.endMin>c.startMin),!o.some(s=>ce(s,c))&&n.length>0&&(r.push(n),n=[]),n.push(c),o.push(c);n.length&&r.push(n);let i=[];for(let c of r){let a=[...c].sort((l,g)=>l.startMin-g.startMin||l.endMin-g.endMin),s=[],d=new Map;for(let l of a){let g=false;for(let p=0;p<s.length;p++)if(s[p]<=l.startMin){s[p]=l.endMin,d.set(l.id,p),g=true;break}g||(s.push(l.endMin),d.set(l.id,s.length-1));}let f=s.length;for(let l of a)i.push({...l,lane:d.get(l.id)??0,lanes:f});}return i}function ue({fallback:e,getValue:t,resources:r,toKey:o}){let n=new Map;for(let i of r)n.set(o(i),t(i)??e);return n}function be({adapter:e,appointments:t,dayMinutes:r,dayStartAbs:o,selectedISO:n}){return t.map(i=>{let c=new Date(e.getStart(i)),a=new Date(e.getEnd(i));return {raw:i,id:e.getId(i),resourceId:e.getResourceId(i),start:c,end:a,startMin:D(ae(o,c),0,r),endMin:D(ae(o,a),0,r),title:e.getTitle(i),renderKey:String(e.getId(i)),visualState:"normal"}}).filter(i=>K(i.start)===n)}function ye(e){return new Map(e.map(t=>[t.id,t]))}function Me(e,t,r,o){return t.kind==="none"||t.kind==="move"?e:e.map(n=>n.id!==t.appointmentId?n:{...n,resourceId:t.resourceId,startMin:t.startMin,endMin:t.endMin,start:z(r,o,t.startMin),end:z(r,o,t.endMin),visualState:"dragging"})}function Ae(e,t){let r=new Map;for(let n of t){let i=r.get(n.resourceId)??[];i.push(n),r.set(n.resourceId,i);}let o=new Map;for(let n of e)o.set(n.id,de(r.get(n.id)??[]));return o}function de(e){return Se(e.map(t=>({...t,appointmentId:t.id,id:t.renderKey}))).map(({appointmentId:t,...r})=>({...r,id:t}))}function Pe(e,t,r,o,n){let i=new Map;for(let c of e){let a=t?.[String(c.id)];if(a){i.set(c.id,{className:a});continue}let s=r?.(c);if(s){i.set(c.id,s);continue}let d=o.get(c.id);if(d){i.set(c.id,{className:d});continue}let f=n.get(c.id);i.set(c.id,f?{className:f}:void 0);}return i}function De({adapter:e,appointments:t,dayEnd:r="18:00",dayStart:o="09:00",resources:n,selectedDate:i}){let c=h__namespace.useMemo(()=>se(o),[o]),a=h__namespace.useMemo(()=>se(r),[r]),s=h__namespace.useMemo(()=>Math.max(0,a-c),[a,c]),d=h__namespace.useMemo(()=>12+s*2+24,[s]),f=h__namespace.useMemo(()=>72+Math.max(n.length,1)*420,[n.length]),l=h__namespace.useMemo(()=>K(i),[i]),g=h__namespace.useMemo(()=>be({adapter:e,appointments:t,dayMinutes:s,dayStartAbs:c,selectedISO:l}),[e,t,s,c,l]);return {appointmentMap:h__namespace.useMemo(()=>ye(g),[g]),dayEndAbs:a,dayMinutes:s,dayStartAbs:c,gridHeight:d,gridMinWidth:f,renderAppts:g}}var pt=4,ft=(e,t)=>{e(r=>r&&{...r,clientX:t.clientX,clientY:t.clientY});},mt=e=>{let{dragRef:t,pendingDragRef:r,pointer:o,setDrag:n,setMovePreview:i,suppressClickRef:c}=e,a=r.current;if(!a||a.drag.pointerId!==o.pointerId)return;let s=o.clientX-a.startClientX,d=o.clientY-a.startClientY;Math.hypot(s,d)<pt||(c.current=true,t.current=a.drag,n(a.drag),a.drag.kind==="move"&&i({appointment:a.appointment,clientX:o.clientX,clientY:o.clientY,width:a.width,height:a.height,offsetX:a.offsetX,offsetY:a.offsetY}),r.current=null);},Rt=(e,t,r,o,n)=>{let i=o(t.clientX,e.resourceId),a=n(i,t.clientY)-e.offsetMin,s=D(U(a),0,r-e.durationMin),d=s+e.durationMin;return s===e.startMin&&d===e.endMin&&i===e.resourceId?null:{...e,resourceId:i,startMin:s,endMin:d}},gt=(e,t,r,o)=>{let n=o(e.resourceId,t.clientY),i=D(U(n),e.startMin+15,r);return i===e.endMin?null:{...e,endMin:i}},we=e=>{let{dayMinutes:t,dragRef:r,latestPointerRef:o,pendingDragRef:n,pointerToMin:i,pointerToResourceId:c,setDrag:a,setMovePreview:s,suppressClickRef:d}=e,f=o.current;if(!f)return;let l=r.current;if(l.kind==="none"&&n.current){mt({pointer:f,pendingDragRef:n,setDrag:a,setMovePreview:s,dragRef:r,suppressClickRef:d});return}if(l.kind==="none")return;if(l.kind==="move"){ft(s,f);let p=Rt(l,f,t,c,i);p&&(d.current=true,r.current=p,a(p));return}let g=gt(l,f,t,i);g&&(d.current=true,r.current=g,a(g));},Ne=e=>{let{dragRef:t,frameRef:r,latestPointerRef:o,pendingDragRef:n,persistDrag:i,setDrag:c,setMovePreview:a,suppressClickRef:s}=e;r.current!==null&&(window.cancelAnimationFrame(r.current),r.current=null),o.current=null,n.current=null,a(null);let d=t.current;d.kind!=="none"&&(c({kind:"none"}),t.current={kind:"none"},s.current&&i(d));};var Ce=({appointmentMap:e,dayMinutes:t,dayStartAbs:r,onAppointmentChange:o,onPersistMoveResize:n,renderAppts:i,resources:c,selectedDate:a,editable:s})=>{let[d,f]=h__namespace.useState({kind:"none"}),[l,g]=h__namespace.useState(null),p=h__namespace.useRef({}),T=h__namespace.useRef(false),v=h__namespace.useRef({kind:"none"}),S=h__namespace.useRef(null),b=h__namespace.useRef(null),y=h__namespace.useRef(null);h__namespace.useEffect(()=>{v.current=d;},[d]),h__namespace.useEffect(()=>()=>{y.current!==null&&window.cancelAnimationFrame(y.current);},[]);let E=h__namespace.useCallback((u,m)=>{let R=p.current[String(u)];if(!R)return 0;let M=m-R.getBoundingClientRect().top-12;return D(U(M/2),0,t)},[t]),$=h__namespace.useCallback((u,m)=>{for(let R of c){let M=p.current[String(R.id)];if(!M)continue;let X=M.getBoundingClientRect();if(u>=X.left&&u<=X.right)return R.id}return m},[c]),O=h__namespace.useCallback((u,m,R,M)=>i.filter(k=>k.resourceId===m&&k.id!==u).some(k=>ce(k,{startMin:R,endMin:M})),[i]),Y=h__namespace.useMemo(()=>d.kind==="none"?false:O(d.appointmentId,d.resourceId,d.startMin,d.endMin),[d,O]),L=h__namespace.useCallback(async u=>{let m=e.get(u.appointmentId);if(!m||O(u.appointmentId,u.resourceId,u.startMin,u.endMin))return;let R={resourceId:u.resourceId,start:z(a,r,u.startMin),end:z(a,r,u.endMin)};if(o){await o({kind:u.kind,appointment:m.raw,previous:{resourceId:m.resourceId,start:m.start,end:m.end},next:R});return}n&&await n({appointment:m.raw,resourceId:R.resourceId,start:R.start,end:R.end});},[e,r,O,o,n,a]),F=h__namespace.useCallback((u,m)=>{if(!s||u.button!==0)return;u.stopPropagation(),T.current=false;let R=u.currentTarget.getBoundingClientRect(),M=E(m.resourceId,u.clientY);S.current={drag:{kind:"move",appointmentId:m.id,pointerId:u.pointerId,resourceId:m.resourceId,durationMin:Math.max(15,m.endMin-m.startMin),offsetMin:M-m.startMin,startMin:m.startMin,endMin:m.endMin},appointment:m,startClientX:u.clientX,startClientY:u.clientY,width:R.width,height:R.height,offsetX:u.clientX-R.left,offsetY:u.clientY-R.top};},[E,s]),j=h__namespace.useCallback((u,m)=>{s&&u.button===0&&(u.stopPropagation(),T.current=false,S.current={drag:{kind:"resize",appointmentId:m.id,pointerId:u.pointerId,resourceId:m.resourceId,startMin:m.startMin,endMin:m.endMin},appointment:m,startClientX:u.clientX,startClientY:u.clientY,width:0,height:0,offsetX:0,offsetY:0});},[s]),W=h__namespace.useCallback(u=>{b.current={clientX:u.clientX,clientY:u.clientY,pointerId:u.pointerId},y.current===null&&(y.current=window.requestAnimationFrame(()=>{y.current=null,we({dayMinutes:t,dragRef:v,latestPointerRef:b,pendingDragRef:S,pointerToMin:E,pointerToResourceId:$,setDrag:f,setMovePreview:g,suppressClickRef:T});}));},[t,E,$]),ee=h__namespace.useCallback(()=>{Ne({dragRef:v,frameRef:y,latestPointerRef:b,pendingDragRef:S,persistDrag:L,setDrag:f,setMovePreview:g,suppressClickRef:T});},[L]);return {colRefs:p,drag:d,isDropInvalid:Y,movePreview:l,onApptPointerDown:F,onGlobalPointerMove:W,onGlobalPointerUp:ee,onResizePointerDown:j,suppressClickRef:T}};function Be({appointmentColorTokenClassMap:e,dayStartAbs:t,drag:r,getResourceAppointmentAppearance:o,getResourceAppointmentBackground:n,getResourceAppointmentColorToken:i,renderAppts:c,resourceAppointmentClassMap:a,resources:s,selectedDate:d}){let f=h__namespace.useMemo(()=>Me(c,r,d,t),[t,r,c,d]),l=h__namespace.useMemo(()=>Ae(s,c),[c,s]),g=h__namespace.useMemo(()=>{if(r.kind!=="resize")return l;let S=new Map(l),b=f.filter(y=>y.resourceId===r.resourceId);return S.set(r.resourceId,de(b)),S},[l,r,f]),p=h__namespace.useMemo(()=>n?ue({fallback:void 0,getValue:n,resources:s,toKey:S=>S.id}):new Map,[n,s]),T=h__namespace.useMemo(()=>{if(!i)return new Map;let S={...Te,...e??{}};return ue({fallback:void 0,getValue:b=>{let y=i(b);return y?S[y]:void 0},resources:s,toKey:b=>b.id})},[e,i,s]);return {appointmentAppearanceByResource:h__namespace.useMemo(()=>Pe(s,a,o,T,p),[p,T,o,a,s]),appointmentBgByResource:p,effectiveAppts:f,laidOutByResource:g}}function Ee({dayMinutes:e,dayStartAbs:t,gridHeight:r}){return jsxRuntime.jsx("div",{className:"rfs-times rfs:border-border rfs:bg-card",style:{width:72,height:r},children:Array.from({length:Math.floor(e/60)+1}).map((o,n)=>jsxRuntime.jsxs("div",{className:"rfs-time-tick rfs:text-muted-foreground",style:{top:12+n*60*2},children:[String(Math.floor((t+n*60)/60)).padStart(2,"0"),":",String((t+n*60)%60).padStart(2,"0")]},`tick-${n}`))})}function Oe({resource:e}){return jsxRuntime.jsx("strong",{children:e.label})}function ze({resources:e,renderResourceHeader:t}){return jsxRuntime.jsxs("div",{className:"rfs-header rfs:border-border rfs:bg-card",children:[jsxRuntime.jsx("div",{className:"rfs-gutter rfs:border-border",style:{width:72}}),e.map(r=>jsxRuntime.jsxs("div",{className:"rfs-resource-header rfs:border-border rfs:bg-card rfs:text-foreground",style:{minWidth:420,flex:1},children:[(t??(o=>Oe({resource:o})))(r),he(r)?jsxRuntime.jsx("div",{className:"rfs-resource-subtitle rfs:text-muted-foreground",children:Ie(r)}):null]},String(r.id)))]})}var He=({resource:e,colRefs:t,gridHeight:r,dayMinutes:o,appointments:n,appointmentAppearance:i,appointmentBg:c,isDropInvalid:a,renderAppointment:s,onApptPointerDown:d,onResizePointerDown:f,drag:l,suppressClickRef:g})=>jsxRuntime.jsx("div",{className:"rfs-col rfs:border-border rfs:bg-card",style:{minWidth:420,flex:1},children:jsxRuntime.jsxs("div",{ref:p=>{t.current[String(e.id)]=p;},className:"rfs-col-inner rfs:bg-card",style:{height:r},children:[Array.from({length:Math.floor(o/60)+1}).map((p,T)=>jsxRuntime.jsx("div",{className:"rfs-hour-line rfs:border-border/70",style:{top:12+T*60*2}},`major-${T}`)),Array.from({length:Math.floor(o/15)+1}).map((p,T)=>jsxRuntime.jsx("div",{className:"rfs-slot-line rfs:border-border/50",style:{top:12+T*15*2}},`minor-${T}`)),n.map(p=>{let T=100/p.lanes,v=12+p.startMin*2,S=Math.max(30,(p.endMin-p.startMin)*2);return jsxRuntime.jsx("div",{className:`rfs-card-slot ${p.visualState==="ghost"?"rfs-card-slot--ghost":""} ${p.visualState==="dragging"?"rfs-card-slot--dragging":""}`,style:{top:v,left:`${T*p.lane}%`,width:`${T}%`,height:S},children:(s??G)({appointment:p,isDropInvalid:a&&l.kind==="resize"&&p.id===l.appointmentId,onPointerDown:b=>d(b,p),onResizePointerDown:b=>f(b,p),appointmentAppearance:i,appointmentBackgroundColor:c,drag:l,suppressClickRef:g})},p.renderKey)})]})});var bt=(e,t)=>[e.resource===t.resource,e.colRefs===t.colRefs,e.gridHeight===t.gridHeight,e.dayMinutes===t.dayMinutes,e.appointments===t.appointments,e.appointmentAppearance===t.appointmentAppearance,e.appointmentBg===t.appointmentBg,e.isDropInvalid===t.isDropInvalid,e.renderAppointment===t.renderAppointment,e.onApptPointerDown===t.onApptPointerDown,e.onResizePointerDown===t.onResizePointerDown,e.drag===t.drag,e.suppressClickRef===t.suppressClickRef].every(Boolean),Xe=h__namespace.memo(He,bt);function H(...e){return e.filter(Boolean).join(" ")}var yt={default:"rfs:bg-primary rfs:text-primary-foreground rfs:hover:bg-primary/90",outline:"rfs:border rfs:border-border rfs:bg-card rfs:text-foreground rfs:hover:bg-muted",ghost:"rfs:text-foreground rfs:hover:bg-muted"},Mt={default:"rfs:h-9 rfs:px-4 rfs:py-2",sm:"rfs:h-8 rfs:px-3 rfs:text-xs",icon:"rfs:h-8 rfs:w-8"},P=h__namespace.forwardRef(function({className:t,variant:r="default",size:o="default",type:n="button",...i},c){return jsxRuntime.jsx("button",{ref:c,type:n,className:H("rfs:inline-flex rfs:items-center rfs:justify-center rfs:gap-2 rfs:rounded-md rfs:text-sm rfs:font-medium rfs:whitespace-nowrap rfs:transition-colors rfs:focus-visible:outline-none rfs:focus-visible:ring-2 rfs:focus-visible:ring-ring rfs:focus-visible:ring-offset-2 rfs:disabled:pointer-events-none rfs:disabled:opacity-50",yt[r],Mt[o],t),...i})});function We({selected:e,onSelect:t}){let[r,o]=h__namespace.useState(e??new Date);h__namespace.useEffect(()=>{e&&o(e);},[e]);let n=dateFns.startOfMonth(r),i=dateFns.startOfWeek(n,{weekStartsOn:1}),c=dateFns.endOfWeek(dateFns.endOfMonth(r),{weekStartsOn:1}),a=[];for(let s=i;s<=c;s=dateFns.addDays(s,1))a.push(s);return jsxRuntime.jsxs("div",{className:"rfs:w-72 rfs:rounded-md rfs:bg-popover",children:[jsxRuntime.jsxs("div",{className:"rfs:mb-2 rfs:flex rfs:items-center rfs:justify-between",children:[jsxRuntime.jsx(P,{variant:"ghost",size:"icon","aria-label":"Previous month",onClick:()=>o(dateFns.addMonths(r,-1)),children:"<"}),jsxRuntime.jsx("div",{className:"rfs:text-sm rfs:font-medium",children:dateFns.format(r,"MMMM yyyy")}),jsxRuntime.jsx(P,{variant:"ghost",size:"icon","aria-label":"Next month",onClick:()=>o(dateFns.addMonths(r,1)),children:">"})]}),jsxRuntime.jsx("div",{className:"rfs:grid rfs:grid-cols-7 rfs:gap-1 rfs:text-center rfs:text-xs rfs:text-muted-foreground",children:["Mo","Tu","We","Th","Fr","Sa","Su"].map(s=>jsxRuntime.jsx("div",{className:"rfs:py-1",children:s},s))}),jsxRuntime.jsx("div",{className:"rfs:grid rfs:grid-cols-7 rfs:gap-1",children:a.map(s=>{let d=e?dateFns.isSameDay(s,e):false;return jsxRuntime.jsx(P,{variant:d?"default":"ghost",size:"icon",className:H("rfs:text-xs",!dateFns.isSameMonth(s,r)&&"rfs:text-muted-foreground rfs:opacity-60",dateFns.isToday(s)&&!d&&"rfs:border rfs:border-border"),onClick:()=>t?.(s),children:dateFns.format(s,"d")},s.toISOString())})})]})}var Ge=h__namespace.createContext(null);function Ke(){let e=h__namespace.useContext(Ge);if(!e)throw new Error("Popover components must be used within Popover.");return e}function qe({children:e,open:t,onOpenChange:r}){let[o,n]=h__namespace.useState(false),i=h__namespace.useRef(null),c=h__namespace.useRef(null),a=t??o,s=h__namespace.useCallback(d=>{let f=typeof d=="function"?d(a):d;t===void 0&&n(f),r?.(f);},[t,r,a]);return h__namespace.useEffect(()=>{if(!a)return;let d=l=>{let g=l.target;i.current?.contains(g)||c.current?.contains(g)||s(false);},f=l=>{l.key==="Escape"&&s(false);};return document.addEventListener("mousedown",d),document.addEventListener("keydown",f),()=>{document.removeEventListener("mousedown",d),document.removeEventListener("keydown",f);}},[a,s]),jsxRuntime.jsx(Ge.Provider,{value:{open:a,setOpen:s,triggerRef:i,contentRef:c},children:jsxRuntime.jsx("div",{className:"rfs:relative rfs:inline-flex",children:e})})}function Je({children:e,asChild:t=false}){let{open:r,setOpen:o,triggerRef:n}=Ke();if(t&&h__namespace.isValidElement(e)){let i=e;return h__namespace.cloneElement(i,{ref:n,"aria-expanded":r,onClick:c=>{i.props.onClick?.(c),o(a=>!a);}})}return jsxRuntime.jsx("button",{ref:n,type:"button","aria-expanded":r,onClick:()=>o(i=>!i),children:e})}function Qe({children:e,className:t,align:r="start"}){let{open:o,contentRef:n}=Ke();return o?jsxRuntime.jsx("div",{ref:n,className:H("rfs:absolute rfs:top-full rfs:z-50 rfs:mt-2 rfs:min-w-72 rfs:rounded-md rfs:border rfs:border-border rfs:bg-popover rfs:p-2 rfs:text-popover-foreground rfs:shadow-md rfs:outline-none",r==="start"&&"rfs:left-0",r==="center"&&"rfs:left-1/2 rfs:-translate-x-1/2",r==="end"&&"rfs:right-0",t),children:e}):null}function Ze({selectedDate:e,onSelectedDateChange:t}){return jsxRuntime.jsxs(qe,{children:[jsxRuntime.jsx(Je,{asChild:true,children:jsxRuntime.jsx(P,{variant:"outline",size:"sm",className:"rfs:min-w-40 rfs:justify-start rfs:text-left rfs:font-normal",children:dateFns.format(e,"PPP")})}),jsxRuntime.jsx(Qe,{className:"rfs:w-auto rfs:p-2",align:"center",children:jsxRuntime.jsx(We,{selected:e,onSelect:t})})]})}function je({goToPreviousDay:e,goToNextDay:t,defaultDatePicker:r,prevButtonLabel:o="Prev",nextButtonLabel:n="Next"}){return jsxRuntime.jsx("div",{className:"rfs-toolbar",children:jsxRuntime.jsxs("div",{className:"rfs:flex rfs:items-center rfs:gap-2 rfs:rounded-lg rfs:border rfs:border-border rfs:bg-card rfs:p-1 rfs:shadow-xs",children:[jsxRuntime.jsx(P,{variant:"outline",size:"sm",onClick:e,children:o}),r,jsxRuntime.jsx(P,{variant:"outline",size:"sm",onClick:t,children:n})]})})}function rt({selectedDate:e,onSelectedDateChange:t,prevButtonLabel:r,nextButtonLabel:o,renderToolbar:n,renderDatePicker:i}){let c=()=>t(ie(e,-1)),a=()=>t(ie(e,1)),s=(i??Ze)({selectedDate:e,onSelectedDateChange:t});return n?jsxRuntime.jsx(jsxRuntime.Fragment,{children:n({selectedDate:e,onSelectedDateChange:t,goToPreviousDay:c,goToNextDay:a,defaultDatePicker:s})}):jsxRuntime.jsx(jsxRuntime.Fragment,{children:je({goToPreviousDay:c,goToNextDay:a,defaultDatePicker:s,prevButtonLabel:r,nextButtonLabel:o})})}var Lt={kind:"none"};function _t({resources:e,appointments:t,selectedDate:r,onSelectedDateChange:o,adapter:n,onPersistMoveResize:i,onAppointmentChange:c,renderResourceHeader:a,renderAppointment:s,resourceAppointmentClassMap:d,getResourceAppointmentAppearance:f,getResourceAppointmentColorToken:l,appointmentColorTokenClassMap:g,getResourceAppointmentBackground:p,renderToolbar:T,renderDatePicker:v,prevButtonLabel:S="Prev",nextButtonLabel:b="Next",dayStart:y="09:00",dayEnd:E="18:00",editable:$=true}){let{appointmentMap:O,dayMinutes:Y,dayStartAbs:L,gridHeight:F,gridMinWidth:j,renderAppts:W}=De({adapter:n,appointments:t,dayEnd:E,dayStart:y,resources:e,selectedDate:r}),{colRefs:ee,drag:u,isDropInvalid:m,movePreview:R,onApptPointerDown:M,onGlobalPointerMove:X,onGlobalPointerUp:k,onResizePointerDown:ot,suppressClickRef:fe}=Ce({appointmentMap:O,dayMinutes:Y,dayStartAbs:L,onAppointmentChange:c,onPersistMoveResize:i,renderAppts:W,resources:e,selectedDate:r,editable:$}),{appointmentAppearanceByResource:te,appointmentBgByResource:re,laidOutByResource:st}=Be({appointmentColorTokenClassMap:g,dayStartAbs:L,drag:u,getResourceAppointmentAppearance:f,getResourceAppointmentBackground:p,getResourceAppointmentColorToken:l,renderAppts:W,resourceAppointmentClassMap:d,resources:e,selectedDate:r}),x=h__namespace.useMemo(()=>u.kind!=="move"||!R?null:{appointment:{...R.appointment,resourceId:u.resourceId,startMin:u.startMin,endMin:u.endMin,visualState:"ghost",renderKey:`${R.appointment.renderKey}-overlay`,lane:0,lanes:1},appearance:te.get(u.resourceId),background:re.get(u.resourceId),left:R.clientX-R.offsetX,top:R.clientY-R.offsetY,width:R.width,height:R.height},[te,re,u,R]);return jsxRuntime.jsxs("section",{className:`rfs-root rfs:rounded-lg rfs:text-foreground ${u.kind==="move"?"rfs-root--drag-move":""} ${u.kind==="resize"?"rfs-root--drag-resize":""}`,onPointerMove:X,onPointerUp:k,onPointerCancel:k,children:[jsxRuntime.jsx(rt,{selectedDate:r,onSelectedDateChange:o,prevButtonLabel:S,nextButtonLabel:b,renderToolbar:T,renderDatePicker:v}),jsxRuntime.jsx("div",{className:"rfs-shell rfs:border-border rfs:bg-card",children:jsxRuntime.jsxs("div",{style:{minWidth:j},children:[jsxRuntime.jsx(ze,{resources:e,renderResourceHeader:a}),jsxRuntime.jsxs("div",{className:"rfs-body",children:[jsxRuntime.jsx(Ee,{dayMinutes:Y,dayStartAbs:L,gridHeight:F}),jsxRuntime.jsx("div",{className:"rfs-grid",children:e.map(_=>jsxRuntime.jsx(Xe,{resource:_,colRefs:ee,gridHeight:F,dayMinutes:Y,appointments:st.get(_.id)??[],appointmentAppearance:te.get(_.id),appointmentBg:re.get(_.id),isDropInvalid:m,renderAppointment:s,onApptPointerDown:M,onResizePointerDown:ot,drag:u.kind==="resize"&&u.resourceId===_.id?u:Lt,suppressClickRef:fe},String(_.id)))})]})]})}),x?jsxRuntime.jsx("div",{className:"rfs-drag-overlay",style:{left:x.left,top:x.top,width:x.width,height:x.height},children:(s??G)({appointment:x.appointment,isDropInvalid:m,onPointerDown:()=>{},onResizePointerDown:()=>{},appointmentAppearance:x.appearance,appointmentBackgroundColor:x.background,drag:u,suppressClickRef:fe})}):null]})}function zt(e,t,r){return e.map(o=>{if(r.getId(o)!==r.getId(t.appointment))return o;let n=r.setResourceId(o,t.next.resourceId),i=r.setStart(n,t.next.start);return r.setEnd(i,t.next.end)})}exports.Scheduler=_t;exports.applySchedulerAppointmentChange=zt;
1
+ 'use strict';var jsxRuntime=require('react/jsx-runtime'),dateFns=require('date-fns'),g=require('react');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var g__namespace=/*#__PURE__*/_interopNamespace(g);var ct=e=>{let{isDropInvalid:t,description:r,title:o}=e;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[t&&jsxRuntime.jsx("div",{className:"rfs:absolute rfs:right-1 rfs:top-1 rfs:flex rfs:h-4 rfs:w-4 rfs:items-center rfs:justify-center rfs:rounded-full rfs:bg-red-600 rfs:text-[10px] rfs:font-bold rfs:text-white",children:"X"}),jsxRuntime.jsx("div",{className:"rfs:text-xs rfs:font-semibold",children:o}),r&&jsxRuntime.jsx("div",{className:"rfs:mt-1 rfs:text-[10px] rfs:font-medium",children:r})]})},ge=ct;function ie({appointment:e,onResizePointerDown:t}){return jsxRuntime.jsx("div",{role:"button","aria-label":"Resize appointment",onPointerDown:r=>{e.visualState!=="ghost"&&(r.stopPropagation(),t(r));},className:"rfs:absolute rfs:inset-x-1 rfs:bottom-1 rfs:h-2 rfs:cursor-ns-resize rfs:rounded-full rfs:bg-border/90 rfs:transition-colors rfs:hover:bg-border"})}function q({appointment:e,isDropInvalid:t,onPointerDown:r,onResizePointerDown:o,appointmentAppearance:n,appointmentBackgroundColor:i}){let u=e.raw,d=typeof u.description=="string"?u.description:void 0,s=typeof i=="string"?i:void 0,c=n?.className??s??"rfs:bg-muted/40 rfs:dark:bg-muted/30",m=t?"rfs:bg-red-100/80 rfs:text-red-950 rfs:dark:bg-red-950/40 rfs:dark:text-red-100":"",f=e.visualState==="ghost"?"rfs:cursor-grab rfs:opacity-35":e.visualState==="dragging"?"rfs:cursor-grabbing rfs:opacity-55 rfs:shadow-xl":"rfs:cursor-grab",R=`rfs:relative rfs:h-full rfs:overflow-hidden rfs:rounded-md rfs:p-2 rfs:pb-5 rfs:text-foreground ${c} ${m} ${f}`;return jsxRuntime.jsxs("div",{onPointerDown:r,className:R,children:[jsxRuntime.jsx(ge,{isDropInvalid:t,title:e.title,description:d}),jsxRuntime.jsx(ie,{onResizePointerDown:o,appointment:e})]})}var F=(e,t)=>typeof t=="function"?t(e):e[t],de=e=>"getId"in e?e:{getEnd:t=>F(t,e.end),getId:t=>F(t,e.id),getResourceId:t=>F(t,e.resourceId),getStart:t=>F(t,e.start),getTitle:t=>F(t,e.title)};function Se(e){if(!e||typeof e!="object")return false;let t=e;return typeof t.firstName=="string"||typeof t.lastName=="string"}var be={slate:"bg-slate-100 dark:bg-slate-900/40",gray:"bg-gray-100 dark:bg-gray-900/40",zinc:"bg-zinc-100 dark:bg-zinc-900/40",neutral:"bg-neutral-100 dark:bg-neutral-900/40",stone:"bg-stone-100 dark:bg-stone-900/40",red:"bg-red-100 dark:bg-red-950/40",orange:"bg-orange-100 dark:bg-orange-950/40",amber:"bg-amber-100 dark:bg-amber-950/40",yellow:"bg-yellow-100 dark:bg-yellow-950/40",lime:"bg-lime-100 dark:bg-lime-950/40",green:"bg-green-100 dark:bg-green-950/40",emerald:"bg-emerald-100 dark:bg-emerald-950/40",teal:"bg-teal-100 dark:bg-teal-950/40",cyan:"bg-cyan-100 dark:bg-cyan-950/40",sky:"bg-sky-100 dark:bg-sky-950/40",blue:"bg-blue-100 dark:bg-blue-950/40",indigo:"bg-indigo-100 dark:bg-indigo-950/40",violet:"bg-violet-100 dark:bg-violet-950/40",purple:"bg-purple-100 dark:bg-purple-950/40",fuchsia:"bg-fuchsia-100 dark:bg-fuchsia-950/40",pink:"bg-pink-100 dark:bg-pink-950/40",rose:"bg-rose-100 dark:bg-rose-950/40"};function w(e,t,r){return Math.max(t,Math.min(r,e))}function V(e,t=15){return Math.round(e/t)*t}function ue(e){let[t,r]=e.split(":").map(Number);return t*60+r}function Ae(e){return `${e.firstName??""} ${e.lastName??""}`.trim()}function J(e){return dateFns.format(e,"yyyy-MM-dd")}function ce(e,t){return new Date(e.getFullYear(),e.getMonth(),e.getDate()+t)}function z(e,t,r){let o=new Date(e.getFullYear(),e.getMonth(),e.getDate(),0,0,0,0),n=t+r,i=Math.floor(n/60),u=n%60;return o.setHours(i,u,0,0),o}function ae(e,t){return t.getHours()*60+t.getMinutes()-e}function pe(e,t){return e.startMin<t.endMin&&t.startMin<e.endMin}function ye(e){let t=[...e].sort((u,d)=>u.startMin-d.startMin||u.endMin-d.endMin),r=[],o=[],n=[];for(let u of t)o=o.filter(s=>s.endMin>u.startMin),!o.some(s=>pe(s,u))&&n.length>0&&(r.push(n),n=[]),n.push(u),o.push(u);n.length&&r.push(n);let i=[];for(let u of r){let d=[...u].sort((f,R)=>f.startMin-R.startMin||f.endMin-R.endMin),s=[],c=new Map;for(let f of d){let R=false;for(let l=0;l<s.length;l++)if(s[l]<=f.startMin){s[l]=f.endMin,c.set(f.id,l),R=true;break}R||(s.push(f.endMin),c.set(f.id,s.length-1));}let m=s.length;for(let f of d)i.push({...f,lane:c.get(f.id)??0,lanes:m});}return i}function le({fallback:e,getValue:t,resources:r,toKey:o}){let n=new Map;for(let i of r)n.set(o(i),t(i)??e);return n}function Me({adapter:e,appointments:t,dayMinutes:r,dayStartAbs:o,selectedISO:n}){return t.map(i=>{let u=e.getId(i),d=new Date(e.getStart(i)),s=new Date(e.getEnd(i));return {raw:i,id:u,resourceId:e.getResourceId(i),start:d,end:s,startMin:w(ae(o,d),0,r),endMin:w(ae(o,s),0,r),title:e.getTitle(i),renderKey:String(u),visualState:"normal"}}).filter(i=>J(i.start)===n)}function ve(e){return new Map(e.map(t=>[t.id,t]))}function Pe(e,t,r,o){return t.kind==="none"||t.kind==="move"?e:e.map(n=>n.id!==t.appointmentId?n:{...n,resourceId:t.resourceId,startMin:t.startMin,endMin:t.endMin,start:z(r,o,t.startMin),end:z(r,o,t.endMin),visualState:"dragging"})}function xe(e,t){let r=new Map;for(let n of t){let i=r.get(n.resourceId)??[];i.push(n),r.set(n.resourceId,i);}let o=new Map;for(let n of e)o.set(n.id,fe(r.get(n.id)??[]));return o}function fe(e){return ye(e.map(t=>({...t,appointmentId:t.id,id:t.renderKey}))).map(({appointmentId:t,...r})=>({...r,id:t}))}function De(e,t,r,o,n){let i=new Map;for(let u of e){let d=t?.[String(u.id)];if(d){i.set(u.id,{className:d});continue}let s=r?.(u);if(s){i.set(u.id,s);continue}let c=o.get(u.id);if(c){i.set(u.id,{className:c});continue}let m=n.get(u.id);i.set(u.id,m?{className:m}:void 0);}return i}function Ne({adapter:e,appointments:t,dayEnd:r="18:00",dayStart:o="09:00",resources:n,selectedDate:i}){let u=g__namespace.useMemo(()=>ue(o),[o]),d=g__namespace.useMemo(()=>ue(r),[r]),s=g__namespace.useMemo(()=>Math.max(0,d-u),[d,u]),c=g__namespace.useMemo(()=>12+s*2+24,[s]),m=g__namespace.useMemo(()=>72+Math.max(n.length,1)*420,[n.length]),f=g__namespace.useMemo(()=>de(e),[e]),R=g__namespace.useMemo(()=>J(i),[i]),l=g__namespace.useMemo(()=>Me({adapter:f,appointments:t,dayMinutes:s,dayStartAbs:u,selectedISO:R}),[t,s,u,f,R]);return {appointmentMap:g__namespace.useMemo(()=>ve(l),[l]),dayEndAbs:d,dayMinutes:s,dayStartAbs:u,gridHeight:c,gridMinWidth:m,renderAppts:l}}var Rt=4,ht=(e,t)=>{e(r=>r&&{...r,clientX:t.clientX,clientY:t.clientY});},gt=e=>{let{dragRef:t,pendingDragRef:r,pointer:o,setDrag:n,setMovePreview:i,suppressClickRef:u}=e,d=r.current;if(!d||d.drag.pointerId!==o.pointerId)return;let s=o.clientX-d.startClientX,c=o.clientY-d.startClientY;Math.hypot(s,c)<Rt||(u.current=true,t.current=d.drag,n(d.drag),d.drag.kind==="move"&&i({appointment:d.appointment,clientX:o.clientX,clientY:o.clientY,width:d.width,height:d.height,offsetX:d.offsetX,offsetY:d.offsetY}),r.current=null);},Tt=(e,t,r,o,n)=>{let i=o(t.clientX,e.resourceId),d=n(i,t.clientY)-e.offsetMin,s=w(V(d),0,r-e.durationMin),c=s+e.durationMin;return s===e.startMin&&c===e.endMin&&i===e.resourceId?null:{...e,resourceId:i,startMin:s,endMin:c}},It=(e,t,r,o)=>{let n=o(e.resourceId,t.clientY),i=w(V(n),e.startMin+15,r);return i===e.endMin?null:{...e,endMin:i}},Be=e=>{let{dayMinutes:t,dragRef:r,latestPointerRef:o,pendingDragRef:n,pointerToMin:i,pointerToResourceId:u,setDrag:d,setMovePreview:s,suppressClickRef:c}=e,m=o.current;if(!m)return;let f=r.current;if(f.kind==="none"&&n.current){gt({pointer:m,pendingDragRef:n,setDrag:d,setMovePreview:s,dragRef:r,suppressClickRef:c});return}if(f.kind==="none")return;if(f.kind==="move"){ht(s,m);let l=Tt(f,m,t,u,i);l&&(c.current=true,r.current=l,d(l));return}let R=It(f,m,t,i);R&&(c.current=true,r.current=R,d(R));},Ee=e=>{let{dragRef:t,frameRef:r,latestPointerRef:o,pendingDragRef:n,persistDrag:i,setDrag:u,setMovePreview:d,suppressClickRef:s}=e;r.current!==null&&(window.cancelAnimationFrame(r.current),r.current=null),o.current=null,n.current=null,d(null);let c=t.current;c.kind!=="none"&&(u({kind:"none"}),t.current={kind:"none"},s.current&&i(c));};var Oe=({appointmentMap:e,dayMinutes:t,dayStartAbs:r,onAppointmentChange:o,onPersistMoveResize:n,renderAppts:i,resources:u,selectedDate:d,editable:s})=>{let[c,m]=g__namespace.useState({kind:"none"}),[f,R]=g__namespace.useState(null),l=g__namespace.useRef({}),T=g__namespace.useRef(false),x=g__namespace.useRef({kind:"none"}),b=g__namespace.useRef(null),A=g__namespace.useRef(null),y=g__namespace.useRef(null),$=g__namespace.useMemo(()=>{let p=new Map;for(let a of i){let h=p.get(a.resourceId)??[];h.push(a),p.set(a.resourceId,h);}return p},[i]);g__namespace.useEffect(()=>{x.current=c;},[c]),g__namespace.useEffect(()=>()=>{y.current!==null&&window.cancelAnimationFrame(y.current);},[]);let O=g__namespace.useCallback((p,a)=>{let h=l.current[String(p)];if(!h)return 0;let M=a-h.getBoundingClientRect().top-12;return w(V(M/2),0,t)},[t]),W=g__namespace.useCallback((p,a)=>{for(let h of u){let M=l.current[String(h.id)];if(!M)continue;let L=M.getBoundingClientRect();if(p>=L.left&&p<=L.right)return h.id}return a},[u]),D=g__namespace.useCallback((p,a,h,M)=>($.get(a)??[]).some(K=>K.id!==p&&pe(K,{startMin:h,endMin:M})),[$]),Y=g__namespace.useMemo(()=>c.kind==="none"?false:D(c.appointmentId,c.resourceId,c.startMin,c.endMin),[c,D]),X=g__namespace.useCallback(async p=>{let a=e.get(p.appointmentId);if(!a||D(p.appointmentId,p.resourceId,p.startMin,p.endMin))return;let h={resourceId:p.resourceId,start:z(d,r,p.startMin),end:z(d,r,p.endMin)};if(o){await o({kind:p.kind,appointment:a.raw,resourceId:h.resourceId,start:h.start,end:h.end,previousResourceId:a.resourceId,previousStart:a.start,previousEnd:a.end,previous:{resourceId:a.resourceId,start:a.start,end:a.end},next:h});return}n&&await n({appointment:a.raw,resourceId:h.resourceId,start:h.start,end:h.end});},[e,r,D,o,n,d]),te=g__namespace.useCallback((p,a)=>{if(!s||p.button!==0)return;p.stopPropagation(),T.current=false;let h=p.currentTarget.getBoundingClientRect(),M=O(a.resourceId,p.clientY);b.current={drag:{kind:"move",appointmentId:a.id,pointerId:p.pointerId,resourceId:a.resourceId,durationMin:Math.max(15,a.endMin-a.startMin),offsetMin:M-a.startMin,startMin:a.startMin,endMin:a.endMin},appointment:a,startClientX:p.clientX,startClientY:p.clientY,width:h.width,height:h.height,offsetX:p.clientX-h.left,offsetY:p.clientY-h.top};},[O,s]),G=g__namespace.useCallback((p,a)=>{s&&p.button===0&&(p.stopPropagation(),T.current=false,b.current={drag:{kind:"resize",appointmentId:a.id,pointerId:p.pointerId,resourceId:a.resourceId,startMin:a.startMin,endMin:a.endMin},appointment:a,startClientX:p.clientX,startClientY:p.clientY,width:0,height:0,offsetX:0,offsetY:0});},[s]),re=g__namespace.useCallback(p=>{A.current={clientX:p.clientX,clientY:p.clientY,pointerId:p.pointerId},y.current===null&&(y.current=window.requestAnimationFrame(()=>{y.current=null,Be({dayMinutes:t,dragRef:x,latestPointerRef:A,pendingDragRef:b,pointerToMin:O,pointerToResourceId:W,setDrag:m,setMovePreview:R,suppressClickRef:T});}));},[t,O,W]),S=g__namespace.useCallback(()=>{Ee({dragRef:x,frameRef:y,latestPointerRef:A,pendingDragRef:b,persistDrag:X,setDrag:m,setMovePreview:R,suppressClickRef:T});},[X]);return {colRefs:l,drag:c,isDropInvalid:Y,movePreview:f,onApptPointerDown:te,onGlobalPointerMove:re,onGlobalPointerUp:S,onResizePointerDown:G,suppressClickRef:T}};function Le({appointmentColorTokenClassMap:e,dayStartAbs:t,drag:r,getResourceAppointmentAppearance:o,getResourceAppointmentBackground:n,getResourceAppointmentColorToken:i,renderAppts:u,resourceAppointmentClassMap:d,resources:s,selectedDate:c}){let m=g__namespace.useMemo(()=>Pe(u,r,c,t),[t,r,u,c]),f=g__namespace.useMemo(()=>xe(s,u),[u,s]),R=g__namespace.useMemo(()=>{if(r.kind!=="resize")return f;let b=new Map(f),A=m.filter(y=>y.resourceId===r.resourceId);return b.set(r.resourceId,fe(A)),b},[f,r,m]),l=g__namespace.useMemo(()=>n?le({fallback:void 0,getValue:n,resources:s,toKey:b=>b.id}):new Map,[n,s]),T=g__namespace.useMemo(()=>{if(!i)return new Map;let b={...be,...e??{}};return le({fallback:void 0,getValue:A=>{let y=i(A);return y?b[y]:void 0},resources:s,toKey:A=>A.id})},[e,i,s]);return {appointmentAppearanceByResource:g__namespace.useMemo(()=>De(s,d,o,T,l),[l,T,o,d,s]),appointmentBgByResource:l,effectiveAppts:m,laidOutByResource:R}}function _e({dayMinutes:e,dayStartAbs:t,gridHeight:r}){return jsxRuntime.jsx("div",{className:"rfs-times rfs:border-border rfs:bg-card",style:{width:72,height:r},children:Array.from({length:Math.floor(e/60)+1}).map((o,n)=>jsxRuntime.jsxs("div",{className:"rfs-time-tick rfs:text-muted-foreground",style:{top:12+n*60*2},children:[String(Math.floor((t+n*60)/60)).padStart(2,"0"),":",String((t+n*60)%60).padStart(2,"0")]},`tick-${n}`))})}function ze({resource:e}){return jsxRuntime.jsx("strong",{children:e.label})}function Xe({resources:e,renderResourceHeader:t}){return jsxRuntime.jsxs("div",{className:"rfs-header rfs:border-border rfs:bg-card",children:[jsxRuntime.jsx("div",{className:"rfs-gutter rfs:border-border",style:{width:72}}),e.map(r=>jsxRuntime.jsxs("div",{className:"rfs-resource-header rfs:border-border rfs:bg-card rfs:text-foreground",style:{minWidth:420,flex:1},children:[(t??(o=>ze({resource:o})))(r),Se(r)?jsxRuntime.jsx("div",{className:"rfs-resource-subtitle rfs:text-muted-foreground",children:Ae(r)}):null]},String(r.id)))]})}var Fe=({resource:e,colRefs:t,gridHeight:r,dayMinutes:o,appointments:n,appointmentAppearance:i,appointmentBg:u,isDropInvalid:d,renderAppointment:s,onApptPointerDown:c,onResizePointerDown:m,drag:f,suppressClickRef:R})=>jsxRuntime.jsx("div",{className:"rfs-col rfs:border-border rfs:bg-card",style:{minWidth:420,flex:1},children:jsxRuntime.jsxs("div",{ref:l=>{t.current[String(e.id)]=l;},className:"rfs-col-inner rfs:bg-card",style:{height:r},children:[Array.from({length:Math.floor(o/60)+1}).map((l,T)=>jsxRuntime.jsx("div",{className:"rfs-hour-line rfs:border-border/70",style:{top:12+T*60*2}},`major-${T}`)),Array.from({length:Math.floor(o/15)+1}).map((l,T)=>jsxRuntime.jsx("div",{className:"rfs-slot-line rfs:border-border/50",style:{top:12+T*15*2}},`minor-${T}`)),n.map(l=>{let T=100/l.lanes,x=12+l.startMin*2,b=Math.max(30,(l.endMin-l.startMin)*2);return jsxRuntime.jsx("div",{className:`rfs-card-slot ${l.visualState==="ghost"?"rfs-card-slot--ghost":""} ${l.visualState==="dragging"?"rfs-card-slot--dragging":""}`,style:{top:x,left:`${T*l.lane}%`,width:`${T}%`,height:b},children:(s??q)({appointment:l,isDropInvalid:d&&f.kind==="resize"&&l.id===f.appointmentId,onPointerDown:A=>c(A,l),onResizePointerDown:A=>m(A,l),appointmentAppearance:i,appointmentBackgroundColor:u,drag:f,suppressClickRef:R})},l.renderKey)})]})});var Mt=(e,t)=>[e.resource===t.resource,e.colRefs===t.colRefs,e.gridHeight===t.gridHeight,e.dayMinutes===t.dayMinutes,e.appointments===t.appointments,e.appointmentAppearance===t.appointmentAppearance,e.appointmentBg===t.appointmentBg,e.isDropInvalid===t.isDropInvalid,e.renderAppointment===t.renderAppointment,e.onApptPointerDown===t.onApptPointerDown,e.onResizePointerDown===t.onResizePointerDown,e.drag===t.drag,e.suppressClickRef===t.suppressClickRef].every(Boolean),Ue=g__namespace.memo(Fe,Mt);function H(...e){return e.filter(Boolean).join(" ")}var vt={default:"rfs:bg-primary rfs:text-primary-foreground rfs:hover:bg-primary/90",outline:"rfs:border rfs:border-border rfs:bg-card rfs:text-foreground rfs:hover:bg-muted",ghost:"rfs:text-foreground rfs:hover:bg-muted"},Pt={default:"rfs:h-9 rfs:px-4 rfs:py-2",sm:"rfs:h-8 rfs:px-3 rfs:text-xs",icon:"rfs:h-8 rfs:w-8"},P=g__namespace.forwardRef(function({className:t,variant:r="default",size:o="default",type:n="button",...i},u){return jsxRuntime.jsx("button",{ref:u,type:n,className:H("rfs:inline-flex rfs:items-center rfs:justify-center rfs:gap-2 rfs:rounded-md rfs:text-sm rfs:font-medium rfs:whitespace-nowrap rfs:transition-colors rfs:focus-visible:outline-none rfs:focus-visible:ring-2 rfs:focus-visible:ring-ring rfs:focus-visible:ring-offset-2 rfs:disabled:pointer-events-none rfs:disabled:opacity-50",vt[r],Pt[o],t),...i})});function qe({selected:e,onSelect:t}){let[r,o]=g__namespace.useState(e??new Date);g__namespace.useEffect(()=>{e&&o(e);},[e]);let n=dateFns.startOfMonth(r),i=dateFns.startOfWeek(n,{weekStartsOn:1}),u=dateFns.endOfWeek(dateFns.endOfMonth(r),{weekStartsOn:1}),d=[];for(let s=i;s<=u;s=dateFns.addDays(s,1))d.push(s);return jsxRuntime.jsxs("div",{className:"rfs:w-72 rfs:rounded-md rfs:bg-popover",children:[jsxRuntime.jsxs("div",{className:"rfs:mb-2 rfs:flex rfs:items-center rfs:justify-between",children:[jsxRuntime.jsx(P,{variant:"ghost",size:"icon","aria-label":"Previous month",onClick:()=>o(dateFns.addMonths(r,-1)),children:"<"}),jsxRuntime.jsx("div",{className:"rfs:text-sm rfs:font-medium",children:dateFns.format(r,"MMMM yyyy")}),jsxRuntime.jsx(P,{variant:"ghost",size:"icon","aria-label":"Next month",onClick:()=>o(dateFns.addMonths(r,1)),children:">"})]}),jsxRuntime.jsx("div",{className:"rfs:grid rfs:grid-cols-7 rfs:gap-1 rfs:text-center rfs:text-xs rfs:text-muted-foreground",children:["Mo","Tu","We","Th","Fr","Sa","Su"].map(s=>jsxRuntime.jsx("div",{className:"rfs:py-1",children:s},s))}),jsxRuntime.jsx("div",{className:"rfs:grid rfs:grid-cols-7 rfs:gap-1",children:d.map(s=>{let c=e?dateFns.isSameDay(s,e):false;return jsxRuntime.jsx(P,{variant:c?"default":"ghost",size:"icon",className:H("rfs:text-xs",!dateFns.isSameMonth(s,r)&&"rfs:text-muted-foreground rfs:opacity-60",dateFns.isToday(s)&&!c&&"rfs:border rfs:border-border"),onClick:()=>t?.(s),children:dateFns.format(s,"d")},s.toISOString())})})]})}var Je=g__namespace.createContext(null);function Qe(){let e=g__namespace.useContext(Je);if(!e)throw new Error("Popover components must be used within Popover.");return e}function Ze({children:e,open:t,onOpenChange:r}){let[o,n]=g__namespace.useState(false),i=g__namespace.useRef(null),u=g__namespace.useRef(null),d=t??o,s=g__namespace.useCallback(c=>{let m=typeof c=="function"?c(d):c;t===void 0&&n(m),r?.(m);},[t,r,d]);return g__namespace.useEffect(()=>{if(!d)return;let c=f=>{let R=f.target;i.current?.contains(R)||u.current?.contains(R)||s(false);},m=f=>{f.key==="Escape"&&s(false);};return document.addEventListener("mousedown",c),document.addEventListener("keydown",m),()=>{document.removeEventListener("mousedown",c),document.removeEventListener("keydown",m);}},[d,s]),jsxRuntime.jsx(Je.Provider,{value:{open:d,setOpen:s,triggerRef:i,contentRef:u},children:jsxRuntime.jsx("div",{className:"rfs:relative rfs:inline-flex",children:e})})}function je({children:e,asChild:t=false}){let{open:r,setOpen:o,triggerRef:n}=Qe();if(t&&g__namespace.isValidElement(e)){let i=e;return g__namespace.cloneElement(i,{ref:n,"aria-expanded":r,onClick:u=>{i.props.onClick?.(u),o(d=>!d);}})}return jsxRuntime.jsx("button",{ref:n,type:"button","aria-expanded":r,onClick:()=>o(i=>!i),children:e})}function et({children:e,className:t,align:r="start"}){let{open:o,contentRef:n}=Qe();return o?jsxRuntime.jsx("div",{ref:n,className:H("rfs:absolute rfs:top-full rfs:z-50 rfs:mt-2 rfs:min-w-72 rfs:rounded-md rfs:border rfs:border-border rfs:bg-popover rfs:p-2 rfs:text-popover-foreground rfs:shadow-md rfs:outline-none",r==="start"&&"rfs:left-0",r==="center"&&"rfs:left-1/2 rfs:-translate-x-1/2",r==="end"&&"rfs:right-0",t),children:e}):null}function tt({selectedDate:e,onSelectedDateChange:t}){return jsxRuntime.jsxs(Ze,{children:[jsxRuntime.jsx(je,{asChild:true,children:jsxRuntime.jsx(P,{variant:"outline",size:"sm",className:"rfs:min-w-40 rfs:justify-start rfs:text-left rfs:font-normal",children:dateFns.format(e,"PPP")})}),jsxRuntime.jsx(et,{className:"rfs:w-auto rfs:p-2",align:"center",children:jsxRuntime.jsx(qe,{selected:e,onSelect:t})})]})}function rt({goToPreviousDay:e,goToNextDay:t,defaultDatePicker:r,prevButtonLabel:o="Prev",nextButtonLabel:n="Next"}){return jsxRuntime.jsx("div",{className:"rfs-toolbar",children:jsxRuntime.jsxs("div",{className:"rfs:flex rfs:items-center rfs:gap-2 rfs:rounded-lg rfs:border rfs:border-border rfs:bg-card rfs:p-1 rfs:shadow-xs",children:[jsxRuntime.jsx(P,{variant:"outline",size:"sm",onClick:e,children:o}),r,jsxRuntime.jsx(P,{variant:"outline",size:"sm",onClick:t,children:n})]})})}function st({selectedDate:e,onSelectedDateChange:t,prevButtonLabel:r,nextButtonLabel:o,renderToolbar:n,renderDatePicker:i}){let u=()=>t(ce(e,-1)),d=()=>t(ce(e,1)),s=(i??tt)({selectedDate:e,onSelectedDateChange:t});return n?jsxRuntime.jsx(jsxRuntime.Fragment,{children:n({selectedDate:e,onSelectedDateChange:t,goToPreviousDay:u,goToNextDay:d,defaultDatePicker:s})}):jsxRuntime.jsx(jsxRuntime.Fragment,{children:rt({goToPreviousDay:u,goToNextDay:d,defaultDatePicker:s,prevButtonLabel:r,nextButtonLabel:o})})}var Ht={kind:"none"};function Yt({resources:e,appointments:t,selectedDate:r,onSelectedDateChange:o,adapter:n,onPersistMoveResize:i,onAppointmentChange:u,renderResourceHeader:d,renderAppointment:s,resourceAppointmentClassMap:c,getResourceAppointmentAppearance:m,getResourceAppointmentColorToken:f,appointmentColorTokenClassMap:R,getResourceAppointmentBackground:l,renderToolbar:T,renderDatePicker:x,prevButtonLabel:b="Prev",nextButtonLabel:A="Next",dayStart:y="09:00",dayEnd:$="18:00",editable:O=true}){let{appointmentMap:W,dayMinutes:D,dayStartAbs:Y,gridHeight:X,gridMinWidth:te,renderAppts:G}=Ne({adapter:n,appointments:t,dayEnd:$,dayStart:y,resources:e,selectedDate:r}),{colRefs:re,drag:S,isDropInvalid:p,movePreview:a,onApptPointerDown:h,onGlobalPointerMove:M,onGlobalPointerUp:L,onResizePointerDown:K,suppressClickRef:he}=Oe({appointmentMap:W,dayMinutes:D,dayStartAbs:Y,onAppointmentChange:u,onPersistMoveResize:i,renderAppts:G,resources:e,selectedDate:r,editable:O}),{appointmentAppearanceByResource:ne,appointmentBgByResource:oe,laidOutByResource:ut}=Le({appointmentColorTokenClassMap:R,dayStartAbs:Y,drag:S,getResourceAppointmentAppearance:m,getResourceAppointmentBackground:l,getResourceAppointmentColorToken:f,renderAppts:G,resourceAppointmentClassMap:c,resources:e,selectedDate:r}),k=g__namespace.useMemo(()=>S.kind!=="move"||!a?null:{appointment:{...a.appointment,resourceId:S.resourceId,startMin:S.startMin,endMin:S.endMin,visualState:"ghost",renderKey:`${a.appointment.renderKey}-overlay`,lane:0,lanes:1},appearance:ne.get(S.resourceId),background:oe.get(S.resourceId),left:a.clientX-a.offsetX,top:a.clientY-a.offsetY,width:a.width,height:a.height},[ne,oe,S,a]);return jsxRuntime.jsxs("section",{className:`rfs-root rfs:rounded-lg rfs:text-foreground ${S.kind==="move"?"rfs-root--drag-move":""} ${S.kind==="resize"?"rfs-root--drag-resize":""}`,onPointerMove:M,onPointerUp:L,onPointerCancel:L,children:[jsxRuntime.jsx(st,{selectedDate:r,onSelectedDateChange:o,prevButtonLabel:b,nextButtonLabel:A,renderToolbar:T,renderDatePicker:x}),jsxRuntime.jsx("div",{className:"rfs-shell rfs:border-border rfs:bg-card",children:jsxRuntime.jsxs("div",{style:{minWidth:te},children:[jsxRuntime.jsx(Xe,{resources:e,renderResourceHeader:d}),jsxRuntime.jsxs("div",{className:"rfs-body",children:[jsxRuntime.jsx(_e,{dayMinutes:D,dayStartAbs:Y,gridHeight:X}),jsxRuntime.jsx("div",{className:"rfs-grid",children:e.map(_=>jsxRuntime.jsx(Ue,{resource:_,colRefs:re,gridHeight:X,dayMinutes:D,appointments:ut.get(_.id)??[],appointmentAppearance:ne.get(_.id),appointmentBg:oe.get(_.id),isDropInvalid:p,renderAppointment:s,onApptPointerDown:h,onResizePointerDown:K,drag:S.kind==="resize"&&S.resourceId===_.id?S:Ht,suppressClickRef:he},String(_.id)))})]})]})}),k?jsxRuntime.jsx("div",{className:"rfs-drag-overlay",style:{left:k.left,top:k.top,width:k.width,height:k.height},children:(s??q)({appointment:k.appointment,isDropInvalid:p,onPointerDown:()=>{},onResizePointerDown:()=>{},appointmentAppearance:k.appearance,appointmentBackgroundColor:k.background,drag:S,suppressClickRef:he})}):null]})}var dt=(e,t)=>typeof t=="function"?t(e):e[t],Xt=e=>"id"in e,Ft=e=>({resourceId:e.resourceId??e.next.resourceId,start:e.start??e.next.start,end:e.end??e.next.end}),Vt=(e,t,r)=>{let o=Ft(t);return e.map(n=>{if(Xt(r)){if(dt(n,r.id)!==dt(t.appointment,r.id))return n;let d=r.dateValue??(s=>s);return {...n,[r.resourceId]:o.resourceId,[r.start]:d(o.start),[r.end]:d(o.end)}}if(r.getId(n)!==r.getId(t.appointment))return n;let i=r.setResourceId(n,o.resourceId),u=r.setStart(i,o.start);return r.setEnd(u,o.end)})};exports.Scheduler=Yt;exports.applySchedulerAppointmentChange=Vt;exports.resolveSchedulerAppointmentAdapter=de;
package/dist/index.d.cts CHANGED
@@ -8,6 +8,15 @@ type SchedulerAppointmentAdapter<TAppointment, TResourceId extends string | numb
8
8
  getEnd: (item: TAppointment) => Date | string;
9
9
  getTitle: (item: TAppointment) => string;
10
10
  };
11
+ type SchedulerAppointmentField<TAppointment, TValue> = Extract<keyof TAppointment, string | number> | ((item: TAppointment) => TValue);
12
+ type SchedulerAppointmentFieldAdapter<TAppointment, TResourceId extends string | number> = {
13
+ id: SchedulerAppointmentField<TAppointment, number | string>;
14
+ resourceId: SchedulerAppointmentField<TAppointment, TResourceId>;
15
+ start: SchedulerAppointmentField<TAppointment, Date | string>;
16
+ end: SchedulerAppointmentField<TAppointment, Date | string>;
17
+ title: SchedulerAppointmentField<TAppointment, string>;
18
+ };
19
+ type SchedulerAppointmentAdapterInput<TAppointment, TResourceId extends string | number> = SchedulerAppointmentAdapter<TAppointment, TResourceId> | SchedulerAppointmentFieldAdapter<TAppointment, TResourceId>;
11
20
  type SchedulerId = string | number;
12
21
  type BaseSchedulerResource<TId extends SchedulerId = number> = {
13
22
  id: TId;
@@ -51,6 +60,12 @@ type RenderSchedulerAppt<TAppointment, TResourceId extends SchedulerId> = Schedu
51
60
  type SchedulerAppointmentChangeArgs<TAppointment, TResourceId extends SchedulerId> = {
52
61
  kind: "move" | "resize";
53
62
  appointment: TAppointment;
63
+ resourceId?: TResourceId;
64
+ start?: Date;
65
+ end?: Date;
66
+ previousResourceId?: TResourceId;
67
+ previousStart?: Date;
68
+ previousEnd?: Date;
54
69
  previous: {
55
70
  resourceId: TResourceId;
56
71
  start: Date;
@@ -62,6 +77,14 @@ type SchedulerAppointmentChangeArgs<TAppointment, TResourceId extends SchedulerI
62
77
  end: Date;
63
78
  };
64
79
  };
80
+ type SchedulerAppointmentChangeEvent<TAppointment, TResourceId extends SchedulerId> = SchedulerAppointmentChangeArgs<TAppointment, TResourceId> & {
81
+ resourceId: TResourceId;
82
+ start: Date;
83
+ end: Date;
84
+ previousResourceId: TResourceId;
85
+ previousStart: Date;
86
+ previousEnd: Date;
87
+ };
65
88
  type SchedulerAppointmentAppearance = {
66
89
  className?: string;
67
90
  };
@@ -79,14 +102,14 @@ type SchedulerProps<TAppointment, TResource extends BaseSchedulerResource<TResou
79
102
  appointments: TAppointment[];
80
103
  selectedDate: Date;
81
104
  onSelectedDateChange: (date: Date) => void;
82
- adapter: SchedulerAppointmentAdapter<TAppointment, TResourceId>;
105
+ adapter: SchedulerAppointmentAdapterInput<TAppointment, TResourceId>;
83
106
  onPersistMoveResize?: (args: {
84
107
  appointment: TAppointment;
85
108
  resourceId: TResourceId;
86
109
  start: Date;
87
110
  end: Date;
88
111
  }) => Promise<void> | void;
89
- onAppointmentChange?: (args: SchedulerAppointmentChangeArgs<TAppointment, TResourceId>) => Promise<void> | void;
112
+ onAppointmentChange?: (args: SchedulerAppointmentChangeEvent<TAppointment, TResourceId>) => Promise<void> | void;
90
113
  renderResourceHeader?: (resource: TResource) => React.ReactNode;
91
114
  renderAppointment?: (args: {
92
115
  appointment: SchedulerPresentationAppointment<TAppointment, TResourceId> & {
@@ -120,12 +143,22 @@ type SchedulerProps<TAppointment, TResource extends BaseSchedulerResource<TResou
120
143
 
121
144
  declare function Scheduler<TAppointment, TResource extends BaseSchedulerResource<TResourceId>, TResourceId extends SchedulerId>({ resources, appointments, selectedDate, onSelectedDateChange, adapter, onPersistMoveResize, onAppointmentChange, renderResourceHeader, renderAppointment, resourceAppointmentClassMap, getResourceAppointmentAppearance, getResourceAppointmentColorToken, appointmentColorTokenClassMap, getResourceAppointmentBackground, renderToolbar, renderDatePicker, prevButtonLabel, nextButtonLabel, dayStart, dayEnd, editable }: SchedulerProps<TAppointment, TResource, TResourceId>): react_jsx_runtime.JSX.Element;
122
145
 
146
+ declare const resolveSchedulerAppointmentAdapter: <TAppointment, TResourceId extends string | number>(adapter: SchedulerAppointmentAdapterInput<TAppointment, TResourceId>) => SchedulerAppointmentAdapter<TAppointment, TResourceId>;
147
+
123
148
  type ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId extends SchedulerId> = {
124
149
  getId: (appointment: TAppointment) => SchedulerId;
125
150
  setResourceId: (appointment: TAppointment, resourceId: TResourceId) => TAppointment;
126
151
  setStart: (appointment: TAppointment, start: Date) => TAppointment;
127
152
  setEnd: (appointment: TAppointment, end: Date) => TAppointment;
128
153
  };
129
- declare function applySchedulerAppointmentChange<TAppointment, TResourceId extends SchedulerId>(appointments: TAppointment[], change: SchedulerAppointmentChangeArgs<TAppointment, TResourceId>, options: ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId>): TAppointment[];
154
+ type ApplySchedulerAppointmentChangeFieldOptions<TAppointment> = {
155
+ id: SchedulerAppointmentField<TAppointment, SchedulerId>;
156
+ resourceId: Extract<keyof TAppointment, string | number>;
157
+ start: Extract<keyof TAppointment, string | number>;
158
+ end: Extract<keyof TAppointment, string | number>;
159
+ dateValue?: (date: Date) => unknown;
160
+ };
161
+ type ApplySchedulerAppointmentChangeInput<TAppointment, TResourceId extends SchedulerId> = ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId> | ApplySchedulerAppointmentChangeFieldOptions<TAppointment>;
162
+ declare const applySchedulerAppointmentChange: <TAppointment, TResourceId extends SchedulerId>(appointments: TAppointment[], change: SchedulerAppointmentChangeArgs<TAppointment, TResourceId>, options: ApplySchedulerAppointmentChangeInput<TAppointment, TResourceId>) => TAppointment[];
130
163
 
131
- export { type ApplySchedulerAppointmentChangeOptions, type BaseSchedulerResource, type RenderSchedulerAppt, Scheduler, type SchedulerAppointmentAdapter, type SchedulerAppointmentAppearance, type SchedulerAppointmentChangeArgs, type SchedulerAppointmentColorToken, type SchedulerAppointmentVisualState, type SchedulerDragState, type SchedulerEvent, type SchedulerId, type SchedulerPresentationAppointment, type SchedulerProps, type SchedulerResourceClassMap, type SchedulerToolbarRenderArgs, applySchedulerAppointmentChange };
164
+ export { type ApplySchedulerAppointmentChangeFieldOptions, type ApplySchedulerAppointmentChangeInput, type ApplySchedulerAppointmentChangeOptions, type BaseSchedulerResource, type RenderSchedulerAppt, Scheduler, type SchedulerAppointmentAdapter, type SchedulerAppointmentAdapterInput, type SchedulerAppointmentAppearance, type SchedulerAppointmentChangeArgs, type SchedulerAppointmentChangeEvent, type SchedulerAppointmentColorToken, type SchedulerAppointmentField, type SchedulerAppointmentFieldAdapter, type SchedulerAppointmentVisualState, type SchedulerDragState, type SchedulerEvent, type SchedulerId, type SchedulerPresentationAppointment, type SchedulerProps, type SchedulerResourceClassMap, type SchedulerToolbarRenderArgs, applySchedulerAppointmentChange, resolveSchedulerAppointmentAdapter };
package/dist/index.d.ts CHANGED
@@ -8,6 +8,15 @@ type SchedulerAppointmentAdapter<TAppointment, TResourceId extends string | numb
8
8
  getEnd: (item: TAppointment) => Date | string;
9
9
  getTitle: (item: TAppointment) => string;
10
10
  };
11
+ type SchedulerAppointmentField<TAppointment, TValue> = Extract<keyof TAppointment, string | number> | ((item: TAppointment) => TValue);
12
+ type SchedulerAppointmentFieldAdapter<TAppointment, TResourceId extends string | number> = {
13
+ id: SchedulerAppointmentField<TAppointment, number | string>;
14
+ resourceId: SchedulerAppointmentField<TAppointment, TResourceId>;
15
+ start: SchedulerAppointmentField<TAppointment, Date | string>;
16
+ end: SchedulerAppointmentField<TAppointment, Date | string>;
17
+ title: SchedulerAppointmentField<TAppointment, string>;
18
+ };
19
+ type SchedulerAppointmentAdapterInput<TAppointment, TResourceId extends string | number> = SchedulerAppointmentAdapter<TAppointment, TResourceId> | SchedulerAppointmentFieldAdapter<TAppointment, TResourceId>;
11
20
  type SchedulerId = string | number;
12
21
  type BaseSchedulerResource<TId extends SchedulerId = number> = {
13
22
  id: TId;
@@ -51,6 +60,12 @@ type RenderSchedulerAppt<TAppointment, TResourceId extends SchedulerId> = Schedu
51
60
  type SchedulerAppointmentChangeArgs<TAppointment, TResourceId extends SchedulerId> = {
52
61
  kind: "move" | "resize";
53
62
  appointment: TAppointment;
63
+ resourceId?: TResourceId;
64
+ start?: Date;
65
+ end?: Date;
66
+ previousResourceId?: TResourceId;
67
+ previousStart?: Date;
68
+ previousEnd?: Date;
54
69
  previous: {
55
70
  resourceId: TResourceId;
56
71
  start: Date;
@@ -62,6 +77,14 @@ type SchedulerAppointmentChangeArgs<TAppointment, TResourceId extends SchedulerI
62
77
  end: Date;
63
78
  };
64
79
  };
80
+ type SchedulerAppointmentChangeEvent<TAppointment, TResourceId extends SchedulerId> = SchedulerAppointmentChangeArgs<TAppointment, TResourceId> & {
81
+ resourceId: TResourceId;
82
+ start: Date;
83
+ end: Date;
84
+ previousResourceId: TResourceId;
85
+ previousStart: Date;
86
+ previousEnd: Date;
87
+ };
65
88
  type SchedulerAppointmentAppearance = {
66
89
  className?: string;
67
90
  };
@@ -79,14 +102,14 @@ type SchedulerProps<TAppointment, TResource extends BaseSchedulerResource<TResou
79
102
  appointments: TAppointment[];
80
103
  selectedDate: Date;
81
104
  onSelectedDateChange: (date: Date) => void;
82
- adapter: SchedulerAppointmentAdapter<TAppointment, TResourceId>;
105
+ adapter: SchedulerAppointmentAdapterInput<TAppointment, TResourceId>;
83
106
  onPersistMoveResize?: (args: {
84
107
  appointment: TAppointment;
85
108
  resourceId: TResourceId;
86
109
  start: Date;
87
110
  end: Date;
88
111
  }) => Promise<void> | void;
89
- onAppointmentChange?: (args: SchedulerAppointmentChangeArgs<TAppointment, TResourceId>) => Promise<void> | void;
112
+ onAppointmentChange?: (args: SchedulerAppointmentChangeEvent<TAppointment, TResourceId>) => Promise<void> | void;
90
113
  renderResourceHeader?: (resource: TResource) => React.ReactNode;
91
114
  renderAppointment?: (args: {
92
115
  appointment: SchedulerPresentationAppointment<TAppointment, TResourceId> & {
@@ -120,12 +143,22 @@ type SchedulerProps<TAppointment, TResource extends BaseSchedulerResource<TResou
120
143
 
121
144
  declare function Scheduler<TAppointment, TResource extends BaseSchedulerResource<TResourceId>, TResourceId extends SchedulerId>({ resources, appointments, selectedDate, onSelectedDateChange, adapter, onPersistMoveResize, onAppointmentChange, renderResourceHeader, renderAppointment, resourceAppointmentClassMap, getResourceAppointmentAppearance, getResourceAppointmentColorToken, appointmentColorTokenClassMap, getResourceAppointmentBackground, renderToolbar, renderDatePicker, prevButtonLabel, nextButtonLabel, dayStart, dayEnd, editable }: SchedulerProps<TAppointment, TResource, TResourceId>): react_jsx_runtime.JSX.Element;
122
145
 
146
+ declare const resolveSchedulerAppointmentAdapter: <TAppointment, TResourceId extends string | number>(adapter: SchedulerAppointmentAdapterInput<TAppointment, TResourceId>) => SchedulerAppointmentAdapter<TAppointment, TResourceId>;
147
+
123
148
  type ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId extends SchedulerId> = {
124
149
  getId: (appointment: TAppointment) => SchedulerId;
125
150
  setResourceId: (appointment: TAppointment, resourceId: TResourceId) => TAppointment;
126
151
  setStart: (appointment: TAppointment, start: Date) => TAppointment;
127
152
  setEnd: (appointment: TAppointment, end: Date) => TAppointment;
128
153
  };
129
- declare function applySchedulerAppointmentChange<TAppointment, TResourceId extends SchedulerId>(appointments: TAppointment[], change: SchedulerAppointmentChangeArgs<TAppointment, TResourceId>, options: ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId>): TAppointment[];
154
+ type ApplySchedulerAppointmentChangeFieldOptions<TAppointment> = {
155
+ id: SchedulerAppointmentField<TAppointment, SchedulerId>;
156
+ resourceId: Extract<keyof TAppointment, string | number>;
157
+ start: Extract<keyof TAppointment, string | number>;
158
+ end: Extract<keyof TAppointment, string | number>;
159
+ dateValue?: (date: Date) => unknown;
160
+ };
161
+ type ApplySchedulerAppointmentChangeInput<TAppointment, TResourceId extends SchedulerId> = ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId> | ApplySchedulerAppointmentChangeFieldOptions<TAppointment>;
162
+ declare const applySchedulerAppointmentChange: <TAppointment, TResourceId extends SchedulerId>(appointments: TAppointment[], change: SchedulerAppointmentChangeArgs<TAppointment, TResourceId>, options: ApplySchedulerAppointmentChangeInput<TAppointment, TResourceId>) => TAppointment[];
130
163
 
131
- export { type ApplySchedulerAppointmentChangeOptions, type BaseSchedulerResource, type RenderSchedulerAppt, Scheduler, type SchedulerAppointmentAdapter, type SchedulerAppointmentAppearance, type SchedulerAppointmentChangeArgs, type SchedulerAppointmentColorToken, type SchedulerAppointmentVisualState, type SchedulerDragState, type SchedulerEvent, type SchedulerId, type SchedulerPresentationAppointment, type SchedulerProps, type SchedulerResourceClassMap, type SchedulerToolbarRenderArgs, applySchedulerAppointmentChange };
164
+ export { type ApplySchedulerAppointmentChangeFieldOptions, type ApplySchedulerAppointmentChangeInput, type ApplySchedulerAppointmentChangeOptions, type BaseSchedulerResource, type RenderSchedulerAppt, Scheduler, type SchedulerAppointmentAdapter, type SchedulerAppointmentAdapterInput, type SchedulerAppointmentAppearance, type SchedulerAppointmentChangeArgs, type SchedulerAppointmentChangeEvent, type SchedulerAppointmentColorToken, type SchedulerAppointmentField, type SchedulerAppointmentFieldAdapter, type SchedulerAppointmentVisualState, type SchedulerDragState, type SchedulerEvent, type SchedulerId, type SchedulerPresentationAppointment, type SchedulerProps, type SchedulerResourceClassMap, type SchedulerToolbarRenderArgs, applySchedulerAppointmentChange, resolveSchedulerAppointmentAdapter };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {format,startOfMonth,startOfWeek,endOfWeek,endOfMonth,addDays,addMonths,isSameDay,isToday,isSameMonth}from'date-fns';import*as h from'react';var it=e=>{let{isDropInvalid:t,description:r,title:o}=e;return jsxs(Fragment,{children:[t&&jsx("div",{className:"rfs:absolute rfs:right-1 rfs:top-1 rfs:flex rfs:h-4 rfs:w-4 rfs:items-center rfs:justify-center rfs:rounded-full rfs:bg-red-600 rfs:text-[10px] rfs:font-bold rfs:text-white",children:"X"}),jsx("div",{className:"rfs:text-xs rfs:font-semibold",children:o}),r&&jsx("div",{className:"rfs:mt-1 rfs:text-[10px] rfs:font-medium",children:r})]})},me=it;function oe({appointment:e,onResizePointerDown:t}){return jsx("div",{role:"button","aria-label":"Resize appointment",onPointerDown:r=>{e.visualState!=="ghost"&&(r.stopPropagation(),t(r));},className:"rfs:absolute rfs:inset-x-1 rfs:bottom-1 rfs:h-2 rfs:cursor-ns-resize rfs:rounded-full rfs:bg-border/90 rfs:transition-colors rfs:hover:bg-border"})}function G({appointment:e,isDropInvalid:t,onPointerDown:r,onResizePointerDown:o,appointmentAppearance:n,appointmentBackgroundColor:i}){let c=e.raw,a=typeof c.description=="string"?c.description:void 0,s=typeof i=="string"?i:void 0,d=n?.className??s??"rfs:bg-muted/40 rfs:dark:bg-muted/30",f=t?"rfs:bg-red-100/80 rfs:text-red-950 rfs:dark:bg-red-950/40 rfs:dark:text-red-100":"",l=e.visualState==="ghost"?"rfs:cursor-grab rfs:opacity-35":e.visualState==="dragging"?"rfs:cursor-grabbing rfs:opacity-55 rfs:shadow-xl":"rfs:cursor-grab",g=`rfs:relative rfs:h-full rfs:overflow-hidden rfs:rounded-md rfs:p-2 rfs:pb-5 rfs:text-foreground ${d} ${f} ${l}`;return jsxs("div",{onPointerDown:r,className:g,children:[jsx(me,{isDropInvalid:t,title:e.title,description:a}),jsx(oe,{onResizePointerDown:o,appointment:e})]})}function he(e){if(!e||typeof e!="object")return false;let t=e;return typeof t.firstName=="string"||typeof t.lastName=="string"}var Te={slate:"bg-slate-100 dark:bg-slate-900/40",gray:"bg-gray-100 dark:bg-gray-900/40",zinc:"bg-zinc-100 dark:bg-zinc-900/40",neutral:"bg-neutral-100 dark:bg-neutral-900/40",stone:"bg-stone-100 dark:bg-stone-900/40",red:"bg-red-100 dark:bg-red-950/40",orange:"bg-orange-100 dark:bg-orange-950/40",amber:"bg-amber-100 dark:bg-amber-950/40",yellow:"bg-yellow-100 dark:bg-yellow-950/40",lime:"bg-lime-100 dark:bg-lime-950/40",green:"bg-green-100 dark:bg-green-950/40",emerald:"bg-emerald-100 dark:bg-emerald-950/40",teal:"bg-teal-100 dark:bg-teal-950/40",cyan:"bg-cyan-100 dark:bg-cyan-950/40",sky:"bg-sky-100 dark:bg-sky-950/40",blue:"bg-blue-100 dark:bg-blue-950/40",indigo:"bg-indigo-100 dark:bg-indigo-950/40",violet:"bg-violet-100 dark:bg-violet-950/40",purple:"bg-purple-100 dark:bg-purple-950/40",fuchsia:"bg-fuchsia-100 dark:bg-fuchsia-950/40",pink:"bg-pink-100 dark:bg-pink-950/40",rose:"bg-rose-100 dark:bg-rose-950/40"};function D(e,t,r){return Math.max(t,Math.min(r,e))}function U(e,t=15){return Math.round(e/t)*t}function se(e){let[t,r]=e.split(":").map(Number);return t*60+r}function Ie(e){return `${e.firstName??""} ${e.lastName??""}`.trim()}function K(e){return format(e,"yyyy-MM-dd")}function ie(e,t){return new Date(e.getFullYear(),e.getMonth(),e.getDate()+t)}function z(e,t,r){let o=new Date(e.getFullYear(),e.getMonth(),e.getDate(),0,0,0,0),n=t+r,i=Math.floor(n/60),c=n%60;return o.setHours(i,c,0,0),o}function ae(e,t){return t.getHours()*60+t.getMinutes()-e}function ce(e,t){return e.startMin<t.endMin&&t.startMin<e.endMin}function Se(e){let t=[...e].sort((c,a)=>c.startMin-a.startMin||c.endMin-a.endMin),r=[],o=[],n=[];for(let c of t)o=o.filter(s=>s.endMin>c.startMin),!o.some(s=>ce(s,c))&&n.length>0&&(r.push(n),n=[]),n.push(c),o.push(c);n.length&&r.push(n);let i=[];for(let c of r){let a=[...c].sort((l,g)=>l.startMin-g.startMin||l.endMin-g.endMin),s=[],d=new Map;for(let l of a){let g=false;for(let p=0;p<s.length;p++)if(s[p]<=l.startMin){s[p]=l.endMin,d.set(l.id,p),g=true;break}g||(s.push(l.endMin),d.set(l.id,s.length-1));}let f=s.length;for(let l of a)i.push({...l,lane:d.get(l.id)??0,lanes:f});}return i}function ue({fallback:e,getValue:t,resources:r,toKey:o}){let n=new Map;for(let i of r)n.set(o(i),t(i)??e);return n}function be({adapter:e,appointments:t,dayMinutes:r,dayStartAbs:o,selectedISO:n}){return t.map(i=>{let c=new Date(e.getStart(i)),a=new Date(e.getEnd(i));return {raw:i,id:e.getId(i),resourceId:e.getResourceId(i),start:c,end:a,startMin:D(ae(o,c),0,r),endMin:D(ae(o,a),0,r),title:e.getTitle(i),renderKey:String(e.getId(i)),visualState:"normal"}}).filter(i=>K(i.start)===n)}function ye(e){return new Map(e.map(t=>[t.id,t]))}function Me(e,t,r,o){return t.kind==="none"||t.kind==="move"?e:e.map(n=>n.id!==t.appointmentId?n:{...n,resourceId:t.resourceId,startMin:t.startMin,endMin:t.endMin,start:z(r,o,t.startMin),end:z(r,o,t.endMin),visualState:"dragging"})}function Ae(e,t){let r=new Map;for(let n of t){let i=r.get(n.resourceId)??[];i.push(n),r.set(n.resourceId,i);}let o=new Map;for(let n of e)o.set(n.id,de(r.get(n.id)??[]));return o}function de(e){return Se(e.map(t=>({...t,appointmentId:t.id,id:t.renderKey}))).map(({appointmentId:t,...r})=>({...r,id:t}))}function Pe(e,t,r,o,n){let i=new Map;for(let c of e){let a=t?.[String(c.id)];if(a){i.set(c.id,{className:a});continue}let s=r?.(c);if(s){i.set(c.id,s);continue}let d=o.get(c.id);if(d){i.set(c.id,{className:d});continue}let f=n.get(c.id);i.set(c.id,f?{className:f}:void 0);}return i}function De({adapter:e,appointments:t,dayEnd:r="18:00",dayStart:o="09:00",resources:n,selectedDate:i}){let c=h.useMemo(()=>se(o),[o]),a=h.useMemo(()=>se(r),[r]),s=h.useMemo(()=>Math.max(0,a-c),[a,c]),d=h.useMemo(()=>12+s*2+24,[s]),f=h.useMemo(()=>72+Math.max(n.length,1)*420,[n.length]),l=h.useMemo(()=>K(i),[i]),g=h.useMemo(()=>be({adapter:e,appointments:t,dayMinutes:s,dayStartAbs:c,selectedISO:l}),[e,t,s,c,l]);return {appointmentMap:h.useMemo(()=>ye(g),[g]),dayEndAbs:a,dayMinutes:s,dayStartAbs:c,gridHeight:d,gridMinWidth:f,renderAppts:g}}var pt=4,ft=(e,t)=>{e(r=>r&&{...r,clientX:t.clientX,clientY:t.clientY});},mt=e=>{let{dragRef:t,pendingDragRef:r,pointer:o,setDrag:n,setMovePreview:i,suppressClickRef:c}=e,a=r.current;if(!a||a.drag.pointerId!==o.pointerId)return;let s=o.clientX-a.startClientX,d=o.clientY-a.startClientY;Math.hypot(s,d)<pt||(c.current=true,t.current=a.drag,n(a.drag),a.drag.kind==="move"&&i({appointment:a.appointment,clientX:o.clientX,clientY:o.clientY,width:a.width,height:a.height,offsetX:a.offsetX,offsetY:a.offsetY}),r.current=null);},Rt=(e,t,r,o,n)=>{let i=o(t.clientX,e.resourceId),a=n(i,t.clientY)-e.offsetMin,s=D(U(a),0,r-e.durationMin),d=s+e.durationMin;return s===e.startMin&&d===e.endMin&&i===e.resourceId?null:{...e,resourceId:i,startMin:s,endMin:d}},gt=(e,t,r,o)=>{let n=o(e.resourceId,t.clientY),i=D(U(n),e.startMin+15,r);return i===e.endMin?null:{...e,endMin:i}},we=e=>{let{dayMinutes:t,dragRef:r,latestPointerRef:o,pendingDragRef:n,pointerToMin:i,pointerToResourceId:c,setDrag:a,setMovePreview:s,suppressClickRef:d}=e,f=o.current;if(!f)return;let l=r.current;if(l.kind==="none"&&n.current){mt({pointer:f,pendingDragRef:n,setDrag:a,setMovePreview:s,dragRef:r,suppressClickRef:d});return}if(l.kind==="none")return;if(l.kind==="move"){ft(s,f);let p=Rt(l,f,t,c,i);p&&(d.current=true,r.current=p,a(p));return}let g=gt(l,f,t,i);g&&(d.current=true,r.current=g,a(g));},Ne=e=>{let{dragRef:t,frameRef:r,latestPointerRef:o,pendingDragRef:n,persistDrag:i,setDrag:c,setMovePreview:a,suppressClickRef:s}=e;r.current!==null&&(window.cancelAnimationFrame(r.current),r.current=null),o.current=null,n.current=null,a(null);let d=t.current;d.kind!=="none"&&(c({kind:"none"}),t.current={kind:"none"},s.current&&i(d));};var Ce=({appointmentMap:e,dayMinutes:t,dayStartAbs:r,onAppointmentChange:o,onPersistMoveResize:n,renderAppts:i,resources:c,selectedDate:a,editable:s})=>{let[d,f]=h.useState({kind:"none"}),[l,g]=h.useState(null),p=h.useRef({}),T=h.useRef(false),v=h.useRef({kind:"none"}),S=h.useRef(null),b=h.useRef(null),y=h.useRef(null);h.useEffect(()=>{v.current=d;},[d]),h.useEffect(()=>()=>{y.current!==null&&window.cancelAnimationFrame(y.current);},[]);let E=h.useCallback((u,m)=>{let R=p.current[String(u)];if(!R)return 0;let M=m-R.getBoundingClientRect().top-12;return D(U(M/2),0,t)},[t]),$=h.useCallback((u,m)=>{for(let R of c){let M=p.current[String(R.id)];if(!M)continue;let X=M.getBoundingClientRect();if(u>=X.left&&u<=X.right)return R.id}return m},[c]),O=h.useCallback((u,m,R,M)=>i.filter(k=>k.resourceId===m&&k.id!==u).some(k=>ce(k,{startMin:R,endMin:M})),[i]),Y=h.useMemo(()=>d.kind==="none"?false:O(d.appointmentId,d.resourceId,d.startMin,d.endMin),[d,O]),L=h.useCallback(async u=>{let m=e.get(u.appointmentId);if(!m||O(u.appointmentId,u.resourceId,u.startMin,u.endMin))return;let R={resourceId:u.resourceId,start:z(a,r,u.startMin),end:z(a,r,u.endMin)};if(o){await o({kind:u.kind,appointment:m.raw,previous:{resourceId:m.resourceId,start:m.start,end:m.end},next:R});return}n&&await n({appointment:m.raw,resourceId:R.resourceId,start:R.start,end:R.end});},[e,r,O,o,n,a]),F=h.useCallback((u,m)=>{if(!s||u.button!==0)return;u.stopPropagation(),T.current=false;let R=u.currentTarget.getBoundingClientRect(),M=E(m.resourceId,u.clientY);S.current={drag:{kind:"move",appointmentId:m.id,pointerId:u.pointerId,resourceId:m.resourceId,durationMin:Math.max(15,m.endMin-m.startMin),offsetMin:M-m.startMin,startMin:m.startMin,endMin:m.endMin},appointment:m,startClientX:u.clientX,startClientY:u.clientY,width:R.width,height:R.height,offsetX:u.clientX-R.left,offsetY:u.clientY-R.top};},[E,s]),j=h.useCallback((u,m)=>{s&&u.button===0&&(u.stopPropagation(),T.current=false,S.current={drag:{kind:"resize",appointmentId:m.id,pointerId:u.pointerId,resourceId:m.resourceId,startMin:m.startMin,endMin:m.endMin},appointment:m,startClientX:u.clientX,startClientY:u.clientY,width:0,height:0,offsetX:0,offsetY:0});},[s]),W=h.useCallback(u=>{b.current={clientX:u.clientX,clientY:u.clientY,pointerId:u.pointerId},y.current===null&&(y.current=window.requestAnimationFrame(()=>{y.current=null,we({dayMinutes:t,dragRef:v,latestPointerRef:b,pendingDragRef:S,pointerToMin:E,pointerToResourceId:$,setDrag:f,setMovePreview:g,suppressClickRef:T});}));},[t,E,$]),ee=h.useCallback(()=>{Ne({dragRef:v,frameRef:y,latestPointerRef:b,pendingDragRef:S,persistDrag:L,setDrag:f,setMovePreview:g,suppressClickRef:T});},[L]);return {colRefs:p,drag:d,isDropInvalid:Y,movePreview:l,onApptPointerDown:F,onGlobalPointerMove:W,onGlobalPointerUp:ee,onResizePointerDown:j,suppressClickRef:T}};function Be({appointmentColorTokenClassMap:e,dayStartAbs:t,drag:r,getResourceAppointmentAppearance:o,getResourceAppointmentBackground:n,getResourceAppointmentColorToken:i,renderAppts:c,resourceAppointmentClassMap:a,resources:s,selectedDate:d}){let f=h.useMemo(()=>Me(c,r,d,t),[t,r,c,d]),l=h.useMemo(()=>Ae(s,c),[c,s]),g=h.useMemo(()=>{if(r.kind!=="resize")return l;let S=new Map(l),b=f.filter(y=>y.resourceId===r.resourceId);return S.set(r.resourceId,de(b)),S},[l,r,f]),p=h.useMemo(()=>n?ue({fallback:void 0,getValue:n,resources:s,toKey:S=>S.id}):new Map,[n,s]),T=h.useMemo(()=>{if(!i)return new Map;let S={...Te,...e??{}};return ue({fallback:void 0,getValue:b=>{let y=i(b);return y?S[y]:void 0},resources:s,toKey:b=>b.id})},[e,i,s]);return {appointmentAppearanceByResource:h.useMemo(()=>Pe(s,a,o,T,p),[p,T,o,a,s]),appointmentBgByResource:p,effectiveAppts:f,laidOutByResource:g}}function Ee({dayMinutes:e,dayStartAbs:t,gridHeight:r}){return jsx("div",{className:"rfs-times rfs:border-border rfs:bg-card",style:{width:72,height:r},children:Array.from({length:Math.floor(e/60)+1}).map((o,n)=>jsxs("div",{className:"rfs-time-tick rfs:text-muted-foreground",style:{top:12+n*60*2},children:[String(Math.floor((t+n*60)/60)).padStart(2,"0"),":",String((t+n*60)%60).padStart(2,"0")]},`tick-${n}`))})}function Oe({resource:e}){return jsx("strong",{children:e.label})}function ze({resources:e,renderResourceHeader:t}){return jsxs("div",{className:"rfs-header rfs:border-border rfs:bg-card",children:[jsx("div",{className:"rfs-gutter rfs:border-border",style:{width:72}}),e.map(r=>jsxs("div",{className:"rfs-resource-header rfs:border-border rfs:bg-card rfs:text-foreground",style:{minWidth:420,flex:1},children:[(t??(o=>Oe({resource:o})))(r),he(r)?jsx("div",{className:"rfs-resource-subtitle rfs:text-muted-foreground",children:Ie(r)}):null]},String(r.id)))]})}var He=({resource:e,colRefs:t,gridHeight:r,dayMinutes:o,appointments:n,appointmentAppearance:i,appointmentBg:c,isDropInvalid:a,renderAppointment:s,onApptPointerDown:d,onResizePointerDown:f,drag:l,suppressClickRef:g})=>jsx("div",{className:"rfs-col rfs:border-border rfs:bg-card",style:{minWidth:420,flex:1},children:jsxs("div",{ref:p=>{t.current[String(e.id)]=p;},className:"rfs-col-inner rfs:bg-card",style:{height:r},children:[Array.from({length:Math.floor(o/60)+1}).map((p,T)=>jsx("div",{className:"rfs-hour-line rfs:border-border/70",style:{top:12+T*60*2}},`major-${T}`)),Array.from({length:Math.floor(o/15)+1}).map((p,T)=>jsx("div",{className:"rfs-slot-line rfs:border-border/50",style:{top:12+T*15*2}},`minor-${T}`)),n.map(p=>{let T=100/p.lanes,v=12+p.startMin*2,S=Math.max(30,(p.endMin-p.startMin)*2);return jsx("div",{className:`rfs-card-slot ${p.visualState==="ghost"?"rfs-card-slot--ghost":""} ${p.visualState==="dragging"?"rfs-card-slot--dragging":""}`,style:{top:v,left:`${T*p.lane}%`,width:`${T}%`,height:S},children:(s??G)({appointment:p,isDropInvalid:a&&l.kind==="resize"&&p.id===l.appointmentId,onPointerDown:b=>d(b,p),onResizePointerDown:b=>f(b,p),appointmentAppearance:i,appointmentBackgroundColor:c,drag:l,suppressClickRef:g})},p.renderKey)})]})});var bt=(e,t)=>[e.resource===t.resource,e.colRefs===t.colRefs,e.gridHeight===t.gridHeight,e.dayMinutes===t.dayMinutes,e.appointments===t.appointments,e.appointmentAppearance===t.appointmentAppearance,e.appointmentBg===t.appointmentBg,e.isDropInvalid===t.isDropInvalid,e.renderAppointment===t.renderAppointment,e.onApptPointerDown===t.onApptPointerDown,e.onResizePointerDown===t.onResizePointerDown,e.drag===t.drag,e.suppressClickRef===t.suppressClickRef].every(Boolean),Xe=h.memo(He,bt);function H(...e){return e.filter(Boolean).join(" ")}var yt={default:"rfs:bg-primary rfs:text-primary-foreground rfs:hover:bg-primary/90",outline:"rfs:border rfs:border-border rfs:bg-card rfs:text-foreground rfs:hover:bg-muted",ghost:"rfs:text-foreground rfs:hover:bg-muted"},Mt={default:"rfs:h-9 rfs:px-4 rfs:py-2",sm:"rfs:h-8 rfs:px-3 rfs:text-xs",icon:"rfs:h-8 rfs:w-8"},P=h.forwardRef(function({className:t,variant:r="default",size:o="default",type:n="button",...i},c){return jsx("button",{ref:c,type:n,className:H("rfs:inline-flex rfs:items-center rfs:justify-center rfs:gap-2 rfs:rounded-md rfs:text-sm rfs:font-medium rfs:whitespace-nowrap rfs:transition-colors rfs:focus-visible:outline-none rfs:focus-visible:ring-2 rfs:focus-visible:ring-ring rfs:focus-visible:ring-offset-2 rfs:disabled:pointer-events-none rfs:disabled:opacity-50",yt[r],Mt[o],t),...i})});function We({selected:e,onSelect:t}){let[r,o]=h.useState(e??new Date);h.useEffect(()=>{e&&o(e);},[e]);let n=startOfMonth(r),i=startOfWeek(n,{weekStartsOn:1}),c=endOfWeek(endOfMonth(r),{weekStartsOn:1}),a=[];for(let s=i;s<=c;s=addDays(s,1))a.push(s);return jsxs("div",{className:"rfs:w-72 rfs:rounded-md rfs:bg-popover",children:[jsxs("div",{className:"rfs:mb-2 rfs:flex rfs:items-center rfs:justify-between",children:[jsx(P,{variant:"ghost",size:"icon","aria-label":"Previous month",onClick:()=>o(addMonths(r,-1)),children:"<"}),jsx("div",{className:"rfs:text-sm rfs:font-medium",children:format(r,"MMMM yyyy")}),jsx(P,{variant:"ghost",size:"icon","aria-label":"Next month",onClick:()=>o(addMonths(r,1)),children:">"})]}),jsx("div",{className:"rfs:grid rfs:grid-cols-7 rfs:gap-1 rfs:text-center rfs:text-xs rfs:text-muted-foreground",children:["Mo","Tu","We","Th","Fr","Sa","Su"].map(s=>jsx("div",{className:"rfs:py-1",children:s},s))}),jsx("div",{className:"rfs:grid rfs:grid-cols-7 rfs:gap-1",children:a.map(s=>{let d=e?isSameDay(s,e):false;return jsx(P,{variant:d?"default":"ghost",size:"icon",className:H("rfs:text-xs",!isSameMonth(s,r)&&"rfs:text-muted-foreground rfs:opacity-60",isToday(s)&&!d&&"rfs:border rfs:border-border"),onClick:()=>t?.(s),children:format(s,"d")},s.toISOString())})})]})}var Ge=h.createContext(null);function Ke(){let e=h.useContext(Ge);if(!e)throw new Error("Popover components must be used within Popover.");return e}function qe({children:e,open:t,onOpenChange:r}){let[o,n]=h.useState(false),i=h.useRef(null),c=h.useRef(null),a=t??o,s=h.useCallback(d=>{let f=typeof d=="function"?d(a):d;t===void 0&&n(f),r?.(f);},[t,r,a]);return h.useEffect(()=>{if(!a)return;let d=l=>{let g=l.target;i.current?.contains(g)||c.current?.contains(g)||s(false);},f=l=>{l.key==="Escape"&&s(false);};return document.addEventListener("mousedown",d),document.addEventListener("keydown",f),()=>{document.removeEventListener("mousedown",d),document.removeEventListener("keydown",f);}},[a,s]),jsx(Ge.Provider,{value:{open:a,setOpen:s,triggerRef:i,contentRef:c},children:jsx("div",{className:"rfs:relative rfs:inline-flex",children:e})})}function Je({children:e,asChild:t=false}){let{open:r,setOpen:o,triggerRef:n}=Ke();if(t&&h.isValidElement(e)){let i=e;return h.cloneElement(i,{ref:n,"aria-expanded":r,onClick:c=>{i.props.onClick?.(c),o(a=>!a);}})}return jsx("button",{ref:n,type:"button","aria-expanded":r,onClick:()=>o(i=>!i),children:e})}function Qe({children:e,className:t,align:r="start"}){let{open:o,contentRef:n}=Ke();return o?jsx("div",{ref:n,className:H("rfs:absolute rfs:top-full rfs:z-50 rfs:mt-2 rfs:min-w-72 rfs:rounded-md rfs:border rfs:border-border rfs:bg-popover rfs:p-2 rfs:text-popover-foreground rfs:shadow-md rfs:outline-none",r==="start"&&"rfs:left-0",r==="center"&&"rfs:left-1/2 rfs:-translate-x-1/2",r==="end"&&"rfs:right-0",t),children:e}):null}function Ze({selectedDate:e,onSelectedDateChange:t}){return jsxs(qe,{children:[jsx(Je,{asChild:true,children:jsx(P,{variant:"outline",size:"sm",className:"rfs:min-w-40 rfs:justify-start rfs:text-left rfs:font-normal",children:format(e,"PPP")})}),jsx(Qe,{className:"rfs:w-auto rfs:p-2",align:"center",children:jsx(We,{selected:e,onSelect:t})})]})}function je({goToPreviousDay:e,goToNextDay:t,defaultDatePicker:r,prevButtonLabel:o="Prev",nextButtonLabel:n="Next"}){return jsx("div",{className:"rfs-toolbar",children:jsxs("div",{className:"rfs:flex rfs:items-center rfs:gap-2 rfs:rounded-lg rfs:border rfs:border-border rfs:bg-card rfs:p-1 rfs:shadow-xs",children:[jsx(P,{variant:"outline",size:"sm",onClick:e,children:o}),r,jsx(P,{variant:"outline",size:"sm",onClick:t,children:n})]})})}function rt({selectedDate:e,onSelectedDateChange:t,prevButtonLabel:r,nextButtonLabel:o,renderToolbar:n,renderDatePicker:i}){let c=()=>t(ie(e,-1)),a=()=>t(ie(e,1)),s=(i??Ze)({selectedDate:e,onSelectedDateChange:t});return n?jsx(Fragment,{children:n({selectedDate:e,onSelectedDateChange:t,goToPreviousDay:c,goToNextDay:a,defaultDatePicker:s})}):jsx(Fragment,{children:je({goToPreviousDay:c,goToNextDay:a,defaultDatePicker:s,prevButtonLabel:r,nextButtonLabel:o})})}var Lt={kind:"none"};function _t({resources:e,appointments:t,selectedDate:r,onSelectedDateChange:o,adapter:n,onPersistMoveResize:i,onAppointmentChange:c,renderResourceHeader:a,renderAppointment:s,resourceAppointmentClassMap:d,getResourceAppointmentAppearance:f,getResourceAppointmentColorToken:l,appointmentColorTokenClassMap:g,getResourceAppointmentBackground:p,renderToolbar:T,renderDatePicker:v,prevButtonLabel:S="Prev",nextButtonLabel:b="Next",dayStart:y="09:00",dayEnd:E="18:00",editable:$=true}){let{appointmentMap:O,dayMinutes:Y,dayStartAbs:L,gridHeight:F,gridMinWidth:j,renderAppts:W}=De({adapter:n,appointments:t,dayEnd:E,dayStart:y,resources:e,selectedDate:r}),{colRefs:ee,drag:u,isDropInvalid:m,movePreview:R,onApptPointerDown:M,onGlobalPointerMove:X,onGlobalPointerUp:k,onResizePointerDown:ot,suppressClickRef:fe}=Ce({appointmentMap:O,dayMinutes:Y,dayStartAbs:L,onAppointmentChange:c,onPersistMoveResize:i,renderAppts:W,resources:e,selectedDate:r,editable:$}),{appointmentAppearanceByResource:te,appointmentBgByResource:re,laidOutByResource:st}=Be({appointmentColorTokenClassMap:g,dayStartAbs:L,drag:u,getResourceAppointmentAppearance:f,getResourceAppointmentBackground:p,getResourceAppointmentColorToken:l,renderAppts:W,resourceAppointmentClassMap:d,resources:e,selectedDate:r}),x=h.useMemo(()=>u.kind!=="move"||!R?null:{appointment:{...R.appointment,resourceId:u.resourceId,startMin:u.startMin,endMin:u.endMin,visualState:"ghost",renderKey:`${R.appointment.renderKey}-overlay`,lane:0,lanes:1},appearance:te.get(u.resourceId),background:re.get(u.resourceId),left:R.clientX-R.offsetX,top:R.clientY-R.offsetY,width:R.width,height:R.height},[te,re,u,R]);return jsxs("section",{className:`rfs-root rfs:rounded-lg rfs:text-foreground ${u.kind==="move"?"rfs-root--drag-move":""} ${u.kind==="resize"?"rfs-root--drag-resize":""}`,onPointerMove:X,onPointerUp:k,onPointerCancel:k,children:[jsx(rt,{selectedDate:r,onSelectedDateChange:o,prevButtonLabel:S,nextButtonLabel:b,renderToolbar:T,renderDatePicker:v}),jsx("div",{className:"rfs-shell rfs:border-border rfs:bg-card",children:jsxs("div",{style:{minWidth:j},children:[jsx(ze,{resources:e,renderResourceHeader:a}),jsxs("div",{className:"rfs-body",children:[jsx(Ee,{dayMinutes:Y,dayStartAbs:L,gridHeight:F}),jsx("div",{className:"rfs-grid",children:e.map(_=>jsx(Xe,{resource:_,colRefs:ee,gridHeight:F,dayMinutes:Y,appointments:st.get(_.id)??[],appointmentAppearance:te.get(_.id),appointmentBg:re.get(_.id),isDropInvalid:m,renderAppointment:s,onApptPointerDown:M,onResizePointerDown:ot,drag:u.kind==="resize"&&u.resourceId===_.id?u:Lt,suppressClickRef:fe},String(_.id)))})]})]})}),x?jsx("div",{className:"rfs-drag-overlay",style:{left:x.left,top:x.top,width:x.width,height:x.height},children:(s??G)({appointment:x.appointment,isDropInvalid:m,onPointerDown:()=>{},onResizePointerDown:()=>{},appointmentAppearance:x.appearance,appointmentBackgroundColor:x.background,drag:u,suppressClickRef:fe})}):null]})}function zt(e,t,r){return e.map(o=>{if(r.getId(o)!==r.getId(t.appointment))return o;let n=r.setResourceId(o,t.next.resourceId),i=r.setStart(n,t.next.start);return r.setEnd(i,t.next.end)})}export{_t as Scheduler,zt as applySchedulerAppointmentChange};
1
+ import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {format,startOfMonth,startOfWeek,endOfWeek,endOfMonth,addDays,addMonths,isSameDay,isToday,isSameMonth}from'date-fns';import*as g from'react';var ct=e=>{let{isDropInvalid:t,description:r,title:o}=e;return jsxs(Fragment,{children:[t&&jsx("div",{className:"rfs:absolute rfs:right-1 rfs:top-1 rfs:flex rfs:h-4 rfs:w-4 rfs:items-center rfs:justify-center rfs:rounded-full rfs:bg-red-600 rfs:text-[10px] rfs:font-bold rfs:text-white",children:"X"}),jsx("div",{className:"rfs:text-xs rfs:font-semibold",children:o}),r&&jsx("div",{className:"rfs:mt-1 rfs:text-[10px] rfs:font-medium",children:r})]})},ge=ct;function ie({appointment:e,onResizePointerDown:t}){return jsx("div",{role:"button","aria-label":"Resize appointment",onPointerDown:r=>{e.visualState!=="ghost"&&(r.stopPropagation(),t(r));},className:"rfs:absolute rfs:inset-x-1 rfs:bottom-1 rfs:h-2 rfs:cursor-ns-resize rfs:rounded-full rfs:bg-border/90 rfs:transition-colors rfs:hover:bg-border"})}function q({appointment:e,isDropInvalid:t,onPointerDown:r,onResizePointerDown:o,appointmentAppearance:n,appointmentBackgroundColor:i}){let u=e.raw,d=typeof u.description=="string"?u.description:void 0,s=typeof i=="string"?i:void 0,c=n?.className??s??"rfs:bg-muted/40 rfs:dark:bg-muted/30",m=t?"rfs:bg-red-100/80 rfs:text-red-950 rfs:dark:bg-red-950/40 rfs:dark:text-red-100":"",f=e.visualState==="ghost"?"rfs:cursor-grab rfs:opacity-35":e.visualState==="dragging"?"rfs:cursor-grabbing rfs:opacity-55 rfs:shadow-xl":"rfs:cursor-grab",R=`rfs:relative rfs:h-full rfs:overflow-hidden rfs:rounded-md rfs:p-2 rfs:pb-5 rfs:text-foreground ${c} ${m} ${f}`;return jsxs("div",{onPointerDown:r,className:R,children:[jsx(ge,{isDropInvalid:t,title:e.title,description:d}),jsx(ie,{onResizePointerDown:o,appointment:e})]})}var F=(e,t)=>typeof t=="function"?t(e):e[t],de=e=>"getId"in e?e:{getEnd:t=>F(t,e.end),getId:t=>F(t,e.id),getResourceId:t=>F(t,e.resourceId),getStart:t=>F(t,e.start),getTitle:t=>F(t,e.title)};function Se(e){if(!e||typeof e!="object")return false;let t=e;return typeof t.firstName=="string"||typeof t.lastName=="string"}var be={slate:"bg-slate-100 dark:bg-slate-900/40",gray:"bg-gray-100 dark:bg-gray-900/40",zinc:"bg-zinc-100 dark:bg-zinc-900/40",neutral:"bg-neutral-100 dark:bg-neutral-900/40",stone:"bg-stone-100 dark:bg-stone-900/40",red:"bg-red-100 dark:bg-red-950/40",orange:"bg-orange-100 dark:bg-orange-950/40",amber:"bg-amber-100 dark:bg-amber-950/40",yellow:"bg-yellow-100 dark:bg-yellow-950/40",lime:"bg-lime-100 dark:bg-lime-950/40",green:"bg-green-100 dark:bg-green-950/40",emerald:"bg-emerald-100 dark:bg-emerald-950/40",teal:"bg-teal-100 dark:bg-teal-950/40",cyan:"bg-cyan-100 dark:bg-cyan-950/40",sky:"bg-sky-100 dark:bg-sky-950/40",blue:"bg-blue-100 dark:bg-blue-950/40",indigo:"bg-indigo-100 dark:bg-indigo-950/40",violet:"bg-violet-100 dark:bg-violet-950/40",purple:"bg-purple-100 dark:bg-purple-950/40",fuchsia:"bg-fuchsia-100 dark:bg-fuchsia-950/40",pink:"bg-pink-100 dark:bg-pink-950/40",rose:"bg-rose-100 dark:bg-rose-950/40"};function w(e,t,r){return Math.max(t,Math.min(r,e))}function V(e,t=15){return Math.round(e/t)*t}function ue(e){let[t,r]=e.split(":").map(Number);return t*60+r}function Ae(e){return `${e.firstName??""} ${e.lastName??""}`.trim()}function J(e){return format(e,"yyyy-MM-dd")}function ce(e,t){return new Date(e.getFullYear(),e.getMonth(),e.getDate()+t)}function z(e,t,r){let o=new Date(e.getFullYear(),e.getMonth(),e.getDate(),0,0,0,0),n=t+r,i=Math.floor(n/60),u=n%60;return o.setHours(i,u,0,0),o}function ae(e,t){return t.getHours()*60+t.getMinutes()-e}function pe(e,t){return e.startMin<t.endMin&&t.startMin<e.endMin}function ye(e){let t=[...e].sort((u,d)=>u.startMin-d.startMin||u.endMin-d.endMin),r=[],o=[],n=[];for(let u of t)o=o.filter(s=>s.endMin>u.startMin),!o.some(s=>pe(s,u))&&n.length>0&&(r.push(n),n=[]),n.push(u),o.push(u);n.length&&r.push(n);let i=[];for(let u of r){let d=[...u].sort((f,R)=>f.startMin-R.startMin||f.endMin-R.endMin),s=[],c=new Map;for(let f of d){let R=false;for(let l=0;l<s.length;l++)if(s[l]<=f.startMin){s[l]=f.endMin,c.set(f.id,l),R=true;break}R||(s.push(f.endMin),c.set(f.id,s.length-1));}let m=s.length;for(let f of d)i.push({...f,lane:c.get(f.id)??0,lanes:m});}return i}function le({fallback:e,getValue:t,resources:r,toKey:o}){let n=new Map;for(let i of r)n.set(o(i),t(i)??e);return n}function Me({adapter:e,appointments:t,dayMinutes:r,dayStartAbs:o,selectedISO:n}){return t.map(i=>{let u=e.getId(i),d=new Date(e.getStart(i)),s=new Date(e.getEnd(i));return {raw:i,id:u,resourceId:e.getResourceId(i),start:d,end:s,startMin:w(ae(o,d),0,r),endMin:w(ae(o,s),0,r),title:e.getTitle(i),renderKey:String(u),visualState:"normal"}}).filter(i=>J(i.start)===n)}function ve(e){return new Map(e.map(t=>[t.id,t]))}function Pe(e,t,r,o){return t.kind==="none"||t.kind==="move"?e:e.map(n=>n.id!==t.appointmentId?n:{...n,resourceId:t.resourceId,startMin:t.startMin,endMin:t.endMin,start:z(r,o,t.startMin),end:z(r,o,t.endMin),visualState:"dragging"})}function xe(e,t){let r=new Map;for(let n of t){let i=r.get(n.resourceId)??[];i.push(n),r.set(n.resourceId,i);}let o=new Map;for(let n of e)o.set(n.id,fe(r.get(n.id)??[]));return o}function fe(e){return ye(e.map(t=>({...t,appointmentId:t.id,id:t.renderKey}))).map(({appointmentId:t,...r})=>({...r,id:t}))}function De(e,t,r,o,n){let i=new Map;for(let u of e){let d=t?.[String(u.id)];if(d){i.set(u.id,{className:d});continue}let s=r?.(u);if(s){i.set(u.id,s);continue}let c=o.get(u.id);if(c){i.set(u.id,{className:c});continue}let m=n.get(u.id);i.set(u.id,m?{className:m}:void 0);}return i}function Ne({adapter:e,appointments:t,dayEnd:r="18:00",dayStart:o="09:00",resources:n,selectedDate:i}){let u=g.useMemo(()=>ue(o),[o]),d=g.useMemo(()=>ue(r),[r]),s=g.useMemo(()=>Math.max(0,d-u),[d,u]),c=g.useMemo(()=>12+s*2+24,[s]),m=g.useMemo(()=>72+Math.max(n.length,1)*420,[n.length]),f=g.useMemo(()=>de(e),[e]),R=g.useMemo(()=>J(i),[i]),l=g.useMemo(()=>Me({adapter:f,appointments:t,dayMinutes:s,dayStartAbs:u,selectedISO:R}),[t,s,u,f,R]);return {appointmentMap:g.useMemo(()=>ve(l),[l]),dayEndAbs:d,dayMinutes:s,dayStartAbs:u,gridHeight:c,gridMinWidth:m,renderAppts:l}}var Rt=4,ht=(e,t)=>{e(r=>r&&{...r,clientX:t.clientX,clientY:t.clientY});},gt=e=>{let{dragRef:t,pendingDragRef:r,pointer:o,setDrag:n,setMovePreview:i,suppressClickRef:u}=e,d=r.current;if(!d||d.drag.pointerId!==o.pointerId)return;let s=o.clientX-d.startClientX,c=o.clientY-d.startClientY;Math.hypot(s,c)<Rt||(u.current=true,t.current=d.drag,n(d.drag),d.drag.kind==="move"&&i({appointment:d.appointment,clientX:o.clientX,clientY:o.clientY,width:d.width,height:d.height,offsetX:d.offsetX,offsetY:d.offsetY}),r.current=null);},Tt=(e,t,r,o,n)=>{let i=o(t.clientX,e.resourceId),d=n(i,t.clientY)-e.offsetMin,s=w(V(d),0,r-e.durationMin),c=s+e.durationMin;return s===e.startMin&&c===e.endMin&&i===e.resourceId?null:{...e,resourceId:i,startMin:s,endMin:c}},It=(e,t,r,o)=>{let n=o(e.resourceId,t.clientY),i=w(V(n),e.startMin+15,r);return i===e.endMin?null:{...e,endMin:i}},Be=e=>{let{dayMinutes:t,dragRef:r,latestPointerRef:o,pendingDragRef:n,pointerToMin:i,pointerToResourceId:u,setDrag:d,setMovePreview:s,suppressClickRef:c}=e,m=o.current;if(!m)return;let f=r.current;if(f.kind==="none"&&n.current){gt({pointer:m,pendingDragRef:n,setDrag:d,setMovePreview:s,dragRef:r,suppressClickRef:c});return}if(f.kind==="none")return;if(f.kind==="move"){ht(s,m);let l=Tt(f,m,t,u,i);l&&(c.current=true,r.current=l,d(l));return}let R=It(f,m,t,i);R&&(c.current=true,r.current=R,d(R));},Ee=e=>{let{dragRef:t,frameRef:r,latestPointerRef:o,pendingDragRef:n,persistDrag:i,setDrag:u,setMovePreview:d,suppressClickRef:s}=e;r.current!==null&&(window.cancelAnimationFrame(r.current),r.current=null),o.current=null,n.current=null,d(null);let c=t.current;c.kind!=="none"&&(u({kind:"none"}),t.current={kind:"none"},s.current&&i(c));};var Oe=({appointmentMap:e,dayMinutes:t,dayStartAbs:r,onAppointmentChange:o,onPersistMoveResize:n,renderAppts:i,resources:u,selectedDate:d,editable:s})=>{let[c,m]=g.useState({kind:"none"}),[f,R]=g.useState(null),l=g.useRef({}),T=g.useRef(false),x=g.useRef({kind:"none"}),b=g.useRef(null),A=g.useRef(null),y=g.useRef(null),$=g.useMemo(()=>{let p=new Map;for(let a of i){let h=p.get(a.resourceId)??[];h.push(a),p.set(a.resourceId,h);}return p},[i]);g.useEffect(()=>{x.current=c;},[c]),g.useEffect(()=>()=>{y.current!==null&&window.cancelAnimationFrame(y.current);},[]);let O=g.useCallback((p,a)=>{let h=l.current[String(p)];if(!h)return 0;let M=a-h.getBoundingClientRect().top-12;return w(V(M/2),0,t)},[t]),W=g.useCallback((p,a)=>{for(let h of u){let M=l.current[String(h.id)];if(!M)continue;let L=M.getBoundingClientRect();if(p>=L.left&&p<=L.right)return h.id}return a},[u]),D=g.useCallback((p,a,h,M)=>($.get(a)??[]).some(K=>K.id!==p&&pe(K,{startMin:h,endMin:M})),[$]),Y=g.useMemo(()=>c.kind==="none"?false:D(c.appointmentId,c.resourceId,c.startMin,c.endMin),[c,D]),X=g.useCallback(async p=>{let a=e.get(p.appointmentId);if(!a||D(p.appointmentId,p.resourceId,p.startMin,p.endMin))return;let h={resourceId:p.resourceId,start:z(d,r,p.startMin),end:z(d,r,p.endMin)};if(o){await o({kind:p.kind,appointment:a.raw,resourceId:h.resourceId,start:h.start,end:h.end,previousResourceId:a.resourceId,previousStart:a.start,previousEnd:a.end,previous:{resourceId:a.resourceId,start:a.start,end:a.end},next:h});return}n&&await n({appointment:a.raw,resourceId:h.resourceId,start:h.start,end:h.end});},[e,r,D,o,n,d]),te=g.useCallback((p,a)=>{if(!s||p.button!==0)return;p.stopPropagation(),T.current=false;let h=p.currentTarget.getBoundingClientRect(),M=O(a.resourceId,p.clientY);b.current={drag:{kind:"move",appointmentId:a.id,pointerId:p.pointerId,resourceId:a.resourceId,durationMin:Math.max(15,a.endMin-a.startMin),offsetMin:M-a.startMin,startMin:a.startMin,endMin:a.endMin},appointment:a,startClientX:p.clientX,startClientY:p.clientY,width:h.width,height:h.height,offsetX:p.clientX-h.left,offsetY:p.clientY-h.top};},[O,s]),G=g.useCallback((p,a)=>{s&&p.button===0&&(p.stopPropagation(),T.current=false,b.current={drag:{kind:"resize",appointmentId:a.id,pointerId:p.pointerId,resourceId:a.resourceId,startMin:a.startMin,endMin:a.endMin},appointment:a,startClientX:p.clientX,startClientY:p.clientY,width:0,height:0,offsetX:0,offsetY:0});},[s]),re=g.useCallback(p=>{A.current={clientX:p.clientX,clientY:p.clientY,pointerId:p.pointerId},y.current===null&&(y.current=window.requestAnimationFrame(()=>{y.current=null,Be({dayMinutes:t,dragRef:x,latestPointerRef:A,pendingDragRef:b,pointerToMin:O,pointerToResourceId:W,setDrag:m,setMovePreview:R,suppressClickRef:T});}));},[t,O,W]),S=g.useCallback(()=>{Ee({dragRef:x,frameRef:y,latestPointerRef:A,pendingDragRef:b,persistDrag:X,setDrag:m,setMovePreview:R,suppressClickRef:T});},[X]);return {colRefs:l,drag:c,isDropInvalid:Y,movePreview:f,onApptPointerDown:te,onGlobalPointerMove:re,onGlobalPointerUp:S,onResizePointerDown:G,suppressClickRef:T}};function Le({appointmentColorTokenClassMap:e,dayStartAbs:t,drag:r,getResourceAppointmentAppearance:o,getResourceAppointmentBackground:n,getResourceAppointmentColorToken:i,renderAppts:u,resourceAppointmentClassMap:d,resources:s,selectedDate:c}){let m=g.useMemo(()=>Pe(u,r,c,t),[t,r,u,c]),f=g.useMemo(()=>xe(s,u),[u,s]),R=g.useMemo(()=>{if(r.kind!=="resize")return f;let b=new Map(f),A=m.filter(y=>y.resourceId===r.resourceId);return b.set(r.resourceId,fe(A)),b},[f,r,m]),l=g.useMemo(()=>n?le({fallback:void 0,getValue:n,resources:s,toKey:b=>b.id}):new Map,[n,s]),T=g.useMemo(()=>{if(!i)return new Map;let b={...be,...e??{}};return le({fallback:void 0,getValue:A=>{let y=i(A);return y?b[y]:void 0},resources:s,toKey:A=>A.id})},[e,i,s]);return {appointmentAppearanceByResource:g.useMemo(()=>De(s,d,o,T,l),[l,T,o,d,s]),appointmentBgByResource:l,effectiveAppts:m,laidOutByResource:R}}function _e({dayMinutes:e,dayStartAbs:t,gridHeight:r}){return jsx("div",{className:"rfs-times rfs:border-border rfs:bg-card",style:{width:72,height:r},children:Array.from({length:Math.floor(e/60)+1}).map((o,n)=>jsxs("div",{className:"rfs-time-tick rfs:text-muted-foreground",style:{top:12+n*60*2},children:[String(Math.floor((t+n*60)/60)).padStart(2,"0"),":",String((t+n*60)%60).padStart(2,"0")]},`tick-${n}`))})}function ze({resource:e}){return jsx("strong",{children:e.label})}function Xe({resources:e,renderResourceHeader:t}){return jsxs("div",{className:"rfs-header rfs:border-border rfs:bg-card",children:[jsx("div",{className:"rfs-gutter rfs:border-border",style:{width:72}}),e.map(r=>jsxs("div",{className:"rfs-resource-header rfs:border-border rfs:bg-card rfs:text-foreground",style:{minWidth:420,flex:1},children:[(t??(o=>ze({resource:o})))(r),Se(r)?jsx("div",{className:"rfs-resource-subtitle rfs:text-muted-foreground",children:Ae(r)}):null]},String(r.id)))]})}var Fe=({resource:e,colRefs:t,gridHeight:r,dayMinutes:o,appointments:n,appointmentAppearance:i,appointmentBg:u,isDropInvalid:d,renderAppointment:s,onApptPointerDown:c,onResizePointerDown:m,drag:f,suppressClickRef:R})=>jsx("div",{className:"rfs-col rfs:border-border rfs:bg-card",style:{minWidth:420,flex:1},children:jsxs("div",{ref:l=>{t.current[String(e.id)]=l;},className:"rfs-col-inner rfs:bg-card",style:{height:r},children:[Array.from({length:Math.floor(o/60)+1}).map((l,T)=>jsx("div",{className:"rfs-hour-line rfs:border-border/70",style:{top:12+T*60*2}},`major-${T}`)),Array.from({length:Math.floor(o/15)+1}).map((l,T)=>jsx("div",{className:"rfs-slot-line rfs:border-border/50",style:{top:12+T*15*2}},`minor-${T}`)),n.map(l=>{let T=100/l.lanes,x=12+l.startMin*2,b=Math.max(30,(l.endMin-l.startMin)*2);return jsx("div",{className:`rfs-card-slot ${l.visualState==="ghost"?"rfs-card-slot--ghost":""} ${l.visualState==="dragging"?"rfs-card-slot--dragging":""}`,style:{top:x,left:`${T*l.lane}%`,width:`${T}%`,height:b},children:(s??q)({appointment:l,isDropInvalid:d&&f.kind==="resize"&&l.id===f.appointmentId,onPointerDown:A=>c(A,l),onResizePointerDown:A=>m(A,l),appointmentAppearance:i,appointmentBackgroundColor:u,drag:f,suppressClickRef:R})},l.renderKey)})]})});var Mt=(e,t)=>[e.resource===t.resource,e.colRefs===t.colRefs,e.gridHeight===t.gridHeight,e.dayMinutes===t.dayMinutes,e.appointments===t.appointments,e.appointmentAppearance===t.appointmentAppearance,e.appointmentBg===t.appointmentBg,e.isDropInvalid===t.isDropInvalid,e.renderAppointment===t.renderAppointment,e.onApptPointerDown===t.onApptPointerDown,e.onResizePointerDown===t.onResizePointerDown,e.drag===t.drag,e.suppressClickRef===t.suppressClickRef].every(Boolean),Ue=g.memo(Fe,Mt);function H(...e){return e.filter(Boolean).join(" ")}var vt={default:"rfs:bg-primary rfs:text-primary-foreground rfs:hover:bg-primary/90",outline:"rfs:border rfs:border-border rfs:bg-card rfs:text-foreground rfs:hover:bg-muted",ghost:"rfs:text-foreground rfs:hover:bg-muted"},Pt={default:"rfs:h-9 rfs:px-4 rfs:py-2",sm:"rfs:h-8 rfs:px-3 rfs:text-xs",icon:"rfs:h-8 rfs:w-8"},P=g.forwardRef(function({className:t,variant:r="default",size:o="default",type:n="button",...i},u){return jsx("button",{ref:u,type:n,className:H("rfs:inline-flex rfs:items-center rfs:justify-center rfs:gap-2 rfs:rounded-md rfs:text-sm rfs:font-medium rfs:whitespace-nowrap rfs:transition-colors rfs:focus-visible:outline-none rfs:focus-visible:ring-2 rfs:focus-visible:ring-ring rfs:focus-visible:ring-offset-2 rfs:disabled:pointer-events-none rfs:disabled:opacity-50",vt[r],Pt[o],t),...i})});function qe({selected:e,onSelect:t}){let[r,o]=g.useState(e??new Date);g.useEffect(()=>{e&&o(e);},[e]);let n=startOfMonth(r),i=startOfWeek(n,{weekStartsOn:1}),u=endOfWeek(endOfMonth(r),{weekStartsOn:1}),d=[];for(let s=i;s<=u;s=addDays(s,1))d.push(s);return jsxs("div",{className:"rfs:w-72 rfs:rounded-md rfs:bg-popover",children:[jsxs("div",{className:"rfs:mb-2 rfs:flex rfs:items-center rfs:justify-between",children:[jsx(P,{variant:"ghost",size:"icon","aria-label":"Previous month",onClick:()=>o(addMonths(r,-1)),children:"<"}),jsx("div",{className:"rfs:text-sm rfs:font-medium",children:format(r,"MMMM yyyy")}),jsx(P,{variant:"ghost",size:"icon","aria-label":"Next month",onClick:()=>o(addMonths(r,1)),children:">"})]}),jsx("div",{className:"rfs:grid rfs:grid-cols-7 rfs:gap-1 rfs:text-center rfs:text-xs rfs:text-muted-foreground",children:["Mo","Tu","We","Th","Fr","Sa","Su"].map(s=>jsx("div",{className:"rfs:py-1",children:s},s))}),jsx("div",{className:"rfs:grid rfs:grid-cols-7 rfs:gap-1",children:d.map(s=>{let c=e?isSameDay(s,e):false;return jsx(P,{variant:c?"default":"ghost",size:"icon",className:H("rfs:text-xs",!isSameMonth(s,r)&&"rfs:text-muted-foreground rfs:opacity-60",isToday(s)&&!c&&"rfs:border rfs:border-border"),onClick:()=>t?.(s),children:format(s,"d")},s.toISOString())})})]})}var Je=g.createContext(null);function Qe(){let e=g.useContext(Je);if(!e)throw new Error("Popover components must be used within Popover.");return e}function Ze({children:e,open:t,onOpenChange:r}){let[o,n]=g.useState(false),i=g.useRef(null),u=g.useRef(null),d=t??o,s=g.useCallback(c=>{let m=typeof c=="function"?c(d):c;t===void 0&&n(m),r?.(m);},[t,r,d]);return g.useEffect(()=>{if(!d)return;let c=f=>{let R=f.target;i.current?.contains(R)||u.current?.contains(R)||s(false);},m=f=>{f.key==="Escape"&&s(false);};return document.addEventListener("mousedown",c),document.addEventListener("keydown",m),()=>{document.removeEventListener("mousedown",c),document.removeEventListener("keydown",m);}},[d,s]),jsx(Je.Provider,{value:{open:d,setOpen:s,triggerRef:i,contentRef:u},children:jsx("div",{className:"rfs:relative rfs:inline-flex",children:e})})}function je({children:e,asChild:t=false}){let{open:r,setOpen:o,triggerRef:n}=Qe();if(t&&g.isValidElement(e)){let i=e;return g.cloneElement(i,{ref:n,"aria-expanded":r,onClick:u=>{i.props.onClick?.(u),o(d=>!d);}})}return jsx("button",{ref:n,type:"button","aria-expanded":r,onClick:()=>o(i=>!i),children:e})}function et({children:e,className:t,align:r="start"}){let{open:o,contentRef:n}=Qe();return o?jsx("div",{ref:n,className:H("rfs:absolute rfs:top-full rfs:z-50 rfs:mt-2 rfs:min-w-72 rfs:rounded-md rfs:border rfs:border-border rfs:bg-popover rfs:p-2 rfs:text-popover-foreground rfs:shadow-md rfs:outline-none",r==="start"&&"rfs:left-0",r==="center"&&"rfs:left-1/2 rfs:-translate-x-1/2",r==="end"&&"rfs:right-0",t),children:e}):null}function tt({selectedDate:e,onSelectedDateChange:t}){return jsxs(Ze,{children:[jsx(je,{asChild:true,children:jsx(P,{variant:"outline",size:"sm",className:"rfs:min-w-40 rfs:justify-start rfs:text-left rfs:font-normal",children:format(e,"PPP")})}),jsx(et,{className:"rfs:w-auto rfs:p-2",align:"center",children:jsx(qe,{selected:e,onSelect:t})})]})}function rt({goToPreviousDay:e,goToNextDay:t,defaultDatePicker:r,prevButtonLabel:o="Prev",nextButtonLabel:n="Next"}){return jsx("div",{className:"rfs-toolbar",children:jsxs("div",{className:"rfs:flex rfs:items-center rfs:gap-2 rfs:rounded-lg rfs:border rfs:border-border rfs:bg-card rfs:p-1 rfs:shadow-xs",children:[jsx(P,{variant:"outline",size:"sm",onClick:e,children:o}),r,jsx(P,{variant:"outline",size:"sm",onClick:t,children:n})]})})}function st({selectedDate:e,onSelectedDateChange:t,prevButtonLabel:r,nextButtonLabel:o,renderToolbar:n,renderDatePicker:i}){let u=()=>t(ce(e,-1)),d=()=>t(ce(e,1)),s=(i??tt)({selectedDate:e,onSelectedDateChange:t});return n?jsx(Fragment,{children:n({selectedDate:e,onSelectedDateChange:t,goToPreviousDay:u,goToNextDay:d,defaultDatePicker:s})}):jsx(Fragment,{children:rt({goToPreviousDay:u,goToNextDay:d,defaultDatePicker:s,prevButtonLabel:r,nextButtonLabel:o})})}var Ht={kind:"none"};function Yt({resources:e,appointments:t,selectedDate:r,onSelectedDateChange:o,adapter:n,onPersistMoveResize:i,onAppointmentChange:u,renderResourceHeader:d,renderAppointment:s,resourceAppointmentClassMap:c,getResourceAppointmentAppearance:m,getResourceAppointmentColorToken:f,appointmentColorTokenClassMap:R,getResourceAppointmentBackground:l,renderToolbar:T,renderDatePicker:x,prevButtonLabel:b="Prev",nextButtonLabel:A="Next",dayStart:y="09:00",dayEnd:$="18:00",editable:O=true}){let{appointmentMap:W,dayMinutes:D,dayStartAbs:Y,gridHeight:X,gridMinWidth:te,renderAppts:G}=Ne({adapter:n,appointments:t,dayEnd:$,dayStart:y,resources:e,selectedDate:r}),{colRefs:re,drag:S,isDropInvalid:p,movePreview:a,onApptPointerDown:h,onGlobalPointerMove:M,onGlobalPointerUp:L,onResizePointerDown:K,suppressClickRef:he}=Oe({appointmentMap:W,dayMinutes:D,dayStartAbs:Y,onAppointmentChange:u,onPersistMoveResize:i,renderAppts:G,resources:e,selectedDate:r,editable:O}),{appointmentAppearanceByResource:ne,appointmentBgByResource:oe,laidOutByResource:ut}=Le({appointmentColorTokenClassMap:R,dayStartAbs:Y,drag:S,getResourceAppointmentAppearance:m,getResourceAppointmentBackground:l,getResourceAppointmentColorToken:f,renderAppts:G,resourceAppointmentClassMap:c,resources:e,selectedDate:r}),k=g.useMemo(()=>S.kind!=="move"||!a?null:{appointment:{...a.appointment,resourceId:S.resourceId,startMin:S.startMin,endMin:S.endMin,visualState:"ghost",renderKey:`${a.appointment.renderKey}-overlay`,lane:0,lanes:1},appearance:ne.get(S.resourceId),background:oe.get(S.resourceId),left:a.clientX-a.offsetX,top:a.clientY-a.offsetY,width:a.width,height:a.height},[ne,oe,S,a]);return jsxs("section",{className:`rfs-root rfs:rounded-lg rfs:text-foreground ${S.kind==="move"?"rfs-root--drag-move":""} ${S.kind==="resize"?"rfs-root--drag-resize":""}`,onPointerMove:M,onPointerUp:L,onPointerCancel:L,children:[jsx(st,{selectedDate:r,onSelectedDateChange:o,prevButtonLabel:b,nextButtonLabel:A,renderToolbar:T,renderDatePicker:x}),jsx("div",{className:"rfs-shell rfs:border-border rfs:bg-card",children:jsxs("div",{style:{minWidth:te},children:[jsx(Xe,{resources:e,renderResourceHeader:d}),jsxs("div",{className:"rfs-body",children:[jsx(_e,{dayMinutes:D,dayStartAbs:Y,gridHeight:X}),jsx("div",{className:"rfs-grid",children:e.map(_=>jsx(Ue,{resource:_,colRefs:re,gridHeight:X,dayMinutes:D,appointments:ut.get(_.id)??[],appointmentAppearance:ne.get(_.id),appointmentBg:oe.get(_.id),isDropInvalid:p,renderAppointment:s,onApptPointerDown:h,onResizePointerDown:K,drag:S.kind==="resize"&&S.resourceId===_.id?S:Ht,suppressClickRef:he},String(_.id)))})]})]})}),k?jsx("div",{className:"rfs-drag-overlay",style:{left:k.left,top:k.top,width:k.width,height:k.height},children:(s??q)({appointment:k.appointment,isDropInvalid:p,onPointerDown:()=>{},onResizePointerDown:()=>{},appointmentAppearance:k.appearance,appointmentBackgroundColor:k.background,drag:S,suppressClickRef:he})}):null]})}var dt=(e,t)=>typeof t=="function"?t(e):e[t],Xt=e=>"id"in e,Ft=e=>({resourceId:e.resourceId??e.next.resourceId,start:e.start??e.next.start,end:e.end??e.next.end}),Vt=(e,t,r)=>{let o=Ft(t);return e.map(n=>{if(Xt(r)){if(dt(n,r.id)!==dt(t.appointment,r.id))return n;let d=r.dateValue??(s=>s);return {...n,[r.resourceId]:o.resourceId,[r.start]:d(o.start),[r.end]:d(o.end)}}if(r.getId(n)!==r.getId(t.appointment))return n;let i=r.setResourceId(n,o.resourceId),u=r.setStart(i,o.start);return r.setEnd(u,o.end)})};export{Yt as Scheduler,Vt as applySchedulerAppointmentChange,de as resolveSchedulerAppointmentAdapter};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marco.colia/react-fast-scheduler",
3
- "version": "3.1.0",
3
+ "version": "3.2.0",
4
4
  "description": "A lightweight React scheduling library.",
5
5
  "keywords": [
6
6
  "react",