@fullcalendar/daygrid 6.1.14 → 7.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.global.js CHANGED
@@ -1,133 +1,215 @@
1
1
  /*!
2
- FullCalendar Day Grid Plugin v6.1.14
2
+ FullCalendar Day Grid Plugin v7.0.0-beta.0
3
3
  Docs & License: https://fullcalendar.io/docs/month-view
4
4
  (c) 2024 Adam Shaw
5
5
  */
6
6
  FullCalendar.DayGrid = (function (exports, core, internal$1, preact) {
7
7
  'use strict';
8
8
 
9
- /* An abstract class for the daygrid views, as well as month view. Renders one or more rows of day cells.
10
- ----------------------------------------------------------------------------------------------------------------------*/
11
- // It is a manager for a Table subcomponent, which does most of the heavy lifting.
12
- // It is responsible for managing width/height.
13
- class TableView extends internal$1.DateComponent {
9
+ class DayTableSlicer extends internal$1.Slicer {
14
10
  constructor() {
15
11
  super(...arguments);
16
- this.headerElRef = preact.createRef();
12
+ this.forceDayIfListItem = true;
17
13
  }
18
- renderSimpleLayout(headerRowContent, bodyContent) {
19
- let { props, context } = this;
20
- let sections = [];
21
- let stickyHeaderDates = internal$1.getStickyHeaderDates(context.options);
22
- if (headerRowContent) {
23
- sections.push({
24
- type: 'header',
25
- key: 'header',
26
- isSticky: stickyHeaderDates,
27
- chunk: {
28
- elRef: this.headerElRef,
29
- tableClassName: 'fc-col-header',
30
- rowContent: headerRowContent,
31
- },
32
- });
14
+ sliceRange(dateRange, dayTableModel) {
15
+ return dayTableModel.sliceRange(dateRange);
16
+ }
17
+ }
18
+
19
+ function renderInner(renderProps) {
20
+ return renderProps.text;
21
+ }
22
+ function buildDayTableModel(dateProfile, dateProfileGenerator) {
23
+ let daySeries = new internal$1.DaySeriesModel(dateProfile.renderRange, dateProfileGenerator);
24
+ return new internal$1.DayTableModel(daySeries, /year|month|week/.test(dateProfile.currentRangeUnit));
25
+ }
26
+ function computeColWidth(colCnt, colMinWidth, viewportWidth) {
27
+ if (viewportWidth == null) {
28
+ return [undefined, undefined];
29
+ }
30
+ const colTempWidth = viewportWidth / colCnt;
31
+ if (colTempWidth < colMinWidth) {
32
+ return [colMinWidth * colCnt, colMinWidth];
33
+ }
34
+ return [viewportWidth, undefined];
35
+ }
36
+ function buildHeaderTiers(dates, datesRepDistinctDays) {
37
+ return [
38
+ datesRepDistinctDays
39
+ ? dates.map((date) => ({ colSpan: 1, date }))
40
+ : dates.map((date) => ({ colSpan: 1, dow: date.getUTCDay() }))
41
+ ];
42
+ }
43
+ // Positioning
44
+ // -------------------------------------------------------------------------------------------------
45
+ function computeTopFromDate(date, cellRows, rowHeightMap) {
46
+ let top = 0;
47
+ for (const cells of cellRows) {
48
+ const start = cells[0].date;
49
+ const end = cells[cells.length - 1].date;
50
+ const key = start.toISOString();
51
+ if (date >= start && date <= end) {
52
+ return top;
33
53
  }
34
- sections.push({
35
- type: 'body',
36
- key: 'body',
37
- liquid: true,
38
- chunk: { content: bodyContent },
39
- });
40
- return (preact.createElement(internal$1.ViewContainer, { elClasses: ['fc-daygrid'], viewSpec: context.viewSpec },
41
- preact.createElement(internal$1.SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, cols: [] /* TODO: make optional? */, sections: sections })));
54
+ const rowHeight = rowHeightMap.get(key);
55
+ if (rowHeight == null) {
56
+ return; // denote unknown
57
+ }
58
+ top += rowHeight;
42
59
  }
43
- renderHScrollLayout(headerRowContent, bodyContent, colCnt, dayMinWidth) {
44
- let ScrollGrid = this.context.pluginHooks.scrollGridImpl;
45
- if (!ScrollGrid) {
46
- throw new Error('No ScrollGrid implementation');
60
+ return top;
61
+ }
62
+ function computeHorizontalsFromSeg(seg, colWidth, colCnt, isRtl) {
63
+ let left;
64
+ let right;
65
+ let width;
66
+ if (colWidth != null) {
67
+ width = (seg.lastCol - seg.firstCol + 1) * colWidth;
68
+ if (isRtl) {
69
+ right = seg.firstCol * colWidth;
47
70
  }
48
- let { props, context } = this;
49
- let stickyHeaderDates = !props.forPrint && internal$1.getStickyHeaderDates(context.options);
50
- let stickyFooterScrollbar = !props.forPrint && internal$1.getStickyFooterScrollbar(context.options);
51
- let sections = [];
52
- if (headerRowContent) {
53
- sections.push({
54
- type: 'header',
55
- key: 'header',
56
- isSticky: stickyHeaderDates,
57
- chunks: [{
58
- key: 'main',
59
- elRef: this.headerElRef,
60
- tableClassName: 'fc-col-header',
61
- rowContent: headerRowContent,
62
- }],
63
- });
71
+ else {
72
+ left = seg.firstCol * colWidth;
64
73
  }
65
- sections.push({
66
- type: 'body',
67
- key: 'body',
68
- liquid: true,
69
- chunks: [{
70
- key: 'main',
71
- content: bodyContent,
72
- }],
73
- });
74
- if (stickyFooterScrollbar) {
75
- sections.push({
76
- type: 'footer',
77
- key: 'footer',
78
- isSticky: true,
79
- chunks: [{
80
- key: 'main',
81
- content: internal$1.renderScrollShim,
82
- }],
83
- });
74
+ }
75
+ else {
76
+ const colWidthFrac = 1 / colCnt;
77
+ width = internal$1.fracToCssDim((seg.lastCol - seg.firstCol + 1) * colWidthFrac);
78
+ if (isRtl) {
79
+ right = internal$1.fracToCssDim(seg.firstCol * colWidthFrac);
80
+ }
81
+ else {
82
+ left = internal$1.fracToCssDim(seg.firstCol * colWidthFrac);
84
83
  }
85
- return (preact.createElement(internal$1.ViewContainer, { elClasses: ['fc-daygrid'], viewSpec: context.viewSpec },
86
- preact.createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, forPrint: props.forPrint, collapsibleWidth: props.forPrint, colGroups: [{ cols: [{ span: colCnt, minWidth: dayMinWidth }] }], sections: sections })));
87
84
  }
85
+ return { left, right, width };
86
+ }
87
+ function computeColFromPosition(positionLeft, elWidth, colWidth, colCnt, isRtl) {
88
+ const realColWidth = colWidth != null ? colWidth : elWidth / colCnt;
89
+ const colFromLeft = Math.floor(positionLeft / realColWidth);
90
+ const col = isRtl ? (colCnt - colFromLeft - 1) : colFromLeft;
91
+ const left = colFromLeft * realColWidth;
92
+ const right = left + realColWidth;
93
+ return { col, left, right };
94
+ }
95
+ function computeRowFromPosition(positionTop, cellRows, rowHeightMap) {
96
+ let row = 0;
97
+ let top = 0;
98
+ let bottom = 0;
99
+ for (const cells of cellRows) {
100
+ const key = cells[0].key;
101
+ top = bottom;
102
+ bottom = top + rowHeightMap.get(key);
103
+ if (positionTop < bottom) {
104
+ break;
105
+ }
106
+ row++;
107
+ }
108
+ return { row, top, bottom };
109
+ }
110
+ // Hit Element
111
+ // -------------------------------------------------------------------------------------------------
112
+ function getRowEl(rootEl, row) {
113
+ return rootEl.querySelectorAll(':scope > [role=row]')[row];
114
+ }
115
+ function getCellEl(rowEl, col) {
116
+ return rowEl.querySelectorAll(':scope > [role=gridcell]')[col];
88
117
  }
89
118
 
90
- function splitSegsByRow(segs, rowCnt) {
91
- let byRow = [];
92
- for (let i = 0; i < rowCnt; i += 1) {
93
- byRow[i] = [];
119
+ class DateHeaderCell extends internal$1.BaseComponent {
120
+ constructor() {
121
+ super(...arguments);
122
+ // ref
123
+ this.innerElRef = preact.createRef();
94
124
  }
95
- for (let seg of segs) {
96
- byRow[seg.row].push(seg);
125
+ render() {
126
+ let { props, context } = this;
127
+ let { dateProfile, date, extraRenderProps, extraDataAttrs } = props;
128
+ let { dateEnv, options, theme, viewApi } = context;
129
+ let dayMeta = internal$1.getDateMeta(date, props.todayRange, null, dateProfile);
130
+ let text = dateEnv.format(date, props.dayHeaderFormat);
131
+ let navLinkAttrs = (!dayMeta.isDisabled && props.navLink)
132
+ ? internal$1.buildNavLinkAttrs(context, date)
133
+ : {};
134
+ let renderProps = Object.assign(Object.assign(Object.assign({ date: dateEnv.toDate(date), view: viewApi }, extraRenderProps), { text }), dayMeta);
135
+ return (preact.createElement(internal$1.ContentContainer, { elTag: 'div', elClasses: [
136
+ ...internal$1.getDayClassNames(dayMeta, theme),
137
+ ...(props.extraClassNames || []),
138
+ 'fc-header-cell',
139
+ 'fc-cell',
140
+ props.colWidth != null ? '' : 'fc-liquid',
141
+ 'fc-flex-column',
142
+ 'fc-align-center',
143
+ ], elAttrs: Object.assign({ 'data-date': !dayMeta.isDisabled ? internal$1.formatDayString(date) : undefined }, extraDataAttrs), elStyle: {
144
+ width: props.colWidth != null // TODO: DRY
145
+ ? props.colWidth * (props.colSpan || 1)
146
+ : undefined,
147
+ }, renderProps: renderProps, generatorName: "dayHeaderContent", customGenerator: options.dayHeaderContent, defaultGenerator: renderInner, classNameGenerator: options.dayHeaderClassNames, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, (InnerContainer) => (preact.createElement("div", { ref: this.innerElRef, className: [
148
+ 'fc-flex-column',
149
+ props.isSticky ? 'fc-sticky-x' : '',
150
+ ].join(' ') }, !dayMeta.isDisabled && (preact.createElement(InnerContainer, { elTag: "a", elAttrs: navLinkAttrs, elClasses: [
151
+ 'fc-cell-inner',
152
+ 'fc-padding-sm',
153
+ ] }))))));
154
+ }
155
+ componentDidMount() {
156
+ const innerEl = this.innerElRef.current; // TODO: make dynamic with useEffect
157
+ // TODO: only attach this if refs props present
158
+ this.disconectInnerHeight = internal$1.watchHeight(innerEl, (height) => {
159
+ internal$1.setRef(this.props.innerHeightRef, height);
160
+ });
161
+ }
162
+ componentWillUnmount() {
163
+ this.disconectInnerHeight();
97
164
  }
98
- return byRow;
99
165
  }
100
- function splitSegsByFirstCol(segs, colCnt) {
101
- let byCol = [];
102
- for (let i = 0; i < colCnt; i += 1) {
103
- byCol[i] = [];
166
+
167
+ function splitSegsByRow(segs, rowCnt) {
168
+ const byRow = [];
169
+ for (let row = 0; row < rowCnt; row++) {
170
+ byRow[row] = [];
104
171
  }
105
- for (let seg of segs) {
106
- byCol[seg.firstCol].push(seg);
172
+ for (const seg of segs) {
173
+ byRow[seg.row].push(seg);
107
174
  }
108
- return byCol;
175
+ return byRow;
109
176
  }
110
177
  function splitInteractionByRow(ui, rowCnt) {
111
- let byRow = [];
178
+ const byRow = [];
112
179
  if (!ui) {
113
- for (let i = 0; i < rowCnt; i += 1) {
114
- byRow[i] = null;
180
+ for (let row = 0; row < rowCnt; row++) {
181
+ byRow[row] = null;
115
182
  }
116
183
  }
117
184
  else {
118
- for (let i = 0; i < rowCnt; i += 1) {
119
- byRow[i] = {
185
+ for (let row = 0; row < rowCnt; row++) {
186
+ byRow[row] = {
120
187
  affectedInstances: ui.affectedInstances,
121
188
  isEvent: ui.isEvent,
122
189
  segs: [],
123
190
  };
124
191
  }
125
- for (let seg of ui.segs) {
192
+ for (const seg of ui.segs) {
126
193
  byRow[seg.row].segs.push(seg);
127
194
  }
128
195
  }
129
196
  return byRow;
130
197
  }
198
+ function splitSegsByCol(segs, colCnt) {
199
+ let byCol = [];
200
+ for (let col = 0; col < colCnt; col++) {
201
+ byCol.push([]);
202
+ }
203
+ for (let seg of segs) {
204
+ for (let col = seg.firstCol; col <= seg.lastCol; col++) {
205
+ if (seg.firstCol !== col) {
206
+ seg = Object.assign(Object.assign({}, seg), { firstCol: col, lastCol: col, isStart: false, isEnd: seg.isEnd && seg.lastCol === col, isStandin: true });
207
+ }
208
+ byCol[col].push(seg);
209
+ }
210
+ }
211
+ return byCol;
212
+ }
131
213
 
132
214
  const DEFAULT_TABLE_EVENT_TIME_FORMAT = internal$1.createFormatter({
133
215
  hour: 'numeric',
@@ -145,14 +227,14 @@ FullCalendar.DayGrid = (function (exports, core, internal$1, preact) {
145
227
  );
146
228
  }
147
229
 
148
- class TableBlockEvent extends internal$1.BaseComponent {
230
+ class DayGridBlockEvent extends internal$1.BaseComponent {
149
231
  render() {
150
232
  let { props } = this;
151
233
  return (preact.createElement(internal$1.StandardEvent, Object.assign({}, props, { elClasses: ['fc-daygrid-event', 'fc-daygrid-block-event', 'fc-h-event'], defaultTimeFormat: DEFAULT_TABLE_EVENT_TIME_FORMAT, defaultDisplayEventEnd: props.defaultDisplayEventEnd, disableResizing: !props.seg.eventRange.def.allDay })));
152
234
  }
153
235
  }
154
236
 
155
- class TableListItemEvent extends internal$1.BaseComponent {
237
+ class DayGridListEvent extends internal$1.BaseComponent {
156
238
  render() {
157
239
  let { props, context } = this;
158
240
  let { options } = context;
@@ -169,80 +251,83 @@ FullCalendar.DayGrid = (function (exports, core, internal$1, preact) {
169
251
  preact.createElement("div", { className: "fc-event-title" }, renderProps.event.title || preact.createElement(preact.Fragment, null, "\u00A0"))));
170
252
  }
171
253
 
172
- class TableCellMoreLink extends internal$1.BaseComponent {
173
- constructor() {
174
- super(...arguments);
175
- this.compileSegs = internal$1.memoize(compileSegs);
176
- }
254
+ class DayGridMoreLink extends internal$1.BaseComponent {
177
255
  render() {
178
256
  let { props } = this;
179
- let { allSegs, invisibleSegs } = this.compileSegs(props.singlePlacements);
180
- return (preact.createElement(internal$1.MoreLinkContainer, { elClasses: ['fc-daygrid-more-link'], dateProfile: props.dateProfile, todayRange: props.todayRange, allDayDate: props.allDayDate, moreCnt: props.moreCnt, allSegs: allSegs, hiddenSegs: invisibleSegs, alignmentElRef: props.alignmentElRef, alignGridTop: props.alignGridTop, extraDateSpan: props.extraDateSpan, popoverContent: () => {
181
- let isForcedInvisible = (props.eventDrag ? props.eventDrag.affectedInstances : null) ||
257
+ return (preact.createElement(internal$1.MoreLinkContainer, { elClasses: ['fc-daygrid-more-link'], dateProfile: props.dateProfile, todayRange: props.todayRange, allDayDate: props.allDayDate, segs: props.segs, hiddenSegs: props.hiddenSegs, alignmentElRef: props.alignmentElRef, alignGridTop: props.alignGridTop, extraDateSpan: props.extraDateSpan, popoverContent: () => {
258
+ let forcedInvisibleMap = // TODO: more convenient/DRY
259
+ (props.eventDrag ? props.eventDrag.affectedInstances : null) ||
182
260
  (props.eventResize ? props.eventResize.affectedInstances : null) ||
183
261
  {};
184
- return (preact.createElement(preact.Fragment, null, allSegs.map((seg) => {
262
+ return (preact.createElement(preact.Fragment, null, props.segs.map((seg) => {
185
263
  let instanceId = seg.eventRange.instance.instanceId;
186
- return (preact.createElement("div", { className: "fc-daygrid-event-harness", key: instanceId, style: {
187
- visibility: isForcedInvisible[instanceId] ? 'hidden' : '',
188
- } }, hasListItemDisplay(seg) ? (preact.createElement(TableListItemEvent, Object.assign({ seg: seg, isDragging: false, isSelected: instanceId === props.eventSelection, defaultDisplayEventEnd: false }, internal$1.getSegMeta(seg, props.todayRange)))) : (preact.createElement(TableBlockEvent, Object.assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === props.eventSelection, defaultDisplayEventEnd: false }, internal$1.getSegMeta(seg, props.todayRange))))));
264
+ return (preact.createElement("div", { key: instanceId, style: {
265
+ visibility: forcedInvisibleMap[instanceId] ? 'hidden' : '',
266
+ } }, hasListItemDisplay(seg) ? (preact.createElement(DayGridListEvent, Object.assign({ seg: seg, isDragging: false, isSelected: instanceId === props.eventSelection, defaultDisplayEventEnd: false }, internal$1.getSegMeta(seg, props.todayRange)))) : (preact.createElement(DayGridBlockEvent, Object.assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === props.eventSelection, defaultDisplayEventEnd: false }, internal$1.getSegMeta(seg, props.todayRange))))));
189
267
  })));
190
268
  } }));
191
269
  }
192
270
  }
193
- function compileSegs(singlePlacements) {
194
- let allSegs = [];
195
- let invisibleSegs = [];
196
- for (let placement of singlePlacements) {
197
- allSegs.push(placement.seg);
198
- if (!placement.isVisible) {
199
- invisibleSegs.push(placement.seg);
200
- }
201
- }
202
- return { allSegs, invisibleSegs };
203
- }
204
271
 
205
- const DEFAULT_WEEK_NUM_FORMAT = internal$1.createFormatter({ week: 'narrow' });
206
- class TableCell extends internal$1.DateComponent {
272
+ class DayGridCell extends internal$1.DateComponent {
207
273
  constructor() {
208
274
  super(...arguments);
209
- this.rootElRef = preact.createRef();
210
- this.state = {
211
- dayNumberId: internal$1.getUniqueDomId(),
212
- };
213
- this.handleRootEl = (el) => {
214
- internal$1.setRef(this.rootElRef, el);
215
- internal$1.setRef(this.props.elRef, el);
216
- };
275
+ // ref
276
+ this.innerElRef = preact.createRef();
277
+ this.headerWrapElRef = preact.createRef();
217
278
  }
218
279
  render() {
219
- let { context, props, state, rootElRef } = this;
280
+ let { props, context } = this;
220
281
  let { options, dateEnv } = context;
221
- let { date, dateProfile } = props;
222
- // TODO: memoize this?
282
+ // TODO: memoize this
223
283
  const isMonthStart = props.showDayNumber &&
224
- shouldDisplayMonthStart(date, dateProfile.currentRange, dateEnv);
225
- return (preact.createElement(internal$1.DayCellContainer, { elTag: "td", elRef: this.handleRootEl, elClasses: [
226
- 'fc-daygrid-day',
284
+ shouldDisplayMonthStart(props.date, props.dateProfile.currentRange, dateEnv);
285
+ return (preact.createElement(internal$1.DayCellContainer, { elTag: "div", elClasses: [
286
+ 'fc-daygrid-cell',
287
+ 'fc-cell',
288
+ props.width != null ? '' : 'fc-liquid',
289
+ 'fc-flex-column',
227
290
  ...(props.extraClassNames || []),
228
- ], elAttrs: Object.assign(Object.assign(Object.assign({}, props.extraDataAttrs), (props.showDayNumber ? { 'aria-labelledby': state.dayNumberId } : {})), { role: 'gridcell' }), defaultGenerator: renderTopInner, date: date, dateProfile: dateProfile, todayRange: props.todayRange, showDayNumber: props.showDayNumber, isMonthStart: isMonthStart, extraRenderProps: props.extraRenderProps }, (InnerContent, renderProps) => (preact.createElement("div", { ref: props.innerElRef, className: "fc-daygrid-day-frame fc-scrollgrid-sync-inner", style: { minHeight: props.minHeight } },
229
- props.showWeekNumber && (preact.createElement(internal$1.WeekNumberContainer, { elTag: "a", elClasses: ['fc-daygrid-week-number'], elAttrs: internal$1.buildNavLinkAttrs(context, date, 'week'), date: date, defaultFormat: DEFAULT_WEEK_NUM_FORMAT })),
230
- !renderProps.isDisabled &&
231
- (props.showDayNumber || internal$1.hasCustomDayCellContent(options) || props.forceDayTop) ? (preact.createElement("div", { className: "fc-daygrid-day-top" },
291
+ ], elAttrs: Object.assign(Object.assign({}, props.extraDataAttrs), { role: 'gridcell' }), elStyle: {
292
+ width: props.width
293
+ }, extraRenderProps: props.extraRenderProps, defaultGenerator: renderTopInner, date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, showDayNumber: props.showDayNumber, isMonthStart: isMonthStart }, (InnerContent, renderProps) => (preact.createElement("div", { ref: this.innerElRef, className: [
294
+ 'fc-daygrid-cell-inner',
295
+ props.fgLiquidHeight ? 'fc-liquid' : ''
296
+ ].join(' ') },
297
+ preact.createElement("div", { ref: this.headerWrapElRef, className: "fc-flex-column" }, !renderProps.isDisabled && (props.showDayNumber || internal$1.hasCustomDayCellContent(options)) && (preact.createElement("div", { className: "fc-daygrid-cell-header" },
232
298
  preact.createElement(InnerContent, { elTag: "a", elClasses: [
233
- 'fc-daygrid-day-number',
299
+ 'fc-daygrid-cell-number',
234
300
  isMonthStart && 'fc-daygrid-month-start',
235
- ], elAttrs: Object.assign(Object.assign({}, internal$1.buildNavLinkAttrs(context, date)), { id: state.dayNumberId }) }))) : props.showDayNumber ? (
236
- // for creating correct amount of space (see issue #7162)
237
- preact.createElement("div", { className: "fc-daygrid-day-top", style: { visibility: 'hidden' } },
238
- preact.createElement("a", { className: "fc-daygrid-day-number" }, "\u00A0"))) : undefined,
239
- preact.createElement("div", { className: "fc-daygrid-day-events", ref: props.fgContentElRef },
240
- props.fgContent,
241
- preact.createElement("div", { className: "fc-daygrid-day-bottom", style: { marginTop: props.moreMarginTop } },
242
- preact.createElement(TableCellMoreLink, { allDayDate: date, singlePlacements: props.singlePlacements, moreCnt: props.moreCnt, alignmentElRef: rootElRef, alignGridTop: !props.showDayNumber, extraDateSpan: props.extraDateSpan, dateProfile: props.dateProfile, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, todayRange: props.todayRange }))),
243
- preact.createElement("div", { className: "fc-daygrid-day-bg" }, props.bgContent)))));
301
+ ], elAttrs: internal$1.buildNavLinkAttrs(context, props.date) })))),
302
+ preact.createElement("div", { className: "fc-daygrid-cell-main", style: {
303
+ height: props.fgLiquidHeight ? '' : props.fgHeight
304
+ } }, props.fg),
305
+ preact.createElement("div", { className: "fc-daygrid-cell-footer", style: props.fgLiquidHeight
306
+ ? { position: 'relative', top: props.fgHeight }
307
+ : {} },
308
+ preact.createElement(DayGridMoreLink, { allDayDate: props.date, segs: props.segs, hiddenSegs: props.hiddenSegs, alignmentElRef: this.innerElRef, alignGridTop: !props.showDayNumber, extraDateSpan: props.extraDateSpan, dateProfile: props.dateProfile, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, todayRange: props.todayRange })),
309
+ props.bg))));
310
+ }
311
+ componentDidMount() {
312
+ const innerEl = this.innerElRef.current; // TODO: make dynamic with useEffect
313
+ const headerWrapEl = this.headerWrapElRef.current; // "
314
+ // TODO: only attach this if refs props present
315
+ this.detachInnerHeight = internal$1.watchHeight(innerEl, (height) => {
316
+ internal$1.setRef(this.props.innerHeightRef, height);
317
+ });
318
+ this.detachHeaderHeight = internal$1.watchHeight(headerWrapEl, (height) => {
319
+ internal$1.setRef(this.props.headerHeightRef, height);
320
+ });
321
+ }
322
+ componentWillUnmount() {
323
+ this.detachInnerHeight();
324
+ this.detachHeaderHeight();
325
+ internal$1.setRef(this.props.innerHeightRef, null);
326
+ internal$1.setRef(this.props.headerHeightRef, null);
244
327
  }
245
328
  }
329
+ // Utils
330
+ // -------------------------------------------------------------------------------------------------
246
331
  function renderTopInner(props) {
247
332
  return props.dayNumberText || preact.createElement(preact.Fragment, null, "\u00A0");
248
333
  }
@@ -262,26 +347,43 @@ FullCalendar.DayGrid = (function (exports, core, internal$1, preact) {
262
347
  (dateEnv.getDay(date) === 1 && date.valueOf() < currentEnd.valueOf()));
263
348
  }
264
349
 
265
- function generateSegKey(seg) {
350
+ /*
351
+ Unique per-START-column, good for cataloging by top
352
+ */
353
+ function getSegStartId(seg) {
266
354
  return seg.eventRange.instance.instanceId + ':' + seg.firstCol;
267
355
  }
268
- function generateSegUid(seg) {
269
- return generateSegKey(seg) + ':' + seg.lastCol;
356
+ /*
357
+ Unique per-START-and-END-column, good for cataloging by width/height
358
+ */
359
+ function getSegSpanId(seg) {
360
+ return getSegStartId(seg) + ':' + seg.lastCol;
270
361
  }
271
- function computeFgSegPlacement(segs, // assumed already sorted
272
- dayMaxEvents, dayMaxEventRows, strictOrder, segHeights, maxContentHeight, cells) {
273
- let hierarchy = new DayGridSegHierarchy((segEntry) => {
274
- // TODO: more DRY with generateSegUid
275
- let segUid = segs[segEntry.index].eventRange.instance.instanceId +
276
- ':' + segEntry.span.start +
277
- ':' + (segEntry.span.end - 1);
278
- // if no thickness known, assume 1 (if 0, so small it always fits)
279
- return segHeights[segUid] || 1;
280
- });
281
- hierarchy.allowReslicing = true;
362
+ function computeFgSegVerticals(segs, segHeightMap, // keyed by segSpanId
363
+ cells, topOrigin, maxHeight, strictOrder, dayMaxEvents, dayMaxEventRows) {
364
+ // initialize column-based arrays
365
+ const colCnt = cells.length;
366
+ const hiddenSegsByCol = [];
367
+ const heightsByCol = [];
368
+ for (let col = 0; col < colCnt; col++) {
369
+ hiddenSegsByCol.push([]);
370
+ heightsByCol.push(0);
371
+ }
372
+ // create entries to be given to DayGridSegHierarchy
373
+ const segEntries = segs.map((seg, index) => ({
374
+ index: index,
375
+ seg,
376
+ span: {
377
+ start: seg.firstCol,
378
+ end: seg.lastCol + 1,
379
+ },
380
+ }));
381
+ // configure hierarchy position-generator
382
+ let hierarchy = new DayGridSegHierarchy((segEntry) => (segHeightMap.get(getSegSpanId(segs[segEntry.index]))));
383
+ hierarchy.allowReslicing = false;
282
384
  hierarchy.strictOrder = strictOrder;
283
385
  if (dayMaxEvents === true || dayMaxEventRows === true) {
284
- hierarchy.maxCoord = maxContentHeight;
386
+ hierarchy.maxCoord = maxHeight;
285
387
  hierarchy.hiddenConsumes = true;
286
388
  }
287
389
  else if (typeof dayMaxEvents === 'number') {
@@ -291,172 +393,30 @@ FullCalendar.DayGrid = (function (exports, core, internal$1, preact) {
291
393
  hierarchy.maxStackCnt = dayMaxEventRows;
292
394
  hierarchy.hiddenConsumes = true;
293
395
  }
294
- // create segInputs only for segs with known heights
295
- let segInputs = [];
296
- let unknownHeightSegs = [];
297
- for (let i = 0; i < segs.length; i += 1) {
298
- let seg = segs[i];
299
- let segUid = generateSegUid(seg);
300
- let eventHeight = segHeights[segUid];
301
- if (eventHeight != null) {
302
- segInputs.push({
303
- index: i,
304
- span: {
305
- start: seg.firstCol,
306
- end: seg.lastCol + 1,
307
- },
308
- });
309
- }
310
- else {
311
- unknownHeightSegs.push(seg);
312
- }
313
- }
314
- let hiddenEntries = hierarchy.addSegs(segInputs);
315
- let segRects = hierarchy.toRects();
316
- let { singleColPlacements, multiColPlacements, leftoverMargins } = placeRects(segRects, segs, cells);
317
- let moreCnts = [];
318
- let moreMarginTops = [];
319
- // add segs with unknown heights
320
- for (let seg of unknownHeightSegs) {
321
- multiColPlacements[seg.firstCol].push({
322
- seg,
323
- isVisible: false,
324
- isAbsolute: true,
325
- absoluteTop: 0,
326
- marginTop: 0,
327
- });
328
- for (let col = seg.firstCol; col <= seg.lastCol; col += 1) {
329
- singleColPlacements[col].push({
330
- seg: resliceSeg(seg, col, col + 1, cells),
331
- isVisible: false,
332
- isAbsolute: false,
333
- absoluteTop: 0,
334
- marginTop: 0,
335
- });
336
- }
337
- }
338
- // add the hidden entries
339
- for (let col = 0; col < cells.length; col += 1) {
340
- moreCnts.push(0);
341
- }
342
- for (let hiddenEntry of hiddenEntries) {
343
- let seg = segs[hiddenEntry.index];
344
- let hiddenSpan = hiddenEntry.span;
345
- multiColPlacements[hiddenSpan.start].push({
346
- seg: resliceSeg(seg, hiddenSpan.start, hiddenSpan.end, cells),
347
- isVisible: false,
348
- isAbsolute: true,
349
- absoluteTop: 0,
350
- marginTop: 0,
351
- });
352
- for (let col = hiddenSpan.start; col < hiddenSpan.end; col += 1) {
353
- moreCnts[col] += 1;
354
- singleColPlacements[col].push({
355
- seg: resliceSeg(seg, col, col + 1, cells),
356
- isVisible: false,
357
- isAbsolute: false,
358
- absoluteTop: 0,
359
- marginTop: 0,
360
- });
361
- }
362
- }
363
- // deal with leftover margins
364
- for (let col = 0; col < cells.length; col += 1) {
365
- moreMarginTops.push(leftoverMargins[col]);
366
- }
367
- return { singleColPlacements, multiColPlacements, moreCnts, moreMarginTops };
368
- }
369
- // rects ordered by top coord, then left
370
- function placeRects(allRects, segs, cells) {
371
- let rectsByEachCol = groupRectsByEachCol(allRects, cells.length);
372
- let singleColPlacements = [];
373
- let multiColPlacements = [];
374
- let leftoverMargins = [];
375
- for (let col = 0; col < cells.length; col += 1) {
376
- let rects = rectsByEachCol[col];
377
- // compute all static segs in singlePlacements
378
- let singlePlacements = [];
379
- let currentHeight = 0;
380
- let currentMarginTop = 0;
381
- for (let rect of rects) {
382
- let seg = segs[rect.index];
383
- singlePlacements.push({
384
- seg: resliceSeg(seg, col, col + 1, cells),
385
- isVisible: true,
386
- isAbsolute: false,
387
- absoluteTop: rect.levelCoord,
388
- marginTop: rect.levelCoord - currentHeight,
389
- });
390
- currentHeight = rect.levelCoord + rect.thickness;
391
- }
392
- // compute mixed static/absolute segs in multiPlacements
393
- let multiPlacements = [];
394
- currentHeight = 0;
395
- currentMarginTop = 0;
396
- for (let rect of rects) {
397
- let seg = segs[rect.index];
398
- let isAbsolute = rect.span.end - rect.span.start > 1; // multi-column?
399
- let isFirstCol = rect.span.start === col;
400
- currentMarginTop += rect.levelCoord - currentHeight; // amount of space since bottom of previous seg
401
- currentHeight = rect.levelCoord + rect.thickness; // height will now be bottom of current seg
402
- if (isAbsolute) {
403
- currentMarginTop += rect.thickness;
404
- if (isFirstCol) {
405
- multiPlacements.push({
406
- seg: resliceSeg(seg, rect.span.start, rect.span.end, cells),
407
- isVisible: true,
408
- isAbsolute: true,
409
- absoluteTop: rect.levelCoord,
410
- marginTop: 0,
411
- });
412
- }
413
- }
414
- else if (isFirstCol) {
415
- multiPlacements.push({
416
- seg: resliceSeg(seg, rect.span.start, rect.span.end, cells),
417
- isVisible: true,
418
- isAbsolute: false,
419
- absoluteTop: rect.levelCoord,
420
- marginTop: currentMarginTop, // claim the margin
421
- });
422
- currentMarginTop = 0;
423
- }
396
+ // compile segTops & heightsByCol
397
+ const hiddenSegEntries = hierarchy.addSegs(segEntries);
398
+ const segRects = hierarchy.toRects();
399
+ const segTops = {};
400
+ for (const segRect of segRects) {
401
+ const seg = segs[segRect.index];
402
+ segTops[getSegStartId(seg)] = topOrigin + segRect.levelCoord;
403
+ let { start: col, end: endCol } = segRect.span;
404
+ for (; col < endCol; col++) {
405
+ heightsByCol[col] = Math.max(heightsByCol[col], segRect.levelCoord + segRect.thickness);
424
406
  }
425
- singleColPlacements.push(singlePlacements);
426
- multiColPlacements.push(multiPlacements);
427
- leftoverMargins.push(currentMarginTop);
428
407
  }
429
- return { singleColPlacements, multiColPlacements, leftoverMargins };
430
- }
431
- function groupRectsByEachCol(rects, colCnt) {
432
- let rectsByEachCol = [];
433
- for (let col = 0; col < colCnt; col += 1) {
434
- rectsByEachCol.push([]);
435
- }
436
- for (let rect of rects) {
437
- for (let col = rect.span.start; col < rect.span.end; col += 1) {
438
- rectsByEachCol[col].push(rect);
408
+ // compile # of invisible segs per-column
409
+ for (const hiddenSegEntry of hiddenSegEntries) {
410
+ const { span } = hiddenSegEntry;
411
+ const hiddenSeg = segs[hiddenSegEntry.index];
412
+ for (let col = span.start; col < span.end; col++) {
413
+ hiddenSegsByCol[col].push(hiddenSeg);
439
414
  }
440
415
  }
441
- return rectsByEachCol;
442
- }
443
- function resliceSeg(seg, spanStart, spanEnd, cells) {
444
- if (seg.firstCol === spanStart && seg.lastCol === spanEnd - 1) {
445
- return seg;
446
- }
447
- let eventRange = seg.eventRange;
448
- let origRange = eventRange.range;
449
- let slicedRange = internal$1.intersectRanges(origRange, {
450
- start: cells[spanStart].date,
451
- end: internal$1.addDays(cells[spanEnd - 1].date, 1),
452
- });
453
- return Object.assign(Object.assign({}, seg), { firstCol: spanStart, lastCol: spanEnd - 1, eventRange: {
454
- def: eventRange.def,
455
- ui: Object.assign(Object.assign({}, eventRange.ui), { durationEditable: false }),
456
- instance: eventRange.instance,
457
- range: slicedRange,
458
- }, isStart: seg.isStart && slicedRange.start.valueOf() === origRange.start.valueOf(), isEnd: seg.isEnd && slicedRange.end.valueOf() === origRange.end.valueOf() });
416
+ return [segTops, heightsByCol, hiddenSegsByCol];
459
417
  }
418
+ // DayGridSegHierarchy
419
+ // -------------------------------------------------------------------------------------------------
460
420
  class DayGridSegHierarchy extends internal$1.SegHierarchy {
461
421
  constructor() {
462
422
  super(...arguments);
@@ -504,74 +464,205 @@ FullCalendar.DayGrid = (function (exports, core, internal$1, preact) {
504
464
  }
505
465
  }
506
466
 
507
- class TableRow extends internal$1.DateComponent {
467
+ class DayGridEventHarness extends preact.Component {
508
468
  constructor() {
509
469
  super(...arguments);
510
- this.cellElRefs = new internal$1.RefMap(); // the <td>
511
- this.frameElRefs = new internal$1.RefMap(); // the fc-daygrid-day-frame
512
- this.fgElRefs = new internal$1.RefMap(); // the fc-daygrid-day-events
513
- this.segHarnessRefs = new internal$1.RefMap(); // indexed by "instanceId:firstCol"
470
+ // ref
514
471
  this.rootElRef = preact.createRef();
515
- this.state = {
516
- framePositions: null,
517
- maxContentHeight: null,
518
- segHeights: {},
472
+ }
473
+ render() {
474
+ const { props } = this;
475
+ return (preact.createElement("div", { className: "fc-abs", style: props.style, ref: this.rootElRef }, props.children));
476
+ }
477
+ componentDidMount() {
478
+ const rootEl = this.rootElRef.current; // TODO: make dynamic with useEffect
479
+ this.detachHeight = internal$1.watchHeight(rootEl, (height) => {
480
+ internal$1.setRef(this.props.heightRef, height);
481
+ });
482
+ }
483
+ componentWillUnmount() {
484
+ this.detachHeight();
485
+ }
486
+ }
487
+
488
+ const DEFAULT_WEEK_NUM_FORMAT = internal$1.createFormatter({ week: 'narrow' });
489
+ const COMPACT_CELL_WIDTH = 80;
490
+ class DayGridRow extends internal$1.BaseComponent {
491
+ constructor() {
492
+ super(...arguments);
493
+ this.cellInnerHeightRefMap = new internal$1.RefMap(() => {
494
+ internal$1.afterSize(this.handleInnerHeights);
495
+ });
496
+ this.cellHeaderHeightRefMap = new internal$1.RefMap(() => {
497
+ internal$1.afterSize(this.handleHeaderHeights);
498
+ });
499
+ this.segHeightRefMap = new internal$1.RefMap(() => {
500
+ internal$1.afterSize(this.handleSegHeights);
501
+ });
502
+ this.handleRootEl = (rootEl) => {
503
+ this.rootEl = rootEl;
504
+ internal$1.setRef(this.props.rootElRef, rootEl);
519
505
  };
520
- this.handleResize = (isForced) => {
521
- if (isForced) {
522
- this.updateSizing(true); // isExternal=true
506
+ // Sizing
507
+ // -----------------------------------------------------------------------------------------------
508
+ this.handleHeaderHeights = () => {
509
+ const cellHeaderHeightMap = this.cellHeaderHeightRefMap.current;
510
+ let max = 0;
511
+ for (const height of cellHeaderHeightMap.values()) {
512
+ max = Math.max(max, height);
513
+ }
514
+ if (this.state.headerHeight !== max) {
515
+ this.setState({ headerHeight: max });
523
516
  }
524
517
  };
518
+ this.handleInnerHeights = () => {
519
+ const { props } = this;
520
+ const fgLiquidHeight = props.dayMaxEvents === true || props.dayMaxEventRows === true;
521
+ const cellInnerHeightMap = this.cellInnerHeightRefMap.current;
522
+ let max = 0;
523
+ for (const height of cellInnerHeightMap.values()) {
524
+ max = Math.max(max, height);
525
+ }
526
+ if (fgLiquidHeight) {
527
+ if (this.state.innerHeight !== max) {
528
+ this.setState({ innerHeight: max }); // will trigger event rerender
529
+ }
530
+ }
531
+ else {
532
+ internal$1.setRef(props.innerHeightRef, max);
533
+ }
534
+ };
535
+ this.handleSegHeights = () => {
536
+ this.setState({ segHeightRev: this.segHeightRefMap.rev }); // will trigger event rerender
537
+ };
525
538
  }
526
539
  render() {
527
- let { props, state, context } = this;
528
- let { options } = context;
529
- let colCnt = props.cells.length;
530
- let businessHoursByCol = splitSegsByFirstCol(props.businessHourSegs, colCnt);
531
- let bgEventSegsByCol = splitSegsByFirstCol(props.bgEventSegs, colCnt);
532
- let highlightSegsByCol = splitSegsByFirstCol(this.getHighlightSegs(), colCnt);
533
- let mirrorSegsByCol = splitSegsByFirstCol(this.getMirrorSegs(), colCnt);
534
- let { singleColPlacements, multiColPlacements, moreCnts, moreMarginTops } = computeFgSegPlacement(internal$1.sortEventSegs(props.fgEventSegs, options.eventOrder), props.dayMaxEvents, props.dayMaxEventRows, options.eventOrderStrict, state.segHeights, state.maxContentHeight, props.cells);
535
- let isForcedInvisible = // TODO: messy way to compute this
540
+ const { props, state, context, cellInnerHeightRefMap, cellHeaderHeightRefMap } = this;
541
+ const { cells } = props;
542
+ const { options } = context;
543
+ const weekDate = props.cells[0].date;
544
+ const colCnt = props.cells.length;
545
+ const fgLiquidHeight = props.dayMaxEvents === true || props.dayMaxEventRows === true;
546
+ // TODO: memoize? sort all types of segs?
547
+ const fgEventSegs = internal$1.sortEventSegs(props.fgEventSegs, options.eventOrder);
548
+ // TODO: memoize?
549
+ const fgEventSegsByCol = splitSegsByCol(fgEventSegs, colCnt);
550
+ const bgEventSegsByCol = splitSegsByCol(props.bgEventSegs, colCnt);
551
+ const businessHoursByCol = splitSegsByCol(props.businessHourSegs, colCnt);
552
+ const highlightSegsByCol = splitSegsByCol(this.getHighlightSegs(), colCnt); // TODO: doesn't need standins
553
+ const mirrorSegsByCol = splitSegsByCol(this.getMirrorSegs(), colCnt); // TODO: doesn't need standins
554
+ // TODO: memoize?
555
+ const [segTops, heightsByCol, hiddenSegsByCol] = computeFgSegVerticals(fgEventSegs, this.segHeightRefMap.current, cells, state.headerHeight, (fgLiquidHeight && state.innerHeight != null && state.headerHeight != null)
556
+ ? state.innerHeight - state.headerHeight
557
+ : undefined, options.eventOrderStrict, props.dayMaxEvents, props.dayMaxEventRows);
558
+ const forcedInvisibleMap = // TODO: more convenient/DRY
536
559
  (props.eventDrag && props.eventDrag.affectedInstances) ||
537
560
  (props.eventResize && props.eventResize.affectedInstances) ||
538
561
  {};
539
- return (preact.createElement("tr", { ref: this.rootElRef, role: "row" },
540
- props.renderIntro && props.renderIntro(),
562
+ return (preact.createElement("div", { role: props.cellGroup ? undefined : 'row', className: [
563
+ 'fc-daygrid-row',
564
+ props.forceVSpacing
565
+ ? 'fc-daygrid-row-spacious'
566
+ : props.compact
567
+ ? 'fc-daygrid-row-compact'
568
+ : '',
569
+ props.cellGroup ? 'fc-flex-row' : 'fc-row',
570
+ 'fc-rel',
571
+ props.className || '',
572
+ ].join(' '), style: {
573
+ minHeight: props.minHeight,
574
+ }, ref: this.handleRootEl },
541
575
  props.cells.map((cell, col) => {
542
- let normalFgNodes = this.renderFgSegs(col, props.forPrint ? singleColPlacements[col] : multiColPlacements[col], props.todayRange, isForcedInvisible);
543
- let mirrorFgNodes = this.renderFgSegs(col, buildMirrorPlacements(mirrorSegsByCol[col], multiColPlacements), props.todayRange, {}, Boolean(props.eventDrag), Boolean(props.eventResize), false);
544
- return (preact.createElement(TableCell, { key: cell.key, elRef: this.cellElRefs.createRef(cell.key), innerElRef: this.frameElRefs.createRef(cell.key) /* FF <td> problem, but okay to use for left/right. TODO: rename prop */, dateProfile: props.dateProfile, date: cell.date, showDayNumber: props.showDayNumbers, showWeekNumber: props.showWeekNumbers && col === 0, forceDayTop: props.showWeekNumbers /* even displaying weeknum for row, not necessarily day */, todayRange: props.todayRange, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, extraRenderProps: cell.extraRenderProps, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames, extraDateSpan: cell.extraDateSpan, moreCnt: moreCnts[col], moreMarginTop: moreMarginTops[col], singlePlacements: singleColPlacements[col], fgContentElRef: this.fgElRefs.createRef(cell.key), fgContent: ( // Fragment scopes the keys
545
- preact.createElement(preact.Fragment, null,
576
+ const normalFgNodes = this.renderFgSegs(fgEventSegsByCol[col], segTops, props.todayRange, forcedInvisibleMap);
577
+ const mirrorFgNodes = this.renderFgSegs(mirrorSegsByCol[col], segTops, props.todayRange, {}, // forcedInvisibleMap
578
+ Boolean(props.eventDrag), Boolean(props.eventResize), false);
579
+ return (preact.createElement(DayGridCell, { key: cell.key, dateProfile: props.dateProfile, todayRange: props.todayRange, date: cell.date, showDayNumber: props.showDayNumbers,
580
+ // content
581
+ segs: fgEventSegsByCol[col], hiddenSegs: hiddenSegsByCol[col], fgLiquidHeight: fgLiquidHeight, fg: (preact.createElement(preact.Fragment, null,
546
582
  preact.createElement(preact.Fragment, null, normalFgNodes),
547
- preact.createElement(preact.Fragment, null, mirrorFgNodes))), bgContent: ( // Fragment scopes the keys
548
- preact.createElement(preact.Fragment, null,
583
+ preact.createElement(preact.Fragment, null, mirrorFgNodes))), bg: (preact.createElement(preact.Fragment, null,
549
584
  this.renderFillSegs(highlightSegsByCol[col], 'highlight'),
550
585
  this.renderFillSegs(businessHoursByCol[col], 'non-business'),
551
- this.renderFillSegs(bgEventSegsByCol[col], 'bg-event'))), minHeight: props.cellMinHeight }));
552
- })));
586
+ this.renderFillSegs(bgEventSegsByCol[col], 'bg-event'))), eventDrag: props.eventDrag, eventResize: props.eventResize, eventSelection: props.eventSelection,
587
+ // render hooks
588
+ extraRenderProps: cell.extraRenderProps, extraDateSpan: cell.extraDateSpan, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames,
589
+ // dimensions
590
+ fgHeight: heightsByCol[col], width: props.colWidth,
591
+ // refs
592
+ innerHeightRef: cellInnerHeightRefMap.createRef(cell.key), headerHeightRef: cellHeaderHeightRefMap.createRef(cell.key) }));
593
+ }),
594
+ props.showWeekNumbers && (preact.createElement(internal$1.WeekNumberContainer, { elTag: "a", elClasses: ['fc-daygrid-week-number'], elAttrs: internal$1.buildNavLinkAttrs(context, weekDate, 'week'), date: weekDate, defaultFormat: DEFAULT_WEEK_NUM_FORMAT }))));
595
+ }
596
+ renderFgSegs(segs, segTops, todayRange, forcedInvisibleMap, isDragging, isResizing, isDateSelecting) {
597
+ const { props, context, segHeightRefMap } = this;
598
+ const { isRtl } = context;
599
+ const { colWidth, eventSelection } = props;
600
+ const colCnt = props.cells.length;
601
+ const defaultDisplayEventEnd = props.cells.length === 1;
602
+ const isMirror = isDragging || isResizing || isDateSelecting;
603
+ const nodes = [];
604
+ for (const seg of segs) {
605
+ const { left, right, width } = computeHorizontalsFromSeg(seg, colWidth, colCnt, isRtl);
606
+ // TODO: optimize ID creation? all related
607
+ const { instanceId } = seg.eventRange.instance;
608
+ const segSpanId = getSegSpanId(seg);
609
+ const segStartId = getSegStartId(seg);
610
+ const top = segTops[segStartId];
611
+ const isVisible = !seg.isStandin &&
612
+ top != null &&
613
+ !forcedInvisibleMap[instanceId];
614
+ /*
615
+ TODO: is this comment still relevant? vvvvvvvv
616
+ known bug: events that are force to be list-item but span multiple days still take up space in later columns
617
+ todo: in print view, for multi-day events, don't display title within non-start/end segs
618
+ */
619
+ nodes.push(preact.createElement(DayGridEventHarness, { key: segSpanId, style: {
620
+ visibility: isVisible ? '' : 'hidden',
621
+ top,
622
+ left,
623
+ right,
624
+ width,
625
+ }, heightRef: (isMirror || seg.isStandin)
626
+ ? null
627
+ : segHeightRefMap.createRef(segSpanId) }, hasListItemDisplay(seg) ? (preact.createElement(DayGridListEvent, Object.assign({ seg: seg, isDragging: isDragging, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, internal$1.getSegMeta(seg, todayRange)))) : (preact.createElement(DayGridBlockEvent, Object.assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, internal$1.getSegMeta(seg, todayRange))))));
628
+ }
629
+ return nodes;
553
630
  }
554
- componentDidMount() {
555
- this.updateSizing(true);
556
- this.context.addResizeHandler(this.handleResize);
631
+ renderFillSegs(segs, fillType) {
632
+ const { props, context } = this;
633
+ const { isRtl } = context;
634
+ const { todayRange, colWidth } = props;
635
+ const colCnt = props.cells.length;
636
+ const nodes = [];
637
+ for (const seg of segs) {
638
+ const { left, right, width } = computeHorizontalsFromSeg(seg, colWidth, colCnt, isRtl);
639
+ const isVisible = !seg.isStandin;
640
+ nodes.push(preact.createElement("div", { key: internal$1.buildEventRangeKey(seg.eventRange), className: "fc-fill-y", style: {
641
+ visibility: isVisible ? '' : 'hidden',
642
+ left,
643
+ right,
644
+ width,
645
+ } }, fillType === 'bg-event' ?
646
+ preact.createElement(internal$1.BgEvent, Object.assign({ seg: seg }, internal$1.getSegMeta(seg, todayRange))) :
647
+ internal$1.renderFill(fillType)));
648
+ }
649
+ return preact.createElement(preact.Fragment, {}, ...nodes);
557
650
  }
558
- componentDidUpdate(prevProps, prevState) {
559
- let currentProps = this.props;
560
- this.updateSizing(!internal$1.isPropsEqual(prevProps, currentProps));
651
+ // Sizing
652
+ // -----------------------------------------------------------------------------------------------
653
+ componentDidMount() {
654
+ const { rootEl } = this; // TODO: make dynamic with useEffect
655
+ this.disconnectHeight = internal$1.watchHeight(rootEl, (contentHeight) => {
656
+ internal$1.setRef(this.props.heightRef, contentHeight);
657
+ });
561
658
  }
562
659
  componentWillUnmount() {
563
- this.context.removeResizeHandler(this.handleResize);
564
- }
565
- getHighlightSegs() {
566
- let { props } = this;
567
- if (props.eventDrag && props.eventDrag.segs.length) { // messy check
568
- return props.eventDrag.segs;
569
- }
570
- if (props.eventResize && props.eventResize.segs.length) { // messy check
571
- return props.eventResize.segs;
572
- }
573
- return props.dateSelectionSegs;
660
+ this.disconnectHeight();
661
+ internal$1.setRef(this.props.heightRef, null);
662
+ internal$1.setRef(this.props.innerHeightRef, null);
574
663
  }
664
+ // Utils
665
+ // -----------------------------------------------------------------------------------------------
575
666
  getMirrorSegs() {
576
667
  let { props } = this;
577
668
  if (props.eventResize && props.eventResize.segs.length) { // messy check
@@ -579,372 +670,428 @@ FullCalendar.DayGrid = (function (exports, core, internal$1, preact) {
579
670
  }
580
671
  return [];
581
672
  }
582
- renderFgSegs(col, segPlacements, todayRange, isForcedInvisible, isDragging, isResizing, isDateSelecting) {
583
- let { context } = this;
584
- let { eventSelection } = this.props;
585
- let { framePositions } = this.state;
586
- let defaultDisplayEventEnd = this.props.cells.length === 1; // colCnt === 1
587
- let isMirror = isDragging || isResizing || isDateSelecting;
588
- let nodes = [];
589
- if (framePositions) {
590
- for (let placement of segPlacements) {
591
- let { seg } = placement;
592
- let { instanceId } = seg.eventRange.instance;
593
- let isVisible = placement.isVisible && !isForcedInvisible[instanceId];
594
- let isAbsolute = placement.isAbsolute;
595
- let left = '';
596
- let right = '';
597
- if (isAbsolute) {
598
- if (context.isRtl) {
599
- right = 0;
600
- left = framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol];
601
- }
602
- else {
603
- left = 0;
604
- right = framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol];
605
- }
606
- }
607
- /*
608
- known bug: events that are force to be list-item but span multiple days still take up space in later columns
609
- todo: in print view, for multi-day events, don't display title within non-start/end segs
610
- */
611
- nodes.push(preact.createElement("div", { className: 'fc-daygrid-event-harness' + (isAbsolute ? ' fc-daygrid-event-harness-abs' : ''), key: generateSegKey(seg), ref: isMirror ? null : this.segHarnessRefs.createRef(generateSegUid(seg)), style: {
612
- visibility: isVisible ? '' : 'hidden',
613
- marginTop: isAbsolute ? '' : placement.marginTop,
614
- top: isAbsolute ? placement.absoluteTop : '',
615
- left,
616
- right,
617
- } }, hasListItemDisplay(seg) ? (preact.createElement(TableListItemEvent, Object.assign({ seg: seg, isDragging: isDragging, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, internal$1.getSegMeta(seg, todayRange)))) : (preact.createElement(TableBlockEvent, Object.assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, internal$1.getSegMeta(seg, todayRange))))));
618
- }
619
- }
620
- return nodes;
621
- }
622
- renderFillSegs(segs, fillType) {
623
- let { isRtl } = this.context;
624
- let { todayRange } = this.props;
625
- let { framePositions } = this.state;
626
- let nodes = [];
627
- if (framePositions) {
628
- for (let seg of segs) {
629
- let leftRightCss = isRtl ? {
630
- right: 0,
631
- left: framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol],
632
- } : {
633
- left: 0,
634
- right: framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol],
635
- };
636
- nodes.push(preact.createElement("div", { key: internal$1.buildEventRangeKey(seg.eventRange), className: "fc-daygrid-bg-harness", style: leftRightCss }, fillType === 'bg-event' ?
637
- preact.createElement(internal$1.BgEvent, Object.assign({ seg: seg }, internal$1.getSegMeta(seg, todayRange))) :
638
- internal$1.renderFill(fillType)));
639
- }
640
- }
641
- return preact.createElement(preact.Fragment, {}, ...nodes);
642
- }
643
- updateSizing(isExternalSizingChange) {
644
- let { props, state, frameElRefs } = this;
645
- if (!props.forPrint &&
646
- props.clientWidth !== null // positioning ready?
647
- ) {
648
- if (isExternalSizingChange) {
649
- let frameEls = props.cells.map((cell) => frameElRefs.currentMap[cell.key]);
650
- if (frameEls.length) {
651
- let originEl = this.rootElRef.current;
652
- let newPositionCache = new internal$1.PositionCache(originEl, frameEls, true, // isHorizontal
653
- false);
654
- if (!state.framePositions || !state.framePositions.similarTo(newPositionCache)) {
655
- this.setState({
656
- framePositions: new internal$1.PositionCache(originEl, frameEls, true, // isHorizontal
657
- false),
658
- });
659
- }
660
- }
661
- }
662
- const oldSegHeights = this.state.segHeights;
663
- const newSegHeights = this.querySegHeights();
664
- const limitByContentHeight = props.dayMaxEvents === true || props.dayMaxEventRows === true;
665
- this.safeSetState({
666
- // HACK to prevent oscillations of events being shown/hidden from max-event-rows
667
- // Essentially, once you compute an element's height, never null-out.
668
- // TODO: always display all events, as visibility:hidden?
669
- segHeights: Object.assign(Object.assign({}, oldSegHeights), newSegHeights),
670
- maxContentHeight: limitByContentHeight ? this.computeMaxContentHeight() : null,
671
- });
672
- }
673
- }
674
- querySegHeights() {
675
- let segElMap = this.segHarnessRefs.currentMap;
676
- let segHeights = {};
677
- // get the max height amongst instance segs
678
- for (let segUid in segElMap) {
679
- let height = Math.round(segElMap[segUid].getBoundingClientRect().height);
680
- segHeights[segUid] = Math.max(segHeights[segUid] || 0, height);
673
+ getHighlightSegs() {
674
+ let { props } = this;
675
+ if (props.eventDrag && props.eventDrag.segs.length) { // messy check
676
+ return props.eventDrag.segs;
681
677
  }
682
- return segHeights;
683
- }
684
- computeMaxContentHeight() {
685
- let firstKey = this.props.cells[0].key;
686
- let cellEl = this.cellElRefs.currentMap[firstKey];
687
- let fcContainerEl = this.fgElRefs.currentMap[firstKey];
688
- return cellEl.getBoundingClientRect().bottom - fcContainerEl.getBoundingClientRect().top;
689
- }
690
- getCellEls() {
691
- let elMap = this.cellElRefs.currentMap;
692
- return this.props.cells.map((cell) => elMap[cell.key]);
693
- }
694
- }
695
- TableRow.addStateEquality({
696
- segHeights: internal$1.isPropsEqual,
697
- });
698
- function buildMirrorPlacements(mirrorSegs, colPlacements) {
699
- if (!mirrorSegs.length) {
700
- return [];
701
- }
702
- let topsByInstanceId = buildAbsoluteTopHash(colPlacements); // TODO: cache this at first render?
703
- return mirrorSegs.map((seg) => ({
704
- seg,
705
- isVisible: true,
706
- isAbsolute: true,
707
- absoluteTop: topsByInstanceId[seg.eventRange.instance.instanceId],
708
- marginTop: 0,
709
- }));
710
- }
711
- function buildAbsoluteTopHash(colPlacements) {
712
- let topsByInstanceId = {};
713
- for (let placements of colPlacements) {
714
- for (let placement of placements) {
715
- topsByInstanceId[placement.seg.eventRange.instance.instanceId] = placement.absoluteTop;
678
+ if (props.eventResize && props.eventResize.segs.length) { // messy check
679
+ return props.eventResize.segs;
716
680
  }
681
+ return props.dateSelectionSegs;
717
682
  }
718
- return topsByInstanceId;
719
683
  }
720
684
 
721
- class TableRows extends internal$1.DateComponent {
685
+ class DayGridRows extends internal$1.DateComponent {
722
686
  constructor() {
723
687
  super(...arguments);
688
+ // memo
724
689
  this.splitBusinessHourSegs = internal$1.memoize(splitSegsByRow);
725
690
  this.splitBgEventSegs = internal$1.memoize(splitSegsByRow);
726
691
  this.splitFgEventSegs = internal$1.memoize(splitSegsByRow);
727
692
  this.splitDateSelectionSegs = internal$1.memoize(splitSegsByRow);
728
693
  this.splitEventDrag = internal$1.memoize(splitInteractionByRow);
729
694
  this.splitEventResize = internal$1.memoize(splitInteractionByRow);
730
- this.rowRefs = new internal$1.RefMap();
695
+ // internal
696
+ this.rowHeightRefMap = new internal$1.RefMap((height, key) => {
697
+ // HACKy way of syncing RefMap results with prop
698
+ const { rowHeightRefMap } = this.props;
699
+ if (rowHeightRefMap) {
700
+ rowHeightRefMap.handleValue(height, key);
701
+ }
702
+ });
703
+ this.handleRootEl = (rootEl) => {
704
+ this.rootEl = rootEl;
705
+ if (rootEl) {
706
+ this.context.registerInteractiveComponent(this, {
707
+ el: rootEl,
708
+ isHitComboAllowed: this.props.isHitComboAllowed,
709
+ });
710
+ }
711
+ else {
712
+ this.context.unregisterInteractiveComponent(this);
713
+ }
714
+ };
731
715
  }
732
716
  render() {
733
- let { props, context } = this;
734
- let rowCnt = props.cells.length;
735
- let businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, rowCnt);
736
- let bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, rowCnt);
717
+ let { props, state, context, rowHeightRefMap } = this;
718
+ let { options } = context;
719
+ let rowCnt = props.cellRows.length;
737
720
  let fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, rowCnt);
721
+ let bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, rowCnt);
722
+ let businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, rowCnt);
738
723
  let dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, rowCnt);
739
724
  let eventDragByRow = this.splitEventDrag(props.eventDrag, rowCnt);
740
725
  let eventResizeByRow = this.splitEventResize(props.eventResize, rowCnt);
741
- // for DayGrid view with many rows, force a min-height on cells so doesn't appear squished
742
- // choose 7 because a month view will have max 6 rows
743
- let cellMinHeight = (rowCnt >= 7 && props.clientWidth) ?
744
- props.clientWidth / context.options.aspectRatio / 6 :
745
- null;
746
- return (preact.createElement(internal$1.NowTimer, { unit: "day" }, (nowDate, todayRange) => (preact.createElement(preact.Fragment, null, props.cells.map((cells, row) => (preact.createElement(TableRow, { ref: this.rowRefs.createRef(row), key: cells.length
747
- ? cells[0].date.toISOString() /* best? or put key on cell? or use diff formatter? */
748
- : row // in case there are no cells (like when resource view is loading)
749
- , showDayNumbers: rowCnt > 1, showWeekNumbers: props.showWeekNumbers, todayRange: todayRange, dateProfile: props.dateProfile, cells: cells, renderIntro: props.renderRowIntro, businessHourSegs: businessHourSegsByRow[row], eventSelection: props.eventSelection, bgEventSegs: bgEventSegsByRow[row].filter(isSegAllDay) /* hack */, fgEventSegs: fgEventSegsByRow[row], dateSelectionSegs: dateSelectionSegsByRow[row], eventDrag: eventDragByRow[row], eventResize: eventResizeByRow[row], dayMaxEvents: props.dayMaxEvents, dayMaxEventRows: props.dayMaxEventRows, clientWidth: props.clientWidth, clientHeight: props.clientHeight, cellMinHeight: cellMinHeight, forPrint: props.forPrint })))))));
726
+ // whether the ROW should expand in height
727
+ // (not to be confused with whether the fg events within the row should be molded by height of row)
728
+ let isHeightAuto = internal$1.getIsHeightAuto(options);
729
+ // maintain at least aspectRatio for cells?
730
+ let rowMinHeight = (state.width != null && (rowCnt >= 7 || // TODO: better way to infer if across single-month boundary
731
+ isHeightAuto)) ? state.width / context.options.aspectRatio / 6 // okay to hardcode 6 (weeks) ?
732
+ : null;
733
+ return (preact.createElement("div", { className: 'fc-grow fc-flex-column', style: { width: props.width }, ref: this.handleRootEl }, props.cellRows.map((cells, row) => (preact.createElement(DayGridRow, { key: cells[0].key, dateProfile: props.dateProfile, todayRange: props.todayRange, cells: cells, showDayNumbers: rowCnt > 1, showWeekNumbers: options.weekNumbers, forPrint: props.forPrint, compact: state.width != null && (state.width / cells.length) < COMPACT_CELL_WIDTH,
734
+ // if not auto-height, distribute height of container somewhat evently to rows
735
+ // (treat all as zero, distribute height, then ensure min-heights -- the inner content height)
736
+ className: isHeightAuto ? '' : 'fc-grow fc-basis0',
737
+ // content
738
+ 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: options.dayMaxEvents, dayMaxEventRows: options.dayMaxEventRows,
739
+ // dimensions
740
+ colWidth: props.colWidth, minHeight: rowMinHeight,
741
+ // refs
742
+ heightRef: rowHeightRefMap.createRef(cells[0].key) })))));
750
743
  }
751
744
  componentDidMount() {
752
- this.registerInteractiveComponent();
753
- }
754
- componentDidUpdate() {
755
- // for if started with zero cells
756
- this.registerInteractiveComponent();
757
- }
758
- registerInteractiveComponent() {
759
- if (!this.rootEl) {
760
- // HACK: need a daygrid wrapper parent to do positioning
761
- // NOTE: a daygrid resource view w/o resources can have zero cells
762
- const firstCellEl = this.rowRefs.currentMap[0].getCellEls()[0];
763
- const rootEl = firstCellEl ? firstCellEl.closest('.fc-daygrid-body') : null;
764
- if (rootEl) {
765
- this.rootEl = rootEl;
766
- this.context.registerInteractiveComponent(this, {
767
- el: rootEl,
768
- isHitComboAllowed: this.props.isHitComboAllowed,
769
- });
770
- }
771
- }
745
+ this.unwatchWidth = internal$1.watchWidth(this.rootEl, (width) => {
746
+ this.setState({ width });
747
+ });
772
748
  }
773
749
  componentWillUnmount() {
774
- if (this.rootEl) {
775
- this.context.unregisterInteractiveComponent(this);
776
- this.rootEl = null;
777
- }
750
+ this.unwatchWidth();
778
751
  }
779
752
  // Hit System
780
- // ----------------------------------------------------------------------------------------------------
781
- prepareHits() {
782
- this.rowPositions = new internal$1.PositionCache(this.rootEl, this.rowRefs.collect().map((rowObj) => rowObj.getCellEls()[0]), // first cell el in each row. TODO: not optimal
783
- false, true);
784
- this.colPositions = new internal$1.PositionCache(this.rootEl, this.rowRefs.currentMap[0].getCellEls(), // cell els in first row
785
- true, // horizontal
786
- false);
787
- }
788
- queryHit(positionLeft, positionTop) {
789
- let { colPositions, rowPositions } = this;
790
- let col = colPositions.leftToIndex(positionLeft);
791
- let row = rowPositions.topToIndex(positionTop);
792
- if (row != null && col != null) {
793
- let cell = this.props.cells[row][col];
794
- return {
795
- dateProfile: this.props.dateProfile,
796
- dateSpan: Object.assign({ range: this.getCellRange(row, col), allDay: true }, cell.extraDateSpan),
797
- dayEl: this.getCellEl(row, col),
798
- rect: {
799
- left: colPositions.lefts[col],
800
- right: colPositions.rights[col],
801
- top: rowPositions.tops[row],
802
- bottom: rowPositions.bottoms[row],
803
- },
804
- layer: 0,
805
- };
806
- }
807
- return null;
808
- }
809
- getCellEl(row, col) {
810
- return this.rowRefs.currentMap[row].getCellEls()[col]; // TODO: not optimal
811
- }
812
- getCellRange(row, col) {
813
- let start = this.props.cells[row][col].date;
814
- let end = internal$1.addDays(start, 1);
815
- return { start, end };
753
+ // -----------------------------------------------------------------------------------------------
754
+ queryHit(positionLeft, positionTop, elWidth) {
755
+ const { props, context } = this;
756
+ const colCnt = props.cellRows[0].length;
757
+ const { col, left, right } = computeColFromPosition(positionLeft, elWidth, props.colWidth, colCnt, context.isRtl);
758
+ const { row, top, bottom } = computeRowFromPosition(positionTop, props.cellRows, this.rowHeightRefMap.current);
759
+ const cell = props.cellRows[row][col];
760
+ const cellStartDate = cell.date;
761
+ const cellEndDate = internal$1.addDays(cellStartDate, 1);
762
+ return {
763
+ dateProfile: props.dateProfile,
764
+ dateSpan: Object.assign({ range: {
765
+ start: cellStartDate,
766
+ end: cellEndDate,
767
+ }, allDay: true }, cell.extraDateSpan),
768
+ // HACK. TODO: This is expensive to do every hit-query
769
+ dayEl: getCellEl(getRowEl(this.rootEl, row), col),
770
+ rect: {
771
+ left,
772
+ right,
773
+ top,
774
+ bottom,
775
+ },
776
+ layer: 0,
777
+ };
816
778
  }
817
779
  }
780
+ // Utils
781
+ // -------------------------------------------------------------------------------------------------
818
782
  function isSegAllDay(seg) {
819
783
  return seg.eventRange.def.allDay;
820
784
  }
821
785
 
822
- class Table extends internal$1.DateComponent {
786
+ class HeaderRow extends internal$1.BaseComponent {
787
+ render() {
788
+ const { props } = this;
789
+ return (preact.createElement("div", { role: props.cellGroup ? undefined : 'row', className: [
790
+ props.cellGroup ? 'fc-flex-row' : 'fc-row',
791
+ props.className || '',
792
+ ].join(' ') }, props.cells.map((cell) => (preact.createElement(preact.Fragment, { key: props.getHeaderModelKey(cell) }, props.renderHeaderContent(cell, props.tierNum, undefined, // innerHeightRef
793
+ props.colWidth))))));
794
+ }
795
+ }
796
+
797
+ function DayGridHeader(props) {
798
+ return (preact.createElement("div", { className: [
799
+ 'fc-rowgroup',
800
+ 'fc-content-box',
801
+ ...(props.extraClassNames || []),
802
+ ].join(' '), style: {
803
+ width: props.width,
804
+ paddingLeft: props.paddingLeft,
805
+ paddingRight: props.paddingRight,
806
+ } }, props.headerTiers.map((cells, tierNum) => (preact.createElement(HeaderRow, { key: tierNum, tierNum: tierNum, cells: cells, renderHeaderContent: props.renderHeaderContent, getHeaderModelKey: props.getHeaderModelKey, colWidth: props.colWidth })))));
807
+ }
808
+
809
+ class DayGridLayoutNormal extends internal$1.BaseComponent {
823
810
  constructor() {
824
811
  super(...arguments);
825
- this.elRef = preact.createRef();
826
- this.needsScrollReset = false;
812
+ this.handleScroller = (scroller) => {
813
+ internal$1.setRef(this.props.scrollerRef, scroller);
814
+ };
815
+ this.handleLeftScrollbarWidth = (leftScrollbarWidth) => {
816
+ this.setState({ leftScrollbarWidth });
817
+ };
818
+ this.handleRightScrollbarWidth = (rightScrollbarWidth) => {
819
+ this.setState({ rightScrollbarWidth });
820
+ };
827
821
  }
828
822
  render() {
829
- let { props } = this;
830
- let { dayMaxEventRows, dayMaxEvents, expandRows } = props;
831
- let limitViaBalanced = dayMaxEvents === true || dayMaxEventRows === true;
832
- // if rows can't expand to fill fixed height, can't do balanced-height event limit
833
- // TODO: best place to normalize these options?
834
- if (limitViaBalanced && !expandRows) {
835
- limitViaBalanced = false;
836
- dayMaxEventRows = null;
837
- dayMaxEvents = null;
838
- }
839
- let classNames = [
840
- 'fc-daygrid-body',
841
- limitViaBalanced ? 'fc-daygrid-body-balanced' : 'fc-daygrid-body-unbalanced',
842
- expandRows ? '' : 'fc-daygrid-body-natural', // will height of one row depend on the others?
843
- ];
844
- return (preact.createElement("div", { ref: this.elRef, className: classNames.join(' '), style: {
845
- // these props are important to give this wrapper correct dimensions for interactions
846
- // TODO: if we set it here, can we avoid giving to inner tables?
847
- width: props.clientWidth,
848
- minWidth: props.tableMinWidth,
849
- } },
850
- preact.createElement("table", { role: "presentation", className: "fc-scrollgrid-sync-table", style: {
851
- width: props.clientWidth,
852
- minWidth: props.tableMinWidth,
853
- height: expandRows ? props.clientHeight : '',
854
- } },
855
- props.colGroupNode,
856
- preact.createElement("tbody", { role: "presentation" },
857
- preact.createElement(TableRows, { dateProfile: props.dateProfile, cells: props.cells, renderRowIntro: props.renderRowIntro, showWeekNumbers: props.showWeekNumbers, clientWidth: props.clientWidth, clientHeight: props.clientHeight, businessHourSegs: props.businessHourSegs, bgEventSegs: props.bgEventSegs, fgEventSegs: props.fgEventSegs, dateSelectionSegs: props.dateSelectionSegs, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, dayMaxEvents: dayMaxEvents, dayMaxEventRows: dayMaxEventRows, forPrint: props.forPrint, isHitComboAllowed: props.isHitComboAllowed })))));
823
+ const { props, state, context } = this;
824
+ const { options } = context;
825
+ const verticalScrollbars = !props.forPrint && !internal$1.getIsHeightAuto(options);
826
+ const stickyHeaderDates = !props.forPrint && internal$1.getStickyHeaderDates(options);
827
+ return (preact.createElement(preact.Fragment, null,
828
+ options.dayHeaders && (preact.createElement(DayGridHeader, { headerTiers: props.headerTiers, renderHeaderContent: props.renderHeaderContent, getHeaderModelKey: props.getHeaderModelKey,
829
+ // render hooks
830
+ extraClassNames: [
831
+ 'fc-daygrid-header',
832
+ stickyHeaderDates ? 'fc-sticky-header' : '',
833
+ ],
834
+ // dimensions
835
+ paddingLeft: state.leftScrollbarWidth, paddingRight: state.rightScrollbarWidth })),
836
+ preact.createElement(internal$1.Scroller, { vertical: verticalScrollbars, leftScrollbarWidthRef: this.handleLeftScrollbarWidth, rightScrollbarWidthRef: this.handleRightScrollbarWidth, elClassNames: [
837
+ 'fc-daygrid-body',
838
+ 'fc-rowgroup',
839
+ 'fc-flex-column',
840
+ verticalScrollbars ? 'fc-liquid' : '',
841
+ ], ref: this.handleScroller },
842
+ preact.createElement(DayGridRows // .fc-grow
843
+ , { dateProfile: props.dateProfile, todayRange: props.todayRange, cellRows: props.cellRows, forPrint: props.forPrint, isHitComboAllowed: props.isHitComboAllowed,
844
+ // content
845
+ fgEventSegs: props.fgEventSegs, bgEventSegs: props.bgEventSegs, businessHourSegs: props.businessHourSegs, dateSelectionSegs: props.dateSelectionSegs, eventDrag: props.eventDrag, eventResize: props.eventResize, eventSelection: props.eventSelection,
846
+ // refs
847
+ rowHeightRefMap: props.rowHeightRefMap }))));
858
848
  }
859
- componentDidMount() {
860
- this.requestScrollReset();
849
+ }
850
+
851
+ class DayGridLayoutPannable extends internal$1.BaseComponent {
852
+ constructor() {
853
+ super(...arguments);
854
+ this.headerScrollerRef = preact.createRef();
855
+ this.bodyScrollerRef = preact.createRef();
856
+ this.footerScrollerRef = preact.createRef();
857
+ // Sizing
858
+ // -----------------------------------------------------------------------------------------------
859
+ this.handleWidth = (width) => {
860
+ this.setState({ width });
861
+ };
862
+ this.handleLeftScrollbarWidth = (leftScrollbarWidth) => {
863
+ this.setState({ leftScrollbarWidth });
864
+ };
865
+ this.handleRightScrollbarWidth = (rightScrollbarWidth) => {
866
+ this.setState({ rightScrollbarWidth });
867
+ };
861
868
  }
862
- componentDidUpdate(prevProps) {
863
- if (prevProps.dateProfile !== this.props.dateProfile) {
864
- this.requestScrollReset();
865
- }
866
- else {
867
- this.flushScrollReset();
868
- }
869
+ render() {
870
+ const { props, state, context } = this;
871
+ const { options } = context;
872
+ const verticalScrollbars = !props.forPrint && !internal$1.getIsHeightAuto(options);
873
+ const stickyHeaderDates = !props.forPrint && internal$1.getStickyHeaderDates(options);
874
+ const stickyFooterScrollbar = !props.forPrint && internal$1.getStickyFooterScrollbar(options);
875
+ const colCnt = props.cellRows[0].length;
876
+ const [canvasWidth, colWidth] = computeColWidth(colCnt, props.dayMinWidth, state.width);
877
+ return (preact.createElement(preact.Fragment, null,
878
+ options.dayHeaders && (preact.createElement(internal$1.Scroller, { horizontal: true, hideScrollbars: true, elClassNames: [
879
+ 'fc-daygrid-header',
880
+ 'fc-rowgroup',
881
+ stickyHeaderDates ? 'fc-sticky-header' : ''
882
+ ], ref: this.headerScrollerRef },
883
+ preact.createElement(DayGridHeader, { headerTiers: props.headerTiers, renderHeaderContent: props.renderHeaderContent, getHeaderModelKey: props.getHeaderModelKey,
884
+ // dimensions
885
+ colWidth: colWidth, width: canvasWidth, paddingLeft: state.leftScrollbarWidth, paddingRight: state.rightScrollbarWidth }))),
886
+ preact.createElement(internal$1.Scroller, { vertical: verticalScrollbars, horizontal: true, hideScrollbars: stickyFooterScrollbar, widthRef: this.handleWidth, leftScrollbarWidthRef: this.handleLeftScrollbarWidth, rightScrollbarWidthRef: this.handleRightScrollbarWidth, elClassNames: [
887
+ 'fc-daygrid-body',
888
+ 'fc-rowgroup',
889
+ 'fc-flex-column',
890
+ verticalScrollbars ? 'fc-liquid' : '',
891
+ ], ref: this.bodyScrollerRef },
892
+ preact.createElement(DayGridRows // .fc-grow
893
+ , { dateProfile: props.dateProfile, todayRange: props.todayRange, cellRows: props.cellRows, forPrint: props.forPrint, isHitComboAllowed: props.isHitComboAllowed,
894
+ // content
895
+ fgEventSegs: props.fgEventSegs, bgEventSegs: props.bgEventSegs, businessHourSegs: props.businessHourSegs, dateSelectionSegs: props.dateSelectionSegs, eventDrag: props.eventDrag, eventResize: props.eventResize, eventSelection: props.eventSelection,
896
+ // dimensions
897
+ colWidth: colWidth, width: canvasWidth,
898
+ // refs
899
+ rowHeightRefMap: props.rowHeightRefMap })),
900
+ Boolean(stickyFooterScrollbar) && (preact.createElement(internal$1.Scroller, { ref: this.footerScrollerRef, horizontal: true, elClassNames: ['fc-sticky-footer'], elStyle: {
901
+ marginTop: '-1px', // HACK
902
+ } },
903
+ preact.createElement("div", { style: {
904
+ width: canvasWidth,
905
+ height: '1px', // HACK
906
+ } })))));
869
907
  }
870
- requestScrollReset() {
871
- this.needsScrollReset = true;
872
- this.flushScrollReset();
873
- }
874
- flushScrollReset() {
875
- if (this.needsScrollReset &&
876
- this.props.clientWidth // sizes computed?
877
- ) {
878
- const subjectEl = getScrollSubjectEl(this.elRef.current, this.props.dateProfile);
879
- if (subjectEl) {
880
- const originEl = subjectEl.closest('.fc-daygrid-body');
881
- const scrollEl = originEl.closest('.fc-scroller');
882
- const scrollTop = subjectEl.getBoundingClientRect().top -
883
- originEl.getBoundingClientRect().top;
884
- scrollEl.scrollTop = scrollTop ? (scrollTop + 1) : 0; // overcome border
885
- }
886
- this.needsScrollReset = false;
887
- }
908
+ // Lifecycle
909
+ // -----------------------------------------------------------------------------------------------
910
+ componentDidMount() {
911
+ // scroller
912
+ const ScrollerSyncer = internal$1.getScrollerSyncerClass(this.context.pluginHooks);
913
+ this.syncedScroller = new ScrollerSyncer(true); // horizontal=true
914
+ internal$1.setRef(this.props.scrollerRef, this.syncedScroller);
915
+ this.updateSyncedScroller();
888
916
  }
889
- }
890
- function getScrollSubjectEl(containerEl, dateProfile) {
891
- let el;
892
- if (dateProfile.currentRangeUnit.match(/year|month/)) {
893
- el = containerEl.querySelector(`[data-date="${internal$1.formatIsoMonthStr(dateProfile.currentDate)}-01"]`);
894
- // even if view is month-based, first-of-month might be hidden...
917
+ componentDidUpdate() {
918
+ // scroller
919
+ this.updateSyncedScroller();
895
920
  }
896
- if (!el) {
897
- el = containerEl.querySelector(`[data-date="${internal$1.formatDayString(dateProfile.currentDate)}"]`);
898
- // could still be hidden if an interior-view hidden day
921
+ componentWillUnmount() {
922
+ // scroller
923
+ this.syncedScroller.destroy();
924
+ }
925
+ // Scrolling
926
+ // -----------------------------------------------------------------------------------------------
927
+ updateSyncedScroller() {
928
+ const { isRtl } = this.context;
929
+ this.syncedScroller.handleChildren([
930
+ this.headerScrollerRef.current,
931
+ this.bodyScrollerRef.current,
932
+ this.footerScrollerRef.current,
933
+ ], isRtl);
899
934
  }
900
- return el;
901
935
  }
902
936
 
903
- class DayTableSlicer extends internal$1.Slicer {
937
+ class DayGridLayout extends internal$1.BaseComponent {
904
938
  constructor() {
905
939
  super(...arguments);
906
- this.forceDayIfListItem = true;
940
+ // ref
941
+ this.scrollerRef = preact.createRef();
942
+ this.rowHeightRefMap = new internal$1.RefMap();
943
+ // Scrolling
944
+ // -----------------------------------------------------------------------------------------------
945
+ this.timeScrollResponder = new internal$1.ScrollResponder((_time) => {
946
+ // HACK to scroll to day
947
+ const rowHeightMap = this.rowHeightRefMap.current;
948
+ const scroller = this.scrollerRef.current;
949
+ const scrollTop = computeTopFromDate(this.props.dateProfile.currentDate, this.props.cellRows, rowHeightMap);
950
+ if (scrollTop != null) {
951
+ scroller.scrollTo({ y: scrollTop });
952
+ return true;
953
+ }
954
+ return false;
955
+ });
907
956
  }
908
- sliceRange(dateRange, dayTableModel) {
909
- return dayTableModel.sliceRange(dateRange);
957
+ render() {
958
+ const { props, context } = this;
959
+ const { options } = context;
960
+ const commonLayoutProps = Object.assign(Object.assign({}, props), { scrollerRef: this.scrollerRef, rowHeightRefMap: this.rowHeightRefMap });
961
+ return (preact.createElement(internal$1.ViewContainer, { viewSpec: context.viewSpec, elClasses: [props.className, 'fc-flex-column', 'fc-border'] }, options.dayMinWidth ? (preact.createElement(DayGridLayoutPannable, Object.assign({}, commonLayoutProps, { dayMinWidth: options.dayMinWidth }))) : (preact.createElement(DayGridLayoutNormal, Object.assign({}, commonLayoutProps)))));
962
+ }
963
+ // Lifecycle
964
+ // -----------------------------------------------------------------------------------------------
965
+ componentDidMount() {
966
+ const { context } = this;
967
+ const { options } = context;
968
+ context.emitter.on('_timeScrollRequest', this.timeScrollResponder.handleScroll);
969
+ this.timeScrollResponder.handleScroll(options.scrollTime);
970
+ }
971
+ componentDidUpdate(prevProps) {
972
+ const { options } = this.context;
973
+ if (prevProps.dateProfile !== this.props.dateProfile && options.scrollTimeReset) {
974
+ this.timeScrollResponder.handleScroll(options.scrollTime);
975
+ }
976
+ else {
977
+ this.timeScrollResponder.drain();
978
+ }
979
+ }
980
+ componentWillUnmount() {
981
+ this.context.emitter.off('_timeScrollRequest', this.timeScrollResponder.handleScroll);
910
982
  }
911
983
  }
912
984
 
913
- class DayTable extends internal$1.DateComponent {
985
+ const WEEKDAY_FORMAT = internal$1.createFormatter({ weekday: 'long' });
986
+ class DayOfWeekHeaderCell extends internal$1.BaseComponent {
914
987
  constructor() {
915
988
  super(...arguments);
916
- this.slicer = new DayTableSlicer();
917
- this.tableRef = preact.createRef();
989
+ // ref
990
+ this.innerElRef = preact.createRef();
918
991
  }
919
992
  render() {
920
993
  let { props, context } = this;
921
- return (preact.createElement(Table, Object.assign({ ref: this.tableRef }, this.slicer.sliceProps(props, props.dateProfile, props.nextDayThreshold, context, props.dayTableModel), { dateProfile: props.dateProfile, cells: props.dayTableModel.cells, colGroupNode: props.colGroupNode, tableMinWidth: props.tableMinWidth, renderRowIntro: props.renderRowIntro, dayMaxEvents: props.dayMaxEvents, dayMaxEventRows: props.dayMaxEventRows, showWeekNumbers: props.showWeekNumbers, expandRows: props.expandRows, headerAlignElRef: props.headerAlignElRef, clientWidth: props.clientWidth, clientHeight: props.clientHeight, forPrint: props.forPrint })));
994
+ let { dateEnv, theme, viewApi, options } = context;
995
+ let date = internal$1.addDays(new Date(259200000), props.dow); // start with Sun, 04 Jan 1970 00:00:00 GMT
996
+ let dateMeta = {
997
+ dow: props.dow,
998
+ isDisabled: false,
999
+ isFuture: false,
1000
+ isPast: false,
1001
+ isToday: false,
1002
+ isOther: false,
1003
+ };
1004
+ let text = dateEnv.format(date, props.dayHeaderFormat);
1005
+ let renderProps = Object.assign(Object.assign(Object.assign(Object.assign({ date }, dateMeta), { view: viewApi }), props.extraRenderProps), { text });
1006
+ return (preact.createElement(internal$1.ContentContainer, { elTag: 'div', elClasses: [
1007
+ ...internal$1.getDayClassNames(dateMeta, theme),
1008
+ ...(props.extraClassNames || []),
1009
+ 'fc-header-cell',
1010
+ 'fc-cell',
1011
+ props.colWidth != null ? '' : 'fc-liquid',
1012
+ 'fc-flex-column',
1013
+ 'fc-align-center',
1014
+ ], elAttrs: props.extraDataAttrs, elStyle: {
1015
+ width: props.colWidth != null // TODO: DRY
1016
+ ? props.colWidth * (props.colSpan || 1)
1017
+ : undefined,
1018
+ }, renderProps: renderProps, generatorName: "dayHeaderContent", customGenerator: options.dayHeaderContent, defaultGenerator: renderInner, classNameGenerator: options.dayHeaderClassNames, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, (InnerContent) => (preact.createElement("div", { ref: this.innerElRef, className: [
1019
+ 'fc-flex-column',
1020
+ props.isSticky ? 'fc-sticky-x' : '',
1021
+ ].join(' ') },
1022
+ preact.createElement(InnerContent, { elTag: "a", elClasses: [
1023
+ 'fc-cell-inner',
1024
+ 'fc-padding-sm',
1025
+ ], elAttrs: {
1026
+ 'aria-label': dateEnv.format(date, WEEKDAY_FORMAT),
1027
+ } })))));
1028
+ }
1029
+ componentDidMount() {
1030
+ const innerEl = this.innerElRef.current; // TODO: make dynamic with useEffect
1031
+ // TODO: only attach this if refs props present
1032
+ this.disconectInnerHeight = internal$1.watchHeight(innerEl, (height) => {
1033
+ internal$1.setRef(this.props.innerHeightRef, height);
1034
+ });
1035
+ }
1036
+ componentWillUnmount() {
1037
+ this.disconectInnerHeight();
922
1038
  }
923
1039
  }
924
1040
 
925
- class DayTableView extends TableView {
1041
+ function createDayHeaderFormatter(explicitFormat, datesRepDistinctDays, dateCnt) {
1042
+ return explicitFormat || computeFallbackHeaderFormat(datesRepDistinctDays, dateCnt);
1043
+ }
1044
+ // Computes a default column header formatting string if `colFormat` is not explicitly defined
1045
+ function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) {
1046
+ // if more than one week row, or if there are a lot of columns with not much space,
1047
+ // put just the day numbers will be in each cell
1048
+ if (!datesRepDistinctDays || dayCnt > 10) {
1049
+ return internal$1.createFormatter({ weekday: 'short' }); // "Sat"
1050
+ }
1051
+ if (dayCnt > 1) {
1052
+ return internal$1.createFormatter({ weekday: 'short', month: 'numeric', day: 'numeric', omitCommas: true }); // "Sat 11/12"
1053
+ }
1054
+ return internal$1.createFormatter({ weekday: 'long' }); // "Saturday"
1055
+ }
1056
+
1057
+ class DayGridView extends internal$1.BaseComponent {
926
1058
  constructor() {
927
1059
  super(...arguments);
1060
+ // memo
928
1061
  this.buildDayTableModel = internal$1.memoize(buildDayTableModel);
929
- this.headerRef = preact.createRef();
930
- this.tableRef = preact.createRef();
931
- // can't override any lifecycle methods from parent
1062
+ this.buildHeaderTiers = internal$1.memoize(buildHeaderTiers);
1063
+ this.createDayHeaderFormatter = internal$1.memoize(createDayHeaderFormatter);
1064
+ // internal
1065
+ this.slicer = new DayTableSlicer();
932
1066
  }
933
1067
  render() {
934
- let { options, dateProfileGenerator } = this.context;
935
- let { props } = this;
936
- let dayTableModel = this.buildDayTableModel(props.dateProfile, dateProfileGenerator);
937
- let headerContent = options.dayHeaders && (preact.createElement(internal$1.DayHeader, { ref: this.headerRef, dateProfile: props.dateProfile, dates: dayTableModel.headerDates, datesRepDistinctDays: dayTableModel.rowCnt === 1 }));
938
- let bodyContent = (contentArg) => (preact.createElement(DayTable, { ref: this.tableRef, dateProfile: props.dateProfile, dayTableModel: dayTableModel, businessHours: props.businessHours, dateSelection: props.dateSelection, eventStore: props.eventStore, eventUiBases: props.eventUiBases, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, nextDayThreshold: options.nextDayThreshold, colGroupNode: contentArg.tableColGroupNode, tableMinWidth: contentArg.tableMinWidth, dayMaxEvents: options.dayMaxEvents, dayMaxEventRows: options.dayMaxEventRows, showWeekNumbers: options.weekNumbers, expandRows: !props.isHeightAuto, headerAlignElRef: this.headerElRef, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, forPrint: props.forPrint }));
939
- return options.dayMinWidth
940
- ? this.renderHScrollLayout(headerContent, bodyContent, dayTableModel.colCnt, options.dayMinWidth)
941
- : this.renderSimpleLayout(headerContent, bodyContent);
1068
+ const { props, context } = this;
1069
+ const { options } = context;
1070
+ const dayTableModel = this.buildDayTableModel(props.dateProfile, context.dateProfileGenerator);
1071
+ const datesRepDistinctDays = dayTableModel.rowCnt === 1;
1072
+ const headerTiers = this.buildHeaderTiers(dayTableModel.headerDates, datesRepDistinctDays);
1073
+ const slicedProps = this.slicer.sliceProps(props, props.dateProfile, options.nextDayThreshold, context, dayTableModel);
1074
+ const dayHeaderFormat = this.createDayHeaderFormatter(context.options.dayHeaderFormat, datesRepDistinctDays, dayTableModel.colCnt);
1075
+ return (preact.createElement(internal$1.NowTimer, { unit: "day" }, (nowDate, todayRange) => (preact.createElement(DayGridLayout, { dateProfile: props.dateProfile, todayRange: todayRange, cellRows: dayTableModel.cellRows, forPrint: props.forPrint, className: 'fc-daygrid-view',
1076
+ // header content
1077
+ headerTiers: headerTiers, renderHeaderContent: (model, tier, innerHeightRef, colWidth) => {
1078
+ if (model.date) {
1079
+ return (preact.createElement(DateHeaderCell, Object.assign({}, model, { dateProfile: props.dateProfile, todayRange: todayRange, navLink: dayTableModel.colCnt > 1, dayHeaderFormat: dayHeaderFormat, colSpan: model.colSpan, colWidth: colWidth })));
1080
+ }
1081
+ else {
1082
+ return (preact.createElement(DayOfWeekHeaderCell, Object.assign({}, model, { dayHeaderFormat: dayHeaderFormat, colSpan: model.colSpan, colWidth: colWidth })));
1083
+ }
1084
+ }, getHeaderModelKey: (model) => {
1085
+ // can use model.key???
1086
+ if (model.date) {
1087
+ return model.date.toUTCString();
1088
+ }
1089
+ return model.dow;
1090
+ },
1091
+ // body content
1092
+ fgEventSegs: slicedProps.fgEventSegs, bgEventSegs: slicedProps.bgEventSegs, businessHourSegs: slicedProps.businessHourSegs, dateSelectionSegs: slicedProps.dateSelectionSegs, eventDrag: slicedProps.eventDrag, eventResize: slicedProps.eventResize, eventSelection: slicedProps.eventSelection }))));
942
1093
  }
943
1094
  }
944
- function buildDayTableModel(dateProfile, dateProfileGenerator) {
945
- let daySeries = new internal$1.DaySeriesModel(dateProfile.renderRange, dateProfileGenerator);
946
- return new internal$1.DayTableModel(daySeries, /year|month|week/.test(dateProfile.currentRangeUnit));
947
- }
948
1095
 
949
1096
  class TableDateProfileGenerator extends internal$1.DateProfileGenerator {
950
1097
  // Computes the date range that will be rendered
@@ -984,7 +1131,7 @@ FullCalendar.DayGrid = (function (exports, core, internal$1, preact) {
984
1131
  return { start, end };
985
1132
  }
986
1133
 
987
- var css_248z = ":root{--fc-daygrid-event-dot-width:8px}.fc-daygrid-day-events:after,.fc-daygrid-day-events:before,.fc-daygrid-day-frame:after,.fc-daygrid-day-frame:before,.fc-daygrid-event-harness:after,.fc-daygrid-event-harness:before{clear:both;content:\"\";display:table}.fc .fc-daygrid-body{position:relative;z-index:1}.fc .fc-daygrid-day.fc-day-today{background-color:var(--fc-today-bg-color)}.fc .fc-daygrid-day-frame{min-height:100%;position:relative}.fc .fc-daygrid-day-top{display:flex;flex-direction:row-reverse}.fc .fc-day-other .fc-daygrid-day-top{opacity:.3}.fc .fc-daygrid-day-number{padding:4px;position:relative;z-index:4}.fc .fc-daygrid-month-start{font-size:1.1em;font-weight:700}.fc .fc-daygrid-day-events{margin-top:1px}.fc .fc-daygrid-body-balanced .fc-daygrid-day-events{left:0;position:absolute;right:0}.fc .fc-daygrid-body-unbalanced .fc-daygrid-day-events{min-height:2em;position:relative}.fc .fc-daygrid-body-natural .fc-daygrid-day-events{margin-bottom:1em}.fc .fc-daygrid-event-harness{position:relative}.fc .fc-daygrid-event-harness-abs{left:0;position:absolute;right:0;top:0}.fc .fc-daygrid-bg-harness{bottom:0;position:absolute;top:0}.fc .fc-daygrid-day-bg .fc-non-business{z-index:1}.fc .fc-daygrid-day-bg .fc-bg-event{z-index:2}.fc .fc-daygrid-day-bg .fc-highlight{z-index:3}.fc .fc-daygrid-event{margin-top:1px;z-index:6}.fc .fc-daygrid-event.fc-event-mirror{z-index:7}.fc .fc-daygrid-day-bottom{font-size:.85em;margin:0 2px}.fc .fc-daygrid-day-bottom:after,.fc .fc-daygrid-day-bottom:before{clear:both;content:\"\";display:table}.fc .fc-daygrid-more-link{border-radius:3px;cursor:pointer;line-height:1;margin-top:1px;max-width:100%;overflow:hidden;padding:2px;position:relative;white-space:nowrap;z-index:4}.fc .fc-daygrid-more-link:hover{background-color:rgba(0,0,0,.1)}.fc .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;z-index:5}.fc .fc-more-popover .fc-popover-body{min-width:220px;padding:10px}.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-more-link{float:left}.fc-direction-ltr .fc-daygrid-week-number{border-radius:0 0 3px 0;left:0}.fc-direction-rtl .fc-daygrid-more-link{float:right}.fc-direction-rtl .fc-daygrid-week-number{border-radius:0 0 0 3px;right:0}.fc-liquid-hack .fc-daygrid-day-frame{position:static}.fc-daygrid-event{border-radius:3px;font-size:var(--fc-small-font-size);position:relative;white-space:nowrap}.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;display:flex;padding:2px 0}.fc-daygrid-dot-event .fc-event-title{flex-grow:1;flex-shrink:1;font-weight:700;min-width:0;overflow:hidden}.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-direction-ltr .fc-daygrid-event .fc-event-time{margin-right:3px}.fc-direction-rtl .fc-daygrid-event .fc-event-time{margin-left:3px}";
1134
+ var css_248z = ":root{--fc-daygrid-event-dot-width:8px}.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;z-index:5}.fc-daygrid-cell.fc-day-today{background-color:var(--fc-today-bg-color)}.fc-daygrid-row-spacious .fc-daygrid-cell-inner{min-height:3em}.fc-daygrid-cell-header{display:flex;flex-direction:row-reverse}.fc-day-other .fc-daygrid-cell-header{opacity:.3}.fc-daygrid-cell-number{padding:4px;position:relative;z-index:4}.fc-daygrid-month-start{font-size:1.1em;font-weight:700}.fc-daygrid-cell-footer{align-items:flex-start;display:flex;flex-direction:column;font-size:.85em;margin:0 2px}.fc-daygrid-row-spacious .fc-daygrid-cell-footer{margin-bottom:1em!important}.fc-daygrid-row-compact .fc-daygrid-cell-footer{align-items:stretch}.fc-daygrid-more-link{border-radius:3px;cursor:pointer;line-height:1;margin-top:1px;max-width:100%;overflow:hidden;padding:2px;position:relative;white-space:nowrap;z-index:4}.fc-daygrid-more-link:hover{background-color:rgba(0,0,0,.1)}.fc-daygrid-row-compact .fc-daygrid-more-link{border:1px solid var(--fc-event-border-color);padding:1px}.fc-daygrid-cell .fc-non-business{z-index:1}.fc-daygrid-cell .fc-bg-event{z-index:2}.fc-daygrid-cell .fc-highlight{z-index:3}.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-top:1px;z-index:6}.fc-daygrid-event.fc-event-mirror{z-index:7}.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}.fc-daygrid-dot-event.fc-event-mirror,.fc-daygrid-dot-event:hover{background:rgba(0,0,0,.1)}.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-width:0}";
988
1135
  internal$1.injectStyles(css_248z);
989
1136
 
990
1137
  var plugin = core.createPlugin({
@@ -992,7 +1139,7 @@ FullCalendar.DayGrid = (function (exports, core, internal$1, preact) {
992
1139
  initialView: 'dayGridMonth',
993
1140
  views: {
994
1141
  dayGrid: {
995
- component: DayTableView,
1142
+ component: DayGridView,
996
1143
  dateProfileGeneratorClass: TableDateProfileGenerator,
997
1144
  },
998
1145
  dayGridDay: {
@@ -1015,17 +1162,58 @@ FullCalendar.DayGrid = (function (exports, core, internal$1, preact) {
1015
1162
  },
1016
1163
  });
1017
1164
 
1165
+ /*
1166
+ TODO: is it even worth doing this "advanced" version?
1167
+ */
1168
+ class HeaderRowAdvanced extends internal$1.BaseComponent {
1169
+ constructor() {
1170
+ super(...arguments);
1171
+ // ref
1172
+ this.innerHeightRefMap = new internal$1.RefMap(() => {
1173
+ internal$1.afterSize(this.handleInnerHeights);
1174
+ });
1175
+ this.handleInnerHeights = () => {
1176
+ const innerHeightMap = this.innerHeightRefMap.current;
1177
+ let max = 0;
1178
+ for (const innerHeight of innerHeightMap.values()) {
1179
+ max = Math.max(max, innerHeight);
1180
+ }
1181
+ if (this.currentInnerHeight !== max) {
1182
+ this.currentInnerHeight = max;
1183
+ internal$1.setRef(this.props.innerHeightRef, max);
1184
+ }
1185
+ };
1186
+ }
1187
+ render() {
1188
+ const { props } = this;
1189
+ return (preact.createElement("div", { role: 'row', className: 'fc-row', style: { height: props.height } }, props.cells.map((cell) => {
1190
+ const key = props.getHeaderModelKey(cell);
1191
+ return (preact.createElement(preact.Fragment, { key: props.getHeaderModelKey(cell) }, props.renderHeaderContent(cell, props.tierNum, this.innerHeightRefMap.createRef(key), // innerHeightRef
1192
+ props.colWidth)));
1193
+ })));
1194
+ }
1195
+ }
1196
+
1018
1197
  var internal = {
1019
1198
  __proto__: null,
1020
- DayTable: DayTable,
1021
1199
  DayTableSlicer: DayTableSlicer,
1022
1200
  TableDateProfileGenerator: TableDateProfileGenerator,
1023
1201
  buildDayTableRenderRange: buildDayTableRenderRange,
1024
- Table: Table,
1025
- TableRows: TableRows,
1026
- TableView: TableView,
1202
+ DayGridView: DayGridView,
1203
+ DateHeaderCell: DateHeaderCell,
1204
+ DayOfWeekHeaderCell: DayOfWeekHeaderCell,
1205
+ HeaderRow: HeaderRow,
1206
+ HeaderRowAdvanced: HeaderRowAdvanced,
1207
+ createDayHeaderFormatter: createDayHeaderFormatter,
1208
+ DayGridLayout: DayGridLayout,
1209
+ DayGridRow: DayGridRow,
1210
+ COMPACT_CELL_WIDTH: COMPACT_CELL_WIDTH,
1211
+ DayGridRows: DayGridRows,
1027
1212
  buildDayTableModel: buildDayTableModel,
1028
- DayGridView: DayTableView
1213
+ computeColWidth: computeColWidth,
1214
+ computeColFromPosition: computeColFromPosition,
1215
+ getRowEl: getRowEl,
1216
+ getCellEl: getCellEl
1029
1217
  };
1030
1218
 
1031
1219
  core.globalPlugins.push(plugin);