@marco.colia/react-fast-scheduler 3.1.0 → 4.0.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
 
@@ -35,6 +35,45 @@ When you pass your own class strings through props like `resourceAppointmentClas
35
35
 
36
36
  ## Quick Start
37
37
 
38
+ If your appointments already use the field names `id`, `resourceId`, `start`, `end`, and `title`, you do not need an adapter:
39
+
40
+ ```tsx
41
+ import { useState } from "react";
42
+ import { Scheduler, applySchedulerAppointmentChange } from "@marco.colia/react-fast-scheduler";
43
+ import "@marco.colia/react-fast-scheduler/styles.css";
44
+
45
+ const resources = [
46
+ { id: 1, label: "Alice" },
47
+ { id: 2, label: "Bob" },
48
+ ];
49
+
50
+ export const MinimalScheduler = () => {
51
+ const [selectedDate, setSelectedDate] = useState(() => new Date());
52
+ const [appointments, setAppointments] = useState([
53
+ { id: 1, resourceId: 1, title: "Haircut", start: "2026-03-27T09:00:00", end: "2026-03-27T10:00:00" },
54
+ ]);
55
+
56
+ return (
57
+ <Scheduler
58
+ resources={resources}
59
+ appointments={appointments}
60
+ selectedDate={selectedDate}
61
+ onSelectedDateChange={setSelectedDate}
62
+ onAppointmentChange={(change) =>
63
+ setAppointments((prev) =>
64
+ applySchedulerAppointmentChange(prev, change, {
65
+ dateValue: (date) => date.toISOString(),
66
+ })
67
+ )
68
+ }
69
+ onAppointmentClick={(appointment) => console.log("clicked", appointment)}
70
+ />
71
+ );
72
+ };
73
+ ```
74
+
75
+ ### Full example with a backend
76
+
38
77
  The scheduler is a controlled component:
39
78
 
40
79
  - your app owns `selectedDate`
@@ -48,7 +87,7 @@ import {
48
87
  Scheduler,
49
88
  applySchedulerAppointmentChange,
50
89
  type BaseSchedulerResource,
51
- type SchedulerAppointmentChangeArgs,
90
+ type SchedulerAppointmentChangeEvent,
52
91
  } from "@marco.colia/react-fast-scheduler";
53
92
  import "@marco.colia/react-fast-scheduler/styles.css";
54
93
 
@@ -103,13 +142,12 @@ export const SchedulerExample = () => {
103
142
  };
104
143
 
105
144
  const handleAppointmentChange = async (
106
- change: SchedulerAppointmentChangeArgs<Appointment, number>
145
+ change: SchedulerAppointmentChangeEvent<Appointment, number>
107
146
  ) => {
147
+ // `id`, `start`, and `end` use the default names, so only `resourceId` needs mapping.
108
148
  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() }),
149
+ resourceId: "staffId",
150
+ dateValue: (date) => date.toISOString(),
113
151
  });
114
152
 
115
153
  setAppointments(optimisticAppointments);
@@ -144,11 +182,8 @@ export const SchedulerExample = () => {
144
182
  selectedDate={selectedDate}
145
183
  onSelectedDateChange={setSelectedDate}
146
184
  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}`,
185
+ resourceId: "staffId",
186
+ title: (item) => `${item.customerName} - ${item.title}`,
152
187
  }}
153
188
  onAppointmentChange={handleAppointmentChange}
154
189
  dayStart="09:00"
@@ -210,7 +245,53 @@ Appointments stay in your own shape. The scheduler reads them through the `adapt
210
245
 
211
246
  ### `adapter`
212
247
 
213
- The adapter maps your appointment structure into scheduler fields:
248
+ The adapter tells the scheduler which appointment fields to read. Every field has a default:
249
+
250
+ | Field | Default | Expected value |
251
+ | ------------ | -------------- | ------------------- |
252
+ | `id` | `"id"` | `string \| number` |
253
+ | `resourceId` | `"resourceId"` | the resource `id` |
254
+ | `start` | `"start"` | `Date \| string` |
255
+ | `end` | `"end"` | `Date \| string` |
256
+ | `title` | `"title"` | `string` |
257
+
258
+ If your appointments already use those names, omit `adapter` entirely. Otherwise map only the fields that differ:
259
+
260
+ ```tsx
261
+ adapter={{ resourceId: "staffId" }}
262
+ ```
263
+
264
+ TypeScript checks this: `adapter` (or a single field) is only optional when your appointment type has a matching field under the default name. Otherwise you get a compile error instead of empty cards at runtime.
265
+
266
+ You can still map every field by key:
267
+
268
+ ```tsx
269
+ adapter={{
270
+ id: "id",
271
+ resourceId: "staffId",
272
+ start: "start",
273
+ end: "end",
274
+ title: "title",
275
+ }}
276
+ ```
277
+
278
+ Each field can also be a function when you need to derive a value:
279
+
280
+ ```tsx
281
+ adapter={{
282
+ id: "id",
283
+ resourceId: "staffId",
284
+ start: "start",
285
+ end: "end",
286
+ title: (item) => `${item.customerName} - ${item.title}`,
287
+ }}
288
+ ```
289
+
290
+ Start and end fields can resolve to either a `Date` or a date string.
291
+
292
+ Key-based adapters can be written inline: the scheduler compares the field values, not the object identity, so an inline `adapter={{ ... }}` does not trigger extra recalculations. If you use function fields, keep them stable (define them outside the component or with `useCallback`).
293
+
294
+ The older getter adapter is still supported:
214
295
 
215
296
  ```tsx
216
297
  adapter={{
@@ -222,8 +303,6 @@ adapter={{
222
303
  }}
223
304
  ```
224
305
 
225
- `getStart` and `getEnd` can return either a `Date` or a date string.
226
-
227
306
  ## Drag, Resize, and Persistence
228
307
 
229
308
  Use `onAppointmentChange` as the main integration point for move and resize operations.
@@ -231,6 +310,8 @@ Use `onAppointmentChange` as the main integration point for move and resize oper
231
310
  It receives:
232
311
 
233
312
  - `appointment`: the original raw appointment
313
+ - `resourceId`, `start`, and `end`: the new values after drop
314
+ - `previousResourceId`, `previousStart`, and `previousEnd`: the values before drag or resize
234
315
  - `previous`: the previous resource and time range
235
316
  - `next`: the new resource and time range after drop
236
317
  - `kind`: `"move"` or `"resize"`
@@ -240,12 +321,12 @@ Example:
240
321
  ```tsx
241
322
  <Scheduler
242
323
  // ...other props
243
- onAppointmentChange={async ({ appointment, next }) => {
324
+ onAppointmentChange={async ({ appointment, resourceId, start, end }) => {
244
325
  const nextAppointment = {
245
326
  ...appointment,
246
- staffId: next.resourceId,
247
- start: next.start.toISOString(),
248
- end: next.end.toISOString(),
327
+ staffId: resourceId,
328
+ start: start.toISOString(),
329
+ end: end.toISOString(),
249
330
  };
250
331
 
251
332
  await fetch(`/api/appointments/${appointment.id}`, {
@@ -257,17 +338,25 @@ Example:
257
338
  />
258
339
  ```
259
340
 
260
- If you want a small helper for optimistic local state updates, use `applySchedulerAppointmentChange`:
341
+ If you want a small helper for optimistic local state updates, use `applySchedulerAppointmentChange`. Like the adapter, it defaults to the `id`, `resourceId`, `start`, and `end` fields, so you only map what differs:
261
342
 
262
343
  ```tsx
344
+ // Appointments with the default field names, stored as Date objects
345
+ const nextAppointments = applySchedulerAppointmentChange(appointments, change);
346
+
347
+ // Different resource field, dates stored as ISO strings
263
348
  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() }),
349
+ resourceId: "staffId",
350
+ dateValue: (date) => date.toISOString(),
268
351
  });
269
352
  ```
270
353
 
354
+ Without `dateValue`, `start` and `end` are written as `Date` objects. Pass `dateValue` when your data stores dates as strings.
355
+
356
+ Drops that would overlap another appointment on the same resource are rejected: the card is shown in red while dragging and `onAppointmentChange` is not called.
357
+
358
+ The previous setter-based helper options are still supported for non-object data or custom immutable updates.
359
+
271
360
  `onPersistMoveResize` is still available as a legacy callback, but `onAppointmentChange` is the recommended API.
272
361
 
273
362
  If you want to render the scheduler in read-only mode, use `editable={false}`:
@@ -281,6 +370,95 @@ If you want to render the scheduler in read-only mode, use `editable={false}`:
281
370
 
282
371
  When `editable` is `false`, move and resize interactions are disabled.
283
372
 
373
+ ## Clicking Appointments
374
+
375
+ Use `onAppointmentClick` to open a detail view or an edit form:
376
+
377
+ ```tsx
378
+ <Scheduler
379
+ // ...other props
380
+ onAppointmentClick={(appointment, event) => {
381
+ setSelectedAppointment(appointment);
382
+ }}
383
+ />
384
+ ```
385
+
386
+ It receives your original appointment object and the click event. It is not called at the end of a drag or resize, and it works with both the built-in card and a custom `renderAppointment`. It also works when `editable` is `false`.
387
+
388
+ ## Views
389
+
390
+ Besides the default resource grid (`"day"`), the scheduler has an `"agenda"` view: a compact table of the selected day with one row every 15 minutes and one column per resource. The times stay visible in a sidebar on the left while you scroll horizontally, and each cell lists the appointments that start in that 15-minute slot, ordered by start time.
391
+
392
+ Unlike the grid, cards are not sized by duration: each row grows to fit its appointments, so overlapping or short appointments stay readable.
393
+
394
+ Enable it with `views`. When more than one view is listed, the built-in toolbar shows a view switcher:
395
+
396
+ ```tsx
397
+ <Scheduler
398
+ // ...other props
399
+ views={["day", "agenda"]}
400
+ />
401
+ ```
402
+
403
+ Without `views`, only the grid is available and no switcher is shown, exactly as before.
404
+
405
+ The agenda uses the same data as the grid, so your data loading does not change: the toolbar still moves one day at a time and calls `onSelectedDateChange`.
406
+
407
+ In the agenda:
408
+
409
+ - column headers use the same `renderResourceHeader` as the grid
410
+ - rows cover every 15-minute slot from `dayStart` to `dayEnd`, extended if an appointment starts outside that range
411
+ - rows use the same colors as the grid cards (see [Styling](#styling))
412
+ - `onAppointmentClick` works on each row
413
+ - move and resize are not available
414
+ - appointments whose `resourceId` does not match a resource are not shown, like in the grid
415
+ - when the whole day has no appointments, `agendaEmptyState` is shown instead of the columns
416
+
417
+ ### Controlling the view
418
+
419
+ By default the scheduler keeps the current view in its own state. Use `defaultView` to choose the initial view, or `view` + `onViewChange` to control it from your app (for example to save it in the URL):
420
+
421
+ ```tsx
422
+ const [view, setView] = useState<SchedulerView>("agenda");
423
+
424
+ <Scheduler
425
+ // ...other props
426
+ views={["day", "agenda"]}
427
+ view={view}
428
+ onViewChange={setView}
429
+ />
430
+ ```
431
+
432
+ ### Labels and empty state
433
+
434
+ ```tsx
435
+ <Scheduler
436
+ // ...other props
437
+ views={["day", "agenda"]}
438
+ viewLabels={{ day: "Giorno", agenda: "Agenda" }}
439
+ agendaEmptyState="Nessun appuntamento"
440
+ />
441
+ ```
442
+
443
+ ### Custom agenda rows
444
+
445
+ Use `renderAgendaItem` to replace the content of each agenda row. It receives the normalized `appointment` (with `title`, `start`, `end`, and your original object in `raw`), the `resource` of its column, and the resolved `appointmentAppearance`:
446
+
447
+ ```tsx
448
+ <Scheduler
449
+ // ...other props
450
+ views={["day", "agenda"]}
451
+ renderAgendaItem={({ appointment, appointmentAppearance }) => (
452
+ <div className={`flex gap-3 rounded-md p-2 ${appointmentAppearance?.className ?? ""}`}>
453
+ <span>{appointment.start.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}</span>
454
+ <strong>{appointment.title}</strong>
455
+ </div>
456
+ )}
457
+ />
458
+ ```
459
+
460
+ With a custom row, `onAppointmentClick` is still called when the row is clicked. If the row should be reachable by keyboard, render a `<button>` inside it.
461
+
284
462
  ## Styling
285
463
 
286
464
  The package ships precompiled CSS:
@@ -332,8 +510,25 @@ If you want semantic mapping, use `getResourceAppointmentColorToken` plus `appoi
332
510
  />
333
511
  ```
334
512
 
513
+ Built-in tokens (`slate`, `gray`, `zinc`, `neutral`, `stone`, `red`, `orange`, `amber`, `yellow`, `lime`, `green`, `emerald`, `teal`, `cyan`, `sky`, `blue`, `indigo`, `violet`, `purple`, `fuchsia`, `pink`, `rose`) ship with the packaged stylesheet, so they work without Tailwind in your app:
514
+
515
+ ```tsx
516
+ <Scheduler
517
+ // ...other props
518
+ getResourceAppointmentColorToken={(resource) => (resource.id === 1 ? "blue" : "rose")}
519
+ />
520
+ ```
521
+
335
522
  For full control, use `getResourceAppointmentAppearance`.
336
523
 
524
+ When a resource matches more than one option, the first match wins:
525
+
526
+ 1. `resourceAppointmentClassMap`
527
+ 2. `getResourceAppointmentAppearance`
528
+ 3. `getResourceAppointmentColorToken` (+ `appointmentColorTokenClassMap`)
529
+ 4. `getResourceAppointmentBackground` (legacy)
530
+ 5. the built-in neutral background
531
+
337
532
  ## Custom Rendering
338
533
 
339
534
  ### Custom appointment card
@@ -349,7 +544,7 @@ The renderer also receives:
349
544
 
350
545
  - `isDropInvalid`: `true` when the current drag position overlaps another appointment
351
546
  - `onPointerDown`: attach this to your appointment root for move interactions
352
- - `onResizePointerDown`: attach this to your resize handle
547
+ - `onResizePointerDown`: attach this to your resize handle; it already stops propagation, so the move handler does not fire
353
548
 
354
549
  ```tsx
355
550
  <Scheduler
@@ -385,13 +580,7 @@ The renderer also receives:
385
580
  <div
386
581
  role="button"
387
582
  aria-label="Resize appointment"
388
- onPointerDown={(event) => {
389
- if (appointment.visualState === "ghost") {
390
- return;
391
- }
392
- event.stopPropagation();
393
- onResizePointerDown(event);
394
- }}
583
+ onPointerDown={onResizePointerDown}
395
584
  className="absolute inset-x-1 bottom-1 h-2 cursor-ns-resize rounded-full bg-slate-300/90 hover:bg-slate-400"
396
585
  />
397
586
  </div>
@@ -428,6 +617,8 @@ Use `renderToolbar` when you want to replace the whole header:
428
617
  />
429
618
  ```
430
619
 
620
+ `renderToolbar` also receives `view`, `views`, `onViewChange`, and `defaultViewSwitcher` (the built-in switcher, or `null` when fewer than two views are enabled). Render `{defaultViewSwitcher}` in your toolbar to keep the view switch, or build your own with `views` and `onViewChange`.
621
+
431
622
  ### Custom date picker slot
432
623
 
433
624
  If you want to keep the default toolbar but swap the date picker UI, use `renderDatePicker`.
@@ -451,11 +642,12 @@ If you want to keep the default toolbar but swap the date picker UI, use `render
451
642
  - `appointments`: array of raw appointment objects
452
643
  - `selectedDate`: currently visible day
453
644
  - `onSelectedDateChange`: controlled date change handler
454
- - `adapter`: mapper between your appointment shape and scheduler fields
645
+ - `adapter`: key-based or getter-based mapper between your appointment shape and scheduler fields; optional when your appointments use the default field names (see [`adapter`](#adapter))
455
646
 
456
647
  ### Common optional props
457
648
 
458
- - `onAppointmentChange`: async or sync handler for move and resize persistence
649
+ - `onAppointmentChange`: async or sync handler for move and resize persistence; receives both flat next values and the nested `previous`/`next` objects
650
+ - `onAppointmentClick`: called with the raw appointment and the click event on a plain click (not after a drag or resize)
459
651
  - `editable`: enables or disables move and resize interactions, defaults to `true`
460
652
  - `renderToolbar`: replace the full toolbar
461
653
  - `renderDatePicker`: replace only the date picker slot used by the default toolbar
@@ -470,12 +662,20 @@ If you want to keep the default toolbar but swap the date picker UI, use `render
470
662
  - `nextButtonLabel`: custom next button label
471
663
  - `dayStart`: visible schedule start time, for example `"09:00"`
472
664
  - `dayEnd`: visible schedule end time, for example `"18:00"`
665
+ - `views`: views offered by the switcher, for example `["day", "agenda"]`; defaults to `["day"]` (no switcher)
666
+ - `view`: controlled current view (`"day"` or `"agenda"`)
667
+ - `defaultView`: initial view when `view` is not controlled; defaults to the first entry of `views`
668
+ - `onViewChange`: called when the user picks a view in the switcher
669
+ - `viewLabels`: switcher labels, for example `{ day: "Giorno", agenda: "Agenda" }`
670
+ - `renderAgendaItem`: custom agenda row content
671
+ - `agendaEmptyState`: content shown in the agenda when the day has no appointments, defaults to `"No appointments"`
473
672
 
474
673
  ## Production Notes
475
674
 
476
675
  - Keep `selectedDate` in application state and fetch data when it changes.
477
676
  - 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
677
  - If persistence fails after a drag or resize, either roll back local state or refetch the visible day.
678
+ - For large schedules, keep `resources`, `appointments`, adapter function fields, and render/click callbacks stable when their data has not changed so React can reuse scheduler calculations. Key-based adapters can stay inline.
479
679
  - Import the package CSS once at app startup.
480
680
 
481
681
  ## 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'),I=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 I__namespace=/*#__PURE__*/_interopNamespace(I);var Et=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})]})},Ne=Et;function ge({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 a=e.raw,d=typeof a.description=="string"?a.description:void 0,s=typeof i=="string"?i:void 0,c=n?.className??s??"rfs:bg-muted/40 rfs:dark:bg-muted/30",R=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",g=`rfs:relative rfs:h-full rfs:overflow-hidden rfs:rounded-md rfs:p-2 rfs:pb-5 rfs:text-foreground ${c} ${R} ${f}`;return jsxRuntime.jsxs("div",{onPointerDown:r,className:g,children:[jsxRuntime.jsx(Ne,{isDropInvalid:t,title:e.title,description:d}),jsxRuntime.jsx(ge,{onResizePointerDown:o,appointment:e})]})}var Ft={id:"id",resourceId:"resourceId",start:"start",end:"end",title:"title"},W=(e,t)=>typeof t=="function"?t(e):e[t],Te=e=>e&&"getId"in e?{id:e.getId,resourceId:e.getResourceId,start:e.getStart,end:e.getEnd,title:e.getTitle}:{...Ft,...e},Se=e=>{if(e&&"getId"in e)return e;let t=Te(e);return {getEnd:r=>W(r,t.end),getId:r=>W(r,t.id),getResourceId:r=>W(r,t.resourceId),getStart:r=>W(r,t.start),getTitle:r=>W(r,t.title)}};function Be(e){if(!e||typeof e!="object")return false;let t=e;return typeof t.firstName=="string"||typeof t.lastName=="string"}var Oe={slate:"rfs:bg-slate-100 rfs:dark:bg-slate-900/40",gray:"rfs:bg-gray-100 rfs:dark:bg-gray-900/40",zinc:"rfs:bg-zinc-100 rfs:dark:bg-zinc-900/40",neutral:"rfs:bg-neutral-100 rfs:dark:bg-neutral-900/40",stone:"rfs:bg-stone-100 rfs:dark:bg-stone-900/40",red:"rfs:bg-red-100 rfs:dark:bg-red-950/40",orange:"rfs:bg-orange-100 rfs:dark:bg-orange-950/40",amber:"rfs:bg-amber-100 rfs:dark:bg-amber-950/40",yellow:"rfs:bg-yellow-100 rfs:dark:bg-yellow-950/40",lime:"rfs:bg-lime-100 rfs:dark:bg-lime-950/40",green:"rfs:bg-green-100 rfs:dark:bg-green-950/40",emerald:"rfs:bg-emerald-100 rfs:dark:bg-emerald-950/40",teal:"rfs:bg-teal-100 rfs:dark:bg-teal-950/40",cyan:"rfs:bg-cyan-100 rfs:dark:bg-cyan-950/40",sky:"rfs:bg-sky-100 rfs:dark:bg-sky-950/40",blue:"rfs:bg-blue-100 rfs:dark:bg-blue-950/40",indigo:"rfs:bg-indigo-100 rfs:dark:bg-indigo-950/40",violet:"rfs:bg-violet-100 rfs:dark:bg-violet-950/40",purple:"rfs:bg-purple-100 rfs:dark:bg-purple-950/40",fuchsia:"rfs:bg-fuchsia-100 rfs:dark:bg-fuchsia-950/40",pink:"rfs:bg-pink-100 rfs:dark:bg-pink-950/40",rose:"rfs:bg-rose-100 rfs:dark:bg-rose-950/40"};function L(e,t,r){return Math.max(t,Math.min(r,e))}function K(e,t=15){return Math.round(e/t)*t}function Ae(e){let[t,r]=e.split(":").map(Number);return t*60+r}function Le(e){return `${e.firstName??""} ${e.lastName??""}`.trim()}function Z(e){return dateFns.format(e,"yyyy-MM-dd")}function Ie(e,t){return new Date(e.getFullYear(),e.getMonth(),e.getDate()+t)}function $(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),a=n%60;return o.setHours(i,a,0,0),o}function be(e,t){return t.getHours()*60+t.getMinutes()-e}function ye(e,t){return e.startMin<t.endMin&&t.startMin<e.endMin}function _e(e){let t=[...e].sort((a,d)=>a.startMin-d.startMin||a.endMin-d.endMin),r=[],o=[],n=[];for(let a of t)o=o.filter(s=>s.endMin>a.startMin),!o.some(s=>ye(s,a))&&n.length>0&&(r.push(n),n=[]),n.push(a),o.push(a);n.length&&r.push(n);let i=[];for(let a of r){let d=[...a].sort((f,g)=>f.startMin-g.startMin||f.endMin-g.endMin),s=[],c=new Map;for(let f of d){let g=false;for(let p=0;p<s.length;p++)if(s[p]<=f.startMin){s[p]=f.endMin,c.set(f.id,p),g=true;break}g||(s.push(f.endMin),c.set(f.id,s.length-1));}let R=s.length;for(let f of d)i.push({...f,lane:c.get(f.id)??0,lanes:R});}return i}function Me({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 Fe({adapter:e,appointments:t,dayMinutes:r,dayStartAbs:o,selectedISO:n}){return t.map(i=>{let a=e.getId(i),d=new Date(e.getStart(i)),s=new Date(e.getEnd(i));return {raw:i,id:a,resourceId:e.getResourceId(i),start:d,end:s,startMin:L(be(o,d),0,r),endMin:L(be(o,s),0,r),title:e.getTitle(i),renderKey:String(a),visualState:"normal"}}).filter(i=>Z(i.start)===n)}function Ve(e){return new Map(e.map(t=>[t.id,t]))}function He(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:$(r,o,t.startMin),end:$(r,o,t.endMin),visualState:"dragging"})}function ze(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,ve(r.get(n.id)??[]));return o}function ve(e){return _e(e.map(t=>({...t,appointmentId:t.id,id:t.renderKey}))).map(({appointmentId:t,...r})=>({...r,id:t}))}function Ye(e,t,r,o,n){let i=new Map;for(let a of e){let d=t?.[String(a.id)];if(d){i.set(a.id,{className:d});continue}let s=r?.(a);if(s){i.set(a.id,s);continue}let c=o.get(a.id);if(c){i.set(a.id,{className:c});continue}let R=n.get(a.id);i.set(a.id,R?{className:R}:void 0);}return i}function Xe({adapter:e,appointments:t,dayEnd:r="18:00",dayStart:o="09:00",resources:n,selectedDate:i}){let a=I__namespace.useMemo(()=>Ae(o),[o]),d=I__namespace.useMemo(()=>Ae(r),[r]),s=I__namespace.useMemo(()=>Math.max(0,d-a),[d,a]),c=I__namespace.useMemo(()=>12+s*2+24,[s]),R=I__namespace.useMemo(()=>72+Math.max(n.length,1)*420,[n.length]),{id:f,resourceId:g,start:p,end:l,title:h}=Te(e),T=I__namespace.useMemo(()=>Se({id:f,resourceId:g,start:p,end:l,title:h}),[f,g,p,l,h]),b=I__namespace.useMemo(()=>Z(i),[i]),S=I__namespace.useMemo(()=>Fe({adapter:T,appointments:t,dayMinutes:s,dayStartAbs:a,selectedISO:b}),[t,s,a,T,b]);return {appointmentMap:I__namespace.useMemo(()=>Ve(S),[S]),dayEndAbs:d,dayMinutes:s,dayStartAbs:a,gridHeight:c,gridMinWidth:R,renderAppts:S}}var Ht=4,zt=(e,t)=>{e(r=>r&&{...r,clientX:t.clientX,clientY:t.clientY});},Yt=e=>{let{dragRef:t,pendingDragRef:r,pointer:o,setDrag:n,setMovePreview:i,suppressClickRef:a}=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)<Ht||(a.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);},Xt=(e,t,r,o,n)=>{let i=o(t.clientX,e.resourceId),d=n(i,t.clientY)-e.offsetMin,s=L(K(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}},Ut=(e,t,r,o)=>{let n=o(e.resourceId,t.clientY),i=L(K(n),e.startMin+15,r);return i===e.endMin?null:{...e,endMin:i}},$e=e=>{let{dayMinutes:t,dragRef:r,latestPointerRef:o,pendingDragRef:n,pointerToMin:i,pointerToResourceId:a,setDrag:d,setMovePreview:s,suppressClickRef:c}=e,R=o.current;if(!R)return;let f=r.current;if(f.kind==="none"&&n.current){Yt({pointer:R,pendingDragRef:n,setDrag:d,setMovePreview:s,dragRef:r,suppressClickRef:c});return}if(f.kind==="none")return;if(f.kind==="move"){zt(s,R);let p=Xt(f,R,t,a,i);p&&(c.current=true,r.current=p,d(p));return}let g=Ut(f,R,t,i);g&&(c.current=true,r.current=g,d(g));},We=e=>{let{dragRef:t,frameRef:r,latestPointerRef:o,pendingDragRef:n,persistDrag:i,setDrag:a,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"&&(a({kind:"none"}),t.current={kind:"none"},s.current&&i(c));};var Ke=({appointmentMap:e,dayMinutes:t,dayStartAbs:r,onAppointmentChange:o,onPersistMoveResize:n,renderAppts:i,resources:a,selectedDate:d,editable:s})=>{let[c,R]=I__namespace.useState({kind:"none"}),[f,g]=I__namespace.useState(null),p=I__namespace.useRef({}),l=I__namespace.useRef(false),h=I__namespace.useRef({kind:"none"}),T=I__namespace.useRef(null),b=I__namespace.useRef(null),S=I__namespace.useRef(null),X=I__namespace.useMemo(()=>{let u=new Map;for(let m of i){let A=u.get(m.resourceId)??[];A.push(m),u.set(m.resourceId,A);}return u},[i]);I__namespace.useEffect(()=>{h.current=c;},[c]),I__namespace.useEffect(()=>()=>{S.current!==null&&window.cancelAnimationFrame(S.current);},[]);let y=I__namespace.useCallback((u,m)=>{let A=p.current[String(u)];if(!A)return 0;let C=m-A.getBoundingClientRect().top-12;return L(K(C/2),0,t)},[t]),k=I__namespace.useCallback((u,m)=>{for(let A of a){let C=p.current[String(A.id)];if(!C)continue;let F=C.getBoundingClientRect();if(u>=F.left&&u<=F.right)return A.id}return m},[a]),w=I__namespace.useCallback((u,m,A,C)=>(X.get(m)??[]).some(V=>V.id!==u&&ye(V,{startMin:A,endMin:C})),[X]),ce=I__namespace.useMemo(()=>c.kind==="none"?false:w(c.appointmentId,c.resourceId,c.startMin,c.endMin),[c,w]),q=I__namespace.useCallback(async u=>{let m=e.get(u.appointmentId);if(!m||w(u.appointmentId,u.resourceId,u.startMin,u.endMin))return;let A={resourceId:u.resourceId,start:$(d,r,u.startMin),end:$(d,r,u.endMin)};if(o){await o({kind:u.kind,appointment:m.raw,resourceId:A.resourceId,start:A.start,end:A.end,previousResourceId:m.resourceId,previousStart:m.start,previousEnd:m.end,previous:{resourceId:m.resourceId,start:m.start,end:m.end},next:A});return}n&&await n({appointment:m.raw,resourceId:A.resourceId,start:A.start,end:A.end});},[e,r,w,o,n,d]),ue=I__namespace.useCallback((u,m)=>{if(l.current=false,!s||u.button!==0)return;u.stopPropagation();let A=u.currentTarget.getBoundingClientRect(),C=y(m.resourceId,u.clientY);T.current={drag:{kind:"move",appointmentId:m.id,pointerId:u.pointerId,resourceId:m.resourceId,durationMin:Math.max(15,m.endMin-m.startMin),offsetMin:C-m.startMin,startMin:m.startMin,endMin:m.endMin},appointment:m,startClientX:u.clientX,startClientY:u.clientY,width:A.width,height:A.height,offsetX:u.clientX-A.left,offsetY:u.clientY-A.top};},[y,s]),pe=I__namespace.useCallback((u,m)=>{l.current=false,s&&u.button===0&&(u.stopPropagation(),T.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]),le=I__namespace.useCallback(u=>{b.current={clientX:u.clientX,clientY:u.clientY,pointerId:u.pointerId},S.current===null&&(S.current=window.requestAnimationFrame(()=>{S.current=null,$e({dayMinutes:t,dragRef:h,latestPointerRef:b,pendingDragRef:T,pointerToMin:y,pointerToResourceId:k,setDrag:R,setMovePreview:g,suppressClickRef:l});}));},[t,y,k]),fe=I__namespace.useCallback(()=>{We({dragRef:h,frameRef:S,latestPointerRef:b,pendingDragRef:T,persistDrag:q,setDrag:R,setMovePreview:g,suppressClickRef:l});},[q]);return {colRefs:p,drag:c,isDropInvalid:ce,movePreview:f,onApptPointerDown:ue,onGlobalPointerMove:le,onGlobalPointerUp:fe,onResizePointerDown:pe,suppressClickRef:l}};function Ge({appointmentColorTokenClassMap:e,dayStartAbs:t,drag:r,getResourceAppointmentAppearance:o,getResourceAppointmentBackground:n,getResourceAppointmentColorToken:i,renderAppts:a,resourceAppointmentClassMap:d,resources:s,selectedDate:c}){let R=I__namespace.useMemo(()=>He(a,r,c,t),[t,r,a,c]),f=I__namespace.useMemo(()=>ze(s,a),[a,s]),g=I__namespace.useMemo(()=>{if(r.kind!=="resize")return f;let T=new Map(f),b=R.filter(S=>S.resourceId===r.resourceId);return T.set(r.resourceId,ve(b)),T},[f,r,R]),p=I__namespace.useMemo(()=>n?Me({fallback:void 0,getValue:n,resources:s,toKey:T=>T.id}):new Map,[n,s]),l=I__namespace.useMemo(()=>{if(!i)return new Map;let T={...Oe,...e??{}};return Me({fallback:void 0,getValue:b=>{let S=i(b);return S?T[S]:void 0},resources:s,toKey:b=>b.id})},[e,i,s]);return {appointmentAppearanceByResource:I__namespace.useMemo(()=>Ye(s,d,o,l,p),[p,l,o,d,s]),appointmentBgByResource:p,effectiveAppts:R,laidOutByResource:g}}function qe({views:e,view:t,defaultView:r,onViewChange:o}){let[n,i]=I__namespace.useState(()=>r??(e.length>0?e[0]:"day")),a=I__namespace.useCallback(d=>{t===void 0&&i(d),o?.(d);},[t,o]);return [t??n,a]}function B(...e){return e.filter(Boolean).join(" ")}function Je({resource:e}){return jsxRuntime.jsx("strong",{children:e.label})}function re({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=>Je({resource:o})))(r),Be(r)?jsxRuntime.jsx("div",{className:"rfs-resource-subtitle rfs:text-muted-foreground",children:Le(r)}):null]},String(r.id)))]})}var je=e=>dateFns.format(e,"HH:mm"),et=e=>String(e).padStart(2,"0"),Kt=e=>`${et(Math.floor(e/60))}:${et(e%60)}`,tt=e=>Math.floor((e.getHours()*60+e.getMinutes())/15)*15,rt=(e,t)=>`${e}|${String(t)}`;function nt({appointment:e}){let t=e.raw,r=typeof t.description=="string"?t.description:void 0;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("span",{className:"rfs:block rfs:text-xs rfs:font-medium rfs:tabular-nums",children:[je(e.start),"\u2013",je(e.end)]}),jsxRuntime.jsx("span",{className:"rfs:block rfs:text-xs rfs:font-semibold",children:e.title}),r&&jsxRuntime.jsx("span",{className:"rfs:block rfs:text-[10px] rfs:font-medium",children:r})]})}function st({appointments:e,resources:t,appointmentAppearanceByResource:r,dayStartAbs:o,dayEndAbs:n,onAppointmentClick:i,renderResourceHeader:a,renderAgendaItem:d,emptyState:s="No appointments"}){let{slots:c,cells:R}=I__namespace.useMemo(()=>{let p=new Set(t.map(y=>y.id)),l=e.filter(y=>p.has(y.resourceId)).sort((y,k)=>y.start.getTime()-k.start.getTime()),h=new Map;for(let y of l){let k=rt(tt(y.start),y.resourceId),w=h.get(k)??[];w.push(y),h.set(k,w);}let T=l.map(y=>tt(y.start)),b=Math.min(Math.floor(o/15)*15,...T),S=Math.max(Math.ceil(n/15)*15-15,...T);return {slots:Array.from({length:Math.max(0,(S-b)/15+1)},(y,k)=>b+k*15),cells:h}},[e,t,o,n]);if(!(R.size>0))return jsxRuntime.jsx("div",{className:"rfs-agenda rfs:rounded-lg rfs:border rfs:border-border rfs:bg-card rfs:p-6 rfs:text-center rfs:text-sm rfs:text-muted-foreground",children:s});let g=(p,l)=>{let h=r.get(l.id),T=i?S=>i(p.raw,S):void 0;if(d)return jsxRuntime.jsx("li",{onClick:T,children:d({appointment:p,resource:l,appointmentAppearance:h})},p.renderKey);let b=B("rfs:block rfs:w-full rfs:rounded-md rfs:px-3 rfs:py-2 rfs:text-left rfs:text-foreground",h?.className??"rfs:bg-muted/40 rfs:dark:bg-muted/30");return jsxRuntime.jsx("li",{children:T?jsxRuntime.jsx("button",{type:"button",className:B(b,"rfs:cursor-pointer"),onClick:T,children:jsxRuntime.jsx(nt,{appointment:p})}):jsxRuntime.jsx("div",{className:b,children:jsxRuntime.jsx(nt,{appointment:p})})},p.renderKey)};return jsxRuntime.jsx("div",{className:"rfs-agenda rfs-shell rfs:border-border rfs:bg-card",children:jsxRuntime.jsxs("div",{style:{minWidth:72+Math.max(t.length,1)*420},children:[jsxRuntime.jsx(re,{resources:t,renderResourceHeader:a}),c.map(p=>{let l=p%60===0,h=(p+15)%60===0?"var(--rfs-border)":"color-mix(in oklab, var(--rfs-border) 40%, transparent)";return jsxRuntime.jsxs("div",{className:"rfs:flex",children:[jsxRuntime.jsx("div",{className:B("rfs-gutter rfs:border-b rfs:px-2 rfs:py-1 rfs:text-xs rfs:tabular-nums",l?"rfs:text-foreground":"rfs:text-muted-foreground/70"),style:{width:72,borderBottomColor:h},children:Kt(p)}),t.map(T=>jsxRuntime.jsx("ul",{"aria-label":T.label,className:"rfs-col rfs:flex rfs:min-h-7 rfs:flex-col rfs:gap-1 rfs:border-b rfs:p-1",style:{minWidth:420,flex:1,borderBottomColor:h},children:(R.get(rt(p,T.id))??[]).map(b=>g(b,T))},String(T.id)))]},p)})]})})}function it({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}`))})}var dt=({resource:e,colRefs:t,gridHeight:r,dayMinutes:o,appointments:n,appointmentAppearance:i,appointmentBg:a,isDropInvalid:d,renderAppointment:s,onAppointmentClick:c,onApptPointerDown:R,onResizePointerDown:f,drag:g,suppressClickRef:p})=>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,h)=>jsxRuntime.jsx("div",{className:"rfs-hour-line rfs:border-border/70",style:{top:12+h*60*2}},`major-${h}`)),Array.from({length:Math.floor(o/15)+1}).map((l,h)=>jsxRuntime.jsx("div",{className:"rfs-slot-line rfs:border-border/50",style:{top:12+h*15*2}},`minor-${h}`)),n.map(l=>{let h=100/l.lanes,T=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:T,left:`${h*l.lane}%`,width:`${h}%`,height:b},onClick:c?S=>{p.current||c(l.raw,S);}:void 0,children:(s??Q)({appointment:l,isDropInvalid:d&&g.kind==="resize"&&l.id===g.appointmentId,onPointerDown:S=>R(S,l),onResizePointerDown:S=>f(S,l),appointmentAppearance:i,appointmentBackgroundColor:a,drag:g,suppressClickRef:p})},l.renderKey)})]})});var Zt=(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.onAppointmentClick===t.onAppointmentClick,e.onApptPointerDown===t.onApptPointerDown,e.onResizePointerDown===t.onResizePointerDown,e.drag===t.drag,e.suppressClickRef===t.suppressClickRef].every(Boolean),ct=I__namespace.memo(dt,Zt);var jt={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"},er={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"},D=I__namespace.forwardRef(function({className:t,variant:r="default",size:o="default",type:n="button",...i},a){return jsxRuntime.jsx("button",{ref:a,type:n,className:B("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",jt[r],er[o],t),...i})});function mt({selected:e,onSelect:t}){let[r,o]=I__namespace.useState(e??new Date);I__namespace.useEffect(()=>{e&&o(e);},[e]);let n=dateFns.startOfMonth(r),i=dateFns.startOfWeek(n,{weekStartsOn:1}),a=dateFns.endOfWeek(dateFns.endOfMonth(r),{weekStartsOn:1}),d=[];for(let s=i;s<=a;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(D,{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(D,{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(D,{variant:c?"default":"ghost",size:"icon",className:B("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 Rt=I__namespace.createContext(null);function ht(){let e=I__namespace.useContext(Rt);if(!e)throw new Error("Popover components must be used within Popover.");return e}function gt({children:e,open:t,onOpenChange:r}){let[o,n]=I__namespace.useState(false),i=I__namespace.useRef(null),a=I__namespace.useRef(null),d=t??o,s=I__namespace.useCallback(c=>{let R=typeof c=="function"?c(d):c;t===void 0&&n(R),r?.(R);},[t,r,d]);return I__namespace.useEffect(()=>{if(!d)return;let c=f=>{let g=f.target;i.current?.contains(g)||a.current?.contains(g)||s(false);},R=f=>{f.key==="Escape"&&s(false);};return document.addEventListener("mousedown",c),document.addEventListener("keydown",R),()=>{document.removeEventListener("mousedown",c),document.removeEventListener("keydown",R);}},[d,s]),jsxRuntime.jsx(Rt.Provider,{value:{open:d,setOpen:s,triggerRef:i,contentRef:a},children:jsxRuntime.jsx("div",{className:"rfs:relative rfs:inline-flex",children:e})})}function Tt({children:e,asChild:t=false}){let{open:r,setOpen:o,triggerRef:n}=ht();if(t&&I__namespace.isValidElement(e)){let i=e;return I__namespace.cloneElement(i,{ref:n,"aria-expanded":r,onClick:a=>{i.props.onClick?.(a),o(d=>!d);}})}return jsxRuntime.jsx("button",{ref:n,type:"button","aria-expanded":r,onClick:()=>o(i=>!i),children:e})}function St({children:e,className:t,align:r="start"}){let{open:o,contentRef:n}=ht();return o?jsxRuntime.jsx("div",{ref:n,className:B("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 At({selectedDate:e,onSelectedDateChange:t}){return jsxRuntime.jsxs(gt,{children:[jsxRuntime.jsx(Tt,{asChild:true,children:jsxRuntime.jsx(D,{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(St,{className:"rfs:w-auto rfs:p-2",align:"center",children:jsxRuntime.jsx(mt,{selected:e,onSelect:t})})]})}function bt({goToPreviousDay:e,goToNextDay:t,defaultDatePicker:r,defaultViewSwitcher:o,prevButtonLabel:n="Prev",nextButtonLabel:i="Next"}){return jsxRuntime.jsxs("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(D,{variant:"outline",size:"sm",onClick:e,children:n}),r,jsxRuntime.jsx(D,{variant:"outline",size:"sm",onClick:t,children:i})]}),o&&jsxRuntime.jsx("div",{className:"rfs:ml-auto",children:o})]})}var lr={day:"Day",agenda:"Agenda"};function Mt({selectedDate:e,onSelectedDateChange:t,prevButtonLabel:r,nextButtonLabel:o,renderToolbar:n,renderDatePicker:i,view:a,views:d,onViewChange:s,viewLabels:c}){let R=()=>t(Ie(e,-1)),f=()=>t(Ie(e,1)),g=(i??At)({selectedDate:e,onSelectedDateChange:t}),p=d.length>1?jsxRuntime.jsx("div",{role:"group","aria-label":"View",className:"rfs:flex rfs:items-center rfs:gap-1 rfs:rounded-lg rfs:border rfs:border-border rfs:bg-card rfs:p-1 rfs:shadow-xs",children:d.map(h=>jsxRuntime.jsx(D,{variant:h===a?"default":"ghost",size:"sm","aria-pressed":h===a,onClick:()=>s(h),children:c?.[h]??lr[h]},h))}):null,l={selectedDate:e,onSelectedDateChange:t,goToPreviousDay:R,goToNextDay:f,defaultDatePicker:g,view:a,views:d,onViewChange:s,defaultViewSwitcher:p};return n?jsxRuntime.jsx(jsxRuntime.Fragment,{children:n(l)}):jsxRuntime.jsx(jsxRuntime.Fragment,{children:bt({...l,prevButtonLabel:r,nextButtonLabel:o})})}var fr={kind:"none"},mr=["day"];function Rr({resources:e,appointments:t,selectedDate:r,onSelectedDateChange:o,adapter:n,onPersistMoveResize:i,onAppointmentChange:a,onAppointmentClick:d,renderResourceHeader:s,renderAppointment:c,resourceAppointmentClassMap:R,getResourceAppointmentAppearance:f,getResourceAppointmentColorToken:g,appointmentColorTokenClassMap:p,getResourceAppointmentBackground:l,renderToolbar:h,renderDatePicker:T,prevButtonLabel:b="Prev",nextButtonLabel:S="Next",dayStart:X="09:00",dayEnd:y="18:00",editable:k=true,views:w=mr,view:ce,defaultView:q,onViewChange:ue,viewLabels:pe,renderAgendaItem:le,agendaEmptyState:fe}){let[u,m]=qe({views:w,view:ce,defaultView:q,onViewChange:ue}),{appointmentMap:A,dayEndAbs:C,dayMinutes:F,dayStartAbs:V,gridHeight:ke,gridMinWidth:Pt,renderAppts:me}=Xe({adapter:n,appointments:t,dayEnd:y,dayStart:X,resources:e,selectedDate:r}),{colRefs:kt,drag:v,isDropInvalid:De,movePreview:N,onApptPointerDown:Dt,onGlobalPointerMove:wt,onGlobalPointerUp:we,onResizePointerDown:Ct,suppressClickRef:Ce}=Ke({appointmentMap:A,dayMinutes:F,dayStartAbs:V,onAppointmentChange:a,onPersistMoveResize:i,renderAppts:me,resources:e,selectedDate:r,editable:k}),{appointmentAppearanceByResource:J,appointmentBgByResource:Re,laidOutByResource:Nt}=Ge({appointmentColorTokenClassMap:p,dayStartAbs:V,drag:v,getResourceAppointmentAppearance:f,getResourceAppointmentBackground:l,getResourceAppointmentColorToken:g,renderAppts:me,resourceAppointmentClassMap:R,resources:e,selectedDate:r}),O=I__namespace.useMemo(()=>v.kind!=="move"||!N?null:{appointment:{...N.appointment,resourceId:v.resourceId,startMin:v.startMin,endMin:v.endMin,visualState:"ghost",renderKey:`${N.appointment.renderKey}-overlay`,lane:0,lanes:1},appearance:J.get(v.resourceId),background:Re.get(v.resourceId),left:N.clientX-N.offsetX,top:N.clientY-N.offsetY,width:N.width,height:N.height},[J,Re,v,N]);return jsxRuntime.jsxs("section",{className:`rfs-root rfs:rounded-lg rfs:text-foreground ${v.kind==="move"?"rfs-root--drag-move":""} ${v.kind==="resize"?"rfs-root--drag-resize":""}`,onPointerMove:wt,onPointerUp:we,onPointerCancel:we,children:[jsxRuntime.jsx(Mt,{selectedDate:r,onSelectedDateChange:o,prevButtonLabel:b,nextButtonLabel:S,renderToolbar:h,renderDatePicker:T,view:u,views:w,onViewChange:m,viewLabels:pe}),u==="agenda"?jsxRuntime.jsx(st,{appointments:me,resources:e,appointmentAppearanceByResource:J,dayStartAbs:V,dayEndAbs:C,onAppointmentClick:d,renderResourceHeader:s,renderAgendaItem:le,emptyState:fe}):jsxRuntime.jsx("div",{className:"rfs-shell rfs:border-border rfs:bg-card",children:jsxRuntime.jsxs("div",{style:{minWidth:Pt},children:[jsxRuntime.jsx(re,{resources:e,renderResourceHeader:s}),jsxRuntime.jsxs("div",{className:"rfs-body",children:[jsxRuntime.jsx(it,{dayMinutes:F,dayStartAbs:V,gridHeight:ke}),jsxRuntime.jsx("div",{className:"rfs-grid",children:e.map(U=>jsxRuntime.jsx(ct,{resource:U,colRefs:kt,gridHeight:ke,dayMinutes:F,appointments:Nt.get(U.id)??[],appointmentAppearance:J.get(U.id),appointmentBg:Re.get(U.id),isDropInvalid:De,renderAppointment:c,onAppointmentClick:d,onApptPointerDown:Dt,onResizePointerDown:Ct,drag:v.kind==="resize"&&v.resourceId===U.id?v:fr,suppressClickRef:Ce},String(U.id)))})]})]})}),O?jsxRuntime.jsx("div",{className:"rfs-drag-overlay",style:{left:O.left,top:O.top,width:O.width,height:O.height},children:(c??Q)({appointment:O.appointment,isDropInvalid:De,onPointerDown:()=>{},onResizePointerDown:()=>{},appointmentAppearance:O.appearance,appointmentBackgroundColor:O.background,drag:v,suppressClickRef:Ce})}):null]})}var hr={id:"id",resourceId:"resourceId",start:"start",end:"end"},xt=(e,t)=>typeof t=="function"?t(e):e[t],gr=e=>!("getId"in e),Tr=e=>({resourceId:e.resourceId??e.next.resourceId,start:e.start??e.next.start,end:e.end??e.next.end}),Sr=(e,t,...[r={}])=>{let o=Tr(t);return e.map(n=>{if(gr(r)){let d={...hr,...r};if(xt(n,d.id)!==xt(t.appointment,d.id))return n;let s=r.dateValue??(c=>c);return {...n,[d.resourceId]:o.resourceId,[d.start]:s(o.start),[d.end]:s(o.end)}}if(r.getId(n)!==r.getId(t.appointment))return n;let i=r.setResourceId(n,o.resourceId),a=r.setStart(i,o.start);return r.setEnd(a,o.end)})};exports.Scheduler=Rr;exports.applySchedulerAppointmentChange=Sr;exports.resolveSchedulerAppointmentAdapter=Se;
package/dist/index.d.cts CHANGED
@@ -8,7 +8,33 @@ 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;
21
+ type SchedulerDefaultFieldValues<TResourceId extends SchedulerId> = {
22
+ id: SchedulerId;
23
+ resourceId: TResourceId;
24
+ start: Date | string;
25
+ end: Date | string;
26
+ title: string;
27
+ };
28
+ /** Adapter fields the appointment already exposes under the default name with a compatible type. */
29
+ type SchedulerDefaultedAppointmentField<TAppointment, TResourceId extends SchedulerId> = {
30
+ [K in keyof SchedulerDefaultFieldValues<TResourceId>]: K extends keyof TAppointment ? TAppointment[K] extends SchedulerDefaultFieldValues<TResourceId>[K] ? K : never : never;
31
+ }[keyof SchedulerDefaultFieldValues<TResourceId>];
32
+ /**
33
+ * Key-based adapter where fields matching the default names
34
+ * (`id`, `resourceId`, `start`, `end`, `title`) can be omitted.
35
+ */
36
+ type SchedulerAppointmentPartialFieldAdapter<TAppointment, TResourceId extends SchedulerId> = Omit<SchedulerAppointmentFieldAdapter<TAppointment, TResourceId>, SchedulerDefaultedAppointmentField<TAppointment, TResourceId>> & Partial<Pick<SchedulerAppointmentFieldAdapter<TAppointment, TResourceId>, SchedulerDefaultedAppointmentField<TAppointment, TResourceId>>>;
37
+ type SchedulerAppointmentAdapterOption<TAppointment, TResourceId extends SchedulerId> = SchedulerAppointmentAdapter<TAppointment, TResourceId> | SchedulerAppointmentPartialFieldAdapter<TAppointment, TResourceId>;
12
38
  type BaseSchedulerResource<TId extends SchedulerId = number> = {
13
39
  id: TId;
14
40
  label: string;
@@ -51,6 +77,12 @@ type RenderSchedulerAppt<TAppointment, TResourceId extends SchedulerId> = Schedu
51
77
  type SchedulerAppointmentChangeArgs<TAppointment, TResourceId extends SchedulerId> = {
52
78
  kind: "move" | "resize";
53
79
  appointment: TAppointment;
80
+ resourceId?: TResourceId;
81
+ start?: Date;
82
+ end?: Date;
83
+ previousResourceId?: TResourceId;
84
+ previousStart?: Date;
85
+ previousEnd?: Date;
54
86
  previous: {
55
87
  resourceId: TResourceId;
56
88
  start: Date;
@@ -62,31 +94,61 @@ type SchedulerAppointmentChangeArgs<TAppointment, TResourceId extends SchedulerI
62
94
  end: Date;
63
95
  };
64
96
  };
97
+ type SchedulerAppointmentChangeEvent<TAppointment, TResourceId extends SchedulerId> = SchedulerAppointmentChangeArgs<TAppointment, TResourceId> & {
98
+ resourceId: TResourceId;
99
+ start: Date;
100
+ end: Date;
101
+ previousResourceId: TResourceId;
102
+ previousStart: Date;
103
+ previousEnd: Date;
104
+ };
65
105
  type SchedulerAppointmentAppearance = {
66
106
  className?: string;
67
107
  };
68
108
  type SchedulerAppointmentColorToken = string;
69
109
  type SchedulerResourceClassMap = Partial<Record<string, string>>;
110
+ /** `"day"` is the resource grid; `"agenda"` is a time-ordered list of the selected day. */
111
+ type SchedulerView = "day" | "agenda";
112
+ type SchedulerAgendaItemRenderArgs<TAppointment, TResource extends BaseSchedulerResource<TResourceId>, TResourceId extends SchedulerId> = {
113
+ appointment: SchedulerEvent<TAppointment, TResourceId>;
114
+ resource: TResource;
115
+ appointmentAppearance?: SchedulerAppointmentAppearance;
116
+ };
70
117
  type SchedulerToolbarRenderArgs = {
71
118
  selectedDate: Date;
72
119
  onSelectedDateChange: (date: Date) => void;
73
120
  goToPreviousDay: () => void;
74
121
  goToNextDay: () => void;
75
122
  defaultDatePicker: React.ReactNode;
123
+ view: SchedulerView;
124
+ views: SchedulerView[];
125
+ onViewChange: (view: SchedulerView) => void;
126
+ /** Built-in view switcher, or `null` when fewer than two views are enabled. */
127
+ defaultViewSwitcher: React.ReactNode;
128
+ };
129
+ /** `adapter` is optional only when every field can fall back to its default name. */
130
+ type SchedulerAdapterProp<TAppointment, TResourceId extends SchedulerId> = [
131
+ Exclude<keyof SchedulerDefaultFieldValues<TResourceId>, SchedulerDefaultedAppointmentField<TAppointment, TResourceId>>
132
+ ] extends [never] ? {
133
+ adapter?: SchedulerAppointmentAdapterOption<TAppointment, TResourceId>;
134
+ } : {
135
+ adapter: SchedulerAppointmentAdapterOption<TAppointment, TResourceId>;
76
136
  };
77
- type SchedulerProps<TAppointment, TResource extends BaseSchedulerResource<TResourceId>, TResourceId extends SchedulerId> = {
137
+ type SchedulerProps<TAppointment, TResource extends BaseSchedulerResource<TResourceId>, TResourceId extends SchedulerId> = SchedulerCommonProps<TAppointment, TResource, TResourceId> & SchedulerAdapterProp<TAppointment, TResourceId>;
138
+ type SchedulerCommonProps<TAppointment, TResource extends BaseSchedulerResource<TResourceId>, TResourceId extends SchedulerId> = {
78
139
  resources: TResource[];
79
140
  appointments: TAppointment[];
80
141
  selectedDate: Date;
81
142
  onSelectedDateChange: (date: Date) => void;
82
- adapter: SchedulerAppointmentAdapter<TAppointment, TResourceId>;
143
+ /** Called on a plain click (not after a drag or resize). */
144
+ onAppointmentClick?: (appointment: TAppointment, event: React.MouseEvent<HTMLElement>) => void;
83
145
  onPersistMoveResize?: (args: {
84
146
  appointment: TAppointment;
85
147
  resourceId: TResourceId;
86
148
  start: Date;
87
149
  end: Date;
88
150
  }) => Promise<void> | void;
89
- onAppointmentChange?: (args: SchedulerAppointmentChangeArgs<TAppointment, TResourceId>) => Promise<void> | void;
151
+ onAppointmentChange?: (args: SchedulerAppointmentChangeEvent<TAppointment, TResourceId>) => Promise<void> | void;
90
152
  renderResourceHeader?: (resource: TResource) => React.ReactNode;
91
153
  renderAppointment?: (args: {
92
154
  appointment: SchedulerPresentationAppointment<TAppointment, TResourceId> & {
@@ -116,9 +178,22 @@ type SchedulerProps<TAppointment, TResource extends BaseSchedulerResource<TResou
116
178
  dayStart?: string;
117
179
  dayEnd?: string;
118
180
  editable?: boolean;
181
+ /** Views offered by the built-in switcher. Defaults to `["day"]` (no switcher). */
182
+ views?: SchedulerView[];
183
+ /** Controlled view. */
184
+ view?: SchedulerView;
185
+ /** Initial view when `view` is not controlled. Defaults to the first entry of `views`. */
186
+ defaultView?: SchedulerView;
187
+ onViewChange?: (view: SchedulerView) => void;
188
+ viewLabels?: Partial<Record<SchedulerView, React.ReactNode>>;
189
+ renderAgendaItem?: (args: SchedulerAgendaItemRenderArgs<TAppointment, TResource, TResourceId>) => React.ReactNode;
190
+ /** Shown in the agenda view when the selected day has no appointments. */
191
+ agendaEmptyState?: React.ReactNode;
119
192
  };
120
193
 
121
- 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;
194
+ declare function Scheduler<TAppointment, TResource extends BaseSchedulerResource<TResourceId>, TResourceId extends SchedulerId>({ resources, appointments, selectedDate, onSelectedDateChange, adapter, onPersistMoveResize, onAppointmentChange, onAppointmentClick, renderResourceHeader, renderAppointment, resourceAppointmentClassMap, getResourceAppointmentAppearance, getResourceAppointmentColorToken, appointmentColorTokenClassMap, getResourceAppointmentBackground, renderToolbar, renderDatePicker, prevButtonLabel, nextButtonLabel, dayStart, dayEnd, editable, views, view: controlledView, defaultView, onViewChange, viewLabels, renderAgendaItem, agendaEmptyState, }: SchedulerProps<TAppointment, TResource, TResourceId>): react_jsx_runtime.JSX.Element;
195
+
196
+ declare const resolveSchedulerAppointmentAdapter: <TAppointment, TResourceId extends string | number>(adapter?: SchedulerAppointmentAdapterInput<TAppointment, TResourceId> | SchedulerAppointmentAdapterOption<TAppointment, TResourceId>) => SchedulerAppointmentAdapter<TAppointment, TResourceId>;
122
197
 
123
198
  type ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId extends SchedulerId> = {
124
199
  getId: (appointment: TAppointment) => SchedulerId;
@@ -126,6 +201,23 @@ type ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId extends Sc
126
201
  setStart: (appointment: TAppointment, start: Date) => TAppointment;
127
202
  setEnd: (appointment: TAppointment, end: Date) => TAppointment;
128
203
  };
129
- declare function applySchedulerAppointmentChange<TAppointment, TResourceId extends SchedulerId>(appointments: TAppointment[], change: SchedulerAppointmentChangeArgs<TAppointment, TResourceId>, options: ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId>): TAppointment[];
204
+ type AppointmentKey<TAppointment> = Extract<keyof TAppointment, string | number>;
205
+ type ChangeFields<TAppointment> = {
206
+ id: SchedulerAppointmentField<TAppointment, SchedulerId>;
207
+ resourceId: AppointmentKey<TAppointment>;
208
+ start: AppointmentKey<TAppointment>;
209
+ end: AppointmentKey<TAppointment>;
210
+ };
211
+ /** Default field names the appointment actually has; those can be omitted from the options. */
212
+ type DefaultedChangeField<TAppointment> = Extract<keyof ChangeFields<TAppointment>, keyof TAppointment>;
213
+ /**
214
+ * Key-based options. `id`, `resourceId`, `start` and `end` default to the fields with the same name,
215
+ * so they are optional when the appointment has them.
216
+ */
217
+ type ApplySchedulerAppointmentChangeFieldOptions<TAppointment> = Omit<ChangeFields<TAppointment>, DefaultedChangeField<TAppointment>> & Partial<Pick<ChangeFields<TAppointment>, DefaultedChangeField<TAppointment>>> & {
218
+ dateValue?: (date: Date) => unknown;
219
+ };
220
+ type ApplySchedulerAppointmentChangeInput<TAppointment, TResourceId extends SchedulerId> = ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId> | ApplySchedulerAppointmentChangeFieldOptions<TAppointment>;
221
+ declare const applySchedulerAppointmentChange: <TAppointment, TResourceId extends SchedulerId>(appointments: TAppointment[], change: SchedulerAppointmentChangeArgs<TAppointment, TResourceId>, ...[options]: [Exclude<keyof ChangeFields<TAppointment>, DefaultedChangeField<TAppointment>>] extends [never] ? [options?: ApplySchedulerAppointmentChangeInput<TAppointment, TResourceId>] : [options: ApplySchedulerAppointmentChangeInput<TAppointment, TResourceId>]) => TAppointment[];
130
222
 
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 };
223
+ export { type ApplySchedulerAppointmentChangeFieldOptions, type ApplySchedulerAppointmentChangeInput, type ApplySchedulerAppointmentChangeOptions, type BaseSchedulerResource, type RenderSchedulerAppt, Scheduler, type SchedulerAdapterProp, type SchedulerAgendaItemRenderArgs, type SchedulerAppointmentAdapter, type SchedulerAppointmentAdapterInput, type SchedulerAppointmentAdapterOption, type SchedulerAppointmentAppearance, type SchedulerAppointmentChangeArgs, type SchedulerAppointmentChangeEvent, type SchedulerAppointmentColorToken, type SchedulerAppointmentField, type SchedulerAppointmentFieldAdapter, type SchedulerAppointmentPartialFieldAdapter, type SchedulerAppointmentVisualState, type SchedulerCommonProps, type SchedulerDefaultedAppointmentField, type SchedulerDragState, type SchedulerEvent, type SchedulerId, type SchedulerPresentationAppointment, type SchedulerProps, type SchedulerResourceClassMap, type SchedulerToolbarRenderArgs, type SchedulerView, applySchedulerAppointmentChange, resolveSchedulerAppointmentAdapter };
package/dist/index.d.ts CHANGED
@@ -8,7 +8,33 @@ 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;
21
+ type SchedulerDefaultFieldValues<TResourceId extends SchedulerId> = {
22
+ id: SchedulerId;
23
+ resourceId: TResourceId;
24
+ start: Date | string;
25
+ end: Date | string;
26
+ title: string;
27
+ };
28
+ /** Adapter fields the appointment already exposes under the default name with a compatible type. */
29
+ type SchedulerDefaultedAppointmentField<TAppointment, TResourceId extends SchedulerId> = {
30
+ [K in keyof SchedulerDefaultFieldValues<TResourceId>]: K extends keyof TAppointment ? TAppointment[K] extends SchedulerDefaultFieldValues<TResourceId>[K] ? K : never : never;
31
+ }[keyof SchedulerDefaultFieldValues<TResourceId>];
32
+ /**
33
+ * Key-based adapter where fields matching the default names
34
+ * (`id`, `resourceId`, `start`, `end`, `title`) can be omitted.
35
+ */
36
+ type SchedulerAppointmentPartialFieldAdapter<TAppointment, TResourceId extends SchedulerId> = Omit<SchedulerAppointmentFieldAdapter<TAppointment, TResourceId>, SchedulerDefaultedAppointmentField<TAppointment, TResourceId>> & Partial<Pick<SchedulerAppointmentFieldAdapter<TAppointment, TResourceId>, SchedulerDefaultedAppointmentField<TAppointment, TResourceId>>>;
37
+ type SchedulerAppointmentAdapterOption<TAppointment, TResourceId extends SchedulerId> = SchedulerAppointmentAdapter<TAppointment, TResourceId> | SchedulerAppointmentPartialFieldAdapter<TAppointment, TResourceId>;
12
38
  type BaseSchedulerResource<TId extends SchedulerId = number> = {
13
39
  id: TId;
14
40
  label: string;
@@ -51,6 +77,12 @@ type RenderSchedulerAppt<TAppointment, TResourceId extends SchedulerId> = Schedu
51
77
  type SchedulerAppointmentChangeArgs<TAppointment, TResourceId extends SchedulerId> = {
52
78
  kind: "move" | "resize";
53
79
  appointment: TAppointment;
80
+ resourceId?: TResourceId;
81
+ start?: Date;
82
+ end?: Date;
83
+ previousResourceId?: TResourceId;
84
+ previousStart?: Date;
85
+ previousEnd?: Date;
54
86
  previous: {
55
87
  resourceId: TResourceId;
56
88
  start: Date;
@@ -62,31 +94,61 @@ type SchedulerAppointmentChangeArgs<TAppointment, TResourceId extends SchedulerI
62
94
  end: Date;
63
95
  };
64
96
  };
97
+ type SchedulerAppointmentChangeEvent<TAppointment, TResourceId extends SchedulerId> = SchedulerAppointmentChangeArgs<TAppointment, TResourceId> & {
98
+ resourceId: TResourceId;
99
+ start: Date;
100
+ end: Date;
101
+ previousResourceId: TResourceId;
102
+ previousStart: Date;
103
+ previousEnd: Date;
104
+ };
65
105
  type SchedulerAppointmentAppearance = {
66
106
  className?: string;
67
107
  };
68
108
  type SchedulerAppointmentColorToken = string;
69
109
  type SchedulerResourceClassMap = Partial<Record<string, string>>;
110
+ /** `"day"` is the resource grid; `"agenda"` is a time-ordered list of the selected day. */
111
+ type SchedulerView = "day" | "agenda";
112
+ type SchedulerAgendaItemRenderArgs<TAppointment, TResource extends BaseSchedulerResource<TResourceId>, TResourceId extends SchedulerId> = {
113
+ appointment: SchedulerEvent<TAppointment, TResourceId>;
114
+ resource: TResource;
115
+ appointmentAppearance?: SchedulerAppointmentAppearance;
116
+ };
70
117
  type SchedulerToolbarRenderArgs = {
71
118
  selectedDate: Date;
72
119
  onSelectedDateChange: (date: Date) => void;
73
120
  goToPreviousDay: () => void;
74
121
  goToNextDay: () => void;
75
122
  defaultDatePicker: React.ReactNode;
123
+ view: SchedulerView;
124
+ views: SchedulerView[];
125
+ onViewChange: (view: SchedulerView) => void;
126
+ /** Built-in view switcher, or `null` when fewer than two views are enabled. */
127
+ defaultViewSwitcher: React.ReactNode;
128
+ };
129
+ /** `adapter` is optional only when every field can fall back to its default name. */
130
+ type SchedulerAdapterProp<TAppointment, TResourceId extends SchedulerId> = [
131
+ Exclude<keyof SchedulerDefaultFieldValues<TResourceId>, SchedulerDefaultedAppointmentField<TAppointment, TResourceId>>
132
+ ] extends [never] ? {
133
+ adapter?: SchedulerAppointmentAdapterOption<TAppointment, TResourceId>;
134
+ } : {
135
+ adapter: SchedulerAppointmentAdapterOption<TAppointment, TResourceId>;
76
136
  };
77
- type SchedulerProps<TAppointment, TResource extends BaseSchedulerResource<TResourceId>, TResourceId extends SchedulerId> = {
137
+ type SchedulerProps<TAppointment, TResource extends BaseSchedulerResource<TResourceId>, TResourceId extends SchedulerId> = SchedulerCommonProps<TAppointment, TResource, TResourceId> & SchedulerAdapterProp<TAppointment, TResourceId>;
138
+ type SchedulerCommonProps<TAppointment, TResource extends BaseSchedulerResource<TResourceId>, TResourceId extends SchedulerId> = {
78
139
  resources: TResource[];
79
140
  appointments: TAppointment[];
80
141
  selectedDate: Date;
81
142
  onSelectedDateChange: (date: Date) => void;
82
- adapter: SchedulerAppointmentAdapter<TAppointment, TResourceId>;
143
+ /** Called on a plain click (not after a drag or resize). */
144
+ onAppointmentClick?: (appointment: TAppointment, event: React.MouseEvent<HTMLElement>) => void;
83
145
  onPersistMoveResize?: (args: {
84
146
  appointment: TAppointment;
85
147
  resourceId: TResourceId;
86
148
  start: Date;
87
149
  end: Date;
88
150
  }) => Promise<void> | void;
89
- onAppointmentChange?: (args: SchedulerAppointmentChangeArgs<TAppointment, TResourceId>) => Promise<void> | void;
151
+ onAppointmentChange?: (args: SchedulerAppointmentChangeEvent<TAppointment, TResourceId>) => Promise<void> | void;
90
152
  renderResourceHeader?: (resource: TResource) => React.ReactNode;
91
153
  renderAppointment?: (args: {
92
154
  appointment: SchedulerPresentationAppointment<TAppointment, TResourceId> & {
@@ -116,9 +178,22 @@ type SchedulerProps<TAppointment, TResource extends BaseSchedulerResource<TResou
116
178
  dayStart?: string;
117
179
  dayEnd?: string;
118
180
  editable?: boolean;
181
+ /** Views offered by the built-in switcher. Defaults to `["day"]` (no switcher). */
182
+ views?: SchedulerView[];
183
+ /** Controlled view. */
184
+ view?: SchedulerView;
185
+ /** Initial view when `view` is not controlled. Defaults to the first entry of `views`. */
186
+ defaultView?: SchedulerView;
187
+ onViewChange?: (view: SchedulerView) => void;
188
+ viewLabels?: Partial<Record<SchedulerView, React.ReactNode>>;
189
+ renderAgendaItem?: (args: SchedulerAgendaItemRenderArgs<TAppointment, TResource, TResourceId>) => React.ReactNode;
190
+ /** Shown in the agenda view when the selected day has no appointments. */
191
+ agendaEmptyState?: React.ReactNode;
119
192
  };
120
193
 
121
- 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;
194
+ declare function Scheduler<TAppointment, TResource extends BaseSchedulerResource<TResourceId>, TResourceId extends SchedulerId>({ resources, appointments, selectedDate, onSelectedDateChange, adapter, onPersistMoveResize, onAppointmentChange, onAppointmentClick, renderResourceHeader, renderAppointment, resourceAppointmentClassMap, getResourceAppointmentAppearance, getResourceAppointmentColorToken, appointmentColorTokenClassMap, getResourceAppointmentBackground, renderToolbar, renderDatePicker, prevButtonLabel, nextButtonLabel, dayStart, dayEnd, editable, views, view: controlledView, defaultView, onViewChange, viewLabels, renderAgendaItem, agendaEmptyState, }: SchedulerProps<TAppointment, TResource, TResourceId>): react_jsx_runtime.JSX.Element;
195
+
196
+ declare const resolveSchedulerAppointmentAdapter: <TAppointment, TResourceId extends string | number>(adapter?: SchedulerAppointmentAdapterInput<TAppointment, TResourceId> | SchedulerAppointmentAdapterOption<TAppointment, TResourceId>) => SchedulerAppointmentAdapter<TAppointment, TResourceId>;
122
197
 
123
198
  type ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId extends SchedulerId> = {
124
199
  getId: (appointment: TAppointment) => SchedulerId;
@@ -126,6 +201,23 @@ type ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId extends Sc
126
201
  setStart: (appointment: TAppointment, start: Date) => TAppointment;
127
202
  setEnd: (appointment: TAppointment, end: Date) => TAppointment;
128
203
  };
129
- declare function applySchedulerAppointmentChange<TAppointment, TResourceId extends SchedulerId>(appointments: TAppointment[], change: SchedulerAppointmentChangeArgs<TAppointment, TResourceId>, options: ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId>): TAppointment[];
204
+ type AppointmentKey<TAppointment> = Extract<keyof TAppointment, string | number>;
205
+ type ChangeFields<TAppointment> = {
206
+ id: SchedulerAppointmentField<TAppointment, SchedulerId>;
207
+ resourceId: AppointmentKey<TAppointment>;
208
+ start: AppointmentKey<TAppointment>;
209
+ end: AppointmentKey<TAppointment>;
210
+ };
211
+ /** Default field names the appointment actually has; those can be omitted from the options. */
212
+ type DefaultedChangeField<TAppointment> = Extract<keyof ChangeFields<TAppointment>, keyof TAppointment>;
213
+ /**
214
+ * Key-based options. `id`, `resourceId`, `start` and `end` default to the fields with the same name,
215
+ * so they are optional when the appointment has them.
216
+ */
217
+ type ApplySchedulerAppointmentChangeFieldOptions<TAppointment> = Omit<ChangeFields<TAppointment>, DefaultedChangeField<TAppointment>> & Partial<Pick<ChangeFields<TAppointment>, DefaultedChangeField<TAppointment>>> & {
218
+ dateValue?: (date: Date) => unknown;
219
+ };
220
+ type ApplySchedulerAppointmentChangeInput<TAppointment, TResourceId extends SchedulerId> = ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId> | ApplySchedulerAppointmentChangeFieldOptions<TAppointment>;
221
+ declare const applySchedulerAppointmentChange: <TAppointment, TResourceId extends SchedulerId>(appointments: TAppointment[], change: SchedulerAppointmentChangeArgs<TAppointment, TResourceId>, ...[options]: [Exclude<keyof ChangeFields<TAppointment>, DefaultedChangeField<TAppointment>>] extends [never] ? [options?: ApplySchedulerAppointmentChangeInput<TAppointment, TResourceId>] : [options: ApplySchedulerAppointmentChangeInput<TAppointment, TResourceId>]) => TAppointment[];
130
222
 
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 };
223
+ export { type ApplySchedulerAppointmentChangeFieldOptions, type ApplySchedulerAppointmentChangeInput, type ApplySchedulerAppointmentChangeOptions, type BaseSchedulerResource, type RenderSchedulerAppt, Scheduler, type SchedulerAdapterProp, type SchedulerAgendaItemRenderArgs, type SchedulerAppointmentAdapter, type SchedulerAppointmentAdapterInput, type SchedulerAppointmentAdapterOption, type SchedulerAppointmentAppearance, type SchedulerAppointmentChangeArgs, type SchedulerAppointmentChangeEvent, type SchedulerAppointmentColorToken, type SchedulerAppointmentField, type SchedulerAppointmentFieldAdapter, type SchedulerAppointmentPartialFieldAdapter, type SchedulerAppointmentVisualState, type SchedulerCommonProps, type SchedulerDefaultedAppointmentField, type SchedulerDragState, type SchedulerEvent, type SchedulerId, type SchedulerPresentationAppointment, type SchedulerProps, type SchedulerResourceClassMap, type SchedulerToolbarRenderArgs, type SchedulerView, 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 I from'react';var Et=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})]})},Ne=Et;function ge({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 a=e.raw,d=typeof a.description=="string"?a.description:void 0,s=typeof i=="string"?i:void 0,c=n?.className??s??"rfs:bg-muted/40 rfs:dark:bg-muted/30",R=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",g=`rfs:relative rfs:h-full rfs:overflow-hidden rfs:rounded-md rfs:p-2 rfs:pb-5 rfs:text-foreground ${c} ${R} ${f}`;return jsxs("div",{onPointerDown:r,className:g,children:[jsx(Ne,{isDropInvalid:t,title:e.title,description:d}),jsx(ge,{onResizePointerDown:o,appointment:e})]})}var Ft={id:"id",resourceId:"resourceId",start:"start",end:"end",title:"title"},W=(e,t)=>typeof t=="function"?t(e):e[t],Te=e=>e&&"getId"in e?{id:e.getId,resourceId:e.getResourceId,start:e.getStart,end:e.getEnd,title:e.getTitle}:{...Ft,...e},Se=e=>{if(e&&"getId"in e)return e;let t=Te(e);return {getEnd:r=>W(r,t.end),getId:r=>W(r,t.id),getResourceId:r=>W(r,t.resourceId),getStart:r=>W(r,t.start),getTitle:r=>W(r,t.title)}};function Be(e){if(!e||typeof e!="object")return false;let t=e;return typeof t.firstName=="string"||typeof t.lastName=="string"}var Oe={slate:"rfs:bg-slate-100 rfs:dark:bg-slate-900/40",gray:"rfs:bg-gray-100 rfs:dark:bg-gray-900/40",zinc:"rfs:bg-zinc-100 rfs:dark:bg-zinc-900/40",neutral:"rfs:bg-neutral-100 rfs:dark:bg-neutral-900/40",stone:"rfs:bg-stone-100 rfs:dark:bg-stone-900/40",red:"rfs:bg-red-100 rfs:dark:bg-red-950/40",orange:"rfs:bg-orange-100 rfs:dark:bg-orange-950/40",amber:"rfs:bg-amber-100 rfs:dark:bg-amber-950/40",yellow:"rfs:bg-yellow-100 rfs:dark:bg-yellow-950/40",lime:"rfs:bg-lime-100 rfs:dark:bg-lime-950/40",green:"rfs:bg-green-100 rfs:dark:bg-green-950/40",emerald:"rfs:bg-emerald-100 rfs:dark:bg-emerald-950/40",teal:"rfs:bg-teal-100 rfs:dark:bg-teal-950/40",cyan:"rfs:bg-cyan-100 rfs:dark:bg-cyan-950/40",sky:"rfs:bg-sky-100 rfs:dark:bg-sky-950/40",blue:"rfs:bg-blue-100 rfs:dark:bg-blue-950/40",indigo:"rfs:bg-indigo-100 rfs:dark:bg-indigo-950/40",violet:"rfs:bg-violet-100 rfs:dark:bg-violet-950/40",purple:"rfs:bg-purple-100 rfs:dark:bg-purple-950/40",fuchsia:"rfs:bg-fuchsia-100 rfs:dark:bg-fuchsia-950/40",pink:"rfs:bg-pink-100 rfs:dark:bg-pink-950/40",rose:"rfs:bg-rose-100 rfs:dark:bg-rose-950/40"};function L(e,t,r){return Math.max(t,Math.min(r,e))}function K(e,t=15){return Math.round(e/t)*t}function Ae(e){let[t,r]=e.split(":").map(Number);return t*60+r}function Le(e){return `${e.firstName??""} ${e.lastName??""}`.trim()}function Z(e){return format(e,"yyyy-MM-dd")}function Ie(e,t){return new Date(e.getFullYear(),e.getMonth(),e.getDate()+t)}function $(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),a=n%60;return o.setHours(i,a,0,0),o}function be(e,t){return t.getHours()*60+t.getMinutes()-e}function ye(e,t){return e.startMin<t.endMin&&t.startMin<e.endMin}function _e(e){let t=[...e].sort((a,d)=>a.startMin-d.startMin||a.endMin-d.endMin),r=[],o=[],n=[];for(let a of t)o=o.filter(s=>s.endMin>a.startMin),!o.some(s=>ye(s,a))&&n.length>0&&(r.push(n),n=[]),n.push(a),o.push(a);n.length&&r.push(n);let i=[];for(let a of r){let d=[...a].sort((f,g)=>f.startMin-g.startMin||f.endMin-g.endMin),s=[],c=new Map;for(let f of d){let g=false;for(let p=0;p<s.length;p++)if(s[p]<=f.startMin){s[p]=f.endMin,c.set(f.id,p),g=true;break}g||(s.push(f.endMin),c.set(f.id,s.length-1));}let R=s.length;for(let f of d)i.push({...f,lane:c.get(f.id)??0,lanes:R});}return i}function Me({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 Fe({adapter:e,appointments:t,dayMinutes:r,dayStartAbs:o,selectedISO:n}){return t.map(i=>{let a=e.getId(i),d=new Date(e.getStart(i)),s=new Date(e.getEnd(i));return {raw:i,id:a,resourceId:e.getResourceId(i),start:d,end:s,startMin:L(be(o,d),0,r),endMin:L(be(o,s),0,r),title:e.getTitle(i),renderKey:String(a),visualState:"normal"}}).filter(i=>Z(i.start)===n)}function Ve(e){return new Map(e.map(t=>[t.id,t]))}function He(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:$(r,o,t.startMin),end:$(r,o,t.endMin),visualState:"dragging"})}function ze(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,ve(r.get(n.id)??[]));return o}function ve(e){return _e(e.map(t=>({...t,appointmentId:t.id,id:t.renderKey}))).map(({appointmentId:t,...r})=>({...r,id:t}))}function Ye(e,t,r,o,n){let i=new Map;for(let a of e){let d=t?.[String(a.id)];if(d){i.set(a.id,{className:d});continue}let s=r?.(a);if(s){i.set(a.id,s);continue}let c=o.get(a.id);if(c){i.set(a.id,{className:c});continue}let R=n.get(a.id);i.set(a.id,R?{className:R}:void 0);}return i}function Xe({adapter:e,appointments:t,dayEnd:r="18:00",dayStart:o="09:00",resources:n,selectedDate:i}){let a=I.useMemo(()=>Ae(o),[o]),d=I.useMemo(()=>Ae(r),[r]),s=I.useMemo(()=>Math.max(0,d-a),[d,a]),c=I.useMemo(()=>12+s*2+24,[s]),R=I.useMemo(()=>72+Math.max(n.length,1)*420,[n.length]),{id:f,resourceId:g,start:p,end:l,title:h}=Te(e),T=I.useMemo(()=>Se({id:f,resourceId:g,start:p,end:l,title:h}),[f,g,p,l,h]),b=I.useMemo(()=>Z(i),[i]),S=I.useMemo(()=>Fe({adapter:T,appointments:t,dayMinutes:s,dayStartAbs:a,selectedISO:b}),[t,s,a,T,b]);return {appointmentMap:I.useMemo(()=>Ve(S),[S]),dayEndAbs:d,dayMinutes:s,dayStartAbs:a,gridHeight:c,gridMinWidth:R,renderAppts:S}}var Ht=4,zt=(e,t)=>{e(r=>r&&{...r,clientX:t.clientX,clientY:t.clientY});},Yt=e=>{let{dragRef:t,pendingDragRef:r,pointer:o,setDrag:n,setMovePreview:i,suppressClickRef:a}=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)<Ht||(a.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);},Xt=(e,t,r,o,n)=>{let i=o(t.clientX,e.resourceId),d=n(i,t.clientY)-e.offsetMin,s=L(K(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}},Ut=(e,t,r,o)=>{let n=o(e.resourceId,t.clientY),i=L(K(n),e.startMin+15,r);return i===e.endMin?null:{...e,endMin:i}},$e=e=>{let{dayMinutes:t,dragRef:r,latestPointerRef:o,pendingDragRef:n,pointerToMin:i,pointerToResourceId:a,setDrag:d,setMovePreview:s,suppressClickRef:c}=e,R=o.current;if(!R)return;let f=r.current;if(f.kind==="none"&&n.current){Yt({pointer:R,pendingDragRef:n,setDrag:d,setMovePreview:s,dragRef:r,suppressClickRef:c});return}if(f.kind==="none")return;if(f.kind==="move"){zt(s,R);let p=Xt(f,R,t,a,i);p&&(c.current=true,r.current=p,d(p));return}let g=Ut(f,R,t,i);g&&(c.current=true,r.current=g,d(g));},We=e=>{let{dragRef:t,frameRef:r,latestPointerRef:o,pendingDragRef:n,persistDrag:i,setDrag:a,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"&&(a({kind:"none"}),t.current={kind:"none"},s.current&&i(c));};var Ke=({appointmentMap:e,dayMinutes:t,dayStartAbs:r,onAppointmentChange:o,onPersistMoveResize:n,renderAppts:i,resources:a,selectedDate:d,editable:s})=>{let[c,R]=I.useState({kind:"none"}),[f,g]=I.useState(null),p=I.useRef({}),l=I.useRef(false),h=I.useRef({kind:"none"}),T=I.useRef(null),b=I.useRef(null),S=I.useRef(null),X=I.useMemo(()=>{let u=new Map;for(let m of i){let A=u.get(m.resourceId)??[];A.push(m),u.set(m.resourceId,A);}return u},[i]);I.useEffect(()=>{h.current=c;},[c]),I.useEffect(()=>()=>{S.current!==null&&window.cancelAnimationFrame(S.current);},[]);let y=I.useCallback((u,m)=>{let A=p.current[String(u)];if(!A)return 0;let C=m-A.getBoundingClientRect().top-12;return L(K(C/2),0,t)},[t]),k=I.useCallback((u,m)=>{for(let A of a){let C=p.current[String(A.id)];if(!C)continue;let F=C.getBoundingClientRect();if(u>=F.left&&u<=F.right)return A.id}return m},[a]),w=I.useCallback((u,m,A,C)=>(X.get(m)??[]).some(V=>V.id!==u&&ye(V,{startMin:A,endMin:C})),[X]),ce=I.useMemo(()=>c.kind==="none"?false:w(c.appointmentId,c.resourceId,c.startMin,c.endMin),[c,w]),q=I.useCallback(async u=>{let m=e.get(u.appointmentId);if(!m||w(u.appointmentId,u.resourceId,u.startMin,u.endMin))return;let A={resourceId:u.resourceId,start:$(d,r,u.startMin),end:$(d,r,u.endMin)};if(o){await o({kind:u.kind,appointment:m.raw,resourceId:A.resourceId,start:A.start,end:A.end,previousResourceId:m.resourceId,previousStart:m.start,previousEnd:m.end,previous:{resourceId:m.resourceId,start:m.start,end:m.end},next:A});return}n&&await n({appointment:m.raw,resourceId:A.resourceId,start:A.start,end:A.end});},[e,r,w,o,n,d]),ue=I.useCallback((u,m)=>{if(l.current=false,!s||u.button!==0)return;u.stopPropagation();let A=u.currentTarget.getBoundingClientRect(),C=y(m.resourceId,u.clientY);T.current={drag:{kind:"move",appointmentId:m.id,pointerId:u.pointerId,resourceId:m.resourceId,durationMin:Math.max(15,m.endMin-m.startMin),offsetMin:C-m.startMin,startMin:m.startMin,endMin:m.endMin},appointment:m,startClientX:u.clientX,startClientY:u.clientY,width:A.width,height:A.height,offsetX:u.clientX-A.left,offsetY:u.clientY-A.top};},[y,s]),pe=I.useCallback((u,m)=>{l.current=false,s&&u.button===0&&(u.stopPropagation(),T.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]),le=I.useCallback(u=>{b.current={clientX:u.clientX,clientY:u.clientY,pointerId:u.pointerId},S.current===null&&(S.current=window.requestAnimationFrame(()=>{S.current=null,$e({dayMinutes:t,dragRef:h,latestPointerRef:b,pendingDragRef:T,pointerToMin:y,pointerToResourceId:k,setDrag:R,setMovePreview:g,suppressClickRef:l});}));},[t,y,k]),fe=I.useCallback(()=>{We({dragRef:h,frameRef:S,latestPointerRef:b,pendingDragRef:T,persistDrag:q,setDrag:R,setMovePreview:g,suppressClickRef:l});},[q]);return {colRefs:p,drag:c,isDropInvalid:ce,movePreview:f,onApptPointerDown:ue,onGlobalPointerMove:le,onGlobalPointerUp:fe,onResizePointerDown:pe,suppressClickRef:l}};function Ge({appointmentColorTokenClassMap:e,dayStartAbs:t,drag:r,getResourceAppointmentAppearance:o,getResourceAppointmentBackground:n,getResourceAppointmentColorToken:i,renderAppts:a,resourceAppointmentClassMap:d,resources:s,selectedDate:c}){let R=I.useMemo(()=>He(a,r,c,t),[t,r,a,c]),f=I.useMemo(()=>ze(s,a),[a,s]),g=I.useMemo(()=>{if(r.kind!=="resize")return f;let T=new Map(f),b=R.filter(S=>S.resourceId===r.resourceId);return T.set(r.resourceId,ve(b)),T},[f,r,R]),p=I.useMemo(()=>n?Me({fallback:void 0,getValue:n,resources:s,toKey:T=>T.id}):new Map,[n,s]),l=I.useMemo(()=>{if(!i)return new Map;let T={...Oe,...e??{}};return Me({fallback:void 0,getValue:b=>{let S=i(b);return S?T[S]:void 0},resources:s,toKey:b=>b.id})},[e,i,s]);return {appointmentAppearanceByResource:I.useMemo(()=>Ye(s,d,o,l,p),[p,l,o,d,s]),appointmentBgByResource:p,effectiveAppts:R,laidOutByResource:g}}function qe({views:e,view:t,defaultView:r,onViewChange:o}){let[n,i]=I.useState(()=>r??(e.length>0?e[0]:"day")),a=I.useCallback(d=>{t===void 0&&i(d),o?.(d);},[t,o]);return [t??n,a]}function B(...e){return e.filter(Boolean).join(" ")}function Je({resource:e}){return jsx("strong",{children:e.label})}function re({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=>Je({resource:o})))(r),Be(r)?jsx("div",{className:"rfs-resource-subtitle rfs:text-muted-foreground",children:Le(r)}):null]},String(r.id)))]})}var je=e=>format(e,"HH:mm"),et=e=>String(e).padStart(2,"0"),Kt=e=>`${et(Math.floor(e/60))}:${et(e%60)}`,tt=e=>Math.floor((e.getHours()*60+e.getMinutes())/15)*15,rt=(e,t)=>`${e}|${String(t)}`;function nt({appointment:e}){let t=e.raw,r=typeof t.description=="string"?t.description:void 0;return jsxs(Fragment,{children:[jsxs("span",{className:"rfs:block rfs:text-xs rfs:font-medium rfs:tabular-nums",children:[je(e.start),"\u2013",je(e.end)]}),jsx("span",{className:"rfs:block rfs:text-xs rfs:font-semibold",children:e.title}),r&&jsx("span",{className:"rfs:block rfs:text-[10px] rfs:font-medium",children:r})]})}function st({appointments:e,resources:t,appointmentAppearanceByResource:r,dayStartAbs:o,dayEndAbs:n,onAppointmentClick:i,renderResourceHeader:a,renderAgendaItem:d,emptyState:s="No appointments"}){let{slots:c,cells:R}=I.useMemo(()=>{let p=new Set(t.map(y=>y.id)),l=e.filter(y=>p.has(y.resourceId)).sort((y,k)=>y.start.getTime()-k.start.getTime()),h=new Map;for(let y of l){let k=rt(tt(y.start),y.resourceId),w=h.get(k)??[];w.push(y),h.set(k,w);}let T=l.map(y=>tt(y.start)),b=Math.min(Math.floor(o/15)*15,...T),S=Math.max(Math.ceil(n/15)*15-15,...T);return {slots:Array.from({length:Math.max(0,(S-b)/15+1)},(y,k)=>b+k*15),cells:h}},[e,t,o,n]);if(!(R.size>0))return jsx("div",{className:"rfs-agenda rfs:rounded-lg rfs:border rfs:border-border rfs:bg-card rfs:p-6 rfs:text-center rfs:text-sm rfs:text-muted-foreground",children:s});let g=(p,l)=>{let h=r.get(l.id),T=i?S=>i(p.raw,S):void 0;if(d)return jsx("li",{onClick:T,children:d({appointment:p,resource:l,appointmentAppearance:h})},p.renderKey);let b=B("rfs:block rfs:w-full rfs:rounded-md rfs:px-3 rfs:py-2 rfs:text-left rfs:text-foreground",h?.className??"rfs:bg-muted/40 rfs:dark:bg-muted/30");return jsx("li",{children:T?jsx("button",{type:"button",className:B(b,"rfs:cursor-pointer"),onClick:T,children:jsx(nt,{appointment:p})}):jsx("div",{className:b,children:jsx(nt,{appointment:p})})},p.renderKey)};return jsx("div",{className:"rfs-agenda rfs-shell rfs:border-border rfs:bg-card",children:jsxs("div",{style:{minWidth:72+Math.max(t.length,1)*420},children:[jsx(re,{resources:t,renderResourceHeader:a}),c.map(p=>{let l=p%60===0,h=(p+15)%60===0?"var(--rfs-border)":"color-mix(in oklab, var(--rfs-border) 40%, transparent)";return jsxs("div",{className:"rfs:flex",children:[jsx("div",{className:B("rfs-gutter rfs:border-b rfs:px-2 rfs:py-1 rfs:text-xs rfs:tabular-nums",l?"rfs:text-foreground":"rfs:text-muted-foreground/70"),style:{width:72,borderBottomColor:h},children:Kt(p)}),t.map(T=>jsx("ul",{"aria-label":T.label,className:"rfs-col rfs:flex rfs:min-h-7 rfs:flex-col rfs:gap-1 rfs:border-b rfs:p-1",style:{minWidth:420,flex:1,borderBottomColor:h},children:(R.get(rt(p,T.id))??[]).map(b=>g(b,T))},String(T.id)))]},p)})]})})}function it({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}`))})}var dt=({resource:e,colRefs:t,gridHeight:r,dayMinutes:o,appointments:n,appointmentAppearance:i,appointmentBg:a,isDropInvalid:d,renderAppointment:s,onAppointmentClick:c,onApptPointerDown:R,onResizePointerDown:f,drag:g,suppressClickRef:p})=>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,h)=>jsx("div",{className:"rfs-hour-line rfs:border-border/70",style:{top:12+h*60*2}},`major-${h}`)),Array.from({length:Math.floor(o/15)+1}).map((l,h)=>jsx("div",{className:"rfs-slot-line rfs:border-border/50",style:{top:12+h*15*2}},`minor-${h}`)),n.map(l=>{let h=100/l.lanes,T=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:T,left:`${h*l.lane}%`,width:`${h}%`,height:b},onClick:c?S=>{p.current||c(l.raw,S);}:void 0,children:(s??Q)({appointment:l,isDropInvalid:d&&g.kind==="resize"&&l.id===g.appointmentId,onPointerDown:S=>R(S,l),onResizePointerDown:S=>f(S,l),appointmentAppearance:i,appointmentBackgroundColor:a,drag:g,suppressClickRef:p})},l.renderKey)})]})});var Zt=(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.onAppointmentClick===t.onAppointmentClick,e.onApptPointerDown===t.onApptPointerDown,e.onResizePointerDown===t.onResizePointerDown,e.drag===t.drag,e.suppressClickRef===t.suppressClickRef].every(Boolean),ct=I.memo(dt,Zt);var jt={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"},er={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"},D=I.forwardRef(function({className:t,variant:r="default",size:o="default",type:n="button",...i},a){return jsx("button",{ref:a,type:n,className:B("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",jt[r],er[o],t),...i})});function mt({selected:e,onSelect:t}){let[r,o]=I.useState(e??new Date);I.useEffect(()=>{e&&o(e);},[e]);let n=startOfMonth(r),i=startOfWeek(n,{weekStartsOn:1}),a=endOfWeek(endOfMonth(r),{weekStartsOn:1}),d=[];for(let s=i;s<=a;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(D,{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(D,{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(D,{variant:c?"default":"ghost",size:"icon",className:B("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 Rt=I.createContext(null);function ht(){let e=I.useContext(Rt);if(!e)throw new Error("Popover components must be used within Popover.");return e}function gt({children:e,open:t,onOpenChange:r}){let[o,n]=I.useState(false),i=I.useRef(null),a=I.useRef(null),d=t??o,s=I.useCallback(c=>{let R=typeof c=="function"?c(d):c;t===void 0&&n(R),r?.(R);},[t,r,d]);return I.useEffect(()=>{if(!d)return;let c=f=>{let g=f.target;i.current?.contains(g)||a.current?.contains(g)||s(false);},R=f=>{f.key==="Escape"&&s(false);};return document.addEventListener("mousedown",c),document.addEventListener("keydown",R),()=>{document.removeEventListener("mousedown",c),document.removeEventListener("keydown",R);}},[d,s]),jsx(Rt.Provider,{value:{open:d,setOpen:s,triggerRef:i,contentRef:a},children:jsx("div",{className:"rfs:relative rfs:inline-flex",children:e})})}function Tt({children:e,asChild:t=false}){let{open:r,setOpen:o,triggerRef:n}=ht();if(t&&I.isValidElement(e)){let i=e;return I.cloneElement(i,{ref:n,"aria-expanded":r,onClick:a=>{i.props.onClick?.(a),o(d=>!d);}})}return jsx("button",{ref:n,type:"button","aria-expanded":r,onClick:()=>o(i=>!i),children:e})}function St({children:e,className:t,align:r="start"}){let{open:o,contentRef:n}=ht();return o?jsx("div",{ref:n,className:B("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 At({selectedDate:e,onSelectedDateChange:t}){return jsxs(gt,{children:[jsx(Tt,{asChild:true,children:jsx(D,{variant:"outline",size:"sm",className:"rfs:min-w-40 rfs:justify-start rfs:text-left rfs:font-normal",children:format(e,"PPP")})}),jsx(St,{className:"rfs:w-auto rfs:p-2",align:"center",children:jsx(mt,{selected:e,onSelect:t})})]})}function bt({goToPreviousDay:e,goToNextDay:t,defaultDatePicker:r,defaultViewSwitcher:o,prevButtonLabel:n="Prev",nextButtonLabel:i="Next"}){return jsxs("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(D,{variant:"outline",size:"sm",onClick:e,children:n}),r,jsx(D,{variant:"outline",size:"sm",onClick:t,children:i})]}),o&&jsx("div",{className:"rfs:ml-auto",children:o})]})}var lr={day:"Day",agenda:"Agenda"};function Mt({selectedDate:e,onSelectedDateChange:t,prevButtonLabel:r,nextButtonLabel:o,renderToolbar:n,renderDatePicker:i,view:a,views:d,onViewChange:s,viewLabels:c}){let R=()=>t(Ie(e,-1)),f=()=>t(Ie(e,1)),g=(i??At)({selectedDate:e,onSelectedDateChange:t}),p=d.length>1?jsx("div",{role:"group","aria-label":"View",className:"rfs:flex rfs:items-center rfs:gap-1 rfs:rounded-lg rfs:border rfs:border-border rfs:bg-card rfs:p-1 rfs:shadow-xs",children:d.map(h=>jsx(D,{variant:h===a?"default":"ghost",size:"sm","aria-pressed":h===a,onClick:()=>s(h),children:c?.[h]??lr[h]},h))}):null,l={selectedDate:e,onSelectedDateChange:t,goToPreviousDay:R,goToNextDay:f,defaultDatePicker:g,view:a,views:d,onViewChange:s,defaultViewSwitcher:p};return n?jsx(Fragment,{children:n(l)}):jsx(Fragment,{children:bt({...l,prevButtonLabel:r,nextButtonLabel:o})})}var fr={kind:"none"},mr=["day"];function Rr({resources:e,appointments:t,selectedDate:r,onSelectedDateChange:o,adapter:n,onPersistMoveResize:i,onAppointmentChange:a,onAppointmentClick:d,renderResourceHeader:s,renderAppointment:c,resourceAppointmentClassMap:R,getResourceAppointmentAppearance:f,getResourceAppointmentColorToken:g,appointmentColorTokenClassMap:p,getResourceAppointmentBackground:l,renderToolbar:h,renderDatePicker:T,prevButtonLabel:b="Prev",nextButtonLabel:S="Next",dayStart:X="09:00",dayEnd:y="18:00",editable:k=true,views:w=mr,view:ce,defaultView:q,onViewChange:ue,viewLabels:pe,renderAgendaItem:le,agendaEmptyState:fe}){let[u,m]=qe({views:w,view:ce,defaultView:q,onViewChange:ue}),{appointmentMap:A,dayEndAbs:C,dayMinutes:F,dayStartAbs:V,gridHeight:ke,gridMinWidth:Pt,renderAppts:me}=Xe({adapter:n,appointments:t,dayEnd:y,dayStart:X,resources:e,selectedDate:r}),{colRefs:kt,drag:v,isDropInvalid:De,movePreview:N,onApptPointerDown:Dt,onGlobalPointerMove:wt,onGlobalPointerUp:we,onResizePointerDown:Ct,suppressClickRef:Ce}=Ke({appointmentMap:A,dayMinutes:F,dayStartAbs:V,onAppointmentChange:a,onPersistMoveResize:i,renderAppts:me,resources:e,selectedDate:r,editable:k}),{appointmentAppearanceByResource:J,appointmentBgByResource:Re,laidOutByResource:Nt}=Ge({appointmentColorTokenClassMap:p,dayStartAbs:V,drag:v,getResourceAppointmentAppearance:f,getResourceAppointmentBackground:l,getResourceAppointmentColorToken:g,renderAppts:me,resourceAppointmentClassMap:R,resources:e,selectedDate:r}),O=I.useMemo(()=>v.kind!=="move"||!N?null:{appointment:{...N.appointment,resourceId:v.resourceId,startMin:v.startMin,endMin:v.endMin,visualState:"ghost",renderKey:`${N.appointment.renderKey}-overlay`,lane:0,lanes:1},appearance:J.get(v.resourceId),background:Re.get(v.resourceId),left:N.clientX-N.offsetX,top:N.clientY-N.offsetY,width:N.width,height:N.height},[J,Re,v,N]);return jsxs("section",{className:`rfs-root rfs:rounded-lg rfs:text-foreground ${v.kind==="move"?"rfs-root--drag-move":""} ${v.kind==="resize"?"rfs-root--drag-resize":""}`,onPointerMove:wt,onPointerUp:we,onPointerCancel:we,children:[jsx(Mt,{selectedDate:r,onSelectedDateChange:o,prevButtonLabel:b,nextButtonLabel:S,renderToolbar:h,renderDatePicker:T,view:u,views:w,onViewChange:m,viewLabels:pe}),u==="agenda"?jsx(st,{appointments:me,resources:e,appointmentAppearanceByResource:J,dayStartAbs:V,dayEndAbs:C,onAppointmentClick:d,renderResourceHeader:s,renderAgendaItem:le,emptyState:fe}):jsx("div",{className:"rfs-shell rfs:border-border rfs:bg-card",children:jsxs("div",{style:{minWidth:Pt},children:[jsx(re,{resources:e,renderResourceHeader:s}),jsxs("div",{className:"rfs-body",children:[jsx(it,{dayMinutes:F,dayStartAbs:V,gridHeight:ke}),jsx("div",{className:"rfs-grid",children:e.map(U=>jsx(ct,{resource:U,colRefs:kt,gridHeight:ke,dayMinutes:F,appointments:Nt.get(U.id)??[],appointmentAppearance:J.get(U.id),appointmentBg:Re.get(U.id),isDropInvalid:De,renderAppointment:c,onAppointmentClick:d,onApptPointerDown:Dt,onResizePointerDown:Ct,drag:v.kind==="resize"&&v.resourceId===U.id?v:fr,suppressClickRef:Ce},String(U.id)))})]})]})}),O?jsx("div",{className:"rfs-drag-overlay",style:{left:O.left,top:O.top,width:O.width,height:O.height},children:(c??Q)({appointment:O.appointment,isDropInvalid:De,onPointerDown:()=>{},onResizePointerDown:()=>{},appointmentAppearance:O.appearance,appointmentBackgroundColor:O.background,drag:v,suppressClickRef:Ce})}):null]})}var hr={id:"id",resourceId:"resourceId",start:"start",end:"end"},xt=(e,t)=>typeof t=="function"?t(e):e[t],gr=e=>!("getId"in e),Tr=e=>({resourceId:e.resourceId??e.next.resourceId,start:e.start??e.next.start,end:e.end??e.next.end}),Sr=(e,t,...[r={}])=>{let o=Tr(t);return e.map(n=>{if(gr(r)){let d={...hr,...r};if(xt(n,d.id)!==xt(t.appointment,d.id))return n;let s=r.dateValue??(c=>c);return {...n,[d.resourceId]:o.resourceId,[d.start]:s(o.start),[d.end]:s(o.end)}}if(r.getId(n)!==r.getId(t.appointment))return n;let i=r.setResourceId(n,o.resourceId),a=r.setStart(i,o.start);return r.setEnd(a,o.end)})};export{Rr as Scheduler,Sr as applySchedulerAppointmentChange,Se as resolveSchedulerAppointmentAdapter};
package/dist/styles.css CHANGED
@@ -1,2 +1,2 @@
1
1
  /*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */
2
- @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){.rfs-root, .rfs-root *,.rfs-root :before,.rfs-root :after,.rfs-root::backdrop, .rfs-root ::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000}}}@layer theme{.rfs-root,.rfs-root{--rfs-color-red-100:oklch(93.6% .032 17.717);--rfs-color-red-600:oklch(57.7% .245 27.325);--rfs-color-red-950:oklch(25.8% .092 26.042);--rfs-color-white:#fff;--rfs-spacing:.25rem;--rfs-text-xs:.75rem;--rfs-text-xs--line-height:calc(1 / .75);--rfs-text-sm:.875rem;--rfs-text-sm--line-height:calc(1.25 / .875);--rfs-font-weight-normal:400;--rfs-font-weight-medium:500;--rfs-font-weight-semibold:600;--rfs-font-weight-bold:700;--rfs-default-transition-duration:.15s;--rfs-default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--rfs-default-font-family:var(--font-sans);--rfs-default-mono-font-family:var(--font-mono)}}@layer base{.rfs-root, .rfs-root *,.rfs-root :after,.rfs-root :before,.rfs-root::backdrop, .rfs-root ::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}.rfs-root::file-selector-button, .rfs-root ::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}.rfs-root,.rfs-root{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--rfs-default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--rfs-default-font-feature-settings,normal);font-variation-settings:var(--rfs-default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}.rfs-root hr{height:0;color:inherit;border-top-width:1px}.rfs-root abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.rfs-root h1,.rfs-root h2,.rfs-root h3,.rfs-root h4,.rfs-root h5,.rfs-root h6{font-size:inherit;font-weight:inherit}.rfs-root a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}.rfs-root b,.rfs-root strong{font-weight:bolder}.rfs-root code,.rfs-root kbd,.rfs-root samp,.rfs-root pre{font-family:var(--rfs-default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--rfs-default-mono-font-feature-settings,normal);font-variation-settings:var(--rfs-default-mono-font-variation-settings,normal);font-size:1em}.rfs-root small{font-size:80%}.rfs-root sub,.rfs-root sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}.rfs-root sub{bottom:-.25em}.rfs-root sup{top:-.5em}.rfs-root table{text-indent:0;border-color:inherit;border-collapse:collapse}.rfs-root :-moz-focusring{outline:auto}.rfs-root progress{vertical-align:baseline}.rfs-root summary{display:list-item}.rfs-root ol,.rfs-root ul,.rfs-root menu{list-style:none}.rfs-root img,.rfs-root svg,.rfs-root video,.rfs-root canvas,.rfs-root audio,.rfs-root iframe,.rfs-root embed,.rfs-root object{vertical-align:middle;display:block}.rfs-root img,.rfs-root video{max-width:100%;height:auto}.rfs-root button,.rfs-root input,.rfs-root select,.rfs-root optgroup,.rfs-root textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}.rfs-root::file-selector-button, .rfs-root ::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}.rfs-root :where(select:is([multiple],[size])) optgroup{font-weight:bolder}.rfs-root :where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}.rfs-root::file-selector-button, .rfs-root ::file-selector-button{margin-inline-end:4px}.rfs-root::placeholder, .rfs-root ::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){.rfs-root::placeholder, .rfs-root ::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){.rfs-root::placeholder, .rfs-root ::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}.rfs-root textarea{resize:vertical}.rfs-root::-webkit-search-decoration, .rfs-root ::-webkit-search-decoration{-webkit-appearance:none}.rfs-root::-webkit-date-and-time-value, .rfs-root ::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}.rfs-root::-webkit-datetime-edit, .rfs-root ::-webkit-datetime-edit{display:inline-flex}.rfs-root::-webkit-datetime-edit-fields-wrapper, .rfs-root ::-webkit-datetime-edit-fields-wrapper{padding:0}.rfs-root::-webkit-datetime-edit, .rfs-root ::-webkit-datetime-edit{padding-block:0}.rfs-root::-webkit-datetime-edit-year-field, .rfs-root ::-webkit-datetime-edit-year-field{padding-block:0}.rfs-root::-webkit-datetime-edit-month-field, .rfs-root ::-webkit-datetime-edit-month-field{padding-block:0}.rfs-root::-webkit-datetime-edit-day-field, .rfs-root ::-webkit-datetime-edit-day-field{padding-block:0}.rfs-root::-webkit-datetime-edit-hour-field, .rfs-root ::-webkit-datetime-edit-hour-field{padding-block:0}.rfs-root::-webkit-datetime-edit-minute-field, .rfs-root ::-webkit-datetime-edit-minute-field{padding-block:0}.rfs-root::-webkit-datetime-edit-second-field, .rfs-root ::-webkit-datetime-edit-second-field{padding-block:0}.rfs-root::-webkit-datetime-edit-millisecond-field, .rfs-root ::-webkit-datetime-edit-millisecond-field{padding-block:0}.rfs-root::-webkit-datetime-edit-meridiem-field, .rfs-root ::-webkit-datetime-edit-meridiem-field{padding-block:0}.rfs-root::-webkit-calendar-picker-indicator, .rfs-root ::-webkit-calendar-picker-indicator{line-height:1}.rfs-root :-moz-ui-invalid{box-shadow:none}.rfs-root button,.rfs-root input:where([type=button],[type=reset],[type=submit]){appearance:button}.rfs-root::file-selector-button, .rfs-root ::file-selector-button{appearance:button}.rfs-root::-webkit-inner-spin-button, .rfs-root ::-webkit-inner-spin-button{height:auto}.rfs-root::-webkit-outer-spin-button, .rfs-root ::-webkit-outer-spin-button{height:auto}.rfs-root [hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.rfs-root.rfs\:absolute, .rfs-root .rfs\:absolute{position:absolute}.rfs-root.rfs\:relative, .rfs-root .rfs\:relative{position:relative}.rfs-root.rfs\:inset-x-1, .rfs-root .rfs\:inset-x-1{inset-inline:calc(var(--rfs-spacing) * 1)}.rfs-root.rfs\:top-1, .rfs-root .rfs\:top-1{top:calc(var(--rfs-spacing) * 1)}.rfs-root.rfs\:top-full, .rfs-root .rfs\:top-full{top:100%}.rfs-root.rfs\:right-0, .rfs-root .rfs\:right-0{right:calc(var(--rfs-spacing) * 0)}.rfs-root.rfs\:right-1, .rfs-root .rfs\:right-1{right:calc(var(--rfs-spacing) * 1)}.rfs-root.rfs\:bottom-1, .rfs-root .rfs\:bottom-1{bottom:calc(var(--rfs-spacing) * 1)}.rfs-root.rfs\:left-0, .rfs-root .rfs\:left-0{left:calc(var(--rfs-spacing) * 0)}.rfs-root.rfs\:left-1\/2, .rfs-root .rfs\:left-1\/2{left:50%}.rfs-root.rfs\:z-50, .rfs-root .rfs\:z-50{z-index:50}.rfs-root.rfs\:mt-1, .rfs-root .rfs\:mt-1{margin-top:calc(var(--rfs-spacing) * 1)}.rfs-root.rfs\:mt-2, .rfs-root .rfs\:mt-2{margin-top:calc(var(--rfs-spacing) * 2)}.rfs-root.rfs\:mb-2, .rfs-root .rfs\:mb-2{margin-bottom:calc(var(--rfs-spacing) * 2)}.rfs-root.rfs\:flex, .rfs-root .rfs\:flex{display:flex}.rfs-root.rfs\:grid, .rfs-root .rfs\:grid{display:grid}.rfs-root.rfs\:inline-flex, .rfs-root .rfs\:inline-flex{display:inline-flex}.rfs-root.rfs\:h-2, .rfs-root .rfs\:h-2{height:calc(var(--rfs-spacing) * 2)}.rfs-root.rfs\:h-4, .rfs-root .rfs\:h-4{height:calc(var(--rfs-spacing) * 4)}.rfs-root.rfs\:h-8, .rfs-root .rfs\:h-8{height:calc(var(--rfs-spacing) * 8)}.rfs-root.rfs\:h-9, .rfs-root .rfs\:h-9{height:calc(var(--rfs-spacing) * 9)}.rfs-root.rfs\:h-full, .rfs-root .rfs\:h-full{height:100%}.rfs-root.rfs\:w-4, .rfs-root .rfs\:w-4{width:calc(var(--rfs-spacing) * 4)}.rfs-root.rfs\:w-8, .rfs-root .rfs\:w-8{width:calc(var(--rfs-spacing) * 8)}.rfs-root.rfs\:w-72, .rfs-root .rfs\:w-72{width:calc(var(--rfs-spacing) * 72)}.rfs-root.rfs\:w-auto, .rfs-root .rfs\:w-auto{width:auto}.rfs-root.rfs\:min-w-40, .rfs-root .rfs\:min-w-40{min-width:calc(var(--rfs-spacing) * 40)}.rfs-root.rfs\:min-w-72, .rfs-root .rfs\:min-w-72{min-width:calc(var(--rfs-spacing) * 72)}.rfs-root.rfs\:-translate-x-1\/2, .rfs-root .rfs\:-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.rfs-root.rfs\:cursor-grab, .rfs-root .rfs\:cursor-grab{cursor:grab}.rfs-root.rfs\:cursor-grabbing, .rfs-root .rfs\:cursor-grabbing{cursor:grabbing}.rfs-root.rfs\:cursor-ns-resize, .rfs-root .rfs\:cursor-ns-resize{cursor:ns-resize}.rfs-root.rfs\:grid-cols-7, .rfs-root .rfs\:grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.rfs-root.rfs\:items-center, .rfs-root .rfs\:items-center{align-items:center}.rfs-root.rfs\:justify-between, .rfs-root .rfs\:justify-between{justify-content:space-between}.rfs-root.rfs\:justify-center, .rfs-root .rfs\:justify-center{justify-content:center}.rfs-root.rfs\:justify-start, .rfs-root .rfs\:justify-start{justify-content:flex-start}.rfs-root.rfs\:gap-1, .rfs-root .rfs\:gap-1{gap:calc(var(--rfs-spacing) * 1)}.rfs-root.rfs\:gap-2, .rfs-root .rfs\:gap-2{gap:calc(var(--rfs-spacing) * 2)}.rfs-root.rfs\:overflow-hidden, .rfs-root .rfs\:overflow-hidden{overflow:hidden}.rfs-root.rfs\:rounded-full, .rfs-root .rfs\:rounded-full{border-radius:3.40282e38px}.rfs-root.rfs\:rounded-lg, .rfs-root .rfs\:rounded-lg{border-radius:var(--radius)}.rfs-root.rfs\:rounded-md, .rfs-root .rfs\:rounded-md{border-radius:calc(var(--radius) - 2px)}.rfs-root.rfs\:border, .rfs-root .rfs\:border{border-style:var(--tw-border-style);border-width:1px}.rfs-root.rfs\:border-border, .rfs-root .rfs\:border-border,.rfs-root.rfs\:border-border\/50, .rfs-root .rfs\:border-border\/50{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:border-border\/50, .rfs-root .rfs\:border-border\/50{border-color:color-mix(in oklab, var(--border) 50%, transparent)}}.rfs-root.rfs\:border-border\/70, .rfs-root .rfs\:border-border\/70{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:border-border\/70, .rfs-root .rfs\:border-border\/70{border-color:color-mix(in oklab, var(--border) 70%, transparent)}}.rfs-root.rfs\:bg-border\/90, .rfs-root .rfs\:bg-border\/90{background-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:bg-border\/90, .rfs-root .rfs\:bg-border\/90{background-color:color-mix(in oklab, var(--border) 90%, transparent)}}.rfs-root.rfs\:bg-card, .rfs-root .rfs\:bg-card{background-color:var(--card)}.rfs-root.rfs\:bg-muted\/40, .rfs-root .rfs\:bg-muted\/40{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:bg-muted\/40, .rfs-root .rfs\:bg-muted\/40{background-color:color-mix(in oklab, var(--muted) 40%, transparent)}}.rfs-root.rfs\:bg-popover, .rfs-root .rfs\:bg-popover{background-color:var(--popover)}.rfs-root.rfs\:bg-primary, .rfs-root .rfs\:bg-primary{background-color:var(--primary)}.rfs-root.rfs\:bg-red-100\/80, .rfs-root .rfs\:bg-red-100\/80{background-color:var(--rfs-color-red-100)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:bg-red-100\/80, .rfs-root .rfs\:bg-red-100\/80{background-color:color-mix(in oklab, var(--rfs-color-red-100) 80%, transparent)}}.rfs-root.rfs\:bg-red-600, .rfs-root .rfs\:bg-red-600{background-color:var(--rfs-color-red-600)}.rfs-root.rfs\:p-1, .rfs-root .rfs\:p-1{padding:calc(var(--rfs-spacing) * 1)}.rfs-root.rfs\:p-2, .rfs-root .rfs\:p-2{padding:calc(var(--rfs-spacing) * 2)}.rfs-root.rfs\:px-3, .rfs-root .rfs\:px-3{padding-inline:calc(var(--rfs-spacing) * 3)}.rfs-root.rfs\:px-4, .rfs-root .rfs\:px-4{padding-inline:calc(var(--rfs-spacing) * 4)}.rfs-root.rfs\:py-1, .rfs-root .rfs\:py-1{padding-block:calc(var(--rfs-spacing) * 1)}.rfs-root.rfs\:py-2, .rfs-root .rfs\:py-2{padding-block:calc(var(--rfs-spacing) * 2)}.rfs-root.rfs\:pb-5, .rfs-root .rfs\:pb-5{padding-bottom:calc(var(--rfs-spacing) * 5)}.rfs-root.rfs\:text-center, .rfs-root .rfs\:text-center{text-align:center}.rfs-root.rfs\:text-left, .rfs-root .rfs\:text-left{text-align:left}.rfs-root.rfs\:text-sm, .rfs-root .rfs\:text-sm{font-size:var(--rfs-text-sm);line-height:var(--tw-leading,var(--rfs-text-sm--line-height))}.rfs-root.rfs\:text-xs, .rfs-root .rfs\:text-xs{font-size:var(--rfs-text-xs);line-height:var(--tw-leading,var(--rfs-text-xs--line-height))}.rfs-root.rfs\:text-\[10px\], .rfs-root .rfs\:text-\[10px\]{font-size:10px}.rfs-root.rfs\:font-bold, .rfs-root .rfs\:font-bold{--tw-font-weight:var(--rfs-font-weight-bold);font-weight:var(--rfs-font-weight-bold)}.rfs-root.rfs\:font-medium, .rfs-root .rfs\:font-medium{--tw-font-weight:var(--rfs-font-weight-medium);font-weight:var(--rfs-font-weight-medium)}.rfs-root.rfs\:font-normal, .rfs-root .rfs\:font-normal{--tw-font-weight:var(--rfs-font-weight-normal);font-weight:var(--rfs-font-weight-normal)}.rfs-root.rfs\:font-semibold, .rfs-root .rfs\:font-semibold{--tw-font-weight:var(--rfs-font-weight-semibold);font-weight:var(--rfs-font-weight-semibold)}.rfs-root.rfs\:whitespace-nowrap, .rfs-root .rfs\:whitespace-nowrap{white-space:nowrap}.rfs-root.rfs\:text-foreground, .rfs-root .rfs\:text-foreground{color:var(--foreground)}.rfs-root.rfs\:text-muted-foreground, .rfs-root .rfs\:text-muted-foreground{color:var(--muted-foreground)}.rfs-root.rfs\:text-popover-foreground, .rfs-root .rfs\:text-popover-foreground{color:var(--popover-foreground)}.rfs-root.rfs\:text-primary-foreground, .rfs-root .rfs\:text-primary-foreground{color:var(--primary-foreground)}.rfs-root.rfs\:text-red-950, .rfs-root .rfs\:text-red-950{color:var(--rfs-color-red-950)}.rfs-root.rfs\:text-white, .rfs-root .rfs\:text-white{color:var(--rfs-color-white)}.rfs-root.rfs\:opacity-35, .rfs-root .rfs\:opacity-35{opacity:.35}.rfs-root.rfs\:opacity-55, .rfs-root .rfs\:opacity-55{opacity:.55}.rfs-root.rfs\:opacity-60, .rfs-root .rfs\:opacity-60{opacity:.6}.rfs-root.rfs\:shadow-md, .rfs-root .rfs\:shadow-md{--tw-shadow:var(--shadow-md);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.rfs-root.rfs\:shadow-xl, .rfs-root .rfs\:shadow-xl{--tw-shadow:var(--shadow-xl);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.rfs-root.rfs\:shadow-xs, .rfs-root .rfs\:shadow-xs{--tw-shadow:var(--shadow-xs);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.rfs-root.rfs\:transition-colors, .rfs-root .rfs\:transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--rfs-default-transition-timing-function));transition-duration:var(--tw-duration,var(--rfs-default-transition-duration))}.rfs-root.rfs\:outline-none, .rfs-root .rfs\:outline-none{--tw-outline-style:none;outline-style:none}@media (hover:hover){.rfs-root.rfs\:hover\:bg-border:hover, .rfs-root .rfs\:hover\:bg-border:hover{background-color:var(--border)}.rfs-root.rfs\:hover\:bg-muted:hover, .rfs-root .rfs\:hover\:bg-muted:hover{background-color:var(--muted)}.rfs-root.rfs\:hover\:bg-primary\/90:hover, .rfs-root .rfs\:hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:hover\:bg-primary\/90:hover, .rfs-root .rfs\:hover\:bg-primary\/90:hover{background-color:color-mix(in oklab, var(--primary) 90%, transparent)}}}.rfs-root.rfs\:focus-visible\:ring-2:focus-visible, .rfs-root .rfs\:focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.rfs-root.rfs\:focus-visible\:ring-ring:focus-visible, .rfs-root .rfs\:focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--ring)}.rfs-root.rfs\:focus-visible\:ring-offset-2:focus-visible, .rfs-root .rfs\:focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.rfs-root.rfs\:focus-visible\:outline-none:focus-visible, .rfs-root .rfs\:focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.rfs-root.rfs\:disabled\:pointer-events-none:disabled, .rfs-root .rfs\:disabled\:pointer-events-none:disabled{pointer-events:none}.rfs-root.rfs\:disabled\:opacity-50:disabled, .rfs-root .rfs\:disabled\:opacity-50:disabled{opacity:.5}.rfs-root.rfs\:dark\:bg-muted\/30:is(.dark *), .rfs-root .rfs\:dark\:bg-muted\/30:is(.dark *){background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-muted\/30:is(.dark *), .rfs-root .rfs\:dark\:bg-muted\/30:is(.dark *){background-color:color-mix(in oklab, var(--muted) 30%, transparent)}}.rfs-root.rfs\:dark\:bg-red-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-red-950\/40:is(.dark *){background-color:var(--rfs-color-red-950)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-red-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-red-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-red-950) 40%, transparent)}}.rfs-root.rfs\:dark\:text-red-100:is(.dark *), .rfs-root .rfs\:dark\:text-red-100:is(.dark *){color:var(--rfs-color-red-100)}}.rfs-root{--topbar-h:39px;--header-h:87px;--footer-h:359px;--site-content-min-h:calc(100dvh - var(--topbar-h) - var(--header-h) - var(--footer-h));--background:oklch(100% 0 0);--foreground:oklch(21.93% .0122 145.145);--card:oklch(100% 0 0);--card-foreground:oklch(21.93% .0122 145.145);--popover:oklch(100% 0 0);--popover-foreground:oklch(21.93% .0122 145.145);--primary:oklch(72.56% .0713 141.056);--primary-foreground:oklch(100% 0 0);--secondary:oklch(96.07% .0112 141.263);--secondary-foreground:oklch(44.45% .0502 141.758);--muted:oklch(96.07% .0112 141.263);--muted-foreground:oklch(53.51% .0432 142.652);--accent:oklch(96.07% .0112 141.263);--accent-foreground:oklch(72.56% .0713 141.056);--destructive:oklch(68.07% .1129 109.059);--destructive-foreground:oklch(100% 0 0);--border:oklch(91% .021 140.896);--input:oklch(91% .021 140.896);--ring:oklch(72.56% .0713 141.056);--chart-1:oklch(72.56% .0713 141.056);--chart-2:oklch(60.42% .0688 140.724);--chart-3:oklch(84.06% .0531 141.655);--chart-4:oklch(49.29% .0598 141.478);--chart-5:oklch(91% .021 140.896);--sidebar:oklch(97.77% .0078 139.442);--sidebar-foreground:oklch(21.93% .0122 145.145);--sidebar-primary:oklch(72.56% .0713 141.056);--sidebar-primary-foreground:oklch(100% 0 0);--sidebar-accent:oklch(91% .021 140.896);--sidebar-accent-foreground:oklch(72.56% .0713 141.056);--sidebar-border:oklch(91% .021 140.896);--sidebar-ring:oklch(72.56% .0713 141.056);--font-sans:Geist, ui-sans-serif, sans-serif, system-ui;--font-serif:PT Serif, ui-serif, serif;--font-mono:Inconsolata, ui-monospace, monospace;--radius:.28rem;--shadow-x:0px;--shadow-y:4px;--shadow-blur:10px;--shadow-spread:0px;--shadow-opacity:.05;--shadow-color:0 0 0;--shadow-2xs:0px 4px 10px 0px #00000008;--shadow-xs:0px 4px 10px 0px #00000008;--shadow-sm:0px 4px 10px 0px #0000000d, 0px 1px 2px -1px #0000000d;--shadow:0px 4px 10px 0px #0000000d, 0px 1px 2px -1px #0000000d;--shadow-md:0px 4px 10px 0px #0000000d, 0px 2px 4px -1px #0000000d;--shadow-lg:0px 4px 10px 0px #0000000d, 0px 4px 6px -1px #0000000d;--shadow-xl:0px 4px 10px 0px #0000000d, 0px 8px 10px -1px #0000000d;--shadow-2xl:0px 4px 10px 0px #00000021;--tracking-normal:.01em;--spacing:.3rem;--rfs-bg:var(--background);--rfs-surface:var(--card);--rfs-border:var(--border);--rfs-text:var(--foreground);--rfs-muted:var(--muted-foreground)}.dark .rfs-root,.rfs-root.dark{--background:oklch(21.93% .0122 145.145);--foreground:oklch(96.07% .0112 141.263);--card:oklch(21.93% .0122 145.145);--card-foreground:oklch(96.07% .0112 141.263);--popover:oklch(21.93% .0122 145.145);--popover-foreground:oklch(96.07% .0112 141.263);--primary:oklch(72.56% .0713 141.056);--primary-foreground:oklch(21.93% .0122 145.145);--secondary:oklch(27.44% .0184 145.053);--secondary-foreground:oklch(84.06% .0531 141.655);--muted:oklch(27.44% .0184 145.053);--muted-foreground:oklch(60.42% .0688 140.724);--accent:oklch(27.44% .0184 145.053);--accent-foreground:oklch(72.56% .0713 141.056);--destructive:oklch(88.44% .1663 107.49);--destructive-foreground:oklch(100% 0 0);--border:oklch(27.44% .0184 145.053);--input:oklch(27.44% .0184 145.053);--ring:oklch(72.56% .0713 141.056);--chart-1:oklch(72.56% .0713 141.056);--chart-2:oklch(84.06% .0531 141.655);--chart-3:oklch(60.42% .0688 140.724);--chart-4:oklch(49.29% .0598 141.478);--chart-5:oklch(35.96% .0355 143.305);--sidebar:oklch(21.93% .0122 145.145);--sidebar-foreground:oklch(96.07% .0112 141.263);--sidebar-primary:oklch(72.56% .0713 141.056);--sidebar-primary-foreground:oklch(21.93% .0122 145.145);--sidebar-accent:oklch(27.44% .0184 145.053);--sidebar-accent-foreground:oklch(72.56% .0713 141.056);--sidebar-border:oklch(27.44% .0184 145.053);--sidebar-ring:oklch(72.56% .0713 141.056);--font-sans:Geist, ui-sans-serif, sans-serif, system-ui;--font-serif:PT Serif, ui-serif, serif;--font-mono:Inconsolata, ui-monospace, monospace;--radius:.28rem;--shadow-x:0px;--shadow-y:10px;--shadow-blur:20px;--shadow-spread:0px;--shadow-opacity:.4;--shadow-color:0 0 0;--shadow-2xs:0px 10px 20px 0px #0003;--shadow-xs:0px 10px 20px 0px #0003;--shadow-sm:0px 10px 20px 0px #0006, 0px 1px 2px -1px #0006;--shadow:0px 10px 20px 0px #0006, 0px 1px 2px -1px #0006;--shadow-md:0px 10px 20px 0px #0006, 0px 2px 4px -1px #0006;--shadow-lg:0px 10px 20px 0px #0006, 0px 4px 6px -1px #0006;--shadow-xl:0px 10px 20px 0px #0006, 0px 8px 10px -1px #0006;--shadow-2xl:0px 10px 20px 0px #000;--rfs-bg:var(--background);--rfs-surface:var(--card);--rfs-border:var(--border);--rfs-text:var(--foreground);--rfs-muted:var(--muted-foreground)}.rfs-root{font-size:var(--rfs-text-sm);line-height:var(--tw-leading,var(--rfs-text-sm--line-height));color:var(--rfs-text)}.rfs-root--drag-move{cursor:grabbing;-webkit-user-select:none;user-select:none}.rfs-root--drag-resize{cursor:ns-resize;-webkit-user-select:none;user-select:none}.rfs-root.rfs-card-slot--ghost, .rfs-root .rfs-card-slot--ghost{z-index:10;pointer-events:none}.rfs-root.rfs-card-slot--dragging, .rfs-root .rfs-card-slot--dragging{z-index:30}.rfs-root.rfs-drag-overlay, .rfs-root .rfs-drag-overlay{z-index:60;pointer-events:none;position:fixed}.rfs-root.rfs-toolbar, .rfs-root .rfs-toolbar{margin-bottom:calc(var(--rfs-spacing) * 3);align-items:center;gap:calc(var(--rfs-spacing) * 2);display:flex}.rfs-root.rfs-btn, .rfs-root .rfs-btn{border-radius:calc(var(--radius) - 2px);border-style:var(--tw-border-style);padding-inline:calc(var(--rfs-spacing) * 2);padding-block:calc(var(--rfs-spacing) * 1);font-size:var(--rfs-text-xs);line-height:var(--tw-leading,var(--rfs-text-xs--line-height));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--rfs-default-transition-timing-function));transition-duration:var(--tw-duration,var(--rfs-default-transition-duration));background:var(--rfs-surface);border-width:1px}.rfs-root.rfs-btn:hover, .rfs-root .rfs-btn:hover{background:var(--rfs-bg)}.rfs-root.rfs-btn:disabled, .rfs-root .rfs-btn:disabled{cursor:not-allowed;opacity:.5}.rfs-root.rfs-date-label, .rfs-root .rfs-date-label{border-radius:calc(var(--radius) - 2px);border-style:var(--tw-border-style);padding-inline:calc(var(--rfs-spacing) * 2);padding-block:calc(var(--rfs-spacing) * 1);font-size:var(--rfs-text-xs);line-height:var(--tw-leading,var(--rfs-text-xs--line-height));--tw-font-weight:var(--rfs-font-weight-semibold);font-weight:var(--rfs-font-weight-semibold);border-width:1px;border-color:var(--rfs-border);background:var(--rfs-surface)}.rfs-root.rfs-shell, .rfs-root .rfs-shell{border-radius:var(--radius);border-style:var(--tw-border-style);background:var(--rfs-surface);border-width:1px;overflow-x:auto}.rfs-root.rfs-header, .rfs-root .rfs-header{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--rfs-border);display:flex}.rfs-root.rfs-gutter, .rfs-root .rfs-gutter{left:calc(var(--rfs-spacing) * 0);z-index:20;border-right-style:var(--tw-border-style);border-right-width:1px;border-color:var(--rfs-border);background:var(--rfs-surface);flex-shrink:0;position:sticky}.rfs-root.rfs-resource-header, .rfs-root .rfs-resource-header{border-right-style:var(--tw-border-style);padding-inline:calc(var(--rfs-spacing) * 2);padding-block:calc(var(--rfs-spacing) * 2);border-right-width:1px;border-color:var(--rfs-border)}.rfs-root.rfs-resource-subtitle, .rfs-root .rfs-resource-subtitle{margin-top:calc(var(--rfs-spacing) * 1);font-size:var(--rfs-text-xs);line-height:var(--tw-leading,var(--rfs-text-xs--line-height));color:var(--rfs-muted)}.rfs-root.rfs-body, .rfs-root .rfs-body{display:flex}.rfs-root.rfs-times, .rfs-root .rfs-times{left:calc(var(--rfs-spacing) * 0);z-index:10;border-right-style:var(--tw-border-style);border-right-width:1px;border-color:var(--rfs-border);background:var(--rfs-surface);flex-shrink:0;position:sticky;box-shadow:8px 0 12px -12px #0000002e}.rfs-root.rfs-time-tick, .rfs-root .rfs-time-tick{left:calc(var(--rfs-spacing) * 1);color:var(--rfs-muted);font-size:11px;position:absolute}.rfs-root.rfs-grid, .rfs-root .rfs-grid{flex:1;display:flex}.rfs-root.rfs-col, .rfs-root .rfs-col{border-right-style:var(--tw-border-style);border-right-width:1px;border-color:var(--rfs-border)}.rfs-root.rfs-col-inner, .rfs-root .rfs-col-inner{position:relative}.rfs-root.rfs-hour-line, .rfs-root .rfs-hour-line,.rfs-root.rfs-slot-line, .rfs-root .rfs-slot-line{right:calc(var(--rfs-spacing) * 0);left:calc(var(--rfs-spacing) * 0);border-top-style:var(--tw-border-style);--tw-border-style:dotted;border-style:dotted;border-top-width:1px;border-color:var(--rfs-border);opacity:.5;position:absolute}.rfs-root.rfs-card-slot, .rfs-root .rfs-card-slot{padding:calc(var(--rfs-spacing) * .5);position:absolute}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){.rfs-root, .rfs-root *,.rfs-root :before,.rfs-root :after,.rfs-root::backdrop, .rfs-root ::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000}}}@layer theme{.rfs-root,.rfs-root{--rfs-color-red-100:oklch(93.6% .032 17.717);--rfs-color-red-600:oklch(57.7% .245 27.325);--rfs-color-red-950:oklch(25.8% .092 26.042);--rfs-color-orange-100:oklch(95.4% .038 75.164);--rfs-color-orange-950:oklch(26.6% .079 36.259);--rfs-color-amber-100:oklch(96.2% .059 95.617);--rfs-color-amber-950:oklch(27.9% .077 45.635);--rfs-color-yellow-100:oklch(97.3% .071 103.193);--rfs-color-yellow-950:oklch(28.6% .066 53.813);--rfs-color-lime-100:oklch(96.7% .067 122.328);--rfs-color-lime-950:oklch(27.4% .072 132.109);--rfs-color-green-100:oklch(96.2% .044 156.743);--rfs-color-green-950:oklch(26.6% .065 152.934);--rfs-color-emerald-100:oklch(95% .052 163.051);--rfs-color-emerald-950:oklch(26.2% .051 172.552);--rfs-color-teal-100:oklch(95.3% .051 180.801);--rfs-color-teal-950:oklch(27.7% .046 192.524);--rfs-color-cyan-100:oklch(95.6% .045 203.388);--rfs-color-cyan-950:oklch(30.2% .056 229.695);--rfs-color-sky-100:oklch(95.1% .026 236.824);--rfs-color-sky-950:oklch(29.3% .066 243.157);--rfs-color-blue-100:oklch(93.2% .032 255.585);--rfs-color-blue-950:oklch(28.2% .091 267.935);--rfs-color-indigo-100:oklch(93% .034 272.788);--rfs-color-indigo-950:oklch(25.7% .09 281.288);--rfs-color-violet-100:oklch(94.3% .029 294.588);--rfs-color-violet-950:oklch(28.3% .141 291.089);--rfs-color-purple-100:oklch(94.6% .033 307.174);--rfs-color-purple-950:oklch(29.1% .149 302.717);--rfs-color-fuchsia-100:oklch(95.2% .037 318.852);--rfs-color-fuchsia-950:oklch(29.3% .136 325.661);--rfs-color-pink-100:oklch(94.8% .028 342.258);--rfs-color-pink-950:oklch(28.4% .109 3.907);--rfs-color-rose-100:oklch(94.1% .03 12.58);--rfs-color-rose-950:oklch(27.1% .105 12.094);--rfs-color-slate-100:oklch(96.8% .007 247.896);--rfs-color-slate-900:oklch(20.8% .042 265.755);--rfs-color-gray-100:oklch(96.7% .003 264.542);--rfs-color-gray-900:oklch(21% .034 264.665);--rfs-color-zinc-100:oklch(96.7% .001 286.375);--rfs-color-zinc-900:oklch(21% .006 285.885);--rfs-color-neutral-100:oklch(97% 0 0);--rfs-color-neutral-900:oklch(20.5% 0 0);--rfs-color-stone-100:oklch(97% .001 106.424);--rfs-color-stone-900:oklch(21.6% .006 56.043);--rfs-color-white:#fff;--rfs-spacing:.25rem;--rfs-text-xs:.75rem;--rfs-text-xs--line-height:calc(1 / .75);--rfs-text-sm:.875rem;--rfs-text-sm--line-height:calc(1.25 / .875);--rfs-font-weight-normal:400;--rfs-font-weight-medium:500;--rfs-font-weight-semibold:600;--rfs-font-weight-bold:700;--rfs-default-transition-duration:.15s;--rfs-default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--rfs-default-font-family:var(--font-sans);--rfs-default-mono-font-family:var(--font-mono)}}@layer base{.rfs-root, .rfs-root *,.rfs-root :after,.rfs-root :before,.rfs-root::backdrop, .rfs-root ::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}.rfs-root::file-selector-button, .rfs-root ::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}.rfs-root,.rfs-root{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--rfs-default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--rfs-default-font-feature-settings,normal);font-variation-settings:var(--rfs-default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}.rfs-root hr{height:0;color:inherit;border-top-width:1px}.rfs-root abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.rfs-root h1,.rfs-root h2,.rfs-root h3,.rfs-root h4,.rfs-root h5,.rfs-root h6{font-size:inherit;font-weight:inherit}.rfs-root a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}.rfs-root b,.rfs-root strong{font-weight:bolder}.rfs-root code,.rfs-root kbd,.rfs-root samp,.rfs-root pre{font-family:var(--rfs-default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--rfs-default-mono-font-feature-settings,normal);font-variation-settings:var(--rfs-default-mono-font-variation-settings,normal);font-size:1em}.rfs-root small{font-size:80%}.rfs-root sub,.rfs-root sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}.rfs-root sub{bottom:-.25em}.rfs-root sup{top:-.5em}.rfs-root table{text-indent:0;border-color:inherit;border-collapse:collapse}.rfs-root :-moz-focusring{outline:auto}.rfs-root progress{vertical-align:baseline}.rfs-root summary{display:list-item}.rfs-root ol,.rfs-root ul,.rfs-root menu{list-style:none}.rfs-root img,.rfs-root svg,.rfs-root video,.rfs-root canvas,.rfs-root audio,.rfs-root iframe,.rfs-root embed,.rfs-root object{vertical-align:middle;display:block}.rfs-root img,.rfs-root video{max-width:100%;height:auto}.rfs-root button,.rfs-root input,.rfs-root select,.rfs-root optgroup,.rfs-root textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}.rfs-root::file-selector-button, .rfs-root ::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}.rfs-root :where(select:is([multiple],[size])) optgroup{font-weight:bolder}.rfs-root :where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}.rfs-root::file-selector-button, .rfs-root ::file-selector-button{margin-inline-end:4px}.rfs-root::placeholder, .rfs-root ::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){.rfs-root::placeholder, .rfs-root ::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){.rfs-root::placeholder, .rfs-root ::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}.rfs-root textarea{resize:vertical}.rfs-root::-webkit-search-decoration, .rfs-root ::-webkit-search-decoration{-webkit-appearance:none}.rfs-root::-webkit-date-and-time-value, .rfs-root ::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}.rfs-root::-webkit-datetime-edit, .rfs-root ::-webkit-datetime-edit{display:inline-flex}.rfs-root::-webkit-datetime-edit-fields-wrapper, .rfs-root ::-webkit-datetime-edit-fields-wrapper{padding:0}.rfs-root::-webkit-datetime-edit, .rfs-root ::-webkit-datetime-edit{padding-block:0}.rfs-root::-webkit-datetime-edit-year-field, .rfs-root ::-webkit-datetime-edit-year-field{padding-block:0}.rfs-root::-webkit-datetime-edit-month-field, .rfs-root ::-webkit-datetime-edit-month-field{padding-block:0}.rfs-root::-webkit-datetime-edit-day-field, .rfs-root ::-webkit-datetime-edit-day-field{padding-block:0}.rfs-root::-webkit-datetime-edit-hour-field, .rfs-root ::-webkit-datetime-edit-hour-field{padding-block:0}.rfs-root::-webkit-datetime-edit-minute-field, .rfs-root ::-webkit-datetime-edit-minute-field{padding-block:0}.rfs-root::-webkit-datetime-edit-second-field, .rfs-root ::-webkit-datetime-edit-second-field{padding-block:0}.rfs-root::-webkit-datetime-edit-millisecond-field, .rfs-root ::-webkit-datetime-edit-millisecond-field{padding-block:0}.rfs-root::-webkit-datetime-edit-meridiem-field, .rfs-root ::-webkit-datetime-edit-meridiem-field{padding-block:0}.rfs-root::-webkit-calendar-picker-indicator, .rfs-root ::-webkit-calendar-picker-indicator{line-height:1}.rfs-root :-moz-ui-invalid{box-shadow:none}.rfs-root button,.rfs-root input:where([type=button],[type=reset],[type=submit]){appearance:button}.rfs-root::file-selector-button, .rfs-root ::file-selector-button{appearance:button}.rfs-root::-webkit-inner-spin-button, .rfs-root ::-webkit-inner-spin-button{height:auto}.rfs-root::-webkit-outer-spin-button, .rfs-root ::-webkit-outer-spin-button{height:auto}.rfs-root [hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.rfs-root.rfs\:absolute, .rfs-root .rfs\:absolute{position:absolute}.rfs-root.rfs\:relative, .rfs-root .rfs\:relative{position:relative}.rfs-root.rfs\:inset-x-1, .rfs-root .rfs\:inset-x-1{inset-inline:calc(var(--rfs-spacing) * 1)}.rfs-root.rfs\:top-1, .rfs-root .rfs\:top-1{top:calc(var(--rfs-spacing) * 1)}.rfs-root.rfs\:top-full, .rfs-root .rfs\:top-full{top:100%}.rfs-root.rfs\:right-0, .rfs-root .rfs\:right-0{right:calc(var(--rfs-spacing) * 0)}.rfs-root.rfs\:right-1, .rfs-root .rfs\:right-1{right:calc(var(--rfs-spacing) * 1)}.rfs-root.rfs\:bottom-1, .rfs-root .rfs\:bottom-1{bottom:calc(var(--rfs-spacing) * 1)}.rfs-root.rfs\:left-0, .rfs-root .rfs\:left-0{left:calc(var(--rfs-spacing) * 0)}.rfs-root.rfs\:left-1\/2, .rfs-root .rfs\:left-1\/2{left:50%}.rfs-root.rfs\:z-50, .rfs-root .rfs\:z-50{z-index:50}.rfs-root.rfs\:mt-1, .rfs-root .rfs\:mt-1{margin-top:calc(var(--rfs-spacing) * 1)}.rfs-root.rfs\:mt-2, .rfs-root .rfs\:mt-2{margin-top:calc(var(--rfs-spacing) * 2)}.rfs-root.rfs\:mb-2, .rfs-root .rfs\:mb-2{margin-bottom:calc(var(--rfs-spacing) * 2)}.rfs-root.rfs\:ml-auto, .rfs-root .rfs\:ml-auto{margin-left:auto}.rfs-root.rfs\:block, .rfs-root .rfs\:block{display:block}.rfs-root.rfs\:flex, .rfs-root .rfs\:flex{display:flex}.rfs-root.rfs\:grid, .rfs-root .rfs\:grid{display:grid}.rfs-root.rfs\:inline-flex, .rfs-root .rfs\:inline-flex{display:inline-flex}.rfs-root.rfs\:h-2, .rfs-root .rfs\:h-2{height:calc(var(--rfs-spacing) * 2)}.rfs-root.rfs\:h-4, .rfs-root .rfs\:h-4{height:calc(var(--rfs-spacing) * 4)}.rfs-root.rfs\:h-8, .rfs-root .rfs\:h-8{height:calc(var(--rfs-spacing) * 8)}.rfs-root.rfs\:h-9, .rfs-root .rfs\:h-9{height:calc(var(--rfs-spacing) * 9)}.rfs-root.rfs\:h-full, .rfs-root .rfs\:h-full{height:100%}.rfs-root.rfs\:min-h-7, .rfs-root .rfs\:min-h-7{min-height:calc(var(--rfs-spacing) * 7)}.rfs-root.rfs\:w-4, .rfs-root .rfs\:w-4{width:calc(var(--rfs-spacing) * 4)}.rfs-root.rfs\:w-8, .rfs-root .rfs\:w-8{width:calc(var(--rfs-spacing) * 8)}.rfs-root.rfs\:w-72, .rfs-root .rfs\:w-72{width:calc(var(--rfs-spacing) * 72)}.rfs-root.rfs\:w-auto, .rfs-root .rfs\:w-auto{width:auto}.rfs-root.rfs\:w-full, .rfs-root .rfs\:w-full{width:100%}.rfs-root.rfs\:min-w-40, .rfs-root .rfs\:min-w-40{min-width:calc(var(--rfs-spacing) * 40)}.rfs-root.rfs\:min-w-72, .rfs-root .rfs\:min-w-72{min-width:calc(var(--rfs-spacing) * 72)}.rfs-root.rfs\:-translate-x-1\/2, .rfs-root .rfs\:-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.rfs-root.rfs\:cursor-grab, .rfs-root .rfs\:cursor-grab{cursor:grab}.rfs-root.rfs\:cursor-grabbing, .rfs-root .rfs\:cursor-grabbing{cursor:grabbing}.rfs-root.rfs\:cursor-ns-resize, .rfs-root .rfs\:cursor-ns-resize{cursor:ns-resize}.rfs-root.rfs\:cursor-pointer, .rfs-root .rfs\:cursor-pointer{cursor:pointer}.rfs-root.rfs\:grid-cols-7, .rfs-root .rfs\:grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.rfs-root.rfs\:flex-col, .rfs-root .rfs\:flex-col{flex-direction:column}.rfs-root.rfs\:items-center, .rfs-root .rfs\:items-center{align-items:center}.rfs-root.rfs\:justify-between, .rfs-root .rfs\:justify-between{justify-content:space-between}.rfs-root.rfs\:justify-center, .rfs-root .rfs\:justify-center{justify-content:center}.rfs-root.rfs\:justify-start, .rfs-root .rfs\:justify-start{justify-content:flex-start}.rfs-root.rfs\:gap-1, .rfs-root .rfs\:gap-1{gap:calc(var(--rfs-spacing) * 1)}.rfs-root.rfs\:gap-2, .rfs-root .rfs\:gap-2{gap:calc(var(--rfs-spacing) * 2)}.rfs-root.rfs\:overflow-hidden, .rfs-root .rfs\:overflow-hidden{overflow:hidden}.rfs-root.rfs\:rounded-full, .rfs-root .rfs\:rounded-full{border-radius:3.40282e38px}.rfs-root.rfs\:rounded-lg, .rfs-root .rfs\:rounded-lg{border-radius:var(--radius)}.rfs-root.rfs\:rounded-md, .rfs-root .rfs\:rounded-md{border-radius:calc(var(--radius) - 2px)}.rfs-root.rfs\:border, .rfs-root .rfs\:border{border-style:var(--tw-border-style);border-width:1px}.rfs-root.rfs\:border-b, .rfs-root .rfs\:border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.rfs-root.rfs\:border-border, .rfs-root .rfs\:border-border,.rfs-root.rfs\:border-border\/50, .rfs-root .rfs\:border-border\/50{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:border-border\/50, .rfs-root .rfs\:border-border\/50{border-color:color-mix(in oklab, var(--border) 50%, transparent)}}.rfs-root.rfs\:border-border\/70, .rfs-root .rfs\:border-border\/70{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:border-border\/70, .rfs-root .rfs\:border-border\/70{border-color:color-mix(in oklab, var(--border) 70%, transparent)}}.rfs-root.rfs\:bg-amber-100, .rfs-root .rfs\:bg-amber-100{background-color:var(--rfs-color-amber-100)}.rfs-root.rfs\:bg-blue-100, .rfs-root .rfs\:bg-blue-100{background-color:var(--rfs-color-blue-100)}.rfs-root.rfs\:bg-border\/90, .rfs-root .rfs\:bg-border\/90{background-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:bg-border\/90, .rfs-root .rfs\:bg-border\/90{background-color:color-mix(in oklab, var(--border) 90%, transparent)}}.rfs-root.rfs\:bg-card, .rfs-root .rfs\:bg-card{background-color:var(--card)}.rfs-root.rfs\:bg-cyan-100, .rfs-root .rfs\:bg-cyan-100{background-color:var(--rfs-color-cyan-100)}.rfs-root.rfs\:bg-emerald-100, .rfs-root .rfs\:bg-emerald-100{background-color:var(--rfs-color-emerald-100)}.rfs-root.rfs\:bg-fuchsia-100, .rfs-root .rfs\:bg-fuchsia-100{background-color:var(--rfs-color-fuchsia-100)}.rfs-root.rfs\:bg-gray-100, .rfs-root .rfs\:bg-gray-100{background-color:var(--rfs-color-gray-100)}.rfs-root.rfs\:bg-green-100, .rfs-root .rfs\:bg-green-100{background-color:var(--rfs-color-green-100)}.rfs-root.rfs\:bg-indigo-100, .rfs-root .rfs\:bg-indigo-100{background-color:var(--rfs-color-indigo-100)}.rfs-root.rfs\:bg-lime-100, .rfs-root .rfs\:bg-lime-100{background-color:var(--rfs-color-lime-100)}.rfs-root.rfs\:bg-muted\/40, .rfs-root .rfs\:bg-muted\/40{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:bg-muted\/40, .rfs-root .rfs\:bg-muted\/40{background-color:color-mix(in oklab, var(--muted) 40%, transparent)}}.rfs-root.rfs\:bg-neutral-100, .rfs-root .rfs\:bg-neutral-100{background-color:var(--rfs-color-neutral-100)}.rfs-root.rfs\:bg-orange-100, .rfs-root .rfs\:bg-orange-100{background-color:var(--rfs-color-orange-100)}.rfs-root.rfs\:bg-pink-100, .rfs-root .rfs\:bg-pink-100{background-color:var(--rfs-color-pink-100)}.rfs-root.rfs\:bg-popover, .rfs-root .rfs\:bg-popover{background-color:var(--popover)}.rfs-root.rfs\:bg-primary, .rfs-root .rfs\:bg-primary{background-color:var(--primary)}.rfs-root.rfs\:bg-purple-100, .rfs-root .rfs\:bg-purple-100{background-color:var(--rfs-color-purple-100)}.rfs-root.rfs\:bg-red-100, .rfs-root .rfs\:bg-red-100,.rfs-root.rfs\:bg-red-100\/80, .rfs-root .rfs\:bg-red-100\/80{background-color:var(--rfs-color-red-100)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:bg-red-100\/80, .rfs-root .rfs\:bg-red-100\/80{background-color:color-mix(in oklab, var(--rfs-color-red-100) 80%, transparent)}}.rfs-root.rfs\:bg-red-600, .rfs-root .rfs\:bg-red-600{background-color:var(--rfs-color-red-600)}.rfs-root.rfs\:bg-rose-100, .rfs-root .rfs\:bg-rose-100{background-color:var(--rfs-color-rose-100)}.rfs-root.rfs\:bg-sky-100, .rfs-root .rfs\:bg-sky-100{background-color:var(--rfs-color-sky-100)}.rfs-root.rfs\:bg-slate-100, .rfs-root .rfs\:bg-slate-100{background-color:var(--rfs-color-slate-100)}.rfs-root.rfs\:bg-stone-100, .rfs-root .rfs\:bg-stone-100{background-color:var(--rfs-color-stone-100)}.rfs-root.rfs\:bg-teal-100, .rfs-root .rfs\:bg-teal-100{background-color:var(--rfs-color-teal-100)}.rfs-root.rfs\:bg-violet-100, .rfs-root .rfs\:bg-violet-100{background-color:var(--rfs-color-violet-100)}.rfs-root.rfs\:bg-yellow-100, .rfs-root .rfs\:bg-yellow-100{background-color:var(--rfs-color-yellow-100)}.rfs-root.rfs\:bg-zinc-100, .rfs-root .rfs\:bg-zinc-100{background-color:var(--rfs-color-zinc-100)}.rfs-root.rfs\:p-1, .rfs-root .rfs\:p-1{padding:calc(var(--rfs-spacing) * 1)}.rfs-root.rfs\:p-2, .rfs-root .rfs\:p-2{padding:calc(var(--rfs-spacing) * 2)}.rfs-root.rfs\:p-6, .rfs-root .rfs\:p-6{padding:calc(var(--rfs-spacing) * 6)}.rfs-root.rfs\:px-2, .rfs-root .rfs\:px-2{padding-inline:calc(var(--rfs-spacing) * 2)}.rfs-root.rfs\:px-3, .rfs-root .rfs\:px-3{padding-inline:calc(var(--rfs-spacing) * 3)}.rfs-root.rfs\:px-4, .rfs-root .rfs\:px-4{padding-inline:calc(var(--rfs-spacing) * 4)}.rfs-root.rfs\:py-1, .rfs-root .rfs\:py-1{padding-block:calc(var(--rfs-spacing) * 1)}.rfs-root.rfs\:py-2, .rfs-root .rfs\:py-2{padding-block:calc(var(--rfs-spacing) * 2)}.rfs-root.rfs\:pb-5, .rfs-root .rfs\:pb-5{padding-bottom:calc(var(--rfs-spacing) * 5)}.rfs-root.rfs\:text-center, .rfs-root .rfs\:text-center{text-align:center}.rfs-root.rfs\:text-left, .rfs-root .rfs\:text-left{text-align:left}.rfs-root.rfs\:text-sm, .rfs-root .rfs\:text-sm{font-size:var(--rfs-text-sm);line-height:var(--tw-leading,var(--rfs-text-sm--line-height))}.rfs-root.rfs\:text-xs, .rfs-root .rfs\:text-xs{font-size:var(--rfs-text-xs);line-height:var(--tw-leading,var(--rfs-text-xs--line-height))}.rfs-root.rfs\:text-\[10px\], .rfs-root .rfs\:text-\[10px\]{font-size:10px}.rfs-root.rfs\:font-bold, .rfs-root .rfs\:font-bold{--tw-font-weight:var(--rfs-font-weight-bold);font-weight:var(--rfs-font-weight-bold)}.rfs-root.rfs\:font-medium, .rfs-root .rfs\:font-medium{--tw-font-weight:var(--rfs-font-weight-medium);font-weight:var(--rfs-font-weight-medium)}.rfs-root.rfs\:font-normal, .rfs-root .rfs\:font-normal{--tw-font-weight:var(--rfs-font-weight-normal);font-weight:var(--rfs-font-weight-normal)}.rfs-root.rfs\:font-semibold, .rfs-root .rfs\:font-semibold{--tw-font-weight:var(--rfs-font-weight-semibold);font-weight:var(--rfs-font-weight-semibold)}.rfs-root.rfs\:whitespace-nowrap, .rfs-root .rfs\:whitespace-nowrap{white-space:nowrap}.rfs-root.rfs\:text-foreground, .rfs-root .rfs\:text-foreground{color:var(--foreground)}.rfs-root.rfs\:text-muted-foreground, .rfs-root .rfs\:text-muted-foreground,.rfs-root.rfs\:text-muted-foreground\/70, .rfs-root .rfs\:text-muted-foreground\/70{color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:text-muted-foreground\/70, .rfs-root .rfs\:text-muted-foreground\/70{color:color-mix(in oklab, var(--muted-foreground) 70%, transparent)}}.rfs-root.rfs\:text-popover-foreground, .rfs-root .rfs\:text-popover-foreground{color:var(--popover-foreground)}.rfs-root.rfs\:text-primary-foreground, .rfs-root .rfs\:text-primary-foreground{color:var(--primary-foreground)}.rfs-root.rfs\:text-red-950, .rfs-root .rfs\:text-red-950{color:var(--rfs-color-red-950)}.rfs-root.rfs\:text-white, .rfs-root .rfs\:text-white{color:var(--rfs-color-white)}.rfs-root.rfs\:tabular-nums, .rfs-root .rfs\:tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.rfs-root.rfs\:opacity-35, .rfs-root .rfs\:opacity-35{opacity:.35}.rfs-root.rfs\:opacity-55, .rfs-root .rfs\:opacity-55{opacity:.55}.rfs-root.rfs\:opacity-60, .rfs-root .rfs\:opacity-60{opacity:.6}.rfs-root.rfs\:shadow-md, .rfs-root .rfs\:shadow-md{--tw-shadow:var(--shadow-md);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.rfs-root.rfs\:shadow-xl, .rfs-root .rfs\:shadow-xl{--tw-shadow:var(--shadow-xl);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.rfs-root.rfs\:shadow-xs, .rfs-root .rfs\:shadow-xs{--tw-shadow:var(--shadow-xs);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.rfs-root.rfs\:transition-colors, .rfs-root .rfs\:transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--rfs-default-transition-timing-function));transition-duration:var(--tw-duration,var(--rfs-default-transition-duration))}.rfs-root.rfs\:outline-none, .rfs-root .rfs\:outline-none{--tw-outline-style:none;outline-style:none}@media (hover:hover){.rfs-root.rfs\:hover\:bg-border:hover, .rfs-root .rfs\:hover\:bg-border:hover{background-color:var(--border)}.rfs-root.rfs\:hover\:bg-muted:hover, .rfs-root .rfs\:hover\:bg-muted:hover{background-color:var(--muted)}.rfs-root.rfs\:hover\:bg-primary\/90:hover, .rfs-root .rfs\:hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:hover\:bg-primary\/90:hover, .rfs-root .rfs\:hover\:bg-primary\/90:hover{background-color:color-mix(in oklab, var(--primary) 90%, transparent)}}}.rfs-root.rfs\:focus-visible\:ring-2:focus-visible, .rfs-root .rfs\:focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.rfs-root.rfs\:focus-visible\:ring-ring:focus-visible, .rfs-root .rfs\:focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--ring)}.rfs-root.rfs\:focus-visible\:ring-offset-2:focus-visible, .rfs-root .rfs\:focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.rfs-root.rfs\:focus-visible\:outline-none:focus-visible, .rfs-root .rfs\:focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.rfs-root.rfs\:disabled\:pointer-events-none:disabled, .rfs-root .rfs\:disabled\:pointer-events-none:disabled{pointer-events:none}.rfs-root.rfs\:disabled\:opacity-50:disabled, .rfs-root .rfs\:disabled\:opacity-50:disabled{opacity:.5}.rfs-root.rfs\:dark\:bg-amber-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-amber-950\/40:is(.dark *){background-color:var(--rfs-color-amber-950)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-amber-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-amber-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-amber-950) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-blue-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-blue-950\/40:is(.dark *){background-color:var(--rfs-color-blue-950)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-blue-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-blue-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-blue-950) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-cyan-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-cyan-950\/40:is(.dark *){background-color:var(--rfs-color-cyan-950)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-cyan-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-cyan-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-cyan-950) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-emerald-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-emerald-950\/40:is(.dark *){background-color:var(--rfs-color-emerald-950)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-emerald-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-emerald-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-emerald-950) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-fuchsia-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-fuchsia-950\/40:is(.dark *){background-color:var(--rfs-color-fuchsia-950)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-fuchsia-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-fuchsia-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-fuchsia-950) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-gray-900\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-gray-900\/40:is(.dark *){background-color:var(--rfs-color-gray-900)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-gray-900\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-gray-900\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-gray-900) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-green-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-green-950\/40:is(.dark *){background-color:var(--rfs-color-green-950)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-green-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-green-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-green-950) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-indigo-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-indigo-950\/40:is(.dark *){background-color:var(--rfs-color-indigo-950)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-indigo-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-indigo-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-indigo-950) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-lime-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-lime-950\/40:is(.dark *){background-color:var(--rfs-color-lime-950)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-lime-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-lime-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-lime-950) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-muted\/30:is(.dark *), .rfs-root .rfs\:dark\:bg-muted\/30:is(.dark *){background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-muted\/30:is(.dark *), .rfs-root .rfs\:dark\:bg-muted\/30:is(.dark *){background-color:color-mix(in oklab, var(--muted) 30%, transparent)}}.rfs-root.rfs\:dark\:bg-neutral-900\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-neutral-900\/40:is(.dark *){background-color:var(--rfs-color-neutral-900)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-neutral-900\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-neutral-900\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-neutral-900) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-orange-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-orange-950\/40:is(.dark *){background-color:var(--rfs-color-orange-950)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-orange-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-orange-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-orange-950) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-pink-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-pink-950\/40:is(.dark *){background-color:var(--rfs-color-pink-950)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-pink-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-pink-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-pink-950) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-purple-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-purple-950\/40:is(.dark *){background-color:var(--rfs-color-purple-950)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-purple-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-purple-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-purple-950) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-red-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-red-950\/40:is(.dark *){background-color:var(--rfs-color-red-950)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-red-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-red-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-red-950) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-rose-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-rose-950\/40:is(.dark *){background-color:var(--rfs-color-rose-950)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-rose-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-rose-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-rose-950) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-sky-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-sky-950\/40:is(.dark *){background-color:var(--rfs-color-sky-950)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-sky-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-sky-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-sky-950) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-slate-900\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-slate-900\/40:is(.dark *){background-color:var(--rfs-color-slate-900)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-slate-900\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-slate-900\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-slate-900) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-stone-900\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-stone-900\/40:is(.dark *){background-color:var(--rfs-color-stone-900)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-stone-900\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-stone-900\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-stone-900) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-teal-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-teal-950\/40:is(.dark *){background-color:var(--rfs-color-teal-950)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-teal-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-teal-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-teal-950) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-violet-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-violet-950\/40:is(.dark *){background-color:var(--rfs-color-violet-950)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-violet-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-violet-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-violet-950) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-yellow-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-yellow-950\/40:is(.dark *){background-color:var(--rfs-color-yellow-950)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-yellow-950\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-yellow-950\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-yellow-950) 40%, transparent)}}.rfs-root.rfs\:dark\:bg-zinc-900\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-zinc-900\/40:is(.dark *){background-color:var(--rfs-color-zinc-900)}@supports (color:color-mix(in lab, red, red)){.rfs-root.rfs\:dark\:bg-zinc-900\/40:is(.dark *), .rfs-root .rfs\:dark\:bg-zinc-900\/40:is(.dark *){background-color:color-mix(in oklab, var(--rfs-color-zinc-900) 40%, transparent)}}.rfs-root.rfs\:dark\:text-red-100:is(.dark *), .rfs-root .rfs\:dark\:text-red-100:is(.dark *){color:var(--rfs-color-red-100)}}.rfs-root{--topbar-h:39px;--header-h:87px;--footer-h:359px;--site-content-min-h:calc(100dvh - var(--topbar-h) - var(--header-h) - var(--footer-h));--background:oklch(100% 0 0);--foreground:oklch(21.93% .0122 145.145);--card:oklch(100% 0 0);--card-foreground:oklch(21.93% .0122 145.145);--popover:oklch(100% 0 0);--popover-foreground:oklch(21.93% .0122 145.145);--primary:oklch(72.56% .0713 141.056);--primary-foreground:oklch(100% 0 0);--secondary:oklch(96.07% .0112 141.263);--secondary-foreground:oklch(44.45% .0502 141.758);--muted:oklch(96.07% .0112 141.263);--muted-foreground:oklch(53.51% .0432 142.652);--accent:oklch(96.07% .0112 141.263);--accent-foreground:oklch(72.56% .0713 141.056);--destructive:oklch(68.07% .1129 109.059);--destructive-foreground:oklch(100% 0 0);--border:oklch(91% .021 140.896);--input:oklch(91% .021 140.896);--ring:oklch(72.56% .0713 141.056);--chart-1:oklch(72.56% .0713 141.056);--chart-2:oklch(60.42% .0688 140.724);--chart-3:oklch(84.06% .0531 141.655);--chart-4:oklch(49.29% .0598 141.478);--chart-5:oklch(91% .021 140.896);--sidebar:oklch(97.77% .0078 139.442);--sidebar-foreground:oklch(21.93% .0122 145.145);--sidebar-primary:oklch(72.56% .0713 141.056);--sidebar-primary-foreground:oklch(100% 0 0);--sidebar-accent:oklch(91% .021 140.896);--sidebar-accent-foreground:oklch(72.56% .0713 141.056);--sidebar-border:oklch(91% .021 140.896);--sidebar-ring:oklch(72.56% .0713 141.056);--font-sans:Geist, ui-sans-serif, sans-serif, system-ui;--font-serif:PT Serif, ui-serif, serif;--font-mono:Inconsolata, ui-monospace, monospace;--radius:.28rem;--shadow-x:0px;--shadow-y:4px;--shadow-blur:10px;--shadow-spread:0px;--shadow-opacity:.05;--shadow-color:0 0 0;--shadow-2xs:0px 4px 10px 0px #00000008;--shadow-xs:0px 4px 10px 0px #00000008;--shadow-sm:0px 4px 10px 0px #0000000d, 0px 1px 2px -1px #0000000d;--shadow:0px 4px 10px 0px #0000000d, 0px 1px 2px -1px #0000000d;--shadow-md:0px 4px 10px 0px #0000000d, 0px 2px 4px -1px #0000000d;--shadow-lg:0px 4px 10px 0px #0000000d, 0px 4px 6px -1px #0000000d;--shadow-xl:0px 4px 10px 0px #0000000d, 0px 8px 10px -1px #0000000d;--shadow-2xl:0px 4px 10px 0px #00000021;--tracking-normal:.01em;--spacing:.3rem;--rfs-bg:var(--background);--rfs-surface:var(--card);--rfs-border:var(--border);--rfs-text:var(--foreground);--rfs-muted:var(--muted-foreground)}.dark .rfs-root,.rfs-root.dark{--background:oklch(21.93% .0122 145.145);--foreground:oklch(96.07% .0112 141.263);--card:oklch(21.93% .0122 145.145);--card-foreground:oklch(96.07% .0112 141.263);--popover:oklch(21.93% .0122 145.145);--popover-foreground:oklch(96.07% .0112 141.263);--primary:oklch(72.56% .0713 141.056);--primary-foreground:oklch(21.93% .0122 145.145);--secondary:oklch(27.44% .0184 145.053);--secondary-foreground:oklch(84.06% .0531 141.655);--muted:oklch(27.44% .0184 145.053);--muted-foreground:oklch(60.42% .0688 140.724);--accent:oklch(27.44% .0184 145.053);--accent-foreground:oklch(72.56% .0713 141.056);--destructive:oklch(88.44% .1663 107.49);--destructive-foreground:oklch(100% 0 0);--border:oklch(27.44% .0184 145.053);--input:oklch(27.44% .0184 145.053);--ring:oklch(72.56% .0713 141.056);--chart-1:oklch(72.56% .0713 141.056);--chart-2:oklch(84.06% .0531 141.655);--chart-3:oklch(60.42% .0688 140.724);--chart-4:oklch(49.29% .0598 141.478);--chart-5:oklch(35.96% .0355 143.305);--sidebar:oklch(21.93% .0122 145.145);--sidebar-foreground:oklch(96.07% .0112 141.263);--sidebar-primary:oklch(72.56% .0713 141.056);--sidebar-primary-foreground:oklch(21.93% .0122 145.145);--sidebar-accent:oklch(27.44% .0184 145.053);--sidebar-accent-foreground:oklch(72.56% .0713 141.056);--sidebar-border:oklch(27.44% .0184 145.053);--sidebar-ring:oklch(72.56% .0713 141.056);--font-sans:Geist, ui-sans-serif, sans-serif, system-ui;--font-serif:PT Serif, ui-serif, serif;--font-mono:Inconsolata, ui-monospace, monospace;--radius:.28rem;--shadow-x:0px;--shadow-y:10px;--shadow-blur:20px;--shadow-spread:0px;--shadow-opacity:.4;--shadow-color:0 0 0;--shadow-2xs:0px 10px 20px 0px #0003;--shadow-xs:0px 10px 20px 0px #0003;--shadow-sm:0px 10px 20px 0px #0006, 0px 1px 2px -1px #0006;--shadow:0px 10px 20px 0px #0006, 0px 1px 2px -1px #0006;--shadow-md:0px 10px 20px 0px #0006, 0px 2px 4px -1px #0006;--shadow-lg:0px 10px 20px 0px #0006, 0px 4px 6px -1px #0006;--shadow-xl:0px 10px 20px 0px #0006, 0px 8px 10px -1px #0006;--shadow-2xl:0px 10px 20px 0px #000;--rfs-bg:var(--background);--rfs-surface:var(--card);--rfs-border:var(--border);--rfs-text:var(--foreground);--rfs-muted:var(--muted-foreground)}.rfs-root{font-size:var(--rfs-text-sm);line-height:var(--tw-leading,var(--rfs-text-sm--line-height));color:var(--rfs-text)}.rfs-root--drag-move{cursor:grabbing;-webkit-user-select:none;user-select:none}.rfs-root--drag-resize{cursor:ns-resize;-webkit-user-select:none;user-select:none}.rfs-root.rfs-card-slot--ghost, .rfs-root .rfs-card-slot--ghost{z-index:10;pointer-events:none}.rfs-root.rfs-card-slot--dragging, .rfs-root .rfs-card-slot--dragging{z-index:30}.rfs-root.rfs-drag-overlay, .rfs-root .rfs-drag-overlay{z-index:60;pointer-events:none;position:fixed}.rfs-root.rfs-toolbar, .rfs-root .rfs-toolbar{margin-bottom:calc(var(--rfs-spacing) * 3);align-items:center;gap:calc(var(--rfs-spacing) * 2);display:flex}.rfs-root.rfs-btn, .rfs-root .rfs-btn{border-radius:calc(var(--radius) - 2px);border-style:var(--tw-border-style);padding-inline:calc(var(--rfs-spacing) * 2);padding-block:calc(var(--rfs-spacing) * 1);font-size:var(--rfs-text-xs);line-height:var(--tw-leading,var(--rfs-text-xs--line-height));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--rfs-default-transition-timing-function));transition-duration:var(--tw-duration,var(--rfs-default-transition-duration));background:var(--rfs-surface);border-width:1px}.rfs-root.rfs-btn:hover, .rfs-root .rfs-btn:hover{background:var(--rfs-bg)}.rfs-root.rfs-btn:disabled, .rfs-root .rfs-btn:disabled{cursor:not-allowed;opacity:.5}.rfs-root.rfs-date-label, .rfs-root .rfs-date-label{border-radius:calc(var(--radius) - 2px);border-style:var(--tw-border-style);padding-inline:calc(var(--rfs-spacing) * 2);padding-block:calc(var(--rfs-spacing) * 1);font-size:var(--rfs-text-xs);line-height:var(--tw-leading,var(--rfs-text-xs--line-height));--tw-font-weight:var(--rfs-font-weight-semibold);font-weight:var(--rfs-font-weight-semibold);border-width:1px;border-color:var(--rfs-border);background:var(--rfs-surface)}.rfs-root.rfs-shell, .rfs-root .rfs-shell{border-radius:var(--radius);border-style:var(--tw-border-style);background:var(--rfs-surface);border-width:1px;overflow-x:auto}.rfs-root.rfs-header, .rfs-root .rfs-header{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--rfs-border);display:flex}.rfs-root.rfs-gutter, .rfs-root .rfs-gutter{left:calc(var(--rfs-spacing) * 0);z-index:20;border-right-style:var(--tw-border-style);border-right-width:1px;border-color:var(--rfs-border);background:var(--rfs-surface);flex-shrink:0;position:sticky}.rfs-root.rfs-resource-header, .rfs-root .rfs-resource-header{border-right-style:var(--tw-border-style);padding-inline:calc(var(--rfs-spacing) * 2);padding-block:calc(var(--rfs-spacing) * 2);border-right-width:1px;border-color:var(--rfs-border)}.rfs-root.rfs-resource-subtitle, .rfs-root .rfs-resource-subtitle{margin-top:calc(var(--rfs-spacing) * 1);font-size:var(--rfs-text-xs);line-height:var(--tw-leading,var(--rfs-text-xs--line-height));color:var(--rfs-muted)}.rfs-root.rfs-body, .rfs-root .rfs-body{display:flex}.rfs-root.rfs-times, .rfs-root .rfs-times{left:calc(var(--rfs-spacing) * 0);z-index:10;border-right-style:var(--tw-border-style);border-right-width:1px;border-color:var(--rfs-border);background:var(--rfs-surface);flex-shrink:0;position:sticky;box-shadow:8px 0 12px -12px #0000002e}.rfs-root.rfs-time-tick, .rfs-root .rfs-time-tick{left:calc(var(--rfs-spacing) * 1);color:var(--rfs-muted);font-size:11px;position:absolute}.rfs-root.rfs-grid, .rfs-root .rfs-grid{flex:1;display:flex}.rfs-root.rfs-col, .rfs-root .rfs-col{border-right-style:var(--tw-border-style);border-right-width:1px;border-color:var(--rfs-border)}.rfs-root.rfs-col-inner, .rfs-root .rfs-col-inner{position:relative}.rfs-root.rfs-hour-line, .rfs-root .rfs-hour-line,.rfs-root.rfs-slot-line, .rfs-root .rfs-slot-line{right:calc(var(--rfs-spacing) * 0);left:calc(var(--rfs-spacing) * 0);border-top-style:var(--tw-border-style);--tw-border-style:dotted;border-style:dotted;border-top-width:1px;border-color:var(--rfs-border);opacity:.5;position:absolute}.rfs-root.rfs-card-slot, .rfs-root .rfs-card-slot{padding:calc(var(--rfs-spacing) * .5);position:absolute}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}
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": "4.0.0",
4
4
  "description": "A lightweight React scheduling library.",
5
5
  "keywords": [
6
6
  "react",