diff --git a/packages/inferno-router/src/Link.ts b/packages/inferno-router/src/Link.ts index 8c6bfa439..e29c011de 100644 --- a/packages/inferno-router/src/Link.ts +++ b/packages/inferno-router/src/Link.ts @@ -1,8 +1,8 @@ -import { linkEvent, createVNode, VNode } from 'inferno'; +import { linkEvent, createVNode, VNode, MouseEvent } from 'inferno'; import { ChildFlags, VNodeFlags } from 'inferno-vnode-flags'; import { invariant } from './utils'; -const isModifiedEvent = (event): boolean => Boolean(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); +const isModifiedEvent = (event: MouseEvent): boolean => Boolean(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); export interface ILinkProps { children: any; @@ -14,7 +14,7 @@ export interface ILinkProps { innerRef: any; } -function handleClick({ props, context }, event) { +function handleClick({ props, context }, event: MouseEvent) { if (props.onClick) { props.onClick(event); } diff --git a/packages/inferno/src/DOM/events/delegation.ts b/packages/inferno/src/DOM/events/delegation.ts index f7c842994..85ee3b457 100644 --- a/packages/inferno/src/DOM/events/delegation.ts +++ b/packages/inferno/src/DOM/events/delegation.ts @@ -1,4 +1,5 @@ import { isNull } from 'inferno-shared'; +import { SemiSyntheticEvent } from "inferno"; const attachedEventCounts = {}; const attachedEvents = {}; @@ -32,7 +33,7 @@ export function handleEvent(name: string, nextEvent: Function | null, dom) { } } -function dispatchEvents(event, target, isClick: boolean, name: string, eventData: IEventData) { +function dispatchEvents(event: SemiSyntheticEvent, target, isClick: boolean, name: string, eventData: IEventData) { let dom = target; while (!isNull(dom)) { // Html Nodes can be nested fe: span inside button in that scenario browser does not handle disabled attribute on parent, diff --git a/packages/inferno/src/DOM/events/events.ts b/packages/inferno/src/DOM/events/events.ts new file mode 100644 index 000000000..428867af5 --- /dev/null +++ b/packages/inferno/src/DOM/events/events.ts @@ -0,0 +1,61 @@ +// +// Event System +// ---------------------------------------------------------------------- + +import { + NativeAnimationEvent, NativeClipboardEvent, NativeCompositionEvent, NativeDragEvent, NativeFocusEvent, + NativeKeyboardEvent, + NativeMouseEvent, NativeTouchEvent, NativeTransitionEvent, NativeUIEvent, NativeWheelEvent +} from "../../JSX"; +import { LinkedEvent } from "./linkEvent"; + +export interface SemiSyntheticEvent extends Event { + /** + * A reference to the element on which the event listener is registered. + */ + currentTarget: EventTarget & T; +} + +export type ClipboardEvent = SemiSyntheticEvent & NativeClipboardEvent; +export type CompositionEvent = SemiSyntheticEvent & NativeCompositionEvent; +export type DragEvent = MouseEvent & NativeDragEvent; +export type FocusEvent = SemiSyntheticEvent & NativeFocusEvent; +export type FormEvent = SemiSyntheticEvent; + +export interface InvalidEvent extends SemiSyntheticEvent { + target: EventTarget & T; +} + +export interface ChangeEvent extends SemiSyntheticEvent { + target: EventTarget & T; +} + +export type KeyboardEvent = SemiSyntheticEvent & NativeKeyboardEvent; +export type MouseEvent = SemiSyntheticEvent & NativeMouseEvent; +export type TouchEvent = SemiSyntheticEvent & NativeTouchEvent; +export type UIEvent = SemiSyntheticEvent & NativeUIEvent; +export type WheelEvent = MouseEvent & NativeWheelEvent; +export type AnimationEvent = SemiSyntheticEvent & NativeAnimationEvent; +export type TransitionEvent = SemiSyntheticEvent & NativeTransitionEvent; + +// +// Event Handler Types +// ---------------------------------------------------------------------- + +export type EventHandler> = { bivarianceHack(event: E): void }["bivarianceHack"] | LinkedEvent; + +export type InfernoEventHandler = EventHandler>; + +export type ClipboardEventHandler = EventHandler>; +export type CompositionEventHandler = EventHandler>; +export type DragEventHandler = EventHandler>; +export type FocusEventHandler = EventHandler>; +export type FormEventHandler = EventHandler>; +export type ChangeEventHandler = EventHandler>; +export type KeyboardEventHandler = EventHandler>; +export type MouseEventHandler = EventHandler>; +export type TouchEventHandler = EventHandler>; +export type UIEventHandler = EventHandler>; +export type WheelEventHandler = EventHandler>; +export type AnimationEventHandler = EventHandler>; +export type TransitionEventHandler = EventHandler>; diff --git a/packages/inferno/src/DOM/events/linkEvent.ts b/packages/inferno/src/DOM/events/linkEvent.ts index 0833f28bf..53c3574de 100644 --- a/packages/inferno/src/DOM/events/linkEvent.ts +++ b/packages/inferno/src/DOM/events/linkEvent.ts @@ -1,12 +1,17 @@ import { isFunction } from 'inferno-shared'; +export interface LinkedEvent { + data: T; + event: (data: T, event: E) => void; +} + /** * Links given data to event as first parameter * @param {*} data data to be linked, it will be available in function as first parameter * @param {Function} event Function to be called when event occurs * @returns {{data: *, event: Function}} */ -export function linkEvent(data, event) { +export function linkEvent(data: T, event: (data: T, event: E) => void): LinkedEvent | null { if (isFunction(event)) { return { data, event }; } diff --git a/packages/inferno/src/JSX.ts b/packages/inferno/src/JSX.ts index 394586e09..b2f572ac5 100644 --- a/packages/inferno/src/JSX.ts +++ b/packages/inferno/src/JSX.ts @@ -1,4 +1,21 @@ -import { Component, ComponentClass, StatelessComponent, InfernoChildren, SFC, VNode } from "inferno"; +import { + Component, ComponentClass, StatelessComponent, InfernoChildren, SFC, VNode, + InfernoEventHandler, KeyboardEventHandler, FormEventHandler, CompositionEventHandler, ClipboardEventHandler, + FocusEventHandler, MouseEventHandler, DragEventHandler, WheelEventHandler, UIEventHandler, TouchEventHandler, + AnimationEventHandler, TransitionEventHandler, ChangeEventHandler +} from "inferno"; + +export type NativeAnimationEvent = AnimationEvent; +export type NativeClipboardEvent = ClipboardEvent; +export type NativeCompositionEvent = CompositionEvent; +export type NativeDragEvent = DragEvent; +export type NativeFocusEvent = FocusEvent; +export type NativeKeyboardEvent = KeyboardEvent; +export type NativeMouseEvent = MouseEvent; +export type NativeTouchEvent = TouchEvent; +export type NativeTransitionEvent = TransitionEvent; +export type NativeUIEvent = UIEvent; +export type NativeWheelEvent = WheelEvent; declare global { // Based on Type definitions for React 16.0 @@ -22,18 +39,6 @@ declare global { /// - type NativeAnimationEvent = AnimationEvent; - type NativeClipboardEvent = ClipboardEvent; - type NativeCompositionEvent = CompositionEvent; - type NativeDragEvent = DragEvent; - type NativeFocusEvent = FocusEvent; - type NativeKeyboardEvent = KeyboardEvent; - type NativeMouseEvent = MouseEvent; - type NativeTouchEvent = TouchEvent; - type NativeTransitionEvent = TransitionEvent; - type NativeUIEvent = UIEvent; - type NativeWheelEvent = WheelEvent; - // tslint:disable-next-line:export-just-namespace // export = InfernoJSX; // export as namespace InfernoJSX; @@ -308,190 +313,6 @@ declare global { // [propertyName: string]: any; // } - // - // Event System - // ---------------------------------------------------------------------- - - interface SyntheticEvent { - bubbles: boolean; - /** - * A reference to the element on which the event listener is registered. - */ - currentTarget: EventTarget & T; - cancelable: boolean; - defaultPrevented: boolean; - eventPhase: number; - isTrusted: boolean; - nativeEvent: Event; - - preventDefault(): void; - - isDefaultPrevented(): boolean; - - stopPropagation(): void; - - isPropagationStopped(): boolean; - - persist(): void; - - // If you thought this should be `EventTarget & T`, see https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12239 - /** - * A reference to the element from which the event was originally dispatched. - * This might be a child element to the element on which the event listener is registered. - * - * @see currentTarget - */ - target: EventTarget; - timeStamp: number; - type: string; - } - - interface ClipboardEvent extends SyntheticEvent { - clipboardData: DataTransfer; - nativeEvent: NativeClipboardEvent; - } - - interface CompositionEvent extends SyntheticEvent { - data: string; - nativeEvent: NativeCompositionEvent; - } - - interface DragEvent extends MouseEvent { - dataTransfer: DataTransfer; - nativeEvent: NativeDragEvent; - } - - interface FocusEvent extends SyntheticEvent { - nativeEvent: NativeFocusEvent; - relatedTarget: EventTarget; - } - - // tslint:disable-next-line:no-empty-interface - interface FormEvent extends SyntheticEvent { - } - - interface InvalidEvent extends SyntheticEvent { - target: EventTarget & T; - } - - interface ChangeEvent extends SyntheticEvent { - target: EventTarget & T; - } - - interface KeyboardEvent extends SyntheticEvent { - altKey: boolean; - charCode: number; - ctrlKey: boolean; - - /** - * See [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#keys-modifier). for a list of valid (case-sensitive) arguments to this method. - */ - getModifierState(key: string): boolean; - - /** - * See the [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#named-key-attribute-values). for possible values - */ - key: string; - keyCode: number; - locale: string; - location: number; - metaKey: boolean; - nativeEvent: NativeKeyboardEvent; - repeat: boolean; - shiftKey: boolean; - which: number; - } - - interface MouseEvent extends SyntheticEvent { - altKey: boolean; - button: number; - buttons: number; - clientX: number; - clientY: number; - ctrlKey: boolean; - - /** - * See [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#keys-modifier). for a list of valid (case-sensitive) arguments to this method. - */ - getModifierState(key: string): boolean; - - metaKey: boolean; - nativeEvent: NativeMouseEvent; - pageX: number; - pageY: number; - relatedTarget: EventTarget; - screenX: number; - screenY: number; - shiftKey: boolean; - } - - interface TouchEvent extends SyntheticEvent { - altKey: boolean; - changedTouches: TouchList; - ctrlKey: boolean; - - /** - * See [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#keys-modifier). for a list of valid (case-sensitive) arguments to this method. - */ - getModifierState(key: string): boolean; - - metaKey: boolean; - nativeEvent: NativeTouchEvent; - shiftKey: boolean; - targetTouches: TouchList; - touches: TouchList; - } - - interface UIEvent extends SyntheticEvent { - detail: number; - nativeEvent: NativeUIEvent; - view: AbstractView; - } - - interface WheelEvent extends MouseEvent { - deltaMode: number; - deltaX: number; - deltaY: number; - deltaZ: number; - nativeEvent: NativeWheelEvent; - } - - interface AnimationEvent extends SyntheticEvent { - animationName: string; - elapsedTime: number; - nativeEvent: NativeAnimationEvent; - pseudoElement: string; - } - - interface TransitionEvent extends SyntheticEvent { - elapsedTime: number; - nativeEvent: NativeTransitionEvent; - propertyName: string; - pseudoElement: string; - } - - // - // Event Handler Types - // ---------------------------------------------------------------------- - - type EventHandler> = { bivarianceHack(event: E): void }["bivarianceHack"]; - - type InfernoEventHandler = EventHandler>; - - type ClipboardEventHandler = EventHandler>; - type CompositionEventHandler = EventHandler>; - type DragEventHandler = EventHandler>; - type FocusEventHandler = EventHandler>; - type FormEventHandler = EventHandler>; - type ChangeEventHandler = EventHandler>; - type KeyboardEventHandler = EventHandler>; - type MouseEventHandler = EventHandler>; - type TouchEventHandler = EventHandler>; - type UIEventHandler = EventHandler>; - type WheelEventHandler = EventHandler>; - type AnimationEventHandler = EventHandler>; - type TransitionEventHandler = EventHandler>; - // // Props / DOM Attributes // ---------------------------------------------------------------------- diff --git a/packages/inferno/src/index.ts b/packages/inferno/src/index.ts index 8ec8ebda9..8f6dd7f2c 100644 --- a/packages/inferno/src/index.ts +++ b/packages/inferno/src/index.ts @@ -13,7 +13,7 @@ import { Refs, VNode } from './core/implementation'; -import { linkEvent } from './DOM/events/linkEvent'; +import { linkEvent, LinkedEvent } from './DOM/events/linkEvent'; import { createPortal, createRenderer, render } from './DOM/rendering'; import { EMPTY_OBJ } from './DOM/utils/common'; import { @@ -27,7 +27,7 @@ import { getNumberStyleValue } from './DOM/props'; import { hydrate } from './DOM/hydration'; import * as JSX from "./JSX"; - +export * from "./DOM/events/events"; if (process.env.NODE_ENV !== 'production') { /* tslint:disable-next-line:no-empty */ @@ -67,6 +67,7 @@ export { getNumberStyleValue, hydrate, linkEvent, + LinkedEvent, normalizeProps, options, render,