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