@fullcalendar/daygrid 7.0.0-beta.4 → 7.0.0-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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;