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