Skip to content

Commit

Permalink
fix(all): strong typed events
Browse files Browse the repository at this point in the history
  • Loading branch information
manucorporat committed Apr 23, 2018
1 parent b8c87c4 commit d5129df
Show file tree
Hide file tree
Showing 44 changed files with 429 additions and 602 deletions.
185 changes: 82 additions & 103 deletions core/src/components.d.ts

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions core/src/components/action-sheet/action-sheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,22 +82,22 @@ export class ActionSheet implements OverlayInterface {
/**
* Emitted after the alert has loaded.
*/
@Event() ionActionSheetDidLoad!: EventEmitter;
@Event() ionActionSheetDidLoad!: EventEmitter<void>;

/**
* Emitted after the alert has unloaded.
*/
@Event() ionActionSheetDidUnload!: EventEmitter;
@Event() ionActionSheetDidUnload!: EventEmitter<void>;

/**
* Emitted after the alert has presented.
*/
@Event({eventName: 'ionActionSheetDidPresent'}) didPresent!: EventEmitter;
@Event({eventName: 'ionActionSheetDidPresent'}) didPresent!: EventEmitter<void>;

/**
* Emitted before the alert has presented.
*/
@Event({eventName: 'ionActionSheetWillPresent'}) willPresent!: EventEmitter;
@Event({eventName: 'ionActionSheetWillPresent'}) willPresent!: EventEmitter<void>;

/**
* Emitted before the alert has dismissed.
Expand Down
2 changes: 1 addition & 1 deletion core/src/components/backdrop/backdrop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export class Backdrop {
/**
* Emitted when the backdrop is tapped.
*/
@Event() ionBackdropTap!: EventEmitter;
@Event() ionBackdropTap!: EventEmitter<void>;

componentDidLoad() {
registerBackdrop(this.doc, this);
Expand Down
5 changes: 2 additions & 3 deletions core/src/components/button/button.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Component, Element, Event, EventEmitter, Prop, State } from '@stencil/core';
import { CssClassMap, Mode } from '../../index';
import { BlurEvent, FocusEvent } from '../../utils/input-interfaces';
import { getButtonClassMap, getElementClassMap, openURL } from '../../utils/theme';


Expand Down Expand Up @@ -94,12 +93,12 @@ export class Button {
/**
* Emitted when the button has focus.
*/
@Event() ionFocus!: EventEmitter<FocusEvent>;
@Event() ionFocus!: EventEmitter<void>;

/**
* Emitted when the button loses focus.
*/
@Event() ionBlur!: EventEmitter<BlurEvent>;
@Event() ionBlur!: EventEmitter<void>;

componentWillLoad() {
if (this.el.closest('ion-buttons')) {
Expand Down
6 changes: 3 additions & 3 deletions core/src/components/checkbox/checkbox.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BlurEvent, CheckboxInput, CheckedInputChangeEvent, FocusEvent, StyleEvent } from '../../utils/input-interfaces';
import { CheckboxInput, CheckedInputChangeEvent, StyleEvent } from '../../utils/input-interfaces';
import { Component, Element, Event, EventEmitter, Prop, State, Watch } from '@stencil/core';
import { CssClassMap, Mode } from '../../index';
import { deferEvent } from '../../utils/helpers';
Expand Down Expand Up @@ -63,12 +63,12 @@ export class Checkbox implements CheckboxInput {
/**
* Emitted when the toggle has focus.
*/
@Event() ionFocus!: EventEmitter<FocusEvent>;
@Event() ionFocus!: EventEmitter<void>;

/**
* Emitted when the toggle loses focus.
*/
@Event() ionBlur!: EventEmitter<BlurEvent>;
@Event() ionBlur!: EventEmitter<void>;

/**
* Emitted when the styles change.
Expand Down
7 changes: 4 additions & 3 deletions core/src/components/datetime/datetime.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {

import { clamp, deferEvent } from '../../utils/helpers';
import { PickerColumn, PickerController, PickerOptions } from '../../index';
import { StyleEvent } from '../../utils/input-interfaces';


@Component({
Expand Down Expand Up @@ -211,12 +212,12 @@ export class Datetime {
/**
* Emitted when the datetime selection was cancelled.
*/
@Event() ionCancel!: EventEmitter;
@Event() ionCancel!: EventEmitter<void>;

/**
* Emitted when the styles change.
*/
@Event() ionStyle!: EventEmitter;
@Event() ionStyle!: EventEmitter<StyleEvent>;


componentWillLoad() {
Expand Down Expand Up @@ -263,7 +264,7 @@ export class Datetime {
{
text: this.cancelText,
role: 'cancel',
handler: () => this.ionCancel.emit(this)
handler: () => this.ionCancel.emit()
},
{
text: this.doneText,
Expand Down
139 changes: 29 additions & 110 deletions core/src/components/gesture/gesture.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, Event, EventEmitter, EventListenerEnable, Listen, Prop, Watch } from '@stencil/core';
import { Component, EventListenerEnable, Listen, Prop, Watch } from '@stencil/core';
import { assert, now } from '../../utils/helpers';
import { BlockerConfig, BlockerDelegate, GestureDelegate, QueueController } from '../../index';
import { PanRecognizer } from './recognizers';
Expand All @@ -18,9 +18,8 @@ export class Gesture {
private positions: number[] = [];
private gesture!: GestureDelegate;
private lastTouch = 0;
private pan?: PanRecognizer; // TODO
private pan!: PanRecognizer;
private hasCapturedPan = false;
private hasPress = false;
private hasStartedPan = false;
private hasFiredStart = true;
private isMoveQueued = false;
Expand All @@ -31,7 +30,7 @@ export class Gesture {
@Prop({ context: 'enableListener' }) enableListener!: EventListenerEnable;

@Prop() disabled = false;
@Prop() attachTo: string|HTMLElement = 'child';
@Prop() attachTo: string | HTMLElement = 'child';
@Prop() autoBlockAll = false;
@Prop() disableScroll = false;
@Prop() direction = 'x';
Expand All @@ -40,41 +39,14 @@ export class Gesture {
@Prop() passive = true;
@Prop() maxAngle = 40;
@Prop() threshold = 10;
@Prop() type = 'pan';

@Prop() canStart?: GestureCallback;
@Prop() onWillStart?: (_: GestureDetail) => Promise<void>;
@Prop() onStart?: GestureCallback;
@Prop() onMove?: GestureCallback;
@Prop() onEnd?: GestureCallback;
@Prop() onPress?: GestureCallback;
@Prop() notCaptured?: GestureCallback;

/**
* Emitted when the gesture moves.
*/
@Event() ionGestureMove!: EventEmitter;

/**
* Emitted when the gesture starts.
*/
@Event() ionGestureStart!: EventEmitter;

/**
* Emitted when the gesture ends.
*/
@Event() ionGestureEnd!: EventEmitter;

/**
* Emitted when the gesture is not captured.
*/
@Event() ionGestureNotCaptured!: EventEmitter;

/**
* Emitted when press is detected.
*/
@Event() ionPress!: EventEmitter;

constructor() {
this.detail = {
type: 'pan',
Expand Down Expand Up @@ -105,13 +77,7 @@ export class Gesture {
// in this case, we already know the GestureController and Gesture are already
// apart of the same bundle, so it's safe to load it this way
// only create one instance of GestureController, and reuse the same one later

const types = this.type.replace(/\s/g, '').toLowerCase().split(',');
if (types.indexOf('pan') > -1) {
this.pan = new PanRecognizer(this.direction, this.threshold, this.maxAngle);
}
this.hasPress = (types.indexOf('press') > -1);

this.pan = new PanRecognizer(this.direction, this.threshold, this.maxAngle);
this.disabledChanged(this.disabled);

if (this.autoBlockAll) {
Expand All @@ -121,14 +87,20 @@ export class Gesture {
}
}

componentDidUnload() {
if (this.blocker) {
this.blocker.destroy();
this.blocker = undefined;
}
this.gesture.destroy();
}

@Watch('disabled')
protected disabledChanged(isDisabled: boolean) {
if (this.pan || this.hasPress) {
this.enableListener(this, 'touchstart', !isDisabled, this.attachTo, this.passive);
this.enableListener(this, 'mousedown', !isDisabled, this.attachTo, this.passive);
if (isDisabled) {
this.abortGesture();
}
this.enableListener(this, 'touchstart', !isDisabled, this.attachTo, this.passive);
this.enableListener(this, 'mousedown', !isDisabled, this.attachTo, this.passive);
if (isDisabled) {
this.abortGesture();
}
}

Expand Down Expand Up @@ -194,13 +166,11 @@ export class Gesture {
}

this.positions.push(detail.currentX, detail.currentY, timeStamp);
if (this.pan) {
this.hasStartedPan = true;
if (this.threshold === 0) {
return this.tryToCapturePan();
}
this.pan.start(detail.startX, detail.startY);
this.hasStartedPan = true;
if (this.threshold === 0) {
return this.tryToCapturePan();
}
this.pan.start(detail.startX, detail.startY);
return true;
}

Expand All @@ -224,11 +194,6 @@ export class Gesture {
}

private pointerMove(ev: UIEvent) {
if (!this.pan) {
assert(false, 'pan must be non null');
return;
}

// fast path, if gesture is currently captured
// do minimun job to get user-land even dispatched
if (this.hasCapturedPan) {
Expand Down Expand Up @@ -262,8 +227,6 @@ export class Gesture {
this.isMoveQueued = false;
if (this.onMove) {
this.onMove(detail);
} else {
this.ionGestureMove.emit(detail);
}
}

Expand Down Expand Up @@ -334,24 +297,26 @@ export class Gesture {
assert(!this.hasFiredStart, 'has fired must be false');
if (this.onStart) {
this.onStart(this.detail);
} else {
this.ionGestureStart.emit(this.detail);
}
this.hasFiredStart = true;
}

private abortGesture() {
this.reset();
this.enable(false);
this.notCaptured && this.notCaptured(this.detail);
if (this.notCaptured) {
this.notCaptured(this.detail);
}
}

private reset() {
this.hasCapturedPan = false;
this.hasStartedPan = false;
this.isMoveQueued = false;
this.hasFiredStart = true;
this.gesture && this.gesture.release();
if (this.gesture) {
this.gesture.release();
}
}

// END *************************
Expand Down Expand Up @@ -390,85 +355,39 @@ export class Gesture {

// Try to capture press
if (hasCaptured) {
detail.type = 'pan';
if (this.onEnd) {
this.onEnd(detail);
} else {
this.ionGestureEnd.emit(detail);
}
return;
}

// Try to capture press
if (this.hasPress && this.detectPress()) {
return;
}

// Not captured any event
if (this.notCaptured) {
this.notCaptured(detail);
} else {
this.ionGestureNotCaptured.emit(detail);
}
}

private detectPress(): boolean {
const detail = this.detail;
const vecX = detail.deltaX;
const vecY = detail.deltaY;
const dis = vecX * vecX + vecY * vecY;
if (dis < 100) {
detail.type = 'press';

if (this.onPress) {
this.onPress(detail);
} else {
this.ionPress.emit(detail);
}
return true;
}
return false;
}

// ENABLE LISTENERS *************************

private enableMouse(shouldEnable: boolean) {
if (this.pan) {
this.enableListener(this, 'document:mousemove', shouldEnable, undefined, this.passive);
}
this.enableListener(this, 'document:mousemove', shouldEnable, undefined, this.passive);
this.enableListener(this, 'document:mouseup', shouldEnable, undefined, this.passive);
}


private enableTouch(shouldEnable: boolean) {
if (this.pan) {
this.enableListener(this, 'touchmove', shouldEnable, this.attachTo, this.passive);
}
this.enableListener(this, 'touchmove', shouldEnable, this.attachTo, this.passive);
this.enableListener(this, 'touchcancel', shouldEnable, this.attachTo, this.passive);
this.enableListener(this, 'touchend', shouldEnable, this.attachTo, this.passive);
}


private enable(shouldEnable: boolean) {
this.enableMouse(shouldEnable);
this.enableTouch(shouldEnable);
}


componentDidUnload() {
if (this.blocker) {
this.blocker.destroy();
this.blocker = undefined;
}
this.gesture.destroy();
}

}


const MOUSE_WAIT = 2500;


export interface GestureDetail {
type: string;
startX: number;
Expand All @@ -489,7 +408,7 @@ export interface GestureCallback {
(detail?: GestureDetail): boolean|void;
}

function updateDetail(ev: any, detail: any) {
function updateDetail(ev: any, detail: GestureDetail) {
// get X coordinates for either a mouse click
// or a touch depending on the given event
let x = 0;
Expand Down
Loading

0 comments on commit d5129df

Please sign in to comment.