فهرست منبع

scrolling alright

Adam Shaw 6 سال پیش
والد
کامیت
52847138c3

+ 1 - 1
packages-premium

@@ -1 +1 @@
-Subproject commit 2d7d571d65e1384fb10a55dd81588dee682b3af9
+Subproject commit 304d26afc37c1c6a5aa0380a79272735e039a7b4

+ 19 - 1
packages/core/src/Calendar.tsx

@@ -106,6 +106,7 @@ export default class Calendar {
   renderRunner: DelayedRunner
   actionRunner: TaskRunner<Action> // for reducer. bad name
   afterSizingTriggers: any = {}
+  afterSizingCallbacks = []
   isViewUpdated: boolean = false
   isDatesUpdated: boolean = false
   isEventsUpdated: boolean = false
@@ -347,6 +348,7 @@ export default class Calendar {
     let viewComponent = calendarComponent.view
 
     calendarComponent.updateSize(false)
+    this.drainAfterSizingCallbacks()
     this.releaseAfterSizingTriggers()
 
     if (this.isViewUpdated) {
@@ -557,6 +559,20 @@ export default class Calendar {
   }
 
 
+  afterSizing(callback) {
+    this.afterSizingCallbacks.push(callback)
+  }
+
+
+  drainAfterSizingCallbacks() {
+    let { afterSizingCallbacks } = this
+
+    while (afterSizingCallbacks.length) {
+      (afterSizingCallbacks.shift())()
+    }
+  }
+
+
   publiclyTriggerAfterSizing<T extends EventHandlerName>(name: T, args: EventHandlerArgs<T>) {
     let { afterSizingTriggers } = this;
 
@@ -1145,8 +1161,10 @@ export default class Calendar {
     let duration = createDuration(timeInput)
 
     if (duration) {
-      this.component.view.scrollToDuration(duration)
+      this.component.view.scrollToTime(duration)
     }
+
+    this.drainAfterSizingCallbacks() // hack
   }
 
 }

+ 9 - 53
packages/core/src/View.ts

@@ -52,21 +52,6 @@ export default abstract class View<State={}> extends DateComponent<ViewProps, St
   // -----------------------------------------------------------------------------------------------------------------
 
 
-  componentDidMount() {
-    this.applyScroll({ duration: createDuration(this.context.options.scrollTime) }, false)
-  }
-
-
-  getSnapshotBeforeUpdate() {
-    return this.queryScroll()
-  }
-
-
-  componentDidUpdate(prevProps, prevState, snapshot) { // how do we know children element will be done?
-    this.applyScroll(snapshot, false)
-  }
-
-
   updateSize(isResize: boolean, viewHeight: number, isAuto: boolean) {
   }
 
@@ -202,55 +187,26 @@ export default abstract class View<State={}> extends DateComponent<ViewProps, St
 
   // Scroller
   // -----------------------------------------------------------------------------------------------------------------
-  // QUESTION: do we need to have date-scroll separate?
-
 
-  queryScroll() {
-    let scroll = {} as any
 
-    if (this.props.dateProfile) { // dates rendered yet?
-      __assign(scroll, this.queryDateScroll())
-    }
+  scrollToInitialTime() {
+    let duration = createDuration(this.context.options.scrollTime)
 
-    return scroll
+    this.scrollToTime(duration)
   }
 
 
-  applyScroll(scroll, isResize: boolean) {
-    let { duration, isForced } = scroll
-
-    if (duration != null && !isForced) {
-      delete scroll.duration
-
-      if (this.props.dateProfile) { // dates rendered yet?
-        __assign(scroll, this.computeDateScroll(duration))
-      }
-    }
-
-    if (this.props.dateProfile) { // dates rendered yet?
-      this.applyDateScroll(scroll)
-    }
-  }
-
-
-  computeDateScroll(duration: Duration) {
-    return {} // subclasses must implement
-  }
-
-
-  queryDateScroll() {
-    return {} // subclasses must implement
+  scrollToTime(duration: Duration) {
+    // subclasses can implement
   }
 
 
-  applyDateScroll(scroll) {
-     // subclasses must implement
-  }
+  // HACKs
+  // -----------------------------------------------------------------------------------------------------------------
 
 
-  // for API
-  scrollToDuration(duration: Duration) {
-    this.applyScroll({ duration }, false)
+  afterSizing(callback) {
+    this.context.calendar.afterSizing(callback)
   }
 
 }

+ 4 - 4
packages/daygrid/src/DayTableView.tsx

@@ -23,6 +23,7 @@ export default class DayTableView extends TableView {
   render(props: ViewProps, state: {}, context: ComponentContext) {
     let { dateProfile } = props
     let dayTableModel = this.buildDayTableModel(dateProfile, props.dateProfileGenerator)
+    let { colWeekNumbersVisible, cellWeekNumbersVisible } = this.processOptions(context.options)
 
     return this.renderLayout(
       <DayHeader
@@ -48,8 +49,8 @@ export default class DayTableView extends TableView {
         renderNumberIntro={this.renderNumberIntro}
         renderBgIntro={this.renderBgIntro}
         renderIntro={this.renderIntro}
-        colWeekNumbersVisible={this.colWeekNumbersVisible}
-        cellWeekNumbersVisible={this.cellWeekNumbersVisible}
+        colWeekNumbersVisible={colWeekNumbersVisible}
+        cellWeekNumbersVisible={cellWeekNumbersVisible}
       />
     )
   }
@@ -64,8 +65,7 @@ export default class DayTableView extends TableView {
         header ? header.rootEl : null,
         table.table,
         viewHeight,
-        isAuto,
-        this.context.options
+        isAuto
       )
     }
 

+ 1 - 1
packages/daygrid/src/TableSkeleton.tsx

@@ -39,7 +39,7 @@ const WEEK_NUM_FORMAT = createFormatter({ week: 'numeric' })
 export default class TableSkeleton extends BaseComponent<TableSkeletonProps> {
 
 
-  render(props: TableSkeletonProps) {
+  render() {
     let rowCnt = this.props.cells.length
     let rowNodes: VNode[] = []
 

+ 19 - 38
packages/daygrid/src/TableView.tsx

@@ -29,14 +29,11 @@ const WEEK_NUM_FORMAT = createFormatter({ week: 'numeric' })
 
 export default abstract class TableView extends View {
 
-  private processOptions = memoize(this._processOptions)
+  protected processOptions = memoize(this._processOptions)
   private rootElRef = createRef<HTMLDivElement>()
   private scrollerRef = createRef<Scroller>()
-
-  // computed options
-  protected colWeekNumbersVisible: boolean
-  protected cellWeekNumbersVisible: boolean
-  protected weekNumberWidth: number
+  private colWeekNumbersVisible: boolean // computed option
+  private weekNumberWidth: number
 
   getRootEl() { return this.rootElRef.current }
 
@@ -75,18 +72,25 @@ export default abstract class TableView extends View {
 
 
   private _processOptions(options) {
+    let cellWeekNumbersVisible: boolean
+    let colWeekNumbersVisible: boolean
+
     if (options.weekNumbers) {
       if (options.weekNumbersWithinDays) {
-        this.cellWeekNumbersVisible = true
-        this.colWeekNumbersVisible = false
+        cellWeekNumbersVisible = true
+        colWeekNumbersVisible = false
       } else {
-        this.cellWeekNumbersVisible = false
-        this.colWeekNumbersVisible = true
+        cellWeekNumbersVisible = false
+        colWeekNumbersVisible = true
       }
     } else {
-      this.colWeekNumbersVisible = false
-      this.cellWeekNumbersVisible = false
+      colWeekNumbersVisible = false
+      cellWeekNumbersVisible = false
     }
+
+    this.colWeekNumbersVisible = colWeekNumbersVisible
+
+    return { cellWeekNumbersVisible, colWeekNumbersVisible }
   }
 
 
@@ -104,9 +108,11 @@ export default abstract class TableView extends View {
 
 
   // Refreshes the horizontal dimensions of the view
-  updateLayoutHeight(headRowEl: HTMLElement | null, table: Table, viewHeight: number, isAuto: boolean, options) {
+  // TODO: dont pass in optinos
+  updateLayoutHeight(headRowEl: HTMLElement | null, table: Table, viewHeight: number, isAuto: boolean) {
     let rootEl = this.rootElRef.current
     let scroller = this.scrollerRef.current
+    let { options } = this.context
     let eventLimit = options.eventLimit
     let scrollerHeight
     let scrollbarWidths
@@ -204,31 +210,6 @@ export default abstract class TableView extends View {
   }
 
 
-  /* Scroll
-  ------------------------------------------------------------------------------------------------------------------*/
-
-
-  computeDateScroll(duration: Duration) {
-    return { top: 0 }
-  }
-
-
-  queryDateScroll() {
-    let scroller = this.scrollerRef.current
-
-    return { top: scroller.controller.getScrollTop() }
-  }
-
-
-  applyDateScroll(scroll) {
-    let scroller = this.scrollerRef.current
-
-    if (scroll.top !== undefined) {
-      scroller.controller.setScrollTop(scroll.top)
-    }
-  }
-
-
   /* Header Rendering
   ------------------------------------------------------------------------------------------------------------------*/
 

+ 39 - 17
packages/timegrid/src/TimeColsView.tsx

@@ -8,6 +8,7 @@ import {
   DateMarker,
   getViewClassNames,
   GotoAnchor,
+  ViewProps
 } from '@fullcalendar/core'
 import { Table } from '@fullcalendar/daygrid'
 import { TimeCols } from './main'
@@ -104,6 +105,25 @@ export default abstract class TimeColsView extends View {
     }
 
     this.startNowIndicator()
+    this.scrollToInitialTime()
+  }
+
+
+  getSnapshotBeforeUpdate() {
+    let scroller = this.scrollerRef.current
+
+    return { scrollTop: scroller.controller.getScrollTop() }
+  }
+
+
+  componentDidUpdate(prevProps: ViewProps, prevState: {}, snapshot) {
+
+    if (prevProps.dateProfile !== this.props.dateProfile) {
+      this.scrollToInitialTime()
+
+    } else {
+      this.scrollTop(snapshot.scrollTop)
+    }
   }
 
 
@@ -225,6 +245,24 @@ export default abstract class TimeColsView extends View {
   ------------------------------------------------------------------------------------------------------------------*/
 
 
+  scrollToTime(duration: Duration) {
+    this.afterSizing(() => { // hack
+      let top = this.computeDateScroll(duration)
+
+      this.scrollTop(top)
+    })
+  }
+
+
+  scrollTop(top: number) {
+    this.afterSizing(() => { // hack
+      let scroller = this.scrollerRef.current
+
+      scroller.controller.setScrollTop(top)
+    })
+  }
+
+
   // Computes the initial pre-configured scroll state prior to allowing the user to change it
   computeDateScroll(duration: Duration) {
     let top = this.getTimeColsObj().timeCols.computeTimeTop(duration)
@@ -236,23 +274,7 @@ export default abstract class TimeColsView extends View {
       top++ // to overcome top border that slots beyond the first have. looks better
     }
 
-    return { top }
-  }
-
-
-  queryDateScroll() {
-    let scroller = this.scrollerRef.current
-
-    return { top: scroller.controller.getScrollTop() }
-  }
-
-
-  applyDateScroll(scroll) {
-    let scroller = this.scrollerRef.current
-
-    if (scroll.top !== undefined) {
-      scroller.controller.setScrollTop(scroll.top)
-    }
+    return top
   }