@marco.colia/react-fast-scheduler 3.2.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 +190 -21
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +69 -10
- package/dist/index.d.ts +69 -10
- package/dist/index.js +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -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`
|
|
@@ -105,11 +144,9 @@ export const SchedulerExample = () => {
|
|
|
105
144
|
const handleAppointmentChange = async (
|
|
106
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
|
-
id: "id",
|
|
110
149
|
resourceId: "staffId",
|
|
111
|
-
start: "start",
|
|
112
|
-
end: "end",
|
|
113
150
|
dateValue: (date) => date.toISOString(),
|
|
114
151
|
});
|
|
115
152
|
|
|
@@ -145,10 +182,7 @@ export const SchedulerExample = () => {
|
|
|
145
182
|
selectedDate={selectedDate}
|
|
146
183
|
onSelectedDateChange={setSelectedDate}
|
|
147
184
|
adapter={{
|
|
148
|
-
id: "id",
|
|
149
185
|
resourceId: "staffId",
|
|
150
|
-
start: "start",
|
|
151
|
-
end: "end",
|
|
152
186
|
title: (item) => `${item.customerName} - ${item.title}`,
|
|
153
187
|
}}
|
|
154
188
|
onAppointmentChange={handleAppointmentChange}
|
|
@@ -211,7 +245,25 @@ Appointments stay in your own shape. The scheduler reads them through the `adapt
|
|
|
211
245
|
|
|
212
246
|
### `adapter`
|
|
213
247
|
|
|
214
|
-
The
|
|
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:
|
|
215
267
|
|
|
216
268
|
```tsx
|
|
217
269
|
adapter={{
|
|
@@ -237,6 +289,8 @@ adapter={{
|
|
|
237
289
|
|
|
238
290
|
Start and end fields can resolve to either a `Date` or a date string.
|
|
239
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
|
+
|
|
240
294
|
The older getter adapter is still supported:
|
|
241
295
|
|
|
242
296
|
```tsx
|
|
@@ -284,18 +338,23 @@ Example:
|
|
|
284
338
|
/>
|
|
285
339
|
```
|
|
286
340
|
|
|
287
|
-
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:
|
|
288
342
|
|
|
289
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
|
|
290
348
|
const nextAppointments = applySchedulerAppointmentChange(appointments, change, {
|
|
291
|
-
id: "id",
|
|
292
349
|
resourceId: "staffId",
|
|
293
|
-
start: "start",
|
|
294
|
-
end: "end",
|
|
295
350
|
dateValue: (date) => date.toISOString(),
|
|
296
351
|
});
|
|
297
352
|
```
|
|
298
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
|
+
|
|
299
358
|
The previous setter-based helper options are still supported for non-object data or custom immutable updates.
|
|
300
359
|
|
|
301
360
|
`onPersistMoveResize` is still available as a legacy callback, but `onAppointmentChange` is the recommended API.
|
|
@@ -311,6 +370,95 @@ If you want to render the scheduler in read-only mode, use `editable={false}`:
|
|
|
311
370
|
|
|
312
371
|
When `editable` is `false`, move and resize interactions are disabled.
|
|
313
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
|
+
|
|
314
462
|
## Styling
|
|
315
463
|
|
|
316
464
|
The package ships precompiled CSS:
|
|
@@ -362,8 +510,25 @@ If you want semantic mapping, use `getResourceAppointmentColorToken` plus `appoi
|
|
|
362
510
|
/>
|
|
363
511
|
```
|
|
364
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
|
+
|
|
365
522
|
For full control, use `getResourceAppointmentAppearance`.
|
|
366
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
|
+
|
|
367
532
|
## Custom Rendering
|
|
368
533
|
|
|
369
534
|
### Custom appointment card
|
|
@@ -379,7 +544,7 @@ The renderer also receives:
|
|
|
379
544
|
|
|
380
545
|
- `isDropInvalid`: `true` when the current drag position overlaps another appointment
|
|
381
546
|
- `onPointerDown`: attach this to your appointment root for move interactions
|
|
382
|
-
- `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
|
|
383
548
|
|
|
384
549
|
```tsx
|
|
385
550
|
<Scheduler
|
|
@@ -415,13 +580,7 @@ The renderer also receives:
|
|
|
415
580
|
<div
|
|
416
581
|
role="button"
|
|
417
582
|
aria-label="Resize appointment"
|
|
418
|
-
onPointerDown={
|
|
419
|
-
if (appointment.visualState === "ghost") {
|
|
420
|
-
return;
|
|
421
|
-
}
|
|
422
|
-
event.stopPropagation();
|
|
423
|
-
onResizePointerDown(event);
|
|
424
|
-
}}
|
|
583
|
+
onPointerDown={onResizePointerDown}
|
|
425
584
|
className="absolute inset-x-1 bottom-1 h-2 cursor-ns-resize rounded-full bg-slate-300/90 hover:bg-slate-400"
|
|
426
585
|
/>
|
|
427
586
|
</div>
|
|
@@ -458,6 +617,8 @@ Use `renderToolbar` when you want to replace the whole header:
|
|
|
458
617
|
/>
|
|
459
618
|
```
|
|
460
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
|
+
|
|
461
622
|
### Custom date picker slot
|
|
462
623
|
|
|
463
624
|
If you want to keep the default toolbar but swap the date picker UI, use `renderDatePicker`.
|
|
@@ -481,11 +642,12 @@ If you want to keep the default toolbar but swap the date picker UI, use `render
|
|
|
481
642
|
- `appointments`: array of raw appointment objects
|
|
482
643
|
- `selectedDate`: currently visible day
|
|
483
644
|
- `onSelectedDateChange`: controlled date change handler
|
|
484
|
-
- `adapter`: key-based or getter-based 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))
|
|
485
646
|
|
|
486
647
|
### Common optional props
|
|
487
648
|
|
|
488
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)
|
|
489
651
|
- `editable`: enables or disables move and resize interactions, defaults to `true`
|
|
490
652
|
- `renderToolbar`: replace the full toolbar
|
|
491
653
|
- `renderDatePicker`: replace only the date picker slot used by the default toolbar
|
|
@@ -500,13 +662,20 @@ If you want to keep the default toolbar but swap the date picker UI, use `render
|
|
|
500
662
|
- `nextButtonLabel`: custom next button label
|
|
501
663
|
- `dayStart`: visible schedule start time, for example `"09:00"`
|
|
502
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"`
|
|
503
672
|
|
|
504
673
|
## Production Notes
|
|
505
674
|
|
|
506
675
|
- Keep `selectedDate` in application state and fetch data when it changes.
|
|
507
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.
|
|
508
677
|
- If persistence fails after a drag or resize, either roll back local state or refetch the visible day.
|
|
509
|
-
- For large schedules, keep `resources`, `appointments`, adapter
|
|
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.
|
|
510
679
|
- Import the package CSS once at app startup.
|
|
511
680
|
|
|
512
681
|
## Development
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var jsxRuntime=require('react/jsx-runtime'),dateFns=require('date-fns'),g=require('react');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var g__namespace=/*#__PURE__*/_interopNamespace(g);var ct=e=>{let{isDropInvalid:t,description:r,title:o}=e;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[t&&jsxRuntime.jsx("div",{className:"rfs:absolute rfs:right-1 rfs:top-1 rfs:flex rfs:h-4 rfs:w-4 rfs:items-center rfs:justify-center rfs:rounded-full rfs:bg-red-600 rfs:text-[10px] rfs:font-bold rfs:text-white",children:"X"}),jsxRuntime.jsx("div",{className:"rfs:text-xs rfs:font-semibold",children:o}),r&&jsxRuntime.jsx("div",{className:"rfs:mt-1 rfs:text-[10px] rfs:font-medium",children:r})]})},ge=ct;function ie({appointment:e,onResizePointerDown:t}){return jsxRuntime.jsx("div",{role:"button","aria-label":"Resize appointment",onPointerDown:r=>{e.visualState!=="ghost"&&(r.stopPropagation(),t(r));},className:"rfs:absolute rfs:inset-x-1 rfs:bottom-1 rfs:h-2 rfs:cursor-ns-resize rfs:rounded-full rfs:bg-border/90 rfs:transition-colors rfs:hover:bg-border"})}function q({appointment:e,isDropInvalid:t,onPointerDown:r,onResizePointerDown:o,appointmentAppearance:n,appointmentBackgroundColor:i}){let u=e.raw,d=typeof u.description=="string"?u.description:void 0,s=typeof i=="string"?i:void 0,c=n?.className??s??"rfs:bg-muted/40 rfs:dark:bg-muted/30",m=t?"rfs:bg-red-100/80 rfs:text-red-950 rfs:dark:bg-red-950/40 rfs:dark:text-red-100":"",f=e.visualState==="ghost"?"rfs:cursor-grab rfs:opacity-35":e.visualState==="dragging"?"rfs:cursor-grabbing rfs:opacity-55 rfs:shadow-xl":"rfs:cursor-grab",R=`rfs:relative rfs:h-full rfs:overflow-hidden rfs:rounded-md rfs:p-2 rfs:pb-5 rfs:text-foreground ${c} ${m} ${f}`;return jsxRuntime.jsxs("div",{onPointerDown:r,className:R,children:[jsxRuntime.jsx(ge,{isDropInvalid:t,title:e.title,description:d}),jsxRuntime.jsx(ie,{onResizePointerDown:o,appointment:e})]})}var F=(e,t)=>typeof t=="function"?t(e):e[t],de=e=>"getId"in e?e:{getEnd:t=>F(t,e.end),getId:t=>F(t,e.id),getResourceId:t=>F(t,e.resourceId),getStart:t=>F(t,e.start),getTitle:t=>F(t,e.title)};function Se(e){if(!e||typeof e!="object")return false;let t=e;return typeof t.firstName=="string"||typeof t.lastName=="string"}var be={slate:"bg-slate-100 dark:bg-slate-900/40",gray:"bg-gray-100 dark:bg-gray-900/40",zinc:"bg-zinc-100 dark:bg-zinc-900/40",neutral:"bg-neutral-100 dark:bg-neutral-900/40",stone:"bg-stone-100 dark:bg-stone-900/40",red:"bg-red-100 dark:bg-red-950/40",orange:"bg-orange-100 dark:bg-orange-950/40",amber:"bg-amber-100 dark:bg-amber-950/40",yellow:"bg-yellow-100 dark:bg-yellow-950/40",lime:"bg-lime-100 dark:bg-lime-950/40",green:"bg-green-100 dark:bg-green-950/40",emerald:"bg-emerald-100 dark:bg-emerald-950/40",teal:"bg-teal-100 dark:bg-teal-950/40",cyan:"bg-cyan-100 dark:bg-cyan-950/40",sky:"bg-sky-100 dark:bg-sky-950/40",blue:"bg-blue-100 dark:bg-blue-950/40",indigo:"bg-indigo-100 dark:bg-indigo-950/40",violet:"bg-violet-100 dark:bg-violet-950/40",purple:"bg-purple-100 dark:bg-purple-950/40",fuchsia:"bg-fuchsia-100 dark:bg-fuchsia-950/40",pink:"bg-pink-100 dark:bg-pink-950/40",rose:"bg-rose-100 dark:bg-rose-950/40"};function w(e,t,r){return Math.max(t,Math.min(r,e))}function V(e,t=15){return Math.round(e/t)*t}function ue(e){let[t,r]=e.split(":").map(Number);return t*60+r}function Ae(e){return `${e.firstName??""} ${e.lastName??""}`.trim()}function J(e){return dateFns.format(e,"yyyy-MM-dd")}function ce(e,t){return new Date(e.getFullYear(),e.getMonth(),e.getDate()+t)}function z(e,t,r){let o=new Date(e.getFullYear(),e.getMonth(),e.getDate(),0,0,0,0),n=t+r,i=Math.floor(n/60),u=n%60;return o.setHours(i,u,0,0),o}function ae(e,t){return t.getHours()*60+t.getMinutes()-e}function pe(e,t){return e.startMin<t.endMin&&t.startMin<e.endMin}function ye(e){let t=[...e].sort((u,d)=>u.startMin-d.startMin||u.endMin-d.endMin),r=[],o=[],n=[];for(let u of t)o=o.filter(s=>s.endMin>u.startMin),!o.some(s=>pe(s,u))&&n.length>0&&(r.push(n),n=[]),n.push(u),o.push(u);n.length&&r.push(n);let i=[];for(let u of r){let d=[...u].sort((f,R)=>f.startMin-R.startMin||f.endMin-R.endMin),s=[],c=new Map;for(let f of d){let R=false;for(let l=0;l<s.length;l++)if(s[l]<=f.startMin){s[l]=f.endMin,c.set(f.id,l),R=true;break}R||(s.push(f.endMin),c.set(f.id,s.length-1));}let m=s.length;for(let f of d)i.push({...f,lane:c.get(f.id)??0,lanes:m});}return i}function le({fallback:e,getValue:t,resources:r,toKey:o}){let n=new Map;for(let i of r)n.set(o(i),t(i)??e);return n}function Me({adapter:e,appointments:t,dayMinutes:r,dayStartAbs:o,selectedISO:n}){return t.map(i=>{let u=e.getId(i),d=new Date(e.getStart(i)),s=new Date(e.getEnd(i));return {raw:i,id:u,resourceId:e.getResourceId(i),start:d,end:s,startMin:w(ae(o,d),0,r),endMin:w(ae(o,s),0,r),title:e.getTitle(i),renderKey:String(u),visualState:"normal"}}).filter(i=>J(i.start)===n)}function ve(e){return new Map(e.map(t=>[t.id,t]))}function Pe(e,t,r,o){return t.kind==="none"||t.kind==="move"?e:e.map(n=>n.id!==t.appointmentId?n:{...n,resourceId:t.resourceId,startMin:t.startMin,endMin:t.endMin,start:z(r,o,t.startMin),end:z(r,o,t.endMin),visualState:"dragging"})}function xe(e,t){let r=new Map;for(let n of t){let i=r.get(n.resourceId)??[];i.push(n),r.set(n.resourceId,i);}let o=new Map;for(let n of e)o.set(n.id,fe(r.get(n.id)??[]));return o}function fe(e){return ye(e.map(t=>({...t,appointmentId:t.id,id:t.renderKey}))).map(({appointmentId:t,...r})=>({...r,id:t}))}function De(e,t,r,o,n){let i=new Map;for(let u of e){let d=t?.[String(u.id)];if(d){i.set(u.id,{className:d});continue}let s=r?.(u);if(s){i.set(u.id,s);continue}let c=o.get(u.id);if(c){i.set(u.id,{className:c});continue}let m=n.get(u.id);i.set(u.id,m?{className:m}:void 0);}return i}function Ne({adapter:e,appointments:t,dayEnd:r="18:00",dayStart:o="09:00",resources:n,selectedDate:i}){let u=g__namespace.useMemo(()=>ue(o),[o]),d=g__namespace.useMemo(()=>ue(r),[r]),s=g__namespace.useMemo(()=>Math.max(0,d-u),[d,u]),c=g__namespace.useMemo(()=>12+s*2+24,[s]),m=g__namespace.useMemo(()=>72+Math.max(n.length,1)*420,[n.length]),f=g__namespace.useMemo(()=>de(e),[e]),R=g__namespace.useMemo(()=>J(i),[i]),l=g__namespace.useMemo(()=>Me({adapter:f,appointments:t,dayMinutes:s,dayStartAbs:u,selectedISO:R}),[t,s,u,f,R]);return {appointmentMap:g__namespace.useMemo(()=>ve(l),[l]),dayEndAbs:d,dayMinutes:s,dayStartAbs:u,gridHeight:c,gridMinWidth:m,renderAppts:l}}var Rt=4,ht=(e,t)=>{e(r=>r&&{...r,clientX:t.clientX,clientY:t.clientY});},gt=e=>{let{dragRef:t,pendingDragRef:r,pointer:o,setDrag:n,setMovePreview:i,suppressClickRef:u}=e,d=r.current;if(!d||d.drag.pointerId!==o.pointerId)return;let s=o.clientX-d.startClientX,c=o.clientY-d.startClientY;Math.hypot(s,c)<Rt||(u.current=true,t.current=d.drag,n(d.drag),d.drag.kind==="move"&&i({appointment:d.appointment,clientX:o.clientX,clientY:o.clientY,width:d.width,height:d.height,offsetX:d.offsetX,offsetY:d.offsetY}),r.current=null);},Tt=(e,t,r,o,n)=>{let i=o(t.clientX,e.resourceId),d=n(i,t.clientY)-e.offsetMin,s=w(V(d),0,r-e.durationMin),c=s+e.durationMin;return s===e.startMin&&c===e.endMin&&i===e.resourceId?null:{...e,resourceId:i,startMin:s,endMin:c}},It=(e,t,r,o)=>{let n=o(e.resourceId,t.clientY),i=w(V(n),e.startMin+15,r);return i===e.endMin?null:{...e,endMin:i}},Be=e=>{let{dayMinutes:t,dragRef:r,latestPointerRef:o,pendingDragRef:n,pointerToMin:i,pointerToResourceId:u,setDrag:d,setMovePreview:s,suppressClickRef:c}=e,m=o.current;if(!m)return;let f=r.current;if(f.kind==="none"&&n.current){gt({pointer:m,pendingDragRef:n,setDrag:d,setMovePreview:s,dragRef:r,suppressClickRef:c});return}if(f.kind==="none")return;if(f.kind==="move"){ht(s,m);let l=Tt(f,m,t,u,i);l&&(c.current=true,r.current=l,d(l));return}let R=It(f,m,t,i);R&&(c.current=true,r.current=R,d(R));},Ee=e=>{let{dragRef:t,frameRef:r,latestPointerRef:o,pendingDragRef:n,persistDrag:i,setDrag:u,setMovePreview:d,suppressClickRef:s}=e;r.current!==null&&(window.cancelAnimationFrame(r.current),r.current=null),o.current=null,n.current=null,d(null);let c=t.current;c.kind!=="none"&&(u({kind:"none"}),t.current={kind:"none"},s.current&&i(c));};var Oe=({appointmentMap:e,dayMinutes:t,dayStartAbs:r,onAppointmentChange:o,onPersistMoveResize:n,renderAppts:i,resources:u,selectedDate:d,editable:s})=>{let[c,m]=g__namespace.useState({kind:"none"}),[f,R]=g__namespace.useState(null),l=g__namespace.useRef({}),T=g__namespace.useRef(false),x=g__namespace.useRef({kind:"none"}),b=g__namespace.useRef(null),A=g__namespace.useRef(null),y=g__namespace.useRef(null),$=g__namespace.useMemo(()=>{let p=new Map;for(let a of i){let h=p.get(a.resourceId)??[];h.push(a),p.set(a.resourceId,h);}return p},[i]);g__namespace.useEffect(()=>{x.current=c;},[c]),g__namespace.useEffect(()=>()=>{y.current!==null&&window.cancelAnimationFrame(y.current);},[]);let O=g__namespace.useCallback((p,a)=>{let h=l.current[String(p)];if(!h)return 0;let M=a-h.getBoundingClientRect().top-12;return w(V(M/2),0,t)},[t]),W=g__namespace.useCallback((p,a)=>{for(let h of u){let M=l.current[String(h.id)];if(!M)continue;let L=M.getBoundingClientRect();if(p>=L.left&&p<=L.right)return h.id}return a},[u]),D=g__namespace.useCallback((p,a,h,M)=>($.get(a)??[]).some(K=>K.id!==p&&pe(K,{startMin:h,endMin:M})),[$]),Y=g__namespace.useMemo(()=>c.kind==="none"?false:D(c.appointmentId,c.resourceId,c.startMin,c.endMin),[c,D]),X=g__namespace.useCallback(async p=>{let a=e.get(p.appointmentId);if(!a||D(p.appointmentId,p.resourceId,p.startMin,p.endMin))return;let h={resourceId:p.resourceId,start:z(d,r,p.startMin),end:z(d,r,p.endMin)};if(o){await o({kind:p.kind,appointment:a.raw,resourceId:h.resourceId,start:h.start,end:h.end,previousResourceId:a.resourceId,previousStart:a.start,previousEnd:a.end,previous:{resourceId:a.resourceId,start:a.start,end:a.end},next:h});return}n&&await n({appointment:a.raw,resourceId:h.resourceId,start:h.start,end:h.end});},[e,r,D,o,n,d]),te=g__namespace.useCallback((p,a)=>{if(!s||p.button!==0)return;p.stopPropagation(),T.current=false;let h=p.currentTarget.getBoundingClientRect(),M=O(a.resourceId,p.clientY);b.current={drag:{kind:"move",appointmentId:a.id,pointerId:p.pointerId,resourceId:a.resourceId,durationMin:Math.max(15,a.endMin-a.startMin),offsetMin:M-a.startMin,startMin:a.startMin,endMin:a.endMin},appointment:a,startClientX:p.clientX,startClientY:p.clientY,width:h.width,height:h.height,offsetX:p.clientX-h.left,offsetY:p.clientY-h.top};},[O,s]),G=g__namespace.useCallback((p,a)=>{s&&p.button===0&&(p.stopPropagation(),T.current=false,b.current={drag:{kind:"resize",appointmentId:a.id,pointerId:p.pointerId,resourceId:a.resourceId,startMin:a.startMin,endMin:a.endMin},appointment:a,startClientX:p.clientX,startClientY:p.clientY,width:0,height:0,offsetX:0,offsetY:0});},[s]),re=g__namespace.useCallback(p=>{A.current={clientX:p.clientX,clientY:p.clientY,pointerId:p.pointerId},y.current===null&&(y.current=window.requestAnimationFrame(()=>{y.current=null,Be({dayMinutes:t,dragRef:x,latestPointerRef:A,pendingDragRef:b,pointerToMin:O,pointerToResourceId:W,setDrag:m,setMovePreview:R,suppressClickRef:T});}));},[t,O,W]),S=g__namespace.useCallback(()=>{Ee({dragRef:x,frameRef:y,latestPointerRef:A,pendingDragRef:b,persistDrag:X,setDrag:m,setMovePreview:R,suppressClickRef:T});},[X]);return {colRefs:l,drag:c,isDropInvalid:Y,movePreview:f,onApptPointerDown:te,onGlobalPointerMove:re,onGlobalPointerUp:S,onResizePointerDown:G,suppressClickRef:T}};function Le({appointmentColorTokenClassMap:e,dayStartAbs:t,drag:r,getResourceAppointmentAppearance:o,getResourceAppointmentBackground:n,getResourceAppointmentColorToken:i,renderAppts:u,resourceAppointmentClassMap:d,resources:s,selectedDate:c}){let m=g__namespace.useMemo(()=>Pe(u,r,c,t),[t,r,u,c]),f=g__namespace.useMemo(()=>xe(s,u),[u,s]),R=g__namespace.useMemo(()=>{if(r.kind!=="resize")return f;let b=new Map(f),A=m.filter(y=>y.resourceId===r.resourceId);return b.set(r.resourceId,fe(A)),b},[f,r,m]),l=g__namespace.useMemo(()=>n?le({fallback:void 0,getValue:n,resources:s,toKey:b=>b.id}):new Map,[n,s]),T=g__namespace.useMemo(()=>{if(!i)return new Map;let b={...be,...e??{}};return le({fallback:void 0,getValue:A=>{let y=i(A);return y?b[y]:void 0},resources:s,toKey:A=>A.id})},[e,i,s]);return {appointmentAppearanceByResource:g__namespace.useMemo(()=>De(s,d,o,T,l),[l,T,o,d,s]),appointmentBgByResource:l,effectiveAppts:m,laidOutByResource:R}}function _e({dayMinutes:e,dayStartAbs:t,gridHeight:r}){return jsxRuntime.jsx("div",{className:"rfs-times rfs:border-border rfs:bg-card",style:{width:72,height:r},children:Array.from({length:Math.floor(e/60)+1}).map((o,n)=>jsxRuntime.jsxs("div",{className:"rfs-time-tick rfs:text-muted-foreground",style:{top:12+n*60*2},children:[String(Math.floor((t+n*60)/60)).padStart(2,"0"),":",String((t+n*60)%60).padStart(2,"0")]},`tick-${n}`))})}function ze({resource:e}){return jsxRuntime.jsx("strong",{children:e.label})}function Xe({resources:e,renderResourceHeader:t}){return jsxRuntime.jsxs("div",{className:"rfs-header rfs:border-border rfs:bg-card",children:[jsxRuntime.jsx("div",{className:"rfs-gutter rfs:border-border",style:{width:72}}),e.map(r=>jsxRuntime.jsxs("div",{className:"rfs-resource-header rfs:border-border rfs:bg-card rfs:text-foreground",style:{minWidth:420,flex:1},children:[(t??(o=>ze({resource:o})))(r),Se(r)?jsxRuntime.jsx("div",{className:"rfs-resource-subtitle rfs:text-muted-foreground",children:Ae(r)}):null]},String(r.id)))]})}var Fe=({resource:e,colRefs:t,gridHeight:r,dayMinutes:o,appointments:n,appointmentAppearance:i,appointmentBg:u,isDropInvalid:d,renderAppointment:s,onApptPointerDown:c,onResizePointerDown:m,drag:f,suppressClickRef:R})=>jsxRuntime.jsx("div",{className:"rfs-col rfs:border-border rfs:bg-card",style:{minWidth:420,flex:1},children:jsxRuntime.jsxs("div",{ref:l=>{t.current[String(e.id)]=l;},className:"rfs-col-inner rfs:bg-card",style:{height:r},children:[Array.from({length:Math.floor(o/60)+1}).map((l,T)=>jsxRuntime.jsx("div",{className:"rfs-hour-line rfs:border-border/70",style:{top:12+T*60*2}},`major-${T}`)),Array.from({length:Math.floor(o/15)+1}).map((l,T)=>jsxRuntime.jsx("div",{className:"rfs-slot-line rfs:border-border/50",style:{top:12+T*15*2}},`minor-${T}`)),n.map(l=>{let T=100/l.lanes,x=12+l.startMin*2,b=Math.max(30,(l.endMin-l.startMin)*2);return jsxRuntime.jsx("div",{className:`rfs-card-slot ${l.visualState==="ghost"?"rfs-card-slot--ghost":""} ${l.visualState==="dragging"?"rfs-card-slot--dragging":""}`,style:{top:x,left:`${T*l.lane}%`,width:`${T}%`,height:b},children:(s??q)({appointment:l,isDropInvalid:d&&f.kind==="resize"&&l.id===f.appointmentId,onPointerDown:A=>c(A,l),onResizePointerDown:A=>m(A,l),appointmentAppearance:i,appointmentBackgroundColor:u,drag:f,suppressClickRef:R})},l.renderKey)})]})});var Mt=(e,t)=>[e.resource===t.resource,e.colRefs===t.colRefs,e.gridHeight===t.gridHeight,e.dayMinutes===t.dayMinutes,e.appointments===t.appointments,e.appointmentAppearance===t.appointmentAppearance,e.appointmentBg===t.appointmentBg,e.isDropInvalid===t.isDropInvalid,e.renderAppointment===t.renderAppointment,e.onApptPointerDown===t.onApptPointerDown,e.onResizePointerDown===t.onResizePointerDown,e.drag===t.drag,e.suppressClickRef===t.suppressClickRef].every(Boolean),Ue=g__namespace.memo(Fe,Mt);function H(...e){return e.filter(Boolean).join(" ")}var vt={default:"rfs:bg-primary rfs:text-primary-foreground rfs:hover:bg-primary/90",outline:"rfs:border rfs:border-border rfs:bg-card rfs:text-foreground rfs:hover:bg-muted",ghost:"rfs:text-foreground rfs:hover:bg-muted"},Pt={default:"rfs:h-9 rfs:px-4 rfs:py-2",sm:"rfs:h-8 rfs:px-3 rfs:text-xs",icon:"rfs:h-8 rfs:w-8"},P=g__namespace.forwardRef(function({className:t,variant:r="default",size:o="default",type:n="button",...i},u){return jsxRuntime.jsx("button",{ref:u,type:n,className:H("rfs:inline-flex rfs:items-center rfs:justify-center rfs:gap-2 rfs:rounded-md rfs:text-sm rfs:font-medium rfs:whitespace-nowrap rfs:transition-colors rfs:focus-visible:outline-none rfs:focus-visible:ring-2 rfs:focus-visible:ring-ring rfs:focus-visible:ring-offset-2 rfs:disabled:pointer-events-none rfs:disabled:opacity-50",vt[r],Pt[o],t),...i})});function qe({selected:e,onSelect:t}){let[r,o]=g__namespace.useState(e??new Date);g__namespace.useEffect(()=>{e&&o(e);},[e]);let n=dateFns.startOfMonth(r),i=dateFns.startOfWeek(n,{weekStartsOn:1}),u=dateFns.endOfWeek(dateFns.endOfMonth(r),{weekStartsOn:1}),d=[];for(let s=i;s<=u;s=dateFns.addDays(s,1))d.push(s);return jsxRuntime.jsxs("div",{className:"rfs:w-72 rfs:rounded-md rfs:bg-popover",children:[jsxRuntime.jsxs("div",{className:"rfs:mb-2 rfs:flex rfs:items-center rfs:justify-between",children:[jsxRuntime.jsx(P,{variant:"ghost",size:"icon","aria-label":"Previous month",onClick:()=>o(dateFns.addMonths(r,-1)),children:"<"}),jsxRuntime.jsx("div",{className:"rfs:text-sm rfs:font-medium",children:dateFns.format(r,"MMMM yyyy")}),jsxRuntime.jsx(P,{variant:"ghost",size:"icon","aria-label":"Next month",onClick:()=>o(dateFns.addMonths(r,1)),children:">"})]}),jsxRuntime.jsx("div",{className:"rfs:grid rfs:grid-cols-7 rfs:gap-1 rfs:text-center rfs:text-xs rfs:text-muted-foreground",children:["Mo","Tu","We","Th","Fr","Sa","Su"].map(s=>jsxRuntime.jsx("div",{className:"rfs:py-1",children:s},s))}),jsxRuntime.jsx("div",{className:"rfs:grid rfs:grid-cols-7 rfs:gap-1",children:d.map(s=>{let c=e?dateFns.isSameDay(s,e):false;return jsxRuntime.jsx(P,{variant:c?"default":"ghost",size:"icon",className:H("rfs:text-xs",!dateFns.isSameMonth(s,r)&&"rfs:text-muted-foreground rfs:opacity-60",dateFns.isToday(s)&&!c&&"rfs:border rfs:border-border"),onClick:()=>t?.(s),children:dateFns.format(s,"d")},s.toISOString())})})]})}var Je=g__namespace.createContext(null);function Qe(){let e=g__namespace.useContext(Je);if(!e)throw new Error("Popover components must be used within Popover.");return e}function Ze({children:e,open:t,onOpenChange:r}){let[o,n]=g__namespace.useState(false),i=g__namespace.useRef(null),u=g__namespace.useRef(null),d=t??o,s=g__namespace.useCallback(c=>{let m=typeof c=="function"?c(d):c;t===void 0&&n(m),r?.(m);},[t,r,d]);return g__namespace.useEffect(()=>{if(!d)return;let c=f=>{let R=f.target;i.current?.contains(R)||u.current?.contains(R)||s(false);},m=f=>{f.key==="Escape"&&s(false);};return document.addEventListener("mousedown",c),document.addEventListener("keydown",m),()=>{document.removeEventListener("mousedown",c),document.removeEventListener("keydown",m);}},[d,s]),jsxRuntime.jsx(Je.Provider,{value:{open:d,setOpen:s,triggerRef:i,contentRef:u},children:jsxRuntime.jsx("div",{className:"rfs:relative rfs:inline-flex",children:e})})}function je({children:e,asChild:t=false}){let{open:r,setOpen:o,triggerRef:n}=Qe();if(t&&g__namespace.isValidElement(e)){let i=e;return g__namespace.cloneElement(i,{ref:n,"aria-expanded":r,onClick:u=>{i.props.onClick?.(u),o(d=>!d);}})}return jsxRuntime.jsx("button",{ref:n,type:"button","aria-expanded":r,onClick:()=>o(i=>!i),children:e})}function et({children:e,className:t,align:r="start"}){let{open:o,contentRef:n}=Qe();return o?jsxRuntime.jsx("div",{ref:n,className:H("rfs:absolute rfs:top-full rfs:z-50 rfs:mt-2 rfs:min-w-72 rfs:rounded-md rfs:border rfs:border-border rfs:bg-popover rfs:p-2 rfs:text-popover-foreground rfs:shadow-md rfs:outline-none",r==="start"&&"rfs:left-0",r==="center"&&"rfs:left-1/2 rfs:-translate-x-1/2",r==="end"&&"rfs:right-0",t),children:e}):null}function tt({selectedDate:e,onSelectedDateChange:t}){return jsxRuntime.jsxs(Ze,{children:[jsxRuntime.jsx(je,{asChild:true,children:jsxRuntime.jsx(P,{variant:"outline",size:"sm",className:"rfs:min-w-40 rfs:justify-start rfs:text-left rfs:font-normal",children:dateFns.format(e,"PPP")})}),jsxRuntime.jsx(et,{className:"rfs:w-auto rfs:p-2",align:"center",children:jsxRuntime.jsx(qe,{selected:e,onSelect:t})})]})}function rt({goToPreviousDay:e,goToNextDay:t,defaultDatePicker:r,prevButtonLabel:o="Prev",nextButtonLabel:n="Next"}){return jsxRuntime.jsx("div",{className:"rfs-toolbar",children:jsxRuntime.jsxs("div",{className:"rfs:flex rfs:items-center rfs:gap-2 rfs:rounded-lg rfs:border rfs:border-border rfs:bg-card rfs:p-1 rfs:shadow-xs",children:[jsxRuntime.jsx(P,{variant:"outline",size:"sm",onClick:e,children:o}),r,jsxRuntime.jsx(P,{variant:"outline",size:"sm",onClick:t,children:n})]})})}function st({selectedDate:e,onSelectedDateChange:t,prevButtonLabel:r,nextButtonLabel:o,renderToolbar:n,renderDatePicker:i}){let u=()=>t(ce(e,-1)),d=()=>t(ce(e,1)),s=(i??tt)({selectedDate:e,onSelectedDateChange:t});return n?jsxRuntime.jsx(jsxRuntime.Fragment,{children:n({selectedDate:e,onSelectedDateChange:t,goToPreviousDay:u,goToNextDay:d,defaultDatePicker:s})}):jsxRuntime.jsx(jsxRuntime.Fragment,{children:rt({goToPreviousDay:u,goToNextDay:d,defaultDatePicker:s,prevButtonLabel:r,nextButtonLabel:o})})}var Ht={kind:"none"};function Yt({resources:e,appointments:t,selectedDate:r,onSelectedDateChange:o,adapter:n,onPersistMoveResize:i,onAppointmentChange:u,renderResourceHeader:d,renderAppointment:s,resourceAppointmentClassMap:c,getResourceAppointmentAppearance:m,getResourceAppointmentColorToken:f,appointmentColorTokenClassMap:R,getResourceAppointmentBackground:l,renderToolbar:T,renderDatePicker:x,prevButtonLabel:b="Prev",nextButtonLabel:A="Next",dayStart:y="09:00",dayEnd:$="18:00",editable:O=true}){let{appointmentMap:W,dayMinutes:D,dayStartAbs:Y,gridHeight:X,gridMinWidth:te,renderAppts:G}=Ne({adapter:n,appointments:t,dayEnd:$,dayStart:y,resources:e,selectedDate:r}),{colRefs:re,drag:S,isDropInvalid:p,movePreview:a,onApptPointerDown:h,onGlobalPointerMove:M,onGlobalPointerUp:L,onResizePointerDown:K,suppressClickRef:he}=Oe({appointmentMap:W,dayMinutes:D,dayStartAbs:Y,onAppointmentChange:u,onPersistMoveResize:i,renderAppts:G,resources:e,selectedDate:r,editable:O}),{appointmentAppearanceByResource:ne,appointmentBgByResource:oe,laidOutByResource:ut}=Le({appointmentColorTokenClassMap:R,dayStartAbs:Y,drag:S,getResourceAppointmentAppearance:m,getResourceAppointmentBackground:l,getResourceAppointmentColorToken:f,renderAppts:G,resourceAppointmentClassMap:c,resources:e,selectedDate:r}),k=g__namespace.useMemo(()=>S.kind!=="move"||!a?null:{appointment:{...a.appointment,resourceId:S.resourceId,startMin:S.startMin,endMin:S.endMin,visualState:"ghost",renderKey:`${a.appointment.renderKey}-overlay`,lane:0,lanes:1},appearance:ne.get(S.resourceId),background:oe.get(S.resourceId),left:a.clientX-a.offsetX,top:a.clientY-a.offsetY,width:a.width,height:a.height},[ne,oe,S,a]);return jsxRuntime.jsxs("section",{className:`rfs-root rfs:rounded-lg rfs:text-foreground ${S.kind==="move"?"rfs-root--drag-move":""} ${S.kind==="resize"?"rfs-root--drag-resize":""}`,onPointerMove:M,onPointerUp:L,onPointerCancel:L,children:[jsxRuntime.jsx(st,{selectedDate:r,onSelectedDateChange:o,prevButtonLabel:b,nextButtonLabel:A,renderToolbar:T,renderDatePicker:x}),jsxRuntime.jsx("div",{className:"rfs-shell rfs:border-border rfs:bg-card",children:jsxRuntime.jsxs("div",{style:{minWidth:te},children:[jsxRuntime.jsx(Xe,{resources:e,renderResourceHeader:d}),jsxRuntime.jsxs("div",{className:"rfs-body",children:[jsxRuntime.jsx(_e,{dayMinutes:D,dayStartAbs:Y,gridHeight:X}),jsxRuntime.jsx("div",{className:"rfs-grid",children:e.map(_=>jsxRuntime.jsx(Ue,{resource:_,colRefs:re,gridHeight:X,dayMinutes:D,appointments:ut.get(_.id)??[],appointmentAppearance:ne.get(_.id),appointmentBg:oe.get(_.id),isDropInvalid:p,renderAppointment:s,onApptPointerDown:h,onResizePointerDown:K,drag:S.kind==="resize"&&S.resourceId===_.id?S:Ht,suppressClickRef:he},String(_.id)))})]})]})}),k?jsxRuntime.jsx("div",{className:"rfs-drag-overlay",style:{left:k.left,top:k.top,width:k.width,height:k.height},children:(s??q)({appointment:k.appointment,isDropInvalid:p,onPointerDown:()=>{},onResizePointerDown:()=>{},appointmentAppearance:k.appearance,appointmentBackgroundColor:k.background,drag:S,suppressClickRef:he})}):null]})}var dt=(e,t)=>typeof t=="function"?t(e):e[t],Xt=e=>"id"in e,Ft=e=>({resourceId:e.resourceId??e.next.resourceId,start:e.start??e.next.start,end:e.end??e.next.end}),Vt=(e,t,r)=>{let o=Ft(t);return e.map(n=>{if(Xt(r)){if(dt(n,r.id)!==dt(t.appointment,r.id))return n;let d=r.dateValue??(s=>s);return {...n,[r.resourceId]:o.resourceId,[r.start]:d(o.start),[r.end]:d(o.end)}}if(r.getId(n)!==r.getId(t.appointment))return n;let i=r.setResourceId(n,o.resourceId),u=r.setStart(i,o.start);return r.setEnd(u,o.end)})};exports.Scheduler=Yt;exports.applySchedulerAppointmentChange=Vt;exports.resolveSchedulerAppointmentAdapter=de;
|
|
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
|
@@ -18,6 +18,23 @@ type SchedulerAppointmentFieldAdapter<TAppointment, TResourceId extends string |
|
|
|
18
18
|
};
|
|
19
19
|
type SchedulerAppointmentAdapterInput<TAppointment, TResourceId extends string | number> = SchedulerAppointmentAdapter<TAppointment, TResourceId> | SchedulerAppointmentFieldAdapter<TAppointment, TResourceId>;
|
|
20
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>;
|
|
21
38
|
type BaseSchedulerResource<TId extends SchedulerId = number> = {
|
|
22
39
|
id: TId;
|
|
23
40
|
label: string;
|
|
@@ -90,19 +107,41 @@ type SchedulerAppointmentAppearance = {
|
|
|
90
107
|
};
|
|
91
108
|
type SchedulerAppointmentColorToken = string;
|
|
92
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
|
+
};
|
|
93
117
|
type SchedulerToolbarRenderArgs = {
|
|
94
118
|
selectedDate: Date;
|
|
95
119
|
onSelectedDateChange: (date: Date) => void;
|
|
96
120
|
goToPreviousDay: () => void;
|
|
97
121
|
goToNextDay: () => void;
|
|
98
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>;
|
|
99
136
|
};
|
|
100
|
-
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> = {
|
|
101
139
|
resources: TResource[];
|
|
102
140
|
appointments: TAppointment[];
|
|
103
141
|
selectedDate: Date;
|
|
104
142
|
onSelectedDateChange: (date: Date) => void;
|
|
105
|
-
|
|
143
|
+
/** Called on a plain click (not after a drag or resize). */
|
|
144
|
+
onAppointmentClick?: (appointment: TAppointment, event: React.MouseEvent<HTMLElement>) => void;
|
|
106
145
|
onPersistMoveResize?: (args: {
|
|
107
146
|
appointment: TAppointment;
|
|
108
147
|
resourceId: TResourceId;
|
|
@@ -139,11 +178,22 @@ type SchedulerProps<TAppointment, TResource extends BaseSchedulerResource<TResou
|
|
|
139
178
|
dayStart?: string;
|
|
140
179
|
dayEnd?: string;
|
|
141
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;
|
|
142
192
|
};
|
|
143
193
|
|
|
144
|
-
declare function Scheduler<TAppointment, TResource extends BaseSchedulerResource<TResourceId>, TResourceId extends SchedulerId>({ resources, appointments, selectedDate, onSelectedDateChange, adapter, onPersistMoveResize, onAppointmentChange, renderResourceHeader, renderAppointment, resourceAppointmentClassMap, getResourceAppointmentAppearance, getResourceAppointmentColorToken, appointmentColorTokenClassMap, getResourceAppointmentBackground, renderToolbar, renderDatePicker, prevButtonLabel, nextButtonLabel, dayStart, dayEnd, editable }: SchedulerProps<TAppointment, TResource, TResourceId>): react_jsx_runtime.JSX.Element;
|
|
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;
|
|
145
195
|
|
|
146
|
-
declare const resolveSchedulerAppointmentAdapter: <TAppointment, TResourceId extends string | number>(adapter
|
|
196
|
+
declare const resolveSchedulerAppointmentAdapter: <TAppointment, TResourceId extends string | number>(adapter?: SchedulerAppointmentAdapterInput<TAppointment, TResourceId> | SchedulerAppointmentAdapterOption<TAppointment, TResourceId>) => SchedulerAppointmentAdapter<TAppointment, TResourceId>;
|
|
147
197
|
|
|
148
198
|
type ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId extends SchedulerId> = {
|
|
149
199
|
getId: (appointment: TAppointment) => SchedulerId;
|
|
@@ -151,14 +201,23 @@ type ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId extends Sc
|
|
|
151
201
|
setStart: (appointment: TAppointment, start: Date) => TAppointment;
|
|
152
202
|
setEnd: (appointment: TAppointment, end: Date) => TAppointment;
|
|
153
203
|
};
|
|
154
|
-
type
|
|
204
|
+
type AppointmentKey<TAppointment> = Extract<keyof TAppointment, string | number>;
|
|
205
|
+
type ChangeFields<TAppointment> = {
|
|
155
206
|
id: SchedulerAppointmentField<TAppointment, SchedulerId>;
|
|
156
|
-
resourceId:
|
|
157
|
-
start:
|
|
158
|
-
end:
|
|
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>>> & {
|
|
159
218
|
dateValue?: (date: Date) => unknown;
|
|
160
219
|
};
|
|
161
220
|
type ApplySchedulerAppointmentChangeInput<TAppointment, TResourceId extends SchedulerId> = ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId> | ApplySchedulerAppointmentChangeFieldOptions<TAppointment>;
|
|
162
|
-
declare const applySchedulerAppointmentChange: <TAppointment, TResourceId extends SchedulerId>(appointments: TAppointment[], change: SchedulerAppointmentChangeArgs<TAppointment, TResourceId>, options: ApplySchedulerAppointmentChangeInput<TAppointment, TResourceId>) => TAppointment[];
|
|
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[];
|
|
163
222
|
|
|
164
|
-
export { type ApplySchedulerAppointmentChangeFieldOptions, type ApplySchedulerAppointmentChangeInput, type ApplySchedulerAppointmentChangeOptions, type BaseSchedulerResource, type RenderSchedulerAppt, Scheduler, type SchedulerAppointmentAdapter, type SchedulerAppointmentAdapterInput, type SchedulerAppointmentAppearance, type SchedulerAppointmentChangeArgs, type SchedulerAppointmentChangeEvent, type SchedulerAppointmentColorToken, type SchedulerAppointmentField, type SchedulerAppointmentFieldAdapter, type SchedulerAppointmentVisualState, type SchedulerDragState, type SchedulerEvent, type SchedulerId, type SchedulerPresentationAppointment, type SchedulerProps, type SchedulerResourceClassMap, type SchedulerToolbarRenderArgs, applySchedulerAppointmentChange, resolveSchedulerAppointmentAdapter };
|
|
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
|
@@ -18,6 +18,23 @@ type SchedulerAppointmentFieldAdapter<TAppointment, TResourceId extends string |
|
|
|
18
18
|
};
|
|
19
19
|
type SchedulerAppointmentAdapterInput<TAppointment, TResourceId extends string | number> = SchedulerAppointmentAdapter<TAppointment, TResourceId> | SchedulerAppointmentFieldAdapter<TAppointment, TResourceId>;
|
|
20
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>;
|
|
21
38
|
type BaseSchedulerResource<TId extends SchedulerId = number> = {
|
|
22
39
|
id: TId;
|
|
23
40
|
label: string;
|
|
@@ -90,19 +107,41 @@ type SchedulerAppointmentAppearance = {
|
|
|
90
107
|
};
|
|
91
108
|
type SchedulerAppointmentColorToken = string;
|
|
92
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
|
+
};
|
|
93
117
|
type SchedulerToolbarRenderArgs = {
|
|
94
118
|
selectedDate: Date;
|
|
95
119
|
onSelectedDateChange: (date: Date) => void;
|
|
96
120
|
goToPreviousDay: () => void;
|
|
97
121
|
goToNextDay: () => void;
|
|
98
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>;
|
|
99
136
|
};
|
|
100
|
-
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> = {
|
|
101
139
|
resources: TResource[];
|
|
102
140
|
appointments: TAppointment[];
|
|
103
141
|
selectedDate: Date;
|
|
104
142
|
onSelectedDateChange: (date: Date) => void;
|
|
105
|
-
|
|
143
|
+
/** Called on a plain click (not after a drag or resize). */
|
|
144
|
+
onAppointmentClick?: (appointment: TAppointment, event: React.MouseEvent<HTMLElement>) => void;
|
|
106
145
|
onPersistMoveResize?: (args: {
|
|
107
146
|
appointment: TAppointment;
|
|
108
147
|
resourceId: TResourceId;
|
|
@@ -139,11 +178,22 @@ type SchedulerProps<TAppointment, TResource extends BaseSchedulerResource<TResou
|
|
|
139
178
|
dayStart?: string;
|
|
140
179
|
dayEnd?: string;
|
|
141
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;
|
|
142
192
|
};
|
|
143
193
|
|
|
144
|
-
declare function Scheduler<TAppointment, TResource extends BaseSchedulerResource<TResourceId>, TResourceId extends SchedulerId>({ resources, appointments, selectedDate, onSelectedDateChange, adapter, onPersistMoveResize, onAppointmentChange, renderResourceHeader, renderAppointment, resourceAppointmentClassMap, getResourceAppointmentAppearance, getResourceAppointmentColorToken, appointmentColorTokenClassMap, getResourceAppointmentBackground, renderToolbar, renderDatePicker, prevButtonLabel, nextButtonLabel, dayStart, dayEnd, editable }: SchedulerProps<TAppointment, TResource, TResourceId>): react_jsx_runtime.JSX.Element;
|
|
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;
|
|
145
195
|
|
|
146
|
-
declare const resolveSchedulerAppointmentAdapter: <TAppointment, TResourceId extends string | number>(adapter
|
|
196
|
+
declare const resolveSchedulerAppointmentAdapter: <TAppointment, TResourceId extends string | number>(adapter?: SchedulerAppointmentAdapterInput<TAppointment, TResourceId> | SchedulerAppointmentAdapterOption<TAppointment, TResourceId>) => SchedulerAppointmentAdapter<TAppointment, TResourceId>;
|
|
147
197
|
|
|
148
198
|
type ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId extends SchedulerId> = {
|
|
149
199
|
getId: (appointment: TAppointment) => SchedulerId;
|
|
@@ -151,14 +201,23 @@ type ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId extends Sc
|
|
|
151
201
|
setStart: (appointment: TAppointment, start: Date) => TAppointment;
|
|
152
202
|
setEnd: (appointment: TAppointment, end: Date) => TAppointment;
|
|
153
203
|
};
|
|
154
|
-
type
|
|
204
|
+
type AppointmentKey<TAppointment> = Extract<keyof TAppointment, string | number>;
|
|
205
|
+
type ChangeFields<TAppointment> = {
|
|
155
206
|
id: SchedulerAppointmentField<TAppointment, SchedulerId>;
|
|
156
|
-
resourceId:
|
|
157
|
-
start:
|
|
158
|
-
end:
|
|
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>>> & {
|
|
159
218
|
dateValue?: (date: Date) => unknown;
|
|
160
219
|
};
|
|
161
220
|
type ApplySchedulerAppointmentChangeInput<TAppointment, TResourceId extends SchedulerId> = ApplySchedulerAppointmentChangeOptions<TAppointment, TResourceId> | ApplySchedulerAppointmentChangeFieldOptions<TAppointment>;
|
|
162
|
-
declare const applySchedulerAppointmentChange: <TAppointment, TResourceId extends SchedulerId>(appointments: TAppointment[], change: SchedulerAppointmentChangeArgs<TAppointment, TResourceId>, options: ApplySchedulerAppointmentChangeInput<TAppointment, TResourceId>) => TAppointment[];
|
|
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[];
|
|
163
222
|
|
|
164
|
-
export { type ApplySchedulerAppointmentChangeFieldOptions, type ApplySchedulerAppointmentChangeInput, type ApplySchedulerAppointmentChangeOptions, type BaseSchedulerResource, type RenderSchedulerAppt, Scheduler, type SchedulerAppointmentAdapter, type SchedulerAppointmentAdapterInput, type SchedulerAppointmentAppearance, type SchedulerAppointmentChangeArgs, type SchedulerAppointmentChangeEvent, type SchedulerAppointmentColorToken, type SchedulerAppointmentField, type SchedulerAppointmentFieldAdapter, type SchedulerAppointmentVisualState, type SchedulerDragState, type SchedulerEvent, type SchedulerId, type SchedulerPresentationAppointment, type SchedulerProps, type SchedulerResourceClassMap, type SchedulerToolbarRenderArgs, applySchedulerAppointmentChange, resolveSchedulerAppointmentAdapter };
|
|
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 g from'react';var ct=e=>{let{isDropInvalid:t,description:r,title:o}=e;return jsxs(Fragment,{children:[t&&jsx("div",{className:"rfs:absolute rfs:right-1 rfs:top-1 rfs:flex rfs:h-4 rfs:w-4 rfs:items-center rfs:justify-center rfs:rounded-full rfs:bg-red-600 rfs:text-[10px] rfs:font-bold rfs:text-white",children:"X"}),jsx("div",{className:"rfs:text-xs rfs:font-semibold",children:o}),r&&jsx("div",{className:"rfs:mt-1 rfs:text-[10px] rfs:font-medium",children:r})]})},ge=ct;function ie({appointment:e,onResizePointerDown:t}){return jsx("div",{role:"button","aria-label":"Resize appointment",onPointerDown:r=>{e.visualState!=="ghost"&&(r.stopPropagation(),t(r));},className:"rfs:absolute rfs:inset-x-1 rfs:bottom-1 rfs:h-2 rfs:cursor-ns-resize rfs:rounded-full rfs:bg-border/90 rfs:transition-colors rfs:hover:bg-border"})}function q({appointment:e,isDropInvalid:t,onPointerDown:r,onResizePointerDown:o,appointmentAppearance:n,appointmentBackgroundColor:i}){let u=e.raw,d=typeof u.description=="string"?u.description:void 0,s=typeof i=="string"?i:void 0,c=n?.className??s??"rfs:bg-muted/40 rfs:dark:bg-muted/30",m=t?"rfs:bg-red-100/80 rfs:text-red-950 rfs:dark:bg-red-950/40 rfs:dark:text-red-100":"",f=e.visualState==="ghost"?"rfs:cursor-grab rfs:opacity-35":e.visualState==="dragging"?"rfs:cursor-grabbing rfs:opacity-55 rfs:shadow-xl":"rfs:cursor-grab",R=`rfs:relative rfs:h-full rfs:overflow-hidden rfs:rounded-md rfs:p-2 rfs:pb-5 rfs:text-foreground ${c} ${m} ${f}`;return jsxs("div",{onPointerDown:r,className:R,children:[jsx(ge,{isDropInvalid:t,title:e.title,description:d}),jsx(ie,{onResizePointerDown:o,appointment:e})]})}var F=(e,t)=>typeof t=="function"?t(e):e[t],de=e=>"getId"in e?e:{getEnd:t=>F(t,e.end),getId:t=>F(t,e.id),getResourceId:t=>F(t,e.resourceId),getStart:t=>F(t,e.start),getTitle:t=>F(t,e.title)};function Se(e){if(!e||typeof e!="object")return false;let t=e;return typeof t.firstName=="string"||typeof t.lastName=="string"}var be={slate:"bg-slate-100 dark:bg-slate-900/40",gray:"bg-gray-100 dark:bg-gray-900/40",zinc:"bg-zinc-100 dark:bg-zinc-900/40",neutral:"bg-neutral-100 dark:bg-neutral-900/40",stone:"bg-stone-100 dark:bg-stone-900/40",red:"bg-red-100 dark:bg-red-950/40",orange:"bg-orange-100 dark:bg-orange-950/40",amber:"bg-amber-100 dark:bg-amber-950/40",yellow:"bg-yellow-100 dark:bg-yellow-950/40",lime:"bg-lime-100 dark:bg-lime-950/40",green:"bg-green-100 dark:bg-green-950/40",emerald:"bg-emerald-100 dark:bg-emerald-950/40",teal:"bg-teal-100 dark:bg-teal-950/40",cyan:"bg-cyan-100 dark:bg-cyan-950/40",sky:"bg-sky-100 dark:bg-sky-950/40",blue:"bg-blue-100 dark:bg-blue-950/40",indigo:"bg-indigo-100 dark:bg-indigo-950/40",violet:"bg-violet-100 dark:bg-violet-950/40",purple:"bg-purple-100 dark:bg-purple-950/40",fuchsia:"bg-fuchsia-100 dark:bg-fuchsia-950/40",pink:"bg-pink-100 dark:bg-pink-950/40",rose:"bg-rose-100 dark:bg-rose-950/40"};function w(e,t,r){return Math.max(t,Math.min(r,e))}function V(e,t=15){return Math.round(e/t)*t}function ue(e){let[t,r]=e.split(":").map(Number);return t*60+r}function Ae(e){return `${e.firstName??""} ${e.lastName??""}`.trim()}function J(e){return format(e,"yyyy-MM-dd")}function ce(e,t){return new Date(e.getFullYear(),e.getMonth(),e.getDate()+t)}function z(e,t,r){let o=new Date(e.getFullYear(),e.getMonth(),e.getDate(),0,0,0,0),n=t+r,i=Math.floor(n/60),u=n%60;return o.setHours(i,u,0,0),o}function ae(e,t){return t.getHours()*60+t.getMinutes()-e}function pe(e,t){return e.startMin<t.endMin&&t.startMin<e.endMin}function ye(e){let t=[...e].sort((u,d)=>u.startMin-d.startMin||u.endMin-d.endMin),r=[],o=[],n=[];for(let u of t)o=o.filter(s=>s.endMin>u.startMin),!o.some(s=>pe(s,u))&&n.length>0&&(r.push(n),n=[]),n.push(u),o.push(u);n.length&&r.push(n);let i=[];for(let u of r){let d=[...u].sort((f,R)=>f.startMin-R.startMin||f.endMin-R.endMin),s=[],c=new Map;for(let f of d){let R=false;for(let l=0;l<s.length;l++)if(s[l]<=f.startMin){s[l]=f.endMin,c.set(f.id,l),R=true;break}R||(s.push(f.endMin),c.set(f.id,s.length-1));}let m=s.length;for(let f of d)i.push({...f,lane:c.get(f.id)??0,lanes:m});}return i}function le({fallback:e,getValue:t,resources:r,toKey:o}){let n=new Map;for(let i of r)n.set(o(i),t(i)??e);return n}function Me({adapter:e,appointments:t,dayMinutes:r,dayStartAbs:o,selectedISO:n}){return t.map(i=>{let u=e.getId(i),d=new Date(e.getStart(i)),s=new Date(e.getEnd(i));return {raw:i,id:u,resourceId:e.getResourceId(i),start:d,end:s,startMin:w(ae(o,d),0,r),endMin:w(ae(o,s),0,r),title:e.getTitle(i),renderKey:String(u),visualState:"normal"}}).filter(i=>J(i.start)===n)}function ve(e){return new Map(e.map(t=>[t.id,t]))}function Pe(e,t,r,o){return t.kind==="none"||t.kind==="move"?e:e.map(n=>n.id!==t.appointmentId?n:{...n,resourceId:t.resourceId,startMin:t.startMin,endMin:t.endMin,start:z(r,o,t.startMin),end:z(r,o,t.endMin),visualState:"dragging"})}function xe(e,t){let r=new Map;for(let n of t){let i=r.get(n.resourceId)??[];i.push(n),r.set(n.resourceId,i);}let o=new Map;for(let n of e)o.set(n.id,fe(r.get(n.id)??[]));return o}function fe(e){return ye(e.map(t=>({...t,appointmentId:t.id,id:t.renderKey}))).map(({appointmentId:t,...r})=>({...r,id:t}))}function De(e,t,r,o,n){let i=new Map;for(let u of e){let d=t?.[String(u.id)];if(d){i.set(u.id,{className:d});continue}let s=r?.(u);if(s){i.set(u.id,s);continue}let c=o.get(u.id);if(c){i.set(u.id,{className:c});continue}let m=n.get(u.id);i.set(u.id,m?{className:m}:void 0);}return i}function Ne({adapter:e,appointments:t,dayEnd:r="18:00",dayStart:o="09:00",resources:n,selectedDate:i}){let u=g.useMemo(()=>ue(o),[o]),d=g.useMemo(()=>ue(r),[r]),s=g.useMemo(()=>Math.max(0,d-u),[d,u]),c=g.useMemo(()=>12+s*2+24,[s]),m=g.useMemo(()=>72+Math.max(n.length,1)*420,[n.length]),f=g.useMemo(()=>de(e),[e]),R=g.useMemo(()=>J(i),[i]),l=g.useMemo(()=>Me({adapter:f,appointments:t,dayMinutes:s,dayStartAbs:u,selectedISO:R}),[t,s,u,f,R]);return {appointmentMap:g.useMemo(()=>ve(l),[l]),dayEndAbs:d,dayMinutes:s,dayStartAbs:u,gridHeight:c,gridMinWidth:m,renderAppts:l}}var Rt=4,ht=(e,t)=>{e(r=>r&&{...r,clientX:t.clientX,clientY:t.clientY});},gt=e=>{let{dragRef:t,pendingDragRef:r,pointer:o,setDrag:n,setMovePreview:i,suppressClickRef:u}=e,d=r.current;if(!d||d.drag.pointerId!==o.pointerId)return;let s=o.clientX-d.startClientX,c=o.clientY-d.startClientY;Math.hypot(s,c)<Rt||(u.current=true,t.current=d.drag,n(d.drag),d.drag.kind==="move"&&i({appointment:d.appointment,clientX:o.clientX,clientY:o.clientY,width:d.width,height:d.height,offsetX:d.offsetX,offsetY:d.offsetY}),r.current=null);},Tt=(e,t,r,o,n)=>{let i=o(t.clientX,e.resourceId),d=n(i,t.clientY)-e.offsetMin,s=w(V(d),0,r-e.durationMin),c=s+e.durationMin;return s===e.startMin&&c===e.endMin&&i===e.resourceId?null:{...e,resourceId:i,startMin:s,endMin:c}},It=(e,t,r,o)=>{let n=o(e.resourceId,t.clientY),i=w(V(n),e.startMin+15,r);return i===e.endMin?null:{...e,endMin:i}},Be=e=>{let{dayMinutes:t,dragRef:r,latestPointerRef:o,pendingDragRef:n,pointerToMin:i,pointerToResourceId:u,setDrag:d,setMovePreview:s,suppressClickRef:c}=e,m=o.current;if(!m)return;let f=r.current;if(f.kind==="none"&&n.current){gt({pointer:m,pendingDragRef:n,setDrag:d,setMovePreview:s,dragRef:r,suppressClickRef:c});return}if(f.kind==="none")return;if(f.kind==="move"){ht(s,m);let l=Tt(f,m,t,u,i);l&&(c.current=true,r.current=l,d(l));return}let R=It(f,m,t,i);R&&(c.current=true,r.current=R,d(R));},Ee=e=>{let{dragRef:t,frameRef:r,latestPointerRef:o,pendingDragRef:n,persistDrag:i,setDrag:u,setMovePreview:d,suppressClickRef:s}=e;r.current!==null&&(window.cancelAnimationFrame(r.current),r.current=null),o.current=null,n.current=null,d(null);let c=t.current;c.kind!=="none"&&(u({kind:"none"}),t.current={kind:"none"},s.current&&i(c));};var Oe=({appointmentMap:e,dayMinutes:t,dayStartAbs:r,onAppointmentChange:o,onPersistMoveResize:n,renderAppts:i,resources:u,selectedDate:d,editable:s})=>{let[c,m]=g.useState({kind:"none"}),[f,R]=g.useState(null),l=g.useRef({}),T=g.useRef(false),x=g.useRef({kind:"none"}),b=g.useRef(null),A=g.useRef(null),y=g.useRef(null),$=g.useMemo(()=>{let p=new Map;for(let a of i){let h=p.get(a.resourceId)??[];h.push(a),p.set(a.resourceId,h);}return p},[i]);g.useEffect(()=>{x.current=c;},[c]),g.useEffect(()=>()=>{y.current!==null&&window.cancelAnimationFrame(y.current);},[]);let O=g.useCallback((p,a)=>{let h=l.current[String(p)];if(!h)return 0;let M=a-h.getBoundingClientRect().top-12;return w(V(M/2),0,t)},[t]),W=g.useCallback((p,a)=>{for(let h of u){let M=l.current[String(h.id)];if(!M)continue;let L=M.getBoundingClientRect();if(p>=L.left&&p<=L.right)return h.id}return a},[u]),D=g.useCallback((p,a,h,M)=>($.get(a)??[]).some(K=>K.id!==p&&pe(K,{startMin:h,endMin:M})),[$]),Y=g.useMemo(()=>c.kind==="none"?false:D(c.appointmentId,c.resourceId,c.startMin,c.endMin),[c,D]),X=g.useCallback(async p=>{let a=e.get(p.appointmentId);if(!a||D(p.appointmentId,p.resourceId,p.startMin,p.endMin))return;let h={resourceId:p.resourceId,start:z(d,r,p.startMin),end:z(d,r,p.endMin)};if(o){await o({kind:p.kind,appointment:a.raw,resourceId:h.resourceId,start:h.start,end:h.end,previousResourceId:a.resourceId,previousStart:a.start,previousEnd:a.end,previous:{resourceId:a.resourceId,start:a.start,end:a.end},next:h});return}n&&await n({appointment:a.raw,resourceId:h.resourceId,start:h.start,end:h.end});},[e,r,D,o,n,d]),te=g.useCallback((p,a)=>{if(!s||p.button!==0)return;p.stopPropagation(),T.current=false;let h=p.currentTarget.getBoundingClientRect(),M=O(a.resourceId,p.clientY);b.current={drag:{kind:"move",appointmentId:a.id,pointerId:p.pointerId,resourceId:a.resourceId,durationMin:Math.max(15,a.endMin-a.startMin),offsetMin:M-a.startMin,startMin:a.startMin,endMin:a.endMin},appointment:a,startClientX:p.clientX,startClientY:p.clientY,width:h.width,height:h.height,offsetX:p.clientX-h.left,offsetY:p.clientY-h.top};},[O,s]),G=g.useCallback((p,a)=>{s&&p.button===0&&(p.stopPropagation(),T.current=false,b.current={drag:{kind:"resize",appointmentId:a.id,pointerId:p.pointerId,resourceId:a.resourceId,startMin:a.startMin,endMin:a.endMin},appointment:a,startClientX:p.clientX,startClientY:p.clientY,width:0,height:0,offsetX:0,offsetY:0});},[s]),re=g.useCallback(p=>{A.current={clientX:p.clientX,clientY:p.clientY,pointerId:p.pointerId},y.current===null&&(y.current=window.requestAnimationFrame(()=>{y.current=null,Be({dayMinutes:t,dragRef:x,latestPointerRef:A,pendingDragRef:b,pointerToMin:O,pointerToResourceId:W,setDrag:m,setMovePreview:R,suppressClickRef:T});}));},[t,O,W]),S=g.useCallback(()=>{Ee({dragRef:x,frameRef:y,latestPointerRef:A,pendingDragRef:b,persistDrag:X,setDrag:m,setMovePreview:R,suppressClickRef:T});},[X]);return {colRefs:l,drag:c,isDropInvalid:Y,movePreview:f,onApptPointerDown:te,onGlobalPointerMove:re,onGlobalPointerUp:S,onResizePointerDown:G,suppressClickRef:T}};function Le({appointmentColorTokenClassMap:e,dayStartAbs:t,drag:r,getResourceAppointmentAppearance:o,getResourceAppointmentBackground:n,getResourceAppointmentColorToken:i,renderAppts:u,resourceAppointmentClassMap:d,resources:s,selectedDate:c}){let m=g.useMemo(()=>Pe(u,r,c,t),[t,r,u,c]),f=g.useMemo(()=>xe(s,u),[u,s]),R=g.useMemo(()=>{if(r.kind!=="resize")return f;let b=new Map(f),A=m.filter(y=>y.resourceId===r.resourceId);return b.set(r.resourceId,fe(A)),b},[f,r,m]),l=g.useMemo(()=>n?le({fallback:void 0,getValue:n,resources:s,toKey:b=>b.id}):new Map,[n,s]),T=g.useMemo(()=>{if(!i)return new Map;let b={...be,...e??{}};return le({fallback:void 0,getValue:A=>{let y=i(A);return y?b[y]:void 0},resources:s,toKey:A=>A.id})},[e,i,s]);return {appointmentAppearanceByResource:g.useMemo(()=>De(s,d,o,T,l),[l,T,o,d,s]),appointmentBgByResource:l,effectiveAppts:m,laidOutByResource:R}}function _e({dayMinutes:e,dayStartAbs:t,gridHeight:r}){return jsx("div",{className:"rfs-times rfs:border-border rfs:bg-card",style:{width:72,height:r},children:Array.from({length:Math.floor(e/60)+1}).map((o,n)=>jsxs("div",{className:"rfs-time-tick rfs:text-muted-foreground",style:{top:12+n*60*2},children:[String(Math.floor((t+n*60)/60)).padStart(2,"0"),":",String((t+n*60)%60).padStart(2,"0")]},`tick-${n}`))})}function ze({resource:e}){return jsx("strong",{children:e.label})}function Xe({resources:e,renderResourceHeader:t}){return jsxs("div",{className:"rfs-header rfs:border-border rfs:bg-card",children:[jsx("div",{className:"rfs-gutter rfs:border-border",style:{width:72}}),e.map(r=>jsxs("div",{className:"rfs-resource-header rfs:border-border rfs:bg-card rfs:text-foreground",style:{minWidth:420,flex:1},children:[(t??(o=>ze({resource:o})))(r),Se(r)?jsx("div",{className:"rfs-resource-subtitle rfs:text-muted-foreground",children:Ae(r)}):null]},String(r.id)))]})}var Fe=({resource:e,colRefs:t,gridHeight:r,dayMinutes:o,appointments:n,appointmentAppearance:i,appointmentBg:u,isDropInvalid:d,renderAppointment:s,onApptPointerDown:c,onResizePointerDown:m,drag:f,suppressClickRef:R})=>jsx("div",{className:"rfs-col rfs:border-border rfs:bg-card",style:{minWidth:420,flex:1},children:jsxs("div",{ref:l=>{t.current[String(e.id)]=l;},className:"rfs-col-inner rfs:bg-card",style:{height:r},children:[Array.from({length:Math.floor(o/60)+1}).map((l,T)=>jsx("div",{className:"rfs-hour-line rfs:border-border/70",style:{top:12+T*60*2}},`major-${T}`)),Array.from({length:Math.floor(o/15)+1}).map((l,T)=>jsx("div",{className:"rfs-slot-line rfs:border-border/50",style:{top:12+T*15*2}},`minor-${T}`)),n.map(l=>{let T=100/l.lanes,x=12+l.startMin*2,b=Math.max(30,(l.endMin-l.startMin)*2);return jsx("div",{className:`rfs-card-slot ${l.visualState==="ghost"?"rfs-card-slot--ghost":""} ${l.visualState==="dragging"?"rfs-card-slot--dragging":""}`,style:{top:x,left:`${T*l.lane}%`,width:`${T}%`,height:b},children:(s??q)({appointment:l,isDropInvalid:d&&f.kind==="resize"&&l.id===f.appointmentId,onPointerDown:A=>c(A,l),onResizePointerDown:A=>m(A,l),appointmentAppearance:i,appointmentBackgroundColor:u,drag:f,suppressClickRef:R})},l.renderKey)})]})});var Mt=(e,t)=>[e.resource===t.resource,e.colRefs===t.colRefs,e.gridHeight===t.gridHeight,e.dayMinutes===t.dayMinutes,e.appointments===t.appointments,e.appointmentAppearance===t.appointmentAppearance,e.appointmentBg===t.appointmentBg,e.isDropInvalid===t.isDropInvalid,e.renderAppointment===t.renderAppointment,e.onApptPointerDown===t.onApptPointerDown,e.onResizePointerDown===t.onResizePointerDown,e.drag===t.drag,e.suppressClickRef===t.suppressClickRef].every(Boolean),Ue=g.memo(Fe,Mt);function H(...e){return e.filter(Boolean).join(" ")}var vt={default:"rfs:bg-primary rfs:text-primary-foreground rfs:hover:bg-primary/90",outline:"rfs:border rfs:border-border rfs:bg-card rfs:text-foreground rfs:hover:bg-muted",ghost:"rfs:text-foreground rfs:hover:bg-muted"},Pt={default:"rfs:h-9 rfs:px-4 rfs:py-2",sm:"rfs:h-8 rfs:px-3 rfs:text-xs",icon:"rfs:h-8 rfs:w-8"},P=g.forwardRef(function({className:t,variant:r="default",size:o="default",type:n="button",...i},u){return jsx("button",{ref:u,type:n,className:H("rfs:inline-flex rfs:items-center rfs:justify-center rfs:gap-2 rfs:rounded-md rfs:text-sm rfs:font-medium rfs:whitespace-nowrap rfs:transition-colors rfs:focus-visible:outline-none rfs:focus-visible:ring-2 rfs:focus-visible:ring-ring rfs:focus-visible:ring-offset-2 rfs:disabled:pointer-events-none rfs:disabled:opacity-50",vt[r],Pt[o],t),...i})});function qe({selected:e,onSelect:t}){let[r,o]=g.useState(e??new Date);g.useEffect(()=>{e&&o(e);},[e]);let n=startOfMonth(r),i=startOfWeek(n,{weekStartsOn:1}),u=endOfWeek(endOfMonth(r),{weekStartsOn:1}),d=[];for(let s=i;s<=u;s=addDays(s,1))d.push(s);return jsxs("div",{className:"rfs:w-72 rfs:rounded-md rfs:bg-popover",children:[jsxs("div",{className:"rfs:mb-2 rfs:flex rfs:items-center rfs:justify-between",children:[jsx(P,{variant:"ghost",size:"icon","aria-label":"Previous month",onClick:()=>o(addMonths(r,-1)),children:"<"}),jsx("div",{className:"rfs:text-sm rfs:font-medium",children:format(r,"MMMM yyyy")}),jsx(P,{variant:"ghost",size:"icon","aria-label":"Next month",onClick:()=>o(addMonths(r,1)),children:">"})]}),jsx("div",{className:"rfs:grid rfs:grid-cols-7 rfs:gap-1 rfs:text-center rfs:text-xs rfs:text-muted-foreground",children:["Mo","Tu","We","Th","Fr","Sa","Su"].map(s=>jsx("div",{className:"rfs:py-1",children:s},s))}),jsx("div",{className:"rfs:grid rfs:grid-cols-7 rfs:gap-1",children:d.map(s=>{let c=e?isSameDay(s,e):false;return jsx(P,{variant:c?"default":"ghost",size:"icon",className:H("rfs:text-xs",!isSameMonth(s,r)&&"rfs:text-muted-foreground rfs:opacity-60",isToday(s)&&!c&&"rfs:border rfs:border-border"),onClick:()=>t?.(s),children:format(s,"d")},s.toISOString())})})]})}var Je=g.createContext(null);function Qe(){let e=g.useContext(Je);if(!e)throw new Error("Popover components must be used within Popover.");return e}function Ze({children:e,open:t,onOpenChange:r}){let[o,n]=g.useState(false),i=g.useRef(null),u=g.useRef(null),d=t??o,s=g.useCallback(c=>{let m=typeof c=="function"?c(d):c;t===void 0&&n(m),r?.(m);},[t,r,d]);return g.useEffect(()=>{if(!d)return;let c=f=>{let R=f.target;i.current?.contains(R)||u.current?.contains(R)||s(false);},m=f=>{f.key==="Escape"&&s(false);};return document.addEventListener("mousedown",c),document.addEventListener("keydown",m),()=>{document.removeEventListener("mousedown",c),document.removeEventListener("keydown",m);}},[d,s]),jsx(Je.Provider,{value:{open:d,setOpen:s,triggerRef:i,contentRef:u},children:jsx("div",{className:"rfs:relative rfs:inline-flex",children:e})})}function je({children:e,asChild:t=false}){let{open:r,setOpen:o,triggerRef:n}=Qe();if(t&&g.isValidElement(e)){let i=e;return g.cloneElement(i,{ref:n,"aria-expanded":r,onClick:u=>{i.props.onClick?.(u),o(d=>!d);}})}return jsx("button",{ref:n,type:"button","aria-expanded":r,onClick:()=>o(i=>!i),children:e})}function et({children:e,className:t,align:r="start"}){let{open:o,contentRef:n}=Qe();return o?jsx("div",{ref:n,className:H("rfs:absolute rfs:top-full rfs:z-50 rfs:mt-2 rfs:min-w-72 rfs:rounded-md rfs:border rfs:border-border rfs:bg-popover rfs:p-2 rfs:text-popover-foreground rfs:shadow-md rfs:outline-none",r==="start"&&"rfs:left-0",r==="center"&&"rfs:left-1/2 rfs:-translate-x-1/2",r==="end"&&"rfs:right-0",t),children:e}):null}function tt({selectedDate:e,onSelectedDateChange:t}){return jsxs(Ze,{children:[jsx(je,{asChild:true,children:jsx(P,{variant:"outline",size:"sm",className:"rfs:min-w-40 rfs:justify-start rfs:text-left rfs:font-normal",children:format(e,"PPP")})}),jsx(et,{className:"rfs:w-auto rfs:p-2",align:"center",children:jsx(qe,{selected:e,onSelect:t})})]})}function rt({goToPreviousDay:e,goToNextDay:t,defaultDatePicker:r,prevButtonLabel:o="Prev",nextButtonLabel:n="Next"}){return jsx("div",{className:"rfs-toolbar",children:jsxs("div",{className:"rfs:flex rfs:items-center rfs:gap-2 rfs:rounded-lg rfs:border rfs:border-border rfs:bg-card rfs:p-1 rfs:shadow-xs",children:[jsx(P,{variant:"outline",size:"sm",onClick:e,children:o}),r,jsx(P,{variant:"outline",size:"sm",onClick:t,children:n})]})})}function st({selectedDate:e,onSelectedDateChange:t,prevButtonLabel:r,nextButtonLabel:o,renderToolbar:n,renderDatePicker:i}){let u=()=>t(ce(e,-1)),d=()=>t(ce(e,1)),s=(i??tt)({selectedDate:e,onSelectedDateChange:t});return n?jsx(Fragment,{children:n({selectedDate:e,onSelectedDateChange:t,goToPreviousDay:u,goToNextDay:d,defaultDatePicker:s})}):jsx(Fragment,{children:rt({goToPreviousDay:u,goToNextDay:d,defaultDatePicker:s,prevButtonLabel:r,nextButtonLabel:o})})}var Ht={kind:"none"};function Yt({resources:e,appointments:t,selectedDate:r,onSelectedDateChange:o,adapter:n,onPersistMoveResize:i,onAppointmentChange:u,renderResourceHeader:d,renderAppointment:s,resourceAppointmentClassMap:c,getResourceAppointmentAppearance:m,getResourceAppointmentColorToken:f,appointmentColorTokenClassMap:R,getResourceAppointmentBackground:l,renderToolbar:T,renderDatePicker:x,prevButtonLabel:b="Prev",nextButtonLabel:A="Next",dayStart:y="09:00",dayEnd:$="18:00",editable:O=true}){let{appointmentMap:W,dayMinutes:D,dayStartAbs:Y,gridHeight:X,gridMinWidth:te,renderAppts:G}=Ne({adapter:n,appointments:t,dayEnd:$,dayStart:y,resources:e,selectedDate:r}),{colRefs:re,drag:S,isDropInvalid:p,movePreview:a,onApptPointerDown:h,onGlobalPointerMove:M,onGlobalPointerUp:L,onResizePointerDown:K,suppressClickRef:he}=Oe({appointmentMap:W,dayMinutes:D,dayStartAbs:Y,onAppointmentChange:u,onPersistMoveResize:i,renderAppts:G,resources:e,selectedDate:r,editable:O}),{appointmentAppearanceByResource:ne,appointmentBgByResource:oe,laidOutByResource:ut}=Le({appointmentColorTokenClassMap:R,dayStartAbs:Y,drag:S,getResourceAppointmentAppearance:m,getResourceAppointmentBackground:l,getResourceAppointmentColorToken:f,renderAppts:G,resourceAppointmentClassMap:c,resources:e,selectedDate:r}),k=g.useMemo(()=>S.kind!=="move"||!a?null:{appointment:{...a.appointment,resourceId:S.resourceId,startMin:S.startMin,endMin:S.endMin,visualState:"ghost",renderKey:`${a.appointment.renderKey}-overlay`,lane:0,lanes:1},appearance:ne.get(S.resourceId),background:oe.get(S.resourceId),left:a.clientX-a.offsetX,top:a.clientY-a.offsetY,width:a.width,height:a.height},[ne,oe,S,a]);return jsxs("section",{className:`rfs-root rfs:rounded-lg rfs:text-foreground ${S.kind==="move"?"rfs-root--drag-move":""} ${S.kind==="resize"?"rfs-root--drag-resize":""}`,onPointerMove:M,onPointerUp:L,onPointerCancel:L,children:[jsx(st,{selectedDate:r,onSelectedDateChange:o,prevButtonLabel:b,nextButtonLabel:A,renderToolbar:T,renderDatePicker:x}),jsx("div",{className:"rfs-shell rfs:border-border rfs:bg-card",children:jsxs("div",{style:{minWidth:te},children:[jsx(Xe,{resources:e,renderResourceHeader:d}),jsxs("div",{className:"rfs-body",children:[jsx(_e,{dayMinutes:D,dayStartAbs:Y,gridHeight:X}),jsx("div",{className:"rfs-grid",children:e.map(_=>jsx(Ue,{resource:_,colRefs:re,gridHeight:X,dayMinutes:D,appointments:ut.get(_.id)??[],appointmentAppearance:ne.get(_.id),appointmentBg:oe.get(_.id),isDropInvalid:p,renderAppointment:s,onApptPointerDown:h,onResizePointerDown:K,drag:S.kind==="resize"&&S.resourceId===_.id?S:Ht,suppressClickRef:he},String(_.id)))})]})]})}),k?jsx("div",{className:"rfs-drag-overlay",style:{left:k.left,top:k.top,width:k.width,height:k.height},children:(s??q)({appointment:k.appointment,isDropInvalid:p,onPointerDown:()=>{},onResizePointerDown:()=>{},appointmentAppearance:k.appearance,appointmentBackgroundColor:k.background,drag:S,suppressClickRef:he})}):null]})}var dt=(e,t)=>typeof t=="function"?t(e):e[t],Xt=e=>"id"in e,Ft=e=>({resourceId:e.resourceId??e.next.resourceId,start:e.start??e.next.start,end:e.end??e.next.end}),Vt=(e,t,r)=>{let o=Ft(t);return e.map(n=>{if(Xt(r)){if(dt(n,r.id)!==dt(t.appointment,r.id))return n;let d=r.dateValue??(s=>s);return {...n,[r.resourceId]:o.resourceId,[r.start]:d(o.start),[r.end]:d(o.end)}}if(r.getId(n)!==r.getId(t.appointment))return n;let i=r.setResourceId(n,o.resourceId),u=r.setStart(i,o.start);return r.setEnd(u,o.end)})};export{Yt as Scheduler,Vt as applySchedulerAppointmentChange,de as resolveSchedulerAppointmentAdapter};
|
|
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}
|