@fullcalendar/timeline 6.1.15 → 7.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs +1 -2
- package/index.global.js +690 -594
- package/index.global.min.js +2 -2
- package/index.js +1 -2
- package/internal.cjs +688 -593
- package/internal.d.ts +138 -138
- package/internal.js +684 -592
- package/package.json +4 -4
package/index.global.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
FullCalendar Timeline Plugin
|
|
2
|
+
FullCalendar Timeline Plugin v7.0.0-beta.0
|
|
3
3
|
Docs & License: https://fullcalendar.io/docs/timeline-view-no-resources
|
|
4
4
|
(c) 2024 Adam Shaw
|
|
5
5
|
*/
|
|
6
|
-
FullCalendar.Timeline = (function (exports, core, premiumCommonPlugin, internal$1, preact
|
|
6
|
+
FullCalendar.Timeline = (function (exports, core, premiumCommonPlugin, internal$1, preact) {
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
9
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
@@ -448,152 +448,90 @@ FullCalendar.Timeline = (function (exports, core, premiumCommonPlugin, internal$
|
|
|
448
448
|
return { date, text, rowUnit, colspan: 1, isWeekStart: false };
|
|
449
449
|
}
|
|
450
450
|
|
|
451
|
-
class
|
|
451
|
+
class TimelineSlatCell extends internal$1.BaseComponent {
|
|
452
452
|
constructor() {
|
|
453
453
|
super(...arguments);
|
|
454
|
-
|
|
455
|
-
this.
|
|
454
|
+
// ref
|
|
455
|
+
this.innerElRef = preact.createRef();
|
|
456
456
|
}
|
|
457
457
|
render() {
|
|
458
458
|
let { props, context } = this;
|
|
459
|
-
let { dateEnv, options } = context;
|
|
460
|
-
let {
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
dateMarker: cell.date,
|
|
468
|
-
text: cell.text,
|
|
469
|
-
dateEnv: context.dateEnv,
|
|
470
|
-
viewApi: context.viewApi,
|
|
471
|
-
});
|
|
472
|
-
return (preact.createElement(internal$1.ContentContainer, { elTag: "th", elClasses: [
|
|
459
|
+
let { dateEnv, options, theme } = context;
|
|
460
|
+
let { date, tDateProfile, isEm } = props;
|
|
461
|
+
let dateMeta = internal$1.getDateMeta(props.date, props.todayRange, props.nowDate, props.dateProfile);
|
|
462
|
+
let renderProps = Object.assign(Object.assign({ date: dateEnv.toDate(props.date) }, dateMeta), { view: context.viewApi });
|
|
463
|
+
return (preact.createElement(internal$1.ContentContainer, { elTag: "div", elClasses: [
|
|
464
|
+
'fc-flex-column',
|
|
465
|
+
'fc-align-start',
|
|
466
|
+
'fc-cell',
|
|
473
467
|
'fc-timeline-slot',
|
|
474
|
-
'fc-timeline-slot-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
468
|
+
'fc-timeline-slot-lane',
|
|
469
|
+
isEm ? 'fc-timeline-slot-em' : '',
|
|
470
|
+
tDateProfile.isTimeScale ? (internal$1.isInt(dateEnv.countDurationsBetween(// best to do this here?
|
|
471
|
+
tDateProfile.normalizedRange.start, props.date, tDateProfile.labelInterval)) ?
|
|
472
|
+
'fc-timeline-slot-major' :
|
|
473
|
+
'fc-timeline-slot-minor') : '',
|
|
474
|
+
...(props.isDay ?
|
|
475
|
+
internal$1.getDayClassNames(dateMeta, theme) :
|
|
476
|
+
internal$1.getSlotClassNames(dateMeta, theme)),
|
|
480
477
|
], elAttrs: {
|
|
481
|
-
|
|
482
|
-
'data-date': dateEnv.formatIso(cell.date, {
|
|
483
|
-
omitTime: !tDateProfile.isTimeScale,
|
|
478
|
+
'data-date': dateEnv.formatIso(date, {
|
|
484
479
|
omitTimeZoneOffset: true,
|
|
480
|
+
omitTime: !tDateProfile.isTimeScale,
|
|
485
481
|
}),
|
|
486
|
-
},
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
props.isSticky && 'fc-sticky',
|
|
491
|
-
], elAttrs: this.buildCellNavLinkAttrs(context, cell.date, cell.rowUnit) })))));
|
|
482
|
+
}, elStyle: {
|
|
483
|
+
width: props.width,
|
|
484
|
+
}, renderProps: renderProps, generatorName: "slotLaneContent", customGenerator: options.slotLaneContent, classNameGenerator: options.slotLaneClassNames, didMount: options.slotLaneDidMount, willUnmount: options.slotLaneWillUnmount }, (InnerContent) => (preact.createElement("div", { ref: this.innerElRef, className: 'fc-flex-column' },
|
|
485
|
+
preact.createElement(InnerContent, { elTag: "div", elClasses: ['fc-cell-inner'] })))));
|
|
492
486
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
}
|
|
502
|
-
function refineRenderProps(input) {
|
|
503
|
-
return {
|
|
504
|
-
level: input.level,
|
|
505
|
-
date: input.dateEnv.toDate(input.dateMarker),
|
|
506
|
-
view: input.viewApi,
|
|
507
|
-
text: input.text,
|
|
508
|
-
};
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
class TimelineHeaderRows extends internal$1.BaseComponent {
|
|
512
|
-
render() {
|
|
513
|
-
let { dateProfile, tDateProfile, rowInnerHeights, todayRange, nowDate } = this.props;
|
|
514
|
-
let { cellRows } = tDateProfile;
|
|
515
|
-
return (preact.createElement(preact.Fragment, null, cellRows.map((rowCells, rowLevel) => {
|
|
516
|
-
let isLast = rowLevel === cellRows.length - 1;
|
|
517
|
-
let isChrono = tDateProfile.isTimeScale && isLast; // the final row, with times?
|
|
518
|
-
let classNames = [
|
|
519
|
-
'fc-timeline-header-row',
|
|
520
|
-
isChrono ? 'fc-timeline-header-row-chrono' : '',
|
|
521
|
-
];
|
|
522
|
-
return ( // eslint-disable-next-line react/no-array-index-key
|
|
523
|
-
preact.createElement("tr", { key: rowLevel, className: classNames.join(' ') }, rowCells.map((cell) => (preact.createElement(TimelineHeaderTh, { key: cell.date.toISOString(), cell: cell, rowLevel: rowLevel, dateProfile: dateProfile, tDateProfile: tDateProfile, todayRange: todayRange, nowDate: nowDate, rowInnerHeight: rowInnerHeights && rowInnerHeights[rowLevel], isSticky: !isLast })))));
|
|
524
|
-
})));
|
|
487
|
+
componentDidMount() {
|
|
488
|
+
const innerEl = this.innerElRef.current;
|
|
489
|
+
this.detachWidth = internal$1.watchWidth(innerEl, (width) => {
|
|
490
|
+
internal$1.setRef(this.props.innerWidthRef, width);
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
componentWillUnmount() {
|
|
494
|
+
this.detachWidth();
|
|
525
495
|
}
|
|
526
496
|
}
|
|
527
497
|
|
|
528
|
-
class
|
|
529
|
-
constructor(
|
|
530
|
-
|
|
531
|
-
this.
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
this.
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
// used for event rendering and scrollTime, to disregard slat border
|
|
540
|
-
this.innerCoordCache = new internal$1.PositionCache(slatRootEl, internal$1.findDirectChildren(slatEls, 'div'), true, // isHorizontal
|
|
541
|
-
false);
|
|
542
|
-
}
|
|
543
|
-
isDateInRange(date) {
|
|
544
|
-
return internal$1.rangeContainsMarker(this.dateProfile.currentRange, date);
|
|
545
|
-
}
|
|
546
|
-
// results range from negative width of area to 0
|
|
547
|
-
dateToCoord(date) {
|
|
548
|
-
let { tDateProfile } = this;
|
|
549
|
-
let snapCoverage = this.computeDateSnapCoverage(date);
|
|
550
|
-
let slotCoverage = snapCoverage / tDateProfile.snapsPerSlot;
|
|
551
|
-
let slotIndex = Math.floor(slotCoverage);
|
|
552
|
-
slotIndex = Math.min(slotIndex, tDateProfile.slotCnt - 1);
|
|
553
|
-
let partial = slotCoverage - slotIndex;
|
|
554
|
-
let { innerCoordCache, outerCoordCache } = this;
|
|
555
|
-
if (this.isRtl) {
|
|
556
|
-
return outerCoordCache.originClientRect.width - (outerCoordCache.rights[slotIndex] -
|
|
557
|
-
(innerCoordCache.getWidth(slotIndex) * partial));
|
|
558
|
-
}
|
|
559
|
-
return (outerCoordCache.lefts[slotIndex] +
|
|
560
|
-
(innerCoordCache.getWidth(slotIndex) * partial));
|
|
561
|
-
}
|
|
562
|
-
rangeToCoords(range) {
|
|
563
|
-
return {
|
|
564
|
-
start: this.dateToCoord(range.start),
|
|
565
|
-
end: this.dateToCoord(range.end),
|
|
566
|
-
};
|
|
567
|
-
}
|
|
568
|
-
durationToCoord(duration) {
|
|
569
|
-
let { dateProfile, tDateProfile, dateEnv, isRtl } = this;
|
|
570
|
-
let coord = 0;
|
|
571
|
-
if (dateProfile) {
|
|
572
|
-
let date = dateEnv.add(dateProfile.activeRange.start, duration);
|
|
573
|
-
if (!tDateProfile.isTimeScale) {
|
|
574
|
-
date = internal$1.startOfDay(date);
|
|
575
|
-
}
|
|
576
|
-
coord = this.dateToCoord(date);
|
|
577
|
-
// hack to overcome the left borders of non-first slat
|
|
578
|
-
if (!isRtl && coord) {
|
|
579
|
-
coord += 1;
|
|
498
|
+
class TimelineSlats extends internal$1.BaseComponent {
|
|
499
|
+
constructor() {
|
|
500
|
+
super(...arguments);
|
|
501
|
+
this.innerWidthRefMap = new internal$1.RefMap(() => {
|
|
502
|
+
internal$1.afterSize(this.handleInnerWidths);
|
|
503
|
+
});
|
|
504
|
+
this.handleInnerWidths = () => {
|
|
505
|
+
const innerWidthMap = this.innerWidthRefMap.current;
|
|
506
|
+
let max = 0;
|
|
507
|
+
for (const innerWidth of innerWidthMap.values()) {
|
|
508
|
+
max = Math.max(max, innerWidth);
|
|
580
509
|
}
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
coordFromLeft(coord) {
|
|
585
|
-
if (this.isRtl) {
|
|
586
|
-
return this.outerCoordCache.originClientRect.width - coord;
|
|
587
|
-
}
|
|
588
|
-
return coord;
|
|
510
|
+
// TODO: check to see if changed before firing ref!? YES. do in other places too
|
|
511
|
+
internal$1.setRef(this.props.innerWidthRef, max);
|
|
512
|
+
};
|
|
589
513
|
}
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
514
|
+
render() {
|
|
515
|
+
let { props, innerWidthRefMap } = this;
|
|
516
|
+
let { tDateProfile, slotWidth } = props;
|
|
517
|
+
let { slotDates, isWeekStarts } = tDateProfile;
|
|
518
|
+
let isDay = !tDateProfile.isTimeScale && !tDateProfile.largeUnit;
|
|
519
|
+
return (preact.createElement("div", { className: "fc-timeline-slots fc-fill fc-flex-row" }, slotDates.map((slotDate, i) => {
|
|
520
|
+
let key = slotDate.toISOString();
|
|
521
|
+
return (preact.createElement(TimelineSlatCell, { key: key, date: slotDate, dateProfile: props.dateProfile, tDateProfile: tDateProfile, nowDate: props.nowDate, todayRange: props.todayRange, isEm: isWeekStarts[i], isDay: isDay,
|
|
522
|
+
// ref
|
|
523
|
+
innerWidthRef: innerWidthRefMap.createRef(key),
|
|
524
|
+
// dimensions
|
|
525
|
+
width: slotWidth }));
|
|
526
|
+
})));
|
|
593
527
|
}
|
|
594
528
|
}
|
|
529
|
+
|
|
530
|
+
/*
|
|
531
|
+
TODO: rename this file!
|
|
532
|
+
*/
|
|
595
533
|
// returned value is between 0 and the number of snaps
|
|
596
|
-
function computeDateSnapCoverage(date, tDateProfile, dateEnv) {
|
|
534
|
+
function computeDateSnapCoverage$1(date, tDateProfile, dateEnv) {
|
|
597
535
|
let snapDiff = dateEnv.countDurationsBetween(tDateProfile.normalizedRange.start, date, tDateProfile.snapDuration);
|
|
598
536
|
if (snapDiff < 0) {
|
|
599
537
|
return 0;
|
|
@@ -613,6 +551,9 @@ FullCalendar.Timeline = (function (exports, core, premiumCommonPlugin, internal$
|
|
|
613
551
|
}
|
|
614
552
|
return snapCoverage;
|
|
615
553
|
}
|
|
554
|
+
/*
|
|
555
|
+
TODO: audit!!!
|
|
556
|
+
*/
|
|
616
557
|
function coordToCss(hcoord, isRtl) {
|
|
617
558
|
if (hcoord === null) {
|
|
618
559
|
return { left: '', right: '' };
|
|
@@ -622,6 +563,9 @@ FullCalendar.Timeline = (function (exports, core, premiumCommonPlugin, internal$
|
|
|
622
563
|
}
|
|
623
564
|
return { left: hcoord, right: '' };
|
|
624
565
|
}
|
|
566
|
+
/*
|
|
567
|
+
TODO: audit!!!
|
|
568
|
+
*/
|
|
625
569
|
function coordsToCss(hcoords, isRtl) {
|
|
626
570
|
if (!hcoords) {
|
|
627
571
|
return { left: '', right: '' };
|
|
@@ -631,216 +575,141 @@ FullCalendar.Timeline = (function (exports, core, premiumCommonPlugin, internal$
|
|
|
631
575
|
}
|
|
632
576
|
return { left: hcoords.start, right: -hcoords.end };
|
|
633
577
|
}
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
render() {
|
|
641
|
-
let { props, context } = this;
|
|
642
|
-
// TODO: very repetitive
|
|
643
|
-
// TODO: make part of tDateProfile?
|
|
644
|
-
let timerUnit = internal$1.greatestDurationDenominator(props.tDateProfile.slotDuration).unit;
|
|
645
|
-
// WORKAROUND: make ignore slatCoords when out of sync with dateProfile
|
|
646
|
-
let slatCoords = props.slatCoords && props.slatCoords.dateProfile === props.dateProfile ? props.slatCoords : null;
|
|
647
|
-
return (preact.createElement(internal$1.NowTimer, { unit: timerUnit }, (nowDate, todayRange) => (preact.createElement("div", { className: "fc-timeline-header", ref: this.rootElRef },
|
|
648
|
-
preact.createElement("table", { "aria-hidden": true, className: "fc-scrollgrid-sync-table", style: { minWidth: props.tableMinWidth, width: props.clientWidth } },
|
|
649
|
-
props.tableColGroupNode,
|
|
650
|
-
preact.createElement("tbody", null,
|
|
651
|
-
preact.createElement(TimelineHeaderRows, { dateProfile: props.dateProfile, tDateProfile: props.tDateProfile, nowDate: nowDate, todayRange: todayRange, rowInnerHeights: props.rowInnerHeights }))),
|
|
652
|
-
context.options.nowIndicator && (
|
|
653
|
-
// need to have a container regardless of whether the current view has a visible now indicator
|
|
654
|
-
// because apparently removal of the element resets the scroll for some reasons (issue #5351).
|
|
655
|
-
// this issue doesn't happen for the timeline body however (
|
|
656
|
-
preact.createElement("div", { className: "fc-timeline-now-indicator-container" }, (slatCoords && slatCoords.isDateInRange(nowDate)) && (preact.createElement(internal$1.NowIndicatorContainer, { elClasses: ['fc-timeline-now-indicator-arrow'], elStyle: coordToCss(slatCoords.dateToCoord(nowDate), context.isRtl), isAxis: true, date: nowDate }))))))));
|
|
578
|
+
/*
|
|
579
|
+
TODO: DRY up with elsewhere?
|
|
580
|
+
*/
|
|
581
|
+
function horizontalsToCss(hcoord, isRtl) {
|
|
582
|
+
if (!hcoord) {
|
|
583
|
+
return {};
|
|
657
584
|
}
|
|
658
|
-
|
|
659
|
-
|
|
585
|
+
if (isRtl) {
|
|
586
|
+
return { right: hcoord.start, width: hcoord.size };
|
|
660
587
|
}
|
|
661
|
-
|
|
662
|
-
|
|
588
|
+
else {
|
|
589
|
+
return { left: hcoord.start, width: hcoord.size };
|
|
663
590
|
}
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
}
|
|
591
|
+
}
|
|
592
|
+
function horizontalCoordToCss(start, isRtl) {
|
|
593
|
+
if (isRtl) {
|
|
594
|
+
return { right: start };
|
|
668
595
|
}
|
|
669
|
-
|
|
670
|
-
return
|
|
596
|
+
else {
|
|
597
|
+
return { left: start };
|
|
671
598
|
}
|
|
672
599
|
}
|
|
673
600
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
let renderProps = Object.assign(Object.assign({ date: dateEnv.toDate(props.date) }, dateMeta), { view: context.viewApi });
|
|
681
|
-
return (preact.createElement(internal$1.ContentContainer, { elTag: "td", elRef: props.elRef, elClasses: [
|
|
682
|
-
'fc-timeline-slot',
|
|
683
|
-
'fc-timeline-slot-lane',
|
|
684
|
-
isEm && 'fc-timeline-slot-em',
|
|
685
|
-
tDateProfile.isTimeScale ? (internal$1.isInt(dateEnv.countDurationsBetween(tDateProfile.normalizedRange.start, props.date, tDateProfile.labelInterval)) ?
|
|
686
|
-
'fc-timeline-slot-major' :
|
|
687
|
-
'fc-timeline-slot-minor') : '',
|
|
688
|
-
...(props.isDay ?
|
|
689
|
-
internal$1.getDayClassNames(dateMeta, theme) :
|
|
690
|
-
internal$1.getSlotClassNames(dateMeta, theme)),
|
|
691
|
-
], elAttrs: {
|
|
692
|
-
'data-date': dateEnv.formatIso(date, {
|
|
693
|
-
omitTimeZoneOffset: true,
|
|
694
|
-
omitTime: !tDateProfile.isTimeScale,
|
|
695
|
-
}),
|
|
696
|
-
}, renderProps: renderProps, generatorName: "slotLaneContent", customGenerator: options.slotLaneContent, classNameGenerator: options.slotLaneClassNames, didMount: options.slotLaneDidMount, willUnmount: options.slotLaneWillUnmount }, (InnerContent) => (preact.createElement(InnerContent, { elTag: "div" }))));
|
|
601
|
+
function createVerticalStyle(props) {
|
|
602
|
+
if (props) {
|
|
603
|
+
return {
|
|
604
|
+
top: props.start,
|
|
605
|
+
height: props.size,
|
|
606
|
+
};
|
|
697
607
|
}
|
|
698
608
|
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
let isDay = !tDateProfile.isTimeScale && !tDateProfile.largeUnit;
|
|
706
|
-
return (preact.createElement("tbody", null,
|
|
707
|
-
preact.createElement("tr", null, slotDates.map((slotDate, i) => {
|
|
708
|
-
let key = slotDate.toISOString();
|
|
709
|
-
return (preact.createElement(TimelineSlatCell, { key: key, elRef: cellElRefs.createRef(key), date: slotDate, dateProfile: props.dateProfile, tDateProfile: tDateProfile, nowDate: props.nowDate, todayRange: props.todayRange, isEm: isWeekStarts[i], isDay: isDay }));
|
|
710
|
-
}))));
|
|
609
|
+
function createHorizontalStyle(props, isRtl) {
|
|
610
|
+
if (props) {
|
|
611
|
+
return {
|
|
612
|
+
[isRtl ? 'right' : 'left']: props.start,
|
|
613
|
+
width: props.size,
|
|
614
|
+
};
|
|
711
615
|
}
|
|
712
616
|
}
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
};
|
|
617
|
+
// Timeline-specific
|
|
618
|
+
// -------------------------------------------------------------------------------------------------
|
|
619
|
+
const MIN_SLOT_WIDTH = 30; // for real
|
|
620
|
+
/*
|
|
621
|
+
TODO: DRY with computeSlatHeight?
|
|
622
|
+
*/
|
|
623
|
+
function computeSlotWidth(slatCnt, slatsPerLabel, slatMinWidth, labelInnerWidth, viewportWidth) {
|
|
624
|
+
if (labelInnerWidth == null || viewportWidth == null) {
|
|
625
|
+
return [undefined, undefined, false];
|
|
626
|
+
}
|
|
627
|
+
slatMinWidth = Math.max(slatMinWidth || 0, (labelInnerWidth + 1) / slatsPerLabel, MIN_SLOT_WIDTH);
|
|
628
|
+
const slatTryWidth = viewportWidth / slatCnt;
|
|
629
|
+
let slatLiquid;
|
|
630
|
+
let slatWidth;
|
|
631
|
+
if (slatTryWidth >= slatMinWidth) {
|
|
632
|
+
slatLiquid = true;
|
|
633
|
+
slatWidth = slatTryWidth;
|
|
731
634
|
}
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
preact.createElement("table", { "aria-hidden": true, className: context.theme.getClass('table'), style: {
|
|
736
|
-
minWidth: props.tableMinWidth,
|
|
737
|
-
width: props.clientWidth,
|
|
738
|
-
} },
|
|
739
|
-
props.tableColGroupNode,
|
|
740
|
-
preact.createElement(TimelineSlatsBody, { cellElRefs: this.cellElRefs, dateProfile: props.dateProfile, tDateProfile: props.tDateProfile, nowDate: props.nowDate, todayRange: props.todayRange }))));
|
|
635
|
+
else {
|
|
636
|
+
slatLiquid = false;
|
|
637
|
+
slatWidth = Math.max(slatMinWidth, slatTryWidth);
|
|
741
638
|
}
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
639
|
+
return [slatWidth * slatCnt, slatWidth, slatLiquid];
|
|
640
|
+
}
|
|
641
|
+
function timeToCoord(// pixels
|
|
642
|
+
time, dateEnv, dateProfile, tDateProfile, slowWidth) {
|
|
643
|
+
let date = dateEnv.add(dateProfile.activeRange.start, time);
|
|
644
|
+
if (!tDateProfile.isTimeScale) {
|
|
645
|
+
date = internal$1.startOfDay(date);
|
|
745
646
|
}
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
647
|
+
return dateToCoord(date, dateEnv, tDateProfile, slowWidth);
|
|
648
|
+
}
|
|
649
|
+
function dateToCoord(// pixels
|
|
650
|
+
date, dateEnv, tDateProfile, slotWidth) {
|
|
651
|
+
let snapCoverage = computeDateSnapCoverage(date, tDateProfile, dateEnv);
|
|
652
|
+
let slotCoverage = snapCoverage / tDateProfile.snapsPerSlot;
|
|
653
|
+
return slotCoverage * slotWidth;
|
|
654
|
+
}
|
|
655
|
+
/*
|
|
656
|
+
returned value is between 0 and the number of snaps
|
|
657
|
+
*/
|
|
658
|
+
function computeDateSnapCoverage(date, tDateProfile, dateEnv) {
|
|
659
|
+
let snapDiff = dateEnv.countDurationsBetween(tDateProfile.normalizedRange.start, date, tDateProfile.snapDuration);
|
|
660
|
+
if (snapDiff < 0) {
|
|
661
|
+
return 0;
|
|
749
662
|
}
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
if (this.props.onCoords) {
|
|
753
|
-
this.props.onCoords(null);
|
|
754
|
-
}
|
|
663
|
+
if (snapDiff >= tDateProfile.snapDiffToIndex.length) {
|
|
664
|
+
return tDateProfile.snapCnt;
|
|
755
665
|
}
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
// ^it's possible to have clientWidth immediately after mount (when returning from print view), but w/o scrollResponder
|
|
761
|
-
) {
|
|
762
|
-
let rootEl = this.rootElRef.current;
|
|
763
|
-
if (rootEl.offsetWidth) { // not hidden by css
|
|
764
|
-
this.coords = new TimelineCoords(this.rootElRef.current, collectCellEls(this.cellElRefs.currentMap, props.tDateProfile.slotDates), props.dateProfile, props.tDateProfile, context.dateEnv, context.isRtl);
|
|
765
|
-
if (props.onCoords) {
|
|
766
|
-
props.onCoords(this.coords);
|
|
767
|
-
}
|
|
768
|
-
this.scrollResponder.update(false); // TODO: wouldn't have to do this if coords were in state
|
|
769
|
-
}
|
|
770
|
-
}
|
|
666
|
+
let snapDiffInt = Math.floor(snapDiff);
|
|
667
|
+
let snapCoverage = tDateProfile.snapDiffToIndex[snapDiffInt];
|
|
668
|
+
if (internal$1.isInt(snapCoverage)) { // not an in-between value
|
|
669
|
+
snapCoverage += snapDiff - snapDiffInt; // add the remainder
|
|
771
670
|
}
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
let slatIndex = outerCoordCache.leftToIndex(leftPosition);
|
|
777
|
-
if (slatIndex != null) {
|
|
778
|
-
// somewhat similar to what TimeGrid does. consolidate?
|
|
779
|
-
let slatWidth = outerCoordCache.getWidth(slatIndex);
|
|
780
|
-
let partial = isRtl ?
|
|
781
|
-
(outerCoordCache.rights[slatIndex] - leftPosition) / slatWidth :
|
|
782
|
-
(leftPosition - outerCoordCache.lefts[slatIndex]) / slatWidth;
|
|
783
|
-
let localSnapIndex = Math.floor(partial * tDateProfile.snapsPerSlot);
|
|
784
|
-
let start = dateEnv.add(tDateProfile.slotDates[slatIndex], internal$1.multiplyDuration(tDateProfile.snapDuration, localSnapIndex));
|
|
785
|
-
let end = dateEnv.add(start, tDateProfile.snapDuration);
|
|
786
|
-
return {
|
|
787
|
-
dateSpan: {
|
|
788
|
-
range: { start, end },
|
|
789
|
-
allDay: !this.props.tDateProfile.isTimeScale,
|
|
790
|
-
},
|
|
791
|
-
dayEl: this.cellElRefs.currentMap[slatIndex],
|
|
792
|
-
left: outerCoordCache.lefts[slatIndex],
|
|
793
|
-
right: outerCoordCache.rights[slatIndex],
|
|
794
|
-
};
|
|
795
|
-
}
|
|
796
|
-
return null;
|
|
671
|
+
else {
|
|
672
|
+
// a fractional value, meaning the date is not visible
|
|
673
|
+
// always round up in this case. works for start AND end dates in a range.
|
|
674
|
+
snapCoverage = Math.ceil(snapCoverage);
|
|
797
675
|
}
|
|
798
|
-
|
|
799
|
-
function collectCellEls(elMap, slotDates) {
|
|
800
|
-
return slotDates.map((slotDate) => {
|
|
801
|
-
let key = slotDate.toISOString();
|
|
802
|
-
return elMap[key];
|
|
803
|
-
});
|
|
676
|
+
return snapCoverage;
|
|
804
677
|
}
|
|
805
678
|
|
|
806
|
-
function
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
let res = timelineCoords.rangeToCoords(seg);
|
|
811
|
-
let start = Math.round(res.start); // for barely-overlapping collisions
|
|
812
|
-
let end = Math.round(res.end); //
|
|
813
|
-
if (end - start < minWidth) {
|
|
814
|
-
end = start + minWidth;
|
|
815
|
-
}
|
|
816
|
-
hcoords.push({ start, end });
|
|
817
|
-
}
|
|
679
|
+
function computeManySegHorizontals(segs, segMinWidth, dateEnv, tDateProfile, slotWidth) {
|
|
680
|
+
const res = {};
|
|
681
|
+
for (const seg of segs) {
|
|
682
|
+
res[seg.eventRange.instance.instanceId] = computeSegHorizontals(seg, segMinWidth, dateEnv, tDateProfile, slotWidth);
|
|
818
683
|
}
|
|
819
|
-
return
|
|
684
|
+
return res;
|
|
685
|
+
}
|
|
686
|
+
function computeSegHorizontals(seg, segMinWidth, dateEnv, tDateProfile, slotWidth) {
|
|
687
|
+
const startCoord = dateToCoord(seg.start, dateEnv, tDateProfile, slotWidth);
|
|
688
|
+
const endCoord = dateToCoord(seg.end, dateEnv, tDateProfile, slotWidth);
|
|
689
|
+
let size = endCoord - startCoord;
|
|
690
|
+
if (segMinWidth) {
|
|
691
|
+
size = Math.max(size, segMinWidth);
|
|
692
|
+
}
|
|
693
|
+
return { start: startCoord, size };
|
|
820
694
|
}
|
|
821
|
-
function computeFgSegPlacements(
|
|
822
|
-
|
|
823
|
-
moreLinkHeights, // might not have for every more-link
|
|
695
|
+
function computeFgSegPlacements(// mostly horizontals
|
|
696
|
+
segs, segHorizontals, segHeights, // keyed by instanceId
|
|
824
697
|
strictOrder, maxStackCnt) {
|
|
825
|
-
let
|
|
826
|
-
let crudePlacements = []; // when we don't know dims
|
|
698
|
+
let segEntries = [];
|
|
827
699
|
for (let i = 0; i < segs.length; i += 1) {
|
|
828
700
|
let seg = segs[i];
|
|
829
701
|
let instanceId = seg.eventRange.instance.instanceId;
|
|
830
|
-
let height =
|
|
831
|
-
let hcoords =
|
|
832
|
-
if (height && hcoords) {
|
|
833
|
-
|
|
702
|
+
let height = segHeights.get(instanceId);
|
|
703
|
+
let hcoords = segHorizontals[instanceId];
|
|
704
|
+
if (height != null && hcoords != null) {
|
|
705
|
+
segEntries.push({
|
|
834
706
|
index: i,
|
|
835
|
-
span: hcoords,
|
|
836
|
-
thickness: height,
|
|
837
|
-
});
|
|
838
|
-
}
|
|
839
|
-
else {
|
|
840
|
-
crudePlacements.push({
|
|
841
707
|
seg,
|
|
842
|
-
|
|
843
|
-
|
|
708
|
+
span: {
|
|
709
|
+
start: hcoords.start,
|
|
710
|
+
end: hcoords.start + hcoords.size,
|
|
711
|
+
},
|
|
712
|
+
thickness: height,
|
|
844
713
|
});
|
|
845
714
|
}
|
|
846
715
|
}
|
|
@@ -851,80 +720,85 @@ FullCalendar.Timeline = (function (exports, core, premiumCommonPlugin, internal$
|
|
|
851
720
|
if (maxStackCnt != null) {
|
|
852
721
|
hierarchy.maxStackCnt = maxStackCnt;
|
|
853
722
|
}
|
|
854
|
-
let hiddenEntries = hierarchy.addSegs(
|
|
855
|
-
let hiddenPlacements = hiddenEntries.map((entry) => ({
|
|
856
|
-
seg: segs[entry.index],
|
|
857
|
-
hcoords: entry.span,
|
|
858
|
-
top: null,
|
|
859
|
-
}));
|
|
723
|
+
let hiddenEntries = hierarchy.addSegs(segEntries);
|
|
860
724
|
let hiddenGroups = internal$1.groupIntersectingEntries(hiddenEntries);
|
|
861
|
-
let
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
let height = moreLinkHeights[internal$1.buildIsoString(internal$1.computeEarliestSegStart(sortedSegs))]; // not optimal :(
|
|
868
|
-
if (height != null) {
|
|
869
|
-
// NOTE: the hiddenGroup's spanStart/spanEnd are already computed by rangeToCoords. computed during input.
|
|
870
|
-
moreLinkInputs.push({
|
|
871
|
-
index: segs.length + i,
|
|
872
|
-
thickness: height,
|
|
873
|
-
span: hiddenGroup.span,
|
|
874
|
-
});
|
|
875
|
-
}
|
|
876
|
-
else {
|
|
877
|
-
moreLinkCrudePlacements.push({
|
|
878
|
-
seg: sortedSegs,
|
|
879
|
-
hcoords: hiddenGroup.span,
|
|
880
|
-
top: null,
|
|
881
|
-
});
|
|
882
|
-
}
|
|
883
|
-
}
|
|
725
|
+
let hiddenGroupEntries = hiddenGroups.map((hiddenGroup, index) => ({
|
|
726
|
+
index: segs.length + index,
|
|
727
|
+
segGroup: hiddenGroup,
|
|
728
|
+
span: hiddenGroup.span,
|
|
729
|
+
thickness: 1, // HACK to ensure it's placed
|
|
730
|
+
}));
|
|
884
731
|
// add more-links into the hierarchy, but don't limit
|
|
885
732
|
hierarchy.maxStackCnt = -1;
|
|
886
|
-
hierarchy.addSegs(
|
|
733
|
+
hierarchy.addSegs(hiddenGroupEntries);
|
|
887
734
|
let visibleRects = hierarchy.toRects();
|
|
888
|
-
let
|
|
889
|
-
let
|
|
735
|
+
let segTops = {};
|
|
736
|
+
let hiddenGroupTops = {};
|
|
890
737
|
for (let rect of visibleRects) {
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
seg
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
});
|
|
899
|
-
maxHeight = Math.max(maxHeight, rect.levelCoord + rect.thickness);
|
|
738
|
+
const { seg, segGroup } = rect;
|
|
739
|
+
if (seg) { // regular seg
|
|
740
|
+
segTops[seg.eventRange.instance.instanceId] = rect.levelCoord;
|
|
741
|
+
}
|
|
742
|
+
else { // hiddenGroup
|
|
743
|
+
hiddenGroupTops[segGroup.key] = rect.levelCoord;
|
|
744
|
+
}
|
|
900
745
|
}
|
|
901
746
|
return [
|
|
902
|
-
|
|
903
|
-
|
|
747
|
+
segTops,
|
|
748
|
+
computeMaxBottom(segs, segTops, segHeights),
|
|
749
|
+
hiddenGroups,
|
|
750
|
+
hiddenGroupTops,
|
|
904
751
|
];
|
|
905
752
|
}
|
|
753
|
+
function computeMaxBottom(segs, segTops, segHeights) {
|
|
754
|
+
let max = 0;
|
|
755
|
+
for (const seg of segs) {
|
|
756
|
+
const { instanceId } = seg.eventRange.instance;
|
|
757
|
+
const top = segTops[instanceId];
|
|
758
|
+
const height = segHeights.get(instanceId);
|
|
759
|
+
if (top != null && height != null) {
|
|
760
|
+
max = Math.max(max, top + height);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
return max;
|
|
764
|
+
}
|
|
765
|
+
/*
|
|
766
|
+
TODO: converge with computeMaxBottom, but keys are different
|
|
767
|
+
*/
|
|
768
|
+
function computeMoreLinkMaxBottom(hiddenGroups, hiddenGroupTops, hiddenGroupHeights) {
|
|
769
|
+
let max = 0;
|
|
770
|
+
for (const hiddenGroup of hiddenGroups) {
|
|
771
|
+
const top = hiddenGroupTops[hiddenGroup.key];
|
|
772
|
+
const height = hiddenGroupHeights.get(hiddenGroup.key);
|
|
773
|
+
if (top != null && height != null) {
|
|
774
|
+
max = Math.max(max, top + height);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
return max;
|
|
778
|
+
}
|
|
906
779
|
|
|
907
780
|
class TimelineLaneBg extends internal$1.BaseComponent {
|
|
908
781
|
render() {
|
|
909
782
|
let { props } = this;
|
|
910
783
|
let highlightSeg = [].concat(props.eventResizeSegs, props.dateSelectionSegs);
|
|
911
|
-
return
|
|
912
|
-
this.renderSegs(props.businessHourSegs || [],
|
|
913
|
-
this.renderSegs(props.bgEventSegs || [],
|
|
914
|
-
this.renderSegs(highlightSeg,
|
|
915
|
-
}
|
|
916
|
-
renderSegs(segs,
|
|
917
|
-
let { todayRange, nowDate } = this.props;
|
|
918
|
-
let { isRtl } = this.context;
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
784
|
+
return (preact.createElement("div", { className: "fc-timeline-bg" },
|
|
785
|
+
this.renderSegs(props.businessHourSegs || [], 'non-business'),
|
|
786
|
+
this.renderSegs(props.bgEventSegs || [], 'bg-event'),
|
|
787
|
+
this.renderSegs(highlightSeg, 'highlight')));
|
|
788
|
+
}
|
|
789
|
+
renderSegs(segs, fillType) {
|
|
790
|
+
let { tDateProfile, todayRange, nowDate, slotWidth } = this.props;
|
|
791
|
+
let { dateEnv, isRtl } = this.context;
|
|
792
|
+
return (preact.createElement(preact.Fragment, null, segs.map((seg) => {
|
|
793
|
+
let hStyle; // TODO
|
|
794
|
+
if (slotWidth != null) {
|
|
795
|
+
let segHorizontal = computeSegHorizontals(seg, undefined, dateEnv, tDateProfile, slotWidth);
|
|
796
|
+
hStyle = horizontalsToCss(segHorizontal, isRtl);
|
|
797
|
+
}
|
|
923
798
|
return (preact.createElement("div", { key: internal$1.buildEventRangeKey(seg.eventRange), className: "fc-timeline-bg-harness", style: hStyle }, fillType === 'bg-event' ?
|
|
924
799
|
preact.createElement(internal$1.BgEvent, Object.assign({ seg: seg }, internal$1.getSegMeta(seg, todayRange, nowDate))) :
|
|
925
800
|
internal$1.renderFill(fillType)));
|
|
926
|
-
});
|
|
927
|
-
return preact.createElement(preact.Fragment, null, children);
|
|
801
|
+
})));
|
|
928
802
|
}
|
|
929
803
|
}
|
|
930
804
|
|
|
@@ -933,8 +807,8 @@ FullCalendar.Timeline = (function (exports, core, premiumCommonPlugin, internal$
|
|
|
933
807
|
let normalRange = normalizeRange(origRange, tDateProfile, dateEnv);
|
|
934
808
|
let segs = [];
|
|
935
809
|
// protect against when the span is entirely in an invalid date region
|
|
936
|
-
if (computeDateSnapCoverage(normalRange.start, tDateProfile, dateEnv)
|
|
937
|
-
< computeDateSnapCoverage(normalRange.end, tDateProfile, dateEnv)) {
|
|
810
|
+
if (computeDateSnapCoverage$1(normalRange.start, tDateProfile, dateEnv)
|
|
811
|
+
< computeDateSnapCoverage$1(normalRange.end, tDateProfile, dateEnv)) {
|
|
938
812
|
// intersect the footprint's range with the grid's range
|
|
939
813
|
let slicedRange = internal$1.intersectRanges(normalRange, tDateProfile.normalizedRange);
|
|
940
814
|
if (slicedRange) {
|
|
@@ -960,48 +834,84 @@ FullCalendar.Timeline = (function (exports, core, premiumCommonPlugin, internal$
|
|
|
960
834
|
});
|
|
961
835
|
class TimelineEvent extends internal$1.BaseComponent {
|
|
962
836
|
render() {
|
|
963
|
-
let { props } = this;
|
|
964
|
-
|
|
837
|
+
let { props, context } = this;
|
|
838
|
+
let { options } = context;
|
|
839
|
+
return (preact.createElement(internal$1.StandardEvent, Object.assign({}, props, { elClasses: [
|
|
840
|
+
'fc-timeline-event',
|
|
841
|
+
'fc-h-event',
|
|
842
|
+
options.eventOverlap === false // TODO: fix bad default
|
|
843
|
+
? 'fc-timeline-event-spacious'
|
|
844
|
+
: ''
|
|
845
|
+
], defaultTimeFormat: DEFAULT_TIME_FORMAT, defaultDisplayEventTime: !props.isTimeScale })));
|
|
965
846
|
}
|
|
966
847
|
}
|
|
967
848
|
|
|
968
849
|
class TimelineLaneMoreLink extends internal$1.BaseComponent {
|
|
969
850
|
render() {
|
|
970
|
-
let { props
|
|
971
|
-
let { hiddenSegs,
|
|
972
|
-
let { top, hcoords } = placement;
|
|
973
|
-
let isVisible = hcoords && top !== null;
|
|
974
|
-
let hStyle = coordsToCss(hcoords, context.isRtl);
|
|
851
|
+
let { props } = this;
|
|
852
|
+
let { hiddenSegs, resourceId, forcedInvisibleMap } = props;
|
|
975
853
|
let extraDateSpan = resourceId ? { resourceId } : {};
|
|
976
|
-
return (preact.createElement(internal$1.MoreLinkContainer, {
|
|
854
|
+
return (preact.createElement(internal$1.MoreLinkContainer, { elClasses: ['fc-timeline-more-link'], allDayDate: null, segs: hiddenSegs, hiddenSegs: hiddenSegs, dateProfile: props.dateProfile, todayRange: props.todayRange, extraDateSpan: extraDateSpan, popoverContent: () => (preact.createElement(preact.Fragment, null, hiddenSegs.map((seg) => {
|
|
977
855
|
let instanceId = seg.eventRange.instance.instanceId;
|
|
978
|
-
return (preact.createElement("div", { key: instanceId, style: { visibility:
|
|
856
|
+
return (preact.createElement("div", { key: instanceId, style: { visibility: forcedInvisibleMap[instanceId] ? 'hidden' : '' } },
|
|
979
857
|
preact.createElement(TimelineEvent, Object.assign({ isTimeScale: props.isTimeScale, seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === props.eventSelection }, internal$1.getSegMeta(seg, props.todayRange, props.nowDate)))));
|
|
980
|
-
}))) }, (InnerContent) => (preact.createElement(InnerContent, { elTag: "div", elClasses: ['fc-timeline-more-link-inner', 'fc-sticky'] }))));
|
|
858
|
+
}))) }, (InnerContent) => (preact.createElement(InnerContent, { elTag: "div", elClasses: ['fc-timeline-more-link-inner', 'fc-sticky-x'] }))));
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
/*
|
|
863
|
+
TODO: make DRY with other Event Harnesses
|
|
864
|
+
*/
|
|
865
|
+
class TimelineEventHarness extends preact.Component {
|
|
866
|
+
constructor() {
|
|
867
|
+
super(...arguments);
|
|
868
|
+
// ref
|
|
869
|
+
this.rootElRef = preact.createRef();
|
|
870
|
+
}
|
|
871
|
+
render() {
|
|
872
|
+
const { props } = this;
|
|
873
|
+
return (preact.createElement("div", { className: "fc-abs", style: props.style, ref: this.rootElRef }, props.children));
|
|
874
|
+
}
|
|
875
|
+
componentDidMount() {
|
|
876
|
+
const rootEl = this.rootElRef.current; // TODO: make dynamic with useEffect
|
|
877
|
+
this.detachHeight = internal$1.watchHeight(rootEl, (height) => {
|
|
878
|
+
internal$1.setRef(this.props.heightRef, height);
|
|
879
|
+
});
|
|
880
|
+
}
|
|
881
|
+
componentWillUnmount() {
|
|
882
|
+
this.detachHeight();
|
|
981
883
|
}
|
|
982
884
|
}
|
|
983
885
|
|
|
886
|
+
/*
|
|
887
|
+
TODO: split TimelineLaneBg and TimelineLaneFg?
|
|
888
|
+
*/
|
|
984
889
|
class TimelineLane extends internal$1.BaseComponent {
|
|
985
890
|
constructor() {
|
|
986
891
|
super(...arguments);
|
|
987
|
-
|
|
892
|
+
// memo
|
|
988
893
|
this.sortEventSegs = internal$1.memoize(internal$1.sortEventSegs);
|
|
989
|
-
|
|
990
|
-
this.
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
this.
|
|
994
|
-
|
|
995
|
-
|
|
894
|
+
// refs
|
|
895
|
+
this.segHeightRefMap = new internal$1.RefMap(() => {
|
|
896
|
+
internal$1.afterSize(this.handleSegHeights);
|
|
897
|
+
});
|
|
898
|
+
this.moreLinkHeightRefMap = new internal$1.RefMap(() => {
|
|
899
|
+
internal$1.afterSize(this.handleMoreLinkHeights);
|
|
900
|
+
});
|
|
901
|
+
// internal
|
|
902
|
+
this.slicer = new TimelineLaneSlicer();
|
|
903
|
+
this.handleMoreLinkHeights = () => {
|
|
904
|
+
this.setState({ moreLinkHeightRev: this.moreLinkHeightRefMap.rev }); // will trigger rerender
|
|
996
905
|
};
|
|
997
|
-
this.
|
|
998
|
-
|
|
999
|
-
this.updateSize();
|
|
1000
|
-
}
|
|
906
|
+
this.handleSegHeights = () => {
|
|
907
|
+
this.setState({ segHeightRev: this.segHeightRefMap.rev }); // will trigger rerender
|
|
1001
908
|
};
|
|
1002
909
|
}
|
|
910
|
+
/*
|
|
911
|
+
TODO: lots of memoization needed here!
|
|
912
|
+
*/
|
|
1003
913
|
render() {
|
|
1004
|
-
let { props,
|
|
914
|
+
let { props, context, segHeightRefMap } = this;
|
|
1005
915
|
let { options } = context;
|
|
1006
916
|
let { dateProfile, tDateProfile } = props;
|
|
1007
917
|
let slicedProps = this.slicer.sliceProps(props, dateProfile, tDateProfile.isTimeScale ? null : props.nextDayThreshold, context, // wish we didn't have to pass in the rest of the args...
|
|
@@ -1010,106 +920,275 @@ FullCalendar.Timeline = (function (exports, core, premiumCommonPlugin, internal$
|
|
|
1010
920
|
(slicedProps.eventResize ? slicedProps.eventResize.segs : null) ||
|
|
1011
921
|
[];
|
|
1012
922
|
let fgSegs = this.sortEventSegs(slicedProps.fgEventSegs, options.eventOrder);
|
|
1013
|
-
let
|
|
1014
|
-
|
|
1015
|
-
|
|
923
|
+
let fgSegHorizontals = props.slotWidth != null
|
|
924
|
+
? computeManySegHorizontals(fgSegs, options.eventMinWidth, context.dateEnv, tDateProfile, props.slotWidth)
|
|
925
|
+
: {};
|
|
926
|
+
let [fgSegTops, fgSegsBottom, hiddenGroups, hiddenGroupTops] = computeFgSegPlacements(// verticals
|
|
927
|
+
fgSegs, fgSegHorizontals, segHeightRefMap.current, options.eventOrderStrict, options.eventMaxStack);
|
|
928
|
+
let moreLinksBottom = computeMoreLinkMaxBottom(hiddenGroups, hiddenGroupTops, this.moreLinkHeightRefMap.current);
|
|
929
|
+
let innerHeight = Math.max(moreLinksBottom, fgSegsBottom);
|
|
930
|
+
let forcedInvisibleMap = // TODO: more convenient/DRY
|
|
1016
931
|
(slicedProps.eventDrag ? slicedProps.eventDrag.affectedInstances : null) ||
|
|
1017
932
|
(slicedProps.eventResize ? slicedProps.eventResize.affectedInstances : null) ||
|
|
1018
933
|
{};
|
|
1019
934
|
return (preact.createElement(preact.Fragment, null,
|
|
1020
|
-
preact.createElement(TimelineLaneBg, {
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
935
|
+
preact.createElement(TimelineLaneBg, { tDateProfile: tDateProfile, nowDate: props.nowDate, todayRange: props.todayRange,
|
|
936
|
+
// content
|
|
937
|
+
bgEventSegs: slicedProps.bgEventSegs, businessHourSegs: slicedProps.businessHourSegs, dateSelectionSegs: slicedProps.dateSelectionSegs, eventResizeSegs: slicedProps.eventResize ? slicedProps.eventResize.segs : [] /* bad new empty array? */,
|
|
938
|
+
// dimensions
|
|
939
|
+
slotWidth: props.slotWidth }),
|
|
940
|
+
preact.createElement("div", { className: [
|
|
941
|
+
'fc-timeline-events',
|
|
942
|
+
'fc-content-box',
|
|
943
|
+
options.eventOverlap === false // TODO: fix bad default
|
|
944
|
+
? 'fc-timeline-events-overlap-disabled'
|
|
945
|
+
: 'fc-timeline-events-overlap-enabled'
|
|
946
|
+
].join(' '), style: { height: innerHeight } },
|
|
947
|
+
this.renderFgSegs(fgSegs, fgSegHorizontals, fgSegTops, forcedInvisibleMap, hiddenGroups, hiddenGroupTops, false, // isDragging
|
|
948
|
+
false, // isResizing
|
|
949
|
+
false),
|
|
950
|
+
this.renderFgSegs(mirrorSegs, props.slotWidth // TODO: memoize
|
|
951
|
+
? computeManySegHorizontals(mirrorSegs, options.eventMinWidth, context.dateEnv, tDateProfile, props.slotWidth)
|
|
952
|
+
: {}, fgSegTops, {}, // forcedInvisibleMap
|
|
953
|
+
[], {}, Boolean(slicedProps.eventDrag), Boolean(slicedProps.eventResize), false))));
|
|
954
|
+
}
|
|
955
|
+
renderFgSegs(segs, segHorizontals, segTops, forcedInvisibleMap, hiddenGroups, hiddenGroupTops, isDragging, isResizing, isDateSelecting) {
|
|
956
|
+
let { props, context, segHeightRefMap, moreLinkHeightRefMap } = this;
|
|
957
|
+
let isMirror = isDragging || isResizing || isDateSelecting;
|
|
958
|
+
return (preact.createElement(preact.Fragment, null,
|
|
959
|
+
segs.map((seg) => {
|
|
960
|
+
const { instanceId } = seg.eventRange.instance;
|
|
961
|
+
const segTop = segTops[instanceId];
|
|
962
|
+
const segHorizontal = segHorizontals[instanceId];
|
|
963
|
+
const isVisible = isMirror ||
|
|
964
|
+
(segHorizontal && segTop != null && !forcedInvisibleMap[instanceId]);
|
|
965
|
+
return (preact.createElement(TimelineEventHarness, { key: instanceId, style: Object.assign({ visibility: isVisible ? '' : 'hidden', top: segTop || 0 }, horizontalsToCss(segHorizontal, context.isRtl)), heightRef: isMirror ? undefined : segHeightRefMap.createRef(instanceId) },
|
|
966
|
+
preact.createElement(TimelineEvent, Object.assign({ isTimeScale: props.tDateProfile.isTimeScale, seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === props.eventSelection /* TODO: bad for mirror? */ }, internal$1.getSegMeta(seg, props.todayRange, props.nowDate)))));
|
|
967
|
+
}),
|
|
968
|
+
hiddenGroups.map((hiddenGroup) => (preact.createElement(TimelineEventHarness, { key: hiddenGroup.key, style: Object.assign({ top: hiddenGroupTops[hiddenGroup.key] || 0 }, horizontalsToCss({
|
|
969
|
+
start: hiddenGroup.span.start,
|
|
970
|
+
size: hiddenGroup.span.end - hiddenGroup.span.start
|
|
971
|
+
}, context.isRtl)), heightRef: moreLinkHeightRefMap.createRef(hiddenGroup.key) },
|
|
972
|
+
preact.createElement(TimelineLaneMoreLink, { hiddenSegs: hiddenGroup.segs /* TODO: make SegGroup generic! */, dateProfile: props.dateProfile, nowDate: props.nowDate, todayRange: props.todayRange, isTimeScale: props.tDateProfile.isTimeScale, eventSelection: props.eventSelection, resourceId: props.resourceId, forcedInvisibleMap: forcedInvisibleMap }))))));
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
class TimelineHeaderCell extends internal$1.BaseComponent {
|
|
977
|
+
constructor() {
|
|
978
|
+
super(...arguments);
|
|
979
|
+
// memo
|
|
980
|
+
this.refineRenderProps = internal$1.memoizeObjArg(refineRenderProps);
|
|
981
|
+
this.buildCellNavLinkAttrs = internal$1.memoize(buildCellNavLinkAttrs);
|
|
982
|
+
// ref
|
|
983
|
+
this.innerElRef = preact.createRef();
|
|
984
|
+
// TODO: unset width/height ref on unmount?
|
|
985
|
+
}
|
|
986
|
+
render() {
|
|
987
|
+
let { props, context } = this;
|
|
988
|
+
let { dateEnv, options } = context;
|
|
989
|
+
let { cell, dateProfile, tDateProfile } = props;
|
|
990
|
+
// the cell.rowUnit is f'd
|
|
991
|
+
// giving 'month' for a 3-day view
|
|
992
|
+
// workaround: to infer day, do NOT time
|
|
993
|
+
let dateMeta = internal$1.getDateMeta(cell.date, props.todayRange, props.nowDate, dateProfile);
|
|
994
|
+
let renderProps = this.refineRenderProps({
|
|
995
|
+
level: props.rowLevel,
|
|
996
|
+
dateMarker: cell.date,
|
|
997
|
+
text: cell.text,
|
|
998
|
+
dateEnv: context.dateEnv,
|
|
999
|
+
viewApi: context.viewApi,
|
|
1000
|
+
});
|
|
1001
|
+
return (preact.createElement(internal$1.ContentContainer, { elTag: "div", elClasses: [
|
|
1002
|
+
'fc-timeline-slot-label',
|
|
1003
|
+
'fc-timeline-slot',
|
|
1004
|
+
cell.isWeekStart ? 'fc-timeline-slot-em' : '',
|
|
1005
|
+
'fc-header-cell',
|
|
1006
|
+
'fc-cell',
|
|
1007
|
+
'fc-flex-column',
|
|
1008
|
+
'fc-justify-center',
|
|
1009
|
+
props.isCentered ? 'fc-align-center' : 'fc-align-start',
|
|
1010
|
+
...( // TODO: so slot classnames for week/month/bigger. see note above about rowUnit
|
|
1011
|
+
cell.rowUnit === 'time' ?
|
|
1012
|
+
internal$1.getSlotClassNames(dateMeta, context.theme) :
|
|
1013
|
+
internal$1.getDayClassNames(dateMeta, context.theme)),
|
|
1014
|
+
], elAttrs: {
|
|
1015
|
+
'data-date': dateEnv.formatIso(cell.date, {
|
|
1016
|
+
omitTime: !tDateProfile.isTimeScale,
|
|
1017
|
+
omitTimeZoneOffset: true,
|
|
1018
|
+
}),
|
|
1019
|
+
}, elStyle: {
|
|
1020
|
+
width: props.slotWidth != null
|
|
1021
|
+
? props.slotWidth * cell.colspan
|
|
1022
|
+
: undefined,
|
|
1023
|
+
}, renderProps: renderProps, generatorName: "slotLabelContent", customGenerator: options.slotLabelContent, defaultGenerator: renderInnerContent, classNameGenerator: options.slotLabelClassNames, didMount: options.slotLabelDidMount, willUnmount: options.slotLabelWillUnmount }, (InnerContent) => (preact.createElement("div", { ref: this.innerElRef, className: [
|
|
1024
|
+
'fc-flex-column',
|
|
1025
|
+
props.isSticky ? 'fc-sticky-x' : '',
|
|
1026
|
+
].join(' ') },
|
|
1027
|
+
preact.createElement(InnerContent, { elTag: "a", elClasses: [
|
|
1028
|
+
'fc-cell-inner',
|
|
1029
|
+
'fc-padding-md',
|
|
1030
|
+
], elAttrs: this.buildCellNavLinkAttrs(context, cell.date, cell.rowUnit) })))));
|
|
1024
1031
|
}
|
|
1025
1032
|
componentDidMount() {
|
|
1026
|
-
this
|
|
1027
|
-
this.
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1033
|
+
const { props } = this;
|
|
1034
|
+
const innerEl = this.innerElRef.current; // TODO: make dynamic with useEffect
|
|
1035
|
+
this.detachSize = internal$1.watchSize(innerEl, (width, height) => {
|
|
1036
|
+
internal$1.setRef(props.innerWidthRef, width);
|
|
1037
|
+
internal$1.setRef(props.innerHeightRef, height);
|
|
1038
|
+
// HACK for sticky-centering
|
|
1039
|
+
innerEl.style.left = innerEl.style.right =
|
|
1040
|
+
(props.isCentered && props.isSticky)
|
|
1041
|
+
? `calc(50% - ${width / 2}px)`
|
|
1042
|
+
: '';
|
|
1043
|
+
});
|
|
1036
1044
|
}
|
|
1037
1045
|
componentWillUnmount() {
|
|
1038
|
-
this.
|
|
1039
|
-
}
|
|
1040
|
-
updateSize() {
|
|
1041
|
-
let { props } = this;
|
|
1042
|
-
let { timelineCoords } = props;
|
|
1043
|
-
const innerEl = this.innerElRef.current;
|
|
1044
|
-
if (props.onHeightChange) {
|
|
1045
|
-
props.onHeightChange(innerEl, false);
|
|
1046
|
-
}
|
|
1047
|
-
if (timelineCoords) {
|
|
1048
|
-
this.setState({
|
|
1049
|
-
eventInstanceHeights: internal$1.mapHash(this.harnessElRefs.currentMap, (harnessEl) => (Math.round(harnessEl.getBoundingClientRect().height))),
|
|
1050
|
-
moreLinkHeights: internal$1.mapHash(this.moreElRefs.currentMap, (moreEl) => (Math.round(moreEl.getBoundingClientRect().height))),
|
|
1051
|
-
}, () => {
|
|
1052
|
-
if (props.onHeightChange) {
|
|
1053
|
-
props.onHeightChange(innerEl, true);
|
|
1054
|
-
}
|
|
1055
|
-
});
|
|
1056
|
-
}
|
|
1057
|
-
// hack
|
|
1058
|
-
if (props.syncParentMinHeight) {
|
|
1059
|
-
innerEl.parentElement.style.minHeight = innerEl.style.height;
|
|
1060
|
-
}
|
|
1046
|
+
this.detachSize();
|
|
1061
1047
|
}
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1048
|
+
}
|
|
1049
|
+
// Utils
|
|
1050
|
+
// -------------------------------------------------------------------------------------------------
|
|
1051
|
+
function buildCellNavLinkAttrs(context, cellDate, rowUnit) {
|
|
1052
|
+
return (rowUnit && rowUnit !== 'time')
|
|
1053
|
+
? internal$1.buildNavLinkAttrs(context, cellDate, rowUnit)
|
|
1054
|
+
: {};
|
|
1055
|
+
}
|
|
1056
|
+
function renderInnerContent(renderProps) {
|
|
1057
|
+
return renderProps.text;
|
|
1058
|
+
}
|
|
1059
|
+
function refineRenderProps(input) {
|
|
1060
|
+
return {
|
|
1061
|
+
level: input.level,
|
|
1062
|
+
date: input.dateEnv.toDate(input.dateMarker),
|
|
1063
|
+
view: input.viewApi,
|
|
1064
|
+
text: input.text,
|
|
1065
|
+
};
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
class TimelineHeaderRow extends internal$1.BaseComponent {
|
|
1069
|
+
constructor() {
|
|
1070
|
+
super(...arguments);
|
|
1071
|
+
// refs
|
|
1072
|
+
this.innerWidthRefMap = new internal$1.RefMap(() => {
|
|
1073
|
+
internal$1.afterSize(this.handleInnerWidths);
|
|
1074
|
+
});
|
|
1075
|
+
this.innerHeightRefMap = new internal$1.RefMap(() => {
|
|
1076
|
+
internal$1.afterSize(this.handleInnerHeights);
|
|
1077
|
+
});
|
|
1078
|
+
this.handleInnerWidths = () => {
|
|
1079
|
+
const innerWidthMap = this.innerWidthRefMap.current;
|
|
1080
|
+
let max = 0;
|
|
1081
|
+
for (const innerWidth of innerWidthMap.values()) {
|
|
1082
|
+
max = Math.max(max, innerWidth);
|
|
1083
|
+
}
|
|
1084
|
+
// TODO: ensure not equal?
|
|
1085
|
+
internal$1.setRef(this.props.innerWidthRef, max);
|
|
1086
|
+
};
|
|
1087
|
+
this.handleInnerHeights = () => {
|
|
1088
|
+
const innerHeightMap = this.innerHeightRefMap.current;
|
|
1089
|
+
let max = 0;
|
|
1090
|
+
for (const innerHeight of innerHeightMap.values()) {
|
|
1091
|
+
max = Math.max(max, innerHeight);
|
|
1070
1092
|
}
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1093
|
+
// TODO: ensure not equal?
|
|
1094
|
+
internal$1.setRef(this.props.innerHeighRef, max);
|
|
1095
|
+
};
|
|
1096
|
+
}
|
|
1097
|
+
render() {
|
|
1098
|
+
const { props, innerWidthRefMap, innerHeightRefMap } = this;
|
|
1099
|
+
const isCentered = !(props.tDateProfile.isTimeScale && props.isLastRow);
|
|
1100
|
+
const isSticky = !props.isLastRow;
|
|
1101
|
+
return (preact.createElement("div", { className: 'fc-row', style: { height: props.height } }, props.cells.map((cell) => {
|
|
1102
|
+
// TODO: make this part of the cell obj?
|
|
1103
|
+
// TODO: rowUnit seems wrong sometimes. says 'month' when it should be day
|
|
1104
|
+
// TODO: rowUnit is relevant to whole row. put it on a row object, not the cells
|
|
1105
|
+
const key = cell.rowUnit + ':' + cell.date.toISOString();
|
|
1106
|
+
return (preact.createElement(TimelineHeaderCell, { key: key, cell: cell, rowLevel: props.rowLevel, dateProfile: props.dateProfile, tDateProfile: props.tDateProfile, todayRange: props.todayRange, nowDate: props.nowDate, isCentered: isCentered, isSticky: isSticky,
|
|
1107
|
+
// refs
|
|
1108
|
+
innerWidthRef: innerWidthRefMap.createRef(key), innerHeightRef: innerHeightRefMap.createRef(key),
|
|
1109
|
+
// dimensions
|
|
1110
|
+
slotWidth: props.slotWidth }));
|
|
1076
1111
|
})));
|
|
1077
1112
|
}
|
|
1078
1113
|
}
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
seg,
|
|
1090
|
-
hcoords: timelineCoords.rangeToCoords(seg),
|
|
1091
|
-
top: topsByInstanceId[seg.eventRange.instance.instanceId],
|
|
1092
|
-
}));
|
|
1114
|
+
|
|
1115
|
+
class TimelineNowIndicatorLine extends internal$1.BaseComponent {
|
|
1116
|
+
render() {
|
|
1117
|
+
const { props, context } = this;
|
|
1118
|
+
return (preact.createElement("div", { className: "fc-timeline-now-indicator-container" },
|
|
1119
|
+
preact.createElement(internal$1.NowIndicatorContainer // TODO: make separate component?
|
|
1120
|
+
, { elClasses: ['fc-timeline-now-indicator-line'], elStyle: props.slotWidth != null
|
|
1121
|
+
? horizontalCoordToCss(dateToCoord(props.nowDate, context.dateEnv, props.tDateProfile, props.slotWidth), context.isRtl)
|
|
1122
|
+
: {}, isAxis: false, date: props.nowDate })));
|
|
1123
|
+
}
|
|
1093
1124
|
}
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1125
|
+
|
|
1126
|
+
class TimelineNowIndicatorArrow extends internal$1.BaseComponent {
|
|
1127
|
+
render() {
|
|
1128
|
+
const { props, context } = this;
|
|
1129
|
+
return (preact.createElement("div", { className: "fc-timeline-now-indicator-container" },
|
|
1130
|
+
preact.createElement(internal$1.NowIndicatorContainer, { elClasses: ['fc-timeline-now-indicator-arrow'], elStyle: props.slotWidth != null
|
|
1131
|
+
? horizontalCoordToCss(dateToCoord(props.nowDate, context.dateEnv, props.tDateProfile, props.slotWidth), context.isRtl)
|
|
1132
|
+
: {}, isAxis: true, date: props.nowDate })));
|
|
1101
1133
|
}
|
|
1102
|
-
return topsByInstanceId;
|
|
1103
1134
|
}
|
|
1104
1135
|
|
|
1105
|
-
class
|
|
1136
|
+
class TimelineView extends internal$1.DateComponent {
|
|
1106
1137
|
constructor() {
|
|
1107
1138
|
super(...arguments);
|
|
1108
|
-
|
|
1109
|
-
this.
|
|
1110
|
-
|
|
1139
|
+
// memoized
|
|
1140
|
+
this.buildTimelineDateProfile = internal$1.memoize(buildTimelineDateProfile);
|
|
1141
|
+
this.computeSlotWidth = internal$1.memoize(computeSlotWidth);
|
|
1142
|
+
// refs
|
|
1143
|
+
this.headerScrollerRef = preact.createRef();
|
|
1144
|
+
this.bodyScrollerRef = preact.createRef();
|
|
1145
|
+
this.footerScrollerRef = preact.createRef();
|
|
1146
|
+
// Sizing
|
|
1147
|
+
// -----------------------------------------------------------------------------------------------
|
|
1148
|
+
this.handleHeaderSlotInnerWidth = (innerWidth) => {
|
|
1149
|
+
this.headerSlotInnerWidth = innerWidth;
|
|
1150
|
+
internal$1.afterSize(this.handleSlotInnerWidths);
|
|
1151
|
+
};
|
|
1152
|
+
this.handleBodySlotInnerWidth = (innerWidth) => {
|
|
1153
|
+
this.bodySlotInnerWidth = innerWidth;
|
|
1154
|
+
internal$1.afterSize(this.handleSlotInnerWidths);
|
|
1111
1155
|
};
|
|
1112
|
-
this.
|
|
1156
|
+
this.handleSlotInnerWidths = () => {
|
|
1157
|
+
const { state } = this;
|
|
1158
|
+
const slotInnerWidth = Math.max(this.headerSlotInnerWidth, this.bodySlotInnerWidth);
|
|
1159
|
+
if (state.slotInnerWidth !== slotInnerWidth) {
|
|
1160
|
+
this.setState({ slotInnerWidth });
|
|
1161
|
+
}
|
|
1162
|
+
};
|
|
1163
|
+
this.handleScrollerWidth = (scrollerWidth) => {
|
|
1164
|
+
this.setState({
|
|
1165
|
+
scrollerWidth,
|
|
1166
|
+
});
|
|
1167
|
+
};
|
|
1168
|
+
this.handleLeftScrollbarWidth = (leftScrollbarWidth) => {
|
|
1169
|
+
this.setState({
|
|
1170
|
+
leftScrollbarWidth
|
|
1171
|
+
});
|
|
1172
|
+
};
|
|
1173
|
+
this.handleRightScrollbarWidth = (rightScrollbarWidth) => {
|
|
1174
|
+
this.setState({
|
|
1175
|
+
rightScrollbarWidth
|
|
1176
|
+
});
|
|
1177
|
+
};
|
|
1178
|
+
this.timeScrollResponder = new internal$1.ScrollResponder((time) => {
|
|
1179
|
+
const { props, context, tDateProfile, slotWidth } = this;
|
|
1180
|
+
if (slotWidth != null) {
|
|
1181
|
+
const x = timeToCoord(time, context.dateEnv, props.dateProfile, tDateProfile, slotWidth) +
|
|
1182
|
+
(context.isRtl ? -1 : 1); // overcome border. TODO: DRY this up
|
|
1183
|
+
this.syncedScroller.scrollTo({ x });
|
|
1184
|
+
return true;
|
|
1185
|
+
}
|
|
1186
|
+
return false;
|
|
1187
|
+
});
|
|
1188
|
+
// Hit System
|
|
1189
|
+
// -----------------------------------------------------------------------------------------------
|
|
1190
|
+
this.handeBodyEl = (el) => {
|
|
1191
|
+
this.bodyEl = el;
|
|
1113
1192
|
if (el) {
|
|
1114
1193
|
this.context.registerInteractiveComponent(this, { el });
|
|
1115
1194
|
}
|
|
@@ -1117,45 +1196,141 @@ FullCalendar.Timeline = (function (exports, core, premiumCommonPlugin, internal$
|
|
|
1117
1196
|
this.context.unregisterInteractiveComponent(this);
|
|
1118
1197
|
}
|
|
1119
1198
|
};
|
|
1120
|
-
this.handleCoords = (coords) => {
|
|
1121
|
-
this.setState({ coords });
|
|
1122
|
-
if (this.props.onSlatCoords) {
|
|
1123
|
-
this.props.onSlatCoords(coords);
|
|
1124
|
-
}
|
|
1125
|
-
};
|
|
1126
1199
|
}
|
|
1127
1200
|
render() {
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1201
|
+
const { props, state, context } = this;
|
|
1202
|
+
const { options } = context;
|
|
1203
|
+
/* date */
|
|
1204
|
+
const tDateProfile = this.tDateProfile = this.buildTimelineDateProfile(props.dateProfile, context.dateEnv, options, context.dateProfileGenerator);
|
|
1205
|
+
const { cellRows } = tDateProfile;
|
|
1206
|
+
const timerUnit = internal$1.greatestDurationDenominator(tDateProfile.slotDuration).unit;
|
|
1207
|
+
/* table settings */
|
|
1208
|
+
const verticalScrolling = !props.forPrint && !internal$1.getIsHeightAuto(options);
|
|
1209
|
+
const stickyHeaderDates = !props.forPrint && internal$1.getStickyHeaderDates(options);
|
|
1210
|
+
const stickyFooterScrollbar = !props.forPrint && internal$1.getStickyFooterScrollbar(options);
|
|
1211
|
+
/* table positions */
|
|
1212
|
+
const [canvasWidth, slotWidth] = this.computeSlotWidth(tDateProfile.slotCnt, tDateProfile.slotsPerLabel, options.slotMinWidth, state.slotInnerWidth, // is ACTUALLY the label width. rename?
|
|
1213
|
+
state.scrollerWidth);
|
|
1214
|
+
this.slotWidth = slotWidth;
|
|
1215
|
+
return (preact.createElement(internal$1.NowTimer, { unit: timerUnit }, (nowDate, todayRange) => {
|
|
1216
|
+
const enableNowIndicator = // TODO: DRY
|
|
1217
|
+
options.nowIndicator &&
|
|
1218
|
+
slotWidth != null &&
|
|
1219
|
+
internal$1.rangeContainsMarker(props.dateProfile.currentRange, nowDate);
|
|
1220
|
+
return (preact.createElement(internal$1.ViewContainer, { viewSpec: context.viewSpec, elClasses: [
|
|
1221
|
+
'fc-timeline-view',
|
|
1222
|
+
'fc-flex-column',
|
|
1223
|
+
'fc-border',
|
|
1224
|
+
] },
|
|
1225
|
+
preact.createElement(internal$1.Scroller, { horizontal: true, hideScrollbars: true, elClassNames: [
|
|
1226
|
+
'fc-timeline-header',
|
|
1227
|
+
'fc-rowgroup',
|
|
1228
|
+
stickyHeaderDates ? 'fc-sticky-header' : '',
|
|
1229
|
+
], ref: this.headerScrollerRef },
|
|
1230
|
+
preact.createElement("div", { className: 'fc-rel fc-content-box' // origin for now-indicator
|
|
1231
|
+
, style: {
|
|
1232
|
+
width: canvasWidth,
|
|
1233
|
+
paddingLeft: state.leftScrollbarWidth,
|
|
1234
|
+
paddingRight: state.rightScrollbarWidth,
|
|
1235
|
+
} },
|
|
1236
|
+
preact.createElement("div", null, cellRows.map((cells, rowLevel) => {
|
|
1237
|
+
const isLast = rowLevel === cellRows.length - 1;
|
|
1238
|
+
return (preact.createElement(TimelineHeaderRow, { key: rowLevel, dateProfile: props.dateProfile, tDateProfile: tDateProfile, nowDate: nowDate, todayRange: todayRange, rowLevel: rowLevel, isLastRow: isLast, cells: cells, slotWidth: slotWidth, innerWidthRef: isLast ? this.handleHeaderSlotInnerWidth : undefined }));
|
|
1239
|
+
})),
|
|
1240
|
+
enableNowIndicator && (
|
|
1241
|
+
// TODO: make this positioned WITHIN padding?
|
|
1242
|
+
preact.createElement(TimelineNowIndicatorArrow, { tDateProfile: tDateProfile, nowDate: nowDate, slotWidth: slotWidth })))),
|
|
1243
|
+
preact.createElement(internal$1.Scroller, { vertical: verticalScrolling, horizontal: true, elClassNames: [
|
|
1244
|
+
'fc-timeline-body',
|
|
1245
|
+
'fc-rowgroup',
|
|
1246
|
+
verticalScrolling ? 'fc-liquid' : '',
|
|
1247
|
+
], ref: this.bodyScrollerRef, widthRef: this.handleScrollerWidth, leftScrollbarWidthRef: this.handleLeftScrollbarWidth, rightScrollbarWidthRef: this.handleRightScrollbarWidth },
|
|
1248
|
+
preact.createElement("div", { className: "fc-rel fc-grow", style: {
|
|
1249
|
+
width: canvasWidth,
|
|
1250
|
+
}, ref: this.handeBodyEl },
|
|
1251
|
+
preact.createElement(TimelineSlats, { dateProfile: props.dateProfile, tDateProfile: tDateProfile, nowDate: nowDate, todayRange: todayRange,
|
|
1252
|
+
// ref
|
|
1253
|
+
innerWidthRef: this.handleBodySlotInnerWidth,
|
|
1254
|
+
// dimensions
|
|
1255
|
+
slotWidth: slotWidth }),
|
|
1256
|
+
preact.createElement(TimelineLane, { dateProfile: props.dateProfile, tDateProfile: tDateProfile, nowDate: nowDate, todayRange: todayRange, nextDayThreshold: options.nextDayThreshold, eventStore: props.eventStore, eventUiBases: props.eventUiBases, businessHours: props.businessHours, dateSelection: props.dateSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, eventSelection: props.eventSelection, slotWidth: slotWidth }),
|
|
1257
|
+
enableNowIndicator && (preact.createElement(TimelineNowIndicatorLine, { tDateProfile: tDateProfile, nowDate: nowDate, slotWidth: slotWidth })))),
|
|
1258
|
+
stickyFooterScrollbar && (preact.createElement(internal$1.Scroller, { ref: this.footerScrollerRef, horizontal: true },
|
|
1259
|
+
preact.createElement("div", { style: { width: canvasWidth } })))));
|
|
1260
|
+
}));
|
|
1261
|
+
}
|
|
1262
|
+
// Lifecycle
|
|
1263
|
+
// -----------------------------------------------------------------------------------------------
|
|
1264
|
+
componentDidMount() {
|
|
1265
|
+
const { context } = this;
|
|
1266
|
+
const { options } = context;
|
|
1267
|
+
const ScrollerSyncer = internal$1.getScrollerSyncerClass(this.context.pluginHooks);
|
|
1268
|
+
this.syncedScroller = new ScrollerSyncer(true); // horizontal=true
|
|
1269
|
+
this.updateSyncedScroller();
|
|
1270
|
+
context.emitter.on('_timeScrollRequest', this.timeScrollResponder.handleScroll);
|
|
1271
|
+
this.timeScrollResponder.handleScroll(options.scrollTime);
|
|
1272
|
+
}
|
|
1273
|
+
componentDidUpdate(prevProps) {
|
|
1274
|
+
const { options } = this.context;
|
|
1275
|
+
this.updateSyncedScroller();
|
|
1276
|
+
if (prevProps.dateProfile !== this.props.dateProfile && options.scrollTimeReset) {
|
|
1277
|
+
this.timeScrollResponder.handleScroll(options.scrollTime);
|
|
1278
|
+
}
|
|
1279
|
+
else {
|
|
1280
|
+
this.timeScrollResponder.drain();
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
componentWillUnmount() {
|
|
1284
|
+
this.syncedScroller.destroy();
|
|
1285
|
+
this.context.emitter.off('_timeScrollRequest', this.timeScrollResponder.handleScroll);
|
|
1286
|
+
}
|
|
1287
|
+
// Scrolling
|
|
1288
|
+
// -----------------------------------------------------------------------------------------------
|
|
1289
|
+
updateSyncedScroller() {
|
|
1290
|
+
this.syncedScroller.handleChildren([
|
|
1291
|
+
this.headerScrollerRef.current,
|
|
1292
|
+
this.bodyScrollerRef.current,
|
|
1293
|
+
this.footerScrollerRef.current
|
|
1294
|
+
], this.context.isRtl);
|
|
1295
|
+
}
|
|
1145
1296
|
queryHit(positionLeft, positionTop, elWidth, elHeight) {
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
if (
|
|
1297
|
+
const { props, context, tDateProfile, slotWidth } = this;
|
|
1298
|
+
const { dateEnv } = context;
|
|
1299
|
+
if (slotWidth) {
|
|
1300
|
+
const x = context.isRtl ? elWidth - positionLeft : positionLeft;
|
|
1301
|
+
const slatIndex = Math.floor(x / slotWidth);
|
|
1302
|
+
const slatX = slatIndex * slotWidth;
|
|
1303
|
+
const partial = (x - slatX) / slotWidth; // floating point number between 0 and 1
|
|
1304
|
+
const localSnapIndex = Math.floor(partial * tDateProfile.snapsPerSlot); // the snap # relative to start of slat
|
|
1305
|
+
let startDate = dateEnv.add(tDateProfile.slotDates[slatIndex], internal$1.multiplyDuration(tDateProfile.snapDuration, localSnapIndex));
|
|
1306
|
+
let endDate = dateEnv.add(startDate, tDateProfile.snapDuration);
|
|
1307
|
+
// TODO: generalize this coord stuff to TimeGrid?
|
|
1308
|
+
let snapWidth = slotWidth / tDateProfile.snapsPerSlot;
|
|
1309
|
+
let startCoord = slatIndex * slotWidth + (snapWidth * localSnapIndex);
|
|
1310
|
+
let endCoord = startCoord + snapWidth;
|
|
1311
|
+
let left, right;
|
|
1312
|
+
if (context.isRtl) {
|
|
1313
|
+
left = elWidth - endCoord;
|
|
1314
|
+
right = elWidth - startCoord;
|
|
1315
|
+
}
|
|
1316
|
+
else {
|
|
1317
|
+
left = startCoord;
|
|
1318
|
+
right = endCoord;
|
|
1319
|
+
}
|
|
1149
1320
|
return {
|
|
1150
|
-
dateProfile:
|
|
1151
|
-
dateSpan:
|
|
1321
|
+
dateProfile: props.dateProfile,
|
|
1322
|
+
dateSpan: {
|
|
1323
|
+
range: { start: startDate, end: endDate },
|
|
1324
|
+
allDay: !tDateProfile.isTimeScale,
|
|
1325
|
+
},
|
|
1152
1326
|
rect: {
|
|
1153
|
-
left
|
|
1154
|
-
right
|
|
1327
|
+
left,
|
|
1328
|
+
right,
|
|
1155
1329
|
top: 0,
|
|
1156
1330
|
bottom: elHeight,
|
|
1157
1331
|
},
|
|
1158
|
-
|
|
1332
|
+
// HACK. TODO: This is expensive to do every hit-query
|
|
1333
|
+
dayEl: this.bodyEl.querySelectorAll('.fc-timeline-slot')[slatIndex],
|
|
1159
1334
|
layer: 0,
|
|
1160
1335
|
};
|
|
1161
1336
|
}
|
|
@@ -1163,94 +1338,12 @@ FullCalendar.Timeline = (function (exports, core, premiumCommonPlugin, internal$
|
|
|
1163
1338
|
}
|
|
1164
1339
|
}
|
|
1165
1340
|
|
|
1166
|
-
|
|
1167
|
-
constructor() {
|
|
1168
|
-
super(...arguments);
|
|
1169
|
-
this.buildTimelineDateProfile = internal$1.memoize(buildTimelineDateProfile);
|
|
1170
|
-
this.scrollGridRef = preact.createRef();
|
|
1171
|
-
this.state = {
|
|
1172
|
-
slatCoords: null,
|
|
1173
|
-
slotCushionMaxWidth: null,
|
|
1174
|
-
};
|
|
1175
|
-
this.handleSlatCoords = (slatCoords) => {
|
|
1176
|
-
this.setState({ slatCoords });
|
|
1177
|
-
};
|
|
1178
|
-
this.handleScrollLeftRequest = (scrollLeft) => {
|
|
1179
|
-
let scrollGrid = this.scrollGridRef.current;
|
|
1180
|
-
scrollGrid.forceScrollLeft(0, scrollLeft);
|
|
1181
|
-
};
|
|
1182
|
-
this.handleMaxCushionWidth = (slotCushionMaxWidth) => {
|
|
1183
|
-
this.setState({
|
|
1184
|
-
slotCushionMaxWidth: Math.ceil(slotCushionMaxWidth), // for less rerendering TODO: DRY
|
|
1185
|
-
});
|
|
1186
|
-
};
|
|
1187
|
-
}
|
|
1188
|
-
render() {
|
|
1189
|
-
let { props, state, context } = this;
|
|
1190
|
-
let { options } = context;
|
|
1191
|
-
let stickyHeaderDates = !props.forPrint && internal$1.getStickyHeaderDates(options);
|
|
1192
|
-
let stickyFooterScrollbar = !props.forPrint && internal$1.getStickyFooterScrollbar(options);
|
|
1193
|
-
let tDateProfile = this.buildTimelineDateProfile(props.dateProfile, context.dateEnv, options, context.dateProfileGenerator);
|
|
1194
|
-
let { slotMinWidth } = options;
|
|
1195
|
-
let slatCols = buildSlatCols(tDateProfile, slotMinWidth || this.computeFallbackSlotMinWidth(tDateProfile));
|
|
1196
|
-
let sections = [
|
|
1197
|
-
{
|
|
1198
|
-
type: 'header',
|
|
1199
|
-
key: 'header',
|
|
1200
|
-
isSticky: stickyHeaderDates,
|
|
1201
|
-
chunks: [{
|
|
1202
|
-
key: 'timeline',
|
|
1203
|
-
content: (contentArg) => (preact.createElement(TimelineHeader, { dateProfile: props.dateProfile, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, tableMinWidth: contentArg.tableMinWidth, tableColGroupNode: contentArg.tableColGroupNode, tDateProfile: tDateProfile, slatCoords: state.slatCoords, onMaxCushionWidth: slotMinWidth ? null : this.handleMaxCushionWidth })),
|
|
1204
|
-
}],
|
|
1205
|
-
},
|
|
1206
|
-
{
|
|
1207
|
-
type: 'body',
|
|
1208
|
-
key: 'body',
|
|
1209
|
-
liquid: true,
|
|
1210
|
-
chunks: [{
|
|
1211
|
-
key: 'timeline',
|
|
1212
|
-
content: (contentArg) => (preact.createElement(TimelineGrid, Object.assign({}, props, { clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, tableMinWidth: contentArg.tableMinWidth, tableColGroupNode: contentArg.tableColGroupNode, tDateProfile: tDateProfile, onSlatCoords: this.handleSlatCoords, onScrollLeftRequest: this.handleScrollLeftRequest }))),
|
|
1213
|
-
}],
|
|
1214
|
-
},
|
|
1215
|
-
];
|
|
1216
|
-
if (stickyFooterScrollbar) {
|
|
1217
|
-
sections.push({
|
|
1218
|
-
type: 'footer',
|
|
1219
|
-
key: 'footer',
|
|
1220
|
-
isSticky: true,
|
|
1221
|
-
chunks: [{
|
|
1222
|
-
key: 'timeline',
|
|
1223
|
-
content: internal$1.renderScrollShim,
|
|
1224
|
-
}],
|
|
1225
|
-
});
|
|
1226
|
-
}
|
|
1227
|
-
return (preact.createElement(internal$1.ViewContainer, { elClasses: [
|
|
1228
|
-
'fc-timeline',
|
|
1229
|
-
options.eventOverlap === false ?
|
|
1230
|
-
'fc-timeline-overlap-disabled' :
|
|
1231
|
-
'',
|
|
1232
|
-
], viewSpec: context.viewSpec },
|
|
1233
|
-
preact.createElement(internal$2.ScrollGrid, { ref: this.scrollGridRef, liquid: !props.isHeightAuto && !props.forPrint, forPrint: props.forPrint, collapsibleWidth: false, colGroups: [
|
|
1234
|
-
{ cols: slatCols },
|
|
1235
|
-
], sections: sections })));
|
|
1236
|
-
}
|
|
1237
|
-
computeFallbackSlotMinWidth(tDateProfile) {
|
|
1238
|
-
return Math.max(30, ((this.state.slotCushionMaxWidth || 0) / tDateProfile.slotsPerLabel));
|
|
1239
|
-
}
|
|
1240
|
-
}
|
|
1241
|
-
function buildSlatCols(tDateProfile, slotMinWidth) {
|
|
1242
|
-
return [{
|
|
1243
|
-
span: tDateProfile.slotCnt,
|
|
1244
|
-
minWidth: slotMinWidth || 1, // needs to be a non-zero number to trigger horizontal scrollbars!??????
|
|
1245
|
-
}];
|
|
1246
|
-
}
|
|
1247
|
-
|
|
1248
|
-
var css_248z = ".fc .fc-timeline-body{min-height:100%;position:relative;z-index:1}.fc .fc-timeline-slots{bottom:0;position:absolute;top:0;z-index:1}.fc .fc-timeline-slots>table{height:100%}.fc .fc-timeline-slot-minor{border-style:dotted}.fc .fc-timeline-slot-frame{align-items:center;display:flex;justify-content:center}.fc .fc-timeline-header-row-chrono .fc-timeline-slot-frame{justify-content:flex-start}.fc .fc-timeline-header-row:last-child .fc-timeline-slot-frame{overflow:hidden}.fc .fc-timeline-slot-cushion{padding:4px 5px;white-space:nowrap}.fc-direction-ltr .fc-timeline-slot{border-right:0!important}.fc-direction-rtl .fc-timeline-slot{border-left:0!important}.fc .fc-timeline-now-indicator-container{bottom:0;left:0;position:absolute;right:0;top:0;width:0;z-index:4}.fc .fc-timeline-now-indicator-arrow,.fc .fc-timeline-now-indicator-line{border-color:var(--fc-now-indicator-color);border-style:solid;pointer-events:none;position:absolute;top:0}.fc .fc-timeline-now-indicator-arrow{border-left-color:transparent;border-right-color:transparent;border-width:6px 5px 0;margin:0 -6px}.fc .fc-timeline-now-indicator-line{border-width:0 0 0 1px;bottom:0;margin:0 -1px}.fc .fc-timeline-events{position:relative;width:0;z-index:3}.fc .fc-timeline-event-harness,.fc .fc-timeline-more-link{position:absolute;top:0}.fc-timeline-event{z-index:1}.fc-timeline-event.fc-event-mirror{z-index:2}.fc-timeline-event{align-items:center;border-radius:0;display:flex;font-size:var(--fc-small-font-size);margin-bottom:1px;padding:2px 1px;position:relative}.fc-timeline-event .fc-event-main{flex-grow:1;flex-shrink:1;min-width:0}.fc-timeline-event .fc-event-time{font-weight:700}.fc-timeline-event .fc-event-time,.fc-timeline-event .fc-event-title{padding:0 2px;white-space:nowrap}.fc-direction-ltr .fc-timeline-event.fc-event-end,.fc-direction-ltr .fc-timeline-more-link{margin-right:1px}.fc-direction-rtl .fc-timeline-event.fc-event-end,.fc-direction-rtl .fc-timeline-more-link{margin-left:1px}.fc-timeline-overlap-disabled .fc-timeline-event{margin-bottom:0;padding-bottom:5px;padding-top:5px}.fc-timeline-event:not(.fc-event-end):after,.fc-timeline-event:not(.fc-event-start):before{border-color:transparent #000;border-style:solid;border-width:5px;content:\"\";flex-grow:0;flex-shrink:0;height:0;margin:0 1px;opacity:.5;width:0}.fc-direction-ltr .fc-timeline-event:not(.fc-event-start):before,.fc-direction-rtl .fc-timeline-event:not(.fc-event-end):after{border-left:0}.fc-direction-ltr .fc-timeline-event:not(.fc-event-end):after,.fc-direction-rtl .fc-timeline-event:not(.fc-event-start):before{border-right:0}.fc-timeline-more-link{background:var(--fc-more-link-bg-color);color:var(--fc-more-link-text-color);cursor:pointer;font-size:var(--fc-small-font-size);padding:1px}.fc-timeline-more-link-inner{display:inline-block;left:0;padding:2px;right:0}.fc .fc-timeline-bg{bottom:0;left:0;position:absolute;right:0;top:0;width:0;z-index:2}.fc .fc-timeline-bg .fc-non-business{z-index:1}.fc .fc-timeline-bg .fc-bg-event{z-index:2}.fc .fc-timeline-bg .fc-highlight{z-index:3}.fc .fc-timeline-bg-harness{bottom:0;position:absolute;top:0}";
|
|
1341
|
+
var css_248z = ".fc-timeline-slots{z-index:1}.fc-timeline-slot-minor{border-style:dotted}.fc-timeline-now-indicator-container{bottom:0;left:0;overflow:hidden;position:absolute;right:0;top:0;z-index:4}.fc-timeline-now-indicator-arrow,.fc-timeline-now-indicator-line{border-color:var(--fc-now-indicator-color);border-style:solid;pointer-events:none;position:absolute;top:0}.fc-timeline-now-indicator-arrow{border-left-color:transparent;border-right-color:transparent;border-width:6px 5px 0;margin:0 -5px}.fc-timeline-now-indicator-line{border-width:0 0 0 1px;bottom:0}.fc-timeline-events{z-index:3}.fc-timeline-events-overlap-enabled{padding-bottom:10px}.fc-timeline-event{border-radius:0;font-size:var(--fc-small-font-size);margin-bottom:1px;z-index:1}.fc-timeline-event.fc-event-mirror{z-index:2}.fc-direction-ltr .fc-timeline-event.fc-event-end{margin-right:1px}.fc-direction-rtl .fc-timeline-event.fc-event-end{margin-left:1px}.fc-timeline-event-spacious{margin-bottom:0;padding-bottom:5px;padding-top:5px}.fc-timeline-event .fc-event-inner{align-items:center;display:flex;flex-direction:row;padding:2px 1px}.fc-timeline-event:not(.fc-event-end) .fc-event-inner:after,.fc-timeline-event:not(.fc-event-start) .fc-event-inner:before{border-color:transparent #000;border-style:solid;border-width:5px;content:\"\";flex-grow:0;flex-shrink:0;height:0;margin:0 1px;opacity:.5;width:0}.fc-direction-ltr .fc-timeline-event:not(.fc-event-start) .fc-event-inner:before,.fc-direction-rtl .fc-timeline-event:not(.fc-event-end) .fc-event-inner:after{border-left:0}.fc-direction-ltr .fc-timeline-event:not(.fc-event-end) .fc-event-inner:after,.fc-direction-rtl .fc-timeline-event:not(.fc-event-start) .fc-event-inner:before{border-right:0}.fc-timeline-event .fc-event-time{font-weight:700}.fc-timeline-event .fc-event-time,.fc-timeline-event .fc-event-title{padding:0 2px}.fc-timeline-more-link{align-items:flex-start;background:var(--fc-more-link-bg-color);color:var(--fc-more-link-text-color);cursor:pointer;display:flex;flex-direction:column;font-size:var(--fc-small-font-size);padding:1px}.fc-direction-ltr .fc-timeline-more-link{margin-right:1px}.fc-direction-rtl .fc-timeline-more-link{margin-left:1px}.fc-timeline-more-link-inner{padding:2px}.fc-timeline-bg{bottom:0;left:0;position:absolute;right:0;top:0;z-index:2}.fc-timeline-bg .fc-non-business{z-index:1}.fc-timeline-bg .fc-bg-event{z-index:2}.fc-timeline-bg .fc-highlight{z-index:3}.fc-timeline-bg-harness{bottom:0;position:absolute;top:0}";
|
|
1249
1342
|
internal$1.injectStyles(css_248z);
|
|
1250
1343
|
|
|
1251
1344
|
var plugin = core.createPlugin({
|
|
1252
1345
|
name: '@fullcalendar/timeline',
|
|
1253
|
-
premiumReleaseDate: '2024-
|
|
1346
|
+
premiumReleaseDate: '2024-10-01',
|
|
1254
1347
|
deps: [premiumCommonPlugin__default["default"]],
|
|
1255
1348
|
initialView: 'timelineDay',
|
|
1256
1349
|
views: {
|
|
@@ -1281,17 +1374,20 @@ FullCalendar.Timeline = (function (exports, core, premiumCommonPlugin, internal$
|
|
|
1281
1374
|
var internal = {
|
|
1282
1375
|
__proto__: null,
|
|
1283
1376
|
TimelineView: TimelineView,
|
|
1284
|
-
buildSlatCols: buildSlatCols,
|
|
1285
1377
|
TimelineLane: TimelineLane,
|
|
1286
1378
|
TimelineLaneBg: TimelineLaneBg,
|
|
1287
|
-
TimelineHeader: TimelineHeader,
|
|
1288
1379
|
TimelineSlats: TimelineSlats,
|
|
1289
1380
|
buildTimelineDateProfile: buildTimelineDateProfile,
|
|
1290
|
-
|
|
1381
|
+
createVerticalStyle: createVerticalStyle,
|
|
1382
|
+
createHorizontalStyle: createHorizontalStyle,
|
|
1383
|
+
computeSlotWidth: computeSlotWidth,
|
|
1384
|
+
timeToCoord: timeToCoord,
|
|
1291
1385
|
coordToCss: coordToCss,
|
|
1292
1386
|
coordsToCss: coordsToCss,
|
|
1293
1387
|
TimelineLaneSlicer: TimelineLaneSlicer,
|
|
1294
|
-
|
|
1388
|
+
TimelineHeaderRow: TimelineHeaderRow,
|
|
1389
|
+
TimelineNowIndicatorArrow: TimelineNowIndicatorArrow,
|
|
1390
|
+
TimelineNowIndicatorLine: TimelineNowIndicatorLine
|
|
1295
1391
|
};
|
|
1296
1392
|
|
|
1297
1393
|
core.globalPlugins.push(plugin);
|
|
@@ -1303,4 +1399,4 @@ FullCalendar.Timeline = (function (exports, core, premiumCommonPlugin, internal$
|
|
|
1303
1399
|
|
|
1304
1400
|
return exports;
|
|
1305
1401
|
|
|
1306
|
-
})({}, FullCalendar, FullCalendar.PremiumCommon, FullCalendar.Internal, FullCalendar.Preact
|
|
1402
|
+
})({}, FullCalendar, FullCalendar.PremiumCommon, FullCalendar.Internal, FullCalendar.Preact);
|