mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 20:33:32 +08:00
refactor(all): use ts strict mode
This commit is contained in:
3336
packages/core/src/components.d.ts.orig
Normal file
3336
packages/core/src/components.d.ts.orig
Normal file
File diff suppressed because it is too large
Load Diff
@ -32,6 +32,9 @@ export class ActionSheetController {
|
|||||||
dismiss(data?: any, role?: any, actionSheetId = -1) {
|
dismiss(data?: any, role?: any, actionSheetId = -1) {
|
||||||
actionSheetId = actionSheetId >= 0 ? actionSheetId : getHighestId();
|
actionSheetId = actionSheetId >= 0 ? actionSheetId : getHighestId();
|
||||||
const actionSheet = actionSheets.get(actionSheetId);
|
const actionSheet = actionSheets.get(actionSheetId);
|
||||||
|
if (!actionSheet) {
|
||||||
|
return Promise.reject('action-sheet does not exist');
|
||||||
|
}
|
||||||
return actionSheet.dismiss(data, role);
|
return actionSheet.dismiss(data, role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ export class ActionSheet {
|
|||||||
color: string;
|
color: string;
|
||||||
actionSheetId: number;
|
actionSheetId: number;
|
||||||
|
|
||||||
private animation: Animation;
|
private animation: Animation | null = null;
|
||||||
|
|
||||||
@Element() private el: HTMLElement;
|
@Element() private el: HTMLElement;
|
||||||
|
|
||||||
@ -232,22 +232,17 @@ export class ActionSheet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let cancelButton: ActionSheetButton;
|
const allButtons = this.buttons.map(b => {
|
||||||
const buttons = this.buttons
|
|
||||||
.map(b => {
|
|
||||||
if (typeof b === 'string') {
|
if (typeof b === 'string') {
|
||||||
b = { text: b };
|
b = { text: b };
|
||||||
}
|
}
|
||||||
if (!b.cssClass) {
|
if (!b.cssClass) {
|
||||||
b.cssClass = '';
|
b.cssClass = '';
|
||||||
}
|
}
|
||||||
if (b.role === 'cancel') {
|
|
||||||
cancelButton = b;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return b;
|
return b;
|
||||||
})
|
});
|
||||||
.filter(b => b !== null);
|
const cancelButton = allButtons.find(b => b.role === 'cancel');
|
||||||
|
const buttons = allButtons.filter(b => b.role !== 'cancel');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
<ion-backdrop
|
<ion-backdrop
|
||||||
|
@ -32,6 +32,9 @@ export class AlertController {
|
|||||||
dismiss(data?: any, role?: any, alertId = -1) {
|
dismiss(data?: any, role?: any, alertId = -1) {
|
||||||
alertId = alertId >= 0 ? alertId : getHighestId();
|
alertId = alertId >= 0 ? alertId : getHighestId();
|
||||||
const alert = alerts.get(alertId);
|
const alert = alerts.get(alertId);
|
||||||
|
if (!alert) {
|
||||||
|
return Promise.reject('alert does not exist');
|
||||||
|
}
|
||||||
return alert.dismiss(data, role);
|
return alert.dismiss(data, role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,9 +26,9 @@ export class Alert {
|
|||||||
color: string;
|
color: string;
|
||||||
alertId: number;
|
alertId: number;
|
||||||
|
|
||||||
private animation: Animation;
|
private animation: Animation | null = null;
|
||||||
private activeId: string;
|
private activeId: string;
|
||||||
private inputType: string;
|
private inputType: string | null = null;
|
||||||
private hdrId: string;
|
private hdrId: string;
|
||||||
|
|
||||||
@Element() private el: HTMLElement;
|
@Element() private el: HTMLElement;
|
||||||
@ -376,22 +376,16 @@ export class Alert {
|
|||||||
'alert-button-group-vertical': this.buttons.length > 2
|
'alert-button-group-vertical': this.buttons.length > 2
|
||||||
};
|
};
|
||||||
|
|
||||||
const buttons = this.buttons
|
const buttons = this.buttons.map(b => {
|
||||||
.map(b => {
|
|
||||||
if (typeof b === 'string') {
|
if (typeof b === 'string') {
|
||||||
b = { text: b };
|
return { text: b } as AlertButton;
|
||||||
}
|
}
|
||||||
return b;
|
return b;
|
||||||
})
|
})
|
||||||
.filter(b => b !== null);
|
.filter(b => b !== null);
|
||||||
|
|
||||||
// An alert can be created with several different inputs. Radios,
|
this.inputs = this.inputs.map((i, index) => {
|
||||||
// checkboxes and inputs are all accepted, but they cannot be mixed.
|
return {
|
||||||
const inputTypes: string[] = [];
|
|
||||||
|
|
||||||
this.inputs = this.inputs
|
|
||||||
.map((i, index) => {
|
|
||||||
const r: AlertInput = {
|
|
||||||
type: i.type || 'text',
|
type: i.type || 'text',
|
||||||
name: i.name ? i.name : index + '',
|
name: i.name ? i.name : index + '',
|
||||||
placeholder: i.placeholder ? i.placeholder : '',
|
placeholder: i.placeholder ? i.placeholder : '',
|
||||||
@ -403,11 +397,12 @@ export class Alert {
|
|||||||
handler: i.handler ? i.handler : null,
|
handler: i.handler ? i.handler : null,
|
||||||
min: i.min ? i.min : null,
|
min: i.min ? i.min : null,
|
||||||
max: i.max ? i.max : null
|
max: i.max ? i.max : null
|
||||||
};
|
} as AlertInput;
|
||||||
return r;
|
}).filter(i => i !== null);
|
||||||
})
|
|
||||||
.filter(i => i !== null);
|
|
||||||
|
|
||||||
|
// An alert can be created with several different inputs. Radios,
|
||||||
|
// checkboxes and inputs are all accepted, but they cannot be mixed.
|
||||||
|
const inputTypes: string[] = [];
|
||||||
this.inputs.forEach(i => {
|
this.inputs.forEach(i => {
|
||||||
if (inputTypes.indexOf(i.type) < 0) {
|
if (inputTypes.indexOf(i.type) < 0) {
|
||||||
inputTypes.push(i.type);
|
inputTypes.push(i.type);
|
||||||
@ -418,7 +413,7 @@ export class Alert {
|
|||||||
console.warn(`Alert cannot mix input types: ${(inputTypes.join('/'))}. Please see alert docs for more info.`);
|
console.warn(`Alert cannot mix input types: ${(inputTypes.join('/'))}. Please see alert docs for more info.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.inputType = inputTypes.length ? inputTypes[0] : null;
|
this.inputType = inputTypes.length > 0 ? inputTypes[0] : null;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
<ion-backdrop
|
<ion-backdrop
|
||||||
@ -434,18 +429,13 @@ export class Alert {
|
|||||||
? <h2 id={subHdrId} class='alert-sub-title'>{this.subTitle}</h2>
|
? <h2 id={subHdrId} class='alert-sub-title'>{this.subTitle}</h2>
|
||||||
: null}
|
: null}
|
||||||
</div>
|
</div>
|
||||||
<div id={msgId} class='alert-message' innerHTML={this.message}></div>
|
|
||||||
|
|
||||||
|
<div id={msgId} class='alert-message' innerHTML={this.message}></div>
|
||||||
{(() => {
|
{(() => {
|
||||||
switch (this.inputType) {
|
switch (this.inputType) {
|
||||||
case 'checkbox':
|
case 'checkbox': return this.renderCheckbox(this.inputs);
|
||||||
return this.renderCheckbox(this.inputs);
|
case 'radio': return this.renderRadio(this.inputs);
|
||||||
|
default: return this.renderInput(this.inputs);
|
||||||
case 'radio':
|
|
||||||
return this.renderRadio(this.inputs);
|
|
||||||
|
|
||||||
default:
|
|
||||||
return this.renderInput(this.inputs);
|
|
||||||
}
|
}
|
||||||
})()}
|
})()}
|
||||||
|
|
||||||
@ -483,8 +473,8 @@ export interface AlertOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AlertInput {
|
export interface AlertInput {
|
||||||
type?: string;
|
type: string;
|
||||||
name?: string | number;
|
name: string | number;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
value?: string;
|
value?: string;
|
||||||
label?: string;
|
label?: string;
|
||||||
@ -497,7 +487,7 @@ export interface AlertInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AlertButton {
|
export interface AlertButton {
|
||||||
text?: string;
|
text: string;
|
||||||
role?: string;
|
role?: string;
|
||||||
cssClass?: string;
|
cssClass?: string;
|
||||||
handler?: (value: any) => boolean|void;
|
handler?: (value: any) => boolean|void;
|
||||||
|
@ -74,6 +74,6 @@ export interface EffectProperty {
|
|||||||
|
|
||||||
export interface EffectState {
|
export interface EffectState {
|
||||||
val: any;
|
val: any;
|
||||||
num: number;
|
num: number|null;
|
||||||
effectUnit: string;
|
effectUnit: string;
|
||||||
}
|
}
|
||||||
|
@ -14,25 +14,25 @@ export class Animator {
|
|||||||
private _beforeStyles: { [property: string]: any; };
|
private _beforeStyles: { [property: string]: any; };
|
||||||
private _childAnimations: Animator[];
|
private _childAnimations: Animator[];
|
||||||
private _childAnimationTotal: number;
|
private _childAnimationTotal: number;
|
||||||
private _duration: number = null;
|
private _duration: number|null = null;
|
||||||
private _easingName: string = null;
|
private _easingName: string|null = null;
|
||||||
private _elements: HTMLElement[] = null;
|
private _elements: HTMLElement[]|null = null;
|
||||||
private _elementTotal: number;
|
private _elementTotal: number;
|
||||||
private _fxProperties: EffectProperty[];
|
private _fxProperties: EffectProperty[];
|
||||||
private _hasDur: boolean;
|
private _hasDur: boolean;
|
||||||
private _hasTweenEffect: boolean;
|
private _hasTweenEffect: boolean;
|
||||||
private _isAsync: boolean;
|
private _isAsync: boolean;
|
||||||
private _isReverse: boolean;
|
private _isReverse: boolean;
|
||||||
private _onFinishCallbacks: Function[];
|
private _onFinishCallbacks: Function[] | undefined;
|
||||||
private _onFinishOneTimeCallbacks: Function[];
|
private _onFinishOneTimeCallbacks: Function[] | undefined;
|
||||||
private _readCallbacks: Function[];
|
private _readCallbacks: Function[];
|
||||||
private _reversedEasingName: string = null;
|
private _reversedEasingName: string|undefined;
|
||||||
private _timerId: any;
|
private _timerId: any;
|
||||||
private _unregisterTrnsEnd: Function;
|
private _unregisterTrnsEnd: Function | undefined;
|
||||||
private _writeCallbacks: Function[];
|
private _writeCallbacks: Function[];
|
||||||
private _destroyed = false;
|
private _destroyed = false;
|
||||||
|
|
||||||
parent: Animator;
|
parent: Animator|undefined;
|
||||||
opts: AnimationOptions;
|
opts: AnimationOptions;
|
||||||
hasChildren = false;
|
hasChildren = false;
|
||||||
isPlaying = false;
|
isPlaying = false;
|
||||||
@ -106,7 +106,7 @@ export class Animator {
|
|||||||
* Get the easing of this animation. If this animation does
|
* Get the easing of this animation. If this animation does
|
||||||
* not have an easing, then it'll get the easing from its parent.
|
* not have an easing, then it'll get the easing from its parent.
|
||||||
*/
|
*/
|
||||||
getEasing(): string {
|
getEasing(): string|null {
|
||||||
if (this._isReverse && this._reversedEasingName) {
|
if (this._isReverse && this._reversedEasingName) {
|
||||||
return this._reversedEasingName;
|
return this._reversedEasingName;
|
||||||
}
|
}
|
||||||
@ -163,14 +163,14 @@ export class Animator {
|
|||||||
* NO DOM
|
* NO DOM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private _getProp(name: string): EffectProperty {
|
private _getProp(name: string): EffectProperty | undefined {
|
||||||
if (this._fxProperties) {
|
if (this._fxProperties) {
|
||||||
return this._fxProperties.find(function(prop) { return prop.effectName === name; });
|
return this._fxProperties.find(prop => prop.effectName === name);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this._fxProperties = [];
|
this._fxProperties = [];
|
||||||
}
|
}
|
||||||
return null;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _addProp(state: string, prop: string, val: any): EffectProperty {
|
private _addProp(state: string, prop: string, val: any): EffectProperty {
|
||||||
@ -361,7 +361,7 @@ export class Animator {
|
|||||||
* DOM WRITE
|
* DOM WRITE
|
||||||
* RECURSION
|
* RECURSION
|
||||||
*/
|
*/
|
||||||
_playInit(opts: PlayOptions) {
|
_playInit(opts: PlayOptions|undefined) {
|
||||||
// always default that an animation does not tween
|
// always default that an animation does not tween
|
||||||
// a tween requires that an Animation class has an element
|
// a tween requires that an Animation class has an element
|
||||||
// and that it has at least one FROM/TO effect
|
// and that it has at least one FROM/TO effect
|
||||||
@ -393,7 +393,7 @@ export class Animator {
|
|||||||
* NO RECURSION
|
* NO RECURSION
|
||||||
* ROOT ANIMATION
|
* ROOT ANIMATION
|
||||||
*/
|
*/
|
||||||
_playDomInspect(opts: PlayOptions) {
|
_playDomInspect(opts: PlayOptions|undefined) {
|
||||||
const self = this;
|
const self = this;
|
||||||
// fire off all the "before" function that have DOM READS in them
|
// fire off all the "before" function that have DOM READS in them
|
||||||
// elements will be in the DOM, however visibily hidden
|
// elements will be in the DOM, however visibily hidden
|
||||||
@ -426,7 +426,7 @@ export class Animator {
|
|||||||
* DOM WRITE
|
* DOM WRITE
|
||||||
* RECURSION
|
* RECURSION
|
||||||
*/
|
*/
|
||||||
_playProgress(opts: PlayOptions) {
|
_playProgress(opts: PlayOptions|undefined) {
|
||||||
const children = this._childAnimations;
|
const children = this._childAnimations;
|
||||||
for (let i = 0; i < this._childAnimationTotal; i++) {
|
for (let i = 0; i < this._childAnimationTotal; i++) {
|
||||||
// ******** DOM WRITE ****************
|
// ******** DOM WRITE ****************
|
||||||
@ -558,7 +558,7 @@ export class Animator {
|
|||||||
* NO DOM
|
* NO DOM
|
||||||
* RECURSION
|
* RECURSION
|
||||||
*/
|
*/
|
||||||
_hasDuration(opts: PlayOptions) {
|
_hasDuration(opts: PlayOptions|undefined) {
|
||||||
if (this.getDuration(opts) > DURATION_MIN) {
|
if (this.getDuration(opts) > DURATION_MIN) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -620,10 +620,11 @@ export class Animator {
|
|||||||
_progress(stepValue: number) {
|
_progress(stepValue: number) {
|
||||||
// bread 'n butter
|
// bread 'n butter
|
||||||
let val: any;
|
let val: any;
|
||||||
|
const elements = this._elements;
|
||||||
const effects = this._fxProperties;
|
const effects = this._fxProperties;
|
||||||
const nuElements = this._elementTotal;
|
const nuElements = this._elementTotal;
|
||||||
|
|
||||||
if (!effects || !nuElements || this._destroyed) {
|
if (!elements || !effects || !nuElements || this._destroyed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -634,7 +635,6 @@ export class Animator {
|
|||||||
let i = 0;
|
let i = 0;
|
||||||
let j = 0;
|
let j = 0;
|
||||||
let finalTransform = '';
|
let finalTransform = '';
|
||||||
const elements = this._elements;
|
|
||||||
let fx: EffectProperty;
|
let fx: EffectProperty;
|
||||||
|
|
||||||
for (i = 0; i < effects.length; i++) {
|
for (i = 0; i < effects.length; i++) {
|
||||||
@ -701,12 +701,13 @@ export class Animator {
|
|||||||
*/
|
*/
|
||||||
_setTrans(dur: number, forcedLinearEasing: boolean) {
|
_setTrans(dur: number, forcedLinearEasing: boolean) {
|
||||||
// Transition is not enabled if there are not effects
|
// Transition is not enabled if there are not effects
|
||||||
if (!this._fxProperties) {
|
const elements = this._elements;
|
||||||
|
const nuElements = this._elementTotal;
|
||||||
|
if (!elements || !this._fxProperties || nuElements === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the TRANSITION properties inline on the element
|
// set the TRANSITION properties inline on the element
|
||||||
const elements = this._elements;
|
|
||||||
const easing = (forcedLinearEasing ? 'linear' : this.getEasing());
|
const easing = (forcedLinearEasing ? 'linear' : this.getEasing());
|
||||||
const durString = dur + 'ms';
|
const durString = dur + 'ms';
|
||||||
const cssTransform = CSS_PROP.transitionProp;
|
const cssTransform = CSS_PROP.transitionProp;
|
||||||
@ -714,7 +715,7 @@ export class Animator {
|
|||||||
const cssTransitionTimingFn = CSS_PROP.transitionTimingFnProp;
|
const cssTransitionTimingFn = CSS_PROP.transitionTimingFnProp;
|
||||||
|
|
||||||
let eleStyle: any;
|
let eleStyle: any;
|
||||||
for (let i = 0; i < this._elementTotal; i++) {
|
for (let i = 0; i < nuElements; i++) {
|
||||||
eleStyle = elements[i].style;
|
eleStyle = elements[i].style;
|
||||||
if (dur > 0) {
|
if (dur > 0) {
|
||||||
// ******** DOM WRITE ****************
|
// ******** DOM WRITE ****************
|
||||||
@ -760,26 +761,27 @@ export class Animator {
|
|||||||
* RECURSION
|
* RECURSION
|
||||||
*/
|
*/
|
||||||
_setBeforeStyles() {
|
_setBeforeStyles() {
|
||||||
let i: number, j: number;
|
let j: number;
|
||||||
const children = this._childAnimations;
|
const children = this._childAnimations;
|
||||||
for (i = 0; i < this._childAnimationTotal; i++) {
|
|
||||||
|
for (let i = 0; i < this._childAnimationTotal; i++) {
|
||||||
children[i]._setBeforeStyles();
|
children[i]._setBeforeStyles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const elements = this._elements;
|
||||||
|
const nuElements = this._elementTotal;
|
||||||
// before the animations have started
|
// before the animations have started
|
||||||
// only set before styles if animation is not reversed
|
// only set before styles if animation is not reversed
|
||||||
if (this._isReverse) {
|
if (!elements || nuElements === 0 || this._isReverse) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const addClasses = this._beforeAddClasses;
|
const addClasses = this._beforeAddClasses;
|
||||||
const removeClasses = this._beforeRemoveClasses;
|
const removeClasses = this._beforeRemoveClasses;
|
||||||
|
|
||||||
let el: HTMLElement;
|
|
||||||
let elementClassList: DOMTokenList;
|
|
||||||
let prop: string;
|
let prop: string;
|
||||||
for (i = 0; i < this._elementTotal; i++) {
|
for (let i = 0; i < nuElements; i++) {
|
||||||
el = this._elements[i];
|
const el = elements[i];
|
||||||
elementClassList = el.classList;
|
const elementClassList = el.classList;
|
||||||
|
|
||||||
// css classes to add before the animation
|
// css classes to add before the animation
|
||||||
if (addClasses) {
|
if (addClasses) {
|
||||||
@ -859,6 +861,9 @@ export class Animator {
|
|||||||
let el: HTMLElement;
|
let el: HTMLElement;
|
||||||
let elementClassList: DOMTokenList;
|
let elementClassList: DOMTokenList;
|
||||||
const elements = this._elements;
|
const elements = this._elements;
|
||||||
|
if (!elements) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let prop: string;
|
let prop: string;
|
||||||
|
|
||||||
for (i = 0; i < this._elementTotal; i++) {
|
for (i = 0; i < this._elementTotal; i++) {
|
||||||
@ -1012,13 +1017,8 @@ export class Animator {
|
|||||||
/**
|
/**
|
||||||
* End the progress animation.
|
* End the progress animation.
|
||||||
*/
|
*/
|
||||||
progressEnd(shouldComplete: boolean, currentStepValue: number, dur: number) {
|
progressEnd(shouldComplete: boolean, currentStepValue: number, dur?: number) {
|
||||||
const self = this;
|
if (this._isReverse) {
|
||||||
if (dur === undefined) {
|
|
||||||
dur = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self._isReverse) {
|
|
||||||
// if the animation is going in reverse then
|
// if the animation is going in reverse then
|
||||||
// flip the step value: 0 becomes 1, 1 becomes 0
|
// flip the step value: 0 becomes 1, 1 becomes 0
|
||||||
currentStepValue = ((currentStepValue * -1) + 1);
|
currentStepValue = ((currentStepValue * -1) + 1);
|
||||||
@ -1026,28 +1026,31 @@ export class Animator {
|
|||||||
const stepValue = shouldComplete ? 1 : 0;
|
const stepValue = shouldComplete ? 1 : 0;
|
||||||
|
|
||||||
const diff = Math.abs(currentStepValue - stepValue);
|
const diff = Math.abs(currentStepValue - stepValue);
|
||||||
|
if (dur === undefined) {
|
||||||
|
dur = -1;
|
||||||
|
}
|
||||||
if (diff < 0.05) {
|
if (diff < 0.05) {
|
||||||
dur = 0;
|
dur = 0;
|
||||||
} else if (dur < 0) {
|
} else if (dur < 0) {
|
||||||
dur = self._duration;
|
dur = this._duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
self._isAsync = (dur > 30);
|
this._isAsync = (dur > 30);
|
||||||
|
|
||||||
self._progressEnd(shouldComplete, stepValue, dur, self._isAsync);
|
this._progressEnd(shouldComplete, stepValue, dur, this._isAsync);
|
||||||
|
|
||||||
if (self._isAsync) {
|
if (this._isAsync) {
|
||||||
// for the root animation only
|
// for the root animation only
|
||||||
// set the async TRANSITION END event
|
// set the async TRANSITION END event
|
||||||
// and run onFinishes when the transition ends
|
// and run onFinishes when the transition ends
|
||||||
// ******** DOM WRITE ****************
|
// ******** DOM WRITE ****************
|
||||||
self._asyncEnd(dur, shouldComplete);
|
this._asyncEnd(dur, shouldComplete);
|
||||||
|
|
||||||
// this animation has a duration so we need another RAF
|
// this animation has a duration so we need another RAF
|
||||||
// for the CSS TRANSITION properties to kick in
|
// for the CSS TRANSITION properties to kick in
|
||||||
if (!self._destroyed) {
|
if (!this._destroyed) {
|
||||||
window.requestAnimationFrame(function() {
|
window.requestAnimationFrame(() => {
|
||||||
self._playToStep(stepValue);
|
this._playToStep(stepValue);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1182,7 +1185,7 @@ export class Animator {
|
|||||||
this._writeCallbacks.length = 0;
|
this._writeCallbacks.length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.parent = null;
|
this.parent = undefined;
|
||||||
|
|
||||||
if (this._childAnimations) {
|
if (this._childAnimations) {
|
||||||
this._childAnimations.length = this._childAnimationTotal = 0;
|
this._childAnimations.length = this._childAnimationTotal = 0;
|
||||||
@ -1198,18 +1201,16 @@ export class Animator {
|
|||||||
/**
|
/**
|
||||||
* NO DOM
|
* NO DOM
|
||||||
*/
|
*/
|
||||||
_transEl(): HTMLElement {
|
_transEl(): HTMLElement|null {
|
||||||
// get the lowest level element that has an Animation
|
// get the lowest level element that has an Animation
|
||||||
let targetEl: HTMLElement;
|
|
||||||
|
|
||||||
for (let i = 0; i < this._childAnimationTotal; i++) {
|
for (let i = 0; i < this._childAnimationTotal; i++) {
|
||||||
targetEl = this._childAnimations[i]._transEl();
|
const targetEl = this._childAnimations[i]._transEl();
|
||||||
if (targetEl) {
|
if (targetEl) {
|
||||||
return targetEl;
|
return targetEl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (this._hasTweenEffect && this._hasDur && this._elementTotal ? this._elements[0] : null);
|
return (this._hasTweenEffect && this._hasDur && this._elements && this._elementTotal > 0 ? this._elements[0] : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
|
@ -1,42 +1,27 @@
|
|||||||
|
|
||||||
export let CSS_PROP = function(docEle: HTMLElement) {
|
export let CSS_PROP = function(docEle: HTMLElement) {
|
||||||
const css: {
|
|
||||||
transformProp?: string;
|
|
||||||
transitionProp?: string;
|
|
||||||
transitionDurationProp?: string;
|
|
||||||
transitionTimingFnProp?: string;
|
|
||||||
} = {};
|
|
||||||
|
|
||||||
// transform
|
// transform
|
||||||
let i: number;
|
const transformProp = [
|
||||||
let keys = ['webkitTransform', '-webkit-transform', 'webkit-transform', 'transform'];
|
'webkitTransform',
|
||||||
|
'-webkit-transform',
|
||||||
|
'webkit-transform',
|
||||||
|
'transform'
|
||||||
|
].find(key => (docEle.style as any)[key] !== undefined) || 'transform';
|
||||||
|
|
||||||
for (i = 0; i < keys.length; i++) {
|
const transitionProp = [
|
||||||
if ((docEle.style as any)[keys[i]] !== undefined) {
|
'webkitTransition',
|
||||||
css.transformProp = keys[i];
|
'transition'
|
||||||
break;
|
].find(key => (docEle.style as any)[key] !== undefined) || 'transition';
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// transition
|
|
||||||
keys = ['webkitTransition', 'transition'];
|
|
||||||
for (i = 0; i < keys.length; i++) {
|
|
||||||
if ((docEle.style as any)[keys[i]] !== undefined) {
|
|
||||||
css.transitionProp = keys[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The only prefix we care about is webkit for transitions.
|
// The only prefix we care about is webkit for transitions.
|
||||||
const prefix = css.transitionProp.indexOf('webkit') > -1 ? '-webkit-' : '';
|
const prefix = transitionProp.indexOf('webkit') > -1 ? '-webkit-' : '';
|
||||||
|
|
||||||
// transition duration
|
return {
|
||||||
css.transitionDurationProp = prefix + 'transition-duration';
|
transitionDurationProp: prefix + 'transition-duration',
|
||||||
|
transitionTimingFnProp: prefix + 'transition-timing-function',
|
||||||
// transition timing function
|
transformProp,
|
||||||
css.transitionTimingFnProp = prefix + 'transition-timing-function';
|
transitionProp
|
||||||
|
};
|
||||||
return css;
|
|
||||||
|
|
||||||
}(document.documentElement);
|
}(document.documentElement);
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ export class Button {
|
|||||||
* Get the classes based on the type
|
* Get the classes based on the type
|
||||||
* e.g. block, full, round, large
|
* e.g. block, full, round, large
|
||||||
*/
|
*/
|
||||||
function getButtonTypeClassMap(buttonType: string, type: string, mode: string): CssClassMap {
|
function getButtonTypeClassMap(buttonType: string, type: string|null, mode: string): CssClassMap {
|
||||||
if (!type) {
|
if (!type) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ export class Content {
|
|||||||
private cTop = 0;
|
private cTop = 0;
|
||||||
private cBottom = 0;
|
private cBottom = 0;
|
||||||
private dirty = false;
|
private dirty = false;
|
||||||
private scrollEl: HTMLIonScrollElement;
|
private scrollEl: HTMLIonScrollElement|null;
|
||||||
|
|
||||||
mode: string;
|
mode: string;
|
||||||
color: string;
|
color: string;
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
|
|
||||||
export class GestureController {
|
export class GestureController {
|
||||||
|
|
||||||
private gestureId = 0;
|
private gestureId = 0;
|
||||||
private requestedStart = new Map<number, number>();
|
private requestedStart = new Map<number, number>();
|
||||||
private disabledGestures = new Map<string, Set<number>>();
|
private disabledGestures = new Map<string, Set<number>>();
|
||||||
private disabledScroll = new Set<number>();
|
private disabledScroll = new Set<number>();
|
||||||
private capturedId: number = null;
|
private capturedId: number|null = null;
|
||||||
|
|
||||||
createGesture(gestureName: string, gesturePriority: number, disableScroll: boolean): GestureDelegate {
|
createGesture(gestureName: string, gesturePriority: number, disableScroll: boolean): GestureDelegate {
|
||||||
return new GestureDelegate(this, this.newID(), gestureName, gesturePriority, disableScroll);
|
return new GestureDelegate(this, this.newID(), gestureName, gesturePriority, disableScroll);
|
||||||
|
@ -21,7 +21,7 @@ export class InfiniteScroll {
|
|||||||
|
|
||||||
private thrPx = 0;
|
private thrPx = 0;
|
||||||
private thrPc = 0;
|
private thrPc = 0;
|
||||||
private scrollEl: HTMLIonScrollElement;
|
private scrollEl: HTMLIonScrollElement|null = null;
|
||||||
private didFire = false;
|
private didFire = false;
|
||||||
private isBusy = false;
|
private isBusy = false;
|
||||||
private init = false;
|
private init = false;
|
||||||
@ -219,7 +219,7 @@ export class InfiniteScroll {
|
|||||||
return (
|
return (
|
||||||
!this.disabled &&
|
!this.disabled &&
|
||||||
!this.isBusy &&
|
!this.isBusy &&
|
||||||
this.scrollEl &&
|
!!this.scrollEl &&
|
||||||
!this.isLoading);
|
!this.isLoading);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,9 @@ export class ModalController {
|
|||||||
dismiss(data?: any, role?: any, modalId = -1) {
|
dismiss(data?: any, role?: any, modalId = -1) {
|
||||||
modalId = modalId >= 0 ? modalId : getHighestId();
|
modalId = modalId >= 0 ? modalId : getHighestId();
|
||||||
const modal = modals.get(modalId);
|
const modal = modals.get(modalId);
|
||||||
|
if (!modal) {
|
||||||
|
return Promise.reject('modal does not exist');
|
||||||
|
}
|
||||||
return modal.dismiss(data, role);
|
return modal.dismiss(data, role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,9 @@ export class PickerController {
|
|||||||
dismiss(data?: any, role?: any, pickerId = -1) {
|
dismiss(data?: any, role?: any, pickerId = -1) {
|
||||||
pickerId = pickerId >= 0 ? pickerId : getHighestId();
|
pickerId = pickerId >= 0 ? pickerId : getHighestId();
|
||||||
const picker = pickers.get(pickerId);
|
const picker = pickers.get(pickerId);
|
||||||
|
if (!picker) {
|
||||||
|
return Promise.reject('picker does not exist');
|
||||||
|
}
|
||||||
return picker.dismiss(data, role);
|
return picker.dismiss(data, role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,9 @@ export class PopoverController {
|
|||||||
dismiss(data?: any, role?: any, popoverId = -1) {
|
dismiss(data?: any, role?: any, popoverId = -1) {
|
||||||
popoverId = popoverId >= 0 ? popoverId : getHighestId();
|
popoverId = popoverId >= 0 ? popoverId : getHighestId();
|
||||||
const popover = popovers.get(popoverId);
|
const popover = popovers.get(popoverId);
|
||||||
|
if (!popover) {
|
||||||
|
return Promise.reject('popover does not exist');
|
||||||
|
}
|
||||||
return popover.dismiss(data, role);
|
return popover.dismiss(data, role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import { Component, Event, EventEmitter, Listen, Prop } from '@stencil/core';
|
|||||||
tag: `ion-range-knob`
|
tag: `ion-range-knob`
|
||||||
})
|
})
|
||||||
export class RangeKnob {
|
export class RangeKnob {
|
||||||
|
|
||||||
@Prop() pressed: boolean;
|
@Prop() pressed: boolean;
|
||||||
@Prop() pin: boolean;
|
@Prop() pin: boolean;
|
||||||
@Prop() min: number;
|
@Prop() min: number;
|
||||||
|
@ -28,8 +28,7 @@ export class Refresher {
|
|||||||
private didStart = false;
|
private didStart = false;
|
||||||
private gestureConfig: any;
|
private gestureConfig: any;
|
||||||
private progress = 0;
|
private progress = 0;
|
||||||
|
private scrollEl: HTMLElement | null = null;
|
||||||
scrollEl: HTMLElement;
|
|
||||||
|
|
||||||
@Prop({ context: 'dom' }) dom: DomController;
|
@Prop({ context: 'dom' }) dom: DomController;
|
||||||
|
|
||||||
@ -116,7 +115,12 @@ export class Refresher {
|
|||||||
console.error('Make sure you use: <ion-refresher slot="fixed">');
|
console.error('Make sure you use: <ion-refresher slot="fixed">');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.scrollEl = this.el.parentElement.querySelector('ion-scroll') as HTMLElement;
|
const parentElement = this.el.parentElement;
|
||||||
|
if (!parentElement) {
|
||||||
|
console.error('ion-refresher is not attached');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.scrollEl = parentElement.querySelector('ion-scroll') as HTMLElement;
|
||||||
if (!this.scrollEl) {
|
if (!this.scrollEl) {
|
||||||
console.error('ion-refresher didn\'t attached, make sure if parent is a ion-content');
|
console.error('ion-refresher didn\'t attached, make sure if parent is a ion-content');
|
||||||
}
|
}
|
||||||
@ -183,6 +187,9 @@ export class Refresher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private onMove(detail: GestureDetail) {
|
private onMove(detail: GestureDetail) {
|
||||||
|
if (!this.scrollEl) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
// this method can get called like a bazillion times per second,
|
// this method can get called like a bazillion times per second,
|
||||||
// so it's built to be as efficient as possible, and does its
|
// so it's built to be as efficient as possible, and does its
|
||||||
// best to do any DOM read/writes only when absolutely necessary
|
// best to do any DOM read/writes only when absolutely necessary
|
||||||
@ -309,26 +316,14 @@ export class Refresher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private close(state: RefresherState, delay: string) {
|
private close(state: RefresherState, delay: string) {
|
||||||
let timer: number;
|
|
||||||
|
|
||||||
function close(ev: TransitionEvent) {
|
|
||||||
// closing is done, return to inactive state
|
|
||||||
if (ev) {
|
|
||||||
clearTimeout(timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// create fallback timer incase something goes wrong with transitionEnd event
|
||||||
|
setTimeout(() => {
|
||||||
this.state = RefresherState.Inactive;
|
this.state = RefresherState.Inactive;
|
||||||
this.progress = 0;
|
this.progress = 0;
|
||||||
this.didStart = false;
|
this.didStart = false;
|
||||||
this.setCss(0, '0ms', false, '');
|
this.setCss(0, '0ms', false, '');
|
||||||
}
|
}, 600);
|
||||||
|
|
||||||
// create fallback timer incase something goes wrong with transitionEnd event
|
|
||||||
timer = setTimeout(close.bind(this), 600);
|
|
||||||
|
|
||||||
// create transition end event on the content's scroll element
|
|
||||||
// TODO: what is this?
|
|
||||||
// this.scrollEl.onScrollElementTransitionEnd(close.bind(this));
|
|
||||||
|
|
||||||
// reset set the styles on the scroll element
|
// reset set the styles on the scroll element
|
||||||
// set that the refresh is actively cancelling/completing
|
// set that the refresh is actively cancelling/completing
|
||||||
@ -336,9 +331,6 @@ export class Refresher {
|
|||||||
this.setCss(0, '', true, delay);
|
this.setCss(0, '', true, delay);
|
||||||
|
|
||||||
// TODO: stop gesture
|
// TODO: stop gesture
|
||||||
// if (this._pointerEvents) {
|
|
||||||
// this._pointerEvents.stop();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private setCss(y: number, duration: string, overflowVisible: boolean, delay: string) {
|
private setCss(y: number, duration: string, overflowVisible: boolean, delay: string) {
|
||||||
|
@ -25,7 +25,7 @@ export class ReorderIndexes {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class ReorderGroup {
|
export class ReorderGroup {
|
||||||
private selectedItemEl: HTMLElement = null;
|
private selectedItemEl: HTMLElement|null = null;
|
||||||
private selectedItemHeight: number;
|
private selectedItemHeight: number;
|
||||||
private lastToIndex: number;
|
private lastToIndex: number;
|
||||||
private cachedHeights: number[] = [];
|
private cachedHeights: number[] = [];
|
||||||
@ -179,7 +179,7 @@ export class ReorderGroup {
|
|||||||
? children[toIndex + 1]
|
? children[toIndex + 1]
|
||||||
: children[toIndex];
|
: children[toIndex];
|
||||||
|
|
||||||
this.containerEl.insertBefore(this.selectedItemEl, ref);
|
this.containerEl.insertBefore(selectedItem, ref);
|
||||||
|
|
||||||
const len = children.length;
|
const len = children.length;
|
||||||
const transform = CSS_PROP.transformProp;
|
const transform = CSS_PROP.transformProp;
|
||||||
@ -188,9 +188,11 @@ export class ReorderGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const reorderInactive = () => {
|
const reorderInactive = () => {
|
||||||
|
if (this.selectedItemEl) {
|
||||||
this.selectedItemEl.style.transition = '';
|
this.selectedItemEl.style.transition = '';
|
||||||
this.selectedItemEl.classList.remove(ITEM_REORDER_SELECTED);
|
this.selectedItemEl.classList.remove(ITEM_REORDER_SELECTED);
|
||||||
this.selectedItemEl = null;
|
this.selectedItemEl = null;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
if (toIndex === fromIndex) {
|
if (toIndex === fromIndex) {
|
||||||
selectedItem.style.transition = 'transform 200ms ease-in-out';
|
selectedItem.style.transition = 'transform 200ms ease-in-out';
|
||||||
@ -287,7 +289,7 @@ function indexForItem(element: any): number {
|
|||||||
return element['$ionIndex'];
|
return element['$ionIndex'];
|
||||||
}
|
}
|
||||||
|
|
||||||
function findReorderItem(node: HTMLElement, container: HTMLElement): HTMLElement {
|
function findReorderItem(node: HTMLElement, container: HTMLElement): HTMLElement|null {
|
||||||
let nested = 0;
|
let nested = 0;
|
||||||
let parent;
|
let parent;
|
||||||
while (node && nested < 6) {
|
while (node && nested < 6) {
|
||||||
|
@ -21,7 +21,7 @@ export class RouterController {
|
|||||||
const base = document.querySelector('head > base');
|
const base = document.querySelector('head > base');
|
||||||
if (base) {
|
if (base) {
|
||||||
const baseURL = base.getAttribute('href');
|
const baseURL = base.getAttribute('href');
|
||||||
if (baseURL.length > 0) {
|
if (baseURL && baseURL.length > 0) {
|
||||||
this.basePrefix = baseURL;
|
this.basePrefix = baseURL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ export interface NavElement extends HTMLElement {
|
|||||||
export interface RouterEntry {
|
export interface RouterEntry {
|
||||||
path: string;
|
path: string;
|
||||||
id: any;
|
id: any;
|
||||||
segments?: string[];
|
segments: string[];
|
||||||
props?: any;
|
props?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ export class RouterSegments {
|
|||||||
|
|
||||||
next(): string {
|
next(): string {
|
||||||
if (this.segments.length > 0) {
|
if (this.segments.length > 0) {
|
||||||
return this.segments.shift();
|
return this.segments.shift() as string;
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@ -55,7 +55,7 @@ export function writeNavState(root: HTMLElement, segments: RouterSegments): Prom
|
|||||||
|
|
||||||
export function readNavState(node: HTMLElement) {
|
export function readNavState(node: HTMLElement) {
|
||||||
const stack = [];
|
const stack = [];
|
||||||
let pivot: NavElement;
|
let pivot: NavElement | null = null;
|
||||||
let state: NavState;
|
let state: NavState;
|
||||||
while (true) {
|
while (true) {
|
||||||
pivot = breadthFirstSearch(node);
|
pivot = breadthFirstSearch(node);
|
||||||
@ -85,13 +85,13 @@ function mustMatchRoute(segments: RouterSegments, routes: RouterEntries) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function matchRoute(segments: RouterSegments, routes: RouterEntries): RouterEntry {
|
export function matchRoute(segments: RouterSegments, routes: RouterEntries): RouterEntry | null {
|
||||||
if (!routes) {
|
if (!routes) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let index = 0;
|
let index = 0;
|
||||||
routes = routes.map(initRoute);
|
routes = routes.map(initRoute);
|
||||||
let selectedRoute: RouterEntry = null;
|
let selectedRoute: RouterEntry|null = null;
|
||||||
let ambiguous = false;
|
let ambiguous = false;
|
||||||
let segment: string;
|
let segment: string;
|
||||||
let l: number;
|
let l: number;
|
||||||
@ -154,7 +154,7 @@ export function parseURL(url: string): string[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const navs = ['ION-NAV', 'ION-TABS'];
|
const navs = ['ION-NAV', 'ION-TABS'];
|
||||||
export function breadthFirstSearch(root: HTMLElement): NavElement {
|
export function breadthFirstSearch(root: HTMLElement): NavElement | null {
|
||||||
if (!root) {
|
if (!root) {
|
||||||
console.error('search root is null');
|
console.error('search root is null');
|
||||||
return null;
|
return null;
|
||||||
@ -166,8 +166,8 @@ export function breadthFirstSearch(root: HTMLElement): NavElement {
|
|||||||
// first, before moving to the next level neighbours.
|
// first, before moving to the next level neighbours.
|
||||||
|
|
||||||
const queue = [root];
|
const queue = [root];
|
||||||
while (queue.length > 0) {
|
let node: HTMLElement | undefined;
|
||||||
const node = queue.shift();
|
while (node = queue.shift()) {
|
||||||
// visit node
|
// visit node
|
||||||
if (navs.indexOf(node.tagName) >= 0) {
|
if (navs.indexOf(node.tagName) >= 0) {
|
||||||
return node as NavElement;
|
return node as NavElement;
|
||||||
|
@ -345,14 +345,14 @@ export class Select {
|
|||||||
openActionSheet() {
|
openActionSheet() {
|
||||||
const interfaceOptions = {...this.interfaceOptions};
|
const interfaceOptions = {...this.interfaceOptions};
|
||||||
|
|
||||||
const actionSheetButtons: ActionSheetButton[] = this.childOpts.map(option => {
|
const actionSheetButtons = this.childOpts.map(option => {
|
||||||
return {
|
return {
|
||||||
role: (option.selected ? 'selected' : ''),
|
role: (option.selected ? 'selected' : ''),
|
||||||
text: option.textContent,
|
text: option.textContent,
|
||||||
handler: () => {
|
handler: () => {
|
||||||
this.value = option.value;
|
this.value = option.value;
|
||||||
}
|
}
|
||||||
};
|
} as ActionSheetButton;
|
||||||
});
|
});
|
||||||
|
|
||||||
actionSheetButtons.push({
|
actionSheetButtons.push({
|
||||||
@ -382,10 +382,7 @@ export class Select {
|
|||||||
const interfaceOptions = {...this.interfaceOptions};
|
const interfaceOptions = {...this.interfaceOptions};
|
||||||
|
|
||||||
const label = this.getLabel();
|
const label = this.getLabel();
|
||||||
let labelText: string = null;
|
const labelText = (label) ? label.textContent : null;
|
||||||
if (label) {
|
|
||||||
labelText = label.textContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
const alertOpts: AlertOptions = Object.assign(interfaceOptions, {
|
const alertOpts: AlertOptions = Object.assign(interfaceOptions, {
|
||||||
title: interfaceOptions.title ? interfaceOptions.title : labelText,
|
title: interfaceOptions.title ? interfaceOptions.title : labelText,
|
||||||
|
@ -62,11 +62,11 @@ export class Tabbar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected analyzeTabs() {
|
protected analyzeTabs() {
|
||||||
const tabs: HTMLIonTabButtonElement[] = Array.from(document.querySelectorAll('ion-tab-button')),
|
const tabs: HTMLIonTabButtonElement[] = Array.from(document.querySelectorAll('ion-tab-button'));
|
||||||
scrollLeft: number = this.scrollEl.scrollLeft,
|
const scrollLeft = this.scrollEl.scrollLeft;
|
||||||
tabsWidth: number = this.scrollEl.clientWidth;
|
const tabsWidth = this.scrollEl.clientWidth;
|
||||||
let previous: {tab: HTMLIonTabButtonElement, amount: number},
|
let previous: {tab: HTMLIonTabButtonElement, amount: number};
|
||||||
next: {tab: HTMLIonTabButtonElement, amount: number};
|
let next: {tab: HTMLIonTabButtonElement, amount: number};
|
||||||
|
|
||||||
tabs.forEach((tab: HTMLIonTabButtonElement) => {
|
tabs.forEach((tab: HTMLIonTabButtonElement) => {
|
||||||
const left: number = tab.offsetLeft,
|
const left: number = tab.offsetLeft,
|
||||||
@ -85,11 +85,70 @@ export class Tabbar {
|
|||||||
return {previous, next};
|
return {previous, next};
|
||||||
}
|
}
|
||||||
|
|
||||||
private getSelectedButton(): HTMLIonTabButtonElement {
|
private getSelectedButton(): HTMLIonTabButtonElement | undefined {
|
||||||
return Array.from(this.el.querySelectorAll('ion-tab-button'))
|
return Array.from(this.el.querySelectorAll('ion-tab-button'))
|
||||||
.find(btn => btn.selected);
|
.find(btn => btn.selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected scrollToSelectedButton() {
|
||||||
|
this.dom.read(() => {
|
||||||
|
const activeTabButton = this.getSelectedButton();
|
||||||
|
|
||||||
|
if (activeTabButton) {
|
||||||
|
const scrollLeft: number = this.scrollEl.scrollLeft,
|
||||||
|
tabsWidth: number = this.scrollEl.clientWidth,
|
||||||
|
left: number = activeTabButton.offsetLeft,
|
||||||
|
right: number = left + activeTabButton.offsetWidth;
|
||||||
|
|
||||||
|
let amount;
|
||||||
|
|
||||||
|
if (right > (tabsWidth + scrollLeft)) {
|
||||||
|
amount = right - tabsWidth;
|
||||||
|
} else if (left < scrollLeft) {
|
||||||
|
amount = left;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (amount !== undefined) {
|
||||||
|
this.scrollEl.scrollToPoint(amount, 0, 250).then(() => {
|
||||||
|
this.updateBoundaries();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private scrollByTab(direction: 'left' | 'right') {
|
||||||
|
this.dom.read(() => {
|
||||||
|
const {previous, next} = this.analyzeTabs(),
|
||||||
|
info = direction === 'right' ? next : previous,
|
||||||
|
amount = info && info.amount;
|
||||||
|
|
||||||
|
if (info) {
|
||||||
|
this.scrollEl.scrollToPoint(amount, 0, 250).then(() => {
|
||||||
|
this.updateBoundaries();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateBoundaries() {
|
||||||
|
this.canScrollLeft = this.scrollEl.scrollLeft !== 0;
|
||||||
|
this.canScrollRight = this.scrollEl.scrollLeft < (this.scrollEl.scrollWidth - this.scrollEl.offsetWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateHighlight() {
|
||||||
|
if (!this.highlight) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.dom.read(() => {
|
||||||
|
const btn = this.getSelectedButton();
|
||||||
|
const highlight = this.el.querySelector('div.tabbar-highlight') as HTMLElement;
|
||||||
|
if (btn && highlight) {
|
||||||
|
highlight.style.transform = `translate3d(${btn.offsetLeft}px,0,0) scaleX(${btn.offsetWidth})`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
hostData() {
|
hostData() {
|
||||||
const themedClasses = this.translucent ? createThemedClasses(this.mode, this.color, 'tabbar-translucent') : {};
|
const themedClasses = this.translucent ? createThemedClasses(this.mode, this.color, 'tabbar-translucent') : {};
|
||||||
|
|
||||||
@ -139,61 +198,4 @@ export class Tabbar {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected scrollToSelectedButton() {
|
|
||||||
this.dom.read(() => {
|
|
||||||
const activeTabButton: HTMLIonTabButtonElement = this.getSelectedButton();
|
|
||||||
|
|
||||||
if (activeTabButton) {
|
|
||||||
const scrollLeft: number = this.scrollEl.scrollLeft,
|
|
||||||
tabsWidth: number = this.scrollEl.clientWidth,
|
|
||||||
left: number = activeTabButton.offsetLeft,
|
|
||||||
right: number = left + activeTabButton.offsetWidth;
|
|
||||||
|
|
||||||
let amount;
|
|
||||||
|
|
||||||
if (right > (tabsWidth + scrollLeft)) {
|
|
||||||
amount = right - tabsWidth;
|
|
||||||
} else if (left < scrollLeft) {
|
|
||||||
amount = left;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (amount !== undefined) {
|
|
||||||
this.scrollEl.scrollToPoint(amount, 0, 250).then(() => {
|
|
||||||
this.updateBoundaries();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollByTab(direction: 'left' | 'right') {
|
|
||||||
this.dom.read(() => {
|
|
||||||
const {previous, next} = this.analyzeTabs(),
|
|
||||||
info = direction === 'right' ? next : previous,
|
|
||||||
amount = info && info.amount;
|
|
||||||
|
|
||||||
if (info) {
|
|
||||||
this.scrollEl.scrollToPoint(amount, 0, 250).then(() => {
|
|
||||||
this.updateBoundaries();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
updateBoundaries() {
|
|
||||||
this.canScrollLeft = this.scrollEl.scrollLeft !== 0;
|
|
||||||
this.canScrollRight = this.scrollEl.scrollLeft < (this.scrollEl.scrollWidth - this.scrollEl.offsetWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateHighlight() {
|
|
||||||
this.dom.read(() => {
|
|
||||||
const btn = this.getSelectedButton(),
|
|
||||||
ionTabbarHighlight: HTMLElement = this.highlight && this.el.querySelector('div.tabbar-highlight');
|
|
||||||
|
|
||||||
if (btn && ionTabbarHighlight) {
|
|
||||||
ionTabbarHighlight.style.transform = `translate3d(${btn.offsetLeft}px,0,0) scaleX(${btn.offsetWidth})`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ export class Tabs {
|
|||||||
@Element() el: HTMLElement;
|
@Element() el: HTMLElement;
|
||||||
|
|
||||||
@State() tabs: HTMLIonTabElement[] = [];
|
@State() tabs: HTMLIonTabElement[] = [];
|
||||||
@State() selectedTab: HTMLIonTabElement;
|
@State() selectedTab: HTMLIonTabElement | undefined;
|
||||||
|
|
||||||
@Prop({ context: 'config' }) config: Config;
|
@Prop({ context: 'config' }) config: Config;
|
||||||
|
|
||||||
@ -77,7 +77,8 @@ export class Tabs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidUnload() {
|
componentDidUnload() {
|
||||||
this.tabs = this.selectedTab = null;
|
this.tabs.length = 0;
|
||||||
|
this.selectedTab = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Listen('ionTabbarClick')
|
@Listen('ionTabbarClick')
|
||||||
@ -132,7 +133,7 @@ export class Tabs {
|
|||||||
* @return {HTMLIonTabElement} Returns the currently selected tab
|
* @return {HTMLIonTabElement} Returns the currently selected tab
|
||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
getSelected(): HTMLIonTabElement {
|
getSelected(): HTMLIonTabElement | undefined {
|
||||||
return this.tabs.find((tab) => tab.selected);
|
return this.tabs.find((tab) => tab.selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +191,8 @@ export class Tabs {
|
|||||||
|
|
||||||
private initSelect() {
|
private initSelect() {
|
||||||
// find pre-selected tabs
|
// find pre-selected tabs
|
||||||
const selectedTab = this.tabs.find(t => t.selected) || this.tabs.find(t => t.show && !t.disabled);
|
const selectedTab = this.tabs.find(t => t.selected) ||
|
||||||
|
this.tabs.find(t => t.show && !t.disabled);
|
||||||
|
|
||||||
// reset all tabs none is selected
|
// reset all tabs none is selected
|
||||||
for (const tab of this.tabs) {
|
for (const tab of this.tabs) {
|
||||||
@ -198,8 +200,9 @@ export class Tabs {
|
|||||||
tab.selected = false;
|
tab.selected = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (selectedTab) {
|
||||||
selectedTab.setActive(true);
|
selectedTab.setActive(true);
|
||||||
|
}
|
||||||
this.selectedTab = selectedTab;
|
this.selectedTab = selectedTab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ export class TapClick {
|
|||||||
|
|
||||||
private gestureCtrl: GestureController;
|
private gestureCtrl: GestureController;
|
||||||
|
|
||||||
private activatableEle: HTMLElement;
|
private activatableEle: HTMLElement | null;
|
||||||
private activeDefer: any;
|
private activeDefer: any;
|
||||||
|
|
||||||
private clearDefers = new WeakMap<HTMLElement, any>();
|
private clearDefers = new WeakMap<HTMLElement, any>();
|
||||||
@ -104,7 +104,7 @@ export class TapClick {
|
|||||||
this.setActivatedElement(null, ev);
|
this.setActivatedElement(null, ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
private setActivatedElement(el: HTMLElement, ev: UIEvent) {
|
private setActivatedElement(el: HTMLElement | null, ev: UIEvent) {
|
||||||
// do nothing
|
// do nothing
|
||||||
const activatableEle = this.activatableEle;
|
const activatableEle = this.activatableEle;
|
||||||
if (el && el === activatableEle) {
|
if (el && el === activatableEle) {
|
||||||
@ -157,7 +157,9 @@ export class TapClick {
|
|||||||
|
|
||||||
private removeActivated(smooth: boolean) {
|
private removeActivated(smooth: boolean) {
|
||||||
const activatableEle = this.activatableEle;
|
const activatableEle = this.activatableEle;
|
||||||
|
if (!activatableEle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const time = CLEAR_STATE_DEFERS - Date.now() + this.lastActivated;
|
const time = CLEAR_STATE_DEFERS - Date.now() + this.lastActivated;
|
||||||
if (smooth && time > 0) {
|
if (smooth && time > 0) {
|
||||||
const deferId = setTimeout(() => {
|
const deferId = setTimeout(() => {
|
||||||
|
@ -32,6 +32,9 @@ export class ToastController {
|
|||||||
dismiss(data?: any, role?: any, toastId = -1) {
|
dismiss(data?: any, role?: any, toastId = -1) {
|
||||||
toastId = toastId >= 0 ? toastId : getHighestId();
|
toastId = toastId >= 0 ? toastId : getHighestId();
|
||||||
const toast = toasts.get(toastId);
|
const toast = toasts.get(toastId);
|
||||||
|
if (!toast) {
|
||||||
|
return Promise.reject('toast does not exist');
|
||||||
|
}
|
||||||
return toast.dismiss(data, role);
|
return toast.dismiss(data, role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ export class Toast {
|
|||||||
mode: string;
|
mode: string;
|
||||||
color: string;
|
color: string;
|
||||||
|
|
||||||
private animation: Animation;
|
private animation: Animation | null;
|
||||||
|
|
||||||
@Element() private el: HTMLElement;
|
@Element() private el: HTMLElement;
|
||||||
|
|
||||||
|
@ -15,10 +15,17 @@
|
|||||||
<ion-header>
|
<ion-header>
|
||||||
<ion-toolbar>
|
<ion-toolbar>
|
||||||
<ion-title>Ionic CDN demo</ion-title>
|
<ion-title>Ionic CDN demo</ion-title>
|
||||||
|
<ion-buttons slot="end">
|
||||||
|
<ion-button onclick="addItems()">Add Items</ion-button>
|
||||||
|
</ion-buttons>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
|
|
||||||
<ion-content>
|
<ion-content>
|
||||||
|
<p>
|
||||||
|
<ion-button onclick="addItems()">Add Items</ion-button>
|
||||||
|
|
||||||
|
</p>
|
||||||
<ion-virtual-scroll id="virtual"></ion-virtual-scroll>
|
<ion-virtual-scroll id="virtual"></ion-virtual-scroll>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
|
||||||
@ -27,6 +34,10 @@
|
|||||||
</ion-app>
|
</ion-app>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
function addItems() {
|
||||||
|
const virtual = document.getElementById('virtual');
|
||||||
|
virtual.addItems()
|
||||||
|
}
|
||||||
async function init() {
|
async function init() {
|
||||||
const virtual = await document.getElementById('virtual').componentOnReady();
|
const virtual = await document.getElementById('virtual').componentOnReady();
|
||||||
virtual.itemHeight = () => 45;
|
virtual.itemHeight = () => 45;
|
||||||
|
@ -11,7 +11,7 @@ import { Cell, DomRenderFn, HeaderFn, ItemHeightFn, ItemRenderFn, NodeHeightFn,
|
|||||||
})
|
})
|
||||||
export class VirtualScroll {
|
export class VirtualScroll {
|
||||||
|
|
||||||
private scrollEl: HTMLElement;
|
private scrollEl: HTMLElement | null;
|
||||||
private range: Range = {offset: 0, length: 0};
|
private range: Range = {offset: 0, length: 0};
|
||||||
private timerUpdate: any;
|
private timerUpdate: any;
|
||||||
private heightIndex: Uint32Array;
|
private heightIndex: Uint32Array;
|
||||||
@ -145,7 +145,7 @@ export class VirtualScroll {
|
|||||||
|
|
||||||
private updateVirtualScroll() {
|
private updateVirtualScroll() {
|
||||||
// do nothing if there is a scheduled update
|
// do nothing if there is a scheduled update
|
||||||
if (!this.isEnabled) {
|
if (!this.isEnabled || !this.scrollEl) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.timerUpdate) {
|
if (this.timerUpdate) {
|
||||||
@ -155,13 +155,15 @@ export class VirtualScroll {
|
|||||||
|
|
||||||
this.dom.read(() => {
|
this.dom.read(() => {
|
||||||
let topOffset = 0;
|
let topOffset = 0;
|
||||||
let node = this.el;
|
let node: HTMLElement | null = this.el;
|
||||||
while (node !== this.scrollEl) {
|
while (node && node !== this.scrollEl) {
|
||||||
topOffset += node.offsetTop;
|
topOffset += node.offsetTop;
|
||||||
node = node.parentElement;
|
node = node.parentElement;
|
||||||
}
|
}
|
||||||
this.viewportOffset = topOffset;
|
this.viewportOffset = topOffset;
|
||||||
|
if (this.scrollEl) {
|
||||||
this.currentScrollTop = this.scrollEl.scrollTop;
|
this.currentScrollTop = this.scrollEl.scrollTop;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.dom.write(() => {
|
this.dom.write(() => {
|
||||||
@ -276,11 +278,15 @@ export class VirtualScroll {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private calcDimensions() {
|
private calcDimensions() {
|
||||||
|
if (this.scrollEl) {
|
||||||
this.viewportHeight = this.scrollEl.offsetHeight;
|
this.viewportHeight = this.scrollEl.offsetHeight;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private enableScrollEvents(shouldListen: boolean) {
|
private enableScrollEvents(shouldListen: boolean) {
|
||||||
|
if (this.scrollEl) {
|
||||||
this.isEnabled = shouldListen;
|
this.isEnabled = shouldListen;
|
||||||
this.enableListener(this, 'scroll', shouldListen, this.scrollEl);
|
this.enableListener(this, 'scroll', shouldListen, this.scrollEl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -28,7 +28,7 @@ export function createConfigController(configObj: any, platforms: PlatformConfig
|
|||||||
return fallback !== undefined ? fallback : null;
|
return fallback !== undefined ? fallback : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBoolean(key: string, fallback: boolean): boolean {
|
function getBoolean(key: string, fallback?: boolean): boolean {
|
||||||
const val = get(key);
|
const val = get(key);
|
||||||
if (val === null) {
|
if (val === null) {
|
||||||
return fallback !== undefined ? fallback : false;
|
return fallback !== undefined ? fallback : false;
|
||||||
@ -39,7 +39,7 @@ export function createConfigController(configObj: any, platforms: PlatformConfig
|
|||||||
return !!val;
|
return !!val;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNumber(key: string, fallback: number): number {
|
function getNumber(key: string, fallback?: number): number {
|
||||||
const val = parseFloat(get(key));
|
const val = parseFloat(get(key));
|
||||||
return isNaN(val) ? (fallback !== undefined ? fallback : NaN) : val;
|
return isNaN(val) ? (fallback !== undefined ? fallback : NaN) : val;
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ export interface DomController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface RafCallback {
|
export interface RafCallback {
|
||||||
(timeStamp?: number): void;
|
(timeStamp: number): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DomControllerCallback {
|
export interface DomControllerCallback {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
|
|
||||||
export function isCordova(): boolean {
|
export function isCordova(): boolean {
|
||||||
return !!(window['cordova'] || window['PhoneGap'] || window['phonegap']);
|
const win = window as any;
|
||||||
|
return !!(win['cordova'] || win['PhoneGap'] || win['phonegap']);
|
||||||
}
|
}
|
||||||
|
2
packages/core/src/index.d.ts
vendored
2
packages/core/src/index.d.ts
vendored
@ -151,7 +151,7 @@ export interface OverlayController {
|
|||||||
|
|
||||||
export interface FrameworkDelegate {
|
export interface FrameworkDelegate {
|
||||||
attachViewToDom(elementOrContainerToMountTo: any, elementOrComponentToMount: any, propsOrDataObj?: any, classesToAdd?: string[], escapeHatch?: any): Promise<FrameworkMountingData>;
|
attachViewToDom(elementOrContainerToMountTo: any, elementOrComponentToMount: any, propsOrDataObj?: any, classesToAdd?: string[], escapeHatch?: any): Promise<FrameworkMountingData>;
|
||||||
removeViewFromDom(elementOrContainerToUnmountFrom: any, elementOrComponentToUnmount: any, escapeHatch?: any): Promise<FrameworkMountingData>;
|
removeViewFromDom(elementOrContainerToUnmountFrom: any, elementOrComponentToUnmount: any, escapeHatch?: any): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FrameworkMountingData {
|
export interface FrameworkMountingData {
|
||||||
|
@ -24,13 +24,9 @@ export class DomFrameworkDelegate implements FrameworkDelegate {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
removeViewFromDom(parentElement: HTMLElement, childElement: HTMLElement): Promise<FrameworkMountingData> {
|
removeViewFromDom(parentElement: HTMLElement, childElement: HTMLElement): Promise<void> {
|
||||||
parentElement.removeChild(childElement);
|
parentElement.removeChild(childElement);
|
||||||
return Promise.resolve({
|
return Promise.resolve();
|
||||||
element: null,
|
|
||||||
data: null,
|
|
||||||
component: null
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldDeferToRouter(_elementOrComponentToMount: any): Promise<boolean> {
|
shouldDeferToRouter(_elementOrComponentToMount: any): Promise<boolean> {
|
||||||
|
@ -253,7 +253,7 @@ export const NON_TEXT_INPUT_REGEX = /^(radio|checkbox|range|file|submit|reset|co
|
|||||||
|
|
||||||
export function hasFocusedTextInput() {
|
export function hasFocusedTextInput() {
|
||||||
const activeElement = getActiveElement();
|
const activeElement = getActiveElement();
|
||||||
if (isTextInput(activeElement)) {
|
if (isTextInput(activeElement) && activeElement.parentElement) {
|
||||||
return activeElement.parentElement.querySelector(':focus') === activeElement;
|
return activeElement.parentElement.querySelector(':focus') === activeElement;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -271,7 +271,7 @@ export function reorderArray(array: any[], indexes: {from: number, to: number}):
|
|||||||
|
|
||||||
export function playAnimationAsync(animation: Animation): Promise<Animation> {
|
export function playAnimationAsync(animation: Animation): Promise<Animation> {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
animation.onFinish((ani: Animation) => {
|
animation.onFinish((ani) => {
|
||||||
resolve(ani);
|
resolve(ani);
|
||||||
});
|
});
|
||||||
animation.play();
|
animation.play();
|
||||||
@ -299,7 +299,7 @@ export function debounce(func: Function, wait = 0) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getNavAsChildIfExists(element: HTMLElement): HTMLIonNavElement {
|
export function getNavAsChildIfExists(element: HTMLElement): HTMLIonNavElement|null {
|
||||||
for (let i = 0; i < element.children.length; i++) {
|
for (let i = 0; i < element.children.length; i++) {
|
||||||
if (element.children[i].tagName.toLowerCase() === 'ion-nav') {
|
if (element.children[i].tagName.toLowerCase() === 'ion-nav') {
|
||||||
return element.children[i] as HTMLIonNavElement;
|
return element.children[i] as HTMLIonNavElement;
|
||||||
|
@ -51,7 +51,7 @@ export function getButtonClassMap(buttonType: string, mode: string): CssClassMap
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function getClassMap(classes: string): CssClassMap {
|
export function getClassMap(classes: string | undefined): CssClassMap {
|
||||||
const map: CssClassMap = {};
|
const map: CssClassMap = {};
|
||||||
if (classes) {
|
if (classes) {
|
||||||
classes
|
classes
|
||||||
|
Reference in New Issue
Block a user