@super-calendar/dom 2.1.5 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/dist/index.d.mts +327 -12
- package/dist/index.d.ts +327 -12
- package/dist/index.js +1111 -286
- package/dist/index.mjs +1087 -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 +247 -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, 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,41 @@ 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({ "data-today": getIsToday(day) }),
|
|
1221
|
+
...slot("dayColumn", {
|
|
1222
|
+
base: {
|
|
1223
|
+
flex: 1,
|
|
1224
|
+
position: "relative"
|
|
1225
|
+
},
|
|
1226
|
+
themed: { borderLeft: `1px solid ${theme.gridLine}` }
|
|
1227
|
+
}),
|
|
1019
1228
|
children: [
|
|
1020
1229
|
bands.map((b) => /* @__PURE__ */ jsx("div", {
|
|
1021
1230
|
"aria-hidden": true,
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1231
|
+
...slot("businessHours", {
|
|
1232
|
+
base: {
|
|
1233
|
+
position: "absolute",
|
|
1234
|
+
left: 0,
|
|
1235
|
+
right: 0,
|
|
1236
|
+
top: b.start * hourHeight,
|
|
1237
|
+
height: (b.end - b.start) * hourHeight,
|
|
1238
|
+
pointerEvents: "none",
|
|
1239
|
+
zIndex: 0
|
|
1240
|
+
},
|
|
1241
|
+
themed: { background: theme.outsideHoursBackground }
|
|
1242
|
+
})
|
|
1032
1243
|
}, b.start)),
|
|
1033
1244
|
/* @__PURE__ */ jsx("div", {
|
|
1034
1245
|
"aria-hidden": true,
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1246
|
+
...slot("gridLines", {
|
|
1247
|
+
base: {
|
|
1248
|
+
position: "absolute",
|
|
1249
|
+
inset: 0,
|
|
1250
|
+
pointerEvents: "none",
|
|
1251
|
+
zIndex: 0
|
|
1252
|
+
},
|
|
1253
|
+
themed: { backgroundImage: gridLines }
|
|
1254
|
+
})
|
|
1042
1255
|
}),
|
|
1043
1256
|
positioned.map((pe, idx) => {
|
|
1044
1257
|
const key = `${dayIndex}:${idx}`;
|
|
@@ -1063,7 +1276,11 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
1063
1276
|
return /* @__PURE__ */ jsxs("div", {
|
|
1064
1277
|
role: "button",
|
|
1065
1278
|
tabIndex: 0,
|
|
1066
|
-
"aria-label": eventAccessibilityLabel({
|
|
1279
|
+
"aria-label": eventAccessibilityLabel$1 ? eventAccessibilityLabel$1(pe.event, {
|
|
1280
|
+
mode,
|
|
1281
|
+
isAllDay: false,
|
|
1282
|
+
ampm
|
|
1283
|
+
}) : eventAccessibilityLabel({
|
|
1067
1284
|
title: pe.event.title,
|
|
1068
1285
|
isAllDay: false,
|
|
1069
1286
|
start: pe.event.start,
|
|
@@ -1081,7 +1298,8 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
1081
1298
|
onPointerUp: draggable ? (e) => endDrag(e, day, pe.event, onPress) : void 0,
|
|
1082
1299
|
onPointerCancel: draggable ? cancelDrag : void 0,
|
|
1083
1300
|
onClick: draggable ? void 0 : onPress,
|
|
1084
|
-
|
|
1301
|
+
...dataState({ "data-dragging": !!active }),
|
|
1302
|
+
...slot("event", { base: {
|
|
1085
1303
|
position: "absolute",
|
|
1086
1304
|
top,
|
|
1087
1305
|
height: boxHeight,
|
|
@@ -1091,10 +1309,11 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
1091
1309
|
touchAction: draggable ? "none" : "auto",
|
|
1092
1310
|
zIndex: active ? 3 : 1,
|
|
1093
1311
|
opacity: active ? .85 : 1
|
|
1094
|
-
},
|
|
1312
|
+
} }),
|
|
1095
1313
|
children: [Renderer ? /* @__PURE__ */ jsx(Renderer, { ...args }) : /* @__PURE__ */ jsx(DefaultDomEvent, {
|
|
1096
1314
|
...args,
|
|
1097
|
-
theme
|
|
1315
|
+
theme,
|
|
1316
|
+
boxProps: slot("eventBox")
|
|
1098
1317
|
}), draggable ? /* @__PURE__ */ jsx("div", {
|
|
1099
1318
|
onPointerDown: (e) => {
|
|
1100
1319
|
e.stopPropagation();
|
|
@@ -1113,7 +1332,7 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
1113
1332
|
}, idx);
|
|
1114
1333
|
}),
|
|
1115
1334
|
showNow ? /* @__PURE__ */ jsxs("div", {
|
|
1116
|
-
|
|
1335
|
+
...slot("nowIndicator", { base: {
|
|
1117
1336
|
position: "absolute",
|
|
1118
1337
|
top: nowTop,
|
|
1119
1338
|
left: 0,
|
|
@@ -1121,7 +1340,7 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
1121
1340
|
height: 0,
|
|
1122
1341
|
zIndex: 2,
|
|
1123
1342
|
pointerEvents: "none"
|
|
1124
|
-
},
|
|
1343
|
+
} }),
|
|
1125
1344
|
children: [/* @__PURE__ */ jsx("div", { style: {
|
|
1126
1345
|
height: 2,
|
|
1127
1346
|
background: theme.nowIndicator
|
|
@@ -1137,19 +1356,23 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
1137
1356
|
}) : null,
|
|
1138
1357
|
ghost ? /* @__PURE__ */ jsx("div", {
|
|
1139
1358
|
"aria-hidden": true,
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1359
|
+
...slot("createGhost", {
|
|
1360
|
+
base: {
|
|
1361
|
+
position: "absolute",
|
|
1362
|
+
left: 1,
|
|
1363
|
+
right: 1,
|
|
1364
|
+
top: ghost.topPx,
|
|
1365
|
+
height: Math.max(ghost.heightPx, 2),
|
|
1366
|
+
opacity: .7,
|
|
1367
|
+
pointerEvents: "none",
|
|
1368
|
+
zIndex: 2
|
|
1369
|
+
},
|
|
1370
|
+
themed: {
|
|
1371
|
+
background: theme.rangeBackground,
|
|
1372
|
+
border: `1px solid ${theme.selectedBackground}`,
|
|
1373
|
+
borderRadius: 6
|
|
1374
|
+
}
|
|
1375
|
+
})
|
|
1153
1376
|
}) : null
|
|
1154
1377
|
]
|
|
1155
1378
|
}, day.toISOString());
|
|
@@ -1172,7 +1395,7 @@ function TimeGrid({ date, events = [], mode = "day", numberOfDays = 1, weekStart
|
|
|
1172
1395
|
* <Calendar mode="week" date={new Date()} events={events} />
|
|
1173
1396
|
* ```
|
|
1174
1397
|
*/
|
|
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 }) {
|
|
1398
|
+
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
1399
|
if (mode === "schedule") return /* @__PURE__ */ jsx(Agenda, {
|
|
1177
1400
|
events: events ?? [],
|
|
1178
1401
|
locale,
|
|
@@ -1182,7 +1405,10 @@ function Calendar({ mode = "week", date, events, weekStartsOn = 0, numberOfDays,
|
|
|
1182
1405
|
activeDate: date,
|
|
1183
1406
|
className,
|
|
1184
1407
|
style,
|
|
1408
|
+
classNames,
|
|
1409
|
+
styles,
|
|
1185
1410
|
renderEvent: renderScheduleEvent,
|
|
1411
|
+
eventAccessibilityLabel,
|
|
1186
1412
|
onPressEvent,
|
|
1187
1413
|
onPressDay
|
|
1188
1414
|
});
|
|
@@ -1190,10 +1416,13 @@ function Calendar({ mode = "week", date, events, weekStartsOn = 0, numberOfDays,
|
|
|
1190
1416
|
date,
|
|
1191
1417
|
events: events ?? [],
|
|
1192
1418
|
weekStartsOn,
|
|
1419
|
+
weekdayFormat,
|
|
1193
1420
|
locale,
|
|
1194
1421
|
theme,
|
|
1195
1422
|
className,
|
|
1196
1423
|
style,
|
|
1424
|
+
classNames,
|
|
1425
|
+
styles,
|
|
1197
1426
|
maxVisibleEventCount,
|
|
1198
1427
|
moreLabel,
|
|
1199
1428
|
showAdjacentMonths,
|
|
@@ -1205,21 +1434,26 @@ function Calendar({ mode = "week", date, events, weekStartsOn = 0, numberOfDays,
|
|
|
1205
1434
|
isDateDisabled,
|
|
1206
1435
|
keyboardDayNavigation,
|
|
1207
1436
|
onPressDay,
|
|
1437
|
+
onCreateEvent,
|
|
1208
1438
|
onPressEvent,
|
|
1209
1439
|
onPressMore,
|
|
1210
|
-
renderEvent: renderMonthEvent
|
|
1440
|
+
renderEvent: renderMonthEvent,
|
|
1441
|
+
eventAccessibilityLabel
|
|
1211
1442
|
});
|
|
1212
1443
|
return /* @__PURE__ */ jsx(TimeGrid, {
|
|
1213
1444
|
date,
|
|
1214
1445
|
mode,
|
|
1215
1446
|
events,
|
|
1216
1447
|
weekStartsOn,
|
|
1448
|
+
weekdayFormat,
|
|
1217
1449
|
numberOfDays,
|
|
1218
1450
|
locale,
|
|
1219
1451
|
theme,
|
|
1220
1452
|
height,
|
|
1221
1453
|
className,
|
|
1222
1454
|
style,
|
|
1455
|
+
classNames,
|
|
1456
|
+
styles,
|
|
1223
1457
|
ampm,
|
|
1224
1458
|
hourHeight,
|
|
1225
1459
|
scrollOffsetMinutes,
|
|
@@ -1235,6 +1469,7 @@ function Calendar({ mode = "week", date, events, weekStartsOn = 0, numberOfDays,
|
|
|
1235
1469
|
onDragEvent,
|
|
1236
1470
|
onPressDateHeader,
|
|
1237
1471
|
renderEvent: renderTimeEvent,
|
|
1472
|
+
eventAccessibilityLabel,
|
|
1238
1473
|
hourComponent
|
|
1239
1474
|
});
|
|
1240
1475
|
}
|
|
@@ -1245,8 +1480,12 @@ function Calendar({ mode = "week", date, events, weekStartsOn = 0, numberOfDays,
|
|
|
1245
1480
|
* Legend List's DOM renderer and the library's headless grid logic. Selection is
|
|
1246
1481
|
* controlled, pass `selectedRange` (or `selectedDates`) and handle `onPressDay`.
|
|
1247
1482
|
*/
|
|
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 }) {
|
|
1483
|
+
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
1484
|
const theme = useMemo(() => mergeDomTheme(themeOverrides), [themeOverrides]);
|
|
1485
|
+
const slot = createSlots({
|
|
1486
|
+
classNames,
|
|
1487
|
+
styles
|
|
1488
|
+
});
|
|
1250
1489
|
const months = useMemo(() => {
|
|
1251
1490
|
const first = startOfMonth(addMonths(date, -pastMonths));
|
|
1252
1491
|
const count = pastMonths + futureMonths + 1;
|
|
@@ -1258,10 +1497,12 @@ function MonthList({ date, pastMonths = 1, futureMonths = 12, weekStartsOn = 0,
|
|
|
1258
1497
|
]);
|
|
1259
1498
|
const weekdays = useMemo(() => buildMonthGrid$1(date, {
|
|
1260
1499
|
weekStartsOn,
|
|
1500
|
+
weekdayFormat,
|
|
1261
1501
|
locale
|
|
1262
1502
|
}).weekdays, [
|
|
1263
1503
|
date,
|
|
1264
1504
|
weekStartsOn,
|
|
1505
|
+
weekdayFormat,
|
|
1265
1506
|
locale
|
|
1266
1507
|
]);
|
|
1267
1508
|
const eventsByDay = useMemo(() => {
|
|
@@ -1287,19 +1528,23 @@ function MonthList({ date, pastMonths = 1, futureMonths = 12, weekStartsOn = 0,
|
|
|
1287
1528
|
...style
|
|
1288
1529
|
},
|
|
1289
1530
|
children: [/* @__PURE__ */ jsx("div", {
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1531
|
+
...slot("weekdays", {
|
|
1532
|
+
base: {
|
|
1533
|
+
display: "grid",
|
|
1534
|
+
gridTemplateColumns: "repeat(7, minmax(0, 1fr))"
|
|
1535
|
+
},
|
|
1536
|
+
themed: {
|
|
1537
|
+
borderBottom: `1px solid ${theme.gridLine}`,
|
|
1538
|
+
padding: "8px 0"
|
|
1539
|
+
}
|
|
1540
|
+
}),
|
|
1296
1541
|
children: weekdays.map((wd) => /* @__PURE__ */ jsx("span", {
|
|
1297
|
-
|
|
1542
|
+
...slot("weekday", { themed: {
|
|
1298
1543
|
textAlign: "center",
|
|
1299
1544
|
fontSize: 12,
|
|
1300
1545
|
fontWeight: 600,
|
|
1301
1546
|
color: theme.textMuted
|
|
1302
|
-
},
|
|
1547
|
+
} }),
|
|
1303
1548
|
children: wd.label
|
|
1304
1549
|
}, wd.label))
|
|
1305
1550
|
}), /* @__PURE__ */ jsx(LegendList, {
|
|
@@ -1319,6 +1564,7 @@ function MonthList({ date, pastMonths = 1, futureMonths = 12, weekStartsOn = 0,
|
|
|
1319
1564
|
events,
|
|
1320
1565
|
eventsByDay,
|
|
1321
1566
|
renderEvent,
|
|
1567
|
+
eventAccessibilityLabel,
|
|
1322
1568
|
maxVisibleEventCount,
|
|
1323
1569
|
moreLabel,
|
|
1324
1570
|
onPressEvent,
|
|
@@ -1334,10 +1580,562 @@ function MonthList({ date, pastMonths = 1, futureMonths = 12, weekStartsOn = 0,
|
|
|
1334
1580
|
maxDate,
|
|
1335
1581
|
isDateDisabled,
|
|
1336
1582
|
keyboardDayNavigation,
|
|
1337
|
-
onPressDay
|
|
1583
|
+
onPressDay,
|
|
1584
|
+
classNames,
|
|
1585
|
+
styles
|
|
1586
|
+
})
|
|
1587
|
+
})]
|
|
1588
|
+
});
|
|
1589
|
+
}
|
|
1590
|
+
//#endregion
|
|
1591
|
+
//#region src/DateRangePicker.tsx
|
|
1592
|
+
const triggerDefault = {
|
|
1593
|
+
display: "inline-flex",
|
|
1594
|
+
alignItems: "center",
|
|
1595
|
+
justifyContent: "space-between",
|
|
1596
|
+
gap: 8,
|
|
1597
|
+
minWidth: 220,
|
|
1598
|
+
padding: "8px 12px",
|
|
1599
|
+
borderRadius: 8,
|
|
1600
|
+
cursor: "pointer",
|
|
1601
|
+
font: "inherit",
|
|
1602
|
+
textAlign: "left"
|
|
1603
|
+
};
|
|
1604
|
+
const popoverDefault = {
|
|
1605
|
+
position: "absolute",
|
|
1606
|
+
zIndex: 20,
|
|
1607
|
+
marginTop: 6,
|
|
1608
|
+
overflow: "hidden",
|
|
1609
|
+
borderRadius: 12,
|
|
1610
|
+
minWidth: 300
|
|
1611
|
+
};
|
|
1612
|
+
/**
|
|
1613
|
+
* The shared popover shell: a trigger button and a calendar panel that closes on
|
|
1614
|
+
* outside-click and Escape, and returns focus to the trigger. `renderCalendar`
|
|
1615
|
+
* gets a close callback so a single-date pick can dismiss immediately.
|
|
1616
|
+
*/
|
|
1617
|
+
function usePopover() {
|
|
1618
|
+
const [open, setOpen] = useState(false);
|
|
1619
|
+
const rootRef = useRef(null);
|
|
1620
|
+
const triggerRef = useRef(null);
|
|
1621
|
+
useEffect(() => {
|
|
1622
|
+
if (!open) return;
|
|
1623
|
+
const onDown = (e) => {
|
|
1624
|
+
if (!rootRef.current?.contains(e.target)) setOpen(false);
|
|
1625
|
+
};
|
|
1626
|
+
const onKey = (e) => {
|
|
1627
|
+
if (e.key === "Escape") {
|
|
1628
|
+
setOpen(false);
|
|
1629
|
+
triggerRef.current?.focus();
|
|
1630
|
+
}
|
|
1631
|
+
};
|
|
1632
|
+
document.addEventListener("mousedown", onDown);
|
|
1633
|
+
document.addEventListener("keydown", onKey);
|
|
1634
|
+
return () => {
|
|
1635
|
+
document.removeEventListener("mousedown", onDown);
|
|
1636
|
+
document.removeEventListener("keydown", onKey);
|
|
1637
|
+
};
|
|
1638
|
+
}, [open]);
|
|
1639
|
+
return {
|
|
1640
|
+
open,
|
|
1641
|
+
setOpen,
|
|
1642
|
+
rootRef,
|
|
1643
|
+
triggerRef
|
|
1644
|
+
};
|
|
1645
|
+
}
|
|
1646
|
+
function PickerShell({ open, setOpen, rootRef, triggerRef, theme, slot, label, hasValue, placeholder, disabled, className, style, ariaLabel, children }) {
|
|
1647
|
+
const dialogId = useId();
|
|
1648
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1649
|
+
ref: rootRef,
|
|
1650
|
+
className,
|
|
1651
|
+
style: {
|
|
1652
|
+
position: "relative",
|
|
1653
|
+
display: "inline-block",
|
|
1654
|
+
fontFamily: theme.fontFamily,
|
|
1655
|
+
...style
|
|
1656
|
+
},
|
|
1657
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
1658
|
+
ref: triggerRef,
|
|
1659
|
+
type: "button",
|
|
1660
|
+
disabled,
|
|
1661
|
+
"aria-haspopup": "dialog",
|
|
1662
|
+
"aria-expanded": open,
|
|
1663
|
+
"aria-controls": open ? dialogId : void 0,
|
|
1664
|
+
onClick: () => setOpen(!open),
|
|
1665
|
+
...slot("trigger", {
|
|
1666
|
+
base: triggerDefault,
|
|
1667
|
+
themed: {
|
|
1668
|
+
border: `1px solid ${theme.gridLine}`,
|
|
1669
|
+
background: theme.eventBackground,
|
|
1670
|
+
color: hasValue ? theme.text : theme.textMuted,
|
|
1671
|
+
opacity: disabled ? .5 : 1
|
|
1672
|
+
}
|
|
1673
|
+
}),
|
|
1674
|
+
children: [/* @__PURE__ */ jsx("span", { children: hasValue ? label : placeholder }), /* @__PURE__ */ jsx("span", {
|
|
1675
|
+
"aria-hidden": true,
|
|
1676
|
+
children: "▾"
|
|
1677
|
+
})]
|
|
1678
|
+
}), open ? /* @__PURE__ */ jsx("div", {
|
|
1679
|
+
id: dialogId,
|
|
1680
|
+
role: "dialog",
|
|
1681
|
+
"aria-label": ariaLabel,
|
|
1682
|
+
...slot("popover", {
|
|
1683
|
+
base: popoverDefault,
|
|
1684
|
+
themed: {
|
|
1685
|
+
background: theme.eventBackground,
|
|
1686
|
+
border: `1px solid ${theme.gridLine}`
|
|
1687
|
+
}
|
|
1688
|
+
}),
|
|
1689
|
+
children
|
|
1690
|
+
}) : null]
|
|
1691
|
+
});
|
|
1692
|
+
}
|
|
1693
|
+
/**
|
|
1694
|
+
* A single-date input with a popover calendar. Controlled via `value` / `onChange`.
|
|
1695
|
+
* Composed from {@link MonthList}; forward calendar slots (e.g. `dayBadge`) through
|
|
1696
|
+
* `classNames` to restyle the popover.
|
|
1697
|
+
*
|
|
1698
|
+
* @example
|
|
1699
|
+
* ```tsx
|
|
1700
|
+
* const [value, setValue] = useState<Date | null>(null);
|
|
1701
|
+
* <DatePicker value={value} onChange={setValue} />
|
|
1702
|
+
* ```
|
|
1703
|
+
*/
|
|
1704
|
+
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 }) {
|
|
1705
|
+
const theme = mergeDomTheme(themeOverrides);
|
|
1706
|
+
const slot = createSlots({
|
|
1707
|
+
classNames,
|
|
1708
|
+
styles
|
|
1709
|
+
});
|
|
1710
|
+
const { open, setOpen, rootRef, triggerRef } = usePopover();
|
|
1711
|
+
return /* @__PURE__ */ jsx(PickerShell, {
|
|
1712
|
+
open,
|
|
1713
|
+
setOpen,
|
|
1714
|
+
rootRef,
|
|
1715
|
+
triggerRef,
|
|
1716
|
+
theme,
|
|
1717
|
+
slot,
|
|
1718
|
+
label: value ? formatLabel(value) : "",
|
|
1719
|
+
hasValue: !!value,
|
|
1720
|
+
placeholder,
|
|
1721
|
+
disabled,
|
|
1722
|
+
className,
|
|
1723
|
+
style,
|
|
1724
|
+
ariaLabel: "Choose a date",
|
|
1725
|
+
children: /* @__PURE__ */ jsx(MonthList, {
|
|
1726
|
+
date: value ?? /* @__PURE__ */ new Date(),
|
|
1727
|
+
weekStartsOn,
|
|
1728
|
+
selectedDates: value ? [value] : [],
|
|
1729
|
+
minDate,
|
|
1730
|
+
maxDate,
|
|
1731
|
+
isDateDisabled,
|
|
1732
|
+
onPressDay: (day) => {
|
|
1733
|
+
onChange(day);
|
|
1734
|
+
setOpen(false);
|
|
1735
|
+
triggerRef.current?.focus();
|
|
1736
|
+
},
|
|
1737
|
+
height,
|
|
1738
|
+
classNames,
|
|
1739
|
+
styles
|
|
1740
|
+
})
|
|
1741
|
+
});
|
|
1742
|
+
}
|
|
1743
|
+
function defaultRangeLabel(range) {
|
|
1744
|
+
const start = format(range.start, "d MMM yyyy");
|
|
1745
|
+
return range.end ? `${start} – ${format(range.end, "d MMM yyyy")}` : `${start} – …`;
|
|
1746
|
+
}
|
|
1747
|
+
/**
|
|
1748
|
+
* A date-range input with a popover calendar. Controlled via `value` / `onChange`;
|
|
1749
|
+
* each pick advances the range through {@link nextDateRange} (start, then end), and
|
|
1750
|
+
* the popover closes once both ends are set.
|
|
1751
|
+
*
|
|
1752
|
+
* @example
|
|
1753
|
+
* ```tsx
|
|
1754
|
+
* const [range, setRange] = useState<DateRange | null>(null);
|
|
1755
|
+
* <DateRangePicker value={range} onChange={setRange} />
|
|
1756
|
+
* ```
|
|
1757
|
+
*/
|
|
1758
|
+
function DateRangePicker({ value, onChange, formatLabel = defaultRangeLabel, weekStartsOn = 0, height = 320, placeholder = "Select dates", disabled, theme: themeOverrides, className, style, classNames, styles, minDate, maxDate, isDateDisabled }) {
|
|
1759
|
+
const theme = mergeDomTheme(themeOverrides);
|
|
1760
|
+
const slot = createSlots({
|
|
1761
|
+
classNames,
|
|
1762
|
+
styles
|
|
1763
|
+
});
|
|
1764
|
+
const { open, setOpen, rootRef, triggerRef } = usePopover();
|
|
1765
|
+
const constraints = {
|
|
1766
|
+
minDate,
|
|
1767
|
+
maxDate,
|
|
1768
|
+
isDateDisabled
|
|
1769
|
+
};
|
|
1770
|
+
return /* @__PURE__ */ jsxs(PickerShell, {
|
|
1771
|
+
open,
|
|
1772
|
+
setOpen,
|
|
1773
|
+
rootRef,
|
|
1774
|
+
triggerRef,
|
|
1775
|
+
theme,
|
|
1776
|
+
slot,
|
|
1777
|
+
label: value ? formatLabel(value) : "",
|
|
1778
|
+
hasValue: !!value,
|
|
1779
|
+
placeholder,
|
|
1780
|
+
disabled,
|
|
1781
|
+
className,
|
|
1782
|
+
style,
|
|
1783
|
+
ariaLabel: "Choose a date range",
|
|
1784
|
+
children: [/* @__PURE__ */ jsx(MonthList, {
|
|
1785
|
+
date: value?.start ?? /* @__PURE__ */ new Date(),
|
|
1786
|
+
weekStartsOn,
|
|
1787
|
+
selectedRange: value ?? void 0,
|
|
1788
|
+
minDate,
|
|
1789
|
+
maxDate,
|
|
1790
|
+
isDateDisabled,
|
|
1791
|
+
onPressDay: (day) => {
|
|
1792
|
+
const next = nextDateRange$1(value, day, constraints);
|
|
1793
|
+
onChange(next);
|
|
1794
|
+
if (next?.end) {
|
|
1795
|
+
setOpen(false);
|
|
1796
|
+
triggerRef.current?.focus();
|
|
1797
|
+
}
|
|
1798
|
+
},
|
|
1799
|
+
height,
|
|
1800
|
+
classNames,
|
|
1801
|
+
styles
|
|
1802
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
1803
|
+
...slot("footer", {
|
|
1804
|
+
base: {
|
|
1805
|
+
display: "flex",
|
|
1806
|
+
justifyContent: "flex-end",
|
|
1807
|
+
padding: "8px 10px"
|
|
1808
|
+
},
|
|
1809
|
+
themed: { borderTop: `1px solid ${theme.gridLine}` }
|
|
1810
|
+
}),
|
|
1811
|
+
children: /* @__PURE__ */ jsx("button", {
|
|
1812
|
+
type: "button",
|
|
1813
|
+
onClick: () => onChange(null),
|
|
1814
|
+
...slot("clear", {
|
|
1815
|
+
base: {
|
|
1816
|
+
border: "none",
|
|
1817
|
+
background: "transparent",
|
|
1818
|
+
cursor: "pointer",
|
|
1819
|
+
font: "inherit"
|
|
1820
|
+
},
|
|
1821
|
+
themed: { color: theme.textMuted }
|
|
1822
|
+
}),
|
|
1823
|
+
children: "Clear"
|
|
1338
1824
|
})
|
|
1339
1825
|
})]
|
|
1340
1826
|
});
|
|
1341
1827
|
}
|
|
1342
1828
|
//#endregion
|
|
1343
|
-
|
|
1829
|
+
//#region src/ResourceTimeline.tsx
|
|
1830
|
+
const clamp = (v, lo, hi) => Math.min(hi, Math.max(lo, v));
|
|
1831
|
+
function DefaultBar({ event, boxProps, theme }) {
|
|
1832
|
+
const time = eventTimeLabel({
|
|
1833
|
+
mode: "day",
|
|
1834
|
+
isAllDay: false,
|
|
1835
|
+
start: event.start,
|
|
1836
|
+
end: event.end,
|
|
1837
|
+
ampm: false,
|
|
1838
|
+
showTime: true
|
|
1839
|
+
});
|
|
1840
|
+
const base = {
|
|
1841
|
+
height: "100%",
|
|
1842
|
+
boxSizing: "border-box",
|
|
1843
|
+
overflow: "hidden"
|
|
1844
|
+
};
|
|
1845
|
+
const themed = {
|
|
1846
|
+
padding: "2px 6px",
|
|
1847
|
+
borderRadius: 6,
|
|
1848
|
+
background: theme.eventBackground,
|
|
1849
|
+
color: theme.eventText,
|
|
1850
|
+
fontSize: 12
|
|
1851
|
+
};
|
|
1852
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1853
|
+
className: boxProps.className,
|
|
1854
|
+
"data-slot": boxProps["data-slot"],
|
|
1855
|
+
style: boxProps.className ? {
|
|
1856
|
+
...base,
|
|
1857
|
+
...boxProps.style
|
|
1858
|
+
} : {
|
|
1859
|
+
...base,
|
|
1860
|
+
...themed,
|
|
1861
|
+
...boxProps.style
|
|
1862
|
+
},
|
|
1863
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
1864
|
+
style: {
|
|
1865
|
+
fontWeight: 600,
|
|
1866
|
+
whiteSpace: "nowrap",
|
|
1867
|
+
overflow: "hidden",
|
|
1868
|
+
textOverflow: "ellipsis"
|
|
1869
|
+
},
|
|
1870
|
+
children: event.title
|
|
1871
|
+
}), time ? /* @__PURE__ */ jsx("div", {
|
|
1872
|
+
style: {
|
|
1873
|
+
opacity: .75,
|
|
1874
|
+
fontSize: 11
|
|
1875
|
+
},
|
|
1876
|
+
children: time
|
|
1877
|
+
}) : null]
|
|
1878
|
+
});
|
|
1879
|
+
}
|
|
1880
|
+
/**
|
|
1881
|
+
* A horizontal resource timeline: rows are resources (rooms, people, machines)
|
|
1882
|
+
* and the x-axis is one day's hours. Events sit in their resource's row, and
|
|
1883
|
+
* overlapping events in the same row stack into sub-lanes (via the shared
|
|
1884
|
+
* `layoutDayEvents`). Pass `onDragEvent` to enable drag-to-move and edge-resize
|
|
1885
|
+
* along the axis.
|
|
1886
|
+
*
|
|
1887
|
+
* @example
|
|
1888
|
+
* ```tsx
|
|
1889
|
+
* <ResourceTimeline
|
|
1890
|
+
* date={new Date()}
|
|
1891
|
+
* resources={[{ id: "a", title: "Room A" }, { id: "b", title: "Room B" }]}
|
|
1892
|
+
* events={events} // each event carries a `resourceId`
|
|
1893
|
+
* />
|
|
1894
|
+
* ```
|
|
1895
|
+
*/
|
|
1896
|
+
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 }) {
|
|
1897
|
+
const theme = useMemo(() => mergeDomTheme(themeOverrides), [themeOverrides]);
|
|
1898
|
+
const slot = createSlots({
|
|
1899
|
+
classNames,
|
|
1900
|
+
styles
|
|
1901
|
+
});
|
|
1902
|
+
const Renderer = renderEvent;
|
|
1903
|
+
const snapHours = dragStepMinutes / 60;
|
|
1904
|
+
const [drag, setDrag] = useState(null);
|
|
1905
|
+
const dragRef = useRef(null);
|
|
1906
|
+
const origin = useRef(null);
|
|
1907
|
+
const applyDrag = (next) => {
|
|
1908
|
+
dragRef.current = next;
|
|
1909
|
+
setDrag(next);
|
|
1910
|
+
};
|
|
1911
|
+
const beginDrag = (e, key, kind, startHours, durationHours) => {
|
|
1912
|
+
if (!onDragEvent) return;
|
|
1913
|
+
e.stopPropagation();
|
|
1914
|
+
try {
|
|
1915
|
+
e.target.setPointerCapture?.(e.pointerId);
|
|
1916
|
+
} catch {}
|
|
1917
|
+
origin.current = {
|
|
1918
|
+
x: e.clientX,
|
|
1919
|
+
startHours,
|
|
1920
|
+
durationHours
|
|
1921
|
+
};
|
|
1922
|
+
applyDrag({
|
|
1923
|
+
key,
|
|
1924
|
+
kind,
|
|
1925
|
+
startHours,
|
|
1926
|
+
durationHours,
|
|
1927
|
+
moved: false
|
|
1928
|
+
});
|
|
1929
|
+
};
|
|
1930
|
+
const moveDrag = (e) => {
|
|
1931
|
+
const d = dragRef.current;
|
|
1932
|
+
if (!d || !origin.current) return;
|
|
1933
|
+
const dHours = (e.clientX - origin.current.x) / hourWidth;
|
|
1934
|
+
const snap = (v) => Math.round(v / snapHours) * snapHours;
|
|
1935
|
+
if (d.kind === "move") {
|
|
1936
|
+
const startHours = clamp(snap(origin.current.startHours + dHours), startHour, endHour - d.durationHours);
|
|
1937
|
+
applyDrag({
|
|
1938
|
+
...d,
|
|
1939
|
+
startHours,
|
|
1940
|
+
moved: true
|
|
1941
|
+
});
|
|
1942
|
+
} else {
|
|
1943
|
+
const durationHours = clamp(snap(origin.current.durationHours + dHours), snapHours, endHour - d.startHours);
|
|
1944
|
+
applyDrag({
|
|
1945
|
+
...d,
|
|
1946
|
+
durationHours,
|
|
1947
|
+
moved: true
|
|
1948
|
+
});
|
|
1949
|
+
}
|
|
1950
|
+
};
|
|
1951
|
+
const endDrag = (e, event, onPress) => {
|
|
1952
|
+
const d = dragRef.current;
|
|
1953
|
+
if (!d) return;
|
|
1954
|
+
try {
|
|
1955
|
+
e.target.releasePointerCapture?.(e.pointerId);
|
|
1956
|
+
} catch {}
|
|
1957
|
+
if (!d.moved) {
|
|
1958
|
+
applyDrag(null);
|
|
1959
|
+
onPress();
|
|
1960
|
+
return;
|
|
1961
|
+
}
|
|
1962
|
+
const base = startOfDay(date);
|
|
1963
|
+
const start = addMinutes(base, Math.round(d.startHours * 60));
|
|
1964
|
+
const end = addMinutes(base, Math.round((d.startHours + d.durationHours) * 60));
|
|
1965
|
+
onDragEvent?.(event, start, end);
|
|
1966
|
+
applyDrag(null);
|
|
1967
|
+
origin.current = null;
|
|
1968
|
+
};
|
|
1969
|
+
const cancelDrag = () => {
|
|
1970
|
+
applyDrag(null);
|
|
1971
|
+
origin.current = null;
|
|
1972
|
+
};
|
|
1973
|
+
const hours = useMemo(() => Array.from({ length: Math.max(0, endHour - startHour) }, (_, i) => startHour + i), [startHour, endHour]);
|
|
1974
|
+
const trackWidth = (endHour - startHour) * hourWidth;
|
|
1975
|
+
const byResource = useMemo(() => {
|
|
1976
|
+
const map = /* @__PURE__ */ new Map();
|
|
1977
|
+
for (const resource of resources) {
|
|
1978
|
+
const own = events.filter((e) => resourceId(e) === resource.id);
|
|
1979
|
+
map.set(resource.id, layoutDayEvents$1(own, date));
|
|
1980
|
+
}
|
|
1981
|
+
return map;
|
|
1982
|
+
}, [
|
|
1983
|
+
resources,
|
|
1984
|
+
events,
|
|
1985
|
+
resourceId,
|
|
1986
|
+
date
|
|
1987
|
+
]);
|
|
1988
|
+
const gridLines = `repeating-linear-gradient(to right, transparent 0, transparent ${hourWidth - 1}px, ${theme.gridLine} ${hourWidth - 1}px, ${theme.gridLine} ${hourWidth}px)`;
|
|
1989
|
+
return /* @__PURE__ */ jsx("div", {
|
|
1990
|
+
className,
|
|
1991
|
+
style: {
|
|
1992
|
+
fontFamily: theme.fontFamily,
|
|
1993
|
+
color: theme.text,
|
|
1994
|
+
overflowX: "auto",
|
|
1995
|
+
...style
|
|
1996
|
+
},
|
|
1997
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
1998
|
+
style: { minWidth: labelWidth + trackWidth },
|
|
1999
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
2000
|
+
...slot("header", {
|
|
2001
|
+
base: { display: "flex" },
|
|
2002
|
+
themed: { borderBottom: `1px solid ${theme.gridLine}` }
|
|
2003
|
+
}),
|
|
2004
|
+
children: [/* @__PURE__ */ jsx("div", { ...slot("corner", { base: {
|
|
2005
|
+
width: labelWidth,
|
|
2006
|
+
flex: "none"
|
|
2007
|
+
} }) }), /* @__PURE__ */ jsx("div", {
|
|
2008
|
+
...slot("timeAxis", { base: {
|
|
2009
|
+
position: "relative",
|
|
2010
|
+
height: 24,
|
|
2011
|
+
width: trackWidth
|
|
2012
|
+
} }),
|
|
2013
|
+
children: hours.map((h) => /* @__PURE__ */ jsx("div", {
|
|
2014
|
+
...slot("hourTick", {
|
|
2015
|
+
base: {
|
|
2016
|
+
position: "absolute",
|
|
2017
|
+
left: (h - startHour) * hourWidth,
|
|
2018
|
+
top: 4
|
|
2019
|
+
},
|
|
2020
|
+
themed: {
|
|
2021
|
+
fontSize: 10,
|
|
2022
|
+
color: theme.textMuted
|
|
2023
|
+
}
|
|
2024
|
+
}),
|
|
2025
|
+
children: formatHour(h, { ampm })
|
|
2026
|
+
}, h))
|
|
2027
|
+
})]
|
|
2028
|
+
}), resources.map((resource) => {
|
|
2029
|
+
const positioned = byResource.get(resource.id) ?? [];
|
|
2030
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
2031
|
+
...slot("row", {
|
|
2032
|
+
base: {
|
|
2033
|
+
display: "flex",
|
|
2034
|
+
height: rowHeight
|
|
2035
|
+
},
|
|
2036
|
+
themed: { borderBottom: `1px solid ${theme.gridLine}` }
|
|
2037
|
+
}),
|
|
2038
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
2039
|
+
...slot("resourceLabel", {
|
|
2040
|
+
base: {
|
|
2041
|
+
width: labelWidth,
|
|
2042
|
+
flex: "none",
|
|
2043
|
+
display: "flex",
|
|
2044
|
+
alignItems: "center",
|
|
2045
|
+
padding: "0 10px",
|
|
2046
|
+
boxSizing: "border-box"
|
|
2047
|
+
},
|
|
2048
|
+
themed: {
|
|
2049
|
+
fontSize: 13,
|
|
2050
|
+
fontWeight: 600,
|
|
2051
|
+
borderRight: `1px solid ${theme.gridLine}`
|
|
2052
|
+
}
|
|
2053
|
+
}),
|
|
2054
|
+
children: resource.title ?? resource.id
|
|
2055
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
2056
|
+
...slot("track", { base: {
|
|
2057
|
+
position: "relative",
|
|
2058
|
+
width: trackWidth
|
|
2059
|
+
} }),
|
|
2060
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
2061
|
+
"aria-hidden": true,
|
|
2062
|
+
...slot("gridLines", {
|
|
2063
|
+
base: {
|
|
2064
|
+
position: "absolute",
|
|
2065
|
+
inset: 0,
|
|
2066
|
+
pointerEvents: "none"
|
|
2067
|
+
},
|
|
2068
|
+
themed: { backgroundImage: gridLines }
|
|
2069
|
+
})
|
|
2070
|
+
}), positioned.map((pe, idx) => {
|
|
2071
|
+
const key = `${resource.id}:${idx}`;
|
|
2072
|
+
const active = drag?.key === key ? drag : null;
|
|
2073
|
+
const startH = active ? active.startHours : pe.startHours;
|
|
2074
|
+
const durH = active ? active.durationHours : pe.durationHours;
|
|
2075
|
+
const left = clamp(startH - startHour, 0, endHour - startHour) * hourWidth;
|
|
2076
|
+
const right = clamp(startH + durH - startHour, 0, endHour - startHour) * hourWidth;
|
|
2077
|
+
const width = Math.max(right - left, 2);
|
|
2078
|
+
const laneHeight = rowHeight / pe.columns;
|
|
2079
|
+
const onPress = () => onPressEvent?.(pe.event);
|
|
2080
|
+
const args = {
|
|
2081
|
+
event: pe.event,
|
|
2082
|
+
width,
|
|
2083
|
+
onPress
|
|
2084
|
+
};
|
|
2085
|
+
const draggable = !!onDragEvent;
|
|
2086
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
2087
|
+
type: "button",
|
|
2088
|
+
onClick: draggable ? void 0 : onPress,
|
|
2089
|
+
"aria-label": pe.event.title,
|
|
2090
|
+
...dataState({ "data-dragging": !!active }),
|
|
2091
|
+
onPointerDown: draggable ? (e) => beginDrag(e, key, "move", pe.startHours, pe.durationHours) : void 0,
|
|
2092
|
+
onPointerMove: draggable ? moveDrag : void 0,
|
|
2093
|
+
onPointerUp: draggable ? (e) => endDrag(e, pe.event, onPress) : void 0,
|
|
2094
|
+
onPointerCancel: draggable ? cancelDrag : void 0,
|
|
2095
|
+
...slot("event", { base: {
|
|
2096
|
+
position: "absolute",
|
|
2097
|
+
left,
|
|
2098
|
+
width,
|
|
2099
|
+
top: pe.column * laneHeight,
|
|
2100
|
+
height: laneHeight,
|
|
2101
|
+
padding: 1,
|
|
2102
|
+
border: "none",
|
|
2103
|
+
background: "transparent",
|
|
2104
|
+
cursor: draggable ? "grab" : "pointer",
|
|
2105
|
+
touchAction: draggable ? "none" : "auto",
|
|
2106
|
+
font: "inherit",
|
|
2107
|
+
textAlign: "left",
|
|
2108
|
+
boxSizing: "border-box",
|
|
2109
|
+
zIndex: active ? 3 : 1,
|
|
2110
|
+
opacity: active ? .85 : 1
|
|
2111
|
+
} }),
|
|
2112
|
+
children: [Renderer ? /* @__PURE__ */ jsx(Renderer, { ...args }) : /* @__PURE__ */ jsx(DefaultBar, {
|
|
2113
|
+
...args,
|
|
2114
|
+
theme,
|
|
2115
|
+
boxProps: slot("eventBox")
|
|
2116
|
+
}), draggable ? /* @__PURE__ */ jsx("span", {
|
|
2117
|
+
"aria-hidden": true,
|
|
2118
|
+
onPointerDown: (e) => {
|
|
2119
|
+
e.stopPropagation();
|
|
2120
|
+
beginDrag(e, key, "resize", pe.startHours, pe.durationHours);
|
|
2121
|
+
},
|
|
2122
|
+
style: {
|
|
2123
|
+
position: "absolute",
|
|
2124
|
+
top: 0,
|
|
2125
|
+
bottom: 0,
|
|
2126
|
+
right: 0,
|
|
2127
|
+
width: 8,
|
|
2128
|
+
cursor: "ew-resize",
|
|
2129
|
+
touchAction: "none"
|
|
2130
|
+
}
|
|
2131
|
+
}) : null]
|
|
2132
|
+
}, idx);
|
|
2133
|
+
})]
|
|
2134
|
+
})]
|
|
2135
|
+
}, resource.id);
|
|
2136
|
+
})]
|
|
2137
|
+
})
|
|
2138
|
+
});
|
|
2139
|
+
}
|
|
2140
|
+
//#endregion
|
|
2141
|
+
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 };
|