@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/src/TimeGrid.tsx
CHANGED
|
@@ -16,7 +16,8 @@ import {
|
|
|
16
16
|
type CalendarMode,
|
|
17
17
|
cellRangeFromDrag,
|
|
18
18
|
closedHourBands,
|
|
19
|
-
eventAccessibilityLabel,
|
|
19
|
+
eventAccessibilityLabel as defaultEventAccessibilityLabel,
|
|
20
|
+
type EventAccessibilityLabeler,
|
|
20
21
|
eventChipLayout,
|
|
21
22
|
eventTimeLabel,
|
|
22
23
|
formatHour,
|
|
@@ -27,10 +28,36 @@ import {
|
|
|
27
28
|
layoutDayEvents,
|
|
28
29
|
type TimeGridMode,
|
|
29
30
|
titleNumberOfLines,
|
|
31
|
+
type WeekdayFormat,
|
|
32
|
+
weekdayFormatToken,
|
|
30
33
|
type WeekStartsOn,
|
|
31
34
|
} from "@super-calendar/core";
|
|
35
|
+
import { createSlots, dataState, type ResolvedSlot, type SlotStyleProps } from "./slots";
|
|
32
36
|
import { type DomCalendarTheme, mergeDomTheme } from "./theme";
|
|
33
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Styleable parts of {@link TimeGrid}. Pass a class or inline style per slot via
|
|
40
|
+
* the `classNames` / `styles` props.
|
|
41
|
+
*/
|
|
42
|
+
export type TimeGridSlot =
|
|
43
|
+
| "header"
|
|
44
|
+
| "columnHeader"
|
|
45
|
+
| "columnHeaderWeekday"
|
|
46
|
+
| "columnHeaderDate"
|
|
47
|
+
| "allDayLane"
|
|
48
|
+
| "allDayLabel"
|
|
49
|
+
| "allDayColumn"
|
|
50
|
+
| "allDayEvent"
|
|
51
|
+
| "hourGutter"
|
|
52
|
+
| "hourLabel"
|
|
53
|
+
| "dayColumn"
|
|
54
|
+
| "gridLines"
|
|
55
|
+
| "businessHours"
|
|
56
|
+
| "event"
|
|
57
|
+
| "eventBox"
|
|
58
|
+
| "nowIndicator"
|
|
59
|
+
| "createGhost";
|
|
60
|
+
|
|
34
61
|
const HOURS = Array.from({ length: 24 }, (_, h) => h);
|
|
35
62
|
const GUTTER_WIDTH = 56;
|
|
36
63
|
const clamp = (v: number, lo: number, hi: number) => Math.min(hi, Math.max(lo, v));
|
|
@@ -59,7 +86,7 @@ export interface DomRenderEventArgs<T = unknown> {
|
|
|
59
86
|
export type DomRenderEvent<T = unknown> = ComponentType<DomRenderEventArgs<T>>;
|
|
60
87
|
|
|
61
88
|
/** Props for {@link TimeGrid}. */
|
|
62
|
-
export interface TimeGridProps<T = unknown> {
|
|
89
|
+
export interface TimeGridProps<T = unknown> extends SlotStyleProps<TimeGridSlot> {
|
|
63
90
|
/** Anchor date; the visible columns are derived from it and `mode`. */
|
|
64
91
|
date: Date;
|
|
65
92
|
/** Events to lay out on the grid. */
|
|
@@ -70,6 +97,8 @@ export interface TimeGridProps<T = unknown> {
|
|
|
70
97
|
numberOfDays?: number;
|
|
71
98
|
/** First day of the week. Sunday = 0 (default) ... Saturday = 6. */
|
|
72
99
|
weekStartsOn?: WeekStartsOn;
|
|
100
|
+
/** Column-header weekday label width: `narrow` ("M"), `short` ("Mon", default), or `long` ("Monday"). */
|
|
101
|
+
weekdayFormat?: WeekdayFormat;
|
|
73
102
|
/** Initial pixels per hour (default 48). */
|
|
74
103
|
hourHeight?: number;
|
|
75
104
|
/** Initial scroll position, in minutes from midnight (default 8:00). */
|
|
@@ -100,6 +129,13 @@ export interface TimeGridProps<T = unknown> {
|
|
|
100
129
|
height?: number | string;
|
|
101
130
|
/** Custom event renderer; falls back to the built-in event box. */
|
|
102
131
|
renderEvent?: DomRenderEvent<T>;
|
|
132
|
+
/**
|
|
133
|
+
* Override the screen-reader label for each event. Receives the event and a
|
|
134
|
+
* `{ mode, isAllDay, ampm }` context; return the full text to announce. Defaults
|
|
135
|
+
* to the title plus the time range (or "all day"), which the grid otherwise only
|
|
136
|
+
* conveys visually.
|
|
137
|
+
*/
|
|
138
|
+
eventAccessibilityLabel?: EventAccessibilityLabeler<T>;
|
|
103
139
|
/** Replace the hour-axis label. Receives the hour (0-23) and the `ampm` flag. */
|
|
104
140
|
hourComponent?: (hour: number, ampm: boolean) => ReactNode;
|
|
105
141
|
/** Tap an event. */
|
|
@@ -146,7 +182,8 @@ function DefaultDomEvent<T>({
|
|
|
146
182
|
boxHeight,
|
|
147
183
|
ampm = false,
|
|
148
184
|
theme,
|
|
149
|
-
|
|
185
|
+
boxProps,
|
|
186
|
+
}: DomRenderEventArgs<T> & { theme: DomCalendarTheme; boxProps?: ResolvedSlot }) {
|
|
150
187
|
const timeLabel = eventTimeLabel({
|
|
151
188
|
mode,
|
|
152
189
|
isAllDay,
|
|
@@ -168,19 +205,36 @@ function DefaultDomEvent<T>({
|
|
|
168
205
|
paddingYPx: DOM_BOX_PADDING_V,
|
|
169
206
|
});
|
|
170
207
|
const oneLine = titleNumberOfLines(mode, isAllDay) === 1;
|
|
208
|
+
// A chip reduced to a single title line (no time) centers it vertically, so a
|
|
209
|
+
// very short event reads balanced instead of hugging the top edge.
|
|
210
|
+
const centerLoneTitle = titleMaxLines === 1 && !showTime;
|
|
211
|
+
// Structural box metrics always apply; the card's look (colour, radius, type)
|
|
212
|
+
// is themed and yields to a `eventBox` class when one is supplied.
|
|
213
|
+
const boxBase: CSSProperties = {
|
|
214
|
+
height: "100%",
|
|
215
|
+
boxSizing: "border-box",
|
|
216
|
+
overflow: "hidden",
|
|
217
|
+
lineHeight: `${DOM_TITLE_LINE_HEIGHT}px`,
|
|
218
|
+
...(centerLoneTitle
|
|
219
|
+
? { display: "flex", flexDirection: "column", justifyContent: "center" }
|
|
220
|
+
: null),
|
|
221
|
+
};
|
|
222
|
+
const boxThemed: CSSProperties = {
|
|
223
|
+
padding: `${DOM_BOX_PADDING_V}px 6px`,
|
|
224
|
+
borderRadius: 6,
|
|
225
|
+
background: theme.eventBackground,
|
|
226
|
+
color: theme.eventText,
|
|
227
|
+
fontSize: 12,
|
|
228
|
+
};
|
|
171
229
|
return (
|
|
172
230
|
<div
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
color: theme.eventText,
|
|
181
|
-
fontSize: 12,
|
|
182
|
-
lineHeight: `${DOM_TITLE_LINE_HEIGHT}px`,
|
|
183
|
-
}}
|
|
231
|
+
className={boxProps?.className}
|
|
232
|
+
data-slot={boxProps?.["data-slot"]}
|
|
233
|
+
style={
|
|
234
|
+
boxProps?.className
|
|
235
|
+
? { ...boxBase, ...boxProps.style }
|
|
236
|
+
: { ...boxBase, ...boxThemed, ...boxProps?.style }
|
|
237
|
+
}
|
|
184
238
|
>
|
|
185
239
|
<div
|
|
186
240
|
style={{
|
|
@@ -226,6 +280,7 @@ export function TimeGrid<T = unknown>({
|
|
|
226
280
|
mode = "day",
|
|
227
281
|
numberOfDays = 1,
|
|
228
282
|
weekStartsOn = 0,
|
|
283
|
+
weekdayFormat = "short",
|
|
229
284
|
hourHeight: initialHourHeight = 48,
|
|
230
285
|
scrollOffsetMinutes = 8 * 60,
|
|
231
286
|
zoomable = true,
|
|
@@ -241,6 +296,7 @@ export function TimeGrid<T = unknown>({
|
|
|
241
296
|
theme: themeOverrides,
|
|
242
297
|
height = 600,
|
|
243
298
|
renderEvent,
|
|
299
|
+
eventAccessibilityLabel,
|
|
244
300
|
hourComponent,
|
|
245
301
|
onPressEvent,
|
|
246
302
|
onPressDateHeader,
|
|
@@ -250,8 +306,11 @@ export function TimeGrid<T = unknown>({
|
|
|
250
306
|
onDragEvent,
|
|
251
307
|
className,
|
|
252
308
|
style,
|
|
309
|
+
classNames,
|
|
310
|
+
styles,
|
|
253
311
|
}: TimeGridProps<T>): ReactElement {
|
|
254
312
|
const theme = useMemo(() => mergeDomTheme(themeOverrides), [themeOverrides]);
|
|
313
|
+
const slot = createSlots<TimeGridSlot>({ classNames, styles });
|
|
255
314
|
const scrollRef = useRef<HTMLDivElement>(null);
|
|
256
315
|
const dfns = locale ? { locale } : undefined;
|
|
257
316
|
const snapHours = dragStepMinutes / 60;
|
|
@@ -508,7 +567,12 @@ export function TimeGrid<T = unknown>({
|
|
|
508
567
|
}}
|
|
509
568
|
>
|
|
510
569
|
{/* Header */}
|
|
511
|
-
<div
|
|
570
|
+
<div
|
|
571
|
+
{...slot("header", {
|
|
572
|
+
base: { display: "flex" },
|
|
573
|
+
themed: { borderBottom: `1px solid ${theme.gridLine}` },
|
|
574
|
+
})}
|
|
575
|
+
>
|
|
512
576
|
<div style={{ width: GUTTER_WIDTH, flex: "none" }} />
|
|
513
577
|
{days.map((day) => {
|
|
514
578
|
const today = getIsToday(day);
|
|
@@ -519,34 +583,43 @@ export function TimeGrid<T = unknown>({
|
|
|
519
583
|
tabIndex={onPressDateHeader ? 0 : -1}
|
|
520
584
|
aria-hidden={onPressDateHeader ? undefined : true}
|
|
521
585
|
onClick={onPressDateHeader ? () => onPressDateHeader(day) : undefined}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
display: "flex",
|
|
531
|
-
flexDirection: "column",
|
|
532
|
-
alignItems: "center",
|
|
533
|
-
gap: 2,
|
|
534
|
-
}}
|
|
535
|
-
>
|
|
536
|
-
<span style={{ fontSize: 11, fontWeight: 600 }}>{format(day, "EEE", dfns)}</span>
|
|
537
|
-
<span
|
|
538
|
-
style={{
|
|
539
|
-
width: 28,
|
|
540
|
-
height: 28,
|
|
541
|
-
borderRadius: "50%",
|
|
586
|
+
{...dataState({ "data-today": today })}
|
|
587
|
+
{...slot("columnHeader", {
|
|
588
|
+
base: {
|
|
589
|
+
flex: 1,
|
|
590
|
+
border: "none",
|
|
591
|
+
background: "transparent",
|
|
592
|
+
font: "inherit",
|
|
593
|
+
cursor: onPressDateHeader ? "pointer" : "default",
|
|
542
594
|
display: "flex",
|
|
595
|
+
flexDirection: "column",
|
|
543
596
|
alignItems: "center",
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
597
|
+
gap: 2,
|
|
598
|
+
},
|
|
599
|
+
themed: { color: theme.textMuted, padding: "6px 0" },
|
|
600
|
+
})}
|
|
601
|
+
>
|
|
602
|
+
<span {...slot("columnHeaderWeekday", { themed: { fontSize: 11, fontWeight: 600 } })}>
|
|
603
|
+
{format(day, weekdayFormatToken(weekdayFormat), dfns)}
|
|
604
|
+
</span>
|
|
605
|
+
<span
|
|
606
|
+
{...dataState({ "data-today": today })}
|
|
607
|
+
{...slot("columnHeaderDate", {
|
|
608
|
+
base: {
|
|
609
|
+
width: 28,
|
|
610
|
+
height: 28,
|
|
611
|
+
borderRadius: "50%",
|
|
612
|
+
display: "flex",
|
|
613
|
+
alignItems: "center",
|
|
614
|
+
justifyContent: "center",
|
|
615
|
+
},
|
|
616
|
+
themed: {
|
|
617
|
+
fontSize: 15,
|
|
618
|
+
fontWeight: 600,
|
|
619
|
+
background: today ? theme.todayBackground : "transparent",
|
|
620
|
+
color: today ? theme.todayText : theme.text,
|
|
621
|
+
},
|
|
622
|
+
})}
|
|
550
623
|
>
|
|
551
624
|
{format(day, "d", dfns)}
|
|
552
625
|
</span>
|
|
@@ -557,16 +630,17 @@ export function TimeGrid<T = unknown>({
|
|
|
557
630
|
|
|
558
631
|
{/* All-day lane */}
|
|
559
632
|
{showAllDayEventCell && hasAllDay ? (
|
|
560
|
-
<div
|
|
633
|
+
<div
|
|
634
|
+
{...slot("allDayLane", {
|
|
635
|
+
base: { display: "flex" },
|
|
636
|
+
themed: { borderBottom: `1px solid ${theme.gridLine}` },
|
|
637
|
+
})}
|
|
638
|
+
>
|
|
561
639
|
<div
|
|
562
|
-
|
|
563
|
-
width: GUTTER_WIDTH,
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
color: theme.textMuted,
|
|
567
|
-
textAlign: "right",
|
|
568
|
-
padding: "4px 6px 0 0",
|
|
569
|
-
}}
|
|
640
|
+
{...slot("allDayLabel", {
|
|
641
|
+
base: { width: GUTTER_WIDTH, flex: "none", textAlign: "right" },
|
|
642
|
+
themed: { fontSize: 10, color: theme.textMuted, padding: "4px 6px 0 0" },
|
|
643
|
+
})}
|
|
570
644
|
>
|
|
571
645
|
all-day
|
|
572
646
|
</div>
|
|
@@ -576,18 +650,20 @@ export function TimeGrid<T = unknown>({
|
|
|
576
650
|
return (
|
|
577
651
|
<div
|
|
578
652
|
key={days[i].toISOString()}
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
653
|
+
{...slot("allDayColumn", {
|
|
654
|
+
base: {
|
|
655
|
+
flex: 1,
|
|
656
|
+
minWidth: 0,
|
|
657
|
+
// Mirror the day column's geometry so the all-day chip lines up
|
|
658
|
+
// exactly with the timed events below it: a 1px left border (the
|
|
659
|
+
// grid line, transparent here) plus a 1px horizontal inset.
|
|
660
|
+
borderLeft: "1px solid transparent",
|
|
661
|
+
padding: "2px 1px",
|
|
662
|
+
display: "flex",
|
|
663
|
+
flexDirection: "column",
|
|
664
|
+
gap: 2,
|
|
665
|
+
},
|
|
666
|
+
})}
|
|
591
667
|
>
|
|
592
668
|
{list.map((event) => {
|
|
593
669
|
const args: DomRenderEventArgs<T> = {
|
|
@@ -606,26 +682,32 @@ export function TimeGrid<T = unknown>({
|
|
|
606
682
|
key={`${event.start.toISOString()}:${event.title}`}
|
|
607
683
|
type="button"
|
|
608
684
|
onClick={() => onPressEvent?.(event)}
|
|
609
|
-
aria-label={
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
685
|
+
aria-label={
|
|
686
|
+
eventAccessibilityLabel
|
|
687
|
+
? eventAccessibilityLabel(event, { mode, isAllDay: true, ampm })
|
|
688
|
+
: defaultEventAccessibilityLabel({
|
|
689
|
+
title: event.title,
|
|
690
|
+
isAllDay: true,
|
|
691
|
+
start: event.start,
|
|
692
|
+
end: event.end,
|
|
693
|
+
ampm,
|
|
694
|
+
})
|
|
695
|
+
}
|
|
696
|
+
{...slot("allDayEvent", {
|
|
697
|
+
base: {
|
|
698
|
+
border: "none",
|
|
699
|
+
padding: 0,
|
|
700
|
+
background: "transparent",
|
|
701
|
+
cursor: "pointer",
|
|
702
|
+
textAlign: "left",
|
|
703
|
+
height: 22,
|
|
704
|
+
},
|
|
615
705
|
})}
|
|
616
|
-
style={{
|
|
617
|
-
border: "none",
|
|
618
|
-
padding: 0,
|
|
619
|
-
background: "transparent",
|
|
620
|
-
cursor: "pointer",
|
|
621
|
-
textAlign: "left",
|
|
622
|
-
height: 22,
|
|
623
|
-
}}
|
|
624
706
|
>
|
|
625
707
|
{Renderer ? (
|
|
626
708
|
<Renderer {...args} />
|
|
627
709
|
) : (
|
|
628
|
-
<DefaultDomEvent {...args} theme={theme} />
|
|
710
|
+
<DefaultDomEvent {...args} theme={theme} boxProps={slot("eventBox")} />
|
|
629
711
|
)}
|
|
630
712
|
</button>
|
|
631
713
|
);
|
|
@@ -652,17 +734,18 @@ export function TimeGrid<T = unknown>({
|
|
|
652
734
|
>
|
|
653
735
|
<div style={{ display: "flex", height: totalHeight, position: "relative" }}>
|
|
654
736
|
{/* Hour gutter */}
|
|
655
|
-
<div
|
|
737
|
+
<div
|
|
738
|
+
{...slot("hourGutter", {
|
|
739
|
+
base: { width: GUTTER_WIDTH, flex: "none", position: "relative" },
|
|
740
|
+
})}
|
|
741
|
+
>
|
|
656
742
|
{HOURS.map((h) => (
|
|
657
743
|
<div
|
|
658
744
|
key={h}
|
|
659
|
-
|
|
660
|
-
position: "absolute",
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
fontSize: 10,
|
|
664
|
-
color: theme.textMuted,
|
|
665
|
-
}}
|
|
745
|
+
{...slot("hourLabel", {
|
|
746
|
+
base: { position: "absolute", top: h * hourHeight - 6, right: 6 },
|
|
747
|
+
themed: { fontSize: 10, color: theme.textMuted },
|
|
748
|
+
})}
|
|
666
749
|
>
|
|
667
750
|
{hourComponent ? hourComponent(h, ampm) : h === 0 ? "" : formatHour(h, { ampm })}
|
|
668
751
|
</div>
|
|
@@ -687,39 +770,38 @@ export function TimeGrid<T = unknown>({
|
|
|
687
770
|
onPointerMove={cellEnabled ? moveCreate : undefined}
|
|
688
771
|
onPointerUp={cellEnabled ? endCreate : undefined}
|
|
689
772
|
onPointerCancel={cellEnabled ? cancelCreate : undefined}
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
position: "relative",
|
|
693
|
-
borderLeft: `1px solid ${theme.gridLine}
|
|
694
|
-
}}
|
|
773
|
+
{...dataState({ "data-today": getIsToday(day) })}
|
|
774
|
+
{...slot("dayColumn", {
|
|
775
|
+
base: { flex: 1, position: "relative" },
|
|
776
|
+
themed: { borderLeft: `1px solid ${theme.gridLine}` },
|
|
777
|
+
})}
|
|
695
778
|
>
|
|
696
779
|
{/* Business-hours shade, behind the grid lines and events. */}
|
|
697
780
|
{bands.map((b) => (
|
|
698
781
|
<div
|
|
699
782
|
key={b.start}
|
|
700
783
|
aria-hidden
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
784
|
+
{...slot("businessHours", {
|
|
785
|
+
base: {
|
|
786
|
+
position: "absolute",
|
|
787
|
+
left: 0,
|
|
788
|
+
right: 0,
|
|
789
|
+
top: b.start * hourHeight,
|
|
790
|
+
height: (b.end - b.start) * hourHeight,
|
|
791
|
+
pointerEvents: "none",
|
|
792
|
+
zIndex: 0,
|
|
793
|
+
},
|
|
794
|
+
themed: { background: theme.outsideHoursBackground },
|
|
795
|
+
})}
|
|
711
796
|
/>
|
|
712
797
|
))}
|
|
713
798
|
{/* Grid lines, painted over the shade so they stay visible. */}
|
|
714
799
|
<div
|
|
715
800
|
aria-hidden
|
|
716
|
-
|
|
717
|
-
position: "absolute",
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
zIndex: 0,
|
|
721
|
-
backgroundImage: gridLines,
|
|
722
|
-
}}
|
|
801
|
+
{...slot("gridLines", {
|
|
802
|
+
base: { position: "absolute", inset: 0, pointerEvents: "none", zIndex: 0 },
|
|
803
|
+
themed: { backgroundImage: gridLines },
|
|
804
|
+
})}
|
|
723
805
|
/>
|
|
724
806
|
{positioned.map((pe, idx) => {
|
|
725
807
|
const key = `${dayIndex}:${idx}`;
|
|
@@ -746,13 +828,17 @@ export function TimeGrid<T = unknown>({
|
|
|
746
828
|
key={idx}
|
|
747
829
|
role="button"
|
|
748
830
|
tabIndex={0}
|
|
749
|
-
aria-label={
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
831
|
+
aria-label={
|
|
832
|
+
eventAccessibilityLabel
|
|
833
|
+
? eventAccessibilityLabel(pe.event, { mode, isAllDay: false, ampm })
|
|
834
|
+
: defaultEventAccessibilityLabel({
|
|
835
|
+
title: pe.event.title,
|
|
836
|
+
isAllDay: false,
|
|
837
|
+
start: pe.event.start,
|
|
838
|
+
end: pe.event.end,
|
|
839
|
+
ampm,
|
|
840
|
+
})
|
|
841
|
+
}
|
|
756
842
|
onKeyDown={(e) => {
|
|
757
843
|
if (e.key === "Enter" || e.key === " ") {
|
|
758
844
|
e.preventDefault();
|
|
@@ -771,22 +857,29 @@ export function TimeGrid<T = unknown>({
|
|
|
771
857
|
}
|
|
772
858
|
onPointerCancel={draggable ? cancelDrag : undefined}
|
|
773
859
|
onClick={draggable ? undefined : onPress}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
860
|
+
{...dataState({ "data-dragging": !!active })}
|
|
861
|
+
{...slot("event", {
|
|
862
|
+
base: {
|
|
863
|
+
position: "absolute",
|
|
864
|
+
top,
|
|
865
|
+
// Height is the event's duration, so it always tracks the
|
|
866
|
+
// grid's hour scale (zoom/resize). Content that doesn't fit
|
|
867
|
+
// is the renderer's concern: the built-in one clamps, and a
|
|
868
|
+
// custom renderer should adapt to the `boxHeight` it's given.
|
|
869
|
+
height: boxHeight,
|
|
870
|
+
left: `calc(${pe.column * widthPct}% + 1px)`,
|
|
871
|
+
width: `calc(${widthPct}% - 2px)`,
|
|
872
|
+
cursor: draggable ? "grab" : "pointer",
|
|
873
|
+
touchAction: draggable ? "none" : "auto",
|
|
874
|
+
zIndex: active ? 3 : 1,
|
|
875
|
+
opacity: active ? 0.85 : 1,
|
|
876
|
+
},
|
|
877
|
+
})}
|
|
785
878
|
>
|
|
786
879
|
{Renderer ? (
|
|
787
880
|
<Renderer {...args} />
|
|
788
881
|
) : (
|
|
789
|
-
<DefaultDomEvent {...args} theme={theme} />
|
|
882
|
+
<DefaultDomEvent {...args} theme={theme} boxProps={slot("eventBox")} />
|
|
790
883
|
)}
|
|
791
884
|
{draggable ? (
|
|
792
885
|
<div
|
|
@@ -810,15 +903,17 @@ export function TimeGrid<T = unknown>({
|
|
|
810
903
|
})}
|
|
811
904
|
{showNow ? (
|
|
812
905
|
<div
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
906
|
+
{...slot("nowIndicator", {
|
|
907
|
+
base: {
|
|
908
|
+
position: "absolute",
|
|
909
|
+
top: nowTop,
|
|
910
|
+
left: 0,
|
|
911
|
+
right: 0,
|
|
912
|
+
height: 0,
|
|
913
|
+
zIndex: 2,
|
|
914
|
+
pointerEvents: "none",
|
|
915
|
+
},
|
|
916
|
+
})}
|
|
822
917
|
>
|
|
823
918
|
<div style={{ height: 2, background: theme.nowIndicator }} />
|
|
824
919
|
<div
|
|
@@ -837,19 +932,23 @@ export function TimeGrid<T = unknown>({
|
|
|
837
932
|
{ghost ? (
|
|
838
933
|
<div
|
|
839
934
|
aria-hidden
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
935
|
+
{...slot("createGhost", {
|
|
936
|
+
base: {
|
|
937
|
+
position: "absolute",
|
|
938
|
+
left: 1,
|
|
939
|
+
right: 1,
|
|
940
|
+
top: ghost.topPx,
|
|
941
|
+
height: Math.max(ghost.heightPx, 2),
|
|
942
|
+
opacity: 0.7,
|
|
943
|
+
pointerEvents: "none",
|
|
944
|
+
zIndex: 2,
|
|
945
|
+
},
|
|
946
|
+
themed: {
|
|
947
|
+
background: theme.rangeBackground,
|
|
948
|
+
border: `1px solid ${theme.selectedBackground}`,
|
|
949
|
+
borderRadius: 6,
|
|
950
|
+
},
|
|
951
|
+
})}
|
|
853
952
|
/>
|
|
854
953
|
) : null}
|
|
855
954
|
</div>
|
package/src/index.ts
CHANGED
|
@@ -19,21 +19,44 @@
|
|
|
19
19
|
*
|
|
20
20
|
* @module
|
|
21
21
|
*/
|
|
22
|
-
export {
|
|
23
|
-
|
|
22
|
+
export {
|
|
23
|
+
Agenda,
|
|
24
|
+
type AgendaProps,
|
|
25
|
+
type AgendaSlot,
|
|
26
|
+
type DomAgendaEvent,
|
|
27
|
+
type DomAgendaEventArgs,
|
|
28
|
+
} from "./Agenda";
|
|
29
|
+
export { Calendar, type CalendarProps, type CalendarSlot } from "./Calendar";
|
|
30
|
+
export {
|
|
31
|
+
DatePicker,
|
|
32
|
+
type DatePickerProps,
|
|
33
|
+
type DatePickerSlot,
|
|
34
|
+
DateRangePicker,
|
|
35
|
+
type DateRangePickerProps,
|
|
36
|
+
} from "./DateRangePicker";
|
|
24
37
|
export {
|
|
25
38
|
type DomMonthEvent,
|
|
26
39
|
type DomMonthEventArgs,
|
|
27
40
|
MonthView,
|
|
28
41
|
type MonthViewProps,
|
|
42
|
+
type MonthViewSlot,
|
|
29
43
|
} from "./MonthView";
|
|
30
|
-
export { MonthList, type MonthListProps } from "./MonthList";
|
|
44
|
+
export { MonthList, type MonthListProps, type MonthListSlot } from "./MonthList";
|
|
45
|
+
export {
|
|
46
|
+
type Resource,
|
|
47
|
+
type ResourceEventArgs,
|
|
48
|
+
ResourceTimeline,
|
|
49
|
+
type ResourceTimelineProps,
|
|
50
|
+
type ResourceTimelineSlot,
|
|
51
|
+
} from "./ResourceTimeline";
|
|
31
52
|
export {
|
|
32
53
|
TimeGrid,
|
|
33
54
|
type TimeGridProps,
|
|
55
|
+
type TimeGridSlot,
|
|
34
56
|
type DomRenderEvent,
|
|
35
57
|
type DomRenderEventArgs,
|
|
36
58
|
} from "./TimeGrid";
|
|
59
|
+
export { type ResolvedSlot, type SlotDefault, type SlotStyleProps } from "./slots";
|
|
37
60
|
export { type DomCalendarTheme, darkDomTheme, defaultDomTheme, mergeDomTheme } from "./theme";
|
|
38
61
|
export {
|
|
39
62
|
type BusinessHours,
|
|
@@ -42,11 +65,20 @@ export {
|
|
|
42
65
|
type DateRange,
|
|
43
66
|
type DateSelectionConstraints,
|
|
44
67
|
type DaySelectionState,
|
|
68
|
+
type EventAccessibilityLabelContext,
|
|
69
|
+
type EventAccessibilityLabeler,
|
|
45
70
|
type ICalendarEvent,
|
|
71
|
+
type ICalEvent,
|
|
72
|
+
parseICalendar,
|
|
73
|
+
toICalendar,
|
|
74
|
+
type ToICalendarOptions,
|
|
46
75
|
type PositionedEvent,
|
|
47
76
|
type TimeGridMode,
|
|
48
77
|
type UseDateRangeOptions,
|
|
49
78
|
type WeekStartsOn,
|
|
79
|
+
type RecurrenceRule,
|
|
80
|
+
type RecurrenceFrequency,
|
|
81
|
+
expandRecurringEvents,
|
|
50
82
|
getViewDays,
|
|
51
83
|
isAllDayEvent,
|
|
52
84
|
layoutDayEvents,
|
|
@@ -58,9 +90,11 @@ export {
|
|
|
58
90
|
useDateRange,
|
|
59
91
|
useMonthGrid,
|
|
60
92
|
buildMonthGrid,
|
|
93
|
+
weekdayFormatToken,
|
|
61
94
|
type MonthGrid,
|
|
62
95
|
type MonthGridDay,
|
|
63
96
|
type MonthGridWeek,
|
|
64
97
|
type MonthGridWeekday,
|
|
65
98
|
type UseMonthGridOptions,
|
|
99
|
+
type WeekdayFormat,
|
|
66
100
|
} from "@super-calendar/core";
|