@super-calendar/dom 2.1.5 → 2.3.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 +17 -0
- package/dist/index.d.mts +327 -12
- package/dist/index.d.ts +327 -12
- package/dist/index.js +1117 -286
- package/dist/index.mjs +1093 -289
- package/package.json +2 -2
- package/src/Agenda.tsx +77 -46
- package/src/Calendar.tsx +40 -4
- package/src/DateRangePicker.tsx +360 -0
- package/src/MonthList.tsx +43 -11
- package/src/MonthView.tsx +329 -130
- package/src/ResourceTimeline.tsx +431 -0
- package/src/TimeGrid.tsx +253 -148
- package/src/index.ts +37 -3
- package/src/slots.ts +87 -0
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,45 @@
|
|
|
1
1
|
import { LegendList } from "@legendapp/list/react";
|
|
2
2
|
import { addDays, addMinutes, addMonths, endOfMonth, format, isSameDay, isSameMonth, startOfDay, startOfMonth } from "date-fns";
|
|
3
|
-
import { useEffect, useMemo, useRef, useState } from "react";
|
|
4
|
-
import { bandRounding, buildMonthGrid, buildMonthGrid as buildMonthGrid$1, cellRangeFromDrag, closedHourBands, compareDayEvents, darkColors, dayBadgeKind, daySelectionState, eventAccessibilityLabel, eventChipLayout, eventTimeLabel, formatHour, getIsToday, getViewDays, getViewDays as getViewDays$1, groupEventsByDay, isAllDayEvent, isAllDayEvent as isAllDayEvent$1, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWithinDateRange, layoutDayEvents, layoutDayEvents as layoutDayEvents$1, lightColors, monthVisibleCount, nextDateRange, rangeBandKind, titleNumberOfLines, useDateRange, useMonthGrid } from "@super-calendar/core";
|
|
3
|
+
import { useEffect, useId, useMemo, useRef, useState } from "react";
|
|
4
|
+
import { bandRounding, buildMonthGrid, buildMonthGrid as buildMonthGrid$1, cellRangeFromDrag, closedHourBands, compareDayEvents, darkColors, dayBadgeKind, daySelectionState, eventAccessibilityLabel, eventChipLayout, eventTimeLabel, expandRecurringEvents, formatHour, getIsToday, getViewDays, getViewDays as getViewDays$1, groupEventsByDay, isAllDayEvent, isAllDayEvent as isAllDayEvent$1, isDateSelectable, isRangeEndpoint, isSameCalendarDay, isWeekend, isWithinDateRange, layoutDayEvents, layoutDayEvents as layoutDayEvents$1, lightColors, monthVisibleCount, nextDateRange, nextDateRange as nextDateRange$1, parseICalendar, rangeBandKind, titleNumberOfLines, toICalendar, useDateRange, useMonthGrid, weekdayFormatToken, weekdayFormatToken as weekdayFormatToken$1 } from "@super-calendar/core";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
//#region src/slots.ts
|
|
7
|
+
/** Join truthy class names (a dependency-free clsx-lite). */
|
|
8
|
+
function cn(...parts) {
|
|
9
|
+
return parts.filter(Boolean).join(" ") || void 0;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Build a slot resolver for one render. `slot(name, defaults)` returns the props to
|
|
13
|
+
* spread on that element: a merged `className`, the resolved inline `style`, and a
|
|
14
|
+
* stable `data-slot` hook for CSS/testing.
|
|
15
|
+
*/
|
|
16
|
+
function createSlots({ classNames, styles }) {
|
|
17
|
+
return (name, defaults) => {
|
|
18
|
+
const slotClass = classNames?.[name];
|
|
19
|
+
const override = styles?.[name];
|
|
20
|
+
const style = {
|
|
21
|
+
...defaults?.base,
|
|
22
|
+
...slotClass ? void 0 : defaults?.themed,
|
|
23
|
+
...override
|
|
24
|
+
};
|
|
25
|
+
return {
|
|
26
|
+
className: cn(slotClass),
|
|
27
|
+
style: Object.keys(style).length ? style : void 0,
|
|
28
|
+
"data-slot": name
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Turn a map of boolean state flags into present/absent `data-*` attributes, so
|
|
34
|
+
* consumers can target state with CSS/Tailwind variants (e.g. `data-[today]:...`).
|
|
35
|
+
* A true flag renders the attribute (empty value); a false/undefined one omits it.
|
|
36
|
+
*/
|
|
37
|
+
function dataState(flags) {
|
|
38
|
+
const out = {};
|
|
39
|
+
for (const key in flags) if (flags[key]) out[key] = "";
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
6
43
|
//#region src/theme.ts
|
|
7
44
|
const METRICS = {
|
|
8
45
|
cellHeight: 48,
|
|
@@ -29,7 +66,7 @@ function mergeDomTheme(overrides, base = defaultDomTheme) {
|
|
|
29
66
|
}
|
|
30
67
|
//#endregion
|
|
31
68
|
//#region src/Agenda.tsx
|
|
32
|
-
function DefaultAgendaRow({ event, isAllDay, ampm = false,
|
|
69
|
+
function DefaultAgendaRow({ event, isAllDay, ampm = false, cardProps }) {
|
|
33
70
|
const time = eventTimeLabel({
|
|
34
71
|
mode: "schedule",
|
|
35
72
|
isAllDay,
|
|
@@ -39,12 +76,7 @@ function DefaultAgendaRow({ event, isAllDay, ampm = false, theme }) {
|
|
|
39
76
|
showTime: true
|
|
40
77
|
}) ?? "";
|
|
41
78
|
return /* @__PURE__ */ jsxs("div", {
|
|
42
|
-
|
|
43
|
-
padding: "6px 10px",
|
|
44
|
-
borderRadius: 8,
|
|
45
|
-
background: theme.eventBackground,
|
|
46
|
-
color: theme.eventText
|
|
47
|
-
},
|
|
79
|
+
...cardProps,
|
|
48
80
|
children: [/* @__PURE__ */ jsx("div", {
|
|
49
81
|
style: {
|
|
50
82
|
fontWeight: 600,
|
|
@@ -71,8 +103,12 @@ function DefaultAgendaRow({ event, isAllDay, ampm = false, theme }) {
|
|
|
71
103
|
* <Agenda events={events} onPressEvent={(e) => console.log(e.title)} />
|
|
72
104
|
* ```
|
|
73
105
|
*/
|
|
74
|
-
function Agenda({ events, locale, ampm = false, activeDate, theme: themeOverrides, height = 480, renderEvent, onPressEvent, onPressDay, className, style }) {
|
|
106
|
+
function Agenda({ events, locale, ampm = false, activeDate, theme: themeOverrides, height = 480, renderEvent, eventAccessibilityLabel, onPressEvent, onPressDay, className, style, classNames, styles }) {
|
|
75
107
|
const theme = useMemo(() => mergeDomTheme(themeOverrides), [themeOverrides]);
|
|
108
|
+
const slot = createSlots({
|
|
109
|
+
classNames,
|
|
110
|
+
styles
|
|
111
|
+
});
|
|
76
112
|
const Renderer = renderEvent;
|
|
77
113
|
const rows = useMemo(() => {
|
|
78
114
|
const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime());
|
|
@@ -116,24 +152,33 @@ function Agenda({ events, locale, ampm = false, activeDate, theme: themeOverride
|
|
|
116
152
|
const highlighted = activeDate ? isSameDay(item.date, activeDate) : getIsToday(item.date);
|
|
117
153
|
const label = format(item.date, "EEEE, d LLLL", locale ? { locale } : void 0);
|
|
118
154
|
const color = highlighted ? theme.todayBackground : theme.textMuted;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
...headerStyle,
|
|
124
|
-
color,
|
|
155
|
+
const headerProps = slot("dayHeader", {
|
|
156
|
+
base: onPressDay ? {
|
|
157
|
+
display: "block",
|
|
158
|
+
width: "100%",
|
|
125
159
|
border: "none",
|
|
126
160
|
background: "transparent",
|
|
127
161
|
cursor: "pointer",
|
|
128
162
|
font: "inherit",
|
|
129
163
|
textAlign: "left"
|
|
164
|
+
} : {
|
|
165
|
+
display: "block",
|
|
166
|
+
width: "100%"
|
|
130
167
|
},
|
|
168
|
+
themed: {
|
|
169
|
+
padding: "12px 12px 4px",
|
|
170
|
+
fontSize: 13,
|
|
171
|
+
fontWeight: 600,
|
|
172
|
+
color
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
return onPressDay ? /* @__PURE__ */ jsx("button", {
|
|
176
|
+
type: "button",
|
|
177
|
+
onClick: () => onPressDay(item.date),
|
|
178
|
+
...headerProps,
|
|
131
179
|
children: label
|
|
132
180
|
}) : /* @__PURE__ */ jsx("div", {
|
|
133
|
-
|
|
134
|
-
...headerStyle,
|
|
135
|
-
color
|
|
136
|
-
},
|
|
181
|
+
...headerProps,
|
|
137
182
|
children: label
|
|
138
183
|
});
|
|
139
184
|
}
|
|
@@ -150,68 +195,78 @@ function Agenda({ events, locale, ampm = false, activeDate, theme: themeOverride
|
|
|
150
195
|
return /* @__PURE__ */ jsx("button", {
|
|
151
196
|
type: "button",
|
|
152
197
|
onClick: onPress,
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
198
|
+
"aria-label": eventAccessibilityLabel ? eventAccessibilityLabel(event, {
|
|
199
|
+
mode: "schedule",
|
|
200
|
+
isAllDay,
|
|
201
|
+
ampm
|
|
202
|
+
}) : void 0,
|
|
203
|
+
...slot("eventRow", {
|
|
204
|
+
base: {
|
|
205
|
+
display: "block",
|
|
206
|
+
width: "100%",
|
|
207
|
+
textAlign: "left",
|
|
208
|
+
border: "none",
|
|
209
|
+
background: "transparent",
|
|
210
|
+
cursor: "pointer",
|
|
211
|
+
font: "inherit"
|
|
212
|
+
},
|
|
213
|
+
themed: { padding: "2px 12px" }
|
|
214
|
+
}),
|
|
163
215
|
children: Renderer ? /* @__PURE__ */ jsx(Renderer, { ...args }) : /* @__PURE__ */ jsx(DefaultAgendaRow, {
|
|
164
216
|
...args,
|
|
165
|
-
|
|
217
|
+
cardProps: slot("event", { themed: {
|
|
218
|
+
padding: "6px 10px",
|
|
219
|
+
borderRadius: 8,
|
|
220
|
+
background: theme.eventBackground,
|
|
221
|
+
color: theme.eventText
|
|
222
|
+
} })
|
|
166
223
|
})
|
|
167
224
|
});
|
|
168
225
|
}
|
|
169
226
|
}), rows.length === 0 ? /* @__PURE__ */ jsx("div", {
|
|
170
|
-
|
|
227
|
+
...slot("empty", { themed: {
|
|
171
228
|
padding: "16px 12px",
|
|
172
229
|
color: theme.textMuted,
|
|
173
230
|
fontSize: 14
|
|
174
|
-
},
|
|
231
|
+
} }),
|
|
175
232
|
children: "No events"
|
|
176
233
|
}) : null]
|
|
177
234
|
});
|
|
178
235
|
}
|
|
179
|
-
const headerStyle = {
|
|
180
|
-
display: "block",
|
|
181
|
-
width: "100%",
|
|
182
|
-
padding: "12px 12px 4px",
|
|
183
|
-
fontSize: 13,
|
|
184
|
-
fontWeight: 600
|
|
185
|
-
};
|
|
186
236
|
//#endregion
|
|
187
237
|
//#region src/MonthView.tsx
|
|
188
238
|
const DATE_ROW = 24;
|
|
189
239
|
const CHIP_HEIGHT = 18;
|
|
190
240
|
const CHIP_GAP = 2;
|
|
191
241
|
const CELL_PAD = 4;
|
|
192
|
-
function
|
|
242
|
+
function dayCellDefault(day, theme) {
|
|
193
243
|
return {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
244
|
+
base: {
|
|
245
|
+
position: "relative",
|
|
246
|
+
height: theme.cellHeight,
|
|
247
|
+
border: "none",
|
|
248
|
+
font: "inherit",
|
|
249
|
+
cursor: day.isDisabled ? "default" : "pointer",
|
|
250
|
+
display: "flex",
|
|
251
|
+
alignItems: "center",
|
|
252
|
+
justifyContent: "center",
|
|
253
|
+
padding: 0,
|
|
254
|
+
WebkitTapHighlightColor: "transparent"
|
|
255
|
+
},
|
|
256
|
+
themed: {
|
|
257
|
+
background: day.isWeekend && !day.isInRange ? theme.weekendBackground : "transparent",
|
|
258
|
+
fontSize: 15,
|
|
259
|
+
color: day.isDisabled ? theme.textDisabled : theme.text
|
|
260
|
+
}
|
|
207
261
|
};
|
|
208
262
|
}
|
|
209
263
|
/**
|
|
210
264
|
* The range band behind a day, rendered as its own layer so it can be a centered
|
|
211
265
|
* rounded strip (the default) or fill the whole cell (`fillCell`). Returns null
|
|
212
|
-
* for days with no band. Endpoints get the leading/trailing pill rounding.
|
|
266
|
+
* for days with no band. Endpoints get the leading/trailing pill rounding. Its
|
|
267
|
+
* geometry is structural; only the fill colour is themed.
|
|
213
268
|
*/
|
|
214
|
-
function
|
|
269
|
+
function rangeBandDefault(day, theme, fillCell) {
|
|
215
270
|
const kind = rangeBandKind(day, fillCell);
|
|
216
271
|
if (kind === "none") return null;
|
|
217
272
|
const fill = kind === "fill";
|
|
@@ -219,80 +274,94 @@ function rangeBandStyle(day, theme, fillCell) {
|
|
|
219
274
|
const radius = fill ? 0 : theme.rangeBandHeight / 2;
|
|
220
275
|
const rounding = bandRounding(kind);
|
|
221
276
|
const cap = `calc(50% - ${theme.dayBadgeSize / 2}px)`;
|
|
222
|
-
const
|
|
277
|
+
const base = {
|
|
223
278
|
position: "absolute",
|
|
224
279
|
left: rounding.start ? cap : 0,
|
|
225
280
|
right: rounding.end ? cap : 0,
|
|
226
281
|
top: inset,
|
|
227
282
|
bottom: inset,
|
|
228
|
-
background: theme.rangeBackground,
|
|
229
283
|
zIndex: 0
|
|
230
284
|
};
|
|
231
285
|
if (rounding.start) {
|
|
232
|
-
|
|
233
|
-
|
|
286
|
+
base.borderTopLeftRadius = radius;
|
|
287
|
+
base.borderBottomLeftRadius = radius;
|
|
234
288
|
}
|
|
235
289
|
if (rounding.end) {
|
|
236
|
-
|
|
237
|
-
|
|
290
|
+
base.borderTopRightRadius = radius;
|
|
291
|
+
base.borderBottomRightRadius = radius;
|
|
238
292
|
}
|
|
239
|
-
return
|
|
293
|
+
return {
|
|
294
|
+
base,
|
|
295
|
+
themed: { background: theme.rangeBackground }
|
|
296
|
+
};
|
|
240
297
|
}
|
|
241
|
-
function
|
|
298
|
+
function badgeDefault(day, theme, hovered) {
|
|
242
299
|
const badge = dayBadgeKind(day, day.isToday);
|
|
243
300
|
const filled = badge !== "none";
|
|
244
301
|
const background = filled ? badge === "today" ? theme.todayBackground : theme.selectedBackground : hovered ? theme.hoverBackground : "transparent";
|
|
245
302
|
return {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
303
|
+
base: {
|
|
304
|
+
position: "relative",
|
|
305
|
+
zIndex: 1,
|
|
306
|
+
width: theme.dayBadgeSize,
|
|
307
|
+
height: theme.dayBadgeSize,
|
|
308
|
+
borderRadius: "50%",
|
|
309
|
+
display: "flex",
|
|
310
|
+
alignItems: "center",
|
|
311
|
+
justifyContent: "center"
|
|
312
|
+
},
|
|
313
|
+
themed: {
|
|
314
|
+
background,
|
|
315
|
+
color: filled ? day.isToday ? theme.todayText : theme.selectedText : "inherit"
|
|
316
|
+
}
|
|
256
317
|
};
|
|
257
318
|
}
|
|
258
|
-
function
|
|
319
|
+
function eventCellDefault(day, theme, height) {
|
|
259
320
|
return {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
321
|
+
base: {
|
|
322
|
+
position: "relative",
|
|
323
|
+
minHeight: height,
|
|
324
|
+
minWidth: 0,
|
|
325
|
+
border: "none",
|
|
326
|
+
cursor: day.isDisabled ? "default" : "pointer",
|
|
327
|
+
display: "flex",
|
|
328
|
+
flexDirection: "column",
|
|
329
|
+
gap: CHIP_GAP,
|
|
330
|
+
padding: CELL_PAD,
|
|
331
|
+
boxSizing: "border-box",
|
|
332
|
+
textAlign: "left",
|
|
333
|
+
WebkitTapHighlightColor: "transparent"
|
|
334
|
+
},
|
|
335
|
+
themed: {
|
|
336
|
+
borderTop: `1px solid ${theme.gridLine}`,
|
|
337
|
+
background: day.isWeekend && !day.isInRange ? theme.weekendBackground : "transparent",
|
|
338
|
+
color: day.isDisabled ? theme.textDisabled : theme.text
|
|
339
|
+
}
|
|
275
340
|
};
|
|
276
341
|
}
|
|
277
|
-
function
|
|
342
|
+
function compactBadgeDefault(day, theme) {
|
|
278
343
|
const badge = dayBadgeKind(day, day.isToday);
|
|
279
344
|
const filled = badge !== "none";
|
|
280
345
|
return {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
346
|
+
base: {
|
|
347
|
+
position: "relative",
|
|
348
|
+
zIndex: 1,
|
|
349
|
+
alignSelf: "flex-end",
|
|
350
|
+
width: DATE_ROW - 2,
|
|
351
|
+
height: DATE_ROW - 2,
|
|
352
|
+
borderRadius: "50%",
|
|
353
|
+
display: "flex",
|
|
354
|
+
alignItems: "center",
|
|
355
|
+
justifyContent: "center"
|
|
356
|
+
},
|
|
357
|
+
themed: {
|
|
358
|
+
fontSize: 13,
|
|
359
|
+
background: filled ? badge === "today" ? theme.todayBackground : theme.selectedBackground : "transparent",
|
|
360
|
+
color: filled ? day.isToday ? theme.todayText : theme.selectedText : "inherit"
|
|
361
|
+
}
|
|
293
362
|
};
|
|
294
363
|
}
|
|
295
|
-
const
|
|
364
|
+
const chipButtonDefault = { base: {
|
|
296
365
|
position: "relative",
|
|
297
366
|
zIndex: 1,
|
|
298
367
|
border: "none",
|
|
@@ -302,38 +371,46 @@ const chipButtonStyle = {
|
|
|
302
371
|
cursor: "pointer",
|
|
303
372
|
textAlign: "left",
|
|
304
373
|
fontFamily: "inherit"
|
|
305
|
-
};
|
|
306
|
-
function
|
|
374
|
+
} };
|
|
375
|
+
function chipDefault(theme) {
|
|
307
376
|
return {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
377
|
+
base: {
|
|
378
|
+
display: "block",
|
|
379
|
+
height: CHIP_HEIGHT,
|
|
380
|
+
lineHeight: `${CHIP_HEIGHT}px`,
|
|
381
|
+
whiteSpace: "nowrap",
|
|
382
|
+
overflow: "hidden",
|
|
383
|
+
textOverflow: "ellipsis"
|
|
384
|
+
},
|
|
385
|
+
themed: {
|
|
386
|
+
padding: "0 6px",
|
|
387
|
+
borderRadius: 4,
|
|
388
|
+
background: theme.eventBackground,
|
|
389
|
+
color: theme.eventText,
|
|
390
|
+
fontSize: 11,
|
|
391
|
+
fontWeight: 600
|
|
392
|
+
}
|
|
320
393
|
};
|
|
321
394
|
}
|
|
322
|
-
function
|
|
395
|
+
function moreButtonDefault(theme) {
|
|
323
396
|
return {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
397
|
+
base: {
|
|
398
|
+
position: "relative",
|
|
399
|
+
zIndex: 1,
|
|
400
|
+
border: "none",
|
|
401
|
+
background: "transparent",
|
|
402
|
+
cursor: "pointer",
|
|
403
|
+
textAlign: "left",
|
|
404
|
+
height: CHIP_HEIGHT,
|
|
405
|
+
lineHeight: `${CHIP_HEIGHT}px`,
|
|
406
|
+
fontFamily: "inherit"
|
|
407
|
+
},
|
|
408
|
+
themed: {
|
|
409
|
+
padding: "0 6px",
|
|
410
|
+
fontSize: 11,
|
|
411
|
+
fontWeight: 600,
|
|
412
|
+
color: theme.textMuted
|
|
413
|
+
}
|
|
337
414
|
};
|
|
338
415
|
}
|
|
339
416
|
/**
|
|
@@ -344,8 +421,12 @@ function moreButtonStyle(theme) {
|
|
|
344
421
|
* <MonthView date={new Date()} events={events} onPressDay={(d) => setDate(d)} />
|
|
345
422
|
* ```
|
|
346
423
|
*/
|
|
347
|
-
function MonthView({ date, weekStartsOn = 0, events, eventsByDay: eventsByDayProp, renderEvent, maxVisibleEventCount = 3, moreLabel = "{moreCount} More", onPressEvent, onPressMore, selectedRange, selectedDates, showAdjacentMonths = true, fillCellOnSelection = false, showTitle = true, showWeekdays = true, locale, theme: themeOverrides, minDate, maxDate, isDateDisabled, onPressDay, keyboardDayNavigation = false, className, style }) {
|
|
424
|
+
function MonthView({ date, weekStartsOn = 0, weekdayFormat = "short", events, eventsByDay: eventsByDayProp, renderEvent, eventAccessibilityLabel, maxVisibleEventCount = 3, moreLabel = "{moreCount} More", onPressEvent, onPressMore, selectedRange, selectedDates, showAdjacentMonths = true, fillCellOnSelection = false, showTitle = true, showWeekdays = true, locale, theme: themeOverrides, minDate, maxDate, isDateDisabled, onPressDay, onCreateEvent, keyboardDayNavigation = false, className, style, classNames, styles }) {
|
|
348
425
|
const theme = useMemo(() => mergeDomTheme(themeOverrides), [themeOverrides]);
|
|
426
|
+
const slot = createSlots({
|
|
427
|
+
classNames,
|
|
428
|
+
styles
|
|
429
|
+
});
|
|
349
430
|
const eventsMode = events !== void 0;
|
|
350
431
|
const dayRoving = !eventsMode || keyboardDayNavigation;
|
|
351
432
|
const eventsByDay = useMemo(() => {
|
|
@@ -358,6 +439,7 @@ function MonthView({ date, weekStartsOn = 0, events, eventsByDay: eventsByDayPro
|
|
|
358
439
|
const eventRowHeight = 32 + maxVisibleEventCount * 20;
|
|
359
440
|
const { weeks, weekdays } = useMemo(() => buildMonthGrid$1(date, {
|
|
360
441
|
weekStartsOn,
|
|
442
|
+
weekdayFormat,
|
|
361
443
|
selectedRange,
|
|
362
444
|
selectedDates,
|
|
363
445
|
minDate,
|
|
@@ -367,6 +449,7 @@ function MonthView({ date, weekStartsOn = 0, events, eventsByDay: eventsByDayPro
|
|
|
367
449
|
}), [
|
|
368
450
|
date,
|
|
369
451
|
weekStartsOn,
|
|
452
|
+
weekdayFormat,
|
|
370
453
|
selectedRange,
|
|
371
454
|
selectedDates,
|
|
372
455
|
minDate,
|
|
@@ -393,6 +476,46 @@ function MonthView({ date, weekStartsOn = 0, events, eventsByDay: eventsByDayPro
|
|
|
393
476
|
const [hoveredKey, setHoveredKey] = useState(null);
|
|
394
477
|
const gridRef = useRef(null);
|
|
395
478
|
const focusKey = format(focusedDate, "yyyy-MM-dd");
|
|
479
|
+
const [creating, setCreating] = useState(null);
|
|
480
|
+
const creatingRef = useRef(creating);
|
|
481
|
+
creatingRef.current = creating;
|
|
482
|
+
const movedRef = useRef(false);
|
|
483
|
+
const suppressClickRef = useRef(false);
|
|
484
|
+
const beginCreate = (day) => {
|
|
485
|
+
if (!onCreateEvent) return;
|
|
486
|
+
const t = startOfDay(day).getTime();
|
|
487
|
+
movedRef.current = false;
|
|
488
|
+
setCreating({
|
|
489
|
+
anchor: t,
|
|
490
|
+
hover: t
|
|
491
|
+
});
|
|
492
|
+
};
|
|
493
|
+
const extendCreate = (day) => {
|
|
494
|
+
if (!creatingRef.current) return;
|
|
495
|
+
const t = startOfDay(day).getTime();
|
|
496
|
+
if (t !== creatingRef.current.hover) {
|
|
497
|
+
movedRef.current = true;
|
|
498
|
+
setCreating((c) => c ? {
|
|
499
|
+
...c,
|
|
500
|
+
hover: t
|
|
501
|
+
} : c);
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
const isCreating = creating !== null;
|
|
505
|
+
useEffect(() => {
|
|
506
|
+
if (!isCreating) return;
|
|
507
|
+
const finish = () => {
|
|
508
|
+
const c = creatingRef.current;
|
|
509
|
+
setCreating(null);
|
|
510
|
+
if (!c || !movedRef.current) return;
|
|
511
|
+
suppressClickRef.current = true;
|
|
512
|
+
const lo = Math.min(c.anchor, c.hover);
|
|
513
|
+
const hi = Math.max(c.anchor, c.hover);
|
|
514
|
+
onCreateEvent?.(new Date(lo), addDays(new Date(hi), 1));
|
|
515
|
+
};
|
|
516
|
+
window.addEventListener("pointerup", finish);
|
|
517
|
+
return () => window.removeEventListener("pointerup", finish);
|
|
518
|
+
}, [isCreating, onCreateEvent]);
|
|
396
519
|
const onKeyDown = (e) => {
|
|
397
520
|
let next = null;
|
|
398
521
|
if (e.key === "ArrowLeft") next = addDays(focusedDate, -1);
|
|
@@ -417,27 +540,31 @@ function MonthView({ date, weekStartsOn = 0, events, eventsByDay: eventsByDayPro
|
|
|
417
540
|
},
|
|
418
541
|
children: [
|
|
419
542
|
showTitle ? /* @__PURE__ */ jsx("div", {
|
|
420
|
-
|
|
543
|
+
...slot("title", { themed: {
|
|
421
544
|
fontSize: 17,
|
|
422
545
|
fontWeight: 700,
|
|
423
546
|
padding: "10px 14px 6px"
|
|
424
|
-
},
|
|
547
|
+
} }),
|
|
425
548
|
children: format(date, "MMMM yyyy", locale ? { locale } : void 0)
|
|
426
549
|
}) : null,
|
|
427
550
|
showWeekdays ? /* @__PURE__ */ jsx("div", {
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
551
|
+
...slot("weekdays", {
|
|
552
|
+
base: {
|
|
553
|
+
display: "grid",
|
|
554
|
+
gridTemplateColumns: "repeat(7, minmax(0, 1fr))"
|
|
555
|
+
},
|
|
556
|
+
themed: {
|
|
557
|
+
borderBottom: `1px solid ${theme.gridLine}`,
|
|
558
|
+
padding: "6px 0"
|
|
559
|
+
}
|
|
560
|
+
}),
|
|
434
561
|
children: weekdays.map((wd) => /* @__PURE__ */ jsx("span", {
|
|
435
|
-
|
|
562
|
+
...slot("weekday", { themed: {
|
|
436
563
|
textAlign: "center",
|
|
437
564
|
fontSize: 12,
|
|
438
565
|
fontWeight: 600,
|
|
439
566
|
color: theme.textMuted
|
|
440
|
-
},
|
|
567
|
+
} }),
|
|
441
568
|
children: wd.label
|
|
442
569
|
}, wd.label))
|
|
443
570
|
}) : null,
|
|
@@ -446,12 +573,13 @@ function MonthView({ date, weekStartsOn = 0, events, eventsByDay: eventsByDayPro
|
|
|
446
573
|
role: "grid",
|
|
447
574
|
"aria-label": format(date, "MMMM yyyy", locale ? { locale } : void 0),
|
|
448
575
|
onKeyDown: dayRoving ? onKeyDown : void 0,
|
|
576
|
+
...slot("grid"),
|
|
449
577
|
children: weeks.map((week) => /* @__PURE__ */ jsx("div", {
|
|
450
578
|
role: "row",
|
|
451
|
-
|
|
579
|
+
...slot("week", { base: {
|
|
452
580
|
display: "grid",
|
|
453
581
|
gridTemplateColumns: "repeat(7, minmax(0, 1fr))"
|
|
454
|
-
},
|
|
582
|
+
} }),
|
|
455
583
|
children: week.days.map((day) => {
|
|
456
584
|
const hidden = !showAdjacentMonths && !day.isCurrentMonth;
|
|
457
585
|
const cellHeight = eventsMode ? eventRowHeight : theme.cellHeight;
|
|
@@ -460,8 +588,19 @@ function MonthView({ date, weekStartsOn = 0, events, eventsByDay: eventsByDayPro
|
|
|
460
588
|
"aria-hidden": true,
|
|
461
589
|
style: { height: cellHeight }
|
|
462
590
|
}, day.id);
|
|
463
|
-
const band =
|
|
591
|
+
const band = rangeBandDefault(day, theme, fillCellOnSelection);
|
|
464
592
|
const label = format(day.date, "EEEE, d MMMM yyyy", locale ? { locale } : void 0);
|
|
593
|
+
const dayTime = startOfDay(day.date).getTime();
|
|
594
|
+
const inCreate = creating != null && dayTime >= Math.min(creating.anchor, creating.hover) && dayTime <= Math.max(creating.anchor, creating.hover);
|
|
595
|
+
const dayData = dataState({
|
|
596
|
+
"data-today": day.isToday,
|
|
597
|
+
"data-selected": day.isSelected,
|
|
598
|
+
"data-range": day.isInRange,
|
|
599
|
+
"data-weekend": day.isWeekend,
|
|
600
|
+
"data-outside": !day.isCurrentMonth,
|
|
601
|
+
"data-disabled": day.isDisabled,
|
|
602
|
+
"data-creating": inCreate
|
|
603
|
+
});
|
|
465
604
|
if (eventsMode) {
|
|
466
605
|
const dayEvents = eventsByDay.get(startOfDay(day.date).toISOString()) ?? [];
|
|
467
606
|
const visible = monthVisibleCount(dayEvents.length, {
|
|
@@ -472,14 +611,30 @@ function MonthView({ date, weekStartsOn = 0, events, eventsByDay: eventsByDayPro
|
|
|
472
611
|
const rest = dayEvents.slice(visible);
|
|
473
612
|
const overflow = rest.length > 0;
|
|
474
613
|
const dayLabel = format(day.date, "d MMMM", locale ? { locale } : void 0);
|
|
614
|
+
const dayCellProps = slot("day", eventCellDefault(day, theme, cellHeight));
|
|
475
615
|
return /* @__PURE__ */ jsxs("div", {
|
|
476
616
|
role: "gridcell",
|
|
477
617
|
"data-day": day.id,
|
|
618
|
+
...dayData,
|
|
478
619
|
tabIndex: keyboardDayNavigation ? day.id === focusKey ? 0 : -1 : void 0,
|
|
479
620
|
"aria-disabled": day.isDisabled || void 0,
|
|
480
621
|
"aria-label": label,
|
|
481
|
-
|
|
482
|
-
|
|
622
|
+
...dayCellProps,
|
|
623
|
+
style: onCreateEvent ? {
|
|
624
|
+
...dayCellProps.style,
|
|
625
|
+
touchAction: "none"
|
|
626
|
+
} : dayCellProps.style,
|
|
627
|
+
onPointerDown: onCreateEvent && !day.isDisabled ? (e) => {
|
|
628
|
+
if (e.button === 0) beginCreate(day.date);
|
|
629
|
+
} : void 0,
|
|
630
|
+
onPointerEnter: onCreateEvent ? () => extendCreate(day.date) : void 0,
|
|
631
|
+
onClick: day.isDisabled ? void 0 : () => {
|
|
632
|
+
if (suppressClickRef.current) {
|
|
633
|
+
suppressClickRef.current = false;
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
onPressDay?.(day.date);
|
|
637
|
+
},
|
|
483
638
|
onKeyDown: keyboardDayNavigation && !day.isDisabled ? (e) => {
|
|
484
639
|
if (e.target !== e.currentTarget) return;
|
|
485
640
|
if (e.key === "Enter" || e.key === " ") {
|
|
@@ -491,18 +646,19 @@ function MonthView({ date, weekStartsOn = 0, events, eventsByDay: eventsByDayPro
|
|
|
491
646
|
band ? /* @__PURE__ */ jsx("span", {
|
|
492
647
|
"data-band": true,
|
|
493
648
|
"aria-hidden": true,
|
|
494
|
-
|
|
649
|
+
...slot("rangeBand", band)
|
|
495
650
|
}) : null,
|
|
496
651
|
/* @__PURE__ */ jsx("span", {
|
|
497
|
-
|
|
652
|
+
...dayData,
|
|
653
|
+
...slot("dayBadge", compactBadgeDefault(day, theme)),
|
|
498
654
|
children: day.label
|
|
499
655
|
}),
|
|
500
656
|
/* @__PURE__ */ jsxs("div", {
|
|
501
|
-
|
|
657
|
+
...slot("events", { base: {
|
|
502
658
|
display: "flex",
|
|
503
659
|
flexDirection: "column",
|
|
504
660
|
gap: CHIP_GAP
|
|
505
|
-
},
|
|
661
|
+
} }),
|
|
506
662
|
children: [shown.map((event) => {
|
|
507
663
|
const onPress = () => onPressEvent?.(event);
|
|
508
664
|
return /* @__PURE__ */ jsx("button", {
|
|
@@ -511,14 +667,18 @@ function MonthView({ date, weekStartsOn = 0, events, eventsByDay: eventsByDayPro
|
|
|
511
667
|
e.stopPropagation();
|
|
512
668
|
onPress();
|
|
513
669
|
},
|
|
514
|
-
|
|
670
|
+
...slot("chipButton", chipButtonDefault),
|
|
515
671
|
title: event.title,
|
|
516
|
-
"aria-label":
|
|
672
|
+
"aria-label": eventAccessibilityLabel ? eventAccessibilityLabel(event, {
|
|
673
|
+
mode: "month",
|
|
674
|
+
isAllDay: isAllDayEvent$1(event),
|
|
675
|
+
ampm: false
|
|
676
|
+
}) : `${event.title}, ${dayLabel}`,
|
|
517
677
|
children: Chip ? /* @__PURE__ */ jsx(Chip, {
|
|
518
678
|
event,
|
|
519
679
|
onPress
|
|
520
680
|
}) : /* @__PURE__ */ jsx("span", {
|
|
521
|
-
|
|
681
|
+
...slot("chip", chipDefault(theme)),
|
|
522
682
|
children: event.title
|
|
523
683
|
})
|
|
524
684
|
}, `${event.start.toISOString()}:${event.title}`);
|
|
@@ -528,7 +688,7 @@ function MonthView({ date, weekStartsOn = 0, events, eventsByDay: eventsByDayPro
|
|
|
528
688
|
e.stopPropagation();
|
|
529
689
|
onPressMore?.(rest, day.date);
|
|
530
690
|
},
|
|
531
|
-
|
|
691
|
+
...slot("more", moreButtonDefault(theme)),
|
|
532
692
|
"aria-label": `${rest.length} more events, ${dayLabel}`,
|
|
533
693
|
children: moreLabel.replace("{moreCount}", String(rest.length))
|
|
534
694
|
}) : null]
|
|
@@ -540,20 +700,22 @@ function MonthView({ date, weekStartsOn = 0, events, eventsByDay: eventsByDayPro
|
|
|
540
700
|
type: "button",
|
|
541
701
|
role: "gridcell",
|
|
542
702
|
"data-day": day.id,
|
|
703
|
+
...dayData,
|
|
543
704
|
tabIndex: day.id === focusKey ? 0 : -1,
|
|
544
705
|
"aria-disabled": day.isDisabled || void 0,
|
|
545
706
|
"aria-label": label,
|
|
546
707
|
"aria-pressed": day.isSelected || day.isInRange,
|
|
547
|
-
|
|
708
|
+
...slot("day", dayCellDefault(day, theme)),
|
|
548
709
|
onClick: day.isDisabled ? void 0 : () => onPressDay?.(day.date),
|
|
549
710
|
onMouseEnter: day.isDisabled ? void 0 : () => setHoveredKey(day.id),
|
|
550
711
|
onMouseLeave: () => setHoveredKey((k) => k === day.id ? null : k),
|
|
551
712
|
children: [band ? /* @__PURE__ */ jsx("span", {
|
|
552
713
|
"data-band": true,
|
|
553
714
|
"aria-hidden": true,
|
|
554
|
-
|
|
715
|
+
...slot("rangeBand", band)
|
|
555
716
|
}) : null, /* @__PURE__ */ jsx("span", {
|
|
556
|
-
|
|
717
|
+
...dayData,
|
|
718
|
+
...slot("dayBadge", badgeDefault(day, theme, hoveredKey === day.id)),
|
|
557
719
|
children: day.label
|
|
558
720
|
})]
|
|
559
721
|
}, day.id);
|
|
@@ -567,11 +729,11 @@ function MonthView({ date, weekStartsOn = 0, events, eventsByDay: eventsByDayPro
|
|
|
567
729
|
//#region src/TimeGrid.tsx
|
|
568
730
|
const HOURS = Array.from({ length: 24 }, (_, h) => h);
|
|
569
731
|
const GUTTER_WIDTH = 56;
|
|
570
|
-
const clamp = (v, lo, hi) => Math.min(hi, Math.max(lo, v));
|
|
732
|
+
const clamp$1 = (v, lo, hi) => Math.min(hi, Math.max(lo, v));
|
|
571
733
|
const DOM_TITLE_LINE_HEIGHT = 16;
|
|
572
734
|
const DOM_TIME_LINE_HEIGHT = 30;
|
|
573
735
|
const DOM_BOX_PADDING_V = 2;
|
|
574
|
-
function DefaultDomEvent({ event, mode, isAllDay, boxHeight, ampm = false, theme }) {
|
|
736
|
+
function DefaultDomEvent({ event, mode, isAllDay, boxHeight, ampm = false, theme, boxProps }) {
|
|
575
737
|
const timeLabel = eventTimeLabel({
|
|
576
738
|
mode,
|
|
577
739
|
isAllDay,
|
|
@@ -589,17 +751,34 @@ function DefaultDomEvent({ event, mode, isAllDay, boxHeight, ampm = false, theme
|
|
|
589
751
|
paddingYPx: DOM_BOX_PADDING_V
|
|
590
752
|
});
|
|
591
753
|
const oneLine = titleNumberOfLines(mode, isAllDay) === 1;
|
|
754
|
+
const boxBase = {
|
|
755
|
+
height: "100%",
|
|
756
|
+
boxSizing: "border-box",
|
|
757
|
+
overflow: "hidden",
|
|
758
|
+
lineHeight: `${DOM_TITLE_LINE_HEIGHT}px`,
|
|
759
|
+
...titleMaxLines === 1 && !showTime ? {
|
|
760
|
+
display: "flex",
|
|
761
|
+
flexDirection: "column",
|
|
762
|
+
justifyContent: "center"
|
|
763
|
+
} : null
|
|
764
|
+
};
|
|
765
|
+
const boxThemed = {
|
|
766
|
+
padding: `${DOM_BOX_PADDING_V}px 6px`,
|
|
767
|
+
borderRadius: 6,
|
|
768
|
+
background: theme.eventBackground,
|
|
769
|
+
color: theme.eventText,
|
|
770
|
+
fontSize: 12
|
|
771
|
+
};
|
|
592
772
|
return /* @__PURE__ */ jsxs("div", {
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
lineHeight: `${DOM_TITLE_LINE_HEIGHT}px`
|
|
773
|
+
className: boxProps?.className,
|
|
774
|
+
"data-slot": boxProps?.["data-slot"],
|
|
775
|
+
style: boxProps?.className ? {
|
|
776
|
+
...boxBase,
|
|
777
|
+
...boxProps.style
|
|
778
|
+
} : {
|
|
779
|
+
...boxBase,
|
|
780
|
+
...boxThemed,
|
|
781
|
+
...boxProps?.style
|
|
603
782
|
},
|
|
604
783
|
children: [/* @__PURE__ */ jsx("div", {
|
|
605
784
|
style: {
|
|
@@ -632,8 +811,12 @@ function DefaultDomEvent({ event, mode, isAllDay, boxHeight, ampm = false, theme
|
|
|
632
811
|
* <TimeGrid mode="week" date={new Date()} events={events} />
|
|
633
812
|
* ```
|
|
634
813
|
*/
|
|
635
|
-
function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStartsOn = 0, hourHeight: initialHourHeight = 48, scrollOffsetMinutes = 480, zoomable = true, minHourHeight = 24, maxHourHeight = 160, dragStepMinutes = 15, ampm = false, timeslots = 1, businessHours, showNowIndicator = true, showAllDayEventCell = true, locale, theme: themeOverrides, height = 600, renderEvent, hourComponent, onPressEvent, onPressDateHeader, onPressCell, onCreateEvent, onDragStart, onDragEvent, className, style }) {
|
|
814
|
+
function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStartsOn = 0, weekdayFormat = "short", hourHeight: initialHourHeight = 48, scrollOffsetMinutes = 480, zoomable = true, minHourHeight = 24, maxHourHeight = 160, dragStepMinutes = 15, ampm = false, timeslots = 1, businessHours, showNowIndicator = true, showAllDayEventCell = true, locale, theme: themeOverrides, height = 600, renderEvent, eventAccessibilityLabel: eventAccessibilityLabel$1, hourComponent, onPressEvent, onPressDateHeader, onPressCell, onCreateEvent, onDragStart, onDragEvent, className, style, classNames, styles }) {
|
|
636
815
|
const theme = useMemo(() => mergeDomTheme(themeOverrides), [themeOverrides]);
|
|
816
|
+
const slot = createSlots({
|
|
817
|
+
classNames,
|
|
818
|
+
styles
|
|
819
|
+
});
|
|
637
820
|
const scrollRef = useRef(null);
|
|
638
821
|
const dfns = locale ? { locale } : void 0;
|
|
639
822
|
const snapHours = dragStepMinutes / 60;
|
|
@@ -672,7 +855,7 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
672
855
|
const onWheel = (e) => {
|
|
673
856
|
if (!e.ctrlKey && !e.metaKey) return;
|
|
674
857
|
e.preventDefault();
|
|
675
|
-
setHourHeight((h) => clamp(h * (1 - e.deltaY * .0015), minHourHeight, maxHourHeight));
|
|
858
|
+
setHourHeight((h) => clamp$1(h * (1 - e.deltaY * .0015), minHourHeight, maxHourHeight));
|
|
676
859
|
};
|
|
677
860
|
el.addEventListener("wheel", onWheel, { passive: false });
|
|
678
861
|
return () => el.removeEventListener("wheel", onWheel);
|
|
@@ -700,7 +883,7 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
700
883
|
if (pinch.current.size === 2 && pinchBase.current) {
|
|
701
884
|
const ys = [...pinch.current.values()];
|
|
702
885
|
const ratio = Math.abs(ys[0] - ys[1]) / (pinchBase.current.dist || 1);
|
|
703
|
-
setHourHeight(clamp(pinchBase.current.height * ratio, minHourHeight, maxHourHeight));
|
|
886
|
+
setHourHeight(clamp$1(pinchBase.current.height * ratio, minHourHeight, maxHourHeight));
|
|
704
887
|
}
|
|
705
888
|
};
|
|
706
889
|
const onBodyPointerUp = (e) => {
|
|
@@ -739,14 +922,14 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
739
922
|
const dHours = (e.clientY - dragOrigin.current.pointerY) / hourHeightRef.current;
|
|
740
923
|
const snap = (v) => Math.round(v / snapHours) * snapHours;
|
|
741
924
|
if (d.kind === "move") {
|
|
742
|
-
const startHours = clamp(snap(dragOrigin.current.startHours + dHours), 0, 24 - d.durationHours);
|
|
925
|
+
const startHours = clamp$1(snap(dragOrigin.current.startHours + dHours), 0, 24 - d.durationHours);
|
|
743
926
|
applyDrag({
|
|
744
927
|
...d,
|
|
745
928
|
startHours,
|
|
746
929
|
moved: true
|
|
747
930
|
});
|
|
748
931
|
} else {
|
|
749
|
-
const durationHours = clamp(snap(dragOrigin.current.durationHours + dHours), snapHours, 24 - d.startHours);
|
|
932
|
+
const durationHours = clamp$1(snap(dragOrigin.current.durationHours + dHours), snapHours, 24 - d.startHours);
|
|
750
933
|
applyDrag({
|
|
751
934
|
...d,
|
|
752
935
|
durationHours,
|
|
@@ -849,10 +1032,10 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
849
1032
|
},
|
|
850
1033
|
children: [
|
|
851
1034
|
/* @__PURE__ */ jsxs("div", {
|
|
852
|
-
|
|
853
|
-
display: "flex",
|
|
854
|
-
borderBottom: `1px solid ${theme.gridLine}`
|
|
855
|
-
},
|
|
1035
|
+
...slot("header", {
|
|
1036
|
+
base: { display: "flex" },
|
|
1037
|
+
themed: { borderBottom: `1px solid ${theme.gridLine}` }
|
|
1038
|
+
}),
|
|
856
1039
|
children: [/* @__PURE__ */ jsx("div", { style: {
|
|
857
1040
|
width: GUTTER_WIDTH,
|
|
858
1041
|
flex: "none"
|
|
@@ -863,63 +1046,77 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
863
1046
|
tabIndex: onPressDateHeader ? 0 : -1,
|
|
864
1047
|
"aria-hidden": onPressDateHeader ? void 0 : true,
|
|
865
1048
|
onClick: onPressDateHeader ? () => onPressDateHeader(day) : void 0,
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
1049
|
+
...dataState({ "data-today": today }),
|
|
1050
|
+
...slot("columnHeader", {
|
|
1051
|
+
base: {
|
|
1052
|
+
flex: 1,
|
|
1053
|
+
border: "none",
|
|
1054
|
+
background: "transparent",
|
|
1055
|
+
font: "inherit",
|
|
1056
|
+
cursor: onPressDateHeader ? "pointer" : "default",
|
|
1057
|
+
display: "flex",
|
|
1058
|
+
flexDirection: "column",
|
|
1059
|
+
alignItems: "center",
|
|
1060
|
+
gap: 2
|
|
1061
|
+
},
|
|
1062
|
+
themed: {
|
|
1063
|
+
color: theme.textMuted,
|
|
1064
|
+
padding: "6px 0"
|
|
1065
|
+
}
|
|
1066
|
+
}),
|
|
879
1067
|
children: [/* @__PURE__ */ jsx("span", {
|
|
880
|
-
|
|
1068
|
+
...slot("columnHeaderWeekday", { themed: {
|
|
881
1069
|
fontSize: 11,
|
|
882
1070
|
fontWeight: 600
|
|
883
|
-
},
|
|
884
|
-
children: format(day,
|
|
1071
|
+
} }),
|
|
1072
|
+
children: format(day, weekdayFormatToken$1(weekdayFormat), dfns)
|
|
885
1073
|
}), /* @__PURE__ */ jsx("span", {
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
1074
|
+
...dataState({ "data-today": today }),
|
|
1075
|
+
...slot("columnHeaderDate", {
|
|
1076
|
+
base: {
|
|
1077
|
+
width: 28,
|
|
1078
|
+
height: 28,
|
|
1079
|
+
borderRadius: "50%",
|
|
1080
|
+
display: "flex",
|
|
1081
|
+
alignItems: "center",
|
|
1082
|
+
justifyContent: "center"
|
|
1083
|
+
},
|
|
1084
|
+
themed: {
|
|
1085
|
+
fontSize: 15,
|
|
1086
|
+
fontWeight: 600,
|
|
1087
|
+
background: today ? theme.todayBackground : "transparent",
|
|
1088
|
+
color: today ? theme.todayText : theme.text
|
|
1089
|
+
}
|
|
1090
|
+
}),
|
|
898
1091
|
children: format(day, "d", dfns)
|
|
899
1092
|
})]
|
|
900
1093
|
}, day.toISOString());
|
|
901
1094
|
})]
|
|
902
1095
|
}),
|
|
903
1096
|
showAllDayEventCell && hasAllDay ? /* @__PURE__ */ jsxs("div", {
|
|
904
|
-
|
|
905
|
-
display: "flex",
|
|
906
|
-
borderBottom: `1px solid ${theme.gridLine}`
|
|
907
|
-
},
|
|
1097
|
+
...slot("allDayLane", {
|
|
1098
|
+
base: { display: "flex" },
|
|
1099
|
+
themed: { borderBottom: `1px solid ${theme.gridLine}` }
|
|
1100
|
+
}),
|
|
908
1101
|
children: [/* @__PURE__ */ jsx("div", {
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
1102
|
+
...slot("allDayLabel", {
|
|
1103
|
+
base: {
|
|
1104
|
+
width: GUTTER_WIDTH,
|
|
1105
|
+
flex: "none",
|
|
1106
|
+
textAlign: "right"
|
|
1107
|
+
},
|
|
1108
|
+
themed: {
|
|
1109
|
+
fontSize: 10,
|
|
1110
|
+
color: theme.textMuted,
|
|
1111
|
+
padding: "4px 6px 0 0"
|
|
1112
|
+
}
|
|
1113
|
+
}),
|
|
917
1114
|
children: "all-day"
|
|
918
1115
|
}), allDayByDay.map((list, i) => {
|
|
919
1116
|
const dayStart = startOfDay(days[i]);
|
|
920
1117
|
const dayEnd = addDays(dayStart, 1);
|
|
921
1118
|
return /* @__PURE__ */ jsx("div", {
|
|
922
|
-
|
|
1119
|
+
...slot("allDayColumn", { base: {
|
|
923
1120
|
flex: 1,
|
|
924
1121
|
minWidth: 0,
|
|
925
1122
|
borderLeft: "1px solid transparent",
|
|
@@ -927,7 +1124,7 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
927
1124
|
display: "flex",
|
|
928
1125
|
flexDirection: "column",
|
|
929
1126
|
gap: 2
|
|
930
|
-
},
|
|
1127
|
+
} }),
|
|
931
1128
|
children: list.map((event) => {
|
|
932
1129
|
const args = {
|
|
933
1130
|
event,
|
|
@@ -941,24 +1138,29 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
941
1138
|
return /* @__PURE__ */ jsx("button", {
|
|
942
1139
|
type: "button",
|
|
943
1140
|
onClick: () => onPressEvent?.(event),
|
|
944
|
-
"aria-label": eventAccessibilityLabel({
|
|
1141
|
+
"aria-label": eventAccessibilityLabel$1 ? eventAccessibilityLabel$1(event, {
|
|
1142
|
+
mode,
|
|
1143
|
+
isAllDay: true,
|
|
1144
|
+
ampm
|
|
1145
|
+
}) : eventAccessibilityLabel({
|
|
945
1146
|
title: event.title,
|
|
946
1147
|
isAllDay: true,
|
|
947
1148
|
start: event.start,
|
|
948
1149
|
end: event.end,
|
|
949
1150
|
ampm
|
|
950
1151
|
}),
|
|
951
|
-
|
|
1152
|
+
...slot("allDayEvent", { base: {
|
|
952
1153
|
border: "none",
|
|
953
1154
|
padding: 0,
|
|
954
1155
|
background: "transparent",
|
|
955
1156
|
cursor: "pointer",
|
|
956
1157
|
textAlign: "left",
|
|
957
1158
|
height: 22
|
|
958
|
-
},
|
|
1159
|
+
} }),
|
|
959
1160
|
children: Renderer ? /* @__PURE__ */ jsx(Renderer, { ...args }) : /* @__PURE__ */ jsx(DefaultDomEvent, {
|
|
960
1161
|
...args,
|
|
961
|
-
theme
|
|
1162
|
+
theme,
|
|
1163
|
+
boxProps: slot("eventBox")
|
|
962
1164
|
})
|
|
963
1165
|
}, `${event.start.toISOString()}:${event.title}`);
|
|
964
1166
|
})
|
|
@@ -984,19 +1186,23 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
984
1186
|
position: "relative"
|
|
985
1187
|
},
|
|
986
1188
|
children: [/* @__PURE__ */ jsx("div", {
|
|
987
|
-
|
|
1189
|
+
...slot("hourGutter", { base: {
|
|
988
1190
|
width: GUTTER_WIDTH,
|
|
989
1191
|
flex: "none",
|
|
990
1192
|
position: "relative"
|
|
991
|
-
},
|
|
1193
|
+
} }),
|
|
992
1194
|
children: HOURS.map((h) => /* @__PURE__ */ jsx("div", {
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1195
|
+
...slot("hourLabel", {
|
|
1196
|
+
base: {
|
|
1197
|
+
position: "absolute",
|
|
1198
|
+
top: h * hourHeight - 6,
|
|
1199
|
+
right: 6
|
|
1200
|
+
},
|
|
1201
|
+
themed: {
|
|
1202
|
+
fontSize: 10,
|
|
1203
|
+
color: theme.textMuted
|
|
1204
|
+
}
|
|
1205
|
+
}),
|
|
1000
1206
|
children: hourComponent ? hourComponent(h, ampm) : h === 0 ? "" : formatHour(h, { ampm })
|
|
1001
1207
|
}, h))
|
|
1002
1208
|
}), days.map((day, dayIndex) => {
|
|
@@ -1011,34 +1217,47 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
1011
1217
|
onPointerMove: cellEnabled ? moveCreate : void 0,
|
|
1012
1218
|
onPointerUp: cellEnabled ? endCreate : void 0,
|
|
1013
1219
|
onPointerCancel: cellEnabled ? cancelCreate : void 0,
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1220
|
+
...dataState({
|
|
1221
|
+
"data-today": getIsToday(day),
|
|
1222
|
+
"data-weekend": isWeekend(day)
|
|
1223
|
+
}),
|
|
1224
|
+
...slot("dayColumn", {
|
|
1225
|
+
base: {
|
|
1226
|
+
flex: 1,
|
|
1227
|
+
position: "relative"
|
|
1228
|
+
},
|
|
1229
|
+
themed: {
|
|
1230
|
+
borderLeft: `1px solid ${theme.gridLine}`,
|
|
1231
|
+
...isWeekend(day) ? { background: theme.weekendBackground } : null
|
|
1232
|
+
}
|
|
1233
|
+
}),
|
|
1019
1234
|
children: [
|
|
1020
1235
|
bands.map((b) => /* @__PURE__ */ jsx("div", {
|
|
1021
1236
|
"aria-hidden": true,
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1237
|
+
...slot("businessHours", {
|
|
1238
|
+
base: {
|
|
1239
|
+
position: "absolute",
|
|
1240
|
+
left: 0,
|
|
1241
|
+
right: 0,
|
|
1242
|
+
top: b.start * hourHeight,
|
|
1243
|
+
height: (b.end - b.start) * hourHeight,
|
|
1244
|
+
pointerEvents: "none",
|
|
1245
|
+
zIndex: 0
|
|
1246
|
+
},
|
|
1247
|
+
themed: { background: theme.outsideHoursBackground }
|
|
1248
|
+
})
|
|
1032
1249
|
}, b.start)),
|
|
1033
1250
|
/* @__PURE__ */ jsx("div", {
|
|
1034
1251
|
"aria-hidden": true,
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1252
|
+
...slot("gridLines", {
|
|
1253
|
+
base: {
|
|
1254
|
+
position: "absolute",
|
|
1255
|
+
inset: 0,
|
|
1256
|
+
pointerEvents: "none",
|
|
1257
|
+
zIndex: 0
|
|
1258
|
+
},
|
|
1259
|
+
themed: { backgroundImage: gridLines }
|
|
1260
|
+
})
|
|
1042
1261
|
}),
|
|
1043
1262
|
positioned.map((pe, idx) => {
|
|
1044
1263
|
const key = `${dayIndex}:${idx}`;
|
|
@@ -1063,7 +1282,11 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
1063
1282
|
return /* @__PURE__ */ jsxs("div", {
|
|
1064
1283
|
role: "button",
|
|
1065
1284
|
tabIndex: 0,
|
|
1066
|
-
"aria-label": eventAccessibilityLabel({
|
|
1285
|
+
"aria-label": eventAccessibilityLabel$1 ? eventAccessibilityLabel$1(pe.event, {
|
|
1286
|
+
mode,
|
|
1287
|
+
isAllDay: false,
|
|
1288
|
+
ampm
|
|
1289
|
+
}) : eventAccessibilityLabel({
|
|
1067
1290
|
title: pe.event.title,
|
|
1068
1291
|
isAllDay: false,
|
|
1069
1292
|
start: pe.event.start,
|
|
@@ -1081,7 +1304,8 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
1081
1304
|
onPointerUp: draggable ? (e) => endDrag(e, day, pe.event, onPress) : void 0,
|
|
1082
1305
|
onPointerCancel: draggable ? cancelDrag : void 0,
|
|
1083
1306
|
onClick: draggable ? void 0 : onPress,
|
|
1084
|
-
|
|
1307
|
+
...dataState({ "data-dragging": !!active }),
|
|
1308
|
+
...slot("event", { base: {
|
|
1085
1309
|
position: "absolute",
|
|
1086
1310
|
top,
|
|
1087
1311
|
height: boxHeight,
|
|
@@ -1091,10 +1315,11 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
1091
1315
|
touchAction: draggable ? "none" : "auto",
|
|
1092
1316
|
zIndex: active ? 3 : 1,
|
|
1093
1317
|
opacity: active ? .85 : 1
|
|
1094
|
-
},
|
|
1318
|
+
} }),
|
|
1095
1319
|
children: [Renderer ? /* @__PURE__ */ jsx(Renderer, { ...args }) : /* @__PURE__ */ jsx(DefaultDomEvent, {
|
|
1096
1320
|
...args,
|
|
1097
|
-
theme
|
|
1321
|
+
theme,
|
|
1322
|
+
boxProps: slot("eventBox")
|
|
1098
1323
|
}), draggable ? /* @__PURE__ */ jsx("div", {
|
|
1099
1324
|
onPointerDown: (e) => {
|
|
1100
1325
|
e.stopPropagation();
|
|
@@ -1113,7 +1338,7 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
1113
1338
|
}, idx);
|
|
1114
1339
|
}),
|
|
1115
1340
|
showNow ? /* @__PURE__ */ jsxs("div", {
|
|
1116
|
-
|
|
1341
|
+
...slot("nowIndicator", { base: {
|
|
1117
1342
|
position: "absolute",
|
|
1118
1343
|
top: nowTop,
|
|
1119
1344
|
left: 0,
|
|
@@ -1121,7 +1346,7 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
1121
1346
|
height: 0,
|
|
1122
1347
|
zIndex: 2,
|
|
1123
1348
|
pointerEvents: "none"
|
|
1124
|
-
},
|
|
1349
|
+
} }),
|
|
1125
1350
|
children: [/* @__PURE__ */ jsx("div", { style: {
|
|
1126
1351
|
height: 2,
|
|
1127
1352
|
background: theme.nowIndicator
|
|
@@ -1137,19 +1362,23 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
1137
1362
|
}) : null,
|
|
1138
1363
|
ghost ? /* @__PURE__ */ jsx("div", {
|
|
1139
1364
|
"aria-hidden": true,
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1365
|
+
...slot("createGhost", {
|
|
1366
|
+
base: {
|
|
1367
|
+
position: "absolute",
|
|
1368
|
+
left: 1,
|
|
1369
|
+
right: 1,
|
|
1370
|
+
top: ghost.topPx,
|
|
1371
|
+
height: Math.max(ghost.heightPx, 2),
|
|
1372
|
+
opacity: .7,
|
|
1373
|
+
pointerEvents: "none",
|
|
1374
|
+
zIndex: 2
|
|
1375
|
+
},
|
|
1376
|
+
themed: {
|
|
1377
|
+
background: theme.rangeBackground,
|
|
1378
|
+
border: `1px solid ${theme.selectedBackground}`,
|
|
1379
|
+
borderRadius: 6
|
|
1380
|
+
}
|
|
1381
|
+
})
|
|
1153
1382
|
}) : null
|
|
1154
1383
|
]
|
|
1155
1384
|
}, day.toISOString());
|
|
@@ -1172,7 +1401,7 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
1172
1401
|
* <Calendar mode="week" date={new Date()} events={events} />
|
|
1173
1402
|
* ```
|
|
1174
1403
|
*/
|
|
1175
|
-
function Calendar({ mode = "week", date, events, weekStartsOn = 0, numberOfDays, locale, theme, height, className, style, onPressEvent, ampm, hourHeight, scrollOffsetMinutes, timeslots, businessHours, showNowIndicator, showAllDayEventCell, dragStepMinutes, onPressCell, onCreateEvent, onDragStart, onDragEvent, onPressDateHeader, renderTimeEvent, hourComponent, maxVisibleEventCount, moreLabel, showAdjacentMonths, fillCellOnSelection, selectedRange, selectedDates, minDate, maxDate, isDateDisabled, keyboardDayNavigation, onPressDay, onPressMore, renderMonthEvent, renderScheduleEvent }) {
|
|
1404
|
+
function Calendar({ mode = "week", date, events, weekStartsOn = 0, numberOfDays, locale, theme, height, className, style, onPressEvent, eventAccessibilityLabel, ampm, hourHeight, scrollOffsetMinutes, timeslots, businessHours, showNowIndicator, showAllDayEventCell, dragStepMinutes, onPressCell, onCreateEvent, onDragStart, onDragEvent, onPressDateHeader, renderTimeEvent, hourComponent, maxVisibleEventCount, moreLabel, showAdjacentMonths, weekdayFormat, fillCellOnSelection, selectedRange, selectedDates, minDate, maxDate, isDateDisabled, keyboardDayNavigation, onPressDay, onPressMore, renderMonthEvent, renderScheduleEvent, classNames, styles }) {
|
|
1176
1405
|
if (mode === "schedule") return /* @__PURE__ */ jsx(Agenda, {
|
|
1177
1406
|
events: events ?? [],
|
|
1178
1407
|
locale,
|
|
@@ -1182,7 +1411,10 @@ function Calendar({ mode = "week", date, events, weekStartsOn = 0, numberOfDays,
|
|
|
1182
1411
|
activeDate: date,
|
|
1183
1412
|
className,
|
|
1184
1413
|
style,
|
|
1414
|
+
classNames,
|
|
1415
|
+
styles,
|
|
1185
1416
|
renderEvent: renderScheduleEvent,
|
|
1417
|
+
eventAccessibilityLabel,
|
|
1186
1418
|
onPressEvent,
|
|
1187
1419
|
onPressDay
|
|
1188
1420
|
});
|
|
@@ -1190,10 +1422,13 @@ function Calendar({ mode = "week", date, events, weekStartsOn = 0, numberOfDays,
|
|
|
1190
1422
|
date,
|
|
1191
1423
|
events: events ?? [],
|
|
1192
1424
|
weekStartsOn,
|
|
1425
|
+
weekdayFormat,
|
|
1193
1426
|
locale,
|
|
1194
1427
|
theme,
|
|
1195
1428
|
className,
|
|
1196
1429
|
style,
|
|
1430
|
+
classNames,
|
|
1431
|
+
styles,
|
|
1197
1432
|
maxVisibleEventCount,
|
|
1198
1433
|
moreLabel,
|
|
1199
1434
|
showAdjacentMonths,
|
|
@@ -1205,21 +1440,26 @@ function Calendar({ mode = "week", date, events, weekStartsOn = 0, numberOfDays,
|
|
|
1205
1440
|
isDateDisabled,
|
|
1206
1441
|
keyboardDayNavigation,
|
|
1207
1442
|
onPressDay,
|
|
1443
|
+
onCreateEvent,
|
|
1208
1444
|
onPressEvent,
|
|
1209
1445
|
onPressMore,
|
|
1210
|
-
renderEvent: renderMonthEvent
|
|
1446
|
+
renderEvent: renderMonthEvent,
|
|
1447
|
+
eventAccessibilityLabel
|
|
1211
1448
|
});
|
|
1212
1449
|
return /* @__PURE__ */ jsx(TimeGrid, {
|
|
1213
1450
|
date,
|
|
1214
1451
|
mode,
|
|
1215
1452
|
events,
|
|
1216
1453
|
weekStartsOn,
|
|
1454
|
+
weekdayFormat,
|
|
1217
1455
|
numberOfDays,
|
|
1218
1456
|
locale,
|
|
1219
1457
|
theme,
|
|
1220
1458
|
height,
|
|
1221
1459
|
className,
|
|
1222
1460
|
style,
|
|
1461
|
+
classNames,
|
|
1462
|
+
styles,
|
|
1223
1463
|
ampm,
|
|
1224
1464
|
hourHeight,
|
|
1225
1465
|
scrollOffsetMinutes,
|
|
@@ -1235,6 +1475,7 @@ function Calendar({ mode = "week", date, events, weekStartsOn = 0, numberOfDays,
|
|
|
1235
1475
|
onDragEvent,
|
|
1236
1476
|
onPressDateHeader,
|
|
1237
1477
|
renderEvent: renderTimeEvent,
|
|
1478
|
+
eventAccessibilityLabel,
|
|
1238
1479
|
hourComponent
|
|
1239
1480
|
});
|
|
1240
1481
|
}
|
|
@@ -1245,8 +1486,12 @@ function Calendar({ mode = "week", date, events, weekStartsOn = 0, numberOfDays,
|
|
|
1245
1486
|
* Legend List's DOM renderer and the library's headless grid logic. Selection is
|
|
1246
1487
|
* controlled, pass `selectedRange` (or `selectedDates`) and handle `onPressDay`.
|
|
1247
1488
|
*/
|
|
1248
|
-
function MonthList({ date, pastMonths = 1, futureMonths = 12, weekStartsOn = 0, events, renderEvent, maxVisibleEventCount, moreLabel, onPressEvent, onPressMore, selectedRange, selectedDates, fillCellOnSelection = false, locale, theme: themeOverrides, height = 480, minDate, maxDate, isDateDisabled, keyboardDayNavigation, onPressDay, className, style }) {
|
|
1489
|
+
function MonthList({ date, pastMonths = 1, futureMonths = 12, weekdayFormat = "short", weekStartsOn = 0, events, renderEvent, eventAccessibilityLabel, maxVisibleEventCount, moreLabel, onPressEvent, onPressMore, selectedRange, selectedDates, fillCellOnSelection = false, locale, theme: themeOverrides, height = 480, minDate, maxDate, isDateDisabled, keyboardDayNavigation, onPressDay, className, style, classNames, styles }) {
|
|
1249
1490
|
const theme = useMemo(() => mergeDomTheme(themeOverrides), [themeOverrides]);
|
|
1491
|
+
const slot = createSlots({
|
|
1492
|
+
classNames,
|
|
1493
|
+
styles
|
|
1494
|
+
});
|
|
1250
1495
|
const months = useMemo(() => {
|
|
1251
1496
|
const first = startOfMonth(addMonths(date, -pastMonths));
|
|
1252
1497
|
const count = pastMonths + futureMonths + 1;
|
|
@@ -1258,10 +1503,12 @@ function MonthList({ date, pastMonths = 1, futureMonths = 12, weekStartsOn = 0,
|
|
|
1258
1503
|
]);
|
|
1259
1504
|
const weekdays = useMemo(() => buildMonthGrid$1(date, {
|
|
1260
1505
|
weekStartsOn,
|
|
1506
|
+
weekdayFormat,
|
|
1261
1507
|
locale
|
|
1262
1508
|
}).weekdays, [
|
|
1263
1509
|
date,
|
|
1264
1510
|
weekStartsOn,
|
|
1511
|
+
weekdayFormat,
|
|
1265
1512
|
locale
|
|
1266
1513
|
]);
|
|
1267
1514
|
const eventsByDay = useMemo(() => {
|
|
@@ -1287,19 +1534,23 @@ function MonthList({ date, pastMonths = 1, futureMonths = 12, weekStartsOn = 0,
|
|
|
1287
1534
|
...style
|
|
1288
1535
|
},
|
|
1289
1536
|
children: [/* @__PURE__ */ jsx("div", {
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1537
|
+
...slot("weekdays", {
|
|
1538
|
+
base: {
|
|
1539
|
+
display: "grid",
|
|
1540
|
+
gridTemplateColumns: "repeat(7, minmax(0, 1fr))"
|
|
1541
|
+
},
|
|
1542
|
+
themed: {
|
|
1543
|
+
borderBottom: `1px solid ${theme.gridLine}`,
|
|
1544
|
+
padding: "8px 0"
|
|
1545
|
+
}
|
|
1546
|
+
}),
|
|
1296
1547
|
children: weekdays.map((wd) => /* @__PURE__ */ jsx("span", {
|
|
1297
|
-
|
|
1548
|
+
...slot("weekday", { themed: {
|
|
1298
1549
|
textAlign: "center",
|
|
1299
1550
|
fontSize: 12,
|
|
1300
1551
|
fontWeight: 600,
|
|
1301
1552
|
color: theme.textMuted
|
|
1302
|
-
},
|
|
1553
|
+
} }),
|
|
1303
1554
|
children: wd.label
|
|
1304
1555
|
}, wd.label))
|
|
1305
1556
|
}), /* @__PURE__ */ jsx(LegendList, {
|
|
@@ -1319,6 +1570,7 @@ function MonthList({ date, pastMonths = 1, futureMonths = 12, weekStartsOn = 0,
|
|
|
1319
1570
|
events,
|
|
1320
1571
|
eventsByDay,
|
|
1321
1572
|
renderEvent,
|
|
1573
|
+
eventAccessibilityLabel,
|
|
1322
1574
|
maxVisibleEventCount,
|
|
1323
1575
|
moreLabel,
|
|
1324
1576
|
onPressEvent,
|
|
@@ -1334,10 +1586,562 @@ function MonthList({ date, pastMonths = 1, futureMonths = 12, weekStartsOn = 0,
|
|
|
1334
1586
|
maxDate,
|
|
1335
1587
|
isDateDisabled,
|
|
1336
1588
|
keyboardDayNavigation,
|
|
1337
|
-
onPressDay
|
|
1589
|
+
onPressDay,
|
|
1590
|
+
classNames,
|
|
1591
|
+
styles
|
|
1592
|
+
})
|
|
1593
|
+
})]
|
|
1594
|
+
});
|
|
1595
|
+
}
|
|
1596
|
+
//#endregion
|
|
1597
|
+
//#region src/DateRangePicker.tsx
|
|
1598
|
+
const triggerDefault = {
|
|
1599
|
+
display: "inline-flex",
|
|
1600
|
+
alignItems: "center",
|
|
1601
|
+
justifyContent: "space-between",
|
|
1602
|
+
gap: 8,
|
|
1603
|
+
minWidth: 220,
|
|
1604
|
+
padding: "8px 12px",
|
|
1605
|
+
borderRadius: 8,
|
|
1606
|
+
cursor: "pointer",
|
|
1607
|
+
font: "inherit",
|
|
1608
|
+
textAlign: "left"
|
|
1609
|
+
};
|
|
1610
|
+
const popoverDefault = {
|
|
1611
|
+
position: "absolute",
|
|
1612
|
+
zIndex: 20,
|
|
1613
|
+
marginTop: 6,
|
|
1614
|
+
overflow: "hidden",
|
|
1615
|
+
borderRadius: 12,
|
|
1616
|
+
minWidth: 300
|
|
1617
|
+
};
|
|
1618
|
+
/**
|
|
1619
|
+
* The shared popover shell: a trigger button and a calendar panel that closes on
|
|
1620
|
+
* outside-click and Escape, and returns focus to the trigger. `renderCalendar`
|
|
1621
|
+
* gets a close callback so a single-date pick can dismiss immediately.
|
|
1622
|
+
*/
|
|
1623
|
+
function usePopover() {
|
|
1624
|
+
const [open, setOpen] = useState(false);
|
|
1625
|
+
const rootRef = useRef(null);
|
|
1626
|
+
const triggerRef = useRef(null);
|
|
1627
|
+
useEffect(() => {
|
|
1628
|
+
if (!open) return;
|
|
1629
|
+
const onDown = (e) => {
|
|
1630
|
+
if (!rootRef.current?.contains(e.target)) setOpen(false);
|
|
1631
|
+
};
|
|
1632
|
+
const onKey = (e) => {
|
|
1633
|
+
if (e.key === "Escape") {
|
|
1634
|
+
setOpen(false);
|
|
1635
|
+
triggerRef.current?.focus();
|
|
1636
|
+
}
|
|
1637
|
+
};
|
|
1638
|
+
document.addEventListener("mousedown", onDown);
|
|
1639
|
+
document.addEventListener("keydown", onKey);
|
|
1640
|
+
return () => {
|
|
1641
|
+
document.removeEventListener("mousedown", onDown);
|
|
1642
|
+
document.removeEventListener("keydown", onKey);
|
|
1643
|
+
};
|
|
1644
|
+
}, [open]);
|
|
1645
|
+
return {
|
|
1646
|
+
open,
|
|
1647
|
+
setOpen,
|
|
1648
|
+
rootRef,
|
|
1649
|
+
triggerRef
|
|
1650
|
+
};
|
|
1651
|
+
}
|
|
1652
|
+
function PickerShell({ open, setOpen, rootRef, triggerRef, theme, slot, label, hasValue, placeholder, disabled, className, style, ariaLabel, children }) {
|
|
1653
|
+
const dialogId = useId();
|
|
1654
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1655
|
+
ref: rootRef,
|
|
1656
|
+
className,
|
|
1657
|
+
style: {
|
|
1658
|
+
position: "relative",
|
|
1659
|
+
display: "inline-block",
|
|
1660
|
+
fontFamily: theme.fontFamily,
|
|
1661
|
+
...style
|
|
1662
|
+
},
|
|
1663
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
1664
|
+
ref: triggerRef,
|
|
1665
|
+
type: "button",
|
|
1666
|
+
disabled,
|
|
1667
|
+
"aria-haspopup": "dialog",
|
|
1668
|
+
"aria-expanded": open,
|
|
1669
|
+
"aria-controls": open ? dialogId : void 0,
|
|
1670
|
+
onClick: () => setOpen(!open),
|
|
1671
|
+
...slot("trigger", {
|
|
1672
|
+
base: triggerDefault,
|
|
1673
|
+
themed: {
|
|
1674
|
+
border: `1px solid ${theme.gridLine}`,
|
|
1675
|
+
background: theme.eventBackground,
|
|
1676
|
+
color: hasValue ? theme.text : theme.textMuted,
|
|
1677
|
+
opacity: disabled ? .5 : 1
|
|
1678
|
+
}
|
|
1679
|
+
}),
|
|
1680
|
+
children: [/* @__PURE__ */ jsx("span", { children: hasValue ? label : placeholder }), /* @__PURE__ */ jsx("span", {
|
|
1681
|
+
"aria-hidden": true,
|
|
1682
|
+
children: "▾"
|
|
1683
|
+
})]
|
|
1684
|
+
}), open ? /* @__PURE__ */ jsx("div", {
|
|
1685
|
+
id: dialogId,
|
|
1686
|
+
role: "dialog",
|
|
1687
|
+
"aria-label": ariaLabel,
|
|
1688
|
+
...slot("popover", {
|
|
1689
|
+
base: popoverDefault,
|
|
1690
|
+
themed: {
|
|
1691
|
+
background: theme.eventBackground,
|
|
1692
|
+
border: `1px solid ${theme.gridLine}`
|
|
1693
|
+
}
|
|
1694
|
+
}),
|
|
1695
|
+
children
|
|
1696
|
+
}) : null]
|
|
1697
|
+
});
|
|
1698
|
+
}
|
|
1699
|
+
/**
|
|
1700
|
+
* A single-date input with a popover calendar. Controlled via `value` / `onChange`.
|
|
1701
|
+
* Composed from {@link MonthList}; forward calendar slots (e.g. `dayBadge`) through
|
|
1702
|
+
* `classNames` to restyle the popover.
|
|
1703
|
+
*
|
|
1704
|
+
* @example
|
|
1705
|
+
* ```tsx
|
|
1706
|
+
* const [value, setValue] = useState<Date | null>(null);
|
|
1707
|
+
* <DatePicker value={value} onChange={setValue} />
|
|
1708
|
+
* ```
|
|
1709
|
+
*/
|
|
1710
|
+
function DatePicker({ value, onChange, formatLabel = (d) => format(d, "d MMM yyyy"), weekStartsOn = 0, height = 320, placeholder = "Select a date", disabled, theme: themeOverrides, className, style, classNames, styles, minDate, maxDate, isDateDisabled }) {
|
|
1711
|
+
const theme = mergeDomTheme(themeOverrides);
|
|
1712
|
+
const slot = createSlots({
|
|
1713
|
+
classNames,
|
|
1714
|
+
styles
|
|
1715
|
+
});
|
|
1716
|
+
const { open, setOpen, rootRef, triggerRef } = usePopover();
|
|
1717
|
+
return /* @__PURE__ */ jsx(PickerShell, {
|
|
1718
|
+
open,
|
|
1719
|
+
setOpen,
|
|
1720
|
+
rootRef,
|
|
1721
|
+
triggerRef,
|
|
1722
|
+
theme,
|
|
1723
|
+
slot,
|
|
1724
|
+
label: value ? formatLabel(value) : "",
|
|
1725
|
+
hasValue: !!value,
|
|
1726
|
+
placeholder,
|
|
1727
|
+
disabled,
|
|
1728
|
+
className,
|
|
1729
|
+
style,
|
|
1730
|
+
ariaLabel: "Choose a date",
|
|
1731
|
+
children: /* @__PURE__ */ jsx(MonthList, {
|
|
1732
|
+
date: value ?? /* @__PURE__ */ new Date(),
|
|
1733
|
+
weekStartsOn,
|
|
1734
|
+
selectedDates: value ? [value] : [],
|
|
1735
|
+
minDate,
|
|
1736
|
+
maxDate,
|
|
1737
|
+
isDateDisabled,
|
|
1738
|
+
onPressDay: (day) => {
|
|
1739
|
+
onChange(day);
|
|
1740
|
+
setOpen(false);
|
|
1741
|
+
triggerRef.current?.focus();
|
|
1742
|
+
},
|
|
1743
|
+
height,
|
|
1744
|
+
classNames,
|
|
1745
|
+
styles
|
|
1746
|
+
})
|
|
1747
|
+
});
|
|
1748
|
+
}
|
|
1749
|
+
function defaultRangeLabel(range) {
|
|
1750
|
+
const start = format(range.start, "d MMM yyyy");
|
|
1751
|
+
return range.end ? `${start} – ${format(range.end, "d MMM yyyy")}` : `${start} – …`;
|
|
1752
|
+
}
|
|
1753
|
+
/**
|
|
1754
|
+
* A date-range input with a popover calendar. Controlled via `value` / `onChange`;
|
|
1755
|
+
* each pick advances the range through {@link nextDateRange} (start, then end), and
|
|
1756
|
+
* the popover closes once both ends are set.
|
|
1757
|
+
*
|
|
1758
|
+
* @example
|
|
1759
|
+
* ```tsx
|
|
1760
|
+
* const [range, setRange] = useState<DateRange | null>(null);
|
|
1761
|
+
* <DateRangePicker value={range} onChange={setRange} />
|
|
1762
|
+
* ```
|
|
1763
|
+
*/
|
|
1764
|
+
function DateRangePicker({ value, onChange, formatLabel = defaultRangeLabel, weekStartsOn = 0, height = 320, placeholder = "Select dates", disabled, theme: themeOverrides, className, style, classNames, styles, minDate, maxDate, isDateDisabled }) {
|
|
1765
|
+
const theme = mergeDomTheme(themeOverrides);
|
|
1766
|
+
const slot = createSlots({
|
|
1767
|
+
classNames,
|
|
1768
|
+
styles
|
|
1769
|
+
});
|
|
1770
|
+
const { open, setOpen, rootRef, triggerRef } = usePopover();
|
|
1771
|
+
const constraints = {
|
|
1772
|
+
minDate,
|
|
1773
|
+
maxDate,
|
|
1774
|
+
isDateDisabled
|
|
1775
|
+
};
|
|
1776
|
+
return /* @__PURE__ */ jsxs(PickerShell, {
|
|
1777
|
+
open,
|
|
1778
|
+
setOpen,
|
|
1779
|
+
rootRef,
|
|
1780
|
+
triggerRef,
|
|
1781
|
+
theme,
|
|
1782
|
+
slot,
|
|
1783
|
+
label: value ? formatLabel(value) : "",
|
|
1784
|
+
hasValue: !!value,
|
|
1785
|
+
placeholder,
|
|
1786
|
+
disabled,
|
|
1787
|
+
className,
|
|
1788
|
+
style,
|
|
1789
|
+
ariaLabel: "Choose a date range",
|
|
1790
|
+
children: [/* @__PURE__ */ jsx(MonthList, {
|
|
1791
|
+
date: value?.start ?? /* @__PURE__ */ new Date(),
|
|
1792
|
+
weekStartsOn,
|
|
1793
|
+
selectedRange: value ?? void 0,
|
|
1794
|
+
minDate,
|
|
1795
|
+
maxDate,
|
|
1796
|
+
isDateDisabled,
|
|
1797
|
+
onPressDay: (day) => {
|
|
1798
|
+
const next = nextDateRange$1(value, day, constraints);
|
|
1799
|
+
onChange(next);
|
|
1800
|
+
if (next?.end) {
|
|
1801
|
+
setOpen(false);
|
|
1802
|
+
triggerRef.current?.focus();
|
|
1803
|
+
}
|
|
1804
|
+
},
|
|
1805
|
+
height,
|
|
1806
|
+
classNames,
|
|
1807
|
+
styles
|
|
1808
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
1809
|
+
...slot("footer", {
|
|
1810
|
+
base: {
|
|
1811
|
+
display: "flex",
|
|
1812
|
+
justifyContent: "flex-end",
|
|
1813
|
+
padding: "8px 10px"
|
|
1814
|
+
},
|
|
1815
|
+
themed: { borderTop: `1px solid ${theme.gridLine}` }
|
|
1816
|
+
}),
|
|
1817
|
+
children: /* @__PURE__ */ jsx("button", {
|
|
1818
|
+
type: "button",
|
|
1819
|
+
onClick: () => onChange(null),
|
|
1820
|
+
...slot("clear", {
|
|
1821
|
+
base: {
|
|
1822
|
+
border: "none",
|
|
1823
|
+
background: "transparent",
|
|
1824
|
+
cursor: "pointer",
|
|
1825
|
+
font: "inherit"
|
|
1826
|
+
},
|
|
1827
|
+
themed: { color: theme.textMuted }
|
|
1828
|
+
}),
|
|
1829
|
+
children: "Clear"
|
|
1338
1830
|
})
|
|
1339
1831
|
})]
|
|
1340
1832
|
});
|
|
1341
1833
|
}
|
|
1342
1834
|
//#endregion
|
|
1343
|
-
|
|
1835
|
+
//#region src/ResourceTimeline.tsx
|
|
1836
|
+
const clamp = (v, lo, hi) => Math.min(hi, Math.max(lo, v));
|
|
1837
|
+
function DefaultBar({ event, boxProps, theme }) {
|
|
1838
|
+
const time = eventTimeLabel({
|
|
1839
|
+
mode: "day",
|
|
1840
|
+
isAllDay: false,
|
|
1841
|
+
start: event.start,
|
|
1842
|
+
end: event.end,
|
|
1843
|
+
ampm: false,
|
|
1844
|
+
showTime: true
|
|
1845
|
+
});
|
|
1846
|
+
const base = {
|
|
1847
|
+
height: "100%",
|
|
1848
|
+
boxSizing: "border-box",
|
|
1849
|
+
overflow: "hidden"
|
|
1850
|
+
};
|
|
1851
|
+
const themed = {
|
|
1852
|
+
padding: "2px 6px",
|
|
1853
|
+
borderRadius: 6,
|
|
1854
|
+
background: theme.eventBackground,
|
|
1855
|
+
color: theme.eventText,
|
|
1856
|
+
fontSize: 12
|
|
1857
|
+
};
|
|
1858
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1859
|
+
className: boxProps.className,
|
|
1860
|
+
"data-slot": boxProps["data-slot"],
|
|
1861
|
+
style: boxProps.className ? {
|
|
1862
|
+
...base,
|
|
1863
|
+
...boxProps.style
|
|
1864
|
+
} : {
|
|
1865
|
+
...base,
|
|
1866
|
+
...themed,
|
|
1867
|
+
...boxProps.style
|
|
1868
|
+
},
|
|
1869
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
1870
|
+
style: {
|
|
1871
|
+
fontWeight: 600,
|
|
1872
|
+
whiteSpace: "nowrap",
|
|
1873
|
+
overflow: "hidden",
|
|
1874
|
+
textOverflow: "ellipsis"
|
|
1875
|
+
},
|
|
1876
|
+
children: event.title
|
|
1877
|
+
}), time ? /* @__PURE__ */ jsx("div", {
|
|
1878
|
+
style: {
|
|
1879
|
+
opacity: .75,
|
|
1880
|
+
fontSize: 11
|
|
1881
|
+
},
|
|
1882
|
+
children: time
|
|
1883
|
+
}) : null]
|
|
1884
|
+
});
|
|
1885
|
+
}
|
|
1886
|
+
/**
|
|
1887
|
+
* A horizontal resource timeline: rows are resources (rooms, people, machines)
|
|
1888
|
+
* and the x-axis is one day's hours. Events sit in their resource's row, and
|
|
1889
|
+
* overlapping events in the same row stack into sub-lanes (via the shared
|
|
1890
|
+
* `layoutDayEvents`). Pass `onDragEvent` to enable drag-to-move and edge-resize
|
|
1891
|
+
* along the axis.
|
|
1892
|
+
*
|
|
1893
|
+
* @example
|
|
1894
|
+
* ```tsx
|
|
1895
|
+
* <ResourceTimeline
|
|
1896
|
+
* date={new Date()}
|
|
1897
|
+
* resources={[{ id: "a", title: "Room A" }, { id: "b", title: "Room B" }]}
|
|
1898
|
+
* events={events} // each event carries a `resourceId`
|
|
1899
|
+
* />
|
|
1900
|
+
* ```
|
|
1901
|
+
*/
|
|
1902
|
+
function ResourceTimeline({ date, resources, events, resourceId = (event) => event.resourceId, startHour = 0, endHour = 24, hourWidth = 80, rowHeight = 56, labelWidth = 140, ampm = false, theme: themeOverrides, renderEvent, onPressEvent, onDragEvent, dragStepMinutes = 15, className, style, classNames, styles }) {
|
|
1903
|
+
const theme = useMemo(() => mergeDomTheme(themeOverrides), [themeOverrides]);
|
|
1904
|
+
const slot = createSlots({
|
|
1905
|
+
classNames,
|
|
1906
|
+
styles
|
|
1907
|
+
});
|
|
1908
|
+
const Renderer = renderEvent;
|
|
1909
|
+
const snapHours = dragStepMinutes / 60;
|
|
1910
|
+
const [drag, setDrag] = useState(null);
|
|
1911
|
+
const dragRef = useRef(null);
|
|
1912
|
+
const origin = useRef(null);
|
|
1913
|
+
const applyDrag = (next) => {
|
|
1914
|
+
dragRef.current = next;
|
|
1915
|
+
setDrag(next);
|
|
1916
|
+
};
|
|
1917
|
+
const beginDrag = (e, key, kind, startHours, durationHours) => {
|
|
1918
|
+
if (!onDragEvent) return;
|
|
1919
|
+
e.stopPropagation();
|
|
1920
|
+
try {
|
|
1921
|
+
e.target.setPointerCapture?.(e.pointerId);
|
|
1922
|
+
} catch {}
|
|
1923
|
+
origin.current = {
|
|
1924
|
+
x: e.clientX,
|
|
1925
|
+
startHours,
|
|
1926
|
+
durationHours
|
|
1927
|
+
};
|
|
1928
|
+
applyDrag({
|
|
1929
|
+
key,
|
|
1930
|
+
kind,
|
|
1931
|
+
startHours,
|
|
1932
|
+
durationHours,
|
|
1933
|
+
moved: false
|
|
1934
|
+
});
|
|
1935
|
+
};
|
|
1936
|
+
const moveDrag = (e) => {
|
|
1937
|
+
const d = dragRef.current;
|
|
1938
|
+
if (!d || !origin.current) return;
|
|
1939
|
+
const dHours = (e.clientX - origin.current.x) / hourWidth;
|
|
1940
|
+
const snap = (v) => Math.round(v / snapHours) * snapHours;
|
|
1941
|
+
if (d.kind === "move") {
|
|
1942
|
+
const startHours = clamp(snap(origin.current.startHours + dHours), startHour, endHour - d.durationHours);
|
|
1943
|
+
applyDrag({
|
|
1944
|
+
...d,
|
|
1945
|
+
startHours,
|
|
1946
|
+
moved: true
|
|
1947
|
+
});
|
|
1948
|
+
} else {
|
|
1949
|
+
const durationHours = clamp(snap(origin.current.durationHours + dHours), snapHours, endHour - d.startHours);
|
|
1950
|
+
applyDrag({
|
|
1951
|
+
...d,
|
|
1952
|
+
durationHours,
|
|
1953
|
+
moved: true
|
|
1954
|
+
});
|
|
1955
|
+
}
|
|
1956
|
+
};
|
|
1957
|
+
const endDrag = (e, event, onPress) => {
|
|
1958
|
+
const d = dragRef.current;
|
|
1959
|
+
if (!d) return;
|
|
1960
|
+
try {
|
|
1961
|
+
e.target.releasePointerCapture?.(e.pointerId);
|
|
1962
|
+
} catch {}
|
|
1963
|
+
if (!d.moved) {
|
|
1964
|
+
applyDrag(null);
|
|
1965
|
+
onPress();
|
|
1966
|
+
return;
|
|
1967
|
+
}
|
|
1968
|
+
const base = startOfDay(date);
|
|
1969
|
+
const start = addMinutes(base, Math.round(d.startHours * 60));
|
|
1970
|
+
const end = addMinutes(base, Math.round((d.startHours + d.durationHours) * 60));
|
|
1971
|
+
onDragEvent?.(event, start, end);
|
|
1972
|
+
applyDrag(null);
|
|
1973
|
+
origin.current = null;
|
|
1974
|
+
};
|
|
1975
|
+
const cancelDrag = () => {
|
|
1976
|
+
applyDrag(null);
|
|
1977
|
+
origin.current = null;
|
|
1978
|
+
};
|
|
1979
|
+
const hours = useMemo(() => Array.from({ length: Math.max(0, endHour - startHour) }, (_, i) => startHour + i), [startHour, endHour]);
|
|
1980
|
+
const trackWidth = (endHour - startHour) * hourWidth;
|
|
1981
|
+
const byResource = useMemo(() => {
|
|
1982
|
+
const map = /* @__PURE__ */ new Map();
|
|
1983
|
+
for (const resource of resources) {
|
|
1984
|
+
const own = events.filter((e) => resourceId(e) === resource.id);
|
|
1985
|
+
map.set(resource.id, layoutDayEvents$1(own, date));
|
|
1986
|
+
}
|
|
1987
|
+
return map;
|
|
1988
|
+
}, [
|
|
1989
|
+
resources,
|
|
1990
|
+
events,
|
|
1991
|
+
resourceId,
|
|
1992
|
+
date
|
|
1993
|
+
]);
|
|
1994
|
+
const gridLines = `repeating-linear-gradient(to right, transparent 0, transparent ${hourWidth - 1}px, ${theme.gridLine} ${hourWidth - 1}px, ${theme.gridLine} ${hourWidth}px)`;
|
|
1995
|
+
return /* @__PURE__ */ jsx("div", {
|
|
1996
|
+
className,
|
|
1997
|
+
style: {
|
|
1998
|
+
fontFamily: theme.fontFamily,
|
|
1999
|
+
color: theme.text,
|
|
2000
|
+
overflowX: "auto",
|
|
2001
|
+
...style
|
|
2002
|
+
},
|
|
2003
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
2004
|
+
style: { minWidth: labelWidth + trackWidth },
|
|
2005
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
2006
|
+
...slot("header", {
|
|
2007
|
+
base: { display: "flex" },
|
|
2008
|
+
themed: { borderBottom: `1px solid ${theme.gridLine}` }
|
|
2009
|
+
}),
|
|
2010
|
+
children: [/* @__PURE__ */ jsx("div", { ...slot("corner", { base: {
|
|
2011
|
+
width: labelWidth,
|
|
2012
|
+
flex: "none"
|
|
2013
|
+
} }) }), /* @__PURE__ */ jsx("div", {
|
|
2014
|
+
...slot("timeAxis", { base: {
|
|
2015
|
+
position: "relative",
|
|
2016
|
+
height: 24,
|
|
2017
|
+
width: trackWidth
|
|
2018
|
+
} }),
|
|
2019
|
+
children: hours.map((h) => /* @__PURE__ */ jsx("div", {
|
|
2020
|
+
...slot("hourTick", {
|
|
2021
|
+
base: {
|
|
2022
|
+
position: "absolute",
|
|
2023
|
+
left: (h - startHour) * hourWidth,
|
|
2024
|
+
top: 4
|
|
2025
|
+
},
|
|
2026
|
+
themed: {
|
|
2027
|
+
fontSize: 10,
|
|
2028
|
+
color: theme.textMuted
|
|
2029
|
+
}
|
|
2030
|
+
}),
|
|
2031
|
+
children: formatHour(h, { ampm })
|
|
2032
|
+
}, h))
|
|
2033
|
+
})]
|
|
2034
|
+
}), resources.map((resource) => {
|
|
2035
|
+
const positioned = byResource.get(resource.id) ?? [];
|
|
2036
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
2037
|
+
...slot("row", {
|
|
2038
|
+
base: {
|
|
2039
|
+
display: "flex",
|
|
2040
|
+
height: rowHeight
|
|
2041
|
+
},
|
|
2042
|
+
themed: { borderBottom: `1px solid ${theme.gridLine}` }
|
|
2043
|
+
}),
|
|
2044
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
2045
|
+
...slot("resourceLabel", {
|
|
2046
|
+
base: {
|
|
2047
|
+
width: labelWidth,
|
|
2048
|
+
flex: "none",
|
|
2049
|
+
display: "flex",
|
|
2050
|
+
alignItems: "center",
|
|
2051
|
+
padding: "0 10px",
|
|
2052
|
+
boxSizing: "border-box"
|
|
2053
|
+
},
|
|
2054
|
+
themed: {
|
|
2055
|
+
fontSize: 13,
|
|
2056
|
+
fontWeight: 600,
|
|
2057
|
+
borderRight: `1px solid ${theme.gridLine}`
|
|
2058
|
+
}
|
|
2059
|
+
}),
|
|
2060
|
+
children: resource.title ?? resource.id
|
|
2061
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
2062
|
+
...slot("track", { base: {
|
|
2063
|
+
position: "relative",
|
|
2064
|
+
width: trackWidth
|
|
2065
|
+
} }),
|
|
2066
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
2067
|
+
"aria-hidden": true,
|
|
2068
|
+
...slot("gridLines", {
|
|
2069
|
+
base: {
|
|
2070
|
+
position: "absolute",
|
|
2071
|
+
inset: 0,
|
|
2072
|
+
pointerEvents: "none"
|
|
2073
|
+
},
|
|
2074
|
+
themed: { backgroundImage: gridLines }
|
|
2075
|
+
})
|
|
2076
|
+
}), positioned.map((pe, idx) => {
|
|
2077
|
+
const key = `${resource.id}:${idx}`;
|
|
2078
|
+
const active = drag?.key === key ? drag : null;
|
|
2079
|
+
const startH = active ? active.startHours : pe.startHours;
|
|
2080
|
+
const durH = active ? active.durationHours : pe.durationHours;
|
|
2081
|
+
const left = clamp(startH - startHour, 0, endHour - startHour) * hourWidth;
|
|
2082
|
+
const right = clamp(startH + durH - startHour, 0, endHour - startHour) * hourWidth;
|
|
2083
|
+
const width = Math.max(right - left, 2);
|
|
2084
|
+
const laneHeight = rowHeight / pe.columns;
|
|
2085
|
+
const onPress = () => onPressEvent?.(pe.event);
|
|
2086
|
+
const args = {
|
|
2087
|
+
event: pe.event,
|
|
2088
|
+
width,
|
|
2089
|
+
onPress
|
|
2090
|
+
};
|
|
2091
|
+
const draggable = !!onDragEvent;
|
|
2092
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
2093
|
+
type: "button",
|
|
2094
|
+
onClick: draggable ? void 0 : onPress,
|
|
2095
|
+
"aria-label": pe.event.title,
|
|
2096
|
+
...dataState({ "data-dragging": !!active }),
|
|
2097
|
+
onPointerDown: draggable ? (e) => beginDrag(e, key, "move", pe.startHours, pe.durationHours) : void 0,
|
|
2098
|
+
onPointerMove: draggable ? moveDrag : void 0,
|
|
2099
|
+
onPointerUp: draggable ? (e) => endDrag(e, pe.event, onPress) : void 0,
|
|
2100
|
+
onPointerCancel: draggable ? cancelDrag : void 0,
|
|
2101
|
+
...slot("event", { base: {
|
|
2102
|
+
position: "absolute",
|
|
2103
|
+
left,
|
|
2104
|
+
width,
|
|
2105
|
+
top: pe.column * laneHeight,
|
|
2106
|
+
height: laneHeight,
|
|
2107
|
+
padding: 1,
|
|
2108
|
+
border: "none",
|
|
2109
|
+
background: "transparent",
|
|
2110
|
+
cursor: draggable ? "grab" : "pointer",
|
|
2111
|
+
touchAction: draggable ? "none" : "auto",
|
|
2112
|
+
font: "inherit",
|
|
2113
|
+
textAlign: "left",
|
|
2114
|
+
boxSizing: "border-box",
|
|
2115
|
+
zIndex: active ? 3 : 1,
|
|
2116
|
+
opacity: active ? .85 : 1
|
|
2117
|
+
} }),
|
|
2118
|
+
children: [Renderer ? /* @__PURE__ */ jsx(Renderer, { ...args }) : /* @__PURE__ */ jsx(DefaultBar, {
|
|
2119
|
+
...args,
|
|
2120
|
+
theme,
|
|
2121
|
+
boxProps: slot("eventBox")
|
|
2122
|
+
}), draggable ? /* @__PURE__ */ jsx("span", {
|
|
2123
|
+
"aria-hidden": true,
|
|
2124
|
+
onPointerDown: (e) => {
|
|
2125
|
+
e.stopPropagation();
|
|
2126
|
+
beginDrag(e, key, "resize", pe.startHours, pe.durationHours);
|
|
2127
|
+
},
|
|
2128
|
+
style: {
|
|
2129
|
+
position: "absolute",
|
|
2130
|
+
top: 0,
|
|
2131
|
+
bottom: 0,
|
|
2132
|
+
right: 0,
|
|
2133
|
+
width: 8,
|
|
2134
|
+
cursor: "ew-resize",
|
|
2135
|
+
touchAction: "none"
|
|
2136
|
+
}
|
|
2137
|
+
}) : null]
|
|
2138
|
+
}, idx);
|
|
2139
|
+
})]
|
|
2140
|
+
})]
|
|
2141
|
+
}, resource.id);
|
|
2142
|
+
})]
|
|
2143
|
+
})
|
|
2144
|
+
});
|
|
2145
|
+
}
|
|
2146
|
+
//#endregion
|
|
2147
|
+
export { Agenda, Calendar, DatePicker, DateRangePicker, MonthList, MonthView, ResourceTimeline, TimeGrid, buildMonthGrid, darkDomTheme, daySelectionState, defaultDomTheme, expandRecurringEvents, getViewDays, isAllDayEvent, isDateSelectable, isRangeEndpoint, isWithinDateRange, layoutDayEvents, mergeDomTheme, nextDateRange, parseICalendar, toICalendar, useDateRange, useMonthGrid, weekdayFormatToken };
|