@fullcalendar/daygrid 7.0.0-beta.4 → 7.0.0-beta.5
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/{index.cjs → cjs/index.cjs} +15 -4
- package/cjs/internal.cjs +1339 -0
- package/esm/index.d.ts +23 -0
- package/{index.js → esm/index.js} +14 -3
- package/{internal.d.ts → esm/internal.d.ts} +49 -31
- package/{internal.js → esm/internal.js} +397 -272
- package/{index.global.js → global.js} +412 -273
- package/global.min.js +6 -0
- package/package.json +22 -19
- package/index.d.ts +0 -6
- package/index.global.min.js +0 -6
- package/internal.cjs +0 -1208
package/internal.cjs
DELETED
|
@@ -1,1208 +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 DayTableSlicer extends internal_cjs.Slicer {
|
|
9
|
-
constructor() {
|
|
10
|
-
super(...arguments);
|
|
11
|
-
this.forceDayIfListItem = true;
|
|
12
|
-
}
|
|
13
|
-
sliceRange(dateRange, dayTableModel) {
|
|
14
|
-
return dayTableModel.sliceRange(dateRange);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// TODO: converge types with DayTableCell and DayCellContainer (the component) and refineRenderProps
|
|
19
|
-
// the generation of DayTableCell will be distinct (for the BODY cells)
|
|
20
|
-
// but can share some of the same types/utils
|
|
21
|
-
// Date Cells
|
|
22
|
-
// -------------------------------------------------------------------------------------------------
|
|
23
|
-
const WEEKDAY_FORMAT = internal_cjs.createFormatter({ weekday: 'long' });
|
|
24
|
-
const firstSunday = new Date(259200000);
|
|
25
|
-
function buildDateRowConfigs(...args) {
|
|
26
|
-
return [buildDateRowConfig(...args)];
|
|
27
|
-
}
|
|
28
|
-
/*
|
|
29
|
-
Should this receive resource data attributes?
|
|
30
|
-
Or ResourceApi object itself?
|
|
31
|
-
*/
|
|
32
|
-
function buildDateRowConfig(dates, datesRepDistinctDays, dateProfile, todayRange, dayHeaderFormat, // TODO: rename to dateHeaderFormat?
|
|
33
|
-
context, colSpan) {
|
|
34
|
-
return {
|
|
35
|
-
renderConfig: buildDateRenderConfig(context),
|
|
36
|
-
dataConfigs: buildDateDataConfigs(dates, datesRepDistinctDays, dateProfile, todayRange, dayHeaderFormat, context, colSpan)
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
/*
|
|
40
|
-
For header cells: how to connect w/ custom rendering
|
|
41
|
-
Applies to all cells in a row
|
|
42
|
-
*/
|
|
43
|
-
function buildDateRenderConfig(context) {
|
|
44
|
-
const { options } = context;
|
|
45
|
-
return {
|
|
46
|
-
generatorName: 'dayHeaderContent',
|
|
47
|
-
customGenerator: options.dayHeaderContent,
|
|
48
|
-
classNameGenerator: options.dayHeaderClassNames,
|
|
49
|
-
didMount: options.dayHeaderDidMount,
|
|
50
|
-
willUnmount: options.dayHeaderWillUnmount,
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
/*
|
|
54
|
-
For header cells: data
|
|
55
|
-
*/
|
|
56
|
-
function buildDateDataConfigs(dates, datesRepDistinctDays, dateProfile, todayRange, dayHeaderFormat, // TODO: rename to dateHeaderFormat?
|
|
57
|
-
context, colSpan = 1, keyPrefix = '') {
|
|
58
|
-
const { dateEnv, viewApi, options } = context;
|
|
59
|
-
return datesRepDistinctDays
|
|
60
|
-
? dates.map((date) => {
|
|
61
|
-
const dateMeta = internal_cjs.getDateMeta(date, todayRange, null, dateProfile);
|
|
62
|
-
const text = dateEnv.format(date, dayHeaderFormat);
|
|
63
|
-
const renderProps = Object.assign(Object.assign({}, dateMeta), { date: dateEnv.toDate(date), view: viewApi, text });
|
|
64
|
-
const isNavLink = options.navLinks && !dateMeta.isDisabled;
|
|
65
|
-
const fullDateStr = internal_cjs.buildDateStr(context, date);
|
|
66
|
-
// for DayGridHeaderCell
|
|
67
|
-
return {
|
|
68
|
-
key: keyPrefix + date.toUTCString(),
|
|
69
|
-
renderProps,
|
|
70
|
-
attrs: Object.assign(Object.assign({ 'aria-label': fullDateStr }, (dateMeta.isToday ? { 'aria-current': 'date' } : {})), { 'data-date': internal_cjs.formatDayString(date) }),
|
|
71
|
-
// for navlink
|
|
72
|
-
innerAttrs: isNavLink
|
|
73
|
-
? internal_cjs.buildNavLinkAttrs(context, date, undefined, fullDateStr)
|
|
74
|
-
: { 'aria-hidden': true },
|
|
75
|
-
colSpan,
|
|
76
|
-
isNavLink,
|
|
77
|
-
className: internal_cjs.getDayClassName(dateMeta),
|
|
78
|
-
};
|
|
79
|
-
})
|
|
80
|
-
: dates.map((date) => {
|
|
81
|
-
const dow = date.getUTCDay();
|
|
82
|
-
const normDate = internal_cjs.addDays(firstSunday, dow);
|
|
83
|
-
const dayMeta = {
|
|
84
|
-
dow,
|
|
85
|
-
isDisabled: false,
|
|
86
|
-
isFuture: false,
|
|
87
|
-
isPast: false,
|
|
88
|
-
isToday: false,
|
|
89
|
-
isOther: false,
|
|
90
|
-
};
|
|
91
|
-
const text = dateEnv.format(normDate, dayHeaderFormat);
|
|
92
|
-
const renderProps = Object.assign(Object.assign({}, dayMeta), { date, view: viewApi, text });
|
|
93
|
-
const fullWeekDayStr = dateEnv.format(normDate, WEEKDAY_FORMAT);
|
|
94
|
-
// for DayGridHeaderCell
|
|
95
|
-
return {
|
|
96
|
-
key: keyPrefix + String(dow),
|
|
97
|
-
renderProps,
|
|
98
|
-
attrs: {
|
|
99
|
-
'aria-label': fullWeekDayStr,
|
|
100
|
-
},
|
|
101
|
-
// for navlink
|
|
102
|
-
innerAttrs: {
|
|
103
|
-
'aria-hidden': true, // label already on cell
|
|
104
|
-
},
|
|
105
|
-
colSpan,
|
|
106
|
-
className: internal_cjs.getDayClassName(dayMeta),
|
|
107
|
-
};
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/*
|
|
112
|
-
We need really specific keys because RefMap::createRef() which is then given to heightRef
|
|
113
|
-
unable to change key! As a result, we cannot reuse elements between normal/slice/standin types,
|
|
114
|
-
but that's okay since they render quite differently
|
|
115
|
-
*/
|
|
116
|
-
function getEventPartKey(seg) {
|
|
117
|
-
return internal_cjs.getEventKey(seg) + ':' + seg.start +
|
|
118
|
-
(seg.standinFor ? ':standin' : seg.isSlice ? ':slice' : '');
|
|
119
|
-
}
|
|
120
|
-
// DayGridRange utils (TODO: move)
|
|
121
|
-
// -------------------------------------------------------------------------------------------------
|
|
122
|
-
function splitSegsByRow(segs, rowCnt) {
|
|
123
|
-
const byRow = [];
|
|
124
|
-
for (let row = 0; row < rowCnt; row++) {
|
|
125
|
-
byRow[row] = [];
|
|
126
|
-
}
|
|
127
|
-
for (const seg of segs) {
|
|
128
|
-
byRow[seg.row].push(seg);
|
|
129
|
-
}
|
|
130
|
-
return byRow;
|
|
131
|
-
}
|
|
132
|
-
function splitInteractionByRow(ui, rowCnt) {
|
|
133
|
-
const byRow = [];
|
|
134
|
-
if (!ui) {
|
|
135
|
-
for (let row = 0; row < rowCnt; row++) {
|
|
136
|
-
byRow[row] = null;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
for (let row = 0; row < rowCnt; row++) {
|
|
141
|
-
byRow[row] = {
|
|
142
|
-
affectedInstances: ui.affectedInstances,
|
|
143
|
-
isEvent: ui.isEvent,
|
|
144
|
-
segs: [],
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
for (const seg of ui.segs) {
|
|
148
|
-
byRow[seg.row].segs.push(seg);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
return byRow;
|
|
152
|
-
}
|
|
153
|
-
function sliceSegForCol(seg, col) {
|
|
154
|
-
return Object.assign(Object.assign({}, seg), { start: col, end: col + 1, isStart: seg.isStart && seg.start === col, isEnd: seg.isEnd && seg.end - 1 === col, standinFor: seg });
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const DEFAULT_TABLE_EVENT_TIME_FORMAT = internal_cjs.createFormatter({
|
|
158
|
-
hour: 'numeric',
|
|
159
|
-
minute: '2-digit',
|
|
160
|
-
omitZeroMinute: true,
|
|
161
|
-
meridiem: 'narrow',
|
|
162
|
-
});
|
|
163
|
-
function hasListItemDisplay(seg) {
|
|
164
|
-
let { display } = seg.eventRange.ui;
|
|
165
|
-
return display === 'list-item' || (display === 'auto' &&
|
|
166
|
-
!seg.eventRange.def.allDay &&
|
|
167
|
-
(seg.end - seg.start) === 1 && // single-day
|
|
168
|
-
seg.isStart && // "
|
|
169
|
-
seg.isEnd // "
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
class DayGridBlockEvent extends internal_cjs.BaseComponent {
|
|
174
|
-
render() {
|
|
175
|
-
let { props } = this;
|
|
176
|
-
return (preact_cjs.createElement(internal_cjs.StandardEvent, Object.assign({}, props, { className: 'fc-daygrid-block-event fc-daygrid-event fc-h-event', defaultTimeFormat: DEFAULT_TABLE_EVENT_TIME_FORMAT, defaultDisplayEventEnd: props.defaultDisplayEventEnd, disableResizing: !props.eventRange.def.allDay })));
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
class DayGridListEvent extends internal_cjs.BaseComponent {
|
|
181
|
-
render() {
|
|
182
|
-
let { props, context } = this;
|
|
183
|
-
let { options } = context;
|
|
184
|
-
let { eventRange } = props;
|
|
185
|
-
let timeFormat = options.eventTimeFormat || DEFAULT_TABLE_EVENT_TIME_FORMAT;
|
|
186
|
-
let timeText = internal_cjs.buildEventRangeTimeText(timeFormat, eventRange,
|
|
187
|
-
/* slicedStart = */ undefined,
|
|
188
|
-
/* slicedEnd = */ undefined, props.isStart, props.isEnd, context,
|
|
189
|
-
/* defaultDisplayEventTime = */ true, props.defaultDisplayEventEnd);
|
|
190
|
-
let [tag, attrs] = internal_cjs.getEventTagAndAttrs(eventRange, context);
|
|
191
|
-
return (preact_cjs.createElement(internal_cjs.EventContainer, Object.assign({}, props, { tag: tag, attrs: attrs, className: 'fc-daygrid-dot-event fc-daygrid-event', defaultGenerator: renderInnerContent, timeText: timeText, isResizing: false, isDateSelecting: false })));
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
function renderInnerContent(renderProps) {
|
|
195
|
-
return (preact_cjs.createElement(preact_cjs.Fragment, null,
|
|
196
|
-
preact_cjs.createElement("div", { className: "fc-daygrid-event-dot", style: { borderColor: renderProps.borderColor || renderProps.backgroundColor } }),
|
|
197
|
-
renderProps.timeText && (preact_cjs.createElement("div", { className: "fc-event-time" }, renderProps.timeText)),
|
|
198
|
-
preact_cjs.createElement("div", { className: "fc-event-title" }, renderProps.event.title || preact_cjs.createElement(preact_cjs.Fragment, null, "\u00A0"))));
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
class DayGridMoreLink extends internal_cjs.BaseComponent {
|
|
202
|
-
render() {
|
|
203
|
-
let { props } = this;
|
|
204
|
-
return (preact_cjs.createElement(internal_cjs.MoreLinkContainer, { className: internal_cjs.joinClassNames('fc-daygrid-more-link', props.isBlock
|
|
205
|
-
? 'fc-daygrid-more-link-block'
|
|
206
|
-
: 'fc-daygrid-more-link-button'), dateProfile: props.dateProfile, todayRange: props.todayRange, allDayDate: props.allDayDate, segs: props.segs, hiddenSegs: props.hiddenSegs, alignElRef: props.alignElRef, alignParentTop: props.alignParentTop, dateSpanProps: props.dateSpanProps, popoverContent: () => {
|
|
207
|
-
let forcedInvisibleMap = // TODO: more convenient/DRY
|
|
208
|
-
(props.eventDrag ? props.eventDrag.affectedInstances : null) ||
|
|
209
|
-
(props.eventResize ? props.eventResize.affectedInstances : null) ||
|
|
210
|
-
{};
|
|
211
|
-
return (preact_cjs.createElement(preact_cjs.Fragment, null, props.segs.map((seg) => {
|
|
212
|
-
let { eventRange } = seg;
|
|
213
|
-
let { instanceId } = eventRange.instance;
|
|
214
|
-
return (preact_cjs.createElement("div", { key: instanceId, style: {
|
|
215
|
-
visibility: forcedInvisibleMap[instanceId] ? 'hidden' : '',
|
|
216
|
-
} }, hasListItemDisplay(seg) ? (preact_cjs.createElement(DayGridListEvent, Object.assign({ eventRange: eventRange, isStart: seg.isStart, isEnd: seg.isEnd, isDragging: false, isSelected: instanceId === props.eventSelection, defaultDisplayEventEnd: false }, internal_cjs.getEventRangeMeta(eventRange, props.todayRange)))) : (preact_cjs.createElement(DayGridBlockEvent, Object.assign({ eventRange: eventRange, isStart: seg.isStart, isEnd: seg.isEnd, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === props.eventSelection, defaultDisplayEventEnd: false }, internal_cjs.getEventRangeMeta(eventRange, props.todayRange))))));
|
|
217
|
-
})));
|
|
218
|
-
} }));
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
class DayGridCell extends internal_cjs.DateComponent {
|
|
223
|
-
constructor() {
|
|
224
|
-
super(...arguments);
|
|
225
|
-
// ref
|
|
226
|
-
this.rootElRef = preact_cjs.createRef();
|
|
227
|
-
this.handleBodyEl = (bodyEl) => {
|
|
228
|
-
if (this.disconnectBodyHeight) {
|
|
229
|
-
this.disconnectBodyHeight();
|
|
230
|
-
this.disconnectBodyHeight = undefined;
|
|
231
|
-
internal_cjs.setRef(this.props.headerHeightRef, null);
|
|
232
|
-
internal_cjs.setRef(this.props.mainHeightRef, null);
|
|
233
|
-
}
|
|
234
|
-
if (bodyEl) {
|
|
235
|
-
// we want to fire on ANY size change, because we do more advanced stuff
|
|
236
|
-
this.disconnectBodyHeight = internal_cjs.watchSize(bodyEl, (_bodyWidth, bodyHeight) => {
|
|
237
|
-
const { props } = this;
|
|
238
|
-
const mainRect = bodyEl.getBoundingClientRect();
|
|
239
|
-
const rootRect = this.rootElRef.current.getBoundingClientRect();
|
|
240
|
-
const headerHeight = mainRect.top - rootRect.top;
|
|
241
|
-
if (!internal_cjs.isDimsEqual(this.headerHeight, headerHeight)) {
|
|
242
|
-
this.headerHeight = headerHeight;
|
|
243
|
-
internal_cjs.setRef(props.headerHeightRef, headerHeight);
|
|
244
|
-
}
|
|
245
|
-
if (props.fgLiquidHeight) {
|
|
246
|
-
internal_cjs.setRef(props.mainHeightRef, bodyHeight);
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
render() {
|
|
253
|
-
let { props, context } = this;
|
|
254
|
-
let { options, dateEnv } = context;
|
|
255
|
-
// TODO: memoize this
|
|
256
|
-
const isMonthStart = props.showDayNumber &&
|
|
257
|
-
shouldDisplayMonthStart(props.date, props.dateProfile.currentRange, dateEnv);
|
|
258
|
-
// TODO: memoize this
|
|
259
|
-
const dateMeta = internal_cjs.getDateMeta(props.date, props.todayRange, null, props.dateProfile);
|
|
260
|
-
const baseClassName = internal_cjs.joinClassNames('fc-daygrid-day', props.borderStart && 'fc-border-s', props.width != null ? '' : 'fc-liquid', 'fc-flex-col');
|
|
261
|
-
if (dateMeta.isDisabled) {
|
|
262
|
-
return (preact_cjs.createElement("div", { role: 'gridcell', "aria-disabled": true, className: internal_cjs.joinClassNames(baseClassName, 'fc-day-disabled'), style: {
|
|
263
|
-
width: props.width
|
|
264
|
-
} }));
|
|
265
|
-
}
|
|
266
|
-
const hasDayNumber = props.showDayNumber || internal_cjs.hasCustomDayCellContent(options);
|
|
267
|
-
const isNavLink = options.navLinks;
|
|
268
|
-
const fullDateStr = internal_cjs.buildDateStr(context, props.date);
|
|
269
|
-
return (preact_cjs.createElement(internal_cjs.DayCellContainer, { tag: "div", className: internal_cjs.joinClassNames(baseClassName, props.className), attrs: Object.assign(Object.assign({}, props.attrs), { role: 'gridcell', 'aria-label': fullDateStr }), style: {
|
|
270
|
-
width: props.width
|
|
271
|
-
}, elRef: this.rootElRef, renderProps: props.renderProps, defaultGenerator: renderTopInner, date: props.date, dateMeta: dateMeta, showDayNumber: props.showDayNumber, isMonthStart: isMonthStart }, (InnerContent) => (preact_cjs.createElement(preact_cjs.Fragment, null,
|
|
272
|
-
hasDayNumber && (preact_cjs.createElement("div", { className: "fc-daygrid-day-header" },
|
|
273
|
-
preact_cjs.createElement(InnerContent, { tag: 'div', attrs: isNavLink
|
|
274
|
-
? internal_cjs.buildNavLinkAttrs(context, props.date, undefined, fullDateStr)
|
|
275
|
-
: { 'aria-hidden': true } // label already on cell
|
|
276
|
-
, className: internal_cjs.joinClassNames('fc-daygrid-day-number', isMonthStart && 'fc-daygrid-month-start') }))),
|
|
277
|
-
preact_cjs.createElement("div", { className: internal_cjs.joinClassNames('fc-daygrid-day-body', props.isTall && 'fc-daygrid-day-body-tall', props.fgLiquidHeight ? 'fc-liquid' : 'fc-grow'), ref: this.handleBodyEl },
|
|
278
|
-
preact_cjs.createElement("div", { className: 'fc-daygrid-day-events', style: { height: props.fgHeight } }, props.fg),
|
|
279
|
-
preact_cjs.createElement(DayGridMoreLink, { isBlock: props.isCompact, allDayDate: props.date, segs: props.segs, hiddenSegs: props.hiddenSegs, alignElRef: this.rootElRef, alignParentTop: props.showDayNumber ? '[role=row]' : '.fc-view', dateSpanProps: props.dateSpanProps, dateProfile: props.dateProfile, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, todayRange: props.todayRange }))))));
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
// Utils
|
|
283
|
-
// -------------------------------------------------------------------------------------------------
|
|
284
|
-
function renderTopInner(props) {
|
|
285
|
-
return props.dayNumberText || preact_cjs.createElement(preact_cjs.Fragment, null, "\u00A0");
|
|
286
|
-
}
|
|
287
|
-
function shouldDisplayMonthStart(date, currentRange, dateEnv) {
|
|
288
|
-
const { start: currentStart, end: currentEnd } = currentRange;
|
|
289
|
-
const currentEndIncl = internal_cjs.addMs(currentEnd, -1);
|
|
290
|
-
const currentFirstYear = dateEnv.getYear(currentStart);
|
|
291
|
-
const currentFirstMonth = dateEnv.getMonth(currentStart);
|
|
292
|
-
const currentLastYear = dateEnv.getYear(currentEndIncl);
|
|
293
|
-
const currentLastMonth = dateEnv.getMonth(currentEndIncl);
|
|
294
|
-
// spans more than one month?
|
|
295
|
-
return !(currentFirstYear === currentLastYear && currentFirstMonth === currentLastMonth) &&
|
|
296
|
-
Boolean(
|
|
297
|
-
// first date in current view?
|
|
298
|
-
date.valueOf() === currentStart.valueOf() ||
|
|
299
|
-
// a month-start that's within the current range?
|
|
300
|
-
(dateEnv.getDay(date) === 1 && date.valueOf() < currentEnd.valueOf()));
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
function computeFgSegVerticals(segs, segHeightMap, cells, maxHeight, strictOrder, allowSlicing = true, dayMaxEvents, dayMaxEventRows) {
|
|
304
|
-
let maxCoord;
|
|
305
|
-
let maxDepth;
|
|
306
|
-
let hiddenConsumes;
|
|
307
|
-
if (dayMaxEvents === true || dayMaxEventRows === true) {
|
|
308
|
-
maxCoord = maxHeight;
|
|
309
|
-
hiddenConsumes = true;
|
|
310
|
-
}
|
|
311
|
-
else if (typeof dayMaxEvents === 'number') {
|
|
312
|
-
maxDepth = dayMaxEvents;
|
|
313
|
-
hiddenConsumes = false;
|
|
314
|
-
}
|
|
315
|
-
else if (typeof dayMaxEventRows === 'number') {
|
|
316
|
-
maxDepth = dayMaxEventRows;
|
|
317
|
-
hiddenConsumes = true;
|
|
318
|
-
}
|
|
319
|
-
// NOTE: visibleSegsMap and hiddenSegMap map NEVER overlap for a given event
|
|
320
|
-
// once a seg has a height, the combined potentially-sliced segs will comprise the entire span of the seg
|
|
321
|
-
// if a seg does not have a height yet, it won't be inserted into either visibleSegsMap/hiddenSegMap
|
|
322
|
-
const visibleSegMap = new Map();
|
|
323
|
-
const hiddenSegMap = new Map();
|
|
324
|
-
const segTops = new Map();
|
|
325
|
-
const isSlicedMap = new Map();
|
|
326
|
-
let hierarchy = new internal_cjs.SegHierarchy(segs, (seg) => segHeightMap.get(getEventPartKey(seg)), strictOrder, maxCoord, maxDepth, hiddenConsumes, allowSlicing);
|
|
327
|
-
hierarchy.traverseSegs((seg, segTop) => {
|
|
328
|
-
addToSegMap(visibleSegMap, seg);
|
|
329
|
-
segTops.set(getEventPartKey(seg), segTop);
|
|
330
|
-
if (seg.isSlice) {
|
|
331
|
-
isSlicedMap.set(seg.eventRange, true);
|
|
332
|
-
}
|
|
333
|
-
});
|
|
334
|
-
for (const hiddenSeg of hierarchy.hiddenSegs) {
|
|
335
|
-
addToSegMap(hiddenSegMap, hiddenSeg); // hidden main segs
|
|
336
|
-
}
|
|
337
|
-
// recompute tops while considering slices
|
|
338
|
-
// portions of these slices might be added to hiddenSegMap
|
|
339
|
-
if (isSlicedMap.size) {
|
|
340
|
-
segTops.clear();
|
|
341
|
-
hierarchy = new internal_cjs.SegHierarchy(compileSegMap(segs, visibleSegMap), (seg) => segHeightMap.get(getEventPartKey(seg)), strictOrder, maxCoord, maxDepth, hiddenConsumes);
|
|
342
|
-
hierarchy.traverseSegs((seg, segTop) => {
|
|
343
|
-
segTops.set(getEventPartKey(seg), segTop); // newly-hidden main segs and slices
|
|
344
|
-
});
|
|
345
|
-
for (const hiddenSeg of hierarchy.hiddenSegs) {
|
|
346
|
-
addToSegMap(hiddenSegMap, hiddenSeg);
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
const segsByCol = [];
|
|
350
|
-
const hiddenSegsByCol = [];
|
|
351
|
-
const renderableSegsByCol = [];
|
|
352
|
-
const heightsByCol = [];
|
|
353
|
-
for (let col = 0; col < cells.length; col++) {
|
|
354
|
-
segsByCol.push([]);
|
|
355
|
-
hiddenSegsByCol.push([]);
|
|
356
|
-
renderableSegsByCol.push([]);
|
|
357
|
-
heightsByCol.push(0);
|
|
358
|
-
}
|
|
359
|
-
for (const seg of segs) {
|
|
360
|
-
const { eventRange } = seg;
|
|
361
|
-
const visibleSegs = visibleSegMap.get(eventRange) || [];
|
|
362
|
-
const hiddenSegs = hiddenSegMap.get(eventRange) || [];
|
|
363
|
-
const isSliced = isSlicedMap.get(eventRange) || false;
|
|
364
|
-
// add orig to renderable
|
|
365
|
-
renderableSegsByCol[seg.start].push(seg);
|
|
366
|
-
// add slices to renderable
|
|
367
|
-
if (isSliced) {
|
|
368
|
-
for (const visibleSeg of visibleSegs) {
|
|
369
|
-
renderableSegsByCol[visibleSeg.start].push(visibleSeg);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
// accumulate segsByCol/heightsByCol for visible segs
|
|
373
|
-
for (const visibleSeg of visibleSegs) {
|
|
374
|
-
for (let col = visibleSeg.start; col < visibleSeg.end; col++) {
|
|
375
|
-
const slice = sliceSegForCol(visibleSeg, col);
|
|
376
|
-
segsByCol[col].push(slice);
|
|
377
|
-
}
|
|
378
|
-
const segKey = getEventPartKey(visibleSeg);
|
|
379
|
-
const segTop = segTops.get(segKey);
|
|
380
|
-
if (segTop != null) { // positioned?
|
|
381
|
-
const segHeight = segHeightMap.get(segKey);
|
|
382
|
-
for (let col = visibleSeg.start; col < visibleSeg.end; col++) {
|
|
383
|
-
heightsByCol[col] = Math.max(heightsByCol[col], segTop + segHeight);
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
// accumulate segsByCol/hiddenSegsByCol for hidden segs
|
|
388
|
-
for (const hiddenSeg of hiddenSegs) {
|
|
389
|
-
for (let col = hiddenSeg.start; col < hiddenSeg.end; col++) {
|
|
390
|
-
const slice = sliceSegForCol(hiddenSeg, col);
|
|
391
|
-
segsByCol[col].push(slice);
|
|
392
|
-
hiddenSegsByCol[col].push(slice);
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
return [
|
|
397
|
-
segsByCol,
|
|
398
|
-
hiddenSegsByCol,
|
|
399
|
-
renderableSegsByCol,
|
|
400
|
-
segTops,
|
|
401
|
-
heightsByCol,
|
|
402
|
-
];
|
|
403
|
-
}
|
|
404
|
-
// Utils
|
|
405
|
-
// -------------------------------------------------------------------------------------------------
|
|
406
|
-
function addToSegMap(map, seg) {
|
|
407
|
-
let list = map.get(seg.eventRange);
|
|
408
|
-
if (!list) {
|
|
409
|
-
map.set(seg.eventRange, list = []);
|
|
410
|
-
}
|
|
411
|
-
list.push(seg);
|
|
412
|
-
}
|
|
413
|
-
/*
|
|
414
|
-
Ensures relative order of DayRowEventRange stays consistent with segs
|
|
415
|
-
*/
|
|
416
|
-
function compileSegMap(segs, segMap) {
|
|
417
|
-
const res = [];
|
|
418
|
-
for (const seg of segs) {
|
|
419
|
-
res.push(...(segMap.get(seg.eventRange) || []));
|
|
420
|
-
}
|
|
421
|
-
return res;
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
/*
|
|
425
|
-
TODO: move this so @fullcalendar/daygrid
|
|
426
|
-
*/
|
|
427
|
-
function buildDayTableModel(dateProfile, dateProfileGenerator) {
|
|
428
|
-
let daySeries = new internal_cjs.DaySeriesModel(dateProfile.renderRange, dateProfileGenerator);
|
|
429
|
-
return new internal_cjs.DayTableModel(daySeries, /year|month|week/.test(dateProfile.currentRangeUnit));
|
|
430
|
-
}
|
|
431
|
-
function computeColWidth(colCnt, colMinWidth, viewportWidth) {
|
|
432
|
-
if (viewportWidth == null) {
|
|
433
|
-
return [undefined, undefined];
|
|
434
|
-
}
|
|
435
|
-
const colTempWidth = viewportWidth / colCnt;
|
|
436
|
-
if (colTempWidth < colMinWidth) {
|
|
437
|
-
return [colMinWidth * colCnt, colMinWidth];
|
|
438
|
-
}
|
|
439
|
-
return [viewportWidth, undefined];
|
|
440
|
-
}
|
|
441
|
-
// Positioning
|
|
442
|
-
// -------------------------------------------------------------------------------------------------
|
|
443
|
-
function computeTopFromDate(date, cellRows, rowHeightMap, adjust = 0) {
|
|
444
|
-
let top = 0;
|
|
445
|
-
for (const cells of cellRows) {
|
|
446
|
-
const start = cells[0].date;
|
|
447
|
-
const end = cells[cells.length - 1].date;
|
|
448
|
-
const key = start.toISOString();
|
|
449
|
-
if (date >= start && date <= end) {
|
|
450
|
-
return top;
|
|
451
|
-
}
|
|
452
|
-
const rowHeight = rowHeightMap.get(key);
|
|
453
|
-
if (rowHeight == null) {
|
|
454
|
-
return; // denote unknown
|
|
455
|
-
}
|
|
456
|
-
top += rowHeight + adjust;
|
|
457
|
-
}
|
|
458
|
-
return top;
|
|
459
|
-
}
|
|
460
|
-
/*
|
|
461
|
-
FYI, `width` is not dependable for aligning completely to farside
|
|
462
|
-
*/
|
|
463
|
-
function computeHorizontalsFromSeg(seg, colWidth, colCnt, isRtl) {
|
|
464
|
-
let fromStart;
|
|
465
|
-
let fromEnd;
|
|
466
|
-
if (colWidth != null) {
|
|
467
|
-
fromStart = seg.start * colWidth;
|
|
468
|
-
fromEnd = (colCnt - seg.end) * colWidth;
|
|
469
|
-
}
|
|
470
|
-
else {
|
|
471
|
-
const colWidthFrac = 1 / colCnt;
|
|
472
|
-
fromStart = internal_cjs.fracToCssDim(seg.start * colWidthFrac);
|
|
473
|
-
fromEnd = internal_cjs.fracToCssDim(1 - seg.end * colWidthFrac);
|
|
474
|
-
}
|
|
475
|
-
if (isRtl) {
|
|
476
|
-
return { right: fromStart, left: fromEnd };
|
|
477
|
-
}
|
|
478
|
-
else {
|
|
479
|
-
return { left: fromStart, right: fromEnd };
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
function computeColFromPosition(positionLeft, elWidth, colWidth, colCnt, isRtl) {
|
|
483
|
-
const realColWidth = colWidth != null ? colWidth : elWidth / colCnt;
|
|
484
|
-
const colFromLeft = Math.floor(positionLeft / realColWidth);
|
|
485
|
-
const col = isRtl ? (colCnt - colFromLeft - 1) : colFromLeft;
|
|
486
|
-
const left = colFromLeft * realColWidth;
|
|
487
|
-
const right = left + realColWidth;
|
|
488
|
-
return { col, left, right };
|
|
489
|
-
}
|
|
490
|
-
function computeRowFromPosition(positionTop, cellRows, rowHeightMap) {
|
|
491
|
-
let row = 0;
|
|
492
|
-
let top = 0;
|
|
493
|
-
let bottom = 0;
|
|
494
|
-
for (const cells of cellRows) {
|
|
495
|
-
const key = cells[0].key;
|
|
496
|
-
top = bottom;
|
|
497
|
-
bottom = top + rowHeightMap.get(key);
|
|
498
|
-
if (positionTop < bottom) {
|
|
499
|
-
break;
|
|
500
|
-
}
|
|
501
|
-
row++;
|
|
502
|
-
}
|
|
503
|
-
return { row, top, bottom };
|
|
504
|
-
}
|
|
505
|
-
// Hit Element
|
|
506
|
-
// -------------------------------------------------------------------------------------------------
|
|
507
|
-
function getRowEl(rootEl, row) {
|
|
508
|
-
return rootEl.querySelectorAll(':scope > [role=row]')[row];
|
|
509
|
-
}
|
|
510
|
-
function getCellEl(rowEl, col) {
|
|
511
|
-
return rowEl.querySelectorAll(':scope > [role=gridcell]')[col];
|
|
512
|
-
}
|
|
513
|
-
// Header Formatting
|
|
514
|
-
// -------------------------------------------------------------------------------------------------
|
|
515
|
-
function createDayHeaderFormatter(explicitFormat, datesRepDistinctDays, dateCnt) {
|
|
516
|
-
return explicitFormat || computeFallbackHeaderFormat(datesRepDistinctDays, dateCnt);
|
|
517
|
-
}
|
|
518
|
-
// Computes a default column header formatting string if `colFormat` is not explicitly defined
|
|
519
|
-
function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) {
|
|
520
|
-
// if more than one week row, or if there are a lot of columns with not much space,
|
|
521
|
-
// put just the day numbers will be in each cell
|
|
522
|
-
if (!datesRepDistinctDays || dayCnt > 10) {
|
|
523
|
-
return internal_cjs.createFormatter({ weekday: 'short' }); // "Sat"
|
|
524
|
-
}
|
|
525
|
-
if (dayCnt > 1) {
|
|
526
|
-
return internal_cjs.createFormatter({ weekday: 'short', month: 'numeric', day: 'numeric', omitCommas: true }); // "Sat 11/12"
|
|
527
|
-
}
|
|
528
|
-
return internal_cjs.createFormatter({ weekday: 'long' }); // "Saturday"
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
class DayGridEventHarness extends preact_cjs.Component {
|
|
532
|
-
constructor() {
|
|
533
|
-
super(...arguments);
|
|
534
|
-
// ref
|
|
535
|
-
this.rootElRef = preact_cjs.createRef();
|
|
536
|
-
}
|
|
537
|
-
render() {
|
|
538
|
-
const { props } = this;
|
|
539
|
-
return (preact_cjs.createElement("div", { className: internal_cjs.joinClassNames(props.className, 'fc-abs'), style: props.style, ref: this.rootElRef }, props.children));
|
|
540
|
-
}
|
|
541
|
-
componentDidMount() {
|
|
542
|
-
const rootEl = this.rootElRef.current; // TODO: make dynamic with useEffect
|
|
543
|
-
this.disconnectHeight = internal_cjs.watchHeight(rootEl, (height) => {
|
|
544
|
-
internal_cjs.setRef(this.props.heightRef, height);
|
|
545
|
-
});
|
|
546
|
-
}
|
|
547
|
-
componentWillUnmount() {
|
|
548
|
-
this.disconnectHeight();
|
|
549
|
-
internal_cjs.setRef(this.props.heightRef, null);
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
const DEFAULT_WEEK_NUM_FORMAT = internal_cjs.createFormatter({ week: 'narrow' });
|
|
554
|
-
class DayGridRow extends internal_cjs.BaseComponent {
|
|
555
|
-
constructor() {
|
|
556
|
-
super(...arguments);
|
|
557
|
-
this.headerHeightRefMap = new internal_cjs.RefMap(() => {
|
|
558
|
-
internal_cjs.afterSize(this.handleSegPositioning);
|
|
559
|
-
});
|
|
560
|
-
this.mainHeightRefMap = new internal_cjs.RefMap(() => {
|
|
561
|
-
const fgLiquidHeight = this.props.dayMaxEvents === true || this.props.dayMaxEventRows === true;
|
|
562
|
-
if (fgLiquidHeight) {
|
|
563
|
-
internal_cjs.afterSize(this.handleSegPositioning);
|
|
564
|
-
}
|
|
565
|
-
});
|
|
566
|
-
this.segHeightRefMap = new internal_cjs.RefMap(() => {
|
|
567
|
-
internal_cjs.afterSize(this.handleSegPositioning);
|
|
568
|
-
});
|
|
569
|
-
this.handleRootEl = (rootEl) => {
|
|
570
|
-
this.rootEl = rootEl;
|
|
571
|
-
internal_cjs.setRef(this.props.rootElRef, rootEl);
|
|
572
|
-
};
|
|
573
|
-
this.handleSegPositioning = () => {
|
|
574
|
-
this.forceUpdate();
|
|
575
|
-
};
|
|
576
|
-
}
|
|
577
|
-
render() {
|
|
578
|
-
const { props, context, headerHeightRefMap, mainHeightRefMap } = this;
|
|
579
|
-
const { cells } = props;
|
|
580
|
-
const { options } = context;
|
|
581
|
-
const weekDate = props.cells[0].date;
|
|
582
|
-
const fgLiquidHeight = props.dayMaxEvents === true || props.dayMaxEventRows === true;
|
|
583
|
-
// TODO: memoize? sort all types of segs?
|
|
584
|
-
const fgEventSegs = internal_cjs.sortEventSegs(props.fgEventSegs, options.eventOrder);
|
|
585
|
-
// TODO: memoize?
|
|
586
|
-
const [maxMainTop, minMainHeight] = this.computeFgDims(); // uses headerHeightRefMap/mainHeightRefMap
|
|
587
|
-
const [segsByCol, hiddenSegsByCol, renderableSegsByCol, segTops, simpleHeightsByCol] = computeFgSegVerticals(fgEventSegs, this.segHeightRefMap.current, cells, fgLiquidHeight ? minMainHeight : undefined, // if not defined in first run, will unlimited!?
|
|
588
|
-
options.eventOrderStrict, options.eventSlicing, props.dayMaxEvents, props.dayMaxEventRows);
|
|
589
|
-
const heightsByCol = [];
|
|
590
|
-
if (maxMainTop != null) {
|
|
591
|
-
let col = 0;
|
|
592
|
-
for (const cell of cells) { // uses headerHeightRefMap/maxMainTop/simpleHeightsByCol
|
|
593
|
-
const cellHeaderHeight = headerHeightRefMap.current.get(cell.key);
|
|
594
|
-
const extraFgHeight = maxMainTop - cellHeaderHeight;
|
|
595
|
-
heightsByCol.push(simpleHeightsByCol[col++] + extraFgHeight);
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
const highlightSegs = this.getHighlightSegs();
|
|
599
|
-
const mirrorSegs = this.getMirrorSegs();
|
|
600
|
-
const forcedInvisibleMap = // TODO: more convenient/DRY
|
|
601
|
-
(props.eventDrag && props.eventDrag.affectedInstances) ||
|
|
602
|
-
(props.eventResize && props.eventResize.affectedInstances) ||
|
|
603
|
-
{};
|
|
604
|
-
const isNavLink = options.navLinks;
|
|
605
|
-
const fullWeekStr = internal_cjs.buildDateStr(context, weekDate, 'week');
|
|
606
|
-
return (preact_cjs.createElement("div", { role: props.role /* !!! */, "aria-label": props.role === 'row' // HACK
|
|
607
|
-
? fullWeekStr
|
|
608
|
-
: undefined // can't have label on non-role div
|
|
609
|
-
, className: internal_cjs.joinClassNames('fc-flex-row fc-rel', props.className), style: {
|
|
610
|
-
minHeight: props.minHeight,
|
|
611
|
-
}, ref: this.handleRootEl },
|
|
612
|
-
this.renderFillSegs(props.businessHourSegs, 'non-business'),
|
|
613
|
-
this.renderFillSegs(props.bgEventSegs, 'bg-event'),
|
|
614
|
-
this.renderFillSegs(highlightSegs, 'highlight'),
|
|
615
|
-
preact_cjs.createElement("div", { className: 'fc-flex-row fc-liquid fc-rel' }, props.cells.map((cell, col) => {
|
|
616
|
-
const normalFgNodes = this.renderFgSegs(maxMainTop, renderableSegsByCol[col], segTops, props.todayRange, forcedInvisibleMap);
|
|
617
|
-
return (preact_cjs.createElement(DayGridCell, { key: cell.key, dateProfile: props.dateProfile, todayRange: props.todayRange, date: cell.date, showDayNumber: props.showDayNumbers, isCompact: props.isCompact, isTall: props.isTall, borderStart: Boolean(col),
|
|
618
|
-
// content
|
|
619
|
-
segs: segsByCol[col], hiddenSegs: hiddenSegsByCol[col], fgLiquidHeight: fgLiquidHeight, fg: (preact_cjs.createElement(preact_cjs.Fragment, null, normalFgNodes)), eventDrag: props.eventDrag, eventResize: props.eventResize, eventSelection: props.eventSelection,
|
|
620
|
-
// render hooks
|
|
621
|
-
renderProps: cell.renderProps, dateSpanProps: cell.dateSpanProps, attrs: cell.attrs, className: cell.className,
|
|
622
|
-
// dimensions
|
|
623
|
-
fgHeight: heightsByCol[col], width: props.colWidth,
|
|
624
|
-
// refs
|
|
625
|
-
headerHeightRef: headerHeightRefMap.createRef(cell.key), mainHeightRef: mainHeightRefMap.createRef(cell.key) }));
|
|
626
|
-
})),
|
|
627
|
-
props.showWeekNumbers && (preact_cjs.createElement(internal_cjs.WeekNumberContainer, { tag: 'div', attrs: Object.assign(Object.assign({}, (isNavLink
|
|
628
|
-
? internal_cjs.buildNavLinkAttrs(context, weekDate, 'week', fullWeekStr, /* isTabbable = */ false)
|
|
629
|
-
: {})), { 'role': undefined, 'aria-hidden': true }), className: 'fc-daygrid-week-number', date: weekDate, defaultFormat: DEFAULT_WEEK_NUM_FORMAT })),
|
|
630
|
-
this.renderFgSegs(maxMainTop, mirrorSegs, segTops, props.todayRange, {}, // forcedInvisibleMap
|
|
631
|
-
Boolean(props.eventDrag), Boolean(props.eventResize), false)));
|
|
632
|
-
}
|
|
633
|
-
renderFgSegs(headerHeight, segs, segTops, todayRange, forcedInvisibleMap, isDragging, isResizing, isDateSelecting) {
|
|
634
|
-
var _a;
|
|
635
|
-
const { props, context, segHeightRefMap } = this;
|
|
636
|
-
const { isRtl } = context;
|
|
637
|
-
const { colWidth, eventSelection } = props;
|
|
638
|
-
const colCnt = props.cells.length;
|
|
639
|
-
const defaultDisplayEventEnd = props.cells.length === 1;
|
|
640
|
-
const isMirror = isDragging || isResizing || isDateSelecting;
|
|
641
|
-
const nodes = [];
|
|
642
|
-
for (const seg of segs) {
|
|
643
|
-
const key = getEventPartKey(seg);
|
|
644
|
-
const { standinFor, eventRange } = seg;
|
|
645
|
-
const { instanceId } = eventRange.instance;
|
|
646
|
-
if (standinFor) {
|
|
647
|
-
continue;
|
|
648
|
-
}
|
|
649
|
-
const { left, right } = computeHorizontalsFromSeg(seg, colWidth, colCnt, isRtl);
|
|
650
|
-
const localTop = (_a = segTops.get(standinFor ? getEventPartKey(standinFor) : key)) !== null && _a !== void 0 ? _a : (isMirror ? 0 : undefined);
|
|
651
|
-
const top = headerHeight != null && localTop != null
|
|
652
|
-
? headerHeight + localTop
|
|
653
|
-
: undefined;
|
|
654
|
-
const isInvisible = standinFor || forcedInvisibleMap[instanceId] || top == null;
|
|
655
|
-
nodes.push(preact_cjs.createElement(DayGridEventHarness, { key: key, className: seg.start ? 'fc-border-transparent fc-border-s' : '', style: {
|
|
656
|
-
visibility: isInvisible ? 'hidden' : '',
|
|
657
|
-
top,
|
|
658
|
-
left,
|
|
659
|
-
right,
|
|
660
|
-
}, heightRef: (!standinFor && !isMirror)
|
|
661
|
-
? segHeightRefMap.createRef(key)
|
|
662
|
-
: null }, hasListItemDisplay(seg) ? (preact_cjs.createElement(DayGridListEvent, Object.assign({ eventRange: eventRange, isStart: seg.isStart, isEnd: seg.isEnd, isDragging: isDragging, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, internal_cjs.getEventRangeMeta(eventRange, todayRange)))) : (preact_cjs.createElement(DayGridBlockEvent, Object.assign({ eventRange: eventRange, isStart: seg.isStart, isEnd: seg.isEnd, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, internal_cjs.getEventRangeMeta(eventRange, todayRange))))));
|
|
663
|
-
}
|
|
664
|
-
return nodes;
|
|
665
|
-
}
|
|
666
|
-
renderFillSegs(segs, fillType) {
|
|
667
|
-
const { props, context } = this;
|
|
668
|
-
const { isRtl } = context;
|
|
669
|
-
const { todayRange, colWidth } = props;
|
|
670
|
-
const colCnt = props.cells.length;
|
|
671
|
-
const nodes = [];
|
|
672
|
-
for (const seg of segs) {
|
|
673
|
-
const key = internal_cjs.buildEventRangeKey(seg.eventRange); // TODO: use different type of key than fg!?
|
|
674
|
-
const { left, right } = computeHorizontalsFromSeg(seg, colWidth, colCnt, isRtl);
|
|
675
|
-
const isVisible = !seg.standinFor;
|
|
676
|
-
nodes.push(preact_cjs.createElement("div", { key: key, className: "fc-fill-y", style: {
|
|
677
|
-
visibility: isVisible ? '' : 'hidden',
|
|
678
|
-
left,
|
|
679
|
-
right,
|
|
680
|
-
} }, fillType === 'bg-event' ?
|
|
681
|
-
preact_cjs.createElement(internal_cjs.BgEvent, Object.assign({ eventRange: seg.eventRange, isStart: seg.isStart, isEnd: seg.isEnd }, internal_cjs.getEventRangeMeta(seg.eventRange, todayRange))) : (internal_cjs.renderFill(fillType))));
|
|
682
|
-
}
|
|
683
|
-
return preact_cjs.createElement(preact_cjs.Fragment, {}, ...nodes); // TODO: shouldn't this be an array, so keyed?
|
|
684
|
-
}
|
|
685
|
-
// Sizing
|
|
686
|
-
// -----------------------------------------------------------------------------------------------
|
|
687
|
-
componentDidMount() {
|
|
688
|
-
const { rootEl } = this; // TODO: make dynamic with useEffect
|
|
689
|
-
this.disconnectHeight = internal_cjs.watchHeight(rootEl, (contentHeight) => {
|
|
690
|
-
internal_cjs.setRef(this.props.heightRef, contentHeight);
|
|
691
|
-
});
|
|
692
|
-
}
|
|
693
|
-
componentWillUnmount() {
|
|
694
|
-
this.disconnectHeight();
|
|
695
|
-
internal_cjs.setRef(this.props.heightRef, null);
|
|
696
|
-
}
|
|
697
|
-
computeFgDims() {
|
|
698
|
-
const { cells } = this.props;
|
|
699
|
-
const headerHeightMap = this.headerHeightRefMap.current;
|
|
700
|
-
const mainHeightMap = this.mainHeightRefMap.current;
|
|
701
|
-
let maxMainTop;
|
|
702
|
-
let minMainBottom;
|
|
703
|
-
for (const cell of cells) {
|
|
704
|
-
const mainTop = headerHeightMap.get(cell.key);
|
|
705
|
-
const mainHeight = mainHeightMap.get(cell.key);
|
|
706
|
-
if (mainTop != null) {
|
|
707
|
-
if (maxMainTop === undefined || mainTop > maxMainTop) {
|
|
708
|
-
maxMainTop = mainTop;
|
|
709
|
-
}
|
|
710
|
-
if (mainHeight != null) {
|
|
711
|
-
const mainBottom = mainTop + mainHeight;
|
|
712
|
-
if (minMainBottom === undefined || mainBottom < minMainBottom) {
|
|
713
|
-
minMainBottom = mainBottom;
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
return [
|
|
719
|
-
maxMainTop,
|
|
720
|
-
minMainBottom != null && maxMainTop != null
|
|
721
|
-
? minMainBottom - maxMainTop
|
|
722
|
-
: undefined,
|
|
723
|
-
];
|
|
724
|
-
}
|
|
725
|
-
// Internal Utils
|
|
726
|
-
// -----------------------------------------------------------------------------------------------
|
|
727
|
-
getMirrorSegs() {
|
|
728
|
-
let { props } = this;
|
|
729
|
-
if (props.eventResize && props.eventResize.segs.length) { // messy check
|
|
730
|
-
return props.eventResize.segs;
|
|
731
|
-
}
|
|
732
|
-
return [];
|
|
733
|
-
}
|
|
734
|
-
getHighlightSegs() {
|
|
735
|
-
let { props } = this;
|
|
736
|
-
if (props.eventDrag && props.eventDrag.segs.length) { // messy check
|
|
737
|
-
return props.eventDrag.segs;
|
|
738
|
-
}
|
|
739
|
-
if (props.eventResize && props.eventResize.segs.length) { // messy check
|
|
740
|
-
return props.eventResize.segs;
|
|
741
|
-
}
|
|
742
|
-
return props.dateSelectionSegs;
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
class DayGridRows extends internal_cjs.DateComponent {
|
|
747
|
-
constructor() {
|
|
748
|
-
super(...arguments);
|
|
749
|
-
// memo
|
|
750
|
-
this.splitBusinessHourSegs = internal_cjs.memoize(splitSegsByRow);
|
|
751
|
-
this.splitBgEventSegs = internal_cjs.memoize(splitSegsByRow);
|
|
752
|
-
this.splitFgEventSegs = internal_cjs.memoize(splitSegsByRow);
|
|
753
|
-
this.splitDateSelectionSegs = internal_cjs.memoize(splitSegsByRow);
|
|
754
|
-
this.splitEventDrag = internal_cjs.memoize(splitInteractionByRow);
|
|
755
|
-
this.splitEventResize = internal_cjs.memoize(splitInteractionByRow);
|
|
756
|
-
// internal
|
|
757
|
-
this.rowHeightRefMap = new internal_cjs.RefMap((height, key) => {
|
|
758
|
-
// HACKy way of syncing RefMap results with prop
|
|
759
|
-
const { rowHeightRefMap } = this.props;
|
|
760
|
-
if (rowHeightRefMap) {
|
|
761
|
-
rowHeightRefMap.handleValue(height, key);
|
|
762
|
-
}
|
|
763
|
-
});
|
|
764
|
-
this.handleRootEl = (rootEl) => {
|
|
765
|
-
this.rootEl = rootEl;
|
|
766
|
-
if (rootEl) {
|
|
767
|
-
this.context.registerInteractiveComponent(this, {
|
|
768
|
-
el: rootEl,
|
|
769
|
-
isHitComboAllowed: this.props.isHitComboAllowed,
|
|
770
|
-
});
|
|
771
|
-
}
|
|
772
|
-
else {
|
|
773
|
-
this.context.unregisterInteractiveComponent(this);
|
|
774
|
-
}
|
|
775
|
-
};
|
|
776
|
-
}
|
|
777
|
-
render() {
|
|
778
|
-
let { props, context, rowHeightRefMap } = this;
|
|
779
|
-
let { options } = context;
|
|
780
|
-
let rowCnt = props.cellRows.length;
|
|
781
|
-
let fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, rowCnt);
|
|
782
|
-
let bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, rowCnt);
|
|
783
|
-
let businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, rowCnt);
|
|
784
|
-
let dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, rowCnt);
|
|
785
|
-
let eventDragByRow = this.splitEventDrag(props.eventDrag, rowCnt);
|
|
786
|
-
let eventResizeByRow = this.splitEventResize(props.eventResize, rowCnt);
|
|
787
|
-
let isHeightAuto = internal_cjs.getIsHeightAuto(options);
|
|
788
|
-
let rowHeightsRedistribute = !props.forPrint && !isHeightAuto;
|
|
789
|
-
let [rowMinHeight, isCompact] = computeRowHeight(props.visibleWidth, rowCnt, isHeightAuto, props.forPrint, options);
|
|
790
|
-
return (preact_cjs.createElement("div", { role: 'rowgroup', className: internal_cjs.joinClassNames(
|
|
791
|
-
// HACK for Safari. Can't do break-inside:avoid with flexbox items, likely b/c it's not standard:
|
|
792
|
-
// https://stackoverflow.com/a/60256345
|
|
793
|
-
!props.forPrint && 'fc-flex-col', props.className), style: { width: props.width }, ref: this.handleRootEl }, props.cellRows.map((cells, row) => (preact_cjs.createElement(DayGridRow, { key: cells[0].key, role: 'row', dateProfile: props.dateProfile, todayRange: props.todayRange, cells: cells, showDayNumbers: rowCnt > 1, showWeekNumbers: rowCnt > 1 && options.weekNumbers, forPrint: props.forPrint, isCompact: isCompact,
|
|
794
|
-
// if not auto-height, distribute height of container somewhat evently to rows
|
|
795
|
-
// (treat all as zero, distribute height, then ensure min-heights -- the inner content height)
|
|
796
|
-
className: internal_cjs.joinClassNames(rowHeightsRedistribute && 'fc-grow fc-basis0', rowCnt > 1 && 'fc-break-inside-avoid', // don't avoid breaks for single tall row
|
|
797
|
-
row < rowCnt - 1 && 'fc-border-b'),
|
|
798
|
-
// content
|
|
799
|
-
fgEventSegs: fgEventSegsByRow[row], bgEventSegs: bgEventSegsByRow[row].filter(isSegAllDay) /* HACK */, businessHourSegs: businessHourSegsByRow[row], dateSelectionSegs: dateSelectionSegsByRow[row], eventSelection: props.eventSelection, eventDrag: eventDragByRow[row], eventResize: eventResizeByRow[row], dayMaxEvents: props.dayMaxEvents, dayMaxEventRows: props.dayMaxEventRows,
|
|
800
|
-
// dimensions
|
|
801
|
-
colWidth: props.colWidth, minHeight: rowMinHeight,
|
|
802
|
-
// refs
|
|
803
|
-
heightRef: rowHeightRefMap.createRef(cells[0].key) })))));
|
|
804
|
-
}
|
|
805
|
-
componentDidMount() {
|
|
806
|
-
this.disconnectWidth = internal_cjs.watchWidth(this.rootEl, (width) => {
|
|
807
|
-
this.setState({ width });
|
|
808
|
-
});
|
|
809
|
-
}
|
|
810
|
-
componentWillUnmount() {
|
|
811
|
-
this.disconnectWidth();
|
|
812
|
-
}
|
|
813
|
-
// Hit System
|
|
814
|
-
// -----------------------------------------------------------------------------------------------
|
|
815
|
-
queryHit(positionLeft, positionTop, elWidth) {
|
|
816
|
-
const { props, context } = this;
|
|
817
|
-
const colCnt = props.cellRows[0].length;
|
|
818
|
-
const { col, left, right } = computeColFromPosition(positionLeft, elWidth, props.colWidth, colCnt, context.isRtl);
|
|
819
|
-
const { row, top, bottom } = computeRowFromPosition(positionTop, props.cellRows, this.rowHeightRefMap.current);
|
|
820
|
-
const cell = props.cellRows[row][col];
|
|
821
|
-
const cellStartDate = cell.date;
|
|
822
|
-
const cellEndDate = internal_cjs.addDays(cellStartDate, 1);
|
|
823
|
-
return {
|
|
824
|
-
dateProfile: props.dateProfile,
|
|
825
|
-
dateSpan: Object.assign({ range: {
|
|
826
|
-
start: cellStartDate,
|
|
827
|
-
end: cellEndDate,
|
|
828
|
-
}, allDay: true }, cell.dateSpanProps),
|
|
829
|
-
// HACK. TODO: This is expensive to do every hit-query
|
|
830
|
-
dayEl: getCellEl(getRowEl(this.rootEl, row), col),
|
|
831
|
-
rect: {
|
|
832
|
-
left,
|
|
833
|
-
right,
|
|
834
|
-
top,
|
|
835
|
-
bottom,
|
|
836
|
-
},
|
|
837
|
-
layer: 0,
|
|
838
|
-
};
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
// Utils
|
|
842
|
-
// -------------------------------------------------------------------------------------------------
|
|
843
|
-
function isSegAllDay(seg) {
|
|
844
|
-
return seg.eventRange.def.allDay;
|
|
845
|
-
}
|
|
846
|
-
function computeRowHeight(visibleWidth, // should INCLUDE any scrollbar width to avoid oscillation
|
|
847
|
-
rowCnt, isHeightAuto, forPrint, options) {
|
|
848
|
-
if (visibleWidth != null) {
|
|
849
|
-
// ensure a consistent row min-height modelled after a month with 6 rows respecting aspectRatio
|
|
850
|
-
// will result in same minHeight regardless of weekends, dayMinWidth, height:auto
|
|
851
|
-
const rowMinHeight = visibleWidth / options.aspectRatio / 6;
|
|
852
|
-
return [
|
|
853
|
-
forPrint
|
|
854
|
-
// special-case for print, which condenses whole-page width without notifying
|
|
855
|
-
// this is value that looks natural on paper for portrait/landscape
|
|
856
|
-
? '6em'
|
|
857
|
-
// don't give minHeight when single-month non-auto-height
|
|
858
|
-
// TODO: better way to detect this with DateProfile?
|
|
859
|
-
: (rowCnt > 6 || isHeightAuto)
|
|
860
|
-
? rowMinHeight
|
|
861
|
-
: undefined,
|
|
862
|
-
// isCompact?: just before most lone +more links hit bottom of cell
|
|
863
|
-
rowMinHeight < 70,
|
|
864
|
-
];
|
|
865
|
-
}
|
|
866
|
-
return [undefined, false];
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
class DayGridHeaderCell extends internal_cjs.BaseComponent {
|
|
870
|
-
constructor() {
|
|
871
|
-
super(...arguments);
|
|
872
|
-
this.handleInnerEl = (innerEl) => {
|
|
873
|
-
if (this.disconectInnerHeight) {
|
|
874
|
-
this.disconectInnerHeight();
|
|
875
|
-
this.disconectInnerHeight = undefined;
|
|
876
|
-
}
|
|
877
|
-
if (innerEl) {
|
|
878
|
-
this.disconectInnerHeight = internal_cjs.watchHeight(innerEl, (height) => {
|
|
879
|
-
internal_cjs.setRef(this.props.innerHeightRef, height);
|
|
880
|
-
});
|
|
881
|
-
}
|
|
882
|
-
else {
|
|
883
|
-
internal_cjs.setRef(this.props.innerHeightRef, null);
|
|
884
|
-
}
|
|
885
|
-
};
|
|
886
|
-
}
|
|
887
|
-
render() {
|
|
888
|
-
const { props } = this;
|
|
889
|
-
const { renderConfig, dataConfig } = props;
|
|
890
|
-
// HACK
|
|
891
|
-
const isDisabled = dataConfig.renderProps.isDisabled;
|
|
892
|
-
return (preact_cjs.createElement(internal_cjs.ContentContainer, { tag: 'div', attrs: Object.assign({ role: 'columnheader', 'aria-colspan': dataConfig.colSpan }, dataConfig.attrs), className: internal_cjs.joinClassNames('fc-header-cell fc-cell fc-flex-col fc-align-center', props.borderStart && 'fc-border-s', !props.isSticky && 'fc-crop', props.colWidth == null && 'fc-liquid', dataConfig.className), style: {
|
|
893
|
-
width: props.colWidth != null
|
|
894
|
-
? props.colWidth * (dataConfig.colSpan || 1)
|
|
895
|
-
: undefined,
|
|
896
|
-
}, renderProps: dataConfig.renderProps, generatorName: renderConfig.generatorName, customGenerator: renderConfig.customGenerator, defaultGenerator: internal_cjs.renderText, classNameGenerator:
|
|
897
|
-
// don't use custom classNames if disabled
|
|
898
|
-
// TODO: make DRY with DayCellContainer
|
|
899
|
-
isDisabled ? undefined : renderConfig.classNameGenerator, didMount: renderConfig.didMount, willUnmount: renderConfig.willUnmount }, (InnerContainer) => (preact_cjs.createElement(InnerContainer, { tag: 'div', attrs: dataConfig.innerAttrs, className: internal_cjs.joinClassNames('fc-cell-inner fc-flex-col fc-padding-sm', props.isSticky && 'fc-sticky-s'), elRef: this.handleInnerEl }))));
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
class DayGridHeaderRow extends internal_cjs.BaseComponent {
|
|
904
|
-
constructor() {
|
|
905
|
-
super(...arguments);
|
|
906
|
-
// ref
|
|
907
|
-
this.innerHeightRefMap = new internal_cjs.RefMap(() => {
|
|
908
|
-
internal_cjs.afterSize(this.handleInnerHeights);
|
|
909
|
-
});
|
|
910
|
-
this.handleInnerHeights = () => {
|
|
911
|
-
const innerHeightMap = this.innerHeightRefMap.current;
|
|
912
|
-
let max = 0;
|
|
913
|
-
for (const innerHeight of innerHeightMap.values()) {
|
|
914
|
-
max = Math.max(max, innerHeight);
|
|
915
|
-
}
|
|
916
|
-
if (this.currentInnerHeight !== max) {
|
|
917
|
-
this.currentInnerHeight = max;
|
|
918
|
-
internal_cjs.setRef(this.props.innerHeightRef, max);
|
|
919
|
-
}
|
|
920
|
-
};
|
|
921
|
-
}
|
|
922
|
-
render() {
|
|
923
|
-
const { props } = this;
|
|
924
|
-
return (preact_cjs.createElement("div", { role: props.role /* !!! */, "aria-rowindex": props.rowIndex != null ? 1 + props.rowIndex : undefined, className: internal_cjs.joinClassNames('fc-flex-row fc-content-box', props.className), style: { height: props.height } }, props.dataConfigs.map((dataConfig, cellI) => (preact_cjs.createElement(DayGridHeaderCell, { key: dataConfig.key, renderConfig: props.renderConfig, dataConfig: dataConfig, isSticky: props.isSticky, borderStart: Boolean(cellI), colWidth: props.colWidth, innerHeightRef: props.innerHeightRef })))));
|
|
925
|
-
}
|
|
926
|
-
}
|
|
927
|
-
|
|
928
|
-
/*
|
|
929
|
-
TODO: kill this class in favor of DayGridHeaderRows?
|
|
930
|
-
*/
|
|
931
|
-
class DayGridHeader extends internal_cjs.BaseComponent {
|
|
932
|
-
render() {
|
|
933
|
-
const { props } = this;
|
|
934
|
-
return (preact_cjs.createElement("div", { role: 'rowgroup', className: internal_cjs.joinClassNames(props.className, 'fc-flex-col', props.width == null && 'fc-liquid'), style: {
|
|
935
|
-
width: props.width
|
|
936
|
-
} }, props.headerTiers.map((rowConfig, tierNum) => (preact_cjs.createElement(DayGridHeaderRow, Object.assign({}, rowConfig, { key: tierNum, role: 'row', className: tierNum ? 'fc-border-t' : '', colWidth: props.colWidth }))))));
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
|
|
940
|
-
class DayGridLayoutNormal extends internal_cjs.BaseComponent {
|
|
941
|
-
constructor() {
|
|
942
|
-
super(...arguments);
|
|
943
|
-
this.handleScroller = (scroller) => {
|
|
944
|
-
internal_cjs.setRef(this.props.scrollerRef, scroller);
|
|
945
|
-
};
|
|
946
|
-
this.handleClientWidth = (clientWidth) => {
|
|
947
|
-
this.setState({ clientWidth });
|
|
948
|
-
};
|
|
949
|
-
this.handleEndScrollbarWidth = (endScrollbarWidth) => {
|
|
950
|
-
this.setState({ endScrollbarWidth });
|
|
951
|
-
};
|
|
952
|
-
}
|
|
953
|
-
render() {
|
|
954
|
-
const { props, state, context } = this;
|
|
955
|
-
const { options } = context;
|
|
956
|
-
const verticalScrollbars = !props.forPrint && !internal_cjs.getIsHeightAuto(options);
|
|
957
|
-
const stickyHeaderDates = !props.forPrint && internal_cjs.getStickyHeaderDates(options);
|
|
958
|
-
return (preact_cjs.createElement(preact_cjs.Fragment, null,
|
|
959
|
-
options.dayHeaders && (preact_cjs.createElement("div", { className: internal_cjs.joinClassNames(props.forPrint ? 'fc-print-header' : 'fc-flex-row', // col for print, row for screen
|
|
960
|
-
'fc-border-b') },
|
|
961
|
-
preact_cjs.createElement(DayGridHeader, { headerTiers: props.headerTiers, className: internal_cjs.joinClassNames('fc-daygrid-header', stickyHeaderDates && 'fc-table-header-sticky') }),
|
|
962
|
-
Boolean(state.endScrollbarWidth) && (preact_cjs.createElement("div", { className: 'fc-border-s fc-filler', style: { minWidth: state.endScrollbarWidth } })))),
|
|
963
|
-
preact_cjs.createElement(internal_cjs.Scroller, { vertical: verticalScrollbars, clientWidthRef: this.handleClientWidth, endScrollbarWidthRef: this.handleEndScrollbarWidth, className: internal_cjs.joinClassNames('fc-daygrid-body',
|
|
964
|
-
// HACK for Safari. Can't do break-inside:avoid with flexbox items, likely b/c it's not standard:
|
|
965
|
-
// https://stackoverflow.com/a/60256345
|
|
966
|
-
!props.forPrint && 'fc-flex-col', verticalScrollbars && 'fc-liquid'), ref: this.handleScroller },
|
|
967
|
-
preact_cjs.createElement(DayGridRows, { dateProfile: props.dateProfile, todayRange: props.todayRange, cellRows: props.cellRows, forPrint: props.forPrint, isHitComboAllowed: props.isHitComboAllowed, className: 'fc-grow', dayMaxEvents: props.forPrint ? undefined : options.dayMaxEvents, dayMaxEventRows: options.dayMaxEventRows,
|
|
968
|
-
// content
|
|
969
|
-
fgEventSegs: props.fgEventSegs, bgEventSegs: props.bgEventSegs, businessHourSegs: props.businessHourSegs, dateSelectionSegs: props.dateSelectionSegs, eventDrag: props.eventDrag, eventResize: props.eventResize, eventSelection: props.eventSelection,
|
|
970
|
-
// dimensions
|
|
971
|
-
visibleWidth: // TODO: DRY
|
|
972
|
-
state.clientWidth != null && state.endScrollbarWidth != null
|
|
973
|
-
? state.clientWidth + state.endScrollbarWidth
|
|
974
|
-
: undefined,
|
|
975
|
-
// refs
|
|
976
|
-
rowHeightRefMap: props.rowHeightRefMap }))));
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
class DayGridLayoutPannable extends internal_cjs.BaseComponent {
|
|
981
|
-
constructor() {
|
|
982
|
-
super(...arguments);
|
|
983
|
-
this.headerScrollerRef = preact_cjs.createRef();
|
|
984
|
-
this.bodyScrollerRef = preact_cjs.createRef();
|
|
985
|
-
this.footerScrollerRef = preact_cjs.createRef();
|
|
986
|
-
// Sizing
|
|
987
|
-
// -----------------------------------------------------------------------------------------------
|
|
988
|
-
this.handleClientWidth = (clientWidth) => {
|
|
989
|
-
this.setState({ clientWidth });
|
|
990
|
-
};
|
|
991
|
-
this.handleEndScrollbarWidth = (endScrollbarWidth) => {
|
|
992
|
-
this.setState({ endScrollbarWidth });
|
|
993
|
-
};
|
|
994
|
-
}
|
|
995
|
-
render() {
|
|
996
|
-
const { props, state, context } = this;
|
|
997
|
-
const { options } = context;
|
|
998
|
-
const verticalScrollbars = !props.forPrint && !internal_cjs.getIsHeightAuto(options);
|
|
999
|
-
const stickyHeaderDates = !props.forPrint && internal_cjs.getStickyHeaderDates(options);
|
|
1000
|
-
const stickyFooterScrollbar = !props.forPrint && internal_cjs.getStickyFooterScrollbar(options);
|
|
1001
|
-
const colCnt = props.cellRows[0].length;
|
|
1002
|
-
const [canvasWidth, colWidth] = computeColWidth(colCnt, props.dayMinWidth, state.clientWidth);
|
|
1003
|
-
return (preact_cjs.createElement(preact_cjs.Fragment, null,
|
|
1004
|
-
options.dayHeaders && (preact_cjs.createElement("div", { className: 'fc-print-header' },
|
|
1005
|
-
preact_cjs.createElement(internal_cjs.Scroller, { horizontal: true, hideScrollbars: true, className: internal_cjs.joinClassNames('fc-daygrid-header fc-flex-row fc-border-b', stickyHeaderDates && 'fc-table-header-sticky'), ref: this.headerScrollerRef },
|
|
1006
|
-
preact_cjs.createElement(DayGridHeader, { headerTiers: props.headerTiers, colWidth: colWidth, width: canvasWidth }),
|
|
1007
|
-
Boolean(state.endScrollbarWidth) && (preact_cjs.createElement("div", { className: 'fc-border-s fc-filler', style: { minWidth: state.endScrollbarWidth } }))))),
|
|
1008
|
-
preact_cjs.createElement(internal_cjs.Scroller, { vertical: verticalScrollbars, horizontal: true, hideScrollbars: stickyFooterScrollbar ||
|
|
1009
|
-
props.forPrint // prevents blank space in print-view on Safari
|
|
1010
|
-
, className: internal_cjs.joinClassNames('fc-daygrid-body',
|
|
1011
|
-
// HACK for Safari. Can't do break-inside:avoid with flexbox items, likely b/c it's not standard:
|
|
1012
|
-
// https://stackoverflow.com/a/60256345
|
|
1013
|
-
!props.forPrint && 'fc-flex-col', verticalScrollbars && 'fc-liquid'), ref: this.bodyScrollerRef, clientWidthRef: this.handleClientWidth, endScrollbarWidthRef: this.handleEndScrollbarWidth },
|
|
1014
|
-
preact_cjs.createElement(DayGridRows, { dateProfile: props.dateProfile, todayRange: props.todayRange, cellRows: props.cellRows, forPrint: props.forPrint, isHitComboAllowed: props.isHitComboAllowed, className: 'fc-grow', dayMaxEvents: props.forPrint ? undefined : options.dayMaxEvents, dayMaxEventRows: options.dayMaxEventRows,
|
|
1015
|
-
// content
|
|
1016
|
-
fgEventSegs: props.fgEventSegs, bgEventSegs: props.bgEventSegs, businessHourSegs: props.businessHourSegs, dateSelectionSegs: props.dateSelectionSegs, eventDrag: props.eventDrag, eventResize: props.eventResize, eventSelection: props.eventSelection,
|
|
1017
|
-
// dimensions
|
|
1018
|
-
colWidth: colWidth, width: canvasWidth, visibleWidth: // TODO: DRY
|
|
1019
|
-
state.clientWidth != null && state.endScrollbarWidth != null
|
|
1020
|
-
? state.clientWidth + state.endScrollbarWidth
|
|
1021
|
-
: undefined,
|
|
1022
|
-
// refs
|
|
1023
|
-
rowHeightRefMap: props.rowHeightRefMap })),
|
|
1024
|
-
Boolean(stickyFooterScrollbar) && (preact_cjs.createElement(internal_cjs.StickyFooterScrollbar, { canvasWidth: canvasWidth, scrollerRef: this.footerScrollerRef }))));
|
|
1025
|
-
}
|
|
1026
|
-
// Lifecycle
|
|
1027
|
-
// -----------------------------------------------------------------------------------------------
|
|
1028
|
-
componentDidMount() {
|
|
1029
|
-
// scroller
|
|
1030
|
-
const ScrollerSyncer = internal_cjs.getScrollerSyncerClass(this.context.pluginHooks);
|
|
1031
|
-
this.syncedScroller = new ScrollerSyncer(true); // horizontal=true
|
|
1032
|
-
internal_cjs.setRef(this.props.scrollerRef, this.syncedScroller);
|
|
1033
|
-
this.updateSyncedScroller();
|
|
1034
|
-
}
|
|
1035
|
-
componentDidUpdate() {
|
|
1036
|
-
// scroller
|
|
1037
|
-
this.updateSyncedScroller();
|
|
1038
|
-
}
|
|
1039
|
-
componentWillUnmount() {
|
|
1040
|
-
// scroller
|
|
1041
|
-
this.syncedScroller.destroy();
|
|
1042
|
-
}
|
|
1043
|
-
// Scrolling
|
|
1044
|
-
// -----------------------------------------------------------------------------------------------
|
|
1045
|
-
updateSyncedScroller() {
|
|
1046
|
-
this.syncedScroller.handleChildren([
|
|
1047
|
-
this.headerScrollerRef.current,
|
|
1048
|
-
this.bodyScrollerRef.current,
|
|
1049
|
-
this.footerScrollerRef.current,
|
|
1050
|
-
]);
|
|
1051
|
-
}
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
|
-
class DayGridLayout extends internal_cjs.BaseComponent {
|
|
1055
|
-
constructor() {
|
|
1056
|
-
super(...arguments);
|
|
1057
|
-
// ref
|
|
1058
|
-
this.scrollerRef = preact_cjs.createRef();
|
|
1059
|
-
this.rowHeightRefMap = new internal_cjs.RefMap(() => {
|
|
1060
|
-
internal_cjs.afterSize(this.updateScrollY);
|
|
1061
|
-
});
|
|
1062
|
-
// internal
|
|
1063
|
-
this.scrollDate = null;
|
|
1064
|
-
this.updateScrollY = () => {
|
|
1065
|
-
const rowHeightMap = this.rowHeightRefMap.current;
|
|
1066
|
-
const scroller = this.scrollerRef.current;
|
|
1067
|
-
// Since updateScrollY is called by rowHeightRefMap, could be called with null during cleanup,
|
|
1068
|
-
// and the scroller might not exist
|
|
1069
|
-
if (scroller && this.scrollDate) {
|
|
1070
|
-
let scrollTop = computeTopFromDate(this.scrollDate, this.props.cellRows, rowHeightMap, 1);
|
|
1071
|
-
if (scrollTop != null) {
|
|
1072
|
-
if (scrollTop) {
|
|
1073
|
-
scrollTop++; // clear top border
|
|
1074
|
-
}
|
|
1075
|
-
scroller.scrollTo({ y: scrollTop });
|
|
1076
|
-
}
|
|
1077
|
-
}
|
|
1078
|
-
};
|
|
1079
|
-
this.handleScrollEnd = ({ isUser }) => {
|
|
1080
|
-
if (isUser) {
|
|
1081
|
-
this.scrollDate = null;
|
|
1082
|
-
}
|
|
1083
|
-
};
|
|
1084
|
-
}
|
|
1085
|
-
render() {
|
|
1086
|
-
const { props, context } = this;
|
|
1087
|
-
const { options } = context;
|
|
1088
|
-
const commonLayoutProps = Object.assign(Object.assign({}, props), { scrollerRef: this.scrollerRef, rowHeightRefMap: this.rowHeightRefMap });
|
|
1089
|
-
return (preact_cjs.createElement(internal_cjs.ViewContainer, { viewSpec: context.viewSpec, attrs: {
|
|
1090
|
-
role: 'grid',
|
|
1091
|
-
'aria-rowcount': props.headerTiers.length + props.cellRows.length,
|
|
1092
|
-
'aria-colcount': props.cellRows[0].length,
|
|
1093
|
-
'aria-labelledby': props.labelId,
|
|
1094
|
-
'aria-label': props.labelStr,
|
|
1095
|
-
}, className: internal_cjs.joinClassNames(props.className, 'fc-print-root fc-border') }, options.dayMinWidth ? (preact_cjs.createElement(DayGridLayoutPannable, Object.assign({}, commonLayoutProps, { dayMinWidth: options.dayMinWidth }))) : (preact_cjs.createElement(DayGridLayoutNormal, Object.assign({}, commonLayoutProps)))));
|
|
1096
|
-
}
|
|
1097
|
-
// Lifecycle
|
|
1098
|
-
// -----------------------------------------------------------------------------------------------
|
|
1099
|
-
componentDidMount() {
|
|
1100
|
-
this.resetScroll();
|
|
1101
|
-
this.scrollerRef.current.addScrollEndListener(this.handleScrollEnd);
|
|
1102
|
-
}
|
|
1103
|
-
componentDidUpdate(prevProps) {
|
|
1104
|
-
if (prevProps.dateProfile !== this.props.dateProfile && this.context.options.scrollTimeReset) {
|
|
1105
|
-
this.resetScroll();
|
|
1106
|
-
}
|
|
1107
|
-
}
|
|
1108
|
-
componentWillUnmount() {
|
|
1109
|
-
this.scrollerRef.current.removeScrollEndListener(this.handleScrollEnd);
|
|
1110
|
-
}
|
|
1111
|
-
// Scrolling
|
|
1112
|
-
// -----------------------------------------------------------------------------------------------
|
|
1113
|
-
resetScroll() {
|
|
1114
|
-
this.scrollDate = this.props.dateProfile.currentDate;
|
|
1115
|
-
this.updateScrollY();
|
|
1116
|
-
const scroller = this.scrollerRef.current;
|
|
1117
|
-
scroller.scrollTo({ x: 0 });
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
|
|
1121
|
-
class DayGridView extends internal_cjs.BaseComponent {
|
|
1122
|
-
constructor() {
|
|
1123
|
-
super(...arguments);
|
|
1124
|
-
// memo
|
|
1125
|
-
this.buildDayTableModel = internal_cjs.memoize(buildDayTableModel);
|
|
1126
|
-
this.buildDateRowConfigs = internal_cjs.memoize(buildDateRowConfigs);
|
|
1127
|
-
this.createDayHeaderFormatter = internal_cjs.memoize(createDayHeaderFormatter);
|
|
1128
|
-
// internal
|
|
1129
|
-
this.slicer = new DayTableSlicer();
|
|
1130
|
-
}
|
|
1131
|
-
render() {
|
|
1132
|
-
const { props, context } = this;
|
|
1133
|
-
const { options } = context;
|
|
1134
|
-
const dayTableModel = this.buildDayTableModel(props.dateProfile, context.dateProfileGenerator);
|
|
1135
|
-
const datesRepDistinctDays = dayTableModel.rowCnt === 1;
|
|
1136
|
-
const dayHeaderFormat = this.createDayHeaderFormatter(context.options.dayHeaderFormat, datesRepDistinctDays, dayTableModel.colCnt);
|
|
1137
|
-
const slicedProps = this.slicer.sliceProps(props, props.dateProfile, options.nextDayThreshold, context, dayTableModel);
|
|
1138
|
-
return (preact_cjs.createElement(internal_cjs.NowTimer, { unit: "day" }, (nowDate, todayRange) => {
|
|
1139
|
-
const headerTiers = this.buildDateRowConfigs(dayTableModel.headerDates, datesRepDistinctDays, props.dateProfile, todayRange, dayHeaderFormat, context);
|
|
1140
|
-
return (preact_cjs.createElement(DayGridLayout, { labelId: props.labelId, labelStr: props.labelStr, dateProfile: props.dateProfile, todayRange: todayRange, cellRows: dayTableModel.cellRows, forPrint: props.forPrint, className: 'fc-daygrid',
|
|
1141
|
-
// header content
|
|
1142
|
-
headerTiers: headerTiers,
|
|
1143
|
-
// body content
|
|
1144
|
-
fgEventSegs: slicedProps.fgEventSegs, bgEventSegs: slicedProps.bgEventSegs, businessHourSegs: slicedProps.businessHourSegs, dateSelectionSegs: slicedProps.dateSelectionSegs, eventDrag: slicedProps.eventDrag, eventResize: slicedProps.eventResize, eventSelection: slicedProps.eventSelection }));
|
|
1145
|
-
}));
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
|
|
1149
|
-
class TableDateProfileGenerator extends internal_cjs.DateProfileGenerator {
|
|
1150
|
-
// Computes the date range that will be rendered
|
|
1151
|
-
buildRenderRange(currentRange, currentRangeUnit, isRangeAllDay) {
|
|
1152
|
-
let renderRange = super.buildRenderRange(currentRange, currentRangeUnit, isRangeAllDay);
|
|
1153
|
-
let { props } = this;
|
|
1154
|
-
return buildDayTableRenderRange({
|
|
1155
|
-
currentRange: renderRange,
|
|
1156
|
-
snapToWeek: /^(year|month)$/.test(currentRangeUnit),
|
|
1157
|
-
fixedWeekCount: props.fixedWeekCount,
|
|
1158
|
-
dateEnv: props.dateEnv,
|
|
1159
|
-
});
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
|
-
function buildDayTableRenderRange(props) {
|
|
1163
|
-
let { dateEnv, currentRange } = props;
|
|
1164
|
-
let { start, end } = currentRange;
|
|
1165
|
-
let endOfWeek;
|
|
1166
|
-
// year and month views should be aligned with weeks. this is already done for week
|
|
1167
|
-
if (props.snapToWeek) {
|
|
1168
|
-
start = dateEnv.startOfWeek(start);
|
|
1169
|
-
// make end-of-week if not already
|
|
1170
|
-
endOfWeek = dateEnv.startOfWeek(end);
|
|
1171
|
-
if (endOfWeek.valueOf() !== end.valueOf()) {
|
|
1172
|
-
end = internal_cjs.addWeeks(endOfWeek, 1);
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
// ensure 6 weeks
|
|
1176
|
-
if (props.fixedWeekCount) {
|
|
1177
|
-
// TODO: instead of these date-math gymnastics (for multimonth view),
|
|
1178
|
-
// compute dateprofiles of all months, then use start of first and end of last.
|
|
1179
|
-
let lastMonthRenderStart = dateEnv.startOfWeek(dateEnv.startOfMonth(internal_cjs.addDays(currentRange.end, -1)));
|
|
1180
|
-
let rowCnt = Math.ceil(// could be partial weeks due to hiddenDays
|
|
1181
|
-
internal_cjs.diffWeeks(lastMonthRenderStart, end));
|
|
1182
|
-
end = internal_cjs.addWeeks(end, 6 - rowCnt);
|
|
1183
|
-
}
|
|
1184
|
-
return { start, end };
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
|
-
var css_248z = ":root{--fc-daygrid-event-dot-width:8px}.fc-daygrid-day.fc-day-today{background-color:var(--fc-today-bg-color)}.fc-daygrid-day-header{display:flex;flex-direction:row-reverse}.fc-day-other .fc-daygrid-day-header{opacity:.3}.fc-daygrid-day-number{padding:4px;position:relative}.fc-daygrid-month-start{font-size:1.1em;font-weight:700}.fc-daygrid-day-body{display:flex;flex-direction:column;margin-bottom:1px}.fc-daygrid-day-body-tall{margin-bottom:1em;min-height:2em}.fc-daygrid-day-body:only-child{margin-top:2px}.fc-daygrid-more-link{border-radius:3px;cursor:pointer;font-size:var(--fc-small-font-size);margin:0 2px 1px;max-width:100%;overflow:hidden;padding:2px;position:relative;white-space:nowrap}.fc-daygrid-more-link:hover{background-color:rgba(0,0,0,.1)}.fc-daygrid-more-link-button{align-self:flex-start}.fc-daygrid-more-link-block{border:1px solid var(--fc-event-border-color);padding:1px}.fc-daygrid-week-number{background-color:var(--fc-neutral-bg-color);color:var(--fc-neutral-text-color);min-width:1.5em;padding:2px;position:absolute;text-align:center;top:0}.fc-more-popover .fc-popover-body{min-width:220px;padding:10px}.fc-daygrid-event{border-radius:3px;font-size:var(--fc-small-font-size);margin-bottom:1px}.fc-media-print .fc-daygrid-event{overflow:hidden!important;white-space:nowrap!important}.fc-direction-ltr .fc-daygrid-event.fc-event-start,.fc-direction-rtl .fc-daygrid-event.fc-event-end{margin-left:2px}.fc-direction-ltr .fc-daygrid-event.fc-event-end,.fc-direction-rtl .fc-daygrid-event.fc-event-start{margin-right:2px}.fc-direction-ltr .fc-daygrid-event .fc-event-time{margin-right:3px}.fc-direction-rtl .fc-daygrid-event .fc-event-time{margin-left:3px}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-start),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-end){border-bottom-left-radius:0;border-left-width:0;border-top-left-radius:0}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-end),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-start){border-bottom-right-radius:0;border-right-width:0;border-top-right-radius:0}.fc-daygrid-block-event .fc-event-time{font-weight:700}.fc-daygrid-block-event .fc-event-time,.fc-daygrid-block-event .fc-event-title{padding:1px}.fc-daygrid-dot-event{align-items:center;direction:row;display:flex;padding:2px 0;position:relative;z-index:2}.fc-daygrid-dot-event.fc-event-mirror,.fc-daygrid-dot-event:hover{background:rgba(0,0,0,.1)}.fc-daygrid-dot-event.fc-event-selected:before{bottom:-10px;top:-10px}.fc-daygrid-event-dot{border:calc(var(--fc-daygrid-event-dot-width)/2) solid var(--fc-event-border-color);border-radius:calc(var(--fc-daygrid-event-dot-width)/2);box-sizing:content-box;height:0;margin:0 4px;width:0}.fc-daygrid-dot-event .fc-event-time,.fc-daygrid-dot-event .fc-event-title{overflow:hidden;white-space:nowrap}.fc-daygrid-dot-event .fc-event-title{flex-basis:0;flex-grow:1;font-weight:700;min-height:0;min-width:0}";
|
|
1188
|
-
internal_cjs.injectStyles(css_248z);
|
|
1189
|
-
|
|
1190
|
-
exports.DayGridHeaderRow = DayGridHeaderRow;
|
|
1191
|
-
exports.DayGridLayout = DayGridLayout;
|
|
1192
|
-
exports.DayGridRow = DayGridRow;
|
|
1193
|
-
exports.DayGridRows = DayGridRows;
|
|
1194
|
-
exports.DayGridView = DayGridView;
|
|
1195
|
-
exports.DayTableSlicer = DayTableSlicer;
|
|
1196
|
-
exports.TableDateProfileGenerator = TableDateProfileGenerator;
|
|
1197
|
-
exports.buildDateDataConfigs = buildDateDataConfigs;
|
|
1198
|
-
exports.buildDateRenderConfig = buildDateRenderConfig;
|
|
1199
|
-
exports.buildDateRowConfig = buildDateRowConfig;
|
|
1200
|
-
exports.buildDateRowConfigs = buildDateRowConfigs;
|
|
1201
|
-
exports.buildDayTableModel = buildDayTableModel;
|
|
1202
|
-
exports.buildDayTableRenderRange = buildDayTableRenderRange;
|
|
1203
|
-
exports.computeColFromPosition = computeColFromPosition;
|
|
1204
|
-
exports.computeColWidth = computeColWidth;
|
|
1205
|
-
exports.computeRowHeight = computeRowHeight;
|
|
1206
|
-
exports.createDayHeaderFormatter = createDayHeaderFormatter;
|
|
1207
|
-
exports.getCellEl = getCellEl;
|
|
1208
|
-
exports.getRowEl = getRowEl;
|