Adam Shaw 5 лет назад
Родитель
Сommit
6e0ae78d1b

+ 1 - 1
packages-premium

@@ -1 +1 @@
-Subproject commit 38a9e2d2d963ade13fd973065d615b573c40c957
+Subproject commit edb2c0dcc081ee4cb8d421ef71a555ea91f45260

+ 2 - 2
packages/core/src/CalendarComponent.tsx

@@ -9,7 +9,7 @@ import { DateMarker } from './datelib/marker'
 import { CalendarState } from './reducers/CalendarState'
 import { ViewPropsTransformerClass } from './plugin-system-struct'
 import { __assign } from 'tslib'
-import { h, createRef, Component } from './vdom'
+import { h, createRef, Component, VDomUIEvent } from './vdom'
 import { buildDelegationHandler } from './util/dom-event'
 import { capitaliseFirstLetter } from './util/misc'
 import { ViewContainer } from './ViewContainer'
@@ -201,7 +201,7 @@ export class CalendarComponent extends Component<CalendarComponentProps, Calenda
   }
 
 
-  _handleNavLinkClick(ev: UIEvent, anchorEl: HTMLElement) {
+  _handleNavLinkClick(ev: VDomUIEvent, anchorEl: HTMLElement) {
     let { dateEnv, options, calendarApi } = this.props
 
     let navLinkOptions: any = anchorEl.getAttribute('data-navlink')

+ 2 - 1
packages/core/src/NowTimer.ts

@@ -37,7 +37,8 @@ export class NowTimer extends Component<NowTimerProps, NowTimerState> {
   }
 
 
-  render(props: NowTimerProps, state: NowTimerState) {
+  render() {
+    let { props, state } = this
     return props.content(state.nowDate, state.todayRange)
   }
 

+ 2 - 2
packages/core/src/ViewContainer.tsx

@@ -1,5 +1,5 @@
 import { BaseComponent } from './vdom-util'
-import { ComponentChildren, Ref, h } from './vdom'
+import { ComponentChildren, Ref, h, VDomUIEvent } from './vdom'
 import { CssDimValue } from './scrollgrid/util'
 
 
@@ -7,7 +7,7 @@ export interface ViewContainerProps {
   liquid?: boolean
   height?: CssDimValue
   aspectRatio?: number
-  onClick?: (ev: Event) => void
+  onClick?: (ev: VDomUIEvent) => void
   elRef?: Ref<HTMLDivElement>
   children?: ComponentChildren
 }

+ 2 - 1
packages/core/src/scrollgrid/ScrollGridImpl.ts

@@ -1,5 +1,5 @@
 import { SectionConfig, ChunkConfig, ColProps, CssDimValue } from './util'
-import { Component } from '../vdom'
+import { Component, Ref } from '../vdom'
 import { ComponentContext } from '../component/ComponentContext'
 
 
@@ -8,6 +8,7 @@ export interface ScrollGridProps {
   sections: ScrollGridSectionConfig[]
   liquid?: boolean
   forPrint?: boolean
+  elRef?: Ref<any>
 }
 
 export interface ScrollGridSectionConfig extends SectionConfig {

+ 4 - 2
packages/core/src/structs/view-config.tsx

@@ -1,7 +1,7 @@
 import { ViewProps } from '../View'
 import { refineProps } from '../util/misc'
 import { mapHash } from '../util/object'
-import { ComponentType, Component, h } from '../vdom'
+import { ComponentType, Component, h, Ref } from '../vdom'
 import { ViewRoot } from '../common/ViewRoot'
 import { RenderHook } from '../common/render-hook'
 import { ComponentContext, ComponentContextType } from '../component/ComponentContext'
@@ -14,7 +14,9 @@ B) options to customize an existing view, in which case only provides options.
 
 export type ViewComponent = Component<ViewProps> // an instance
 
-export type ViewComponentType = ComponentType<ViewProps> // a class or a function
+export type ViewComponentType = ComponentType< // a class or a function
+  ViewProps & { ref?: Ref<any> } // shouldn't need to add ref, but @types/react needs it
+>
 
 export interface ViewConfigObjectInput { // not strict enough. will basically allow for anything :(
   type?: string

+ 4 - 4
packages/core/src/util/dom-event.ts

@@ -1,4 +1,5 @@
 import { elementClosest } from './dom-manip'
+import { VDomUIEvent } from '../vdom'
 
 
 // Stops a mouse/touch event from doing it's native browser action
@@ -10,12 +11,11 @@ export function preventDefault(ev) {
 // Event Delegation
 // ----------------------------------------------------------------------------------------------------------------
 
-
-export function buildDelegationHandler(
+export function buildDelegationHandler<EventType extends (Event | VDomUIEvent)>(
   selector: string,
-  handler: (ev: Event, matchedTarget: HTMLElement) => void
+  handler: (ev: EventType, matchedTarget: HTMLElement) => void
 ) {
-  return function(ev: Event) {
+  return function(ev: EventType) {
     let matchedChild = elementClosest(ev.target as HTMLElement, selector)
 
     if (matchedChild) {

+ 7 - 0
packages/core/src/vdom-preact.ts

@@ -3,6 +3,13 @@ export { Component, render, createRef, VNode, Fragment, ComponentChildren, creat
 import { Component, h, options, render } from 'preact'
 
 
+export type VDomUIEvent = UIEvent
+
+export function getNativeEvent(vdomEvent: VDomUIEvent) {
+  return vdomEvent as UIEvent
+}
+
+
 export function flushToDom() {
   let oldDebounceRendering = options.debounceRendering
   let callbackQ = []

+ 8 - 2
packages/core/src/vdom-react.ts

@@ -1,8 +1,14 @@
 
-export { Component, Fragment, createRef, ReactNode, createContext, Ref, RefObject, ComponentType, createElement as h } from 'react'
+export { Component, Fragment, createRef, createContext, Ref, RefObject, ComponentType, createElement as h } from 'react'
 export { render } from 'react-dom'
 
-import { ReactNode } from 'react'
+import { ReactNode, UIEvent as VDomUIEvent } from 'react'
+export { ReactNode, VDomUIEvent }
+
+export function getNativeEvent(vdomEvent: VDomUIEvent) {
+  return vdomEvent.nativeEvent
+}
+
 export type VNode = ReactNode
 export type ComponentChild =
   | VNode

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

@@ -57,7 +57,7 @@ export class MorePopover extends DateComponent<MorePopoverProps> {
                   className='fc-daygrid-event-harness'
                   key={instanceId}
                   style={{
-                    visibility: hiddenInstances[instanceId] ? 'hidden' : ''
+                    visibility: hiddenInstances[instanceId] ? 'hidden' : ('' as any)
                   }}
                 >
                   {hasListItemDisplay(eventRange) ?

+ 1 - 2
packages/daygrid/src/Popover.tsx

@@ -75,10 +75,9 @@ export class Popover extends BaseComponent<PopoverProps> {
   // Triggered when the user clicks *anywhere* in the document, for the autoHide feature
   handleDocumentMousedown = (ev) => {
     let { onClose } = this.props
-    let rootEl = this.base // bad
 
     // only hide the popover if the click happened outside the popover
-    if (onClose && !rootEl.contains(ev.target)) {
+    if (onClose && !this.rootEl.contains(ev.target)) {
       onClose()
     }
   }

+ 17 - 5
packages/daygrid/src/TableCell.tsx

@@ -17,6 +17,9 @@ import {
   addDays,
   intersectRanges,
   DateProfile,
+  VDomUIEvent,
+  getNativeEvent,
+  setRef,
 } from '@fullcalendar/core'
 import { TableSeg } from './TableSeg'
 
@@ -74,6 +77,8 @@ const DEFAULT_WEEK_NUM_FORMAT = { week: 'narrow' }
 
 export class TableCell extends DateComponent<TableCellProps> {
 
+  private rootEl: HTMLElement
+
 
   render() {
     let { options, viewApi } = this.context
@@ -87,7 +92,7 @@ export class TableCell extends DateComponent<TableCellProps> {
         todayRange={props.todayRange}
         showDayNumber={props.showDayNumber}
         extraHookProps={props.extraHookProps}
-        elRef={props.elRef}
+        elRef={this.handleRootEl}
       >
         {(rootElRef, classNames, rootDataAttrs, isDisabled) => (
           <td
@@ -132,7 +137,7 @@ export class TableCell extends DateComponent<TableCellProps> {
                       defaultContent={renderMoreLinkInner}
                     >
                       {(rootElRef, classNames, innerElRef, innerContent) => (
-                        <a onClick={this.handleMoreLink} ref={rootElRef} className={[ 'fc-daygrid-more-link' ].concat(classNames).join(' ')}>
+                        <a onClick={this.handleMoreLinkClick} ref={rootElRef} className={[ 'fc-daygrid-more-link' ].concat(classNames).join(' ')}>
                           {innerContent}
                         </a>
                       )}
@@ -151,7 +156,14 @@ export class TableCell extends DateComponent<TableCellProps> {
   }
 
 
-  handleMoreLink = (ev: UIEvent) => {
+  handleRootEl = (el: HTMLElement) => {
+    this.rootEl = el
+
+    setRef(this.props.elRef, el)
+  }
+
+
+  handleMoreLinkClick = (ev: VDomUIEvent) => {
     let { props } = this
 
     if (props.onMoreClick) {
@@ -165,8 +177,8 @@ export class TableCell extends DateComponent<TableCellProps> {
         allSegs,
         hiddenSegs,
         moreCnt: props.moreCnt,
-        dayEl: this.base as HTMLElement, // TODO: bad pattern
-        ev
+        dayEl: this.rootEl,
+        ev: getNativeEvent(ev)
       })
     }
   }

+ 8 - 6
packages/daygrid/src/TableRow.tsx

@@ -13,7 +13,8 @@ import {
   Fragment,
   BgEvent,
   renderFill,
-  isPropsEqual
+  isPropsEqual,
+  createRef
 } from '@fullcalendar/core'
 import { TableSeg, splitSegsByFirstCol } from './TableSeg'
 import { TableCell, TableCellModel, MoreLinkArg } from './TableCell'
@@ -61,6 +62,7 @@ export class TableRow extends DateComponent<TableRowProps, TableRowState> {
   private cellInnerElRefs = new RefMap<HTMLElement>() // the fc-daygrid-day-frame
   private cellContentElRefs = new RefMap<HTMLDivElement>() // the fc-daygrid-day-events
   private segHarnessRefs = new RefMap<HTMLDivElement>()
+  private rootElRef = createRef<HTMLTableRowElement>()
 
   state: TableRowState = {
     cellInnerPositions: null,
@@ -95,7 +97,7 @@ export class TableRow extends DateComponent<TableRowProps, TableRowState> {
       {}
 
     return (
-      <tr>
+      <tr ref={this.rootElRef}>
         {props.renderIntro && props.renderIntro()}
         {props.cells.map((cell, col) => {
           let normalFgNodes = this.renderFgSegs(
@@ -211,7 +213,7 @@ export class TableRow extends DateComponent<TableRowProps, TableRowState> {
     isDragging?: boolean,
     isResizing?: boolean,
     isDateSelecting?: boolean
-  ) {
+  ): VNode[] {
     let { context } = this
     let { eventSelection } = this.props
     let { cellInnerPositions, cellContentPositions } = this.state
@@ -255,7 +257,7 @@ export class TableRow extends DateComponent<TableRowProps, TableRowState> {
             key={instanceId}
             ref={isMirror ? null : this.segHarnessRefs.createRef(instanceId)}
             style={{
-              visibility: isInvisible ? 'hidden' : '',
+              visibility: isInvisible ? 'hidden' : ('' as any),
               marginTop: marginTop || '',
               top: top || '',
               left: left || '',
@@ -289,7 +291,7 @@ export class TableRow extends DateComponent<TableRowProps, TableRowState> {
   }
 
 
-  renderFillSegs(segs: TableSeg[], fillType: string) {
+  renderFillSegs(segs: TableSeg[], fillType: string): VNode[] {
     let { isRtl } = this.context
     let { todayRange } = this.props
     let { cellInnerPositions } = this.state
@@ -340,7 +342,7 @@ export class TableRow extends DateComponent<TableRowProps, TableRowState> {
         let cellContentEls = props.cells.map((cell) => cellContentElRefs.currentMap[cell.key])
 
         if (cellContentEls.length) {
-          let originEl = this.base as HTMLElement // BAD
+          let originEl = this.rootElRef.current
 
           this.setState({ // will trigger isCellPositionsChanged...
             cellInnerPositions: new PositionCache(

+ 1 - 1
packages/timegrid/src/TimeCol.tsx

@@ -122,7 +122,7 @@ export class TimeCol extends BaseComponent<TimeColProps> {
           className={'fc-timegrid-event-harness' + (seg.level > 0 ? ' fc-timegrid-event-harness-inset' : '')}
           key={instanceId}
           style={{
-            visibility: segIsInvisible[instanceId] ? 'hidden' : '',
+            visibility: segIsInvisible[instanceId] ? 'hidden' : ('' as any),
             ...positionCss
           }}
         >