import { __assign } from 'tslib' ; import { ViewContextType , buildViewContext } from './ViewContext' ; import { ViewSpec } from './structs/view-spec' ; import { ViewProps } from './View' ; import { Toolbar } from './Toolbar' ; import { DateProfileGenerator , DateProfile } from './DateProfileGenerator' ; import { rangeContainsMarker } from './datelib/date-range' ; import { memoize } from './util/memoize' ; import { DateMarker } from './datelib/marker' ; import { CalendarData } from './reducers/data-types' ; import { ViewPropsTransformerClass } from './plugin-system-struct' ; import { createElement , createRef , Fragment , VNode } from './vdom' ; import { ViewContainer } from './ViewContainer' ; import { Interaction , InteractionSettingsInput , InteractionClass , parseInteractionSettings , interactionSettingsStore , } from './interactions/interaction' ; import { DateComponent } from './component/DateComponent' ; import { EventClicking } from './interactions/EventClicking' ; import { EventHovering } from './interactions/EventHovering' ; import { getNow } from './reducers/current-date' ; import { CalendarInteraction } from './calendar-utils' ; import { DelayedRunner } from './util/DelayedRunner' ; import { PureComponent } from './vdom-util' ; import { getUniqueDomId } from './util/dom-manip' ; export interface CalendarContentProps extends CalendarData { forPrint : boolean ; isHeightAuto : boolean ; } export class CalendarContent extends PureComponent < CalendarContentProps > { private buildViewContext = memoize ( buildViewContext ) ; private buildViewPropTransformers = memoize ( buildViewPropTransformers ) ; private buildToolbarProps = memoize ( buildToolbarProps ) ; private headerRef = createRef < Toolbar > ( ) ; private footerRef = createRef < Toolbar > ( ) ; private interactionsStore : { [ componentUid ] : Interaction [ ] ; } = { } ; private calendarInteractions : CalendarInteraction [ ] ; state = { viewLabelId : getUniqueDomId ( ) , } ; render ( ) { let { props } = this ; let { toolbarConfig , options } = props ; let toolbarProps = this . buildToolbarProps ( props . viewSpec , props . dateProfile , props . dateProfileGenerator , props . currentDate , getNow ( props . options . now , props . dateEnv ) , props . viewTitle ) ; let viewVGrow = false ; let viewHeight = '' ; let viewAspectRatio ; if ( props . isHeightAuto || props . forPrint ) { viewHeight = '' ; } else if ( options . height != null ) { viewVGrow = true ; } else if ( options . contentHeight != null ) { viewHeight = options . contentHeight ; } else { viewAspectRatio = Math . max ( options . aspectRatio , 0.5 ) ; } let viewContext = this . buildViewContext ( props . viewSpec , props . viewApi , props . options , props . dateProfileGenerator , props . dateEnv , props . theme , props . pluginHooks , props . dispatch , props . getCurrentData , props . emitter , props . calendarApi , this . registerInteractiveComponent , this . unregisterInteractiveComponent ) ; let viewLabelId = ( toolbarConfig . header && toolbarConfig . header . hasTitle ) ? this . state . viewLabelId : '' ; return ( < ViewContextType . Provider value = { viewContext } > { toolbarConfig . header && ( < Toolbar ref = { this . headerRef } extraClassName = "fc-header-toolbar" model = { toolbarConfig . header } titleId = { viewLabelId } { ... toolbarProps } />)} < ViewContainer liquid = { viewVGrow } height = { viewHeight } aspectRatio = { viewAspectRatio } labeledById = { viewLabelId } > { this . renderView ( props ) } { this . buildAppendContent ( ) } < /ViewContainer> { toolbarConfig . footer && ( < Toolbar ref = { this . footerRef } extraClassName = "fc-footer-toolbar" model = { toolbarConfig . footer } titleId = "" { ... toolbarProps } />)} < /ViewContextType.Provider>); } componentDidMount ( ) { let { props } = this ; this . calendarInteractions = props . pluginHooks . calendarInteractions . map ( ( CalendarInteractionClass ) => new CalendarInteractionClass ( props ) ) ; window . addEventListener ( 'resize' , this . handleWindowResize ) ; let { propSetHandlers } = props . pluginHooks ; for ( let propName in propSetHandlers ) { propSetHandlers [ propName ] ( props [ propName ] , props ) ; } } componentDidUpdate ( prevProps ) { let { props } = this ; let { propSetHandlers } = props . pluginHooks ; for ( let propName in propSetHandlers ) { if ( props [ propName ] !== prevProps [ propName ] ) { propSetHandlers [ propName ] ( props [ propName ] , props ) ; } } } componentWillUnmount ( ) { window . removeEventListener ( 'resize' , this . handleWindowResize ) ; this . resizeRunner . clear ( ) ; for ( let interaction of this . calendarInteractions ) { interaction . destroy ( ) ; } this . props . emitter . trigger ( '_unmount' ) ; } buildAppendContent ( ) { let { props } = this ; let children = props . pluginHooks . viewContainerAppends . map ( ( buildAppendContent ) => buildAppendContent ( props ) ) ; return createElement ( Fragment , { } , ... children ) ; } renderView ( props ) { let { pluginHooks } = props ; let { viewSpec } = props ; let viewProps = { dateProfile : props . dateProfile , businessHours : props . businessHours , eventStore : props . renderableEventStore , eventUiBases : props . eventUiBases , dateSelection : props . dateSelection , eventSelection : props . eventSelection , eventDrag : props . eventDrag , eventResize : props . eventResize , isHeightAuto : props . isHeightAuto , forPrint : props . forPrint , } ; let transformers = this . buildViewPropTransformers ( pluginHooks . viewPropsTransformers ) ; for ( let transformer of transformers ) { __assign ( viewProps , transformer . transform ( viewProps , props ) ) ; } let ViewComponent = viewSpec . component ; return ( < ViewComponent { ... viewProps } / > ) ; } registerInteractiveComponent = ( component , settingsInput ) => { let settings = parseInteractionSettings ( component , settingsInput ) ; let DEFAULT_INTERACTIONS = [ EventClicking , EventHovering , ] ; let interactionClasses = DEFAULT_INTERACTIONS . concat ( this . props . pluginHooks . componentInteractions ) ; let interactions = interactionClasses . map ( ( TheInteractionClass ) => new TheInteractionClass ( settings ) ) ; this . interactionsStore [ component . uid ] = interactions ; interactionSettingsStore [ component . uid ] = settings ; } ; unregisterInteractiveComponent = ( component ) => { for ( let listener of this . interactionsStore [ component . uid ] ) { listener . destroy ( ) ; } delete this . interactionsStore [ component . uid ] ; delete interactionSettingsStore [ component . uid ] ; } ; resizeRunner = new DelayedRunner ( ( ) => { this . props . emitter . trigger ( '_resize' , true ) ; this . props . emitter . trigger ( 'windowResize' , { view : this . props . viewApi } ) ; } ) ; handleWindowResize = ( ev ) => { let { options } = this . props ; if ( options . handleWindowResize && ev . target === window ) { this . resizeRunner . request ( options . windowResizeDelay ) ; } } ; } function buildToolbarProps ( viewSpec , dateProfile , dateProfileGenerator , currentDate , now , title ) { let todayInfo = dateProfileGenerator . build ( now , undefined , false ) ; let prevInfo = dateProfileGenerator . buildPrev ( dateProfile , currentDate , false ) ; let nextInfo = dateProfileGenerator . buildNext ( dateProfile , currentDate , false ) ; return { title , activeButton : viewSpec . type , navUnit : viewSpec . singleUnit , isTodayEnabled : todayInfo . isValid && ! rangeContainsMarker ( dateProfile . currentRange , now ) , isPrevEnabled : prevInfo . isValid , isNextEnabled : nextInfo . isValid , } ; } function buildViewPropTransformers ( theClasses ) { return theClasses . map ( ( TheClass ) => new TheClass ( ) ) ; }