@fullcalendar/timeline 7.0.0-beta.4 → 7.0.0-rc.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/LICENSE.md +2 -2
- package/index.cjs +1 -1
- package/index.global.js +348 -315
- package/index.global.min.js +2 -2
- package/index.js +1 -1
- package/internal.cjs +345 -312
- package/internal.d.ts +21 -18
- package/internal.js +344 -312
- package/package.json +4 -4
package/internal.cjs
CHANGED
|
@@ -447,6 +447,8 @@ function buildCellObject(date, text, rowUnit) {
|
|
|
447
447
|
class TimelineSlatCell extends internal_cjs.BaseComponent {
|
|
448
448
|
constructor() {
|
|
449
449
|
super(...arguments);
|
|
450
|
+
// memo
|
|
451
|
+
this.getPublicDate = internal_cjs.memoize((dateEnv, date) => dateEnv.toDate(date));
|
|
450
452
|
// ref
|
|
451
453
|
this.innerElRef = preact_cjs.createRef();
|
|
452
454
|
}
|
|
@@ -455,7 +457,7 @@ class TimelineSlatCell extends internal_cjs.BaseComponent {
|
|
|
455
457
|
let { dateEnv, options } = context;
|
|
456
458
|
let { date, tDateProfile, isEm } = props;
|
|
457
459
|
let dateMeta = internal_cjs.getDateMeta(props.date, props.todayRange, props.nowDate, props.dateProfile);
|
|
458
|
-
let renderProps = Object.assign(Object.assign({ date:
|
|
460
|
+
let renderProps = Object.assign(Object.assign({ date: this.getPublicDate(dateEnv, props.date) }, dateMeta), { view: context.viewApi });
|
|
459
461
|
return (preact_cjs.createElement(internal_cjs.ContentContainer, { tag: "div",
|
|
460
462
|
// fc-align-start shrinks width of InnerContent
|
|
461
463
|
// TODO: document this semantic className fc-timeline-slot-em
|
|
@@ -469,7 +471,11 @@ class TimelineSlatCell extends internal_cjs.BaseComponent {
|
|
|
469
471
|
omitTime: !tDateProfile.isTimeScale,
|
|
470
472
|
}) }, (dateMeta.isToday ? { 'aria-current': 'date' } : {})), style: {
|
|
471
473
|
width: props.width,
|
|
472
|
-
}, renderProps: renderProps, generatorName: "slotLaneContent", customGenerator: options.slotLaneContent, classNameGenerator: options.slotLaneClassNames, didMount: options.slotLaneDidMount, willUnmount: options.slotLaneWillUnmount }, (InnerContent) => (preact_cjs.createElement(InnerContent, { tag: "div", className: 'fc-cell-inner',
|
|
474
|
+
}, renderProps: renderProps, generatorName: "slotLaneContent", customGenerator: options.slotLaneContent, classNameGenerator: options.slotLaneClassNames, didMount: options.slotLaneDidMount, willUnmount: options.slotLaneWillUnmount }, (InnerContent) => (preact_cjs.createElement(InnerContent, { tag: "div", className: 'fc-cell-inner', style: {
|
|
475
|
+
// HACK for Safari 16.4,
|
|
476
|
+
// which can't use ResizeObserver on elements with natural width 0
|
|
477
|
+
minWidth: 1,
|
|
478
|
+
}, elRef: this.innerElRef }))));
|
|
473
479
|
}
|
|
474
480
|
componentDidMount() {
|
|
475
481
|
const innerEl = this.innerElRef.current;
|
|
@@ -504,7 +510,7 @@ class TimelineSlats extends internal_cjs.BaseComponent {
|
|
|
504
510
|
let { tDateProfile, slotWidth } = props;
|
|
505
511
|
let { slotDates, isWeekStarts } = tDateProfile;
|
|
506
512
|
let isDay = !tDateProfile.isTimeScale && !tDateProfile.largeUnit;
|
|
507
|
-
return (preact_cjs.createElement("div", { "aria-hidden": true, className: "fc-timeline-slots fc-
|
|
513
|
+
return (preact_cjs.createElement("div", { "aria-hidden": true, className: "fc-timeline-slots fc-flex-row fc-fill", style: { height: props.height } }, slotDates.map((slotDate, i) => {
|
|
508
514
|
let key = slotDate.toISOString();
|
|
509
515
|
return (preact_cjs.createElement(TimelineSlatCell, { key: key, date: slotDate, dateProfile: props.dateProfile, tDateProfile: tDateProfile, nowDate: props.nowDate, todayRange: props.todayRange, isEm: isWeekStarts[i], isDay: isDay, borderStart: Boolean(i),
|
|
510
516
|
// ref
|
|
@@ -515,50 +521,132 @@ class TimelineSlats extends internal_cjs.BaseComponent {
|
|
|
515
521
|
}
|
|
516
522
|
}
|
|
517
523
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
//
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
return 0;
|
|
524
|
+
class TimelineHeaderCell extends internal_cjs.BaseComponent {
|
|
525
|
+
constructor() {
|
|
526
|
+
super(...arguments);
|
|
527
|
+
// memo
|
|
528
|
+
this.refineRenderProps = internal_cjs.memoizeObjArg(refineRenderProps);
|
|
529
|
+
// ref
|
|
530
|
+
this.innerElRef = preact_cjs.createRef();
|
|
526
531
|
}
|
|
527
|
-
|
|
528
|
-
|
|
532
|
+
render() {
|
|
533
|
+
let { props, context } = this;
|
|
534
|
+
let { dateEnv, options } = context;
|
|
535
|
+
let { cell, dateProfile, tDateProfile } = props;
|
|
536
|
+
// the cell.rowUnit is f'd
|
|
537
|
+
// giving 'month' for a 3-day view
|
|
538
|
+
// workaround: to infer day, do NOT time
|
|
539
|
+
let dateMeta = internal_cjs.getDateMeta(cell.date, props.todayRange, props.nowDate, dateProfile);
|
|
540
|
+
let renderProps = this.refineRenderProps({
|
|
541
|
+
level: props.rowLevel,
|
|
542
|
+
dateMarker: cell.date,
|
|
543
|
+
text: cell.text,
|
|
544
|
+
dateEnv: context.dateEnv,
|
|
545
|
+
viewApi: context.viewApi,
|
|
546
|
+
});
|
|
547
|
+
let isNavLink = !dateMeta.isDisabled && (cell.rowUnit && cell.rowUnit !== 'time');
|
|
548
|
+
return (preact_cjs.createElement(internal_cjs.ContentContainer, { tag: "div", className: internal_cjs.joinClassNames('fc-timeline-slot-label fc-timeline-slot', cell.isWeekStart && 'fc-timeline-slot-em', // TODO: document this semantic className
|
|
549
|
+
'fc-header-cell fc-cell fc-flex-col fc-justify-center', props.borderStart && 'fc-border-s', props.isCentered ? 'fc-align-center' : 'fc-align-start',
|
|
550
|
+
// TODO: so slot classnames for week/month/bigger. see note above about rowUnit
|
|
551
|
+
cell.rowUnit === 'time' ?
|
|
552
|
+
internal_cjs.getSlotClassName(dateMeta) :
|
|
553
|
+
internal_cjs.getDayClassName(dateMeta)), attrs: Object.assign({ 'data-date': dateEnv.formatIso(cell.date, {
|
|
554
|
+
omitTime: !tDateProfile.isTimeScale,
|
|
555
|
+
omitTimeZoneOffset: true,
|
|
556
|
+
}) }, (dateMeta.isToday ? { 'aria-current': 'date' } : {})), style: {
|
|
557
|
+
width: props.slotWidth != null
|
|
558
|
+
? props.slotWidth * cell.colspan
|
|
559
|
+
: undefined,
|
|
560
|
+
}, renderProps: renderProps, generatorName: "slotLabelContent", customGenerator: options.slotLabelContent, defaultGenerator: renderInnerContent, classNameGenerator: options.slotLabelClassNames, didMount: options.slotLabelDidMount, willUnmount: options.slotLabelWillUnmount }, (InnerContent) => (preact_cjs.createElement(InnerContent, { tag: 'div', attrs: isNavLink
|
|
561
|
+
// not tabbable because parent is aria-hidden
|
|
562
|
+
? internal_cjs.buildNavLinkAttrs(context, cell.date, cell.rowUnit, undefined, /* isTabbable = */ false)
|
|
563
|
+
: {} // don't bother with aria-hidden because parent already hidden
|
|
564
|
+
, className: internal_cjs.joinClassNames('fc-cell-inner fc-padding-md', props.isSticky && 'fc-sticky-s'), elRef: this.innerElRef }))));
|
|
529
565
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
566
|
+
componentDidMount() {
|
|
567
|
+
const { props } = this;
|
|
568
|
+
const innerEl = this.innerElRef.current; // TODO: make dynamic with useEffect
|
|
569
|
+
this.detachSize = internal_cjs.watchSize(innerEl, (width, height) => {
|
|
570
|
+
internal_cjs.setRef(props.innerWidthRef, width);
|
|
571
|
+
internal_cjs.setRef(props.innerHeightRef, height);
|
|
572
|
+
// HACK for sticky-centering
|
|
573
|
+
innerEl.style.left = innerEl.style.right =
|
|
574
|
+
(props.isCentered && props.isSticky)
|
|
575
|
+
? `calc(50% - ${width / 2}px)`
|
|
576
|
+
: '';
|
|
577
|
+
});
|
|
534
578
|
}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
579
|
+
componentWillUnmount() {
|
|
580
|
+
const { props } = this;
|
|
581
|
+
this.detachSize();
|
|
582
|
+
internal_cjs.setRef(props.innerWidthRef, null);
|
|
583
|
+
internal_cjs.setRef(props.innerHeightRef, null);
|
|
539
584
|
}
|
|
540
|
-
return snapCoverage;
|
|
541
585
|
}
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
if (!hcoord) {
|
|
547
|
-
return {};
|
|
548
|
-
}
|
|
549
|
-
if (isRtl) {
|
|
550
|
-
return { right: hcoord.start, width: hcoord.size };
|
|
551
|
-
}
|
|
552
|
-
else {
|
|
553
|
-
return { left: hcoord.start, width: hcoord.size };
|
|
554
|
-
}
|
|
586
|
+
// Utils
|
|
587
|
+
// -------------------------------------------------------------------------------------------------
|
|
588
|
+
function renderInnerContent(renderProps) {
|
|
589
|
+
return renderProps.text;
|
|
555
590
|
}
|
|
556
|
-
function
|
|
557
|
-
|
|
558
|
-
|
|
591
|
+
function refineRenderProps(input) {
|
|
592
|
+
return {
|
|
593
|
+
level: input.level,
|
|
594
|
+
date: input.dateEnv.toDate(input.dateMarker),
|
|
595
|
+
view: input.viewApi,
|
|
596
|
+
text: input.text,
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
class TimelineHeaderRow extends internal_cjs.BaseComponent {
|
|
601
|
+
constructor() {
|
|
602
|
+
super(...arguments);
|
|
603
|
+
// refs
|
|
604
|
+
this.innerWidthRefMap = new internal_cjs.RefMap(() => {
|
|
605
|
+
internal_cjs.afterSize(this.handleInnerWidths);
|
|
606
|
+
});
|
|
607
|
+
this.innerHeightRefMap = new internal_cjs.RefMap(() => {
|
|
608
|
+
internal_cjs.afterSize(this.handleInnerHeights);
|
|
609
|
+
});
|
|
610
|
+
this.handleInnerWidths = () => {
|
|
611
|
+
const innerWidthMap = this.innerWidthRefMap.current;
|
|
612
|
+
let max = 0;
|
|
613
|
+
for (const innerWidth of innerWidthMap.values()) {
|
|
614
|
+
max = Math.max(max, innerWidth);
|
|
615
|
+
}
|
|
616
|
+
// TODO: ensure not equal?
|
|
617
|
+
internal_cjs.setRef(this.props.innerWidthRef, max);
|
|
618
|
+
};
|
|
619
|
+
this.handleInnerHeights = () => {
|
|
620
|
+
const innerHeightMap = this.innerHeightRefMap.current;
|
|
621
|
+
let max = 0;
|
|
622
|
+
for (const innerHeight of innerHeightMap.values()) {
|
|
623
|
+
max = Math.max(max, innerHeight);
|
|
624
|
+
}
|
|
625
|
+
// TODO: ensure not equal?
|
|
626
|
+
internal_cjs.setRef(this.props.innerHeighRef, max);
|
|
627
|
+
};
|
|
559
628
|
}
|
|
560
|
-
|
|
561
|
-
|
|
629
|
+
render() {
|
|
630
|
+
const { props, innerWidthRefMap, innerHeightRefMap } = this;
|
|
631
|
+
const isCentered = !(props.tDateProfile.isTimeScale && props.isLastRow);
|
|
632
|
+
const isSticky = !props.isLastRow;
|
|
633
|
+
return (preact_cjs.createElement("div", { className: internal_cjs.joinClassNames('fc-flex-row fc-grow', // TODO: move fc-grow to parent?
|
|
634
|
+
!props.isLastRow && 'fc-border-b') }, props.cells.map((cell, cellI) => {
|
|
635
|
+
// TODO: make this part of the cell obj?
|
|
636
|
+
// TODO: rowUnit seems wrong sometimes. says 'month' when it should be day
|
|
637
|
+
// TODO: rowUnit is relevant to whole row. put it on a row object, not the cells
|
|
638
|
+
// TODO: use rowUnit to key the Row itself?
|
|
639
|
+
const key = cell.rowUnit + ':' + cell.date.toISOString();
|
|
640
|
+
return (preact_cjs.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, borderStart: Boolean(cellI),
|
|
641
|
+
// refs
|
|
642
|
+
innerWidthRef: innerWidthRefMap.createRef(key), innerHeightRef: innerHeightRefMap.createRef(key),
|
|
643
|
+
// dimensions
|
|
644
|
+
slotWidth: props.slotWidth }));
|
|
645
|
+
})));
|
|
646
|
+
}
|
|
647
|
+
componentWillUnmount() {
|
|
648
|
+
internal_cjs.setRef(this.props.innerWidthRef, null);
|
|
649
|
+
internal_cjs.setRef(this.props.innerHeighRef, null);
|
|
562
650
|
}
|
|
563
651
|
}
|
|
564
652
|
|
|
@@ -613,13 +701,38 @@ time, dateEnv, dateProfile, tDateProfile, slowWidth) {
|
|
|
613
701
|
}
|
|
614
702
|
function dateToCoord(// pixels
|
|
615
703
|
date, dateEnv, tDateProfile, slotWidth) {
|
|
616
|
-
let snapCoverage = computeDateSnapCoverage(date, tDateProfile, dateEnv);
|
|
704
|
+
let snapCoverage = computeDateSnapCoverage$1(date, tDateProfile, dateEnv);
|
|
617
705
|
let slotCoverage = snapCoverage / tDateProfile.snapsPerSlot;
|
|
618
706
|
return slotCoverage * slotWidth;
|
|
619
707
|
}
|
|
620
708
|
/*
|
|
621
709
|
returned value is between 0 and the number of snaps
|
|
622
710
|
*/
|
|
711
|
+
function computeDateSnapCoverage$1(date, tDateProfile, dateEnv) {
|
|
712
|
+
let snapDiff = dateEnv.countDurationsBetween(tDateProfile.normalizedRange.start, date, tDateProfile.snapDuration);
|
|
713
|
+
if (snapDiff < 0) {
|
|
714
|
+
return 0;
|
|
715
|
+
}
|
|
716
|
+
if (snapDiff >= tDateProfile.snapDiffToIndex.length) {
|
|
717
|
+
return tDateProfile.snapCnt;
|
|
718
|
+
}
|
|
719
|
+
let snapDiffInt = Math.floor(snapDiff);
|
|
720
|
+
let snapCoverage = tDateProfile.snapDiffToIndex[snapDiffInt];
|
|
721
|
+
if (internal_cjs.isInt(snapCoverage)) { // not an in-between value
|
|
722
|
+
snapCoverage += snapDiff - snapDiffInt; // add the remainder
|
|
723
|
+
}
|
|
724
|
+
else {
|
|
725
|
+
// a fractional value, meaning the date is not visible
|
|
726
|
+
// always round up in this case. works for start AND end dates in a range.
|
|
727
|
+
snapCoverage = Math.ceil(snapCoverage);
|
|
728
|
+
}
|
|
729
|
+
return snapCoverage;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
/*
|
|
733
|
+
TODO: rename this file!
|
|
734
|
+
*/
|
|
735
|
+
// returned value is between 0 and the number of snaps
|
|
623
736
|
function computeDateSnapCoverage(date, tDateProfile, dateEnv) {
|
|
624
737
|
let snapDiff = dateEnv.countDurationsBetween(tDateProfile.normalizedRange.start, date, tDateProfile.snapDuration);
|
|
625
738
|
if (snapDiff < 0) {
|
|
@@ -638,7 +751,107 @@ function computeDateSnapCoverage(date, tDateProfile, dateEnv) {
|
|
|
638
751
|
// always round up in this case. works for start AND end dates in a range.
|
|
639
752
|
snapCoverage = Math.ceil(snapCoverage);
|
|
640
753
|
}
|
|
641
|
-
return snapCoverage;
|
|
754
|
+
return snapCoverage;
|
|
755
|
+
}
|
|
756
|
+
/*
|
|
757
|
+
TODO: DRY up with elsewhere?
|
|
758
|
+
*/
|
|
759
|
+
function horizontalsToCss(hcoord, isRtl) {
|
|
760
|
+
if (!hcoord) {
|
|
761
|
+
return {};
|
|
762
|
+
}
|
|
763
|
+
if (isRtl) {
|
|
764
|
+
return { right: hcoord.start, width: hcoord.size };
|
|
765
|
+
}
|
|
766
|
+
else {
|
|
767
|
+
return { left: hcoord.start, width: hcoord.size };
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
function horizontalCoordToCss(start, isRtl) {
|
|
771
|
+
if (isRtl) {
|
|
772
|
+
return { right: start };
|
|
773
|
+
}
|
|
774
|
+
else {
|
|
775
|
+
return { left: start };
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
class TimelineNowIndicatorLine extends internal_cjs.BaseComponent {
|
|
780
|
+
render() {
|
|
781
|
+
const { props, context } = this;
|
|
782
|
+
return (preact_cjs.createElement("div", { className: "fc-timeline-now-indicator-container" },
|
|
783
|
+
preact_cjs.createElement(internal_cjs.NowIndicatorContainer // TODO: make separate component?
|
|
784
|
+
, { className: 'fc-timeline-now-indicator-line', style: props.slotWidth != null
|
|
785
|
+
? horizontalCoordToCss(dateToCoord(props.nowDate, context.dateEnv, props.tDateProfile, props.slotWidth), context.isRtl)
|
|
786
|
+
: {}, isAxis: false, date: props.nowDate })));
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
class TimelineNowIndicatorArrow extends internal_cjs.BaseComponent {
|
|
791
|
+
render() {
|
|
792
|
+
const { props, context } = this;
|
|
793
|
+
return (preact_cjs.createElement("div", { className: "fc-timeline-now-indicator-container" },
|
|
794
|
+
preact_cjs.createElement(internal_cjs.NowIndicatorContainer, { className: 'fc-timeline-now-indicator-arrow', style: props.slotWidth != null
|
|
795
|
+
? horizontalCoordToCss(dateToCoord(props.nowDate, context.dateEnv, props.tDateProfile, props.slotWidth), context.isRtl)
|
|
796
|
+
: {}, isAxis: true, date: props.nowDate })));
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
function getTimelineSlotEl(parentEl, index) {
|
|
801
|
+
return parentEl.querySelectorAll('.fc-timeline-slot')[index];
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
class TimelineLaneSlicer extends internal_cjs.Slicer {
|
|
805
|
+
sliceRange(origRange, dateProfile, dateProfileGenerator, tDateProfile, dateEnv) {
|
|
806
|
+
let normalRange = normalizeRange(origRange, tDateProfile, dateEnv);
|
|
807
|
+
let segs = [];
|
|
808
|
+
// protect against when the span is entirely in an invalid date region
|
|
809
|
+
if (computeDateSnapCoverage(normalRange.start, tDateProfile, dateEnv)
|
|
810
|
+
< computeDateSnapCoverage(normalRange.end, tDateProfile, dateEnv)) {
|
|
811
|
+
// intersect the footprint's range with the grid's range
|
|
812
|
+
let slicedRange = internal_cjs.intersectRanges(normalRange, tDateProfile.normalizedRange);
|
|
813
|
+
if (slicedRange) {
|
|
814
|
+
segs.push({
|
|
815
|
+
startDate: slicedRange.start,
|
|
816
|
+
endDate: slicedRange.end,
|
|
817
|
+
isStart: slicedRange.start.valueOf() === normalRange.start.valueOf()
|
|
818
|
+
&& isValidDate(slicedRange.start, tDateProfile, dateProfile, dateProfileGenerator),
|
|
819
|
+
isEnd: slicedRange.end.valueOf() === normalRange.end.valueOf()
|
|
820
|
+
&& isValidDate(internal_cjs.addMs(slicedRange.end, -1), tDateProfile, dateProfile, dateProfileGenerator),
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
return segs;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
const DEFAULT_TIME_FORMAT = internal_cjs.createFormatter({
|
|
829
|
+
hour: 'numeric',
|
|
830
|
+
minute: '2-digit',
|
|
831
|
+
omitZeroMinute: true,
|
|
832
|
+
meridiem: 'narrow',
|
|
833
|
+
});
|
|
834
|
+
class TimelineEvent extends internal_cjs.BaseComponent {
|
|
835
|
+
render() {
|
|
836
|
+
let { props, context } = this;
|
|
837
|
+
let { options } = context;
|
|
838
|
+
return (preact_cjs.createElement(internal_cjs.StandardEvent, Object.assign({}, props, { className: internal_cjs.joinClassNames('fc-timeline-event', options.eventOverlap === false // TODO: fix bad default
|
|
839
|
+
&& 'fc-timeline-event-spacious', 'fc-h-event'), defaultTimeFormat: DEFAULT_TIME_FORMAT, defaultDisplayEventTime: !props.isTimeScale })));
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
class TimelineLaneMoreLink extends internal_cjs.BaseComponent {
|
|
844
|
+
render() {
|
|
845
|
+
let { props } = this;
|
|
846
|
+
let { hiddenSegs, resourceId, forcedInvisibleMap } = props;
|
|
847
|
+
let dateSpanProps = resourceId ? { resourceId } : {};
|
|
848
|
+
return (preact_cjs.createElement(internal_cjs.MoreLinkContainer, { className: 'fc-timeline-more-link', allDayDate: null, segs: hiddenSegs, hiddenSegs: hiddenSegs, dateProfile: props.dateProfile, todayRange: props.todayRange, dateSpanProps: dateSpanProps, popoverContent: () => (preact_cjs.createElement(preact_cjs.Fragment, null, hiddenSegs.map((seg) => {
|
|
849
|
+
let { eventRange } = seg;
|
|
850
|
+
let instanceId = eventRange.instance.instanceId;
|
|
851
|
+
return (preact_cjs.createElement("div", { key: instanceId, style: { visibility: forcedInvisibleMap[instanceId] ? 'hidden' : '' } },
|
|
852
|
+
preact_cjs.createElement(TimelineEvent, Object.assign({ isTimeScale: props.isTimeScale, eventRange: eventRange, isStart: seg.isStart, isEnd: seg.isEnd, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === props.eventSelection }, internal_cjs.getEventRangeMeta(eventRange, props.todayRange, props.nowDate)))));
|
|
853
|
+
}))) }, (InnerContent) => (preact_cjs.createElement(InnerContent, { tag: "div", className: 'fc-timeline-more-link-inner fc-sticky-s' }))));
|
|
854
|
+
}
|
|
642
855
|
}
|
|
643
856
|
|
|
644
857
|
function computeManySegHorizontals(segs, segMinWidth, dateEnv, tDateProfile, slotWidth) {
|
|
@@ -705,83 +918,6 @@ hiddenGroupHeights, strictOrder, maxDepth) {
|
|
|
705
918
|
];
|
|
706
919
|
}
|
|
707
920
|
|
|
708
|
-
class TimelineLaneBg extends internal_cjs.BaseComponent {
|
|
709
|
-
render() {
|
|
710
|
-
let { props } = this;
|
|
711
|
-
let highlightSeg = [].concat(props.eventResizeSegs, props.dateSelectionSegs);
|
|
712
|
-
return (preact_cjs.createElement(preact_cjs.Fragment, null,
|
|
713
|
-
this.renderSegs(props.businessHourSegs || [], 'non-business'),
|
|
714
|
-
this.renderSegs(props.bgEventSegs || [], 'bg-event'),
|
|
715
|
-
this.renderSegs(highlightSeg, 'highlight')));
|
|
716
|
-
}
|
|
717
|
-
renderSegs(segs, fillType) {
|
|
718
|
-
let { tDateProfile, todayRange, nowDate, slotWidth } = this.props;
|
|
719
|
-
let { dateEnv, isRtl } = this.context;
|
|
720
|
-
return (preact_cjs.createElement(preact_cjs.Fragment, null, segs.map((seg) => {
|
|
721
|
-
let hStyle; // TODO
|
|
722
|
-
if (slotWidth != null) {
|
|
723
|
-
let segHorizontal = computeSegHorizontals(seg, undefined, dateEnv, tDateProfile, slotWidth);
|
|
724
|
-
hStyle = horizontalsToCss(segHorizontal, isRtl);
|
|
725
|
-
}
|
|
726
|
-
return (preact_cjs.createElement("div", { key: internal_cjs.buildEventRangeKey(seg.eventRange), className: "fc-fill-y", style: hStyle }, fillType === 'bg-event' ?
|
|
727
|
-
preact_cjs.createElement(internal_cjs.BgEvent, Object.assign({ eventRange: seg.eventRange, isStart: seg.isStart, isEnd: seg.isEnd }, internal_cjs.getEventRangeMeta(seg.eventRange, todayRange, nowDate))) : (internal_cjs.renderFill(fillType))));
|
|
728
|
-
})));
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
class TimelineLaneSlicer extends internal_cjs.Slicer {
|
|
733
|
-
sliceRange(origRange, dateProfile, dateProfileGenerator, tDateProfile, dateEnv) {
|
|
734
|
-
let normalRange = normalizeRange(origRange, tDateProfile, dateEnv);
|
|
735
|
-
let segs = [];
|
|
736
|
-
// protect against when the span is entirely in an invalid date region
|
|
737
|
-
if (computeDateSnapCoverage$1(normalRange.start, tDateProfile, dateEnv)
|
|
738
|
-
< computeDateSnapCoverage$1(normalRange.end, tDateProfile, dateEnv)) {
|
|
739
|
-
// intersect the footprint's range with the grid's range
|
|
740
|
-
let slicedRange = internal_cjs.intersectRanges(normalRange, tDateProfile.normalizedRange);
|
|
741
|
-
if (slicedRange) {
|
|
742
|
-
segs.push({
|
|
743
|
-
startDate: slicedRange.start,
|
|
744
|
-
endDate: slicedRange.end,
|
|
745
|
-
isStart: slicedRange.start.valueOf() === normalRange.start.valueOf()
|
|
746
|
-
&& isValidDate(slicedRange.start, tDateProfile, dateProfile, dateProfileGenerator),
|
|
747
|
-
isEnd: slicedRange.end.valueOf() === normalRange.end.valueOf()
|
|
748
|
-
&& isValidDate(internal_cjs.addMs(slicedRange.end, -1), tDateProfile, dateProfile, dateProfileGenerator),
|
|
749
|
-
});
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
return segs;
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
const DEFAULT_TIME_FORMAT = internal_cjs.createFormatter({
|
|
757
|
-
hour: 'numeric',
|
|
758
|
-
minute: '2-digit',
|
|
759
|
-
omitZeroMinute: true,
|
|
760
|
-
meridiem: 'narrow',
|
|
761
|
-
});
|
|
762
|
-
class TimelineEvent extends internal_cjs.BaseComponent {
|
|
763
|
-
render() {
|
|
764
|
-
let { props, context } = this;
|
|
765
|
-
let { options } = context;
|
|
766
|
-
return (preact_cjs.createElement(internal_cjs.StandardEvent, Object.assign({}, props, { className: internal_cjs.joinClassNames('fc-timeline-event', options.eventOverlap === false // TODO: fix bad default
|
|
767
|
-
&& 'fc-timeline-event-spacious', 'fc-h-event'), defaultTimeFormat: DEFAULT_TIME_FORMAT, defaultDisplayEventTime: !props.isTimeScale })));
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
class TimelineLaneMoreLink extends internal_cjs.BaseComponent {
|
|
772
|
-
render() {
|
|
773
|
-
let { props } = this;
|
|
774
|
-
let { hiddenSegs, resourceId, forcedInvisibleMap } = props;
|
|
775
|
-
let dateSpanProps = resourceId ? { resourceId } : {};
|
|
776
|
-
return (preact_cjs.createElement(internal_cjs.MoreLinkContainer, { className: 'fc-timeline-more-link', allDayDate: null, segs: hiddenSegs, hiddenSegs: hiddenSegs, dateProfile: props.dateProfile, todayRange: props.todayRange, dateSpanProps: dateSpanProps, popoverContent: () => (preact_cjs.createElement(preact_cjs.Fragment, null, hiddenSegs.map((seg) => {
|
|
777
|
-
let { eventRange } = seg;
|
|
778
|
-
let instanceId = eventRange.instance.instanceId;
|
|
779
|
-
return (preact_cjs.createElement("div", { key: instanceId, style: { visibility: forcedInvisibleMap[instanceId] ? 'hidden' : '' } },
|
|
780
|
-
preact_cjs.createElement(TimelineEvent, Object.assign({ isTimeScale: props.isTimeScale, eventRange: eventRange, isStart: seg.isStart, isEnd: seg.isEnd, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === props.eventSelection }, internal_cjs.getEventRangeMeta(eventRange, props.todayRange, props.nowDate)))));
|
|
781
|
-
}))) }, (InnerContent) => (preact_cjs.createElement(InnerContent, { tag: "div", className: 'fc-timeline-more-link-inner fc-sticky-s' }))));
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
|
|
785
921
|
/*
|
|
786
922
|
TODO: make DRY with other Event Harnesses
|
|
787
923
|
*/
|
|
@@ -807,10 +943,7 @@ class TimelineEventHarness extends preact_cjs.Component {
|
|
|
807
943
|
}
|
|
808
944
|
}
|
|
809
945
|
|
|
810
|
-
|
|
811
|
-
TODO: split TimelineLaneBg and TimelineLaneFg?
|
|
812
|
-
*/
|
|
813
|
-
class TimelineLane extends internal_cjs.BaseComponent {
|
|
946
|
+
class TimelineFg extends internal_cjs.BaseComponent {
|
|
814
947
|
constructor() {
|
|
815
948
|
super(...arguments);
|
|
816
949
|
// memo
|
|
@@ -822,8 +955,6 @@ class TimelineLane extends internal_cjs.BaseComponent {
|
|
|
822
955
|
this.moreLinkHeightRefMap = new internal_cjs.RefMap(() => {
|
|
823
956
|
internal_cjs.afterSize(this.handleMoreLinkHeights);
|
|
824
957
|
});
|
|
825
|
-
// internal
|
|
826
|
-
this.slicer = new TimelineLaneSlicer();
|
|
827
958
|
this.handleMoreLinkHeights = () => {
|
|
828
959
|
this.setState({ moreLinkHeightRev: this.moreLinkHeightRefMap.rev }); // will trigger rerender
|
|
829
960
|
};
|
|
@@ -837,39 +968,30 @@ class TimelineLane extends internal_cjs.BaseComponent {
|
|
|
837
968
|
render() {
|
|
838
969
|
let { props, context, segHeightRefMap, moreLinkHeightRefMap } = this;
|
|
839
970
|
let { options } = context;
|
|
840
|
-
let {
|
|
841
|
-
let
|
|
842
|
-
|
|
843
|
-
let mirrorSegs = (slicedProps.eventDrag ? slicedProps.eventDrag.segs : null) ||
|
|
844
|
-
(slicedProps.eventResize ? slicedProps.eventResize.segs : null) ||
|
|
971
|
+
let { tDateProfile } = props;
|
|
972
|
+
let mirrorSegs = (props.eventDrag ? props.eventDrag.segs : null) ||
|
|
973
|
+
(props.eventResize ? props.eventResize.segs : null) ||
|
|
845
974
|
[];
|
|
846
|
-
let fgSegs = this.sortEventSegs(
|
|
975
|
+
let fgSegs = this.sortEventSegs(props.fgEventSegs, options.eventOrder);
|
|
847
976
|
let fgSegHorizontals = props.slotWidth != null
|
|
848
977
|
? computeManySegHorizontals(fgSegs, options.eventMinWidth, context.dateEnv, tDateProfile, props.slotWidth)
|
|
849
978
|
: {};
|
|
850
979
|
let [fgSegTops, hiddenGroups, hiddenGroupTops, totalHeight] = computeFgSegPlacements(fgSegs, fgSegHorizontals, segHeightRefMap.current, moreLinkHeightRefMap.current, options.eventOrderStrict, options.eventMaxStack);
|
|
980
|
+
this.totalHeight = totalHeight;
|
|
851
981
|
let forcedInvisibleMap = // TODO: more convenient/DRY
|
|
852
|
-
(
|
|
853
|
-
(
|
|
982
|
+
(props.eventDrag ? props.eventDrag.affectedInstances : null) ||
|
|
983
|
+
(props.eventResize ? props.eventResize.affectedInstances : null) ||
|
|
854
984
|
{};
|
|
855
|
-
return (preact_cjs.createElement(
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
false, // isResizing
|
|
866
|
-
false),
|
|
867
|
-
this.renderFgSegs(mirrorSegs, props.slotWidth // TODO: memoize
|
|
868
|
-
? computeManySegHorizontals(mirrorSegs, options.eventMinWidth, context.dateEnv, tDateProfile, props.slotWidth)
|
|
869
|
-
: {}, fgSegTops, {}, // forcedInvisibleMap
|
|
870
|
-
[], // hiddenGroups
|
|
871
|
-
new Map(), // hiddenGroupTops
|
|
872
|
-
Boolean(slicedProps.eventDrag), Boolean(slicedProps.eventResize), false))));
|
|
985
|
+
return (preact_cjs.createElement("div", { className: 'fc-timeline-events fc-rel', style: { height: totalHeight } },
|
|
986
|
+
this.renderFgSegs(fgSegs, fgSegHorizontals, fgSegTops, forcedInvisibleMap, hiddenGroups, hiddenGroupTops, false, // isDragging
|
|
987
|
+
false, // isResizing
|
|
988
|
+
false),
|
|
989
|
+
this.renderFgSegs(mirrorSegs, props.slotWidth // TODO: memoize
|
|
990
|
+
? computeManySegHorizontals(mirrorSegs, options.eventMinWidth, context.dateEnv, tDateProfile, props.slotWidth)
|
|
991
|
+
: {}, fgSegTops, {}, // forcedInvisibleMap
|
|
992
|
+
[], // hiddenGroups
|
|
993
|
+
new Map(), // hiddenGroupTops
|
|
994
|
+
Boolean(props.eventDrag), Boolean(props.eventResize), false)));
|
|
873
995
|
}
|
|
874
996
|
renderFgSegs(segs, segHorizontals, segTops, forcedInvisibleMap, hiddenGroups, hiddenGroupTops, isDragging, isResizing, isDateSelecting) {
|
|
875
997
|
let { props, context, segHeightRefMap, moreLinkHeightRefMap } = this;
|
|
@@ -891,155 +1013,43 @@ class TimelineLane extends internal_cjs.BaseComponent {
|
|
|
891
1013
|
}, context.isRtl)), heightRef: moreLinkHeightRefMap.createRef(hiddenGroup.key) },
|
|
892
1014
|
preact_cjs.createElement(TimelineLaneMoreLink, { hiddenSegs: hiddenGroup.segs, dateProfile: props.dateProfile, nowDate: props.nowDate, todayRange: props.todayRange, isTimeScale: props.tDateProfile.isTimeScale, eventSelection: props.eventSelection, resourceId: props.resourceId, forcedInvisibleMap: forcedInvisibleMap }))))));
|
|
893
1015
|
}
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
constructor() {
|
|
898
|
-
super(...arguments);
|
|
899
|
-
// memo
|
|
900
|
-
this.refineRenderProps = internal_cjs.memoizeObjArg(refineRenderProps);
|
|
901
|
-
// ref
|
|
902
|
-
this.innerElRef = preact_cjs.createRef();
|
|
903
|
-
}
|
|
904
|
-
render() {
|
|
905
|
-
let { props, context } = this;
|
|
906
|
-
let { dateEnv, options } = context;
|
|
907
|
-
let { cell, dateProfile, tDateProfile } = props;
|
|
908
|
-
// the cell.rowUnit is f'd
|
|
909
|
-
// giving 'month' for a 3-day view
|
|
910
|
-
// workaround: to infer day, do NOT time
|
|
911
|
-
let dateMeta = internal_cjs.getDateMeta(cell.date, props.todayRange, props.nowDate, dateProfile);
|
|
912
|
-
let renderProps = this.refineRenderProps({
|
|
913
|
-
level: props.rowLevel,
|
|
914
|
-
dateMarker: cell.date,
|
|
915
|
-
text: cell.text,
|
|
916
|
-
dateEnv: context.dateEnv,
|
|
917
|
-
viewApi: context.viewApi,
|
|
918
|
-
});
|
|
919
|
-
let isNavLink = !dateMeta.isDisabled && (cell.rowUnit && cell.rowUnit !== 'time');
|
|
920
|
-
return (preact_cjs.createElement(internal_cjs.ContentContainer, { tag: "div", className: internal_cjs.joinClassNames('fc-timeline-slot-label fc-timeline-slot', cell.isWeekStart && 'fc-timeline-slot-em', // TODO: document this semantic className
|
|
921
|
-
'fc-header-cell fc-cell fc-flex-col fc-justify-center', props.borderStart && 'fc-border-s', props.isCentered ? 'fc-align-center' : 'fc-align-start',
|
|
922
|
-
// TODO: so slot classnames for week/month/bigger. see note above about rowUnit
|
|
923
|
-
cell.rowUnit === 'time' ?
|
|
924
|
-
internal_cjs.getSlotClassName(dateMeta) :
|
|
925
|
-
internal_cjs.getDayClassName(dateMeta)), attrs: Object.assign({ 'data-date': dateEnv.formatIso(cell.date, {
|
|
926
|
-
omitTime: !tDateProfile.isTimeScale,
|
|
927
|
-
omitTimeZoneOffset: true,
|
|
928
|
-
}) }, (dateMeta.isToday ? { 'aria-current': 'date' } : {})), style: {
|
|
929
|
-
width: props.slotWidth != null
|
|
930
|
-
? props.slotWidth * cell.colspan
|
|
931
|
-
: undefined,
|
|
932
|
-
}, renderProps: renderProps, generatorName: "slotLabelContent", customGenerator: options.slotLabelContent, defaultGenerator: renderInnerContent, classNameGenerator: options.slotLabelClassNames, didMount: options.slotLabelDidMount, willUnmount: options.slotLabelWillUnmount }, (InnerContent) => (preact_cjs.createElement(InnerContent, { tag: 'div', attrs: isNavLink
|
|
933
|
-
// not tabbable because parent is aria-hidden
|
|
934
|
-
? internal_cjs.buildNavLinkAttrs(context, cell.date, cell.rowUnit, undefined, /* isTabbable = */ false)
|
|
935
|
-
: {} // don't bother with aria-hidden because parent already hidden
|
|
936
|
-
, className: internal_cjs.joinClassNames('fc-cell-inner fc-padding-md', props.isSticky && 'fc-sticky-s'), elRef: this.innerElRef }))));
|
|
937
|
-
}
|
|
938
|
-
componentDidMount() {
|
|
939
|
-
const { props } = this;
|
|
940
|
-
const innerEl = this.innerElRef.current; // TODO: make dynamic with useEffect
|
|
941
|
-
this.detachSize = internal_cjs.watchSize(innerEl, (width, height) => {
|
|
942
|
-
internal_cjs.setRef(props.innerWidthRef, width);
|
|
943
|
-
internal_cjs.setRef(props.innerHeightRef, height);
|
|
944
|
-
// HACK for sticky-centering
|
|
945
|
-
innerEl.style.left = innerEl.style.right =
|
|
946
|
-
(props.isCentered && props.isSticky)
|
|
947
|
-
? `calc(50% - ${width / 2}px)`
|
|
948
|
-
: '';
|
|
949
|
-
});
|
|
950
|
-
}
|
|
951
|
-
componentWillUnmount() {
|
|
952
|
-
const { props } = this;
|
|
953
|
-
this.detachSize();
|
|
954
|
-
internal_cjs.setRef(props.innerWidthRef, null);
|
|
955
|
-
internal_cjs.setRef(props.innerHeightRef, null);
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
// Utils
|
|
959
|
-
// -------------------------------------------------------------------------------------------------
|
|
960
|
-
function renderInnerContent(renderProps) {
|
|
961
|
-
return renderProps.text;
|
|
962
|
-
}
|
|
963
|
-
function refineRenderProps(input) {
|
|
964
|
-
return {
|
|
965
|
-
level: input.level,
|
|
966
|
-
date: input.dateEnv.toDate(input.dateMarker),
|
|
967
|
-
view: input.viewApi,
|
|
968
|
-
text: input.text,
|
|
969
|
-
};
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
class TimelineHeaderRow extends internal_cjs.BaseComponent {
|
|
973
|
-
constructor() {
|
|
974
|
-
super(...arguments);
|
|
975
|
-
// refs
|
|
976
|
-
this.innerWidthRefMap = new internal_cjs.RefMap(() => {
|
|
977
|
-
internal_cjs.afterSize(this.handleInnerWidths);
|
|
978
|
-
});
|
|
979
|
-
this.innerHeightRefMap = new internal_cjs.RefMap(() => {
|
|
980
|
-
internal_cjs.afterSize(this.handleInnerHeights);
|
|
981
|
-
});
|
|
982
|
-
this.handleInnerWidths = () => {
|
|
983
|
-
const innerWidthMap = this.innerWidthRefMap.current;
|
|
984
|
-
let max = 0;
|
|
985
|
-
for (const innerWidth of innerWidthMap.values()) {
|
|
986
|
-
max = Math.max(max, innerWidth);
|
|
987
|
-
}
|
|
988
|
-
// TODO: ensure not equal?
|
|
989
|
-
internal_cjs.setRef(this.props.innerWidthRef, max);
|
|
990
|
-
};
|
|
991
|
-
this.handleInnerHeights = () => {
|
|
992
|
-
const innerHeightMap = this.innerHeightRefMap.current;
|
|
993
|
-
let max = 0;
|
|
994
|
-
for (const innerHeight of innerHeightMap.values()) {
|
|
995
|
-
max = Math.max(max, innerHeight);
|
|
996
|
-
}
|
|
997
|
-
// TODO: ensure not equal?
|
|
998
|
-
internal_cjs.setRef(this.props.innerHeighRef, max);
|
|
999
|
-
};
|
|
1016
|
+
/*
|
|
1017
|
+
componentDidMount(): void {
|
|
1018
|
+
// might want to do firedTotalHeight, but won't be ready on first render
|
|
1000
1019
|
}
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
// TODO: make this part of the cell obj?
|
|
1008
|
-
// TODO: rowUnit seems wrong sometimes. says 'month' when it should be day
|
|
1009
|
-
// TODO: rowUnit is relevant to whole row. put it on a row object, not the cells
|
|
1010
|
-
// TODO: use rowUnit to key the Row itself?
|
|
1011
|
-
const key = cell.rowUnit + ':' + cell.date.toISOString();
|
|
1012
|
-
return (preact_cjs.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, borderStart: Boolean(cellI),
|
|
1013
|
-
// refs
|
|
1014
|
-
innerWidthRef: innerWidthRefMap.createRef(key), innerHeightRef: innerHeightRefMap.createRef(key),
|
|
1015
|
-
// dimensions
|
|
1016
|
-
slotWidth: props.slotWidth }));
|
|
1017
|
-
})));
|
|
1020
|
+
*/
|
|
1021
|
+
componentDidUpdate() {
|
|
1022
|
+
if (this.totalHeight !== this.firedTotalHeight) {
|
|
1023
|
+
this.firedTotalHeight = this.totalHeight;
|
|
1024
|
+
internal_cjs.setRef(this.props.heightRef, this.totalHeight);
|
|
1025
|
+
}
|
|
1018
1026
|
}
|
|
1019
1027
|
componentWillUnmount() {
|
|
1020
|
-
internal_cjs.setRef(this.props.
|
|
1021
|
-
internal_cjs.setRef(this.props.innerHeighRef, null);
|
|
1028
|
+
internal_cjs.setRef(this.props.heightRef, null);
|
|
1022
1029
|
}
|
|
1023
1030
|
}
|
|
1024
1031
|
|
|
1025
|
-
class
|
|
1032
|
+
class TimelineBg extends internal_cjs.BaseComponent {
|
|
1026
1033
|
render() {
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1034
|
+
let { props } = this;
|
|
1035
|
+
let highlightSeg = [].concat(props.eventResizeSegs || [], props.dateSelectionSegs);
|
|
1036
|
+
return (preact_cjs.createElement(preact_cjs.Fragment, null,
|
|
1037
|
+
this.renderSegs(props.businessHourSegs || [], 'non-business'),
|
|
1038
|
+
this.renderSegs(props.bgEventSegs || [], 'bg-event'),
|
|
1039
|
+
this.renderSegs(highlightSeg, 'highlight')));
|
|
1033
1040
|
}
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1041
|
+
renderSegs(segs, fillType) {
|
|
1042
|
+
let { tDateProfile, todayRange, nowDate, slotWidth } = this.props;
|
|
1043
|
+
let { dateEnv, isRtl } = this.context;
|
|
1044
|
+
return (preact_cjs.createElement(preact_cjs.Fragment, null, segs.map((seg) => {
|
|
1045
|
+
let hStyle; // TODO
|
|
1046
|
+
if (slotWidth != null) {
|
|
1047
|
+
let segHorizontal = computeSegHorizontals(seg, undefined, dateEnv, tDateProfile, slotWidth);
|
|
1048
|
+
hStyle = horizontalsToCss(segHorizontal, isRtl);
|
|
1049
|
+
}
|
|
1050
|
+
return (preact_cjs.createElement("div", { key: internal_cjs.buildEventRangeKey(seg.eventRange), className: "fc-fill-y", style: hStyle }, fillType === 'bg-event' ?
|
|
1051
|
+
preact_cjs.createElement(internal_cjs.BgEvent, Object.assign({ eventRange: seg.eventRange, isStart: seg.isStart, isEnd: seg.isEnd }, internal_cjs.getEventRangeMeta(seg.eventRange, todayRange, nowDate))) : (internal_cjs.renderFill(fillType))));
|
|
1052
|
+
})));
|
|
1043
1053
|
}
|
|
1044
1054
|
}
|
|
1045
1055
|
|
|
@@ -1057,6 +1067,7 @@ class TimelineView extends internal_cjs.DateComponent {
|
|
|
1057
1067
|
internal_cjs.afterSize(this.handleSlotInnerWidths);
|
|
1058
1068
|
});
|
|
1059
1069
|
this.scrollTime = null;
|
|
1070
|
+
this.slicer = new TimelineLaneSlicer();
|
|
1060
1071
|
// Sizing
|
|
1061
1072
|
// -----------------------------------------------------------------------------------------------
|
|
1062
1073
|
this.handleBodySlotInnerWidth = (innerWidth) => {
|
|
@@ -1064,27 +1075,30 @@ class TimelineView extends internal_cjs.DateComponent {
|
|
|
1064
1075
|
internal_cjs.afterSize(this.handleSlotInnerWidths);
|
|
1065
1076
|
};
|
|
1066
1077
|
this.handleSlotInnerWidths = () => {
|
|
1067
|
-
const
|
|
1068
|
-
const
|
|
1069
|
-
if (
|
|
1070
|
-
|
|
1078
|
+
const headerSlotInnerWidth = this.headerRowInnerWidthMap.current.get(this.tDateProfile.cellRows.length - 1);
|
|
1079
|
+
const { bodySlotInnerWidth } = this;
|
|
1080
|
+
if (headerSlotInnerWidth != null && bodySlotInnerWidth != null) {
|
|
1081
|
+
const slotInnerWidth = Math.max(headerSlotInnerWidth, bodySlotInnerWidth);
|
|
1082
|
+
if (slotInnerWidth !== this.state.slotInnerWidth) {
|
|
1083
|
+
this.setState({ slotInnerWidth });
|
|
1084
|
+
}
|
|
1071
1085
|
}
|
|
1072
1086
|
};
|
|
1073
|
-
this.
|
|
1087
|
+
this.handleTotalWidth = (totalWidth) => {
|
|
1074
1088
|
this.setState({
|
|
1075
|
-
|
|
1089
|
+
totalWidth,
|
|
1076
1090
|
});
|
|
1077
1091
|
};
|
|
1078
|
-
this.
|
|
1092
|
+
this.handleClientWidth = (clientWidth) => {
|
|
1079
1093
|
this.setState({
|
|
1080
|
-
|
|
1094
|
+
clientWidth,
|
|
1081
1095
|
});
|
|
1082
1096
|
};
|
|
1083
1097
|
this.handleTimeScrollRequest = (scrollTime) => {
|
|
1084
1098
|
this.scrollTime = scrollTime;
|
|
1085
1099
|
this.applyTimeScroll();
|
|
1086
1100
|
};
|
|
1087
|
-
this.handleTimeScrollEnd = (
|
|
1101
|
+
this.handleTimeScrollEnd = (isUser) => {
|
|
1088
1102
|
if (isUser) {
|
|
1089
1103
|
this.scrollTime = null;
|
|
1090
1104
|
}
|
|
@@ -1104,6 +1118,10 @@ class TimelineView extends internal_cjs.DateComponent {
|
|
|
1104
1118
|
render() {
|
|
1105
1119
|
const { props, state, context } = this;
|
|
1106
1120
|
const { options } = context;
|
|
1121
|
+
const { totalWidth, clientWidth } = state;
|
|
1122
|
+
const endScrollbarWidth = (totalWidth != null && clientWidth != null)
|
|
1123
|
+
? totalWidth - clientWidth
|
|
1124
|
+
: undefined;
|
|
1107
1125
|
/* date */
|
|
1108
1126
|
const tDateProfile = this.tDateProfile = this.buildTimelineDateProfile(props.dateProfile, context.dateEnv, options, context.dateProfileGenerator);
|
|
1109
1127
|
const { cellRows } = tDateProfile;
|
|
@@ -1114,8 +1132,11 @@ class TimelineView extends internal_cjs.DateComponent {
|
|
|
1114
1132
|
const stickyFooterScrollbar = !props.forPrint && internal_cjs.getStickyFooterScrollbar(options);
|
|
1115
1133
|
/* table positions */
|
|
1116
1134
|
const [canvasWidth, slotWidth] = this.computeSlotWidth(tDateProfile.slotCnt, tDateProfile.slotsPerLabel, options.slotMinWidth, state.slotInnerWidth, // is ACTUALLY the label width. rename?
|
|
1117
|
-
|
|
1135
|
+
clientWidth);
|
|
1118
1136
|
this.slotWidth = slotWidth;
|
|
1137
|
+
/* sliced */
|
|
1138
|
+
let slicedProps = this.slicer.sliceProps(props, props.dateProfile, tDateProfile.isTimeScale ? null : options.nextDayThreshold, context, // wish we didn't have to pass in the rest of the args...
|
|
1139
|
+
props.dateProfile, context.dateProfileGenerator, tDateProfile, context.dateEnv);
|
|
1119
1140
|
return (preact_cjs.createElement(internal_cjs.NowTimer, { unit: timerUnit }, (nowDate, todayRange) => {
|
|
1120
1141
|
const enableNowIndicator = // TODO: DRY
|
|
1121
1142
|
options.nowIndicator &&
|
|
@@ -1135,18 +1156,30 @@ class TimelineView extends internal_cjs.DateComponent {
|
|
|
1135
1156
|
return (preact_cjs.createElement(TimelineHeaderRow, { key: rowLevel, dateProfile: props.dateProfile, tDateProfile: tDateProfile, nowDate: nowDate, todayRange: todayRange, rowLevel: rowLevel, isLastRow: isLast, cells: cells, slotWidth: slotWidth, innerWidthRef: this.headerRowInnerWidthMap.createRef(rowLevel) }));
|
|
1136
1157
|
}),
|
|
1137
1158
|
enableNowIndicator && (preact_cjs.createElement(TimelineNowIndicatorArrow, { tDateProfile: tDateProfile, nowDate: nowDate, slotWidth: slotWidth }))),
|
|
1138
|
-
Boolean(
|
|
1139
|
-
preact_cjs.createElement(internal_cjs.Scroller, { vertical: verticalScrolling, horizontal: true, hideScrollbars:
|
|
1159
|
+
Boolean(endScrollbarWidth) && (preact_cjs.createElement("div", { className: 'fc-border-s fc-filler', style: { minWidth: endScrollbarWidth } }))),
|
|
1160
|
+
preact_cjs.createElement(internal_cjs.Scroller, { vertical: verticalScrolling, horizontal: true, hideScrollbars: stickyFooterScrollbar ||
|
|
1161
|
+
props.forPrint // prevents blank space in print-view on Safari
|
|
1162
|
+
, className: internal_cjs.joinClassNames('fc-timeline-body fc-flex-col', verticalScrolling && 'fc-liquid'), ref: this.bodyScrollerRef, clientWidthRef: this.handleClientWidth },
|
|
1140
1163
|
preact_cjs.createElement("div", { "aria-label": options.eventsHint, className: "fc-rel fc-grow", style: { width: canvasWidth }, ref: this.handeBodyEl },
|
|
1141
1164
|
preact_cjs.createElement(TimelineSlats, { dateProfile: props.dateProfile, tDateProfile: tDateProfile, nowDate: nowDate, todayRange: todayRange,
|
|
1142
1165
|
// ref
|
|
1143
1166
|
innerWidthRef: this.handleBodySlotInnerWidth,
|
|
1144
1167
|
// dimensions
|
|
1145
1168
|
slotWidth: slotWidth }),
|
|
1146
|
-
preact_cjs.createElement(
|
|
1169
|
+
preact_cjs.createElement(TimelineBg, { tDateProfile: tDateProfile, nowDate: nowDate, todayRange: todayRange,
|
|
1170
|
+
// content
|
|
1171
|
+
bgEventSegs: slicedProps.bgEventSegs, businessHourSegs: slicedProps.businessHourSegs, dateSelectionSegs: slicedProps.dateSelectionSegs, eventResizeSegs: slicedProps.eventResize ? slicedProps.eventResize.segs : null,
|
|
1172
|
+
// dimensions
|
|
1173
|
+
slotWidth: slotWidth }),
|
|
1174
|
+
preact_cjs.createElement(TimelineFg, { dateProfile: props.dateProfile, tDateProfile: tDateProfile, nowDate: nowDate, todayRange: todayRange,
|
|
1175
|
+
// content
|
|
1176
|
+
fgEventSegs: slicedProps.fgEventSegs, eventDrag: slicedProps.eventDrag, eventResize: slicedProps.eventResize, eventSelection: slicedProps.eventSelection,
|
|
1177
|
+
// dimensions
|
|
1178
|
+
slotWidth: slotWidth }),
|
|
1179
|
+
preact_cjs.createElement("div", { className: 'fc-timeline-lane-footer' }),
|
|
1147
1180
|
enableNowIndicator && (preact_cjs.createElement(TimelineNowIndicatorLine, { tDateProfile: tDateProfile, nowDate: nowDate, slotWidth: slotWidth })))),
|
|
1148
|
-
stickyFooterScrollbar && (preact_cjs.createElement(internal_cjs.
|
|
1149
|
-
|
|
1181
|
+
Boolean(stickyFooterScrollbar) && (preact_cjs.createElement(internal_cjs.FooterScrollbar, { isSticky: true, canvasWidth: canvasWidth, scrollerRef: this.footerScrollerRef })),
|
|
1182
|
+
preact_cjs.createElement(internal_cjs.Ruler, { widthRef: this.handleTotalWidth })));
|
|
1150
1183
|
}));
|
|
1151
1184
|
}
|
|
1152
1185
|
// Lifecycle
|
|
@@ -1231,8 +1264,7 @@ class TimelineView extends internal_cjs.DateComponent {
|
|
|
1231
1264
|
top: 0,
|
|
1232
1265
|
bottom: elHeight,
|
|
1233
1266
|
},
|
|
1234
|
-
|
|
1235
|
-
dayEl: this.bodyEl.querySelectorAll('.fc-timeline-slot')[slatIndex],
|
|
1267
|
+
getDayEl: () => getTimelineSlotEl(this.bodyEl, slatIndex),
|
|
1236
1268
|
layer: 0,
|
|
1237
1269
|
};
|
|
1238
1270
|
}
|
|
@@ -1240,12 +1272,12 @@ class TimelineView extends internal_cjs.DateComponent {
|
|
|
1240
1272
|
}
|
|
1241
1273
|
}
|
|
1242
1274
|
|
|
1243
|
-
var css_248z = ".fc-timeline-
|
|
1275
|
+
var css_248z = ".fc-timeline-lane-footer{padding-bottom:10px}.fc-timeline-overlap-disabled .fc-timeline-lane-footer{padding-bottom:0}.fc-timeline-slot-minor{border-style:dotted}.fc-timeline-event{border-radius:0;font-size:var(--fc-small-font-size);margin-bottom:1px}.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 .fc-event-inner{align-items:center;display:flex;flex-direction:row;padding:2px 1px}.fc-timeline-event-spacious .fc-event-inner{padding-bottom:5px;padding-top:5px}.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-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-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-now-indicator-container{bottom:0;left:0;overflow:hidden;pointer-events:none;position:absolute;right:0;top:0;z-index:2}.fc-timeline-now-indicator-arrow{border-bottom-style:solid;border-bottom-width:0;border-color:var(--fc-now-indicator-color);border-left:5px solid transparent;border-right:5px solid transparent;border-top-style:solid;border-top-width:6px;height:0;margin:0 -5px;position:absolute;top:0;width:0}.fc-timeline-now-indicator-line{border-left:1px solid var(--fc-now-indicator-color);bottom:0;position:absolute;top:0}";
|
|
1244
1276
|
internal_cjs.injectStyles(css_248z);
|
|
1245
1277
|
|
|
1278
|
+
exports.TimelineBg = TimelineBg;
|
|
1279
|
+
exports.TimelineFg = TimelineFg;
|
|
1246
1280
|
exports.TimelineHeaderRow = TimelineHeaderRow;
|
|
1247
|
-
exports.TimelineLane = TimelineLane;
|
|
1248
|
-
exports.TimelineLaneBg = TimelineLaneBg;
|
|
1249
1281
|
exports.TimelineLaneSlicer = TimelineLaneSlicer;
|
|
1250
1282
|
exports.TimelineNowIndicatorArrow = TimelineNowIndicatorArrow;
|
|
1251
1283
|
exports.TimelineNowIndicatorLine = TimelineNowIndicatorLine;
|
|
@@ -1255,4 +1287,5 @@ exports.buildTimelineDateProfile = buildTimelineDateProfile;
|
|
|
1255
1287
|
exports.computeSlotWidth = computeSlotWidth;
|
|
1256
1288
|
exports.createHorizontalStyle = createHorizontalStyle;
|
|
1257
1289
|
exports.createVerticalStyle = createVerticalStyle;
|
|
1290
|
+
exports.getTimelineSlotEl = getTimelineSlotEl;
|
|
1258
1291
|
exports.timeToCoord = timeToCoord;
|