Forráskód Böngészése

fix emitter stuff

Adam Shaw 5 éve
szülő
commit
00208c544c

+ 1 - 1
packages/common/src/CalendarContent.tsx

@@ -282,7 +282,7 @@ export class CalendarContent extends Component<CalendarContentProps, CalendarCon
 
   resizeRunner = new DelayedRunner(() => {
     this.props.emitter.trigger('_resize', true) // should window resizes be considered "forced" ?
-    this.props.emitter.trigger('windowResize')
+    this.props.emitter.trigger('windowResize', { view: this.props.viewApi })
   })
 
 

+ 2 - 2
packages/common/src/CalendarContext.ts

@@ -1,5 +1,5 @@
 import { DateEnv } from './datelib/env'
-import { RefinedBaseOptions } from './options'
+import { RefinedBaseOptions, CalendarListeners } from './options'
 import { PluginHooks } from './plugin-system-struct'
 import { Emitter } from './common/Emitter'
 import { Action } from './reducers/Action'
@@ -10,7 +10,7 @@ export interface CalendarContext {
   dateEnv: DateEnv
   options: RefinedBaseOptions // does not have calendar-specific properties. aims to be compatible with RefinedViewOptions
   pluginHooks: PluginHooks
-  emitter: Emitter
+  emitter: Emitter<CalendarListeners>
   dispatch(action: Action): void
   getCurrentData(): CalendarData
   calendarApi: CalendarApi

+ 2 - 1
packages/common/src/ScrollResponder.ts

@@ -1,6 +1,7 @@
 import { Duration } from './datelib/duration'
 import { __assign } from 'tslib'
 import { Emitter } from './common/Emitter'
+import { CalendarListeners } from './options'
 
 
 export interface ScrollRequest {
@@ -18,7 +19,7 @@ export class ScrollResponder {
 
   constructor(
     private execFunc: ScrollRequestHandler,
-    private emitter: Emitter,
+    private emitter: Emitter<CalendarListeners>,
     private scrollTime: Duration
   ) {
     emitter.on('_scrollRequest', this.handleScrollRequest)

+ 2 - 2
packages/common/src/ViewContext.ts

@@ -14,7 +14,7 @@ import { InteractionSettingsInput } from './interactions/interaction'
 import { DateComponent } from './component/DateComponent'
 import { CalendarContext } from './CalendarContext'
 import { createDuration } from './datelib/duration'
-import { RefinedViewOptions } from './options'
+import { RefinedViewOptions, CalendarListeners } from './options'
 
 export const ViewContextType = createContext<ViewContext>({} as any) // for Components
 export type ResizeHandler = (force: boolean) => void
@@ -47,7 +47,7 @@ export function buildViewContext(
   pluginHooks: PluginHooks,
   dispatch: (action: Action) => void,
   getCurrentData: () => CalendarData,
-  emitter: Emitter,
+  emitter: Emitter<CalendarListeners>,
   calendarApi: CalendarApi,
   registerInteractiveComponent: (component: DateComponent<any>, settingsInput: InteractionSettingsInput) => void,
   unregisterInteractiveComponent: (component: DateComponent<any>) => void

+ 8 - 8
packages/common/src/common/Emitter.ts

@@ -1,10 +1,10 @@
 import { applyAll } from '../util/misc'
 
 
-export class Emitter<Options = {}> {
+export class Emitter<HandlerFuncs extends { [eventName: string]: (...args: any[]) => any }> {
 
-  private handlers: any = {}
-  private options: Options
+  private handlers: { [Prop in keyof HandlerFuncs]?: HandlerFuncs[Prop][] } = {}
+  private options: HandlerFuncs
   private thisContext: any = null
 
 
@@ -13,22 +13,22 @@ export class Emitter<Options = {}> {
   }
 
 
-  setOptions(options: Options) {
+  setOptions(options: HandlerFuncs) {
     this.options = options
   }
 
 
-  on(type, handler) {
+  on<Prop extends keyof HandlerFuncs>(type: Prop, handler: HandlerFuncs[Prop]) {
     addToHash(this.handlers, type, handler)
   }
 
 
-  off(type, handler?) {
+  off<Prop extends keyof HandlerFuncs>(type: Prop, handler?: HandlerFuncs[Prop]) {
     removeFromHash(this.handlers, type, handler)
   }
 
 
-  trigger(type, ...args) {
+  trigger<Prop extends keyof HandlerFuncs>(type: Prop, ...args: Parameters<HandlerFuncs[Prop]>) {
     let res = applyAll(this.handlers[type], this.thisContext, args)
 
     let handlerFromOptions = this.options && this.options[type]
@@ -40,7 +40,7 @@ export class Emitter<Options = {}> {
   }
 
 
-  hasHandlers(type) {
+  hasHandlers(type: keyof HandlerFuncs) {
     return this.handlers[type] && this.handlers[type].length
   }
 

+ 1 - 1
packages/common/src/interactions/ElementDragging.ts

@@ -15,7 +15,7 @@ subclasses must emit:
 */
 export abstract class ElementDragging { // TODO: rename to *Interface?
 
-  emitter: Emitter
+  emitter: Emitter<any>
 
   constructor(el: HTMLElement) {
     this.emitter = new Emitter()

+ 0 - 5
packages/common/src/interactions/EventHovering.ts

@@ -14,7 +14,6 @@ export class EventHovering extends Interaction {
 
   constructor(settings: InteractionSettings) {
     super(settings)
-    let { component } = settings
 
     this.removeHoverListeners = listenToHoverBySelector(
       settings.el,
@@ -22,14 +21,10 @@ export class EventHovering extends Interaction {
       this.handleSegEnter,
       this.handleSegLeave
     )
-
-    // how to make sure component already has context?
-    component.context.emitter.on('eventElRemove', this.handleEventElRemove)
   }
 
   destroy() {
     this.removeHoverListeners()
-    this.component.context.emitter.off('eventElRemove', this.handleEventElRemove)
   }
 
   // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it

+ 6 - 1
packages/common/src/options.ts

@@ -271,8 +271,11 @@ export const CALENDAR_OPTION_REFINERS = { // does not include base
   events: identity as Identity<EventSourceInput>,
   eventSources: identity as Identity<EventSourceInput[]>,
 
+  datesDidUpdate: identity as Identity<
+    () => void
+  >,
   windowResize: identity as Identity<
-    (view: ViewApi) => void
+    (arg: { view: ViewApi }) => void
   >,
 
   _destroy: identity as Identity<() => void>,
@@ -486,3 +489,5 @@ export interface DayHeaderHookProps extends DateMeta {
   text: string
   [otherProp: string]: any
 }
+
+// TODO: do rtl/ltr

+ 2 - 2
packages/common/src/reducers/CalendarDataManager.ts

@@ -24,7 +24,7 @@ import { Emitter } from '../common/Emitter'
 import { EventUiHash, EventUi, processUiProps } from '../component/event-ui'
 import { EventDefHash } from '../structs/event-def'
 import { parseToolbars } from '../toolbar-parse'
-import { RefinedCalendarOptions, RefinedBaseOptions, RawCalendarOptions, CALENDAR_OPTION_REFINERS, RawViewOptions, RefinedViewOptions, RAW_BASE_DEFAULTS, mergeRawOptions, BASE_OPTION_REFINERS, VIEW_OPTION_REFINERS } from '../options'
+import { RefinedCalendarOptions, RefinedBaseOptions, RawCalendarOptions, CALENDAR_OPTION_REFINERS, RawViewOptions, RefinedViewOptions, RAW_BASE_DEFAULTS, mergeRawOptions, BASE_OPTION_REFINERS, VIEW_OPTION_REFINERS, CalendarListeners } from '../options'
 import { rangeContainsMarker } from '../datelib/date-range'
 import { ViewApi } from '../ViewApi'
 import { parseBusinessHours } from '../structs/business-hours'
@@ -74,7 +74,7 @@ export class CalendarDataManager {
   private parseContextBusinessHours = memoizeObjArg(parseContextBusinessHours)
   private buildTitle = memoize(buildTitle)
 
-  public emitter = new Emitter<RefinedCalendarOptions>()
+  public emitter = new Emitter<CalendarListeners>()
   private actionRunner = new TaskRunner(this._handleAction.bind(this), this.updateData.bind(this))
   private props: CalendarDataManagerProps
   private state: CalendarDataManagerState

+ 2 - 2
packages/common/src/reducers/data-types.ts

@@ -13,7 +13,7 @@ import { Theme } from '../theme/Theme'
 import { EventStore } from '../structs/event-store'
 import { DateSpan } from '../structs/date-span'
 import { EventInteractionState } from '../interactions/event-interaction-state'
-import { RefinedCalendarOptions, RefinedViewOptions, RawCalendarOptions } from '../options'
+import { RefinedCalendarOptions, RefinedViewOptions, RawCalendarOptions, CalendarListeners } from '../options'
 
 
 export interface CalendarDataManagerState {
@@ -61,6 +61,6 @@ export interface CalendarData extends CalendarDataBase {
   viewTitle: string // based on current date
   calendarApi: CalendarApi // TODO: try to remove this
   dispatch: (action: Action) => void
-  emitter: Emitter
+  emitter: Emitter<CalendarListeners>
   getCurrentData(): CalendarData // TODO: try to remove
 }

+ 1 - 3
packages/daygrid/src/Table.tsx

@@ -198,9 +198,7 @@ export class Table extends DateComponent<TableProps, TableState> {
     }
 
     if (typeof clickOption === 'function') {
-      // the returned value can be an atomic option
-      // TODO: weird how we don't use the `clickOption`
-      clickOption = context.emitter.trigger('moreLinkClick', {
+      clickOption = clickOption({
         date: dateEnv.toDate(arg.date),
         allDay: true,
         allSegs: arg.allSegs.map(segForPublic),

+ 11 - 3
packages/daygrid/src/options.ts

@@ -15,12 +15,20 @@ export interface EventSegment {
   isEnd: boolean
 }
 
-export type MoreLinkClickHandler = 'popover' | 'week' | 'day' | 'timeGridWeek' | 'timeGridDay' | string |
-  ((arg: { date: Date, allDay: boolean, allSegs: EventSegment[], hiddenSegs: EventSegment[], jsEvent: MouseEvent, view: ViewApi }) => void)
+export type MoreLinkAction = MoreLinkSimpleAction | MoreLinkHandler
+export type MoreLinkSimpleAction = 'popover' | 'week' | 'day' | 'timeGridWeek' | 'timeGridDay' | string
+export type MoreLinkHandler = (arg: {
+  date: Date,
+  allDay: boolean,
+  allSegs: EventSegment[],
+  hiddenSegs: EventSegment[],
+  jsEvent: UIEvent,
+  view: ViewApi
+}) => MoreLinkSimpleAction
 
 
 export const OPTION_REFINERS = {
-  moreLinkClick: identity as Identity<MoreLinkClickHandler>,
+  moreLinkClick: identity as Identity<MoreLinkAction>,
   moreLinkClassNames: identity as Identity<ClassNameGenerator<MoreLinkHookProps>>,
   moreLinkContent: identity as Identity<CustomContentGenerator<MoreLinkHookProps>>,
   moreLinkDidMount: identity as Identity<DidMountHandler<MoreLinkHookProps>>,

+ 1 - 1
packages/interaction/src/dnd/PointerDragging.ts

@@ -24,7 +24,7 @@ export class PointerDragging {
   containerEl: EventTarget
   subjectEl: HTMLElement | null = null
   downEl: HTMLElement | null = null
-  emitter: Emitter
+  emitter: Emitter<any>
 
   // options that can be directly assigned by caller
   selector: string = '' // will cause subjectEl in all emitted events to be this element

+ 1 - 1
packages/interaction/src/interactions/HitDragging.ts

@@ -28,7 +28,7 @@ export class HitDragging {
 
   droppableStore: InteractionSettingsStore
   dragging: ElementDragging
-  emitter: Emitter
+  emitter: Emitter<any>
 
   // options that can be set by caller
   useSubjectCenter: boolean = false