@marco.colia/react-fast-scheduler 1.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/LICENSE +22 -0
- package/README.md +213 -0
- package/dist/index.cjs +436 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +97 -0
- package/dist/index.d.ts +97 -0
- package/dist/index.js +414 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.css +2 -0
- package/package.json +86 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { format } from 'date-fns';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
// src/components/Scheduler.tsx
|
|
6
|
+
|
|
7
|
+
// src/components/constants.ts
|
|
8
|
+
var STEP_MIN = 15;
|
|
9
|
+
var MIN_EVENT_MIN = 15;
|
|
10
|
+
var PX_PER_MIN = 2;
|
|
11
|
+
var GUTTER_W = 72;
|
|
12
|
+
var TOP_PAD = 12;
|
|
13
|
+
var BOTTOM_PAD = 24;
|
|
14
|
+
var RESOURCE_MIN_W = 420;
|
|
15
|
+
var clamp = (n, min, max) => {
|
|
16
|
+
return Math.max(min, Math.min(max, n));
|
|
17
|
+
};
|
|
18
|
+
var snap = (mins, stepMin = STEP_MIN) => {
|
|
19
|
+
return Math.round(mins / stepMin) * stepMin;
|
|
20
|
+
};
|
|
21
|
+
var parseHHMM = (hhmm) => {
|
|
22
|
+
const [h, m] = hhmm.split(":").map(Number);
|
|
23
|
+
return h * 60 + m;
|
|
24
|
+
};
|
|
25
|
+
var fullName = (u) => {
|
|
26
|
+
return `${u.firstName ?? ""} ${u.lastName ?? ""}`.trim();
|
|
27
|
+
};
|
|
28
|
+
var dayISO = (d) => {
|
|
29
|
+
return format(d, "yyyy-MM-dd");
|
|
30
|
+
};
|
|
31
|
+
var shiftDays = (d, delta) => {
|
|
32
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate() + delta);
|
|
33
|
+
};
|
|
34
|
+
var dateAtMinute = (selectedDate, dayStartAbs, minuteFromStart) => {
|
|
35
|
+
const base = new Date(
|
|
36
|
+
selectedDate.getFullYear(),
|
|
37
|
+
selectedDate.getMonth(),
|
|
38
|
+
selectedDate.getDate(),
|
|
39
|
+
0,
|
|
40
|
+
0,
|
|
41
|
+
0,
|
|
42
|
+
0
|
|
43
|
+
);
|
|
44
|
+
const abs = dayStartAbs + minuteFromStart;
|
|
45
|
+
const hh = Math.floor(abs / 60);
|
|
46
|
+
const mm = abs % 60;
|
|
47
|
+
base.setHours(hh, mm, 0, 0);
|
|
48
|
+
return base;
|
|
49
|
+
};
|
|
50
|
+
var minutesFromDayStart = (dayStartAbs, dt) => {
|
|
51
|
+
return dt.getHours() * 60 + dt.getMinutes() - dayStartAbs;
|
|
52
|
+
};
|
|
53
|
+
var overlaps = (a, b) => {
|
|
54
|
+
return a.startMin < b.endMin && b.startMin < a.endMin;
|
|
55
|
+
};
|
|
56
|
+
var layoutOverlaps = (blocks) => {
|
|
57
|
+
const sorted = [...blocks].sort((a, b) => a.startMin - b.startMin || a.endMin - b.endMin);
|
|
58
|
+
const groups = [];
|
|
59
|
+
let active = [];
|
|
60
|
+
let current = [];
|
|
61
|
+
for (const e of sorted) {
|
|
62
|
+
active = active.filter((x) => x.endMin > e.startMin);
|
|
63
|
+
const conflicts = active.some((x) => overlaps(x, e));
|
|
64
|
+
if (!conflicts && current.length > 0) {
|
|
65
|
+
groups.push(current);
|
|
66
|
+
current = [];
|
|
67
|
+
}
|
|
68
|
+
current.push(e);
|
|
69
|
+
active.push(e);
|
|
70
|
+
}
|
|
71
|
+
if (current.length) {
|
|
72
|
+
groups.push(current);
|
|
73
|
+
}
|
|
74
|
+
const out = [];
|
|
75
|
+
for (const group of groups) {
|
|
76
|
+
const g = [...group].sort((a, b) => a.startMin - b.startMin || a.endMin - b.endMin);
|
|
77
|
+
const laneEnd = [];
|
|
78
|
+
const laneOf = /* @__PURE__ */ new Map();
|
|
79
|
+
for (const e of g) {
|
|
80
|
+
let placed = false;
|
|
81
|
+
for (let i = 0; i < laneEnd.length; i++) {
|
|
82
|
+
if (laneEnd[i] <= e.startMin) {
|
|
83
|
+
laneEnd[i] = e.endMin;
|
|
84
|
+
laneOf.set(e.id, i);
|
|
85
|
+
placed = true;
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (!placed) {
|
|
90
|
+
laneEnd.push(e.endMin);
|
|
91
|
+
laneOf.set(e.id, laneEnd.length - 1);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const lanes = laneEnd.length;
|
|
95
|
+
for (const e of g) {
|
|
96
|
+
out.push({ ...e, lane: laneOf.get(e.id) ?? 0, lanes });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return out;
|
|
100
|
+
};
|
|
101
|
+
function isNameLike(resource) {
|
|
102
|
+
if (!resource || typeof resource !== "object") {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
const maybe = resource;
|
|
106
|
+
return typeof maybe.firstName === "string" || typeof maybe.lastName === "string";
|
|
107
|
+
}
|
|
108
|
+
function Scheduler({
|
|
109
|
+
resources,
|
|
110
|
+
appointments,
|
|
111
|
+
selectedDate,
|
|
112
|
+
onSelectedDateChange,
|
|
113
|
+
adapter,
|
|
114
|
+
onPersistMoveResize,
|
|
115
|
+
onAppointmentChange,
|
|
116
|
+
renderResourceHeader,
|
|
117
|
+
renderAppointment,
|
|
118
|
+
getResourceAppointmentBackground,
|
|
119
|
+
renderDatePicker,
|
|
120
|
+
prevButtonLabel = "Prev",
|
|
121
|
+
nextButtonLabel = "Next",
|
|
122
|
+
dayStart = "09:00",
|
|
123
|
+
dayEnd = "18:00"
|
|
124
|
+
}) {
|
|
125
|
+
const [drag, setDrag] = React.useState({ kind: "none" });
|
|
126
|
+
const colRefs = React.useRef({});
|
|
127
|
+
const suppressClickRef = React.useRef(false);
|
|
128
|
+
const dayStartAbs = parseHHMM(dayStart);
|
|
129
|
+
const dayEndAbs = parseHHMM(dayEnd);
|
|
130
|
+
const dayMinutes = Math.max(0, dayEndAbs - dayStartAbs);
|
|
131
|
+
const gridHeight = TOP_PAD + dayMinutes * PX_PER_MIN + BOTTOM_PAD;
|
|
132
|
+
const gridMinWidth = GUTTER_W + Math.max(resources.length, 1) * RESOURCE_MIN_W;
|
|
133
|
+
const selectedISO = React.useMemo(() => dayISO(selectedDate), [selectedDate]);
|
|
134
|
+
const renderAppts = React.useMemo(() => {
|
|
135
|
+
return appointments.map((appointment) => {
|
|
136
|
+
const start = new Date(adapter.getStart(appointment));
|
|
137
|
+
const end = new Date(adapter.getEnd(appointment));
|
|
138
|
+
return {
|
|
139
|
+
raw: appointment,
|
|
140
|
+
id: adapter.getId(appointment),
|
|
141
|
+
resourceId: adapter.getResourceId(appointment),
|
|
142
|
+
start,
|
|
143
|
+
end,
|
|
144
|
+
startMin: clamp(minutesFromDayStart(dayStartAbs, start), 0, dayMinutes),
|
|
145
|
+
endMin: clamp(minutesFromDayStart(dayStartAbs, end), 0, dayMinutes),
|
|
146
|
+
title: adapter.getTitle(appointment)
|
|
147
|
+
};
|
|
148
|
+
}).filter((appointment) => dayISO(appointment.start) === selectedISO);
|
|
149
|
+
}, [appointments, adapter, dayStartAbs, dayMinutes, selectedISO]);
|
|
150
|
+
const appointmentMap = React.useMemo(() => {
|
|
151
|
+
return new Map(renderAppts.map((appointment) => [appointment.id, appointment]));
|
|
152
|
+
}, [renderAppts]);
|
|
153
|
+
const effectiveAppts = React.useMemo(() => {
|
|
154
|
+
if (drag.kind === "none") {
|
|
155
|
+
return renderAppts;
|
|
156
|
+
}
|
|
157
|
+
return renderAppts.map((appointment) => {
|
|
158
|
+
if (appointment.id !== drag.appointmentId) {
|
|
159
|
+
return appointment;
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
...appointment,
|
|
163
|
+
resourceId: drag.resourceId,
|
|
164
|
+
startMin: drag.startMin,
|
|
165
|
+
endMin: drag.endMin,
|
|
166
|
+
start: dateAtMinute(selectedDate, dayStartAbs, drag.startMin),
|
|
167
|
+
end: dateAtMinute(selectedDate, dayStartAbs, drag.endMin)
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
}, [drag, renderAppts, selectedDate, dayStartAbs]);
|
|
171
|
+
const laidOutByResource = React.useMemo(() => {
|
|
172
|
+
const byResource = /* @__PURE__ */ new Map();
|
|
173
|
+
for (const resource of resources) {
|
|
174
|
+
const events = effectiveAppts.filter((appointment) => appointment.resourceId === resource.id);
|
|
175
|
+
byResource.set(resource.id, layoutOverlaps(events));
|
|
176
|
+
}
|
|
177
|
+
return byResource;
|
|
178
|
+
}, [effectiveAppts, resources]);
|
|
179
|
+
const appointmentBgByResource = React.useMemo(() => {
|
|
180
|
+
const map = /* @__PURE__ */ new Map();
|
|
181
|
+
if (!getResourceAppointmentBackground) {
|
|
182
|
+
return map;
|
|
183
|
+
}
|
|
184
|
+
for (const resource of resources) {
|
|
185
|
+
map.set(resource.id, getResourceAppointmentBackground(resource));
|
|
186
|
+
}
|
|
187
|
+
return map;
|
|
188
|
+
}, [getResourceAppointmentBackground, resources]);
|
|
189
|
+
const pointerToMin = (resourceId, clientY) => {
|
|
190
|
+
const col = colRefs.current[String(resourceId)];
|
|
191
|
+
if (!col) {
|
|
192
|
+
return 0;
|
|
193
|
+
}
|
|
194
|
+
const y = clientY - col.getBoundingClientRect().top - TOP_PAD;
|
|
195
|
+
return clamp(snap(y / PX_PER_MIN), 0, dayMinutes);
|
|
196
|
+
};
|
|
197
|
+
const pointerToResourceId = (clientX, fallbackResourceId) => {
|
|
198
|
+
for (const resource of resources) {
|
|
199
|
+
const col = colRefs.current[String(resource.id)];
|
|
200
|
+
if (!col) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
const rect = col.getBoundingClientRect();
|
|
204
|
+
if (clientX >= rect.left && clientX <= rect.right) {
|
|
205
|
+
return resource.id;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return fallbackResourceId;
|
|
209
|
+
};
|
|
210
|
+
const hasOverlap = (appointmentId, resourceId, startMin, endMin) => {
|
|
211
|
+
const events = renderAppts.filter((appointment) => appointment.resourceId === resourceId && appointment.id !== appointmentId);
|
|
212
|
+
return events.some((appointment) => overlaps(appointment, { startMin, endMin }));
|
|
213
|
+
};
|
|
214
|
+
const persistDrag = async (state) => {
|
|
215
|
+
const target = appointmentMap.get(state.appointmentId);
|
|
216
|
+
if (!target) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (hasOverlap(state.appointmentId, state.resourceId, state.startMin, state.endMin)) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const next = {
|
|
223
|
+
resourceId: state.resourceId,
|
|
224
|
+
start: dateAtMinute(selectedDate, dayStartAbs, state.startMin),
|
|
225
|
+
end: dateAtMinute(selectedDate, dayStartAbs, state.endMin)
|
|
226
|
+
};
|
|
227
|
+
if (onAppointmentChange) {
|
|
228
|
+
await onAppointmentChange({
|
|
229
|
+
kind: state.kind,
|
|
230
|
+
appointment: target.raw,
|
|
231
|
+
previous: {
|
|
232
|
+
resourceId: target.resourceId,
|
|
233
|
+
start: target.start,
|
|
234
|
+
end: target.end
|
|
235
|
+
},
|
|
236
|
+
next
|
|
237
|
+
});
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
if (onPersistMoveResize) {
|
|
241
|
+
await onPersistMoveResize({
|
|
242
|
+
appointment: target.raw,
|
|
243
|
+
resourceId: next.resourceId,
|
|
244
|
+
start: next.start,
|
|
245
|
+
end: next.end
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
const onApptPointerDown = (event, appointment) => {
|
|
250
|
+
if (event.button !== 0) {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
event.stopPropagation();
|
|
254
|
+
suppressClickRef.current = false;
|
|
255
|
+
const pointerMin = pointerToMin(appointment.resourceId, event.clientY);
|
|
256
|
+
setDrag({
|
|
257
|
+
kind: "move",
|
|
258
|
+
appointmentId: appointment.id,
|
|
259
|
+
pointerId: event.pointerId,
|
|
260
|
+
resourceId: appointment.resourceId,
|
|
261
|
+
durationMin: Math.max(MIN_EVENT_MIN, appointment.endMin - appointment.startMin),
|
|
262
|
+
offsetMin: pointerMin - appointment.startMin,
|
|
263
|
+
startMin: appointment.startMin,
|
|
264
|
+
endMin: appointment.endMin
|
|
265
|
+
});
|
|
266
|
+
};
|
|
267
|
+
const onResizePointerDown = (event, appointment) => {
|
|
268
|
+
if (event.button !== 0) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
event.stopPropagation();
|
|
272
|
+
suppressClickRef.current = false;
|
|
273
|
+
setDrag({
|
|
274
|
+
kind: "resize",
|
|
275
|
+
appointmentId: appointment.id,
|
|
276
|
+
pointerId: event.pointerId,
|
|
277
|
+
resourceId: appointment.resourceId,
|
|
278
|
+
startMin: appointment.startMin,
|
|
279
|
+
endMin: appointment.endMin
|
|
280
|
+
});
|
|
281
|
+
};
|
|
282
|
+
const onGlobalPointerMove = (event) => {
|
|
283
|
+
if (drag.kind === "none") {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
if (drag.kind === "move") {
|
|
287
|
+
const nextResourceId = pointerToResourceId(event.clientX, drag.resourceId);
|
|
288
|
+
const pointerMin2 = pointerToMin(nextResourceId, event.clientY);
|
|
289
|
+
const rawStart = pointerMin2 - drag.offsetMin;
|
|
290
|
+
const nextStartMin = clamp(snap(rawStart), 0, dayMinutes - drag.durationMin);
|
|
291
|
+
const nextEndMin2 = nextStartMin + drag.durationMin;
|
|
292
|
+
if (nextStartMin !== drag.startMin || nextEndMin2 !== drag.endMin || nextResourceId !== drag.resourceId) {
|
|
293
|
+
suppressClickRef.current = true;
|
|
294
|
+
setDrag({
|
|
295
|
+
...drag,
|
|
296
|
+
resourceId: nextResourceId,
|
|
297
|
+
startMin: nextStartMin,
|
|
298
|
+
endMin: nextEndMin2
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
const pointerMin = pointerToMin(drag.resourceId, event.clientY);
|
|
304
|
+
const nextEndMin = clamp(snap(pointerMin), drag.startMin + MIN_EVENT_MIN, dayMinutes);
|
|
305
|
+
if (nextEndMin !== drag.endMin) {
|
|
306
|
+
suppressClickRef.current = true;
|
|
307
|
+
setDrag({
|
|
308
|
+
...drag,
|
|
309
|
+
endMin: nextEndMin
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
const onGlobalPointerUp = () => {
|
|
314
|
+
if (drag.kind === "none") {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
const current = drag;
|
|
318
|
+
setDrag({ kind: "none" });
|
|
319
|
+
if (suppressClickRef.current) {
|
|
320
|
+
void persistDrag(current);
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
return /* @__PURE__ */ jsxs(
|
|
324
|
+
"section",
|
|
325
|
+
{
|
|
326
|
+
className: `rfs-root ${drag.kind === "move" ? "rfs-root--drag-move" : ""} ${drag.kind === "resize" ? "rfs-root--drag-resize" : ""}`,
|
|
327
|
+
onPointerMove: onGlobalPointerMove,
|
|
328
|
+
onPointerUp: onGlobalPointerUp,
|
|
329
|
+
onPointerCancel: onGlobalPointerUp,
|
|
330
|
+
children: [
|
|
331
|
+
/* @__PURE__ */ jsxs("div", { className: "rfs-toolbar", children: [
|
|
332
|
+
/* @__PURE__ */ jsx("button", { className: "rfs-btn", type: "button", onClick: () => onSelectedDateChange(shiftDays(selectedDate, -1)), children: prevButtonLabel }),
|
|
333
|
+
renderDatePicker ? renderDatePicker({ selectedDate, onSelectedDateChange }) : /* @__PURE__ */ jsx("strong", { className: "rfs-date-label", children: selectedISO }),
|
|
334
|
+
/* @__PURE__ */ jsx("button", { className: "rfs-btn", type: "button", onClick: () => onSelectedDateChange(shiftDays(selectedDate, 1)), children: nextButtonLabel })
|
|
335
|
+
] }),
|
|
336
|
+
/* @__PURE__ */ jsx("div", { className: "rfs-shell", children: /* @__PURE__ */ jsxs("div", { style: { minWidth: gridMinWidth }, children: [
|
|
337
|
+
/* @__PURE__ */ jsxs("div", { className: "rfs-header", children: [
|
|
338
|
+
/* @__PURE__ */ jsx("div", { className: "rfs-gutter", style: { width: GUTTER_W } }),
|
|
339
|
+
resources.map((resource) => /* @__PURE__ */ jsxs("div", { className: "rfs-resource-header", style: { minWidth: RESOURCE_MIN_W, flex: 1 }, children: [
|
|
340
|
+
renderResourceHeader(resource),
|
|
341
|
+
isNameLike(resource) ? /* @__PURE__ */ jsx("div", { className: "rfs-resource-subtitle", children: fullName(resource) }) : null
|
|
342
|
+
] }, String(resource.id)))
|
|
343
|
+
] }),
|
|
344
|
+
/* @__PURE__ */ jsxs("div", { className: "rfs-body", children: [
|
|
345
|
+
/* @__PURE__ */ jsx("div", { className: "rfs-times", style: { width: GUTTER_W, height: gridHeight }, children: Array.from({ length: Math.floor(dayMinutes / 60) + 1 }).map((_, i) => /* @__PURE__ */ jsxs("div", { className: "rfs-time-tick", style: { top: TOP_PAD + i * 60 * PX_PER_MIN }, children: [
|
|
346
|
+
String(Math.floor((dayStartAbs + i * 60) / 60)).padStart(2, "0"),
|
|
347
|
+
":",
|
|
348
|
+
String((dayStartAbs + i * 60) % 60).padStart(2, "0")
|
|
349
|
+
] }, `tick-${i}`)) }),
|
|
350
|
+
/* @__PURE__ */ jsx("div", { className: "rfs-grid", children: resources.map((resource) => /* @__PURE__ */ jsx("div", { className: "rfs-col", style: { minWidth: RESOURCE_MIN_W, flex: 1 }, children: /* @__PURE__ */ jsxs(
|
|
351
|
+
"div",
|
|
352
|
+
{
|
|
353
|
+
ref: (el) => {
|
|
354
|
+
colRefs.current[String(resource.id)] = el;
|
|
355
|
+
},
|
|
356
|
+
className: "rfs-col-inner",
|
|
357
|
+
style: { height: gridHeight },
|
|
358
|
+
children: [
|
|
359
|
+
Array.from({ length: Math.floor(dayMinutes / 60) + 1 }).map((_, i) => /* @__PURE__ */ jsx(
|
|
360
|
+
"div",
|
|
361
|
+
{
|
|
362
|
+
className: "rfs-hour-line",
|
|
363
|
+
style: { top: TOP_PAD + i * 60 * PX_PER_MIN }
|
|
364
|
+
},
|
|
365
|
+
`major-${String(resource.id)}-${i}`
|
|
366
|
+
)),
|
|
367
|
+
Array.from({ length: Math.floor(dayMinutes / STEP_MIN) + 1 }).map((_, i) => /* @__PURE__ */ jsx(
|
|
368
|
+
"div",
|
|
369
|
+
{
|
|
370
|
+
className: "rfs-slot-line",
|
|
371
|
+
style: { top: TOP_PAD + i * STEP_MIN * PX_PER_MIN }
|
|
372
|
+
},
|
|
373
|
+
`minor-${String(resource.id)}-${i}`
|
|
374
|
+
)),
|
|
375
|
+
(laidOutByResource.get(resource.id) ?? []).map((appointment) => {
|
|
376
|
+
const laneWidthPct = 100 / appointment.lanes;
|
|
377
|
+
const top = TOP_PAD + appointment.startMin * PX_PER_MIN;
|
|
378
|
+
const height = Math.max(MIN_EVENT_MIN * PX_PER_MIN, (appointment.endMin - appointment.startMin) * PX_PER_MIN);
|
|
379
|
+
const appointmentBackgroundColor = appointmentBgByResource.get(resource.id);
|
|
380
|
+
return /* @__PURE__ */ jsx(
|
|
381
|
+
"div",
|
|
382
|
+
{
|
|
383
|
+
className: "rfs-card-slot",
|
|
384
|
+
style: {
|
|
385
|
+
top,
|
|
386
|
+
left: `${laneWidthPct * appointment.lane}%`,
|
|
387
|
+
width: `${laneWidthPct}%`,
|
|
388
|
+
height
|
|
389
|
+
},
|
|
390
|
+
children: renderAppointment({
|
|
391
|
+
appointment,
|
|
392
|
+
onPointerDown: (event) => onApptPointerDown(event, appointment),
|
|
393
|
+
onResizePointerDown: (event) => onResizePointerDown(event, appointment),
|
|
394
|
+
appointmentBackgroundColor,
|
|
395
|
+
drag,
|
|
396
|
+
suppressClickRef
|
|
397
|
+
})
|
|
398
|
+
},
|
|
399
|
+
String(appointment.id)
|
|
400
|
+
);
|
|
401
|
+
})
|
|
402
|
+
]
|
|
403
|
+
}
|
|
404
|
+
) }, String(resource.id))) })
|
|
405
|
+
] })
|
|
406
|
+
] }) })
|
|
407
|
+
]
|
|
408
|
+
}
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
export { Scheduler };
|
|
413
|
+
//# sourceMappingURL=index.js.map
|
|
414
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/constants.ts","../src/components/utils.ts","../src/components/Scheduler.tsx"],"names":["pointerMin","nextEndMin"],"mappings":"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","file":"index.js","sourcesContent":["const OPEN_TIME = '09:00';\nconst CLOSE_TIME = '18:00';\n\nconst STEP_MIN = 15;\nconst MIN_EVENT_MIN = 15;\nconst DEFAULT_CREATE_MIN = 30;\n\nconst PX_PER_MIN = 2; // visual scale\nconst HEADER_H = 56;\nconst GUTTER_W = 72;\nconst TOP_PAD = 12;\nconst BOTTOM_PAD = 24;\n\nconst RESOURCE_MIN_W = 420; // columns expand to fill available width; min width enables x-scroll when needed\nconst RESOURCE_MIN_W_TW = 'min-w-[400px] lg:w-full'; // columns expand to fill available width; min width enables x-scroll when needed\nconst LANE_GAP = 6;\n\nexport {\n OPEN_TIME,\n CLOSE_TIME,\n STEP_MIN,\n MIN_EVENT_MIN,\n DEFAULT_CREATE_MIN,\n PX_PER_MIN,\n HEADER_H,\n GUTTER_W,\n TOP_PAD,\n BOTTOM_PAD,\n RESOURCE_MIN_W,\n LANE_GAP,\n RESOURCE_MIN_W_TW,\n}","import { format } from \"date-fns\";\nimport { STEP_MIN } from \"./constants\";\n\ntype NameLike = {\n firstName?: string | null;\n lastName?: string | null;\n};\n\ntype TimeBlockLike<TId extends string | number = string | number> = {\n id: TId;\n startMin: number;\n endMin: number;\n};\n\ntype LaidOut<T extends TimeBlockLike> = T & {\n lane: number;\n lanes: number;\n};\n\nconst clamp = (n: number, min: number, max: number) => {\n return Math.max(min, Math.min(max, n));\n};\n\nconst snap = (mins: number, stepMin = STEP_MIN) => {\n return Math.round(mins / stepMin) * stepMin;\n};\n\nconst parseHHMM = (hhmm: string) => {\n const [h, m] = hhmm.split(\":\").map(Number);\n return h * 60 + m;\n};\n\nconst fullName = <T extends NameLike>(u: T) => {\n return `${u.firstName ?? \"\"} ${u.lastName ?? \"\"}`.trim();\n};\n\nconst dayISO = (d: Date) => {\n return format(d, \"yyyy-MM-dd\");\n};\n\nconst shiftDays = (d: Date, delta: number) => {\n return new Date(d.getFullYear(), d.getMonth(), d.getDate() + delta);\n};\n\nconst dateAtMinute = (\n selectedDate: Date,\n dayStartAbs: number,\n minuteFromStart: number\n) => {\n const base = new Date(\n selectedDate.getFullYear(),\n selectedDate.getMonth(),\n selectedDate.getDate(),\n 0,\n 0,\n 0,\n 0\n );\n const abs = dayStartAbs + minuteFromStart;\n const hh = Math.floor(abs / 60);\n const mm = abs % 60;\n base.setHours(hh, mm, 0, 0);\n return base;\n};\n\nconst minutesFromDayStart = (dayStartAbs: number, dt: Date) => {\n return dt.getHours() * 60 + dt.getMinutes() - dayStartAbs;\n};\n\nconst overlaps = (a: TimeBlockLike, b: TimeBlockLike) => {\n return a.startMin < b.endMin && b.startMin < a.endMin;\n};\n\nconst layoutOverlaps = <T extends TimeBlockLike>(blocks: T[]): LaidOut<T>[] => {\n const sorted = [...blocks].sort((a, b) => a.startMin - b.startMin || a.endMin - b.endMin);\n\n const groups: T[][] = [];\n let active: T[] = [];\n let current: T[] = [];\n\n for (const e of sorted) {\n active = active.filter((x) => x.endMin > e.startMin);\n const conflicts = active.some((x) => overlaps(x, e));\n\n if (!conflicts && current.length > 0) {\n groups.push(current);\n current = [];\n }\n current.push(e);\n active.push(e);\n }\n if (current.length) {\n groups.push(current);\n }\n\n const out: LaidOut<T>[] = [];\n\n for (const group of groups) {\n const g = [...group].sort((a, b) => a.startMin - b.startMin || a.endMin - b.endMin);\n const laneEnd: number[] = [];\n const laneOf = new Map<T[\"id\"], number>();\n\n for (const e of g) {\n let placed = false;\n for (let i = 0; i < laneEnd.length; i++) {\n if (laneEnd[i] <= e.startMin) {\n laneEnd[i] = e.endMin;\n laneOf.set(e.id, i);\n placed = true;\n break;\n }\n }\n if (!placed) {\n laneEnd.push(e.endMin);\n laneOf.set(e.id, laneEnd.length - 1);\n }\n }\n\n const lanes = laneEnd.length;\n for (const e of g) {\n out.push({ ...e, lane: laneOf.get(e.id) ?? 0, lanes });\n }\n }\n\n return out;\n};\n\nexport {\n clamp,\n snap,\n parseHHMM,\n fullName,\n dayISO,\n shiftDays,\n dateAtMinute,\n minutesFromDayStart,\n overlaps,\n layoutOverlaps,\n};\n","import * as React from \"react\";\nimport { BOTTOM_PAD, GUTTER_W, MIN_EVENT_MIN, PX_PER_MIN, RESOURCE_MIN_W, STEP_MIN, TOP_PAD } from \"./constants\";\nimport { clamp, dateAtMinute, dayISO, fullName, layoutOverlaps, minutesFromDayStart, overlaps, parseHHMM, shiftDays, snap } from \"./utils\";\nimport type { BaseSchedulerResource, SchedulerDragState, SchedulerEvent, SchedulerId, SchedulerProps } from \"../types/scheduler\";\n\nfunction isNameLike(resource: unknown): resource is { firstName?: string | null; lastName?: string | null } {\n if (!resource || typeof resource !== \"object\") {\n return false;\n }\n const maybe = resource as { firstName?: unknown; lastName?: unknown };\n return typeof maybe.firstName === \"string\" || typeof maybe.lastName === \"string\";\n}\n\nexport function Scheduler<TAppointment, TResource extends BaseSchedulerResource<TResourceId>, TResourceId extends SchedulerId>({\n resources,\n appointments,\n selectedDate,\n onSelectedDateChange,\n adapter,\n onPersistMoveResize,\n onAppointmentChange,\n renderResourceHeader,\n renderAppointment,\n getResourceAppointmentBackground,\n renderDatePicker,\n prevButtonLabel = \"Prev\",\n nextButtonLabel = \"Next\",\n dayStart = \"09:00\",\n dayEnd = \"18:00\"\n}: SchedulerProps<TAppointment, TResource, TResourceId>) {\n const [drag, setDrag] = React.useState<SchedulerDragState<TResourceId>>({ kind: \"none\" });\n const colRefs = React.useRef<Record<string, HTMLDivElement | null>>({});\n const suppressClickRef = React.useRef(false);\n\n const dayStartAbs = parseHHMM(dayStart);\n const dayEndAbs = parseHHMM(dayEnd);\n const dayMinutes = Math.max(0, dayEndAbs - dayStartAbs);\n const gridHeight = TOP_PAD + dayMinutes * PX_PER_MIN + BOTTOM_PAD;\n const gridMinWidth = GUTTER_W + Math.max(resources.length, 1) * RESOURCE_MIN_W;\n const selectedISO = React.useMemo(() => dayISO(selectedDate), [selectedDate]);\n\n const renderAppts = React.useMemo<SchedulerEvent<TAppointment, TResourceId>[]>(() => {\n return appointments\n .map((appointment) => {\n const start = new Date(adapter.getStart(appointment));\n const end = new Date(adapter.getEnd(appointment));\n return {\n raw: appointment,\n id: adapter.getId(appointment),\n resourceId: adapter.getResourceId(appointment),\n start,\n end,\n startMin: clamp(minutesFromDayStart(dayStartAbs, start), 0, dayMinutes),\n endMin: clamp(minutesFromDayStart(dayStartAbs, end), 0, dayMinutes),\n title: adapter.getTitle(appointment)\n };\n })\n .filter((appointment) => dayISO(appointment.start) === selectedISO);\n }, [appointments, adapter, dayStartAbs, dayMinutes, selectedISO]);\n\n const appointmentMap = React.useMemo(() => {\n return new Map(renderAppts.map((appointment) => [appointment.id, appointment]));\n }, [renderAppts]);\n\n const effectiveAppts = React.useMemo<SchedulerEvent<TAppointment, TResourceId>[]>(() => {\n if (drag.kind === \"none\") {\n return renderAppts;\n }\n return renderAppts.map((appointment) => {\n if (appointment.id !== drag.appointmentId) {\n return appointment;\n }\n return {\n ...appointment,\n resourceId: drag.resourceId,\n startMin: drag.startMin,\n endMin: drag.endMin,\n start: dateAtMinute(selectedDate, dayStartAbs, drag.startMin),\n end: dateAtMinute(selectedDate, dayStartAbs, drag.endMin)\n };\n });\n }, [drag, renderAppts, selectedDate, dayStartAbs]);\n\n const laidOutByResource = React.useMemo(() => {\n const byResource = new Map<TResourceId, ReturnType<typeof layoutOverlaps<SchedulerEvent<TAppointment, TResourceId>>>>();\n for (const resource of resources) {\n const events = effectiveAppts.filter((appointment) => appointment.resourceId === resource.id);\n byResource.set(resource.id, layoutOverlaps(events));\n }\n return byResource;\n }, [effectiveAppts, resources]);\n\n const appointmentBgByResource = React.useMemo(() => {\n const map = new Map<TResourceId, string | undefined>();\n if (!getResourceAppointmentBackground) {\n return map;\n }\n for (const resource of resources) {\n map.set(resource.id, getResourceAppointmentBackground(resource));\n }\n return map;\n }, [getResourceAppointmentBackground, resources]);\n\n const pointerToMin = (resourceId: TResourceId, clientY: number) => {\n const col = colRefs.current[String(resourceId)];\n if (!col) {\n return 0;\n }\n const y = clientY - col.getBoundingClientRect().top - TOP_PAD;\n return clamp(snap(y / PX_PER_MIN), 0, dayMinutes);\n };\n\n const pointerToResourceId = (clientX: number, fallbackResourceId: TResourceId) => {\n for (const resource of resources) {\n const col = colRefs.current[String(resource.id)];\n if (!col) {\n continue;\n }\n const rect = col.getBoundingClientRect();\n if (clientX >= rect.left && clientX <= rect.right) {\n return resource.id;\n }\n }\n return fallbackResourceId;\n };\n\n const hasOverlap = (appointmentId: SchedulerId, resourceId: TResourceId, startMin: number, endMin: number) => {\n const events = renderAppts.filter((appointment) => appointment.resourceId === resourceId && appointment.id !== appointmentId);\n return events.some((appointment) => overlaps(appointment, { id: appointmentId, startMin, endMin }));\n };\n\n const persistDrag = async (state: Exclude<SchedulerDragState<TResourceId>, { kind: \"none\" }>) => {\n const target = appointmentMap.get(state.appointmentId);\n if (!target) {\n return;\n }\n if (hasOverlap(state.appointmentId, state.resourceId, state.startMin, state.endMin)) {\n return;\n }\n const next = {\n resourceId: state.resourceId,\n start: dateAtMinute(selectedDate, dayStartAbs, state.startMin),\n end: dateAtMinute(selectedDate, dayStartAbs, state.endMin)\n };\n\n if (onAppointmentChange) {\n await onAppointmentChange({\n kind: state.kind,\n appointment: target.raw,\n previous: {\n resourceId: target.resourceId,\n start: target.start,\n end: target.end\n },\n next\n });\n return;\n }\n\n if (onPersistMoveResize) {\n await onPersistMoveResize({\n appointment: target.raw,\n resourceId: next.resourceId,\n start: next.start,\n end: next.end\n });\n }\n };\n\n const onApptPointerDown = (event: React.PointerEvent, appointment: SchedulerEvent<TAppointment, TResourceId>) => {\n if (event.button !== 0) {\n return;\n }\n event.stopPropagation();\n suppressClickRef.current = false;\n const pointerMin = pointerToMin(appointment.resourceId, event.clientY);\n setDrag({\n kind: \"move\",\n appointmentId: appointment.id,\n pointerId: event.pointerId,\n resourceId: appointment.resourceId,\n durationMin: Math.max(MIN_EVENT_MIN, appointment.endMin - appointment.startMin),\n offsetMin: pointerMin - appointment.startMin,\n startMin: appointment.startMin,\n endMin: appointment.endMin\n });\n };\n\n const onResizePointerDown = (event: React.PointerEvent, appointment: SchedulerEvent<TAppointment, TResourceId>) => {\n if (event.button !== 0) {\n return;\n }\n event.stopPropagation();\n suppressClickRef.current = false;\n setDrag({\n kind: \"resize\",\n appointmentId: appointment.id,\n pointerId: event.pointerId,\n resourceId: appointment.resourceId,\n startMin: appointment.startMin,\n endMin: appointment.endMin\n });\n };\n\n const onGlobalPointerMove = (event: React.PointerEvent<HTMLElement>) => {\n if (drag.kind === \"none\") {\n return;\n }\n\n if (drag.kind === \"move\") {\n const nextResourceId = pointerToResourceId(event.clientX, drag.resourceId);\n const pointerMin = pointerToMin(nextResourceId, event.clientY);\n const rawStart = pointerMin - drag.offsetMin;\n const nextStartMin = clamp(snap(rawStart), 0, dayMinutes - drag.durationMin);\n const nextEndMin = nextStartMin + drag.durationMin;\n if (nextStartMin !== drag.startMin || nextEndMin !== drag.endMin || nextResourceId !== drag.resourceId) {\n suppressClickRef.current = true;\n setDrag({\n ...drag,\n resourceId: nextResourceId,\n startMin: nextStartMin,\n endMin: nextEndMin\n });\n }\n return;\n }\n\n const pointerMin = pointerToMin(drag.resourceId, event.clientY);\n const nextEndMin = clamp(snap(pointerMin), drag.startMin + MIN_EVENT_MIN, dayMinutes);\n if (nextEndMin !== drag.endMin) {\n suppressClickRef.current = true;\n setDrag({\n ...drag,\n endMin: nextEndMin\n });\n }\n };\n\n const onGlobalPointerUp = () => {\n if (drag.kind === \"none\") {\n return;\n }\n const current = drag;\n setDrag({ kind: \"none\" });\n if (suppressClickRef.current) {\n void persistDrag(current);\n }\n };\n\n return (\n <section\n className={`rfs-root ${drag.kind === \"move\" ? \"rfs-root--drag-move\" : \"\"} ${drag.kind === \"resize\" ? \"rfs-root--drag-resize\" : \"\"}`}\n onPointerMove={onGlobalPointerMove}\n onPointerUp={onGlobalPointerUp}\n onPointerCancel={onGlobalPointerUp}\n >\n <div className=\"rfs-toolbar\">\n <button className=\"rfs-btn\" type=\"button\" onClick={() => onSelectedDateChange(shiftDays(selectedDate, -1))}>\n {prevButtonLabel}\n </button>\n {renderDatePicker ? (\n renderDatePicker({ selectedDate, onSelectedDateChange })\n ) : (\n <strong className=\"rfs-date-label\">{selectedISO}</strong>\n )}\n <button className=\"rfs-btn\" type=\"button\" onClick={() => onSelectedDateChange(shiftDays(selectedDate, 1))}>\n {nextButtonLabel}\n </button>\n </div>\n\n <div className=\"rfs-shell\">\n <div style={{ minWidth: gridMinWidth }}>\n <div className=\"rfs-header\">\n <div className=\"rfs-gutter\" style={{ width: GUTTER_W }} />\n {resources.map((resource) => (\n <div key={String(resource.id)} className=\"rfs-resource-header\" style={{ minWidth: RESOURCE_MIN_W, flex: 1 }}>\n {renderResourceHeader(resource)}\n {isNameLike(resource) ? <div className=\"rfs-resource-subtitle\">{fullName(resource)}</div> : null}\n </div>\n ))}\n </div>\n <div className=\"rfs-body\">\n <div className=\"rfs-times\" style={{ width: GUTTER_W, height: gridHeight }}>\n {Array.from({ length: Math.floor(dayMinutes / 60) + 1 }).map((_, i) => (\n <div key={`tick-${i}`} className=\"rfs-time-tick\" style={{ top: TOP_PAD + i * 60 * PX_PER_MIN }}>\n {String(Math.floor((dayStartAbs + i * 60) / 60)).padStart(2, \"0\")}:\n {String((dayStartAbs + i * 60) % 60).padStart(2, \"0\")}\n </div>\n ))}\n </div>\n <div className=\"rfs-grid\">\n {resources.map((resource) => (\n <div key={String(resource.id)} className=\"rfs-col\" style={{ minWidth: RESOURCE_MIN_W, flex: 1 }}>\n <div\n ref={(el) => {\n colRefs.current[String(resource.id)] = el;\n }}\n className=\"rfs-col-inner\"\n style={{ height: gridHeight }}\n >\n {Array.from({ length: Math.floor(dayMinutes / 60) + 1 }).map((_, i) => (\n <div\n key={`major-${String(resource.id)}-${i}`}\n className=\"rfs-hour-line\"\n style={{ top: TOP_PAD + i * 60 * PX_PER_MIN }}\n />\n ))}\n {Array.from({ length: Math.floor(dayMinutes / STEP_MIN) + 1 }).map((_, i) => (\n <div\n key={`minor-${String(resource.id)}-${i}`}\n className=\"rfs-slot-line\"\n style={{ top: TOP_PAD + i * STEP_MIN * PX_PER_MIN }}\n />\n ))}\n {(laidOutByResource.get(resource.id) ?? []).map((appointment) => {\n const laneWidthPct = 100 / appointment.lanes;\n const top = TOP_PAD + appointment.startMin * PX_PER_MIN;\n const height = Math.max(MIN_EVENT_MIN * PX_PER_MIN, (appointment.endMin - appointment.startMin) * PX_PER_MIN);\n const appointmentBackgroundColor = appointmentBgByResource.get(resource.id);\n return (\n <div\n key={String(appointment.id)}\n className=\"rfs-card-slot\"\n style={{\n top,\n left: `${laneWidthPct * appointment.lane}%`,\n width: `${laneWidthPct}%`,\n height\n }}\n >\n {renderAppointment({\n appointment,\n onPointerDown: (event) => onApptPointerDown(event, appointment),\n onResizePointerDown: (event) => onResizePointerDown(event, appointment),\n appointmentBackgroundColor,\n drag,\n suppressClickRef\n })}\n </div>\n );\n })}\n </div>\n </div>\n ))}\n </div>\n </div>\n </div>\n </div>\n </section>\n );\n}\n"]}
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
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)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking: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;--tw-outline-style:solid}}}@layer theme{:root,:host{--font-sans:var(--font-sans);--font-serif:var(--font-serif);--font-mono:var(--font-mono);--color-amber-100:oklch(96.2% .059 95.617);--color-blue-100:oklch(93.2% .032 255.585);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-medium:500;--font-weight-semibold:600;--tracking-normal:var(--tracking-normal);--leading-tight:1.25;--shadow-2xs:var(--shadow-2xs);--shadow-xs:var(--shadow-xs);--shadow-sm:var(--shadow-sm);--shadow-md:var(--shadow-md);--shadow-lg:var(--shadow-lg);--shadow-xl:var(--shadow-xl);--shadow-2xl:var(--shadow-2xl);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--shadow:var(--shadow)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--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(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::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}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-x-1{inset-inline:calc(var(--spacing) * 1)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.bottom-1{bottom:calc(var(--spacing) * 1)}.mx-auto{margin-inline:auto}.my-6{margin-block:calc(var(--spacing) * 6)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.contents{display:contents}.flex{display:flex}.h-2{height:calc(var(--spacing) * 2)}.h-full{height:100%}.w-auto{width:auto}.min-w-\[400px\]{min-width:400px}.cursor-grab{cursor:grab}.cursor-ns-resize{cursor:ns-resize}.resize{resize:both}.overflow-hidden{overflow:hidden}.rounded-full{border-radius:3.40282e38px}.rounded-md{border-radius:calc(var(--radius) - 2px)}.border{border-style:var(--tw-border-style);border-width:1px}.border-slate-300{border-color:var(--color-slate-300)}.bg-amber-100{background-color:var(--color-amber-100)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-slate-100{background-color:var(--color-slate-100)}.bg-slate-300\/90{background-color:#cad5e2e6}@supports (color:color-mix(in lab, red, red)){.bg-slate-300\/90{background-color:color-mix(in oklab, var(--color-slate-300) 90%, transparent)}}.bg-white{background-color:var(--color-white)}.p-0{padding:calc(var(--spacing) * 0)}.p-2{padding:calc(var(--spacing) * 2)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-1{padding-block:calc(var(--spacing) * 1)}.pb-5{padding-bottom:calc(var(--spacing) * 5)}.font-sans{font-family:var(--font-sans)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:calc(var(--tracking-normal) - .025em);letter-spacing:calc(var(--tracking-normal) - .025em)}.tracking-wide{--tw-tracking:calc(var(--tracking-normal) + .025em);letter-spacing:calc(var(--tracking-normal) + .025em)}.text-slate-500{color:var(--color-slate-500)}.shadow-sm{--tw-shadow:var(--shadow-sm);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}@media (hover:hover){.hover\:bg-slate-400:hover{background-color:var(--color-slate-400)}}.active\:cursor-grabbing:active{cursor:grabbing}@media (min-width:64rem){.lg\:w-full{width:100%}}}: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{--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(--text-sm);line-height:var(--tw-leading,var(--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-toolbar{margin-bottom:calc(var(--spacing) * 3);align-items:center;gap:calc(var(--spacing) * 2);display:flex}.rfs-btn{border-radius:calc(var(--radius) - 2px);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 1);font-size:var(--text-xs);line-height:var(--tw-leading,var(--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(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));border-width:1px;border-color:var(--rfs-border);background:var(--rfs-surface)}.rfs-btn:hover{background:var(--rfs-bg)}.rfs-btn:disabled{cursor:not-allowed;opacity:.5}.rfs-date-label{border-radius:calc(var(--radius) - 2px);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 1);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);border-width:1px;border-color:var(--rfs-border);background:var(--rfs-surface)}.rfs-shell{border-radius:var(--radius);border-style:var(--tw-border-style);border-width:1px;border-color:var(--rfs-border);background:var(--rfs-surface);overflow-x:auto}.rfs-header{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--rfs-border);display:flex}.rfs-gutter{border-right-style:var(--tw-border-style);border-right-width:1px;border-color:var(--rfs-border);flex-shrink:0}.rfs-resource-header{border-right-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 2);border-right-width:1px;border-color:var(--rfs-border)}.rfs-resource-subtitle{margin-top:calc(var(--spacing) * 1);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--rfs-muted)}.rfs-body{display:flex}.rfs-times{border-right-style:var(--tw-border-style);border-right-width:1px;border-color:var(--rfs-border);flex-shrink:0;position:relative}.rfs-time-tick{left:calc(var(--spacing) * 1);color:var(--rfs-muted);font-size:11px;position:absolute}.rfs-grid{flex:1;display:flex}.rfs-col{border-right-style:var(--tw-border-style);border-right-width:1px;border-color:var(--rfs-border)}.rfs-col-inner{position:relative}.rfs-hour-line,.rfs-slot-line{right:calc(var(--spacing) * 0);left:calc(var(--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-card-slot{padding:calc(var(--spacing) * .5);position:absolute}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{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}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}
|
package/package.json
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@marco.colia/react-fast-scheduler",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A lightweight React scheduling library.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"react",
|
|
7
|
+
"scheduler",
|
|
8
|
+
"calendar",
|
|
9
|
+
"library"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"author": "Marco Colia",
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "./dist/index.cjs",
|
|
15
|
+
"module": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"sideEffects": false,
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/index.js",
|
|
25
|
+
"require": "./dist/index.cjs"
|
|
26
|
+
},
|
|
27
|
+
"./styles.css": "./dist/styles.css"
|
|
28
|
+
},
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/justoverclockl/react-fast-scheduler.git"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://github.com/justoverclockl/react-fast-scheduler#readme",
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/justoverclockl/react-fast-scheduler/issues"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "npm run build:js && npm run build:css",
|
|
42
|
+
"build:js": "tsup",
|
|
43
|
+
"build:css": "tailwindcss -i ./src/global.css -o ./dist/styles.css --minify",
|
|
44
|
+
"dev:demo": "vite",
|
|
45
|
+
"changeset": "changeset",
|
|
46
|
+
"clean": "rimraf dist",
|
|
47
|
+
"dev": "tsup --watch",
|
|
48
|
+
"lint": "eslint .",
|
|
49
|
+
"release": "npm run build && changeset publish",
|
|
50
|
+
"test": "vitest run --passWithNoTests",
|
|
51
|
+
"test:watch": "vitest",
|
|
52
|
+
"typecheck": "tsc --noEmit",
|
|
53
|
+
"prepack": "npm run clean && npm run build"
|
|
54
|
+
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
57
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@tailwindcss/cli": "^4.1.13",
|
|
61
|
+
"@tailwindcss/vite": "^4.1.13",
|
|
62
|
+
"@changesets/changelog-github": "^0.5.1",
|
|
63
|
+
"@changesets/cli": "^2.29.4",
|
|
64
|
+
"@eslint/js": "^9.25.1",
|
|
65
|
+
"@testing-library/jest-dom": "^6.6.3",
|
|
66
|
+
"@testing-library/react": "^16.3.0",
|
|
67
|
+
"@types/react": "^19.1.8",
|
|
68
|
+
"@types/react-dom": "^19.1.6",
|
|
69
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
70
|
+
"eslint": "^9.25.1",
|
|
71
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
72
|
+
"globals": "^16.0.0",
|
|
73
|
+
"jsdom": "^26.1.0",
|
|
74
|
+
"react": "^19.1.1",
|
|
75
|
+
"react-dom": "^19.1.1",
|
|
76
|
+
"rimraf": "^6.0.1",
|
|
77
|
+
"tsup": "^8.5.0",
|
|
78
|
+
"tailwindcss": "^4.1.13",
|
|
79
|
+
"typescript": "^5.8.3",
|
|
80
|
+
"typescript-eslint": "^8.30.1",
|
|
81
|
+
"vitest": "^3.2.4"
|
|
82
|
+
},
|
|
83
|
+
"dependencies": {
|
|
84
|
+
"date-fns": "^4.1.0"
|
|
85
|
+
}
|
|
86
|
+
}
|