@fullcalendar/daygrid 7.0.0-beta.1 → 7.0.0-beta.3

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