@fullcalendar/timeline 7.0.0-beta.1 → 7.0.0-beta.3

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/internal.cjs CHANGED
@@ -452,42 +452,35 @@ class TimelineSlatCell extends internal_cjs.BaseComponent {
452
452
  }
453
453
  render() {
454
454
  let { props, context } = this;
455
- let { dateEnv, options, theme } = context;
455
+ let { dateEnv, options } = context;
456
456
  let { date, tDateProfile, isEm } = props;
457
457
  let dateMeta = internal_cjs.getDateMeta(props.date, props.todayRange, props.nowDate, props.dateProfile);
458
458
  let renderProps = Object.assign(Object.assign({ date: dateEnv.toDate(props.date) }, dateMeta), { view: context.viewApi });
459
- return (preact_cjs.createElement(internal_cjs.ContentContainer, { elTag: "div", elClasses: [
460
- 'fc-flex-column',
461
- 'fc-align-start',
462
- 'fc-cell',
463
- 'fc-timeline-slot',
464
- 'fc-timeline-slot-lane',
465
- isEm ? 'fc-timeline-slot-em' : '',
466
- tDateProfile.isTimeScale ? (internal_cjs.isInt(dateEnv.countDurationsBetween(// best to do this here?
467
- tDateProfile.normalizedRange.start, props.date, tDateProfile.labelInterval)) ?
468
- 'fc-timeline-slot-major' :
469
- 'fc-timeline-slot-minor') : '',
470
- ...(props.isDay ?
471
- internal_cjs.getDayClassNames(dateMeta, theme) :
472
- internal_cjs.getSlotClassNames(dateMeta, theme)),
473
- ], elAttrs: {
459
+ return (preact_cjs.createElement(internal_cjs.ContentContainer, { tag: "div",
460
+ // fc-align-start shrinks width of InnerContent
461
+ // TODO: document this semantic className fc-timeline-slot-em
462
+ className: internal_cjs.joinClassNames('fc-timeline-slot', isEm && 'fc-timeline-slot-em', tDateProfile.isTimeScale && (internal_cjs.isInt(dateEnv.countDurationsBetween(// best to do this here?
463
+ tDateProfile.normalizedRange.start, props.date, tDateProfile.labelInterval)) ?
464
+ 'fc-timeline-slot-major' :
465
+ 'fc-timeline-slot-minor'), 'fc-timeline-slot-lane fc-cell fc-flex-col fc-align-start', props.borderStart && 'fc-border-s', props.isDay ?
466
+ internal_cjs.getDayClassName(dateMeta) :
467
+ internal_cjs.getSlotClassName(dateMeta)), attrs: {
474
468
  'data-date': dateEnv.formatIso(date, {
475
469
  omitTimeZoneOffset: true,
476
470
  omitTime: !tDateProfile.isTimeScale,
477
471
  }),
478
- }, elStyle: {
472
+ }, style: {
479
473
  width: props.width,
480
- }, renderProps: renderProps, generatorName: "slotLaneContent", customGenerator: options.slotLaneContent, classNameGenerator: options.slotLaneClassNames, didMount: options.slotLaneDidMount, willUnmount: options.slotLaneWillUnmount }, (InnerContent) => (preact_cjs.createElement("div", { ref: this.innerElRef, className: 'fc-flex-column' },
481
- preact_cjs.createElement(InnerContent, { elTag: "div", elClasses: ['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', elRef: this.innerElRef }))));
482
475
  }
483
476
  componentDidMount() {
484
477
  const innerEl = this.innerElRef.current;
485
- this.detachWidth = internal_cjs.watchWidth(innerEl, (width) => {
478
+ this.disconnectInnerWidth = internal_cjs.watchWidth(innerEl, (width) => {
486
479
  internal_cjs.setRef(this.props.innerWidthRef, width);
487
480
  });
488
481
  }
489
482
  componentWillUnmount() {
490
- this.detachWidth();
483
+ this.disconnectInnerWidth();
491
484
  internal_cjs.setRef(this.props.innerWidthRef, null);
492
485
  }
493
486
  }
@@ -513,9 +506,9 @@ class TimelineSlats extends internal_cjs.BaseComponent {
513
506
  let { tDateProfile, slotWidth } = props;
514
507
  let { slotDates, isWeekStarts } = tDateProfile;
515
508
  let isDay = !tDateProfile.isTimeScale && !tDateProfile.largeUnit;
516
- return (preact_cjs.createElement("div", { className: "fc-timeline-slots fc-fill fc-flex-row" }, slotDates.map((slotDate, i) => {
509
+ return (preact_cjs.createElement("div", { className: "fc-timeline-slots fc-fill fc-flex-row", style: { height: props.height } }, slotDates.map((slotDate, i) => {
517
510
  let key = slotDate.toISOString();
518
- 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,
511
+ 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),
519
512
  // ref
520
513
  innerWidthRef: innerWidthRefMap.createRef(key),
521
514
  // dimensions
@@ -549,30 +542,6 @@ function computeDateSnapCoverage$1(date, tDateProfile, dateEnv) {
549
542
  return snapCoverage;
550
543
  }
551
544
  /*
552
- TODO: audit!!!
553
- */
554
- function coordToCss(hcoord, isRtl) {
555
- if (hcoord === null) {
556
- return { left: '', right: '' };
557
- }
558
- if (isRtl) {
559
- return { right: hcoord, left: '' };
560
- }
561
- return { left: hcoord, right: '' };
562
- }
563
- /*
564
- TODO: audit!!!
565
- */
566
- function coordsToCss(hcoords, isRtl) {
567
- if (!hcoords) {
568
- return { left: '', right: '' };
569
- }
570
- if (isRtl) {
571
- return { right: hcoords.start, left: -hcoords.end };
572
- }
573
- return { left: hcoords.start, right: -hcoords.end };
574
- }
575
- /*
576
545
  TODO: DRY up with elsewhere?
577
546
  */
578
547
  function horizontalsToCss(hcoord, isRtl) {
@@ -603,7 +572,8 @@ function createVerticalStyle(props) {
603
572
  };
604
573
  }
605
574
  }
606
- function createHorizontalStyle(props, isRtl) {
575
+ function createHorizontalStyle(// TODO: DRY up?
576
+ props, isRtl) {
607
577
  if (props) {
608
578
  return {
609
579
  [isRtl ? 'right' : 'left']: props.start,
@@ -676,13 +646,13 @@ function computeDateSnapCoverage(date, tDateProfile, dateEnv) {
676
646
  function computeManySegHorizontals(segs, segMinWidth, dateEnv, tDateProfile, slotWidth) {
677
647
  const res = {};
678
648
  for (const seg of segs) {
679
- res[seg.eventRange.instance.instanceId] = computeSegHorizontals(seg, segMinWidth, dateEnv, tDateProfile, slotWidth);
649
+ res[internal_cjs.getEventKey(seg)] = computeSegHorizontals(seg, segMinWidth, dateEnv, tDateProfile, slotWidth);
680
650
  }
681
651
  return res;
682
652
  }
683
653
  function computeSegHorizontals(seg, segMinWidth, dateEnv, tDateProfile, slotWidth) {
684
- const startCoord = dateToCoord(seg.start, dateEnv, tDateProfile, slotWidth);
685
- const endCoord = dateToCoord(seg.end, dateEnv, tDateProfile, slotWidth);
654
+ const startCoord = dateToCoord(seg.startDate, dateEnv, tDateProfile, slotWidth);
655
+ const endCoord = dateToCoord(seg.endDate, dateEnv, tDateProfile, slotWidth);
686
656
  let size = endCoord - startCoord;
687
657
  if (segMinWidth) {
688
658
  size = Math.max(size, segMinWidth);
@@ -690,95 +660,58 @@ function computeSegHorizontals(seg, segMinWidth, dateEnv, tDateProfile, slotWidt
690
660
  return { start: startCoord, size };
691
661
  }
692
662
  function computeFgSegPlacements(// mostly horizontals
693
- segs, segHorizontals, segHeights, // keyed by instanceId
694
- strictOrder, maxStackCnt) {
695
- let segEntries = [];
696
- for (let i = 0; i < segs.length; i += 1) {
697
- let seg = segs[i];
698
- let instanceId = seg.eventRange.instance.instanceId;
699
- let height = segHeights.get(instanceId);
700
- let hcoords = segHorizontals[instanceId];
701
- if (height != null && hcoords != null) {
702
- segEntries.push({
703
- index: i,
704
- seg,
705
- span: {
706
- start: hcoords.start,
707
- end: hcoords.start + hcoords.size,
708
- },
709
- thickness: height,
710
- });
663
+ segs, segHorizontals, // TODO: use Map
664
+ segHeights, // keyed by instanceId
665
+ hiddenGroupHeights, strictOrder, maxDepth) {
666
+ const segRanges = [];
667
+ // isn't it true that there will either be ALL hcoords or NONE? can optimize
668
+ for (const seg of segs) {
669
+ const hcoords = segHorizontals[internal_cjs.getEventKey(seg)];
670
+ if (hcoords) {
671
+ segRanges.push(Object.assign(Object.assign({}, seg), { start: hcoords.start, end: hcoords.start + hcoords.size }));
711
672
  }
712
673
  }
713
- let hierarchy = new internal_cjs.SegHierarchy();
714
- if (strictOrder != null) {
715
- hierarchy.strictOrder = strictOrder;
716
- }
717
- if (maxStackCnt != null) {
718
- hierarchy.maxStackCnt = maxStackCnt;
719
- }
720
- let hiddenEntries = hierarchy.addSegs(segEntries);
721
- let hiddenGroups = internal_cjs.groupIntersectingEntries(hiddenEntries);
722
- let hiddenGroupEntries = hiddenGroups.map((hiddenGroup, index) => ({
723
- index: segs.length + index,
724
- segGroup: hiddenGroup,
725
- span: hiddenGroup.span,
726
- thickness: 1, // HACK to ensure it's placed
727
- }));
728
- // add more-links into the hierarchy, but don't limit
729
- hierarchy.maxStackCnt = -1;
730
- hierarchy.addSegs(hiddenGroupEntries);
731
- let visibleRects = hierarchy.toRects();
732
- let segTops = {};
733
- let hiddenGroupTops = {};
734
- for (let rect of visibleRects) {
735
- const { seg, segGroup } = rect;
736
- if (seg) { // regular seg
737
- segTops[seg.eventRange.instance.instanceId] = rect.levelCoord;
738
- }
739
- else { // hiddenGroup
740
- hiddenGroupTops[segGroup.key] = rect.levelCoord;
674
+ const hierarchy = new internal_cjs.SegHierarchy(segRanges, (seg) => segHeights.get(internal_cjs.getEventKey(seg)), strictOrder, undefined, // maxCoord
675
+ maxDepth);
676
+ const segTops = new Map();
677
+ hierarchy.traverseSegs((seg, segTop) => {
678
+ segTops.set(internal_cjs.getEventKey(seg), segTop);
679
+ });
680
+ const { hiddenSegs } = hierarchy;
681
+ let totalHeight = 0;
682
+ for (const segRange of segRanges) {
683
+ const segKey = internal_cjs.getEventKey(segRange);
684
+ const segHeight = segHeights.get(segKey);
685
+ const segTop = segTops.get(segKey);
686
+ if (segHeight != null) {
687
+ if (segTop != null) {
688
+ totalHeight = Math.max(totalHeight, segTop + segHeight);
689
+ }
741
690
  }
742
691
  }
692
+ const hiddenGroups = internal_cjs.groupIntersectingSegs(hiddenSegs);
693
+ const hiddenGroupTops = new Map();
694
+ // HACK for hiddenGroup findInsertion() call
695
+ hierarchy.strictOrder = true;
696
+ for (const hiddenGroup of hiddenGroups) {
697
+ const { levelCoord: top } = hierarchy.findInsertion(hiddenGroup, 0);
698
+ const hiddenGroupHeight = hiddenGroupHeights.get(hiddenGroup.key) || 0;
699
+ hiddenGroupTops.set(hiddenGroup.key, top);
700
+ totalHeight = Math.max(totalHeight, top + hiddenGroupHeight);
701
+ }
743
702
  return [
744
703
  segTops,
745
- computeMaxBottom(segs, segTops, segHeights),
746
704
  hiddenGroups,
747
705
  hiddenGroupTops,
706
+ totalHeight,
748
707
  ];
749
708
  }
750
- function computeMaxBottom(segs, segTops, segHeights) {
751
- let max = 0;
752
- for (const seg of segs) {
753
- const { instanceId } = seg.eventRange.instance;
754
- const top = segTops[instanceId];
755
- const height = segHeights.get(instanceId);
756
- if (top != null && height != null) {
757
- max = Math.max(max, top + height);
758
- }
759
- }
760
- return max;
761
- }
762
- /*
763
- TODO: converge with computeMaxBottom, but keys are different
764
- */
765
- function computeMoreLinkMaxBottom(hiddenGroups, hiddenGroupTops, hiddenGroupHeights) {
766
- let max = 0;
767
- for (const hiddenGroup of hiddenGroups) {
768
- const top = hiddenGroupTops[hiddenGroup.key];
769
- const height = hiddenGroupHeights.get(hiddenGroup.key);
770
- if (top != null && height != null) {
771
- max = Math.max(max, top + height);
772
- }
773
- }
774
- return max;
775
- }
776
709
 
777
710
  class TimelineLaneBg extends internal_cjs.BaseComponent {
778
711
  render() {
779
712
  let { props } = this;
780
713
  let highlightSeg = [].concat(props.eventResizeSegs, props.dateSelectionSegs);
781
- return (preact_cjs.createElement("div", { className: "fc-timeline-bg" },
714
+ return (preact_cjs.createElement(preact_cjs.Fragment, null,
782
715
  this.renderSegs(props.businessHourSegs || [], 'non-business'),
783
716
  this.renderSegs(props.bgEventSegs || [], 'bg-event'),
784
717
  this.renderSegs(highlightSeg, 'highlight')));
@@ -792,7 +725,7 @@ class TimelineLaneBg extends internal_cjs.BaseComponent {
792
725
  let segHorizontal = computeSegHorizontals(seg, undefined, dateEnv, tDateProfile, slotWidth);
793
726
  hStyle = horizontalsToCss(segHorizontal, isRtl);
794
727
  }
795
- return (preact_cjs.createElement("div", { key: internal_cjs.buildEventRangeKey(seg.eventRange), className: "fc-timeline-bg-harness", style: hStyle }, fillType === 'bg-event' ?
728
+ return (preact_cjs.createElement("div", { key: internal_cjs.buildEventRangeKey(seg.eventRange), className: "fc-fill-y", style: hStyle }, fillType === 'bg-event' ?
796
729
  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))));
797
730
  })));
798
731
  }
@@ -809,8 +742,8 @@ class TimelineLaneSlicer extends internal_cjs.Slicer {
809
742
  let slicedRange = internal_cjs.intersectRanges(normalRange, tDateProfile.normalizedRange);
810
743
  if (slicedRange) {
811
744
  segs.push({
812
- start: slicedRange.start,
813
- end: slicedRange.end,
745
+ startDate: slicedRange.start,
746
+ endDate: slicedRange.end,
814
747
  isStart: slicedRange.start.valueOf() === normalRange.start.valueOf()
815
748
  && isValidDate(slicedRange.start, tDateProfile, dateProfile, dateProfileGenerator),
816
749
  isEnd: slicedRange.end.valueOf() === normalRange.end.valueOf()
@@ -832,13 +765,8 @@ class TimelineEvent extends internal_cjs.BaseComponent {
832
765
  render() {
833
766
  let { props, context } = this;
834
767
  let { options } = context;
835
- return (preact_cjs.createElement(internal_cjs.StandardEvent, Object.assign({}, props, { elClasses: [
836
- 'fc-timeline-event',
837
- 'fc-h-event',
838
- options.eventOverlap === false // TODO: fix bad default
839
- ? 'fc-timeline-event-spacious'
840
- : ''
841
- ], defaultTimeFormat: DEFAULT_TIME_FORMAT, defaultDisplayEventTime: !props.isTimeScale })));
768
+ return (preact_cjs.createElement(internal_cjs.StandardEvent, Object.assign({}, props, { className: internal_cjs.joinClassNames('fc-timeline-event', options.eventOverlap === false // TODO: fix bad default
769
+ && 'fc-timeline-event-spacious', 'fc-h-event'), defaultTimeFormat: DEFAULT_TIME_FORMAT, defaultDisplayEventTime: !props.isTimeScale })));
842
770
  }
843
771
  }
844
772
 
@@ -846,13 +774,13 @@ class TimelineLaneMoreLink extends internal_cjs.BaseComponent {
846
774
  render() {
847
775
  let { props } = this;
848
776
  let { hiddenSegs, resourceId, forcedInvisibleMap } = props;
849
- let extraDateSpan = resourceId ? { resourceId } : {};
850
- return (preact_cjs.createElement(internal_cjs.MoreLinkContainer, { elClasses: ['fc-timeline-more-link'], allDayDate: null, segs: hiddenSegs, hiddenSegs: hiddenSegs, dateProfile: props.dateProfile, todayRange: props.todayRange, extraDateSpan: extraDateSpan, popoverContent: () => (preact_cjs.createElement(preact_cjs.Fragment, null, hiddenSegs.map((seg) => {
777
+ let dateSpanProps = resourceId ? { resourceId } : {};
778
+ 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) => {
851
779
  let { eventRange } = seg;
852
780
  let instanceId = eventRange.instance.instanceId;
853
781
  return (preact_cjs.createElement("div", { key: instanceId, style: { visibility: forcedInvisibleMap[instanceId] ? 'hidden' : '' } },
854
782
  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)))));
855
- }))) }, (InnerContent) => (preact_cjs.createElement(InnerContent, { elTag: "div", elClasses: ['fc-timeline-more-link-inner', 'fc-sticky-x'] }))));
783
+ }))) }, (InnerContent) => (preact_cjs.createElement(InnerContent, { tag: "div", className: 'fc-timeline-more-link-inner fc-sticky-s' }))));
856
784
  }
857
785
  }
858
786
 
@@ -871,12 +799,12 @@ class TimelineEventHarness extends preact_cjs.Component {
871
799
  }
872
800
  componentDidMount() {
873
801
  const rootEl = this.rootElRef.current; // TODO: make dynamic with useEffect
874
- this.detachHeight = internal_cjs.watchHeight(rootEl, (height) => {
802
+ this.disconnectHeight = internal_cjs.watchHeight(rootEl, (height) => {
875
803
  internal_cjs.setRef(this.props.heightRef, height);
876
804
  });
877
805
  }
878
806
  componentWillUnmount() {
879
- this.detachHeight();
807
+ this.disconnectHeight();
880
808
  internal_cjs.setRef(this.props.heightRef, null);
881
809
  }
882
810
  }
@@ -909,7 +837,7 @@ class TimelineLane extends internal_cjs.BaseComponent {
909
837
  TODO: lots of memoization needed here!
910
838
  */
911
839
  render() {
912
- let { props, context, segHeightRefMap } = this;
840
+ let { props, context, segHeightRefMap, moreLinkHeightRefMap } = this;
913
841
  let { options } = context;
914
842
  let { dateProfile, tDateProfile } = props;
915
843
  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...
@@ -921,10 +849,7 @@ class TimelineLane extends internal_cjs.BaseComponent {
921
849
  let fgSegHorizontals = props.slotWidth != null
922
850
  ? computeManySegHorizontals(fgSegs, options.eventMinWidth, context.dateEnv, tDateProfile, props.slotWidth)
923
851
  : {};
924
- let [fgSegTops, fgSegsBottom, hiddenGroups, hiddenGroupTops] = computeFgSegPlacements(// verticals
925
- fgSegs, fgSegHorizontals, segHeightRefMap.current, options.eventOrderStrict, options.eventMaxStack);
926
- let moreLinksBottom = computeMoreLinkMaxBottom(hiddenGroups, hiddenGroupTops, this.moreLinkHeightRefMap.current);
927
- let innerHeight = Math.max(moreLinksBottom, fgSegsBottom);
852
+ let [fgSegTops, hiddenGroups, hiddenGroupTops, totalHeight] = computeFgSegPlacements(fgSegs, fgSegHorizontals, segHeightRefMap.current, moreLinkHeightRefMap.current, options.eventOrderStrict, options.eventMaxStack);
928
853
  let forcedInvisibleMap = // TODO: more convenient/DRY
929
854
  (slicedProps.eventDrag ? slicedProps.eventDrag.affectedInstances : null) ||
930
855
  (slicedProps.eventResize ? slicedProps.eventResize.affectedInstances : null) ||
@@ -935,20 +860,18 @@ class TimelineLane extends internal_cjs.BaseComponent {
935
860
  bgEventSegs: slicedProps.bgEventSegs, businessHourSegs: slicedProps.businessHourSegs, dateSelectionSegs: slicedProps.dateSelectionSegs, eventResizeSegs: slicedProps.eventResize ? slicedProps.eventResize.segs : [] /* bad new empty array? */,
936
861
  // dimensions
937
862
  slotWidth: props.slotWidth }),
938
- preact_cjs.createElement("div", { className: [
939
- 'fc-timeline-events',
940
- 'fc-content-box',
941
- options.eventOverlap === false // TODO: fix bad default
942
- ? 'fc-timeline-events-overlap-disabled'
943
- : 'fc-timeline-events-overlap-enabled'
944
- ].join(' '), style: { height: innerHeight } },
863
+ preact_cjs.createElement("div", { className: internal_cjs.joinClassNames('fc-timeline-events', options.eventOverlap === false // TODO: fix bad default
864
+ ? 'fc-timeline-events-overlap-disabled'
865
+ : 'fc-timeline-events-overlap-enabled', 'fc-content-box'), style: { height: totalHeight } },
945
866
  this.renderFgSegs(fgSegs, fgSegHorizontals, fgSegTops, forcedInvisibleMap, hiddenGroups, hiddenGroupTops, false, // isDragging
946
867
  false, // isResizing
947
868
  false),
948
869
  this.renderFgSegs(mirrorSegs, props.slotWidth // TODO: memoize
949
870
  ? computeManySegHorizontals(mirrorSegs, options.eventMinWidth, context.dateEnv, tDateProfile, props.slotWidth)
950
871
  : {}, fgSegTops, {}, // forcedInvisibleMap
951
- [], {}, Boolean(slicedProps.eventDrag), Boolean(slicedProps.eventResize), false))));
872
+ [], // hiddenGroups
873
+ new Map(), // hiddenGroupTops
874
+ Boolean(slicedProps.eventDrag), Boolean(slicedProps.eventResize), false))));
952
875
  }
953
876
  renderFgSegs(segs, segHorizontals, segTops, forcedInvisibleMap, hiddenGroups, hiddenGroupTops, isDragging, isResizing, isDateSelecting) {
954
877
  let { props, context, segHeightRefMap, moreLinkHeightRefMap } = this;
@@ -957,18 +880,18 @@ class TimelineLane extends internal_cjs.BaseComponent {
957
880
  segs.map((seg) => {
958
881
  const { eventRange } = seg;
959
882
  const { instanceId } = eventRange.instance;
960
- const segTop = segTops[instanceId];
883
+ const segTop = segTops.get(instanceId);
961
884
  const segHorizontal = segHorizontals[instanceId];
962
885
  const isVisible = isMirror ||
963
886
  (segHorizontal && segTop != null && !forcedInvisibleMap[instanceId]);
964
887
  return (preact_cjs.createElement(TimelineEventHarness, { key: instanceId, style: Object.assign({ visibility: isVisible ? '' : 'hidden', top: segTop || 0 }, horizontalsToCss(segHorizontal, context.isRtl)), heightRef: isMirror ? undefined : segHeightRefMap.createRef(instanceId) },
965
888
  preact_cjs.createElement(TimelineEvent, Object.assign({ isTimeScale: props.tDateProfile.isTimeScale, eventRange: eventRange, isStart: seg.isStart, isEnd: seg.isEnd, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === props.eventSelection /* TODO: bad for mirror? */ }, internal_cjs.getEventRangeMeta(eventRange, props.todayRange, props.nowDate)))));
966
889
  }),
967
- hiddenGroups.map((hiddenGroup) => (preact_cjs.createElement(TimelineEventHarness, { key: hiddenGroup.key, style: Object.assign({ top: hiddenGroupTops[hiddenGroup.key] || 0 }, horizontalsToCss({
968
- start: hiddenGroup.span.start,
969
- size: hiddenGroup.span.end - hiddenGroup.span.start
890
+ hiddenGroups.map((hiddenGroup) => (preact_cjs.createElement(TimelineEventHarness, { key: hiddenGroup.key, style: Object.assign({ top: hiddenGroupTops.get(hiddenGroup.key) || 0 }, horizontalsToCss({
891
+ start: hiddenGroup.start,
892
+ size: hiddenGroup.end - hiddenGroup.start
970
893
  }, context.isRtl)), heightRef: moreLinkHeightRefMap.createRef(hiddenGroup.key) },
971
- preact_cjs.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 }))))));
894
+ 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 }))))));
972
895
  }
973
896
  }
974
897
 
@@ -996,36 +919,21 @@ class TimelineHeaderCell extends internal_cjs.BaseComponent {
996
919
  dateEnv: context.dateEnv,
997
920
  viewApi: context.viewApi,
998
921
  });
999
- return (preact_cjs.createElement(internal_cjs.ContentContainer, { elTag: "div", elClasses: [
1000
- 'fc-timeline-slot-label',
1001
- 'fc-timeline-slot',
1002
- cell.isWeekStart ? 'fc-timeline-slot-em' : '',
1003
- 'fc-header-cell',
1004
- 'fc-cell',
1005
- 'fc-flex-column',
1006
- 'fc-justify-center',
1007
- props.isCentered ? 'fc-align-center' : 'fc-align-start',
1008
- ...( // TODO: so slot classnames for week/month/bigger. see note above about rowUnit
1009
- cell.rowUnit === 'time' ?
1010
- internal_cjs.getSlotClassNames(dateMeta, context.theme) :
1011
- internal_cjs.getDayClassNames(dateMeta, context.theme)),
1012
- ], elAttrs: {
922
+ 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
923
+ 'fc-header-cell fc-cell fc-flex-col fc-justify-center', props.borderStart && 'fc-border-s', props.isCentered ? 'fc-align-center' : 'fc-align-start',
924
+ // TODO: so slot classnames for week/month/bigger. see note above about rowUnit
925
+ cell.rowUnit === 'time' ?
926
+ internal_cjs.getSlotClassName(dateMeta) :
927
+ internal_cjs.getDayClassName(dateMeta)), attrs: {
1013
928
  'data-date': dateEnv.formatIso(cell.date, {
1014
929
  omitTime: !tDateProfile.isTimeScale,
1015
930
  omitTimeZoneOffset: true,
1016
931
  }),
1017
- }, elStyle: {
932
+ }, style: {
1018
933
  width: props.slotWidth != null
1019
934
  ? props.slotWidth * cell.colspan
1020
935
  : undefined,
1021
- }, renderProps: renderProps, generatorName: "slotLabelContent", customGenerator: options.slotLabelContent, defaultGenerator: renderInnerContent, classNameGenerator: options.slotLabelClassNames, didMount: options.slotLabelDidMount, willUnmount: options.slotLabelWillUnmount }, (InnerContent) => (preact_cjs.createElement("div", { ref: this.innerElRef, className: [
1022
- 'fc-flex-column',
1023
- props.isSticky ? 'fc-sticky-x' : '',
1024
- ].join(' ') },
1025
- preact_cjs.createElement(InnerContent, { elTag: "a", elClasses: [
1026
- 'fc-cell-inner',
1027
- 'fc-padding-md',
1028
- ], elAttrs: this.buildCellNavLinkAttrs(context, cell.date, cell.rowUnit) })))));
936
+ }, renderProps: renderProps, generatorName: "slotLabelContent", customGenerator: options.slotLabelContent, defaultGenerator: renderInnerContent, classNameGenerator: options.slotLabelClassNames, didMount: options.slotLabelDidMount, willUnmount: options.slotLabelWillUnmount }, (InnerContent) => (preact_cjs.createElement(InnerContent, { tag: "a", attrs: this.buildCellNavLinkAttrs(context, cell.date, cell.rowUnit), className: internal_cjs.joinClassNames('fc-cell-inner fc-padding-md', props.isSticky && 'fc-sticky-s'), elRef: this.innerElRef }))));
1029
937
  }
1030
938
  componentDidMount() {
1031
939
  const { props } = this;
@@ -1099,13 +1007,14 @@ class TimelineHeaderRow extends internal_cjs.BaseComponent {
1099
1007
  const { props, innerWidthRefMap, innerHeightRefMap } = this;
1100
1008
  const isCentered = !(props.tDateProfile.isTimeScale && props.isLastRow);
1101
1009
  const isSticky = !props.isLastRow;
1102
- return (preact_cjs.createElement("div", { className: 'fc-row', style: { height: props.height } }, props.cells.map((cell) => {
1010
+ return (preact_cjs.createElement("div", { className: internal_cjs.joinClassNames('fc-flex-row fc-grow', // TODO: move fc-grow to parent?
1011
+ !props.isLastRow && 'fc-border-b') }, props.cells.map((cell, cellI) => {
1103
1012
  // TODO: make this part of the cell obj?
1104
1013
  // TODO: rowUnit seems wrong sometimes. says 'month' when it should be day
1105
1014
  // TODO: rowUnit is relevant to whole row. put it on a row object, not the cells
1106
1015
  // TODO: use rowUnit to key the Row itself?
1107
1016
  const key = cell.rowUnit + ':' + cell.date.toISOString();
1108
- 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,
1017
+ 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),
1109
1018
  // refs
1110
1019
  innerWidthRef: innerWidthRefMap.createRef(key), innerHeightRef: innerHeightRefMap.createRef(key),
1111
1020
  // dimensions
@@ -1123,7 +1032,7 @@ class TimelineNowIndicatorLine extends internal_cjs.BaseComponent {
1123
1032
  const { props, context } = this;
1124
1033
  return (preact_cjs.createElement("div", { className: "fc-timeline-now-indicator-container" },
1125
1034
  preact_cjs.createElement(internal_cjs.NowIndicatorContainer // TODO: make separate component?
1126
- , { elClasses: ['fc-timeline-now-indicator-line'], elStyle: props.slotWidth != null
1035
+ , { className: 'fc-timeline-now-indicator-line', style: props.slotWidth != null
1127
1036
  ? horizontalCoordToCss(dateToCoord(props.nowDate, context.dateEnv, props.tDateProfile, props.slotWidth), context.isRtl)
1128
1037
  : {}, isAxis: false, date: props.nowDate })));
1129
1038
  }
@@ -1133,7 +1042,7 @@ class TimelineNowIndicatorArrow extends internal_cjs.BaseComponent {
1133
1042
  render() {
1134
1043
  const { props, context } = this;
1135
1044
  return (preact_cjs.createElement("div", { className: "fc-timeline-now-indicator-container" },
1136
- preact_cjs.createElement(internal_cjs.NowIndicatorContainer, { elClasses: ['fc-timeline-now-indicator-arrow'], elStyle: props.slotWidth != null
1045
+ preact_cjs.createElement(internal_cjs.NowIndicatorContainer, { className: 'fc-timeline-now-indicator-arrow', style: props.slotWidth != null
1137
1046
  ? horizontalCoordToCss(dateToCoord(props.nowDate, context.dateEnv, props.tDateProfile, props.slotWidth), context.isRtl)
1138
1047
  : {}, isAxis: true, date: props.nowDate })));
1139
1048
  }
@@ -1166,19 +1075,14 @@ class TimelineView extends internal_cjs.DateComponent {
1166
1075
  this.setState({ slotInnerWidth });
1167
1076
  }
1168
1077
  };
1169
- this.handleScrollerWidth = (scrollerWidth) => {
1170
- this.setState({
1171
- scrollerWidth,
1172
- });
1173
- };
1174
- this.handleLeftScrollbarWidth = (leftScrollbarWidth) => {
1078
+ this.handleClientWidth = (clientWidth) => {
1175
1079
  this.setState({
1176
- leftScrollbarWidth
1080
+ clientWidth,
1177
1081
  });
1178
1082
  };
1179
- this.handleRightScrollbarWidth = (rightScrollbarWidth) => {
1083
+ this.handleEndScrollbarWidth = (endScrollbarWidth) => {
1180
1084
  this.setState({
1181
- rightScrollbarWidth
1085
+ endScrollbarWidth
1182
1086
  });
1183
1087
  };
1184
1088
  this.handleTimeScroll = (scrollTime) => {
@@ -1190,7 +1094,7 @@ class TimelineView extends internal_cjs.DateComponent {
1190
1094
  if (scrollTime != null && slotWidth != null) {
1191
1095
  let x = timeToCoord(scrollTime, context.dateEnv, props.dateProfile, tDateProfile, slotWidth);
1192
1096
  if (x) {
1193
- x += context.isRtl ? -1 : 1; // overcome border. TODO: DRY this up
1097
+ x += 1; // overcome border. TODO: DRY this up
1194
1098
  }
1195
1099
  this.syncedScroller.scrollTo({ x });
1196
1100
  }
@@ -1223,44 +1127,30 @@ class TimelineView extends internal_cjs.DateComponent {
1223
1127
  const stickyFooterScrollbar = !props.forPrint && internal_cjs.getStickyFooterScrollbar(options);
1224
1128
  /* table positions */
1225
1129
  const [canvasWidth, slotWidth] = this.computeSlotWidth(tDateProfile.slotCnt, tDateProfile.slotsPerLabel, options.slotMinWidth, state.slotInnerWidth, // is ACTUALLY the label width. rename?
1226
- state.scrollerWidth);
1130
+ state.clientWidth);
1227
1131
  this.slotWidth = slotWidth;
1228
1132
  return (preact_cjs.createElement(internal_cjs.NowTimer, { unit: timerUnit }, (nowDate, todayRange) => {
1229
1133
  const enableNowIndicator = // TODO: DRY
1230
1134
  options.nowIndicator &&
1231
1135
  slotWidth != null &&
1232
1136
  internal_cjs.rangeContainsMarker(props.dateProfile.currentRange, nowDate);
1233
- return (preact_cjs.createElement(internal_cjs.ViewContainer, { viewSpec: context.viewSpec, elClasses: [
1234
- 'fc-timeline-view',
1235
- 'fc-flex-column',
1236
- 'fc-border',
1237
- ] },
1238
- preact_cjs.createElement(internal_cjs.Scroller, { horizontal: true, hideScrollbars: true, elClassNames: [
1239
- 'fc-timeline-header',
1240
- 'fc-rowgroup',
1241
- stickyHeaderDates ? 'fc-sticky-header' : '',
1242
- ], ref: this.headerScrollerRef },
1243
- preact_cjs.createElement("div", { className: 'fc-rel fc-content-box' // origin for now-indicator
1244
- , style: {
1245
- width: canvasWidth,
1246
- paddingLeft: state.leftScrollbarWidth,
1247
- paddingRight: state.rightScrollbarWidth,
1248
- } },
1249
- preact_cjs.createElement("div", null, cellRows.map((cells, rowLevel) => {
1137
+ return (preact_cjs.createElement(internal_cjs.ViewContainer, { viewSpec: context.viewSpec, className: internal_cjs.joinClassNames('fc-timeline fc-border',
1138
+ // HACK for Safari print-mode, where fc-scroller-no-bars won't take effect for
1139
+ // the below Scrollers if they have liquid flex height
1140
+ !props.forPrint && 'fc-flex-col') },
1141
+ preact_cjs.createElement(internal_cjs.Scroller, { horizontal: true, hideScrollbars: true, className: internal_cjs.joinClassNames('fc-timeline-header fc-flex-row fc-border-b', stickyHeaderDates && 'fc-table-header-sticky'), ref: this.headerScrollerRef },
1142
+ preact_cjs.createElement("div", {
1143
+ // TODO: DRY
1144
+ className: internal_cjs.joinClassNames('fc-rel', // origin for now-indicator
1145
+ canvasWidth == null && 'fc-liquid'), style: { width: canvasWidth } },
1146
+ cellRows.map((cells, rowLevel) => {
1250
1147
  const isLast = rowLevel === cellRows.length - 1;
1251
1148
  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) }));
1252
- })),
1253
- enableNowIndicator && (
1254
- // TODO: make this positioned WITHIN padding?
1255
- preact_cjs.createElement(TimelineNowIndicatorArrow, { tDateProfile: tDateProfile, nowDate: nowDate, slotWidth: slotWidth })))),
1256
- preact_cjs.createElement(internal_cjs.Scroller, { vertical: verticalScrolling, horizontal: true, elClassNames: [
1257
- 'fc-timeline-body',
1258
- 'fc-rowgroup',
1259
- verticalScrolling ? 'fc-liquid' : '',
1260
- ], ref: this.bodyScrollerRef, widthRef: this.handleScrollerWidth, leftScrollbarWidthRef: this.handleLeftScrollbarWidth, rightScrollbarWidthRef: this.handleRightScrollbarWidth },
1261
- preact_cjs.createElement("div", { className: "fc-rel fc-grow", style: {
1262
- width: canvasWidth,
1263
- }, ref: this.handeBodyEl },
1149
+ }),
1150
+ enableNowIndicator && (preact_cjs.createElement(TimelineNowIndicatorArrow, { tDateProfile: tDateProfile, nowDate: nowDate, slotWidth: slotWidth }))),
1151
+ Boolean(state.endScrollbarWidth) && (preact_cjs.createElement("div", { className: 'fc-border-s fc-filler', style: { minWidth: state.endScrollbarWidth } }))),
1152
+ preact_cjs.createElement(internal_cjs.Scroller, { vertical: verticalScrolling, horizontal: true, hideScrollbars: props.forPrint, className: internal_cjs.joinClassNames('fc-timeline-body fc-flex-col', verticalScrolling && 'fc-liquid'), ref: this.bodyScrollerRef, clientWidthRef: this.handleClientWidth, endScrollbarWidthRef: this.handleEndScrollbarWidth },
1153
+ preact_cjs.createElement("div", { className: "fc-rel fc-grow", style: { width: canvasWidth }, ref: this.handeBodyEl },
1264
1154
  preact_cjs.createElement(TimelineSlats, { dateProfile: props.dateProfile, tDateProfile: tDateProfile, nowDate: nowDate, todayRange: todayRange,
1265
1155
  // ref
1266
1156
  innerWidthRef: this.handleBodySlotInnerWidth,
@@ -1353,7 +1243,7 @@ class TimelineView extends internal_cjs.DateComponent {
1353
1243
  }
1354
1244
  }
1355
1245
 
1356
- 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}";
1246
+ var css_248z = ".fc-timeline-slots{z-index:1}.fc-timeline-events{position:relative;z-index:2}.fc-timeline-slot-minor{border-style:dotted}.fc-timeline-events-overlap-enabled{padding-bottom:10px}.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:4}.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}";
1357
1247
  internal_cjs.injectStyles(css_248z);
1358
1248
 
1359
1249
  exports.TimelineHeaderRow = TimelineHeaderRow;
@@ -1366,8 +1256,6 @@ exports.TimelineSlats = TimelineSlats;
1366
1256
  exports.TimelineView = TimelineView;
1367
1257
  exports.buildTimelineDateProfile = buildTimelineDateProfile;
1368
1258
  exports.computeSlotWidth = computeSlotWidth;
1369
- exports.coordToCss = coordToCss;
1370
- exports.coordsToCss = coordsToCss;
1371
1259
  exports.createHorizontalStyle = createHorizontalStyle;
1372
1260
  exports.createVerticalStyle = createVerticalStyle;
1373
1261
  exports.timeToCoord = timeToCoord;