@fullcalendar/list 7.0.0-beta.4 → 7.0.0-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -1
- package/README.md +6 -1
- package/cjs/index.cjs +60 -0
- package/cjs/internal.cjs +228 -0
- package/esm/index.d.ts +54 -0
- package/{index.js → esm/index.js} +15 -11
- package/{internal-common.d.ts → esm/internal-common.d.ts} +5 -10
- package/esm/internal.js +220 -0
- package/global.js +290 -0
- package/global.min.js +6 -0
- package/package.json +22 -19
- package/index.cjs +0 -56
- package/index.d.ts +0 -27
- package/index.global.js +0 -334
- package/index.global.min.js +0 -6
- package/internal.cjs +0 -273
- package/internal.js +0 -269
- /package/{internal.d.ts → esm/internal.d.ts} +0 -0
package/internal.cjs
DELETED
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
var internal_cjs = require('@fullcalendar/core/internal.cjs');
|
|
6
|
-
var preact_cjs = require('@fullcalendar/core/preact.cjs');
|
|
7
|
-
|
|
8
|
-
class ListDayHeader extends internal_cjs.BaseComponent {
|
|
9
|
-
render() {
|
|
10
|
-
let { dateEnv, options, viewApi } = this.context;
|
|
11
|
-
let { dayDate, todayRange } = this.props;
|
|
12
|
-
let stickyHeaderDates = !this.props.forPrint && internal_cjs.getStickyHeaderDates(options);
|
|
13
|
-
let dayMeta = internal_cjs.getDateMeta(dayDate, todayRange);
|
|
14
|
-
// will ever be falsy?
|
|
15
|
-
let text = options.listDayFormat ? dateEnv.format(dayDate, options.listDayFormat) : '';
|
|
16
|
-
// will ever be falsy? also, BAD NAME "alt"
|
|
17
|
-
let sideText = options.listDaySideFormat ? dateEnv.format(dayDate, options.listDaySideFormat) : '';
|
|
18
|
-
let isNavLink = options.navLinks;
|
|
19
|
-
let renderProps = Object.assign({ date: dateEnv.toDate(dayDate), view: viewApi, text,
|
|
20
|
-
sideText, navLinkAttrs: isNavLink
|
|
21
|
-
? internal_cjs.buildNavLinkAttrs(this.context, dayDate, undefined, text)
|
|
22
|
-
: {}, sideNavLinkAttrs: isNavLink
|
|
23
|
-
// duplicate navLink, so does not need to be tabbable
|
|
24
|
-
? internal_cjs.buildNavLinkAttrs(this.context, dayDate, undefined, sideText, /* isTabbable = */ false)
|
|
25
|
-
: {} }, dayMeta);
|
|
26
|
-
// TODO: make a reusable HOC for dayHeader (used in daygrid/timegrid too)
|
|
27
|
-
return (preact_cjs.createElement("div", { className: internal_cjs.joinClassNames('fc-list-day-outer', stickyHeaderDates && 'fc-list-day-outer-sticky') },
|
|
28
|
-
preact_cjs.createElement(internal_cjs.ContentContainer, { tag: "div", className: internal_cjs.joinClassNames('fc-list-day', internal_cjs.getDayClassName(dayMeta)), attrs: Object.assign({ 'data-date': internal_cjs.formatDayString(dayDate) }, (dayMeta.isToday ? { 'aria-current': 'date' } : {})), renderProps: renderProps, generatorName: "dayHeaderContent", customGenerator: options.dayHeaderContent, defaultGenerator: renderInnerContent, classNameGenerator: options.dayHeaderClassNames, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount })));
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
function renderInnerContent(props) {
|
|
32
|
-
return (preact_cjs.createElement(preact_cjs.Fragment, null,
|
|
33
|
-
props.text && (preact_cjs.createElement("div", Object.assign({ className: "fc-list-day-text" }, props.navLinkAttrs), props.text)),
|
|
34
|
-
props.sideText && (preact_cjs.createElement("div", Object.assign({ className: "fc-list-day-side-text" }, props.sideNavLinkAttrs), props.sideText))));
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const DEFAULT_TIME_FORMAT = internal_cjs.createFormatter({
|
|
38
|
-
hour: 'numeric',
|
|
39
|
-
minute: '2-digit',
|
|
40
|
-
meridiem: 'short',
|
|
41
|
-
});
|
|
42
|
-
class ListEvent extends internal_cjs.BaseComponent {
|
|
43
|
-
constructor() {
|
|
44
|
-
super(...arguments);
|
|
45
|
-
this.handleTitleEl = (titleEl) => {
|
|
46
|
-
if (this.disconnectTitleWidth) {
|
|
47
|
-
this.disconnectTitleWidth();
|
|
48
|
-
}
|
|
49
|
-
if (titleEl) {
|
|
50
|
-
this.disconnectTitleWidth = internal_cjs.watchWidth(titleEl, (titleWidth) => {
|
|
51
|
-
internal_cjs.setRef(this.props.timeWidthRef, titleWidth);
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
render() {
|
|
57
|
-
let { props, context } = this;
|
|
58
|
-
let { eventRange } = props;
|
|
59
|
-
let { options } = context;
|
|
60
|
-
let timeFormat = options.eventTimeFormat || DEFAULT_TIME_FORMAT;
|
|
61
|
-
let [tag, attrs] = internal_cjs.getEventTagAndAttrs(eventRange, context);
|
|
62
|
-
return (preact_cjs.createElement(internal_cjs.EventContainer, Object.assign({}, props, { tag: tag, attrs: Object.assign({ role: 'listitem' }, attrs), className: 'fc-list-event', defaultGenerator: renderEventTitleOnly, eventRange: eventRange, timeText: "", disableDragging: true, disableResizing: true }), (InnerContent, eventContentArg) => (preact_cjs.createElement(preact_cjs.Fragment, null,
|
|
63
|
-
preact_cjs.createElement("div", { className: 'fc-list-event-time-outer', style: { width: props.timeOuterWidth } }, this.buildTimeContent(eventRange, props.slicedStart, props.slicedEnd, props.isStart, props.isEnd, timeFormat, context)),
|
|
64
|
-
preact_cjs.createElement("div", { className: "fc-list-event-dot-outer" },
|
|
65
|
-
preact_cjs.createElement("span", { className: "fc-list-event-dot", style: {
|
|
66
|
-
borderColor: eventContentArg.borderColor || eventContentArg.backgroundColor,
|
|
67
|
-
} })),
|
|
68
|
-
preact_cjs.createElement(InnerContent, { tag: "div", className: 'fc-list-event-title' })))));
|
|
69
|
-
}
|
|
70
|
-
buildTimeContent(eventRange, // whole-day span
|
|
71
|
-
slicedStart, // view-sliced whole-day span
|
|
72
|
-
slicedEnd, // view-sliced whole-day span
|
|
73
|
-
isStart, isEnd, timeFormat, context) {
|
|
74
|
-
let { options } = context;
|
|
75
|
-
if (options.displayEventTime !== false) {
|
|
76
|
-
if (eventRange.def.allDay || (!isStart && !isEnd)) {
|
|
77
|
-
let renderProps = {
|
|
78
|
-
text: context.options.allDayText,
|
|
79
|
-
view: context.viewApi,
|
|
80
|
-
};
|
|
81
|
-
return (preact_cjs.createElement(internal_cjs.ContentContainer, { tag: "div", className: 'fc-list-event-time', renderProps: renderProps, elRef: this.handleTitleEl, generatorName: "allDayContent", customGenerator: options.allDayContent, defaultGenerator: renderAllDayInner, classNameGenerator: options.allDayClassNames, didMount: options.allDayDidMount, willUnmount: options.allDayWillUnmount }));
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
return (preact_cjs.createElement("div", { className: "fc-list-event-time", ref: this.handleTitleEl }, internal_cjs.buildEventRangeTimeText(timeFormat, eventRange, slicedStart, slicedEnd, isStart, isEnd, context)));
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return null;
|
|
88
|
-
}
|
|
89
|
-
componentWillUnmount() {
|
|
90
|
-
internal_cjs.setRef(this.props.timeWidthRef, null);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
function renderEventTitleOnly(renderProps) {
|
|
94
|
-
return renderProps.event.title;
|
|
95
|
-
}
|
|
96
|
-
function renderAllDayInner(renderProps) {
|
|
97
|
-
return renderProps.text;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
class ListDay extends internal_cjs.BaseComponent {
|
|
101
|
-
constructor() {
|
|
102
|
-
super(...arguments);
|
|
103
|
-
// memo
|
|
104
|
-
this.sortEventSegs = internal_cjs.memoize(internal_cjs.sortEventSegs);
|
|
105
|
-
// ref
|
|
106
|
-
this.timeWidthRefMap = new internal_cjs.RefMap(() => {
|
|
107
|
-
internal_cjs.afterSize(this.handleTimeWidths);
|
|
108
|
-
});
|
|
109
|
-
this.handleTimeWidths = () => {
|
|
110
|
-
const timeWidthMap = this.timeWidthRefMap.current;
|
|
111
|
-
let max = 0;
|
|
112
|
-
for (const timeWidth of timeWidthMap.values()) {
|
|
113
|
-
max = Math.max(max, timeWidth);
|
|
114
|
-
}
|
|
115
|
-
internal_cjs.setRef(this.props.timeWidthRef, max);
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
render() {
|
|
119
|
-
const { props, context, timeWidthRefMap } = this;
|
|
120
|
-
const { nowDate, todayRange } = props;
|
|
121
|
-
const { options } = context;
|
|
122
|
-
const segs = this.sortEventSegs(props.segs, options.eventOrder);
|
|
123
|
-
const fullDateStr = internal_cjs.buildDateStr(this.context, props.dayDate);
|
|
124
|
-
return (preact_cjs.createElement("div", { role: 'listitem', "aria-label": fullDateStr, className: 'fc-list-day-and-events' },
|
|
125
|
-
preact_cjs.createElement(ListDayHeader, { dayDate: props.dayDate, todayRange: todayRange, forPrint: props.forPrint }),
|
|
126
|
-
preact_cjs.createElement("div", { role: 'list', "aria-label": options.eventsHint }, segs.map((seg) => {
|
|
127
|
-
const key = internal_cjs.getEventKey(seg);
|
|
128
|
-
return (preact_cjs.createElement(ListEvent, Object.assign({ key: key, eventRange: seg.eventRange, slicedStart: seg.slicedStart, slicedEnd: seg.slicedEnd, isStart: seg.isStart, isEnd: seg.isEnd, timeWidthRef: timeWidthRefMap.createRef(key), timeOuterWidth: props.timeOuterWidth, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: false }, internal_cjs.getEventRangeMeta(seg.eventRange, todayRange, nowDate))));
|
|
129
|
-
}))));
|
|
130
|
-
}
|
|
131
|
-
componentWillUnmount() {
|
|
132
|
-
internal_cjs.setRef(this.props.timeWidthRef, null);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/*
|
|
137
|
-
Responsible for the scroller, and forwarding event-related actions into the "grid".
|
|
138
|
-
*/
|
|
139
|
-
class ListView extends internal_cjs.DateComponent {
|
|
140
|
-
constructor() {
|
|
141
|
-
super(...arguments);
|
|
142
|
-
// memo
|
|
143
|
-
this.computeDateVars = internal_cjs.memoize(computeDateVars);
|
|
144
|
-
this.eventStoreToSegs = internal_cjs.memoize(this._eventStoreToSegs);
|
|
145
|
-
// ref
|
|
146
|
-
this.timeWidthRefMap = new internal_cjs.RefMap(() => {
|
|
147
|
-
internal_cjs.afterSize(this.handleTimeWidths);
|
|
148
|
-
});
|
|
149
|
-
this.setRootEl = (rootEl) => {
|
|
150
|
-
if (rootEl) {
|
|
151
|
-
this.context.registerInteractiveComponent(this, {
|
|
152
|
-
el: rootEl,
|
|
153
|
-
disableHits: true, // HACK to not do date-clicking/selecting
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
this.context.unregisterInteractiveComponent(this);
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
this.handleTimeWidths = () => {
|
|
161
|
-
const timeWidthMap = this.timeWidthRefMap.current;
|
|
162
|
-
let max = 0;
|
|
163
|
-
for (const timeWidth of timeWidthMap.values()) {
|
|
164
|
-
max = Math.max(max, timeWidth);
|
|
165
|
-
}
|
|
166
|
-
this.setState({ timeOuterWidth: max });
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
render() {
|
|
170
|
-
let { props, context } = this;
|
|
171
|
-
let { options } = context;
|
|
172
|
-
let { dayDates, dayRanges } = this.computeDateVars(props.dateProfile);
|
|
173
|
-
let eventSegs = this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges);
|
|
174
|
-
let verticalScrolling = !props.forPrint && !internal_cjs.getIsHeightAuto(options);
|
|
175
|
-
return (preact_cjs.createElement(internal_cjs.ViewContainer, { viewSpec: context.viewSpec, className: 'fc-list fc-flex-col fc-border', elRef: this.setRootEl },
|
|
176
|
-
preact_cjs.createElement(internal_cjs.Scroller // TODO: don't need heavyweight component
|
|
177
|
-
, { vertical: verticalScrolling, className: verticalScrolling ? 'fc-liquid' : '' },
|
|
178
|
-
this.renderSegList(eventSegs, dayDates),
|
|
179
|
-
!eventSegs.length && this.renderEmptyMessage())));
|
|
180
|
-
}
|
|
181
|
-
renderEmptyMessage() {
|
|
182
|
-
let { options, viewApi } = this.context;
|
|
183
|
-
let renderProps = {
|
|
184
|
-
text: options.noEventsText,
|
|
185
|
-
view: viewApi,
|
|
186
|
-
};
|
|
187
|
-
return (preact_cjs.createElement(internal_cjs.ContentContainer, { tag: "div", attrs: {
|
|
188
|
-
role: 'status', // does a polite announcement
|
|
189
|
-
}, className: 'fc-list-empty', renderProps: renderProps, generatorName: "noEventsContent", customGenerator: options.noEventsContent, defaultGenerator: renderNoEventsInner, classNameGenerator: options.noEventsClassNames, didMount: options.noEventsDidMount, willUnmount: options.noEventsWillUnmount }, (InnerContent) => (preact_cjs.createElement(InnerContent, { tag: "div", className: 'fc-list-empty-inner' }))));
|
|
190
|
-
}
|
|
191
|
-
renderSegList(allSegs, dayDates) {
|
|
192
|
-
let segsByDay = groupSegsByDay(allSegs); // sparse array
|
|
193
|
-
return (preact_cjs.createElement("div", { role: 'list', "aria-labelledby": this.props.labelId, "aria-label": this.props.labelStr },
|
|
194
|
-
preact_cjs.createElement(internal_cjs.NowTimer, { unit: "day" }, (nowDate, todayRange) => {
|
|
195
|
-
const dayNodes = [];
|
|
196
|
-
for (let dayIndex = 0; dayIndex < segsByDay.length; dayIndex += 1) {
|
|
197
|
-
let daySegs = segsByDay[dayIndex];
|
|
198
|
-
if (daySegs) { // sparse array, so might be undefined
|
|
199
|
-
const dayDate = dayDates[dayIndex];
|
|
200
|
-
const key = internal_cjs.formatDayString(dayDate);
|
|
201
|
-
dayNodes.push(preact_cjs.createElement(ListDay, { key: key, dayDate: dayDate, nowDate: nowDate, todayRange: todayRange, segs: daySegs, forPrint: this.props.forPrint, timeWidthRef: this.timeWidthRefMap.createRef(key), timeOuterWidth: this.state.timeOuterWidth }));
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
return (preact_cjs.createElement(preact_cjs.Fragment, null, dayNodes));
|
|
205
|
-
})));
|
|
206
|
-
}
|
|
207
|
-
_eventStoreToSegs(eventStore, eventUiBases, dayRanges) {
|
|
208
|
-
return this.eventRangesToSegs(internal_cjs.sliceEventStore(eventStore, eventUiBases,
|
|
209
|
-
// HACKY to reference internal state...
|
|
210
|
-
this.props.dateProfile.activeRange, this.context.options.nextDayThreshold).fg, dayRanges);
|
|
211
|
-
}
|
|
212
|
-
eventRangesToSegs(fullDayEventRanges, dayRanges) {
|
|
213
|
-
let segs = [];
|
|
214
|
-
for (let fullDayEventRange of fullDayEventRanges) {
|
|
215
|
-
segs.push(...this.eventRangeToSegs(fullDayEventRange, dayRanges));
|
|
216
|
-
}
|
|
217
|
-
return segs;
|
|
218
|
-
}
|
|
219
|
-
eventRangeToSegs(fullDayEventRange, dayRanges) {
|
|
220
|
-
let fullDayRange = fullDayEventRange.range;
|
|
221
|
-
let dayIndex;
|
|
222
|
-
let segs = [];
|
|
223
|
-
for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex += 1) {
|
|
224
|
-
const slicedFullDayRange = internal_cjs.intersectRanges(fullDayRange, dayRanges[dayIndex]);
|
|
225
|
-
if (slicedFullDayRange) {
|
|
226
|
-
segs.push({
|
|
227
|
-
eventRange: fullDayEventRange,
|
|
228
|
-
slicedStart: slicedFullDayRange.start,
|
|
229
|
-
slicedEnd: slicedFullDayRange.end,
|
|
230
|
-
isStart: fullDayEventRange.isStart && fullDayRange.start.valueOf() === slicedFullDayRange.start.valueOf(),
|
|
231
|
-
isEnd: fullDayEventRange.isEnd && fullDayRange.end.valueOf() === slicedFullDayRange.end.valueOf(),
|
|
232
|
-
dayIndex,
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
return segs;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
function renderNoEventsInner(renderProps) {
|
|
240
|
-
return renderProps.text;
|
|
241
|
-
}
|
|
242
|
-
function computeDateVars(dateProfile) {
|
|
243
|
-
let dayStart = internal_cjs.startOfDay(dateProfile.renderRange.start);
|
|
244
|
-
let viewEnd = dateProfile.renderRange.end;
|
|
245
|
-
let dayDates = [];
|
|
246
|
-
let dayRanges = [];
|
|
247
|
-
while (dayStart < viewEnd) {
|
|
248
|
-
dayDates.push(dayStart);
|
|
249
|
-
dayRanges.push({
|
|
250
|
-
start: dayStart,
|
|
251
|
-
end: internal_cjs.addDays(dayStart, 1),
|
|
252
|
-
});
|
|
253
|
-
dayStart = internal_cjs.addDays(dayStart, 1);
|
|
254
|
-
}
|
|
255
|
-
return { dayDates, dayRanges };
|
|
256
|
-
}
|
|
257
|
-
// Returns a sparse array of arrays, segs grouped by their dayIndex
|
|
258
|
-
function groupSegsByDay(segs) {
|
|
259
|
-
let segsByDay = []; // sparse array
|
|
260
|
-
let i;
|
|
261
|
-
let seg;
|
|
262
|
-
for (i = 0; i < segs.length; i += 1) {
|
|
263
|
-
seg = segs[i];
|
|
264
|
-
(segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = []))
|
|
265
|
-
.push(seg);
|
|
266
|
-
}
|
|
267
|
-
return segsByDay;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
var css_248z = ":root{--fc-list-event-dot-width:10px;--fc-list-event-hover-bg-color:#f5f5f5}.fc-list-day,.fc-list-event-dot-outer,.fc-list-event-time,.fc-list-event-title{padding:8px 14px}.fc-direction-ltr .fc-list-event-dot-outer{padding-right:0}.fc-direction-rtl .fc-list-event-dot-outer{padding-left:0}.fc-list-empty{align-items:center;background-color:var(--fc-neutral-bg-color);display:flex;height:100%;justify-content:center}.fc-list-empty-inner{margin:5em 0}.fc-list-day,.fc-list-event:not(.fc-list-day-and-events:last-child .fc-list-event:last-child){border-bottom:1px solid var(--fc-border-color)}.fc-list-day-outer-sticky{background:var(--fc-page-bg-color);position:sticky;top:0}.fc-list-day{background:var(--fc-neutral-bg-color);display:flex;font-weight:700;justify-content:space-between}.fc-list-event{display:flex;flex-direction:row}a.fc-list-event{color:inherit;text-decoration:none}.fc-list-event:hover{background-color:var(--fc-list-event-hover-bg-color)}.fc-list-event-time-outer{display:flex;flex-direction:row}.fc-list-event-dot-outer,.fc-list-event-time{white-space:nowrap}.fc-list-event-dot{border:calc(var(--fc-list-event-dot-width)/2) solid var(--fc-event-border-color);border-radius:calc(var(--fc-list-event-dot-width)/2);box-sizing:content-box;display:inline-block;height:0;width:0}a.fc-list-event:hover .fc-list-event-title{text-decoration:underline}";
|
|
271
|
-
internal_cjs.injectStyles(css_248z);
|
|
272
|
-
|
|
273
|
-
exports.ListView = ListView;
|
package/internal.js
DELETED
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
import { BaseComponent, getStickyHeaderDates, getDateMeta, buildNavLinkAttrs, joinClassNames, ContentContainer, getDayClassName, formatDayString, createFormatter, watchWidth, setRef, getEventTagAndAttrs, EventContainer, buildEventRangeTimeText, memoize, sortEventSegs, RefMap, afterSize, buildDateStr, getEventKey, getEventRangeMeta, DateComponent, getIsHeightAuto, ViewContainer, Scroller, NowTimer, sliceEventStore, intersectRanges, startOfDay, addDays, injectStyles } from '@fullcalendar/core/internal.js';
|
|
2
|
-
import { createElement, Fragment } from '@fullcalendar/core/preact.js';
|
|
3
|
-
|
|
4
|
-
class ListDayHeader extends BaseComponent {
|
|
5
|
-
render() {
|
|
6
|
-
let { dateEnv, options, viewApi } = this.context;
|
|
7
|
-
let { dayDate, todayRange } = this.props;
|
|
8
|
-
let stickyHeaderDates = !this.props.forPrint && getStickyHeaderDates(options);
|
|
9
|
-
let dayMeta = getDateMeta(dayDate, todayRange);
|
|
10
|
-
// will ever be falsy?
|
|
11
|
-
let text = options.listDayFormat ? dateEnv.format(dayDate, options.listDayFormat) : '';
|
|
12
|
-
// will ever be falsy? also, BAD NAME "alt"
|
|
13
|
-
let sideText = options.listDaySideFormat ? dateEnv.format(dayDate, options.listDaySideFormat) : '';
|
|
14
|
-
let isNavLink = options.navLinks;
|
|
15
|
-
let renderProps = Object.assign({ date: dateEnv.toDate(dayDate), view: viewApi, text,
|
|
16
|
-
sideText, navLinkAttrs: isNavLink
|
|
17
|
-
? buildNavLinkAttrs(this.context, dayDate, undefined, text)
|
|
18
|
-
: {}, sideNavLinkAttrs: isNavLink
|
|
19
|
-
// duplicate navLink, so does not need to be tabbable
|
|
20
|
-
? buildNavLinkAttrs(this.context, dayDate, undefined, sideText, /* isTabbable = */ false)
|
|
21
|
-
: {} }, dayMeta);
|
|
22
|
-
// TODO: make a reusable HOC for dayHeader (used in daygrid/timegrid too)
|
|
23
|
-
return (createElement("div", { className: joinClassNames('fc-list-day-outer', stickyHeaderDates && 'fc-list-day-outer-sticky') },
|
|
24
|
-
createElement(ContentContainer, { tag: "div", className: joinClassNames('fc-list-day', getDayClassName(dayMeta)), attrs: Object.assign({ 'data-date': formatDayString(dayDate) }, (dayMeta.isToday ? { 'aria-current': 'date' } : {})), renderProps: renderProps, generatorName: "dayHeaderContent", customGenerator: options.dayHeaderContent, defaultGenerator: renderInnerContent, classNameGenerator: options.dayHeaderClassNames, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount })));
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
function renderInnerContent(props) {
|
|
28
|
-
return (createElement(Fragment, null,
|
|
29
|
-
props.text && (createElement("div", Object.assign({ className: "fc-list-day-text" }, props.navLinkAttrs), props.text)),
|
|
30
|
-
props.sideText && (createElement("div", Object.assign({ className: "fc-list-day-side-text" }, props.sideNavLinkAttrs), props.sideText))));
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const DEFAULT_TIME_FORMAT = createFormatter({
|
|
34
|
-
hour: 'numeric',
|
|
35
|
-
minute: '2-digit',
|
|
36
|
-
meridiem: 'short',
|
|
37
|
-
});
|
|
38
|
-
class ListEvent extends BaseComponent {
|
|
39
|
-
constructor() {
|
|
40
|
-
super(...arguments);
|
|
41
|
-
this.handleTitleEl = (titleEl) => {
|
|
42
|
-
if (this.disconnectTitleWidth) {
|
|
43
|
-
this.disconnectTitleWidth();
|
|
44
|
-
}
|
|
45
|
-
if (titleEl) {
|
|
46
|
-
this.disconnectTitleWidth = watchWidth(titleEl, (titleWidth) => {
|
|
47
|
-
setRef(this.props.timeWidthRef, titleWidth);
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
render() {
|
|
53
|
-
let { props, context } = this;
|
|
54
|
-
let { eventRange } = props;
|
|
55
|
-
let { options } = context;
|
|
56
|
-
let timeFormat = options.eventTimeFormat || DEFAULT_TIME_FORMAT;
|
|
57
|
-
let [tag, attrs] = getEventTagAndAttrs(eventRange, context);
|
|
58
|
-
return (createElement(EventContainer, Object.assign({}, props, { tag: tag, attrs: Object.assign({ role: 'listitem' }, attrs), className: 'fc-list-event', defaultGenerator: renderEventTitleOnly, eventRange: eventRange, timeText: "", disableDragging: true, disableResizing: true }), (InnerContent, eventContentArg) => (createElement(Fragment, null,
|
|
59
|
-
createElement("div", { className: 'fc-list-event-time-outer', style: { width: props.timeOuterWidth } }, this.buildTimeContent(eventRange, props.slicedStart, props.slicedEnd, props.isStart, props.isEnd, timeFormat, context)),
|
|
60
|
-
createElement("div", { className: "fc-list-event-dot-outer" },
|
|
61
|
-
createElement("span", { className: "fc-list-event-dot", style: {
|
|
62
|
-
borderColor: eventContentArg.borderColor || eventContentArg.backgroundColor,
|
|
63
|
-
} })),
|
|
64
|
-
createElement(InnerContent, { tag: "div", className: 'fc-list-event-title' })))));
|
|
65
|
-
}
|
|
66
|
-
buildTimeContent(eventRange, // whole-day span
|
|
67
|
-
slicedStart, // view-sliced whole-day span
|
|
68
|
-
slicedEnd, // view-sliced whole-day span
|
|
69
|
-
isStart, isEnd, timeFormat, context) {
|
|
70
|
-
let { options } = context;
|
|
71
|
-
if (options.displayEventTime !== false) {
|
|
72
|
-
if (eventRange.def.allDay || (!isStart && !isEnd)) {
|
|
73
|
-
let renderProps = {
|
|
74
|
-
text: context.options.allDayText,
|
|
75
|
-
view: context.viewApi,
|
|
76
|
-
};
|
|
77
|
-
return (createElement(ContentContainer, { tag: "div", className: 'fc-list-event-time', renderProps: renderProps, elRef: this.handleTitleEl, generatorName: "allDayContent", customGenerator: options.allDayContent, defaultGenerator: renderAllDayInner, classNameGenerator: options.allDayClassNames, didMount: options.allDayDidMount, willUnmount: options.allDayWillUnmount }));
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
return (createElement("div", { className: "fc-list-event-time", ref: this.handleTitleEl }, buildEventRangeTimeText(timeFormat, eventRange, slicedStart, slicedEnd, isStart, isEnd, context)));
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return null;
|
|
84
|
-
}
|
|
85
|
-
componentWillUnmount() {
|
|
86
|
-
setRef(this.props.timeWidthRef, null);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
function renderEventTitleOnly(renderProps) {
|
|
90
|
-
return renderProps.event.title;
|
|
91
|
-
}
|
|
92
|
-
function renderAllDayInner(renderProps) {
|
|
93
|
-
return renderProps.text;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
class ListDay extends BaseComponent {
|
|
97
|
-
constructor() {
|
|
98
|
-
super(...arguments);
|
|
99
|
-
// memo
|
|
100
|
-
this.sortEventSegs = memoize(sortEventSegs);
|
|
101
|
-
// ref
|
|
102
|
-
this.timeWidthRefMap = new RefMap(() => {
|
|
103
|
-
afterSize(this.handleTimeWidths);
|
|
104
|
-
});
|
|
105
|
-
this.handleTimeWidths = () => {
|
|
106
|
-
const timeWidthMap = this.timeWidthRefMap.current;
|
|
107
|
-
let max = 0;
|
|
108
|
-
for (const timeWidth of timeWidthMap.values()) {
|
|
109
|
-
max = Math.max(max, timeWidth);
|
|
110
|
-
}
|
|
111
|
-
setRef(this.props.timeWidthRef, max);
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
render() {
|
|
115
|
-
const { props, context, timeWidthRefMap } = this;
|
|
116
|
-
const { nowDate, todayRange } = props;
|
|
117
|
-
const { options } = context;
|
|
118
|
-
const segs = this.sortEventSegs(props.segs, options.eventOrder);
|
|
119
|
-
const fullDateStr = buildDateStr(this.context, props.dayDate);
|
|
120
|
-
return (createElement("div", { role: 'listitem', "aria-label": fullDateStr, className: 'fc-list-day-and-events' },
|
|
121
|
-
createElement(ListDayHeader, { dayDate: props.dayDate, todayRange: todayRange, forPrint: props.forPrint }),
|
|
122
|
-
createElement("div", { role: 'list', "aria-label": options.eventsHint }, segs.map((seg) => {
|
|
123
|
-
const key = getEventKey(seg);
|
|
124
|
-
return (createElement(ListEvent, Object.assign({ key: key, eventRange: seg.eventRange, slicedStart: seg.slicedStart, slicedEnd: seg.slicedEnd, isStart: seg.isStart, isEnd: seg.isEnd, timeWidthRef: timeWidthRefMap.createRef(key), timeOuterWidth: props.timeOuterWidth, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: false }, getEventRangeMeta(seg.eventRange, todayRange, nowDate))));
|
|
125
|
-
}))));
|
|
126
|
-
}
|
|
127
|
-
componentWillUnmount() {
|
|
128
|
-
setRef(this.props.timeWidthRef, null);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/*
|
|
133
|
-
Responsible for the scroller, and forwarding event-related actions into the "grid".
|
|
134
|
-
*/
|
|
135
|
-
class ListView extends DateComponent {
|
|
136
|
-
constructor() {
|
|
137
|
-
super(...arguments);
|
|
138
|
-
// memo
|
|
139
|
-
this.computeDateVars = memoize(computeDateVars);
|
|
140
|
-
this.eventStoreToSegs = memoize(this._eventStoreToSegs);
|
|
141
|
-
// ref
|
|
142
|
-
this.timeWidthRefMap = new RefMap(() => {
|
|
143
|
-
afterSize(this.handleTimeWidths);
|
|
144
|
-
});
|
|
145
|
-
this.setRootEl = (rootEl) => {
|
|
146
|
-
if (rootEl) {
|
|
147
|
-
this.context.registerInteractiveComponent(this, {
|
|
148
|
-
el: rootEl,
|
|
149
|
-
disableHits: true, // HACK to not do date-clicking/selecting
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
this.context.unregisterInteractiveComponent(this);
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
this.handleTimeWidths = () => {
|
|
157
|
-
const timeWidthMap = this.timeWidthRefMap.current;
|
|
158
|
-
let max = 0;
|
|
159
|
-
for (const timeWidth of timeWidthMap.values()) {
|
|
160
|
-
max = Math.max(max, timeWidth);
|
|
161
|
-
}
|
|
162
|
-
this.setState({ timeOuterWidth: max });
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
render() {
|
|
166
|
-
let { props, context } = this;
|
|
167
|
-
let { options } = context;
|
|
168
|
-
let { dayDates, dayRanges } = this.computeDateVars(props.dateProfile);
|
|
169
|
-
let eventSegs = this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges);
|
|
170
|
-
let verticalScrolling = !props.forPrint && !getIsHeightAuto(options);
|
|
171
|
-
return (createElement(ViewContainer, { viewSpec: context.viewSpec, className: 'fc-list fc-flex-col fc-border', elRef: this.setRootEl },
|
|
172
|
-
createElement(Scroller // TODO: don't need heavyweight component
|
|
173
|
-
, { vertical: verticalScrolling, className: verticalScrolling ? 'fc-liquid' : '' },
|
|
174
|
-
this.renderSegList(eventSegs, dayDates),
|
|
175
|
-
!eventSegs.length && this.renderEmptyMessage())));
|
|
176
|
-
}
|
|
177
|
-
renderEmptyMessage() {
|
|
178
|
-
let { options, viewApi } = this.context;
|
|
179
|
-
let renderProps = {
|
|
180
|
-
text: options.noEventsText,
|
|
181
|
-
view: viewApi,
|
|
182
|
-
};
|
|
183
|
-
return (createElement(ContentContainer, { tag: "div", attrs: {
|
|
184
|
-
role: 'status', // does a polite announcement
|
|
185
|
-
}, className: 'fc-list-empty', renderProps: renderProps, generatorName: "noEventsContent", customGenerator: options.noEventsContent, defaultGenerator: renderNoEventsInner, classNameGenerator: options.noEventsClassNames, didMount: options.noEventsDidMount, willUnmount: options.noEventsWillUnmount }, (InnerContent) => (createElement(InnerContent, { tag: "div", className: 'fc-list-empty-inner' }))));
|
|
186
|
-
}
|
|
187
|
-
renderSegList(allSegs, dayDates) {
|
|
188
|
-
let segsByDay = groupSegsByDay(allSegs); // sparse array
|
|
189
|
-
return (createElement("div", { role: 'list', "aria-labelledby": this.props.labelId, "aria-label": this.props.labelStr },
|
|
190
|
-
createElement(NowTimer, { unit: "day" }, (nowDate, todayRange) => {
|
|
191
|
-
const dayNodes = [];
|
|
192
|
-
for (let dayIndex = 0; dayIndex < segsByDay.length; dayIndex += 1) {
|
|
193
|
-
let daySegs = segsByDay[dayIndex];
|
|
194
|
-
if (daySegs) { // sparse array, so might be undefined
|
|
195
|
-
const dayDate = dayDates[dayIndex];
|
|
196
|
-
const key = formatDayString(dayDate);
|
|
197
|
-
dayNodes.push(createElement(ListDay, { key: key, dayDate: dayDate, nowDate: nowDate, todayRange: todayRange, segs: daySegs, forPrint: this.props.forPrint, timeWidthRef: this.timeWidthRefMap.createRef(key), timeOuterWidth: this.state.timeOuterWidth }));
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
return (createElement(Fragment, null, dayNodes));
|
|
201
|
-
})));
|
|
202
|
-
}
|
|
203
|
-
_eventStoreToSegs(eventStore, eventUiBases, dayRanges) {
|
|
204
|
-
return this.eventRangesToSegs(sliceEventStore(eventStore, eventUiBases,
|
|
205
|
-
// HACKY to reference internal state...
|
|
206
|
-
this.props.dateProfile.activeRange, this.context.options.nextDayThreshold).fg, dayRanges);
|
|
207
|
-
}
|
|
208
|
-
eventRangesToSegs(fullDayEventRanges, dayRanges) {
|
|
209
|
-
let segs = [];
|
|
210
|
-
for (let fullDayEventRange of fullDayEventRanges) {
|
|
211
|
-
segs.push(...this.eventRangeToSegs(fullDayEventRange, dayRanges));
|
|
212
|
-
}
|
|
213
|
-
return segs;
|
|
214
|
-
}
|
|
215
|
-
eventRangeToSegs(fullDayEventRange, dayRanges) {
|
|
216
|
-
let fullDayRange = fullDayEventRange.range;
|
|
217
|
-
let dayIndex;
|
|
218
|
-
let segs = [];
|
|
219
|
-
for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex += 1) {
|
|
220
|
-
const slicedFullDayRange = intersectRanges(fullDayRange, dayRanges[dayIndex]);
|
|
221
|
-
if (slicedFullDayRange) {
|
|
222
|
-
segs.push({
|
|
223
|
-
eventRange: fullDayEventRange,
|
|
224
|
-
slicedStart: slicedFullDayRange.start,
|
|
225
|
-
slicedEnd: slicedFullDayRange.end,
|
|
226
|
-
isStart: fullDayEventRange.isStart && fullDayRange.start.valueOf() === slicedFullDayRange.start.valueOf(),
|
|
227
|
-
isEnd: fullDayEventRange.isEnd && fullDayRange.end.valueOf() === slicedFullDayRange.end.valueOf(),
|
|
228
|
-
dayIndex,
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
return segs;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
function renderNoEventsInner(renderProps) {
|
|
236
|
-
return renderProps.text;
|
|
237
|
-
}
|
|
238
|
-
function computeDateVars(dateProfile) {
|
|
239
|
-
let dayStart = startOfDay(dateProfile.renderRange.start);
|
|
240
|
-
let viewEnd = dateProfile.renderRange.end;
|
|
241
|
-
let dayDates = [];
|
|
242
|
-
let dayRanges = [];
|
|
243
|
-
while (dayStart < viewEnd) {
|
|
244
|
-
dayDates.push(dayStart);
|
|
245
|
-
dayRanges.push({
|
|
246
|
-
start: dayStart,
|
|
247
|
-
end: addDays(dayStart, 1),
|
|
248
|
-
});
|
|
249
|
-
dayStart = addDays(dayStart, 1);
|
|
250
|
-
}
|
|
251
|
-
return { dayDates, dayRanges };
|
|
252
|
-
}
|
|
253
|
-
// Returns a sparse array of arrays, segs grouped by their dayIndex
|
|
254
|
-
function groupSegsByDay(segs) {
|
|
255
|
-
let segsByDay = []; // sparse array
|
|
256
|
-
let i;
|
|
257
|
-
let seg;
|
|
258
|
-
for (i = 0; i < segs.length; i += 1) {
|
|
259
|
-
seg = segs[i];
|
|
260
|
-
(segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = []))
|
|
261
|
-
.push(seg);
|
|
262
|
-
}
|
|
263
|
-
return segsByDay;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
var css_248z = ":root{--fc-list-event-dot-width:10px;--fc-list-event-hover-bg-color:#f5f5f5}.fc-list-day,.fc-list-event-dot-outer,.fc-list-event-time,.fc-list-event-title{padding:8px 14px}.fc-direction-ltr .fc-list-event-dot-outer{padding-right:0}.fc-direction-rtl .fc-list-event-dot-outer{padding-left:0}.fc-list-empty{align-items:center;background-color:var(--fc-neutral-bg-color);display:flex;height:100%;justify-content:center}.fc-list-empty-inner{margin:5em 0}.fc-list-day,.fc-list-event:not(.fc-list-day-and-events:last-child .fc-list-event:last-child){border-bottom:1px solid var(--fc-border-color)}.fc-list-day-outer-sticky{background:var(--fc-page-bg-color);position:sticky;top:0}.fc-list-day{background:var(--fc-neutral-bg-color);display:flex;font-weight:700;justify-content:space-between}.fc-list-event{display:flex;flex-direction:row}a.fc-list-event{color:inherit;text-decoration:none}.fc-list-event:hover{background-color:var(--fc-list-event-hover-bg-color)}.fc-list-event-time-outer{display:flex;flex-direction:row}.fc-list-event-dot-outer,.fc-list-event-time{white-space:nowrap}.fc-list-event-dot{border:calc(var(--fc-list-event-dot-width)/2) solid var(--fc-event-border-color);border-radius:calc(var(--fc-list-event-dot-width)/2);box-sizing:content-box;display:inline-block;height:0;width:0}a.fc-list-event:hover .fc-list-event-title{text-decoration:underline}";
|
|
267
|
-
injectStyles(css_248z);
|
|
268
|
-
|
|
269
|
-
export { ListView };
|
|
File without changes
|