Sfoglia il codice sorgente

better way of doing slatcoords

Adam Shaw 6 anni fa
parent
commit
30b0461946

+ 11 - 30
packages/timegrid/src/TimeCols.tsx

@@ -24,7 +24,7 @@ import TimeColsSlats from './TimeColsSlats'
 import TimeColsContent from './TimeColsContent'
 import TimeColsBg from './TimeColsBg'
 import { __assign } from 'tslib'
-import TimeColsSlatsCoords, { TimeColsSlatsCoordsProps } from './TimeColsSlatsCoords'
+import TimeColsSlatsCoords from './TimeColsSlatsCoords'
 
 
 export interface TimeColsProps {
@@ -60,7 +60,7 @@ export interface TimeColsSeg extends Seg {
 export const TIME_COLS_NOW_INDICATOR_UNIT = 'minute'
 
 interface TimeColsState {
-  slatPositions?: PositionCache
+  slatCoords?: TimeColsSlatsCoords
 }
 
 
@@ -70,12 +70,10 @@ interface TimeColsState {
 export default class TimeCols extends BaseComponent<TimeColsProps, TimeColsState> {
 
   private processSlotOptions = memoize(processSlotOptions)
-  private buildSlatCoords = memoize(buildSlatCoords)
   private snapDuration: Duration
   private snapsPerSlot: number
   private scrollResponder: ScrollResponder
   private colCoords: PositionCache
-  private slatCoords: TimeColsSlatsCoords
 
 
   render(props: TimeColsProps, state: TimeColsState, context: ComponentContext) {
@@ -86,14 +84,6 @@ export default class TimeCols extends BaseComponent<TimeColsProps, TimeColsState
     this.snapDuration = snapDuration
     this.snapsPerSlot = snapsPerSlot
 
-    this.slatCoords = this.buildSlatCoords({
-      positions: state.slatPositions,
-      dateProfile: props.dateProfile,
-      slotDuration,
-      cells: props.cells,
-      eventMinHeight: options.timeGridEventMinHeight
-    })
-
     return (
       <div class='fc-time-grid' ref={props.rootElRef}>
         <TimeColsBg
@@ -115,7 +105,7 @@ export default class TimeCols extends BaseComponent<TimeColsProps, TimeColsState
           onCoords={this.handleSlatCoords}
         />
         <TimeColsContent
-          colCnt={props.cells.length}
+          cells={props.cells}
           renderIntro={props.renderIntro}
           businessHourSegs={props.businessHourSegs}
           bgEventSegs={props.bgEventSegs}
@@ -129,7 +119,7 @@ export default class TimeCols extends BaseComponent<TimeColsProps, TimeColsState
           clientWidth={props.clientWidth}
           tableMinWidth={props.tableMinWidth}
           tableColGroupNode={props.tableColGroupNode}
-          coords={this.slatCoords}
+          coords={state.slatCoords}
           forPrint={props.forPrint}
         />
       </div>
@@ -154,7 +144,7 @@ export default class TimeCols extends BaseComponent<TimeColsProps, TimeColsState
 
   handleScrollRequest = (request: ScrollRequest) => {
     let { onScrollTopRequest } = this.props
-    let { slatCoords } = this
+    let { slatCoords } = this.state
 
     if (onScrollTopRequest && slatCoords) {
 
@@ -176,22 +166,22 @@ export default class TimeCols extends BaseComponent<TimeColsProps, TimeColsState
   }
 
 
-  handleSlatCoords = (slatPositions: PositionCache | null) => {
-    this.setState({ slatPositions })
+  handleSlatCoords = (slatCoords: TimeColsSlatsCoords | null) => {
+    this.setState({ slatCoords })
   }
 
 
   positionToHit(positionLeft, positionTop) {
     let { dateEnv } = this.context
     let { snapsPerSlot, snapDuration, colCoords } = this
-    let { slatPositions } = this.state
+    let { slatCoords } = this.state
 
     let colIndex = colCoords.leftToIndex(positionLeft)
-    let slatIndex = slatPositions.topToIndex(positionTop)
+    let slatIndex = slatCoords.positions.topToIndex(positionTop)
 
     if (colIndex != null && slatIndex != null) {
-      let slatTop = slatPositions.tops[slatIndex]
-      let slatHeight = slatPositions.getHeight(slatIndex)
+      let slatTop = slatCoords.positions.tops[slatIndex]
+      let slatHeight = slatCoords.positions.getHeight(slatIndex)
       let partial = (positionTop - slatTop) / slatHeight // floating point number between 0 and 1
       let localSnapIndex = Math.floor(partial * snapsPerSlot) // the snap # relative to start of slat
       let snapIndex = slatIndex * snapsPerSlot + localSnapIndex
@@ -287,12 +277,3 @@ function processSlotOptions(options) {
 
   return { slotDuration, snapDuration, snapsPerSlot }
 }
-
-
-function buildSlatCoords(slatCoordProps: TimeColsSlatsCoordsProps) {
-  if (slatCoordProps.positions) {
-    return new TimeColsSlatsCoords(slatCoordProps)
-  } else {
-    return null
-  }
-}

+ 19 - 10
packages/timegrid/src/TimeColsContent.tsx

@@ -13,6 +13,7 @@ import TimeColsFills from './TimeColsFills'
 import { TimeColsSeg } from './TimeCols'
 import TimeColsSlatsCoords from './TimeColsSlatsCoords'
 import TimeColsNowIndicator from './TimeColsNowIndicator'
+import { DayBgCellModel } from '@fullcalendar/daygrid'
 
 
 export interface TimeColsContentProps extends TimeColsContentBaseProps {
@@ -37,7 +38,7 @@ export default class TimeColsContent extends BaseComponent<TimeColsContentProps>
         }}>
           {props.tableColGroupNode}
           <TimeColsContentBody
-            colCnt={props.colCnt}
+            cells={props.cells}
             businessHourSegs={props.businessHourSegs}
             bgEventSegs={props.bgEventSegs}
             fgEventSegs={props.fgEventSegs}
@@ -70,7 +71,7 @@ export interface TimeColsContentBodyProps extends TimeColsContentBaseProps {
 }
 
 export interface TimeColsContentBaseProps {
-  colCnt: number
+  cells: DayBgCellModel[]
   businessHourSegs: TimeColsSeg[]
   bgEventSegs: TimeColsSeg[]
   fgEventSegs: TimeColsSeg[]
@@ -104,8 +105,9 @@ export class TimeColsContentBody extends BaseComponent<TimeColsContentBodyProps>
 
   render(props: TimeColsContentBodyProps) {
     let cellNodes: VNode[] = props.renderIntro()
+    let cellCnt = props.cells.length
 
-    for (let i = 0; i < props.colCnt; i++) {
+    for (let i = 0; i < cellCnt; i++) {
       cellNodes.push(
         <td>
           <div class='fc-content-col' ref={this.colContainerRefs.createRef(i)}>
@@ -150,21 +152,24 @@ export class TimeColsContentBody extends BaseComponent<TimeColsContentBodyProps>
       type: 'businessHours',
       containerEls: this.businessContainerRefs.collect(),
       segs: props.businessHourSegs,
-      coords: props.coords
+      coords: props.coords,
+      cells: props.cells
     })
 
     this.renderDateSelection({
       type: 'highlight',
       containerEls: this.highlightContainerRefs.collect(),
       segs: options.selectMirror ? [] : props.dateSelectionSegs, // do highlight if NO mirror
-      coords: props.coords
+      coords: props.coords,
+      cells: props.cells
     })
 
     this.renderBgEvents({
       type: 'bgEvent',
       containerEls: this.bgContainerRefs.collect(),
       segs: props.bgEventSegs,
-      coords: props.coords
+      coords: props.coords,
+      cells: props.cells
     })
 
     this.renderFgEvents({
@@ -178,7 +183,8 @@ export class TimeColsContentBody extends BaseComponent<TimeColsContentBodyProps>
       isResizing: false,
       isSelecting: false,
       forPrint: props.forPrint,
-      coords: props.coords
+      coords: props.coords,
+      cells: props.cells
     })
 
     this.subrenderMirror(this.mirrorContainerRefs.collect(), options)
@@ -203,7 +209,8 @@ export class TimeColsContentBody extends BaseComponent<TimeColsContentBodyProps>
         isSelecting: false,
         interactingSeg: props.eventDrag.interactingSeg,
         forPrint: props.forPrint,
-        coords: props.coords
+        coords: props.coords,
+        cells: props.cells
       })
 
     } else if (props.eventResize && props.eventResize.segs.length) {
@@ -215,7 +222,8 @@ export class TimeColsContentBody extends BaseComponent<TimeColsContentBodyProps>
         isSelecting: false,
         interactingSeg: props.eventResize.interactingSeg,
         forPrint: props.forPrint,
-        coords: props.coords
+        coords: props.coords,
+        cells: props.cells
       })
 
     } else if (options.selectMirror) {
@@ -226,7 +234,8 @@ export class TimeColsContentBody extends BaseComponent<TimeColsContentBodyProps>
         isResizing: false,
         isSelecting: true,
         forPrint: props.forPrint,
-        coords: props.coords
+        coords: props.coords,
+        cells: props.cells
       })
 
     } else {

+ 11 - 5
packages/timegrid/src/TimeColsEvents.ts

@@ -6,6 +6,7 @@ import {
   Seg, isMultiDayRange, compareByFieldSpecs,
   computeEventDraggable, computeEventStartResizable, computeEventEndResizable, ComponentContext, BaseFgEventRendererProps, subrenderer, isArraysEqual
 } from '@fullcalendar/core'
+import { DayBgCellModel } from '@fullcalendar/daygrid'
 import { attachSegs, detachSegs } from './TimeCols'
 import TimeColsSlatsCoords from './TimeColsSlatsCoords'
 
@@ -13,6 +14,7 @@ export interface TimeColsEventsProps extends BaseFgEventRendererProps {
   containerEls: HTMLElement[]
   forPrint: boolean
   coords: TimeColsSlatsCoords
+  cells: DayBgCellModel[]
 }
 
 /*
@@ -64,20 +66,24 @@ export default class TimeColsEvents extends FgEventRenderer<TimeColsEventsProps>
 
 
   computeSegSizes(allSegs: Seg[], slatCoords: TimeColsSlatsCoords) {
-    let { segsByCol } = this
-    let colCnt = this.props.containerEls.length
+    let { segsByCol, props, context } = this
+    let colCnt = props.cells.length
 
-    slatCoords.computeSegVerticals(allSegs) // horizontals relies on this
+    slatCoords.computeSegVerticals(
+      allSegs,
+      props.cells,
+      context.options.timeGridEventMinHeight
+    )
 
     for (let col = 0; col < colCnt; col++) {
-      computeSegHorizontals(segsByCol[col], this.context) // compute horizontal coordinates, z-index's, and reorder the array
+      computeSegHorizontals(segsByCol[col], context) // compute horizontal coordinates, z-index's, and reorder the array
     }
   }
 
 
   assignSegSizes(allSegs: Seg[], slatCoords: TimeColsSlatsCoords) {
     let { segsByCol } = this
-    let colCnt = this.props.containerEls.length
+    let colCnt = this.props.cells.length
 
     slatCoords.assignSegVerticals(allSegs) // horizontals relies on this
 

+ 5 - 1
packages/timegrid/src/TimeColsFills.ts

@@ -1,12 +1,16 @@
 import { FillRenderer, subrenderer, BaseFillRendererProps, isArraysEqual } from '@fullcalendar/core'
+import { DayBgCellModel } from '@fullcalendar/daygrid'
 import { attachSegs, detachSegs } from './TimeCols'
 import TimeColsSlatsCoords from './TimeColsSlatsCoords'
 
+
 export interface TimeColsFillsProps extends BaseFillRendererProps {
   containerEls: HTMLElement[]
   coords: TimeColsSlatsCoords
+  cells: DayBgCellModel[]
 }
 
+
 export default class TimeColsFills extends FillRenderer<TimeColsFillsProps> {
 
   private attachSegs = subrenderer(attachSegs, detachSegs)
@@ -26,7 +30,7 @@ export default class TimeColsFills extends FillRenderer<TimeColsFillsProps> {
     })
 
     if (coords) {
-      coords.computeSegVerticals(segs)
+      coords.computeSegVerticals(segs, props.cells, 0)
       coords.assignSegVerticals(segs)
     }
   }

+ 11 - 6
packages/timegrid/src/TimeColsSlats.tsx

@@ -17,6 +17,7 @@ import {
   createRef,
   PositionCache
 } from '@fullcalendar/core'
+import TimeColsSlatsCoords from './TimeColsSlatsCoords'
 
 
 export interface TimeColsSlatsProps extends TimeColsSlatsContentProps {
@@ -24,7 +25,7 @@ export interface TimeColsSlatsProps extends TimeColsSlatsContentProps {
   minHeight: CssDimValue
   tableMinWidth: CssDimValue
   tableColGroupNode: VNode
-  onCoords?: (coords: PositionCache | null) => void
+  onCoords?: (coords: TimeColsSlatsCoords | null) => void
 }
 
 interface TimeColsSlatsContentProps {
@@ -101,11 +102,15 @@ export default class TimeColsSlats extends BaseComponent<TimeColsSlatsProps> {
 
     if (props.onCoords && props.clientWidth) { // clientWidth means sizing has stabilized
       props.onCoords(
-        new PositionCache(
-          this.rootElRef.current,
-          this.slatElRefs.collect(),
-          false,
-          true // vertical
+        new TimeColsSlatsCoords(
+          new PositionCache(
+            this.rootElRef.current,
+            this.slatElRefs.collect(),
+            false,
+            true // vertical
+          ),
+          props.dateProfile,
+          props.slotDuration
         )
       )
     }

+ 8 - 14
packages/timegrid/src/TimeColsSlatsCoords.ts

@@ -2,24 +2,19 @@ import { PositionCache, DateMarker, startOfDay, createDuration, asRoughMs, DateP
 import { DayBgCellModel } from '@fullcalendar/daygrid'
 
 
-export interface TimeColsSlatsCoordsProps {
-  positions: PositionCache
-  dateProfile: DateProfile
-  slotDuration: Duration
-  cells: DayBgCellModel[]
-  eventMinHeight: number
-}
-
-
 export default class TimeColsSlatsCoords {
 
 
-  constructor(private props: TimeColsSlatsCoordsProps) {
+  constructor(
+    public positions: PositionCache,
+    private dateProfile: DateProfile,
+    private slotDuration: Duration
+  ) {
   }
 
 
   safeComputeTop(date: DateMarker | null) {
-    if (date && rangeContainsMarker(this.props.dateProfile.currentRange, date)) {
+    if (date && rangeContainsMarker(this.dateProfile.currentRange, date)) {
       return this.computeDateTop(date)
     }
   }
@@ -37,7 +32,7 @@ export default class TimeColsSlatsCoords {
 
   // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).
   computeTimeTop(duration: Duration) {
-    let { positions, dateProfile, slotDuration } = this.props
+    let { positions, dateProfile, slotDuration } = this
     let len = positions.els.length
     let slatCoverage = (duration.milliseconds - asRoughMs(dateProfile.minTime)) / asRoughMs(slotDuration) // floating-point value of # of slots covered
     let slatIndex
@@ -64,8 +59,7 @@ export default class TimeColsSlatsCoords {
 
 
   // For each segment in an array, computes and assigns its top and bottom properties
-  computeSegVerticals(segs: Seg[]) {
-    let { eventMinHeight, cells } = this.props
+  computeSegVerticals(segs: Seg[], cells: DayBgCellModel[], eventMinHeight: number) {
     let i
     let seg
     let dayDate