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