UNPKG

72.9 kBJavaScriptView Raw
1/*!
2FullCalendar v5.11.3
3Docs & License: https://fullcalendar.io/
4(c) 2022 Adam Shaw
5*/
6var FullCalendarTimeGrid = (function (exports, common, daygrid) {
7 'use strict';
8
9 /*! *****************************************************************************
10 Copyright (c) Microsoft Corporation.
11
12 Permission to use, copy, modify, and/or distribute this software for any
13 purpose with or without fee is hereby granted.
14
15 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
16 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
17 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
18 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
19 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
20 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21 PERFORMANCE OF THIS SOFTWARE.
22 ***************************************************************************** */
23 /* global Reflect, Promise */
24
25 var extendStatics = function(d, b) {
26 extendStatics = Object.setPrototypeOf ||
27 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
28 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
29 return extendStatics(d, b);
30 };
31
32 function __extends(d, b) {
33 if (typeof b !== "function" && b !== null)
34 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
35 extendStatics(d, b);
36 function __() { this.constructor = d; }
37 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
38 }
39
40 var __assign = function() {
41 __assign = Object.assign || function __assign(t) {
42 for (var s, i = 1, n = arguments.length; i < n; i++) {
43 s = arguments[i];
44 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
45 }
46 return t;
47 };
48 return __assign.apply(this, arguments);
49 };
50
51 var AllDaySplitter = /** @class */ (function (_super) {
52 __extends(AllDaySplitter, _super);
53 function AllDaySplitter() {
54 return _super !== null && _super.apply(this, arguments) || this;
55 }
56 AllDaySplitter.prototype.getKeyInfo = function () {
57 return {
58 allDay: {},
59 timed: {},
60 };
61 };
62 AllDaySplitter.prototype.getKeysForDateSpan = function (dateSpan) {
63 if (dateSpan.allDay) {
64 return ['allDay'];
65 }
66 return ['timed'];
67 };
68 AllDaySplitter.prototype.getKeysForEventDef = function (eventDef) {
69 if (!eventDef.allDay) {
70 return ['timed'];
71 }
72 if (common.hasBgRendering(eventDef)) {
73 return ['timed', 'allDay'];
74 }
75 return ['allDay'];
76 };
77 return AllDaySplitter;
78 }(common.Splitter));
79
80 var DEFAULT_SLAT_LABEL_FORMAT = common.createFormatter({
81 hour: 'numeric',
82 minute: '2-digit',
83 omitZeroMinute: true,
84 meridiem: 'short',
85 });
86 function TimeColsAxisCell(props) {
87 var classNames = [
88 'fc-timegrid-slot',
89 'fc-timegrid-slot-label',
90 props.isLabeled ? 'fc-scrollgrid-shrink' : 'fc-timegrid-slot-minor',
91 ];
92 return (common.createElement(common.ViewContextType.Consumer, null, function (context) {
93 if (!props.isLabeled) {
94 return (common.createElement("td", { className: classNames.join(' '), "data-time": props.isoTimeStr }));
95 }
96 var dateEnv = context.dateEnv, options = context.options, viewApi = context.viewApi;
97 var labelFormat = // TODO: fully pre-parse
98 options.slotLabelFormat == null ? DEFAULT_SLAT_LABEL_FORMAT :
99 Array.isArray(options.slotLabelFormat) ? common.createFormatter(options.slotLabelFormat[0]) :
100 common.createFormatter(options.slotLabelFormat);
101 var hookProps = {
102 level: 0,
103 time: props.time,
104 date: dateEnv.toDate(props.date),
105 view: viewApi,
106 text: dateEnv.format(props.date, labelFormat),
107 };
108 return (common.createElement(common.RenderHook, { hookProps: hookProps, classNames: options.slotLabelClassNames, content: options.slotLabelContent, defaultContent: renderInnerContent, didMount: options.slotLabelDidMount, willUnmount: options.slotLabelWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (common.createElement("td", { ref: rootElRef, className: classNames.concat(customClassNames).join(' '), "data-time": props.isoTimeStr },
109 common.createElement("div", { className: "fc-timegrid-slot-label-frame fc-scrollgrid-shrink-frame" },
110 common.createElement("div", { className: "fc-timegrid-slot-label-cushion fc-scrollgrid-shrink-cushion", ref: innerElRef }, innerContent)))); }));
111 }));
112 }
113 function renderInnerContent(props) {
114 return props.text;
115 }
116
117 var TimeBodyAxis = /** @class */ (function (_super) {
118 __extends(TimeBodyAxis, _super);
119 function TimeBodyAxis() {
120 return _super !== null && _super.apply(this, arguments) || this;
121 }
122 TimeBodyAxis.prototype.render = function () {
123 return this.props.slatMetas.map(function (slatMeta) { return (common.createElement("tr", { key: slatMeta.key },
124 common.createElement(TimeColsAxisCell, __assign({}, slatMeta)))); });
125 };
126 return TimeBodyAxis;
127 }(common.BaseComponent));
128
129 var DEFAULT_WEEK_NUM_FORMAT = common.createFormatter({ week: 'short' });
130 var AUTO_ALL_DAY_MAX_EVENT_ROWS = 5;
131 var TimeColsView = /** @class */ (function (_super) {
132 __extends(TimeColsView, _super);
133 function TimeColsView() {
134 var _this = _super !== null && _super.apply(this, arguments) || this;
135 _this.allDaySplitter = new AllDaySplitter(); // for use by subclasses
136 _this.headerElRef = common.createRef();
137 _this.rootElRef = common.createRef();
138 _this.scrollerElRef = common.createRef();
139 _this.state = {
140 slatCoords: null,
141 };
142 _this.handleScrollTopRequest = function (scrollTop) {
143 var scrollerEl = _this.scrollerElRef.current;
144 if (scrollerEl) { // TODO: not sure how this could ever be null. weirdness with the reducer
145 scrollerEl.scrollTop = scrollTop;
146 }
147 };
148 /* Header Render Methods
149 ------------------------------------------------------------------------------------------------------------------*/
150 _this.renderHeadAxis = function (rowKey, frameHeight) {
151 if (frameHeight === void 0) { frameHeight = ''; }
152 var options = _this.context.options;
153 var dateProfile = _this.props.dateProfile;
154 var range = dateProfile.renderRange;
155 var dayCnt = common.diffDays(range.start, range.end);
156 var navLinkAttrs = (dayCnt === 1) // only do in day views (to avoid doing in week views that dont need it)
157 ? common.buildNavLinkAttrs(_this.context, range.start, 'week')
158 : {};
159 if (options.weekNumbers && rowKey === 'day') {
160 return (common.createElement(common.WeekNumberRoot, { date: range.start, defaultFormat: DEFAULT_WEEK_NUM_FORMAT }, function (rootElRef, classNames, innerElRef, innerContent) { return (common.createElement("th", { ref: rootElRef, "aria-hidden": true, className: [
161 'fc-timegrid-axis',
162 'fc-scrollgrid-shrink',
163 ].concat(classNames).join(' ') },
164 common.createElement("div", { className: "fc-timegrid-axis-frame fc-scrollgrid-shrink-frame fc-timegrid-axis-frame-liquid", style: { height: frameHeight } },
165 common.createElement("a", __assign({ ref: innerElRef, className: "fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner" }, navLinkAttrs), innerContent)))); }));
166 }
167 return (common.createElement("th", { "aria-hidden": true, className: "fc-timegrid-axis" },
168 common.createElement("div", { className: "fc-timegrid-axis-frame", style: { height: frameHeight } })));
169 };
170 /* Table Component Render Methods
171 ------------------------------------------------------------------------------------------------------------------*/
172 // only a one-way height sync. we don't send the axis inner-content height to the DayGrid,
173 // but DayGrid still needs to have classNames on inner elements in order to measure.
174 _this.renderTableRowAxis = function (rowHeight) {
175 var _a = _this.context, options = _a.options, viewApi = _a.viewApi;
176 var hookProps = {
177 text: options.allDayText,
178 view: viewApi,
179 };
180 return (
181 // TODO: make reusable hook. used in list view too
182 common.createElement(common.RenderHook, { hookProps: hookProps, classNames: options.allDayClassNames, content: options.allDayContent, defaultContent: renderAllDayInner, didMount: options.allDayDidMount, willUnmount: options.allDayWillUnmount }, function (rootElRef, classNames, innerElRef, innerContent) { return (common.createElement("td", { ref: rootElRef, "aria-hidden": true, className: [
183 'fc-timegrid-axis',
184 'fc-scrollgrid-shrink',
185 ].concat(classNames).join(' ') },
186 common.createElement("div", { className: 'fc-timegrid-axis-frame fc-scrollgrid-shrink-frame' + (rowHeight == null ? ' fc-timegrid-axis-frame-liquid' : ''), style: { height: rowHeight } },
187 common.createElement("span", { className: "fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner", ref: innerElRef }, innerContent)))); }));
188 };
189 _this.handleSlatCoords = function (slatCoords) {
190 _this.setState({ slatCoords: slatCoords });
191 };
192 return _this;
193 }
194 // rendering
195 // ----------------------------------------------------------------------------------------------------
196 TimeColsView.prototype.renderSimpleLayout = function (headerRowContent, allDayContent, timeContent) {
197 var _a = this, context = _a.context, props = _a.props;
198 var sections = [];
199 var stickyHeaderDates = common.getStickyHeaderDates(context.options);
200 if (headerRowContent) {
201 sections.push({
202 type: 'header',
203 key: 'header',
204 isSticky: stickyHeaderDates,
205 chunk: {
206 elRef: this.headerElRef,
207 tableClassName: 'fc-col-header',
208 rowContent: headerRowContent,
209 },
210 });
211 }
212 if (allDayContent) {
213 sections.push({
214 type: 'body',
215 key: 'all-day',
216 chunk: { content: allDayContent },
217 });
218 sections.push({
219 type: 'body',
220 key: 'all-day-divider',
221 outerContent: ( // TODO: rename to cellContent so don't need to define <tr>?
222 common.createElement("tr", { role: "presentation", className: "fc-scrollgrid-section" },
223 common.createElement("td", { className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))),
224 });
225 }
226 sections.push({
227 type: 'body',
228 key: 'body',
229 liquid: true,
230 expandRows: Boolean(context.options.expandRows),
231 chunk: {
232 scrollerElRef: this.scrollerElRef,
233 content: timeContent,
234 },
235 });
236 return (common.createElement(common.ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (common.createElement("div", { className: ['fc-timegrid'].concat(classNames).join(' '), ref: rootElRef },
237 common.createElement(common.SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, cols: [{ width: 'shrink' }], sections: sections }))); }));
238 };
239 TimeColsView.prototype.renderHScrollLayout = function (headerRowContent, allDayContent, timeContent, colCnt, dayMinWidth, slatMetas, slatCoords) {
240 var _this = this;
241 var ScrollGrid = this.context.pluginHooks.scrollGridImpl;
242 if (!ScrollGrid) {
243 throw new Error('No ScrollGrid implementation');
244 }
245 var _a = this, context = _a.context, props = _a.props;
246 var stickyHeaderDates = !props.forPrint && common.getStickyHeaderDates(context.options);
247 var stickyFooterScrollbar = !props.forPrint && common.getStickyFooterScrollbar(context.options);
248 var sections = [];
249 if (headerRowContent) {
250 sections.push({
251 type: 'header',
252 key: 'header',
253 isSticky: stickyHeaderDates,
254 syncRowHeights: true,
255 chunks: [
256 {
257 key: 'axis',
258 rowContent: function (arg) { return (common.createElement("tr", { role: "presentation" }, _this.renderHeadAxis('day', arg.rowSyncHeights[0]))); },
259 },
260 {
261 key: 'cols',
262 elRef: this.headerElRef,
263 tableClassName: 'fc-col-header',
264 rowContent: headerRowContent,
265 },
266 ],
267 });
268 }
269 if (allDayContent) {
270 sections.push({
271 type: 'body',
272 key: 'all-day',
273 syncRowHeights: true,
274 chunks: [
275 {
276 key: 'axis',
277 rowContent: function (contentArg) { return (common.createElement("tr", { role: "presentation" }, _this.renderTableRowAxis(contentArg.rowSyncHeights[0]))); },
278 },
279 {
280 key: 'cols',
281 content: allDayContent,
282 },
283 ],
284 });
285 sections.push({
286 key: 'all-day-divider',
287 type: 'body',
288 outerContent: ( // TODO: rename to cellContent so don't need to define <tr>?
289 common.createElement("tr", { role: "presentation", className: "fc-scrollgrid-section" },
290 common.createElement("td", { colSpan: 2, className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))),
291 });
292 }
293 var isNowIndicator = context.options.nowIndicator;
294 sections.push({
295 type: 'body',
296 key: 'body',
297 liquid: true,
298 expandRows: Boolean(context.options.expandRows),
299 chunks: [
300 {
301 key: 'axis',
302 content: function (arg) { return (
303 // TODO: make this now-indicator arrow more DRY with TimeColsContent
304 common.createElement("div", { className: "fc-timegrid-axis-chunk" },
305 common.createElement("table", { "aria-hidden": true, style: { height: arg.expandRows ? arg.clientHeight : '' } },
306 arg.tableColGroupNode,
307 common.createElement("tbody", null,
308 common.createElement(TimeBodyAxis, { slatMetas: slatMetas }))),
309 common.createElement("div", { className: "fc-timegrid-now-indicator-container" },
310 common.createElement(common.NowTimer, { unit: isNowIndicator ? 'minute' : 'day' /* hacky */ }, function (nowDate) {
311 var nowIndicatorTop = isNowIndicator &&
312 slatCoords &&
313 slatCoords.safeComputeTop(nowDate); // might return void
314 if (typeof nowIndicatorTop === 'number') {
315 return (common.createElement(common.NowIndicatorRoot, { isAxis: true, date: nowDate }, function (rootElRef, classNames, innerElRef, innerContent) { return (common.createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-arrow'].concat(classNames).join(' '), style: { top: nowIndicatorTop } }, innerContent)); }));
316 }
317 return null;
318 })))); },
319 },
320 {
321 key: 'cols',
322 scrollerElRef: this.scrollerElRef,
323 content: timeContent,
324 },
325 ],
326 });
327 if (stickyFooterScrollbar) {
328 sections.push({
329 key: 'footer',
330 type: 'footer',
331 isSticky: true,
332 chunks: [
333 {
334 key: 'axis',
335 content: common.renderScrollShim,
336 },
337 {
338 key: 'cols',
339 content: common.renderScrollShim,
340 },
341 ],
342 });
343 }
344 return (common.createElement(common.ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (common.createElement("div", { className: ['fc-timegrid'].concat(classNames).join(' '), ref: rootElRef },
345 common.createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: false, colGroups: [
346 { width: 'shrink', cols: [{ width: 'shrink' }] },
347 { cols: [{ span: colCnt, minWidth: dayMinWidth }] },
348 ], sections: sections }))); }));
349 };
350 /* Dimensions
351 ------------------------------------------------------------------------------------------------------------------*/
352 TimeColsView.prototype.getAllDayMaxEventProps = function () {
353 var _a = this.context.options, dayMaxEvents = _a.dayMaxEvents, dayMaxEventRows = _a.dayMaxEventRows;
354 if (dayMaxEvents === true || dayMaxEventRows === true) { // is auto?
355 dayMaxEvents = undefined;
356 dayMaxEventRows = AUTO_ALL_DAY_MAX_EVENT_ROWS; // make sure "auto" goes to a real number
357 }
358 return { dayMaxEvents: dayMaxEvents, dayMaxEventRows: dayMaxEventRows };
359 };
360 return TimeColsView;
361 }(common.DateComponent));
362 function renderAllDayInner(hookProps) {
363 return hookProps.text;
364 }
365
366 var TimeColsSlatsCoords = /** @class */ (function () {
367 function TimeColsSlatsCoords(positions, dateProfile, slotDuration) {
368 this.positions = positions;
369 this.dateProfile = dateProfile;
370 this.slotDuration = slotDuration;
371 }
372 TimeColsSlatsCoords.prototype.safeComputeTop = function (date) {
373 var dateProfile = this.dateProfile;
374 if (common.rangeContainsMarker(dateProfile.currentRange, date)) {
375 var startOfDayDate = common.startOfDay(date);
376 var timeMs = date.valueOf() - startOfDayDate.valueOf();
377 if (timeMs >= common.asRoughMs(dateProfile.slotMinTime) &&
378 timeMs < common.asRoughMs(dateProfile.slotMaxTime)) {
379 return this.computeTimeTop(common.createDuration(timeMs));
380 }
381 }
382 return null;
383 };
384 // Computes the top coordinate, relative to the bounds of the grid, of the given date.
385 // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.
386 TimeColsSlatsCoords.prototype.computeDateTop = function (when, startOfDayDate) {
387 if (!startOfDayDate) {
388 startOfDayDate = common.startOfDay(when);
389 }
390 return this.computeTimeTop(common.createDuration(when.valueOf() - startOfDayDate.valueOf()));
391 };
392 // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).
393 // This is a makeshify way to compute the time-top. Assumes all slatMetas dates are uniform.
394 // Eventually allow computation with arbirary slat dates.
395 TimeColsSlatsCoords.prototype.computeTimeTop = function (duration) {
396 var _a = this, positions = _a.positions, dateProfile = _a.dateProfile;
397 var len = positions.els.length;
398 // floating-point value of # of slots covered
399 var slatCoverage = (duration.milliseconds - common.asRoughMs(dateProfile.slotMinTime)) / common.asRoughMs(this.slotDuration);
400 var slatIndex;
401 var slatRemainder;
402 // compute a floating-point number for how many slats should be progressed through.
403 // from 0 to number of slats (inclusive)
404 // constrained because slotMinTime/slotMaxTime might be customized.
405 slatCoverage = Math.max(0, slatCoverage);
406 slatCoverage = Math.min(len, slatCoverage);
407 // an integer index of the furthest whole slat
408 // from 0 to number slats (*exclusive*, so len-1)
409 slatIndex = Math.floor(slatCoverage);
410 slatIndex = Math.min(slatIndex, len - 1);
411 // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition.
412 // could be 1.0 if slatCoverage is covering *all* the slots
413 slatRemainder = slatCoverage - slatIndex;
414 return positions.tops[slatIndex] +
415 positions.getHeight(slatIndex) * slatRemainder;
416 };
417 return TimeColsSlatsCoords;
418 }());
419
420 var TimeColsSlatsBody = /** @class */ (function (_super) {
421 __extends(TimeColsSlatsBody, _super);
422 function TimeColsSlatsBody() {
423 return _super !== null && _super.apply(this, arguments) || this;
424 }
425 TimeColsSlatsBody.prototype.render = function () {
426 var _a = this, props = _a.props, context = _a.context;
427 var options = context.options;
428 var slatElRefs = props.slatElRefs;
429 return (common.createElement("tbody", null, props.slatMetas.map(function (slatMeta, i) {
430 var hookProps = {
431 time: slatMeta.time,
432 date: context.dateEnv.toDate(slatMeta.date),
433 view: context.viewApi,
434 };
435 var classNames = [
436 'fc-timegrid-slot',
437 'fc-timegrid-slot-lane',
438 slatMeta.isLabeled ? '' : 'fc-timegrid-slot-minor',
439 ];
440 return (common.createElement("tr", { key: slatMeta.key, ref: slatElRefs.createRef(slatMeta.key) },
441 props.axis && (common.createElement(TimeColsAxisCell, __assign({}, slatMeta))),
442 common.createElement(common.RenderHook, { hookProps: hookProps, classNames: options.slotLaneClassNames, content: options.slotLaneContent, didMount: options.slotLaneDidMount, willUnmount: options.slotLaneWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (common.createElement("td", { ref: rootElRef, className: classNames.concat(customClassNames).join(' '), "data-time": slatMeta.isoTimeStr }, innerContent)); })));
443 })));
444 };
445 return TimeColsSlatsBody;
446 }(common.BaseComponent));
447
448 /*
449 for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL.
450 */
451 var TimeColsSlats = /** @class */ (function (_super) {
452 __extends(TimeColsSlats, _super);
453 function TimeColsSlats() {
454 var _this = _super !== null && _super.apply(this, arguments) || this;
455 _this.rootElRef = common.createRef();
456 _this.slatElRefs = new common.RefMap();
457 return _this;
458 }
459 TimeColsSlats.prototype.render = function () {
460 var _a = this, props = _a.props, context = _a.context;
461 return (common.createElement("div", { ref: this.rootElRef, className: "fc-timegrid-slots" },
462 common.createElement("table", { "aria-hidden": true, className: context.theme.getClass('table'), style: {
463 minWidth: props.tableMinWidth,
464 width: props.clientWidth,
465 height: props.minHeight,
466 } },
467 props.tableColGroupNode /* relies on there only being a single <col> for the axis */,
468 common.createElement(TimeColsSlatsBody, { slatElRefs: this.slatElRefs, axis: props.axis, slatMetas: props.slatMetas }))));
469 };
470 TimeColsSlats.prototype.componentDidMount = function () {
471 this.updateSizing();
472 };
473 TimeColsSlats.prototype.componentDidUpdate = function () {
474 this.updateSizing();
475 };
476 TimeColsSlats.prototype.componentWillUnmount = function () {
477 if (this.props.onCoords) {
478 this.props.onCoords(null);
479 }
480 };
481 TimeColsSlats.prototype.updateSizing = function () {
482 var _a = this, context = _a.context, props = _a.props;
483 if (props.onCoords &&
484 props.clientWidth !== null // means sizing has stabilized
485 ) {
486 var rootEl = this.rootElRef.current;
487 if (rootEl.offsetHeight) { // not hidden by css
488 props.onCoords(new TimeColsSlatsCoords(new common.PositionCache(this.rootElRef.current, collectSlatEls(this.slatElRefs.currentMap, props.slatMetas), false, true), this.props.dateProfile, context.options.slotDuration));
489 }
490 }
491 };
492 return TimeColsSlats;
493 }(common.BaseComponent));
494 function collectSlatEls(elMap, slatMetas) {
495 return slatMetas.map(function (slatMeta) { return elMap[slatMeta.key]; });
496 }
497
498 function splitSegsByCol(segs, colCnt) {
499 var segsByCol = [];
500 var i;
501 for (i = 0; i < colCnt; i += 1) {
502 segsByCol.push([]);
503 }
504 if (segs) {
505 for (i = 0; i < segs.length; i += 1) {
506 segsByCol[segs[i].col].push(segs[i]);
507 }
508 }
509 return segsByCol;
510 }
511 function splitInteractionByCol(ui, colCnt) {
512 var byRow = [];
513 if (!ui) {
514 for (var i = 0; i < colCnt; i += 1) {
515 byRow[i] = null;
516 }
517 }
518 else {
519 for (var i = 0; i < colCnt; i += 1) {
520 byRow[i] = {
521 affectedInstances: ui.affectedInstances,
522 isEvent: ui.isEvent,
523 segs: [],
524 };
525 }
526 for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) {
527 var seg = _a[_i];
528 byRow[seg.col].segs.push(seg);
529 }
530 }
531 return byRow;
532 }
533
534 var TimeColMoreLink = /** @class */ (function (_super) {
535 __extends(TimeColMoreLink, _super);
536 function TimeColMoreLink() {
537 var _this = _super !== null && _super.apply(this, arguments) || this;
538 _this.rootElRef = common.createRef();
539 return _this;
540 }
541 TimeColMoreLink.prototype.render = function () {
542 var _this = this;
543 var props = this.props;
544 return (common.createElement(common.MoreLinkRoot, { allDayDate: null, moreCnt: props.hiddenSegs.length, allSegs: props.hiddenSegs, hiddenSegs: props.hiddenSegs, alignmentElRef: this.rootElRef, defaultContent: renderMoreLinkInner, extraDateSpan: props.extraDateSpan, dateProfile: props.dateProfile, todayRange: props.todayRange, popoverContent: function () { return renderPlainFgSegs(props.hiddenSegs, props); } }, function (rootElRef, classNames, innerElRef, innerContent, handleClick, title, isExpanded, popoverId) { return (common.createElement("a", { ref: function (el) {
545 common.setRef(rootElRef, el);
546 common.setRef(_this.rootElRef, el);
547 }, className: ['fc-timegrid-more-link'].concat(classNames).join(' '), style: { top: props.top, bottom: props.bottom }, onClick: handleClick, title: title, "aria-expanded": isExpanded, "aria-controls": popoverId },
548 common.createElement("div", { ref: innerElRef, className: "fc-timegrid-more-link-inner fc-sticky" }, innerContent))); }));
549 };
550 return TimeColMoreLink;
551 }(common.BaseComponent));
552 function renderMoreLinkInner(props) {
553 return props.shortText;
554 }
555
556 // segInputs assumed sorted
557 function buildPositioning(segInputs, strictOrder, maxStackCnt) {
558 var hierarchy = new common.SegHierarchy();
559 if (strictOrder != null) {
560 hierarchy.strictOrder = strictOrder;
561 }
562 if (maxStackCnt != null) {
563 hierarchy.maxStackCnt = maxStackCnt;
564 }
565 var hiddenEntries = hierarchy.addSegs(segInputs);
566 var hiddenGroups = common.groupIntersectingEntries(hiddenEntries);
567 var web = buildWeb(hierarchy);
568 web = stretchWeb(web, 1); // all levelCoords/thickness will have 0.0-1.0
569 var segRects = webToRects(web);
570 return { segRects: segRects, hiddenGroups: hiddenGroups };
571 }
572 function buildWeb(hierarchy) {
573 var entriesByLevel = hierarchy.entriesByLevel;
574 var buildNode = cacheable(function (level, lateral) { return level + ':' + lateral; }, function (level, lateral) {
575 var siblingRange = findNextLevelSegs(hierarchy, level, lateral);
576 var nextLevelRes = buildNodes(siblingRange, buildNode);
577 var entry = entriesByLevel[level][lateral];
578 return [
579 __assign(__assign({}, entry), { nextLevelNodes: nextLevelRes[0] }),
580 entry.thickness + nextLevelRes[1], // the pressure builds
581 ];
582 });
583 return buildNodes(entriesByLevel.length
584 ? { level: 0, lateralStart: 0, lateralEnd: entriesByLevel[0].length }
585 : null, buildNode)[0];
586 }
587 function buildNodes(siblingRange, buildNode) {
588 if (!siblingRange) {
589 return [[], 0];
590 }
591 var level = siblingRange.level, lateralStart = siblingRange.lateralStart, lateralEnd = siblingRange.lateralEnd;
592 var lateral = lateralStart;
593 var pairs = [];
594 while (lateral < lateralEnd) {
595 pairs.push(buildNode(level, lateral));
596 lateral += 1;
597 }
598 pairs.sort(cmpDescPressures);
599 return [
600 pairs.map(extractNode),
601 pairs[0][1], // first item's pressure
602 ];
603 }
604 function cmpDescPressures(a, b) {
605 return b[1] - a[1];
606 }
607 function extractNode(a) {
608 return a[0];
609 }
610 function findNextLevelSegs(hierarchy, subjectLevel, subjectLateral) {
611 var levelCoords = hierarchy.levelCoords, entriesByLevel = hierarchy.entriesByLevel;
612 var subjectEntry = entriesByLevel[subjectLevel][subjectLateral];
613 var afterSubject = levelCoords[subjectLevel] + subjectEntry.thickness;
614 var levelCnt = levelCoords.length;
615 var level = subjectLevel;
616 // skip past levels that are too high up
617 for (; level < levelCnt && levelCoords[level] < afterSubject; level += 1)
618 ; // do nothing
619 for (; level < levelCnt; level += 1) {
620 var entries = entriesByLevel[level];
621 var entry = void 0;
622 var searchIndex = common.binarySearch(entries, subjectEntry.span.start, common.getEntrySpanEnd);
623 var lateralStart = searchIndex[0] + searchIndex[1]; // if exact match (which doesn't collide), go to next one
624 var lateralEnd = lateralStart;
625 while ( // loop through entries that horizontally intersect
626 (entry = entries[lateralEnd]) && // but not past the whole seg list
627 entry.span.start < subjectEntry.span.end) {
628 lateralEnd += 1;
629 }
630 if (lateralStart < lateralEnd) {
631 return { level: level, lateralStart: lateralStart, lateralEnd: lateralEnd };
632 }
633 }
634 return null;
635 }
636 function stretchWeb(topLevelNodes, totalThickness) {
637 var stretchNode = cacheable(function (node, startCoord, prevThickness) { return common.buildEntryKey(node); }, function (node, startCoord, prevThickness) {
638 var nextLevelNodes = node.nextLevelNodes, thickness = node.thickness;
639 var allThickness = thickness + prevThickness;
640 var thicknessFraction = thickness / allThickness;
641 var endCoord;
642 var newChildren = [];
643 if (!nextLevelNodes.length) {
644 endCoord = totalThickness;
645 }
646 else {
647 for (var _i = 0, nextLevelNodes_1 = nextLevelNodes; _i < nextLevelNodes_1.length; _i++) {
648 var childNode = nextLevelNodes_1[_i];
649 if (endCoord === undefined) {
650 var res = stretchNode(childNode, startCoord, allThickness);
651 endCoord = res[0];
652 newChildren.push(res[1]);
653 }
654 else {
655 var res = stretchNode(childNode, endCoord, 0);
656 newChildren.push(res[1]);
657 }
658 }
659 }
660 var newThickness = (endCoord - startCoord) * thicknessFraction;
661 return [endCoord - newThickness, __assign(__assign({}, node), { thickness: newThickness, nextLevelNodes: newChildren })];
662 });
663 return topLevelNodes.map(function (node) { return stretchNode(node, 0, 0)[1]; });
664 }
665 // not sorted in any particular order
666 function webToRects(topLevelNodes) {
667 var rects = [];
668 var processNode = cacheable(function (node, levelCoord, stackDepth) { return common.buildEntryKey(node); }, function (node, levelCoord, stackDepth) {
669 var rect = __assign(__assign({}, node), { levelCoord: levelCoord,
670 stackDepth: stackDepth, stackForward: 0 });
671 rects.push(rect);
672 return (rect.stackForward = processNodes(node.nextLevelNodes, levelCoord + node.thickness, stackDepth + 1) + 1);
673 });
674 function processNodes(nodes, levelCoord, stackDepth) {
675 var stackForward = 0;
676 for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
677 var node = nodes_1[_i];
678 stackForward = Math.max(processNode(node, levelCoord, stackDepth), stackForward);
679 }
680 return stackForward;
681 }
682 processNodes(topLevelNodes, 0, 0);
683 return rects; // TODO: sort rects by levelCoord to be consistent with toRects?
684 }
685 // TODO: move to general util
686 function cacheable(keyFunc, workFunc) {
687 var cache = {};
688 return function () {
689 var args = [];
690 for (var _i = 0; _i < arguments.length; _i++) {
691 args[_i] = arguments[_i];
692 }
693 var key = keyFunc.apply(void 0, args);
694 return (key in cache)
695 ? cache[key]
696 : (cache[key] = workFunc.apply(void 0, args));
697 };
698 }
699
700 function computeSegVCoords(segs, colDate, slatCoords, eventMinHeight) {
701 if (slatCoords === void 0) { slatCoords = null; }
702 if (eventMinHeight === void 0) { eventMinHeight = 0; }
703 var vcoords = [];
704 if (slatCoords) {
705 for (var i = 0; i < segs.length; i += 1) {
706 var seg = segs[i];
707 var spanStart = slatCoords.computeDateTop(seg.start, colDate);
708 var spanEnd = Math.max(spanStart + (eventMinHeight || 0), // :(
709 slatCoords.computeDateTop(seg.end, colDate));
710 vcoords.push({
711 start: Math.round(spanStart),
712 end: Math.round(spanEnd), //
713 });
714 }
715 }
716 return vcoords;
717 }
718 function computeFgSegPlacements(segs, segVCoords, // might not have for every seg
719 eventOrderStrict, eventMaxStack) {
720 var segInputs = [];
721 var dumbSegs = []; // segs without coords
722 for (var i = 0; i < segs.length; i += 1) {
723 var vcoords = segVCoords[i];
724 if (vcoords) {
725 segInputs.push({
726 index: i,
727 thickness: 1,
728 span: vcoords,
729 });
730 }
731 else {
732 dumbSegs.push(segs[i]);
733 }
734 }
735 var _a = buildPositioning(segInputs, eventOrderStrict, eventMaxStack), segRects = _a.segRects, hiddenGroups = _a.hiddenGroups;
736 var segPlacements = [];
737 for (var _i = 0, segRects_1 = segRects; _i < segRects_1.length; _i++) {
738 var segRect = segRects_1[_i];
739 segPlacements.push({
740 seg: segs[segRect.index],
741 rect: segRect,
742 });
743 }
744 for (var _b = 0, dumbSegs_1 = dumbSegs; _b < dumbSegs_1.length; _b++) {
745 var dumbSeg = dumbSegs_1[_b];
746 segPlacements.push({ seg: dumbSeg, rect: null });
747 }
748 return { segPlacements: segPlacements, hiddenGroups: hiddenGroups };
749 }
750
751 var DEFAULT_TIME_FORMAT = common.createFormatter({
752 hour: 'numeric',
753 minute: '2-digit',
754 meridiem: false,
755 });
756 var TimeColEvent = /** @class */ (function (_super) {
757 __extends(TimeColEvent, _super);
758 function TimeColEvent() {
759 return _super !== null && _super.apply(this, arguments) || this;
760 }
761 TimeColEvent.prototype.render = function () {
762 var classNames = [
763 'fc-timegrid-event',
764 'fc-v-event',
765 ];
766 if (this.props.isShort) {
767 classNames.push('fc-timegrid-event-short');
768 }
769 return (common.createElement(common.StandardEvent, __assign({}, this.props, { defaultTimeFormat: DEFAULT_TIME_FORMAT, extraClassNames: classNames })));
770 };
771 return TimeColEvent;
772 }(common.BaseComponent));
773
774 var TimeColMisc = /** @class */ (function (_super) {
775 __extends(TimeColMisc, _super);
776 function TimeColMisc() {
777 return _super !== null && _super.apply(this, arguments) || this;
778 }
779 TimeColMisc.prototype.render = function () {
780 var props = this.props;
781 return (common.createElement(common.DayCellContent, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps }, function (innerElRef, innerContent) { return (innerContent &&
782 common.createElement("div", { className: "fc-timegrid-col-misc", ref: innerElRef }, innerContent)); }));
783 };
784 return TimeColMisc;
785 }(common.BaseComponent));
786
787 var TimeCol = /** @class */ (function (_super) {
788 __extends(TimeCol, _super);
789 function TimeCol() {
790 var _this = _super !== null && _super.apply(this, arguments) || this;
791 _this.sortEventSegs = common.memoize(common.sortEventSegs);
792 return _this;
793 }
794 // TODO: memoize event-placement?
795 TimeCol.prototype.render = function () {
796 var _this = this;
797 var _a = this, props = _a.props, context = _a.context;
798 var isSelectMirror = context.options.selectMirror;
799 var mirrorSegs = (props.eventDrag && props.eventDrag.segs) ||
800 (props.eventResize && props.eventResize.segs) ||
801 (isSelectMirror && props.dateSelectionSegs) ||
802 [];
803 var interactionAffectedInstances = // TODO: messy way to compute this
804 (props.eventDrag && props.eventDrag.affectedInstances) ||
805 (props.eventResize && props.eventResize.affectedInstances) ||
806 {};
807 var sortedFgSegs = this.sortEventSegs(props.fgEventSegs, context.options.eventOrder);
808 return (common.createElement(common.DayCellRoot, { elRef: props.elRef, date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps }, function (rootElRef, classNames, dataAttrs) { return (common.createElement("td", __assign({ ref: rootElRef, role: "gridcell", className: ['fc-timegrid-col'].concat(classNames, props.extraClassNames || []).join(' ') }, dataAttrs, props.extraDataAttrs),
809 common.createElement("div", { className: "fc-timegrid-col-frame" },
810 common.createElement("div", { className: "fc-timegrid-col-bg" },
811 _this.renderFillSegs(props.businessHourSegs, 'non-business'),
812 _this.renderFillSegs(props.bgEventSegs, 'bg-event'),
813 _this.renderFillSegs(props.dateSelectionSegs, 'highlight')),
814 common.createElement("div", { className: "fc-timegrid-col-events" }, _this.renderFgSegs(sortedFgSegs, interactionAffectedInstances, false, false, false)),
815 common.createElement("div", { className: "fc-timegrid-col-events" }, _this.renderFgSegs(mirrorSegs, {}, Boolean(props.eventDrag), Boolean(props.eventResize), Boolean(isSelectMirror))),
816 common.createElement("div", { className: "fc-timegrid-now-indicator-container" }, _this.renderNowIndicator(props.nowIndicatorSegs)),
817 common.createElement(TimeColMisc, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps })))); }));
818 };
819 TimeCol.prototype.renderFgSegs = function (sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting) {
820 var props = this.props;
821 if (props.forPrint) {
822 return renderPlainFgSegs(sortedFgSegs, props);
823 }
824 return this.renderPositionedFgSegs(sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting);
825 };
826 TimeCol.prototype.renderPositionedFgSegs = function (segs, // if not mirror, needs to be sorted
827 segIsInvisible, isDragging, isResizing, isDateSelecting) {
828 var _this = this;
829 var _a = this.context.options, eventMaxStack = _a.eventMaxStack, eventShortHeight = _a.eventShortHeight, eventOrderStrict = _a.eventOrderStrict, eventMinHeight = _a.eventMinHeight;
830 var _b = this.props, date = _b.date, slatCoords = _b.slatCoords, eventSelection = _b.eventSelection, todayRange = _b.todayRange, nowDate = _b.nowDate;
831 var isMirror = isDragging || isResizing || isDateSelecting;
832 var segVCoords = computeSegVCoords(segs, date, slatCoords, eventMinHeight);
833 var _c = computeFgSegPlacements(segs, segVCoords, eventOrderStrict, eventMaxStack), segPlacements = _c.segPlacements, hiddenGroups = _c.hiddenGroups;
834 return (common.createElement(common.Fragment, null,
835 this.renderHiddenGroups(hiddenGroups, segs),
836 segPlacements.map(function (segPlacement) {
837 var seg = segPlacement.seg, rect = segPlacement.rect;
838 var instanceId = seg.eventRange.instance.instanceId;
839 var isVisible = isMirror || Boolean(!segIsInvisible[instanceId] && rect);
840 var vStyle = computeSegVStyle(rect && rect.span);
841 var hStyle = (!isMirror && rect) ? _this.computeSegHStyle(rect) : { left: 0, right: 0 };
842 var isInset = Boolean(rect) && rect.stackForward > 0;
843 var isShort = Boolean(rect) && (rect.span.end - rect.span.start) < eventShortHeight; // look at other places for this problem
844 return (common.createElement("div", { className: 'fc-timegrid-event-harness' +
845 (isInset ? ' fc-timegrid-event-harness-inset' : ''), key: instanceId, style: __assign(__assign({ visibility: isVisible ? '' : 'hidden' }, vStyle), hStyle) },
846 common.createElement(TimeColEvent, __assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === eventSelection, isShort: isShort }, common.getSegMeta(seg, todayRange, nowDate)))));
847 })));
848 };
849 // will already have eventMinHeight applied because segInputs already had it
850 TimeCol.prototype.renderHiddenGroups = function (hiddenGroups, segs) {
851 var _a = this.props, extraDateSpan = _a.extraDateSpan, dateProfile = _a.dateProfile, todayRange = _a.todayRange, nowDate = _a.nowDate, eventSelection = _a.eventSelection, eventDrag = _a.eventDrag, eventResize = _a.eventResize;
852 return (common.createElement(common.Fragment, null, hiddenGroups.map(function (hiddenGroup) {
853 var positionCss = computeSegVStyle(hiddenGroup.span);
854 var hiddenSegs = compileSegsFromEntries(hiddenGroup.entries, segs);
855 return (common.createElement(TimeColMoreLink, { key: common.buildIsoString(common.computeEarliestSegStart(hiddenSegs)), hiddenSegs: hiddenSegs, top: positionCss.top, bottom: positionCss.bottom, extraDateSpan: extraDateSpan, dateProfile: dateProfile, todayRange: todayRange, nowDate: nowDate, eventSelection: eventSelection, eventDrag: eventDrag, eventResize: eventResize }));
856 })));
857 };
858 TimeCol.prototype.renderFillSegs = function (segs, fillType) {
859 var _a = this, props = _a.props, context = _a.context;
860 var segVCoords = computeSegVCoords(segs, props.date, props.slatCoords, context.options.eventMinHeight); // don't assume all populated
861 var children = segVCoords.map(function (vcoords, i) {
862 var seg = segs[i];
863 return (common.createElement("div", { key: common.buildEventRangeKey(seg.eventRange), className: "fc-timegrid-bg-harness", style: computeSegVStyle(vcoords) }, fillType === 'bg-event' ?
864 common.createElement(common.BgEvent, __assign({ seg: seg }, common.getSegMeta(seg, props.todayRange, props.nowDate))) :
865 common.renderFill(fillType)));
866 });
867 return common.createElement(common.Fragment, null, children);
868 };
869 TimeCol.prototype.renderNowIndicator = function (segs) {
870 var _a = this.props, slatCoords = _a.slatCoords, date = _a.date;
871 if (!slatCoords) {
872 return null;
873 }
874 return segs.map(function (seg, i) { return (common.createElement(common.NowIndicatorRoot, { isAxis: false, date: date,
875 // key doesn't matter. will only ever be one
876 key: i }, function (rootElRef, classNames, innerElRef, innerContent) { return (common.createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-line'].concat(classNames).join(' '), style: { top: slatCoords.computeDateTop(seg.start, date) } }, innerContent)); })); });
877 };
878 TimeCol.prototype.computeSegHStyle = function (segHCoords) {
879 var _a = this.context, isRtl = _a.isRtl, options = _a.options;
880 var shouldOverlap = options.slotEventOverlap;
881 var nearCoord = segHCoords.levelCoord; // the left side if LTR. the right side if RTL. floating-point
882 var farCoord = segHCoords.levelCoord + segHCoords.thickness; // the right side if LTR. the left side if RTL. floating-point
883 var left; // amount of space from left edge, a fraction of the total width
884 var right; // amount of space from right edge, a fraction of the total width
885 if (shouldOverlap) {
886 // double the width, but don't go beyond the maximum forward coordinate (1.0)
887 farCoord = Math.min(1, nearCoord + (farCoord - nearCoord) * 2);
888 }
889 if (isRtl) {
890 left = 1 - farCoord;
891 right = nearCoord;
892 }
893 else {
894 left = nearCoord;
895 right = 1 - farCoord;
896 }
897 var props = {
898 zIndex: segHCoords.stackDepth + 1,
899 left: left * 100 + '%',
900 right: right * 100 + '%',
901 };
902 if (shouldOverlap && !segHCoords.stackForward) {
903 // add padding to the edge so that forward stacked events don't cover the resizer's icon
904 props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width
905 }
906 return props;
907 };
908 return TimeCol;
909 }(common.BaseComponent));
910 function renderPlainFgSegs(sortedFgSegs, _a) {
911 var todayRange = _a.todayRange, nowDate = _a.nowDate, eventSelection = _a.eventSelection, eventDrag = _a.eventDrag, eventResize = _a.eventResize;
912 var hiddenInstances = (eventDrag ? eventDrag.affectedInstances : null) ||
913 (eventResize ? eventResize.affectedInstances : null) ||
914 {};
915 return (common.createElement(common.Fragment, null, sortedFgSegs.map(function (seg) {
916 var instanceId = seg.eventRange.instance.instanceId;
917 return (common.createElement("div", { key: instanceId, style: { visibility: hiddenInstances[instanceId] ? 'hidden' : '' } },
918 common.createElement(TimeColEvent, __assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === eventSelection, isShort: false }, common.getSegMeta(seg, todayRange, nowDate)))));
919 })));
920 }
921 function computeSegVStyle(segVCoords) {
922 if (!segVCoords) {
923 return { top: '', bottom: '' };
924 }
925 return {
926 top: segVCoords.start,
927 bottom: -segVCoords.end,
928 };
929 }
930 function compileSegsFromEntries(segEntries, allSegs) {
931 return segEntries.map(function (segEntry) { return allSegs[segEntry.index]; });
932 }
933
934 var TimeColsContent = /** @class */ (function (_super) {
935 __extends(TimeColsContent, _super);
936 function TimeColsContent() {
937 var _this = _super !== null && _super.apply(this, arguments) || this;
938 _this.splitFgEventSegs = common.memoize(splitSegsByCol);
939 _this.splitBgEventSegs = common.memoize(splitSegsByCol);
940 _this.splitBusinessHourSegs = common.memoize(splitSegsByCol);
941 _this.splitNowIndicatorSegs = common.memoize(splitSegsByCol);
942 _this.splitDateSelectionSegs = common.memoize(splitSegsByCol);
943 _this.splitEventDrag = common.memoize(splitInteractionByCol);
944 _this.splitEventResize = common.memoize(splitInteractionByCol);
945 _this.rootElRef = common.createRef();
946 _this.cellElRefs = new common.RefMap();
947 return _this;
948 }
949 TimeColsContent.prototype.render = function () {
950 var _this = this;
951 var _a = this, props = _a.props, context = _a.context;
952 var nowIndicatorTop = context.options.nowIndicator &&
953 props.slatCoords &&
954 props.slatCoords.safeComputeTop(props.nowDate); // might return void
955 var colCnt = props.cells.length;
956 var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, colCnt);
957 var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, colCnt);
958 var businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, colCnt);
959 var nowIndicatorSegsByRow = this.splitNowIndicatorSegs(props.nowIndicatorSegs, colCnt);
960 var dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, colCnt);
961 var eventDragByRow = this.splitEventDrag(props.eventDrag, colCnt);
962 var eventResizeByRow = this.splitEventResize(props.eventResize, colCnt);
963 return (common.createElement("div", { className: "fc-timegrid-cols", ref: this.rootElRef },
964 common.createElement("table", { role: "presentation", style: {
965 minWidth: props.tableMinWidth,
966 width: props.clientWidth,
967 } },
968 props.tableColGroupNode,
969 common.createElement("tbody", { role: "presentation" },
970 common.createElement("tr", { role: "row" },
971 props.axis && (common.createElement("td", { "aria-hidden": true, className: "fc-timegrid-col fc-timegrid-axis" },
972 common.createElement("div", { className: "fc-timegrid-col-frame" },
973 common.createElement("div", { className: "fc-timegrid-now-indicator-container" }, typeof nowIndicatorTop === 'number' && (common.createElement(common.NowIndicatorRoot, { isAxis: true, date: props.nowDate }, function (rootElRef, classNames, innerElRef, innerContent) { return (common.createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-arrow'].concat(classNames).join(' '), style: { top: nowIndicatorTop } }, innerContent)); })))))),
974 props.cells.map(function (cell, i) { return (common.createElement(TimeCol, { key: cell.key, elRef: _this.cellElRefs.createRef(cell.key), dateProfile: props.dateProfile, date: cell.date, nowDate: props.nowDate, todayRange: props.todayRange, extraHookProps: cell.extraHookProps, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames, extraDateSpan: cell.extraDateSpan, fgEventSegs: fgEventSegsByRow[i], bgEventSegs: bgEventSegsByRow[i], businessHourSegs: businessHourSegsByRow[i], nowIndicatorSegs: nowIndicatorSegsByRow[i], dateSelectionSegs: dateSelectionSegsByRow[i], eventDrag: eventDragByRow[i], eventResize: eventResizeByRow[i], slatCoords: props.slatCoords, eventSelection: props.eventSelection, forPrint: props.forPrint })); }))))));
975 };
976 TimeColsContent.prototype.componentDidMount = function () {
977 this.updateCoords();
978 };
979 TimeColsContent.prototype.componentDidUpdate = function () {
980 this.updateCoords();
981 };
982 TimeColsContent.prototype.updateCoords = function () {
983 var props = this.props;
984 if (props.onColCoords &&
985 props.clientWidth !== null // means sizing has stabilized
986 ) {
987 props.onColCoords(new common.PositionCache(this.rootElRef.current, collectCellEls(this.cellElRefs.currentMap, props.cells), true, // horizontal
988 false));
989 }
990 };
991 return TimeColsContent;
992 }(common.BaseComponent));
993 function collectCellEls(elMap, cells) {
994 return cells.map(function (cell) { return elMap[cell.key]; });
995 }
996
997 /* A component that renders one or more columns of vertical time slots
998 ----------------------------------------------------------------------------------------------------------------------*/
999 var TimeCols = /** @class */ (function (_super) {
1000 __extends(TimeCols, _super);
1001 function TimeCols() {
1002 var _this = _super !== null && _super.apply(this, arguments) || this;
1003 _this.processSlotOptions = common.memoize(processSlotOptions);
1004 _this.state = {
1005 slatCoords: null,
1006 };
1007 _this.handleRootEl = function (el) {
1008 if (el) {
1009 _this.context.registerInteractiveComponent(_this, {
1010 el: el,
1011 isHitComboAllowed: _this.props.isHitComboAllowed,
1012 });
1013 }
1014 else {
1015 _this.context.unregisterInteractiveComponent(_this);
1016 }
1017 };
1018 _this.handleScrollRequest = function (request) {
1019 var onScrollTopRequest = _this.props.onScrollTopRequest;
1020 var slatCoords = _this.state.slatCoords;
1021 if (onScrollTopRequest && slatCoords) {
1022 if (request.time) {
1023 var top_1 = slatCoords.computeTimeTop(request.time);
1024 top_1 = Math.ceil(top_1); // zoom can give weird floating-point values. rather scroll a little bit further
1025 if (top_1) {
1026 top_1 += 1; // to overcome top border that slots beyond the first have. looks better
1027 }
1028 onScrollTopRequest(top_1);
1029 }
1030 return true;
1031 }
1032 return false;
1033 };
1034 _this.handleColCoords = function (colCoords) {
1035 _this.colCoords = colCoords;
1036 };
1037 _this.handleSlatCoords = function (slatCoords) {
1038 _this.setState({ slatCoords: slatCoords });
1039 if (_this.props.onSlatCoords) {
1040 _this.props.onSlatCoords(slatCoords);
1041 }
1042 };
1043 return _this;
1044 }
1045 TimeCols.prototype.render = function () {
1046 var _a = this, props = _a.props, state = _a.state;
1047 return (common.createElement("div", { className: "fc-timegrid-body", ref: this.handleRootEl, style: {
1048 // these props are important to give this wrapper correct dimensions for interactions
1049 // TODO: if we set it here, can we avoid giving to inner tables?
1050 width: props.clientWidth,
1051 minWidth: props.tableMinWidth,
1052 } },
1053 common.createElement(TimeColsSlats, { axis: props.axis, dateProfile: props.dateProfile, slatMetas: props.slatMetas, clientWidth: props.clientWidth, minHeight: props.expandRows ? props.clientHeight : '', tableMinWidth: props.tableMinWidth, tableColGroupNode: props.axis ? props.tableColGroupNode : null /* axis depends on the colgroup's shrinking */, onCoords: this.handleSlatCoords }),
1054 common.createElement(TimeColsContent, { cells: props.cells, axis: props.axis, dateProfile: props.dateProfile, businessHourSegs: props.businessHourSegs, bgEventSegs: props.bgEventSegs, fgEventSegs: props.fgEventSegs, dateSelectionSegs: props.dateSelectionSegs, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, todayRange: props.todayRange, nowDate: props.nowDate, nowIndicatorSegs: props.nowIndicatorSegs, clientWidth: props.clientWidth, tableMinWidth: props.tableMinWidth, tableColGroupNode: props.tableColGroupNode, slatCoords: state.slatCoords, onColCoords: this.handleColCoords, forPrint: props.forPrint })));
1055 };
1056 TimeCols.prototype.componentDidMount = function () {
1057 this.scrollResponder = this.context.createScrollResponder(this.handleScrollRequest);
1058 };
1059 TimeCols.prototype.componentDidUpdate = function (prevProps) {
1060 this.scrollResponder.update(prevProps.dateProfile !== this.props.dateProfile);
1061 };
1062 TimeCols.prototype.componentWillUnmount = function () {
1063 this.scrollResponder.detach();
1064 };
1065 TimeCols.prototype.queryHit = function (positionLeft, positionTop) {
1066 var _a = this.context, dateEnv = _a.dateEnv, options = _a.options;
1067 var colCoords = this.colCoords;
1068 var dateProfile = this.props.dateProfile;
1069 var slatCoords = this.state.slatCoords;
1070 var _b = this.processSlotOptions(this.props.slotDuration, options.snapDuration), snapDuration = _b.snapDuration, snapsPerSlot = _b.snapsPerSlot;
1071 var colIndex = colCoords.leftToIndex(positionLeft);
1072 var slatIndex = slatCoords.positions.topToIndex(positionTop);
1073 if (colIndex != null && slatIndex != null) {
1074 var cell = this.props.cells[colIndex];
1075 var slatTop = slatCoords.positions.tops[slatIndex];
1076 var slatHeight = slatCoords.positions.getHeight(slatIndex);
1077 var partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1
1078 var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat
1079 var snapIndex = slatIndex * snapsPerSlot + localSnapIndex;
1080 var dayDate = this.props.cells[colIndex].date;
1081 var time = common.addDurations(dateProfile.slotMinTime, common.multiplyDuration(snapDuration, snapIndex));
1082 var start = dateEnv.add(dayDate, time);
1083 var end = dateEnv.add(start, snapDuration);
1084 return {
1085 dateProfile: dateProfile,
1086 dateSpan: __assign({ range: { start: start, end: end }, allDay: false }, cell.extraDateSpan),
1087 dayEl: colCoords.els[colIndex],
1088 rect: {
1089 left: colCoords.lefts[colIndex],
1090 right: colCoords.rights[colIndex],
1091 top: slatTop,
1092 bottom: slatTop + slatHeight,
1093 },
1094 layer: 0,
1095 };
1096 }
1097 return null;
1098 };
1099 return TimeCols;
1100 }(common.DateComponent));
1101 function processSlotOptions(slotDuration, snapDurationOverride) {
1102 var snapDuration = snapDurationOverride || slotDuration;
1103 var snapsPerSlot = common.wholeDivideDurations(slotDuration, snapDuration);
1104 if (snapsPerSlot === null) {
1105 snapDuration = slotDuration;
1106 snapsPerSlot = 1;
1107 // TODO: say warning?
1108 }
1109 return { snapDuration: snapDuration, snapsPerSlot: snapsPerSlot };
1110 }
1111
1112 var DayTimeColsSlicer = /** @class */ (function (_super) {
1113 __extends(DayTimeColsSlicer, _super);
1114 function DayTimeColsSlicer() {
1115 return _super !== null && _super.apply(this, arguments) || this;
1116 }
1117 DayTimeColsSlicer.prototype.sliceRange = function (range, dayRanges) {
1118 var segs = [];
1119 for (var col = 0; col < dayRanges.length; col += 1) {
1120 var segRange = common.intersectRanges(range, dayRanges[col]);
1121 if (segRange) {
1122 segs.push({
1123 start: segRange.start,
1124 end: segRange.end,
1125 isStart: segRange.start.valueOf() === range.start.valueOf(),
1126 isEnd: segRange.end.valueOf() === range.end.valueOf(),
1127 col: col,
1128 });
1129 }
1130 }
1131 return segs;
1132 };
1133 return DayTimeColsSlicer;
1134 }(common.Slicer));
1135
1136 var DayTimeCols = /** @class */ (function (_super) {
1137 __extends(DayTimeCols, _super);
1138 function DayTimeCols() {
1139 var _this = _super !== null && _super.apply(this, arguments) || this;
1140 _this.buildDayRanges = common.memoize(buildDayRanges);
1141 _this.slicer = new DayTimeColsSlicer();
1142 _this.timeColsRef = common.createRef();
1143 return _this;
1144 }
1145 DayTimeCols.prototype.render = function () {
1146 var _this = this;
1147 var _a = this, props = _a.props, context = _a.context;
1148 var dateProfile = props.dateProfile, dayTableModel = props.dayTableModel;
1149 var isNowIndicator = context.options.nowIndicator;
1150 var dayRanges = this.buildDayRanges(dayTableModel, dateProfile, context.dateEnv);
1151 // give it the first row of cells
1152 // TODO: would move this further down hierarchy, but sliceNowDate needs it
1153 return (common.createElement(common.NowTimer, { unit: isNowIndicator ? 'minute' : 'day' }, function (nowDate, todayRange) { return (common.createElement(TimeCols, __assign({ ref: _this.timeColsRef }, _this.slicer.sliceProps(props, dateProfile, null, context, dayRanges), { forPrint: props.forPrint, axis: props.axis, dateProfile: dateProfile, slatMetas: props.slatMetas, slotDuration: props.slotDuration, cells: dayTableModel.cells[0], tableColGroupNode: props.tableColGroupNode, tableMinWidth: props.tableMinWidth, clientWidth: props.clientWidth, clientHeight: props.clientHeight, expandRows: props.expandRows, nowDate: nowDate, nowIndicatorSegs: isNowIndicator && _this.slicer.sliceNowDate(nowDate, context, dayRanges), todayRange: todayRange, onScrollTopRequest: props.onScrollTopRequest, onSlatCoords: props.onSlatCoords }))); }));
1154 };
1155 return DayTimeCols;
1156 }(common.DateComponent));
1157 function buildDayRanges(dayTableModel, dateProfile, dateEnv) {
1158 var ranges = [];
1159 for (var _i = 0, _a = dayTableModel.headerDates; _i < _a.length; _i++) {
1160 var date = _a[_i];
1161 ranges.push({
1162 start: dateEnv.add(date, dateProfile.slotMinTime),
1163 end: dateEnv.add(date, dateProfile.slotMaxTime),
1164 });
1165 }
1166 return ranges;
1167 }
1168
1169 // potential nice values for the slot-duration and interval-duration
1170 // from largest to smallest
1171 var STOCK_SUB_DURATIONS = [
1172 { hours: 1 },
1173 { minutes: 30 },
1174 { minutes: 15 },
1175 { seconds: 30 },
1176 { seconds: 15 },
1177 ];
1178 function buildSlatMetas(slotMinTime, slotMaxTime, explicitLabelInterval, slotDuration, dateEnv) {
1179 var dayStart = new Date(0);
1180 var slatTime = slotMinTime;
1181 var slatIterator = common.createDuration(0);
1182 var labelInterval = explicitLabelInterval || computeLabelInterval(slotDuration);
1183 var metas = [];
1184 while (common.asRoughMs(slatTime) < common.asRoughMs(slotMaxTime)) {
1185 var date = dateEnv.add(dayStart, slatTime);
1186 var isLabeled = common.wholeDivideDurations(slatIterator, labelInterval) !== null;
1187 metas.push({
1188 date: date,
1189 time: slatTime,
1190 key: date.toISOString(),
1191 isoTimeStr: common.formatIsoTimeString(date),
1192 isLabeled: isLabeled,
1193 });
1194 slatTime = common.addDurations(slatTime, slotDuration);
1195 slatIterator = common.addDurations(slatIterator, slotDuration);
1196 }
1197 return metas;
1198 }
1199 // Computes an automatic value for slotLabelInterval
1200 function computeLabelInterval(slotDuration) {
1201 var i;
1202 var labelInterval;
1203 var slotsPerLabel;
1204 // find the smallest stock label interval that results in more than one slots-per-label
1205 for (i = STOCK_SUB_DURATIONS.length - 1; i >= 0; i -= 1) {
1206 labelInterval = common.createDuration(STOCK_SUB_DURATIONS[i]);
1207 slotsPerLabel = common.wholeDivideDurations(labelInterval, slotDuration);
1208 if (slotsPerLabel !== null && slotsPerLabel > 1) {
1209 return labelInterval;
1210 }
1211 }
1212 return slotDuration; // fall back
1213 }
1214
1215 var DayTimeColsView = /** @class */ (function (_super) {
1216 __extends(DayTimeColsView, _super);
1217 function DayTimeColsView() {
1218 var _this = _super !== null && _super.apply(this, arguments) || this;
1219 _this.buildTimeColsModel = common.memoize(buildTimeColsModel);
1220 _this.buildSlatMetas = common.memoize(buildSlatMetas);
1221 return _this;
1222 }
1223 DayTimeColsView.prototype.render = function () {
1224 var _this = this;
1225 var _a = this.context, options = _a.options, dateEnv = _a.dateEnv, dateProfileGenerator = _a.dateProfileGenerator;
1226 var props = this.props;
1227 var dateProfile = props.dateProfile;
1228 var dayTableModel = this.buildTimeColsModel(dateProfile, dateProfileGenerator);
1229 var splitProps = this.allDaySplitter.splitProps(props);
1230 var slatMetas = this.buildSlatMetas(dateProfile.slotMinTime, dateProfile.slotMaxTime, options.slotLabelInterval, options.slotDuration, dateEnv);
1231 var dayMinWidth = options.dayMinWidth;
1232 var hasAttachedAxis = !dayMinWidth;
1233 var hasDetachedAxis = dayMinWidth;
1234 var headerContent = options.dayHeaders && (common.createElement(common.DayHeader, { dates: dayTableModel.headerDates, dateProfile: dateProfile, datesRepDistinctDays: true, renderIntro: hasAttachedAxis ? this.renderHeadAxis : null }));
1235 var allDayContent = (options.allDaySlot !== false) && (function (contentArg) { return (common.createElement(daygrid.DayTable, __assign({}, splitProps.allDay, { dateProfile: dateProfile, dayTableModel: dayTableModel, nextDayThreshold: options.nextDayThreshold, tableMinWidth: contentArg.tableMinWidth, colGroupNode: contentArg.tableColGroupNode, renderRowIntro: hasAttachedAxis ? _this.renderTableRowAxis : null, showWeekNumbers: false, expandRows: false, headerAlignElRef: _this.headerElRef, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, forPrint: props.forPrint }, _this.getAllDayMaxEventProps()))); });
1236 var timeGridContent = function (contentArg) { return (common.createElement(DayTimeCols, __assign({}, splitProps.timed, { dayTableModel: dayTableModel, dateProfile: dateProfile, axis: hasAttachedAxis, slotDuration: options.slotDuration, slatMetas: slatMetas, forPrint: props.forPrint, tableColGroupNode: contentArg.tableColGroupNode, tableMinWidth: contentArg.tableMinWidth, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, onSlatCoords: _this.handleSlatCoords, expandRows: contentArg.expandRows, onScrollTopRequest: _this.handleScrollTopRequest }))); };
1237 return hasDetachedAxis
1238 ? this.renderHScrollLayout(headerContent, allDayContent, timeGridContent, dayTableModel.colCnt, dayMinWidth, slatMetas, this.state.slatCoords)
1239 : this.renderSimpleLayout(headerContent, allDayContent, timeGridContent);
1240 };
1241 return DayTimeColsView;
1242 }(TimeColsView));
1243 function buildTimeColsModel(dateProfile, dateProfileGenerator) {
1244 var daySeries = new common.DaySeriesModel(dateProfile.renderRange, dateProfileGenerator);
1245 return new common.DayTableModel(daySeries, false);
1246 }
1247
1248 var OPTION_REFINERS = {
1249 allDaySlot: Boolean,
1250 };
1251
1252 var plugin = common.createPlugin({
1253 initialView: 'timeGridWeek',
1254 optionRefiners: OPTION_REFINERS,
1255 views: {
1256 timeGrid: {
1257 component: DayTimeColsView,
1258 usesMinMaxTime: true,
1259 allDaySlot: true,
1260 slotDuration: '00:30:00',
1261 slotEventOverlap: true, // a bad name. confused with overlap/constraint system
1262 },
1263 timeGridDay: {
1264 type: 'timeGrid',
1265 duration: { days: 1 },
1266 },
1267 timeGridWeek: {
1268 type: 'timeGrid',
1269 duration: { weeks: 1 },
1270 },
1271 },
1272 });
1273
1274 common.globalPlugins.push(plugin);
1275
1276 exports.DayTimeCols = DayTimeCols;
1277 exports.DayTimeColsSlicer = DayTimeColsSlicer;
1278 exports.DayTimeColsView = DayTimeColsView;
1279 exports.TimeCols = TimeCols;
1280 exports.TimeColsSlatsCoords = TimeColsSlatsCoords;
1281 exports.TimeColsView = TimeColsView;
1282 exports.buildDayRanges = buildDayRanges;
1283 exports.buildSlatMetas = buildSlatMetas;
1284 exports.buildTimeColsModel = buildTimeColsModel;
1285 exports.default = plugin;
1286
1287 Object.defineProperty(exports, '__esModule', { value: true });
1288
1289 return exports;
1290
1291}({}, FullCalendar, FullCalendarDayGrid));