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