mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 19:57:22 +08:00
feat(angular): build for angular 12.0 (#23970)
This commit is contained in:
@ -1,32 +1,30 @@
|
||||
import { Directive, ElementRef, HostListener, Injector } from '@angular/core';
|
||||
import { Directive, HostListener, ElementRef, Injector } from '@angular/core';
|
||||
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
import { ValueAccessor, setIonicClasses } from './value-accessor';
|
||||
|
||||
@Directive({
|
||||
/* tslint:disable-next-line:directive-selector */
|
||||
selector: 'ion-checkbox,ion-toggle',
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: BooleanValueAccessor,
|
||||
multi: true
|
||||
}
|
||||
]
|
||||
useExisting: BooleanValueAccessorDirective,
|
||||
multi: true,
|
||||
},
|
||||
],
|
||||
})
|
||||
export class BooleanValueAccessor extends ValueAccessor {
|
||||
|
||||
export class BooleanValueAccessorDirective extends ValueAccessor {
|
||||
constructor(injector: Injector, el: ElementRef) {
|
||||
super(injector, el);
|
||||
}
|
||||
|
||||
writeValue(value: any) {
|
||||
writeValue(value: any): void {
|
||||
this.el.nativeElement.checked = this.lastValue = value == null ? false : value;
|
||||
setIonicClasses(this.el);
|
||||
}
|
||||
|
||||
@HostListener('ionChange', ['$event.target'])
|
||||
_handleIonChange(el: any) {
|
||||
_handleIonChange(el: any): void {
|
||||
this.handleChangeEvent(el, el.checked);
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +1,30 @@
|
||||
import { Directive, ElementRef, HostListener, Injector } from '@angular/core';
|
||||
import { Directive, HostListener, ElementRef, Injector } from '@angular/core';
|
||||
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
import { ValueAccessor } from './value-accessor';
|
||||
|
||||
@Directive({
|
||||
/* tslint:disable-next-line:directive-selector */
|
||||
selector: 'ion-input[type=number]',
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: NumericValueAccessor,
|
||||
multi: true
|
||||
}
|
||||
]
|
||||
useExisting: NumericValueAccessorDirective,
|
||||
multi: true,
|
||||
},
|
||||
],
|
||||
})
|
||||
export class NumericValueAccessor extends ValueAccessor {
|
||||
|
||||
export class NumericValueAccessorDirective extends ValueAccessor {
|
||||
constructor(injector: Injector, el: ElementRef) {
|
||||
super(injector, el);
|
||||
}
|
||||
|
||||
@HostListener('ionChange', ['$event.target'])
|
||||
_handleIonChange(el: any) {
|
||||
_handleIonChange(el: any): void {
|
||||
this.handleChangeEvent(el, el.value);
|
||||
}
|
||||
|
||||
registerOnChange(fn: (_: number | null) => void) {
|
||||
super.registerOnChange(value => {
|
||||
registerOnChange(fn: (_: number | null) => void): void {
|
||||
super.registerOnChange((value) => {
|
||||
fn(value === '' ? null : parseFloat(value));
|
||||
});
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Directive, ElementRef, HostListener, Injector } from '@angular/core';
|
||||
import { ElementRef, Injector, Directive, HostListener } from '@angular/core';
|
||||
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
import { ValueAccessor } from './value-accessor';
|
||||
@ -9,19 +9,18 @@ import { ValueAccessor } from './value-accessor';
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: RadioValueAccessor,
|
||||
multi: true
|
||||
}
|
||||
]
|
||||
useExisting: RadioValueAccessorDirective,
|
||||
multi: true,
|
||||
},
|
||||
],
|
||||
})
|
||||
export class RadioValueAccessor extends ValueAccessor {
|
||||
|
||||
export class RadioValueAccessorDirective extends ValueAccessor {
|
||||
constructor(injector: Injector, el: ElementRef) {
|
||||
super(injector, el);
|
||||
}
|
||||
|
||||
@HostListener('ionSelect', ['$event.target'])
|
||||
_handleIonSelect(el: any) {
|
||||
_handleIonSelect(el: any): void {
|
||||
this.handleChangeEvent(el, el.checked);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Directive, ElementRef, HostListener, Injector } from '@angular/core';
|
||||
import { ElementRef, Injector, Directive, HostListener } from '@angular/core';
|
||||
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
import { ValueAccessor } from './value-accessor';
|
||||
@ -9,19 +9,18 @@ import { ValueAccessor } from './value-accessor';
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: SelectValueAccessor,
|
||||
multi: true
|
||||
}
|
||||
]
|
||||
useExisting: SelectValueAccessorDirective,
|
||||
multi: true,
|
||||
},
|
||||
],
|
||||
})
|
||||
export class SelectValueAccessor extends ValueAccessor {
|
||||
|
||||
export class SelectValueAccessorDirective extends ValueAccessor {
|
||||
constructor(injector: Injector, el: ElementRef) {
|
||||
super(injector, el);
|
||||
}
|
||||
|
||||
@HostListener('ionChange', ['$event.target'])
|
||||
_handleChangeEvent(el: any) {
|
||||
_handleChangeEvent(el: any): void {
|
||||
this.handleChangeEvent(el, el.value);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Directive, ElementRef, HostListener, Injector } from '@angular/core';
|
||||
import { ElementRef, Injector, Directive, HostListener } from '@angular/core';
|
||||
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
import { ValueAccessor } from './value-accessor';
|
||||
@ -9,19 +9,18 @@ import { ValueAccessor } from './value-accessor';
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: TextValueAccessor,
|
||||
multi: true
|
||||
}
|
||||
]
|
||||
useExisting: TextValueAccessorDirective,
|
||||
multi: true,
|
||||
},
|
||||
],
|
||||
})
|
||||
export class TextValueAccessor extends ValueAccessor {
|
||||
|
||||
export class TextValueAccessorDirective extends ValueAccessor {
|
||||
constructor(injector: Injector, el: ElementRef) {
|
||||
super(injector, el);
|
||||
}
|
||||
|
||||
@HostListener('ionChange', ['$event.target'])
|
||||
_handleInputEvent(el: any) {
|
||||
_handleInputEvent(el: any): void {
|
||||
this.handleChangeEvent(el, el.value);
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,23 @@
|
||||
import { AfterViewInit, ElementRef, HostListener, Injector, OnDestroy, Type } from '@angular/core';
|
||||
import { AfterViewInit, ElementRef, Injector, OnDestroy, Directive, HostListener } from '@angular/core';
|
||||
import { ControlValueAccessor, NgControl } from '@angular/forms';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
import { raf } from '../../util/util';
|
||||
|
||||
@Directive()
|
||||
export class ValueAccessor implements ControlValueAccessor, AfterViewInit, OnDestroy {
|
||||
|
||||
private onChange: (value: any) => void = () => {/**/};
|
||||
private onTouched: () => void = () => {/**/};
|
||||
private onChange: (value: any) => void = () => {
|
||||
/**/
|
||||
};
|
||||
private onTouched: () => void = () => {
|
||||
/**/
|
||||
};
|
||||
protected lastValue: any;
|
||||
private statusChanges?: Subscription;
|
||||
|
||||
constructor(protected injector: Injector, protected el: ElementRef) {}
|
||||
|
||||
writeValue(value: any) {
|
||||
writeValue(value: any): void {
|
||||
/**
|
||||
* TODO for Ionic 6:
|
||||
* Change `value == null ? '' : value;`
|
||||
@ -25,7 +29,7 @@ export class ValueAccessor implements ControlValueAccessor, AfterViewInit, OnDes
|
||||
setIonicClasses(this.el);
|
||||
}
|
||||
|
||||
handleChangeEvent(el: HTMLElement, value: any) {
|
||||
handleChangeEvent(el: HTMLElement, value: any): void {
|
||||
if (el === this.el.nativeElement) {
|
||||
if (value !== this.lastValue) {
|
||||
this.lastValue = value;
|
||||
@ -36,38 +40,42 @@ export class ValueAccessor implements ControlValueAccessor, AfterViewInit, OnDes
|
||||
}
|
||||
|
||||
@HostListener('ionBlur', ['$event.target'])
|
||||
_handleBlurEvent(el: any) {
|
||||
_handleBlurEvent(el: any): void {
|
||||
if (el === this.el.nativeElement) {
|
||||
this.onTouched();
|
||||
setIonicClasses(this.el);
|
||||
}
|
||||
}
|
||||
|
||||
registerOnChange(fn: (value: any) => void) {
|
||||
registerOnChange(fn: (value: any) => void): void {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: () => void) {
|
||||
registerOnTouched(fn: () => void): void {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
|
||||
setDisabledState(isDisabled: boolean) {
|
||||
setDisabledState(isDisabled: boolean): void {
|
||||
this.el.nativeElement.disabled = isDisabled;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
ngOnDestroy(): void {
|
||||
if (this.statusChanges) {
|
||||
this.statusChanges.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
ngAfterViewInit(): void {
|
||||
let ngControl;
|
||||
try {
|
||||
ngControl = this.injector.get<NgControl>(NgControl as Type<NgControl>);
|
||||
} catch { /* No FormControl or ngModel binding */ }
|
||||
ngControl = this.injector.get<NgControl>(NgControl);
|
||||
} catch {
|
||||
/* No FormControl or ngModel binding */
|
||||
}
|
||||
|
||||
if (!ngControl) { return; }
|
||||
if (!ngControl) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Listen for changes in validity, disabled, or pending states
|
||||
if (ngControl.statusChanges) {
|
||||
@ -84,15 +92,15 @@ export class ValueAccessor implements ControlValueAccessor, AfterViewInit, OnDes
|
||||
* This patches the methods to manually sync
|
||||
* the classes until this feature is implemented in Angular.
|
||||
*/
|
||||
const formControl = ngControl.control;
|
||||
const formControl = ngControl.control as any;
|
||||
if (formControl) {
|
||||
const methodsToPatch = ['markAsTouched', 'markAllAsTouched', 'markAsUntouched', 'markAsDirty', 'markAsPristine'];
|
||||
methodsToPatch.forEach(method => {
|
||||
if (formControl[method]) {
|
||||
const oldFn = formControl[method].bind(formControl);
|
||||
formControl[method] = (...params) => {
|
||||
oldFn(...params);
|
||||
setIonicClasses(this.el);
|
||||
methodsToPatch.forEach((method) => {
|
||||
if (formControl.get(method)) {
|
||||
const oldFn = formControl[method].bind(formControl);
|
||||
formControl[method] = (...params: any[]) => {
|
||||
oldFn(...params);
|
||||
setIonicClasses(this.el);
|
||||
};
|
||||
}
|
||||
});
|
||||
@ -100,7 +108,7 @@ export class ValueAccessor implements ControlValueAccessor, AfterViewInit, OnDes
|
||||
}
|
||||
}
|
||||
|
||||
export const setIonicClasses = (element: ElementRef) => {
|
||||
export const setIonicClasses = (element: ElementRef): void => {
|
||||
raf(() => {
|
||||
const input = element.nativeElement as HTMLElement;
|
||||
const classes = getClasses(input);
|
||||
@ -127,16 +135,11 @@ const getClasses = (element: HTMLElement) => {
|
||||
|
||||
const setClasses = (element: HTMLElement, classes: string[]) => {
|
||||
const classList = element.classList;
|
||||
[
|
||||
'ion-valid',
|
||||
'ion-invalid',
|
||||
'ion-touched',
|
||||
'ion-untouched',
|
||||
'ion-dirty',
|
||||
'ion-pristine'
|
||||
].forEach(c => classList.remove(c));
|
||||
['ion-valid', 'ion-invalid', 'ion-touched', 'ion-untouched', 'ion-dirty', 'ion-pristine'].forEach((c) =>
|
||||
classList.remove(c)
|
||||
);
|
||||
|
||||
classes.forEach(c => classList.add(c));
|
||||
classes.forEach((c) => classList.add(c));
|
||||
};
|
||||
|
||||
const startsWith = (input: string, search: string): boolean => {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Directive, HostListener, Optional } from '@angular/core';
|
||||
import { Directive, HostListener, Input, Optional } from '@angular/core';
|
||||
import { AnimationBuilder } from '@ionic/core';
|
||||
|
||||
import { Config } from '../../providers/config';
|
||||
@ -8,11 +8,12 @@ import { IonRouterOutlet } from './ion-router-outlet';
|
||||
|
||||
@Directive({
|
||||
selector: 'ion-back-button',
|
||||
inputs: ['defaultHref', 'routerAnimation'],
|
||||
})
|
||||
export class IonBackButtonDelegate {
|
||||
|
||||
export class IonBackButtonDelegateDirective {
|
||||
@Input()
|
||||
defaultHref: string | undefined | null;
|
||||
|
||||
@Input()
|
||||
routerAnimation?: AnimationBuilder;
|
||||
|
||||
constructor(
|
||||
@ -25,10 +26,10 @@ export class IonBackButtonDelegate {
|
||||
* @internal
|
||||
*/
|
||||
@HostListener('click', ['$event'])
|
||||
onClick(ev: Event) {
|
||||
onClick(ev: Event): void {
|
||||
const defaultHref = this.defaultHref || this.config.get('backButtonDefaultHref');
|
||||
|
||||
if (this.routerOutlet && this.routerOutlet.canGoBack()) {
|
||||
if (this.routerOutlet?.canGoBack()) {
|
||||
this.navCtrl.setDirection('back', undefined, undefined, this.routerAnimation);
|
||||
this.routerOutlet.pop();
|
||||
ev.preventDefault();
|
||||
|
@ -1,11 +1,26 @@
|
||||
import { Location } from '@angular/common';
|
||||
import { Attribute, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, EventEmitter, Injector, NgZone, OnDestroy, OnInit, Optional, Output, SkipSelf, ViewContainerRef } from '@angular/core';
|
||||
import { ActivatedRoute, ChildrenOutletContexts, OutletContext, PRIMARY_OUTLET, Router } from '@angular/router';
|
||||
import {
|
||||
ComponentFactoryResolver,
|
||||
ComponentRef,
|
||||
ElementRef,
|
||||
Injector,
|
||||
NgZone,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
ViewContainerRef,
|
||||
Attribute,
|
||||
Directive,
|
||||
EventEmitter,
|
||||
Optional,
|
||||
Output,
|
||||
SkipSelf,
|
||||
} from '@angular/core';
|
||||
import { OutletContext, Router, ActivatedRoute, ChildrenOutletContexts, PRIMARY_OUTLET } from '@angular/router';
|
||||
import { componentOnReady } from '@ionic/core';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { Observable, BehaviorSubject } from 'rxjs';
|
||||
import { distinctUntilChanged, filter, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { AnimationBuilder } from '../../';
|
||||
import { AnimationBuilder } from '../../ionic-core';
|
||||
import { Config } from '../../providers/config';
|
||||
import { NavController } from '../../providers/nav-controller';
|
||||
|
||||
@ -15,8 +30,10 @@ import { RouteView, getUrl } from './stack-utils';
|
||||
@Directive({
|
||||
selector: 'ion-router-outlet',
|
||||
exportAs: 'outlet',
|
||||
inputs: ['animated', 'animation', 'swipeGesture']
|
||||
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
|
||||
inputs: ['animated', 'animation', 'swipeGesture'],
|
||||
})
|
||||
// eslint-disable-next-line @angular-eslint/directive-class-suffix
|
||||
export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
nativeEl: HTMLIonRouterOutletElement;
|
||||
|
||||
@ -37,7 +54,9 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
tabsPrefix: string | undefined;
|
||||
|
||||
@Output() stackEvents = new EventEmitter<any>();
|
||||
// eslint-disable-next-line @angular-eslint/no-output-rename
|
||||
@Output('activate') activateEvents = new EventEmitter<any>();
|
||||
// eslint-disable-next-line @angular-eslint/no-output-rename
|
||||
@Output('deactivate') deactivateEvents = new EventEmitter<any>();
|
||||
|
||||
set animation(animation: AnimationBuilder) {
|
||||
@ -51,11 +70,13 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
set swipeGesture(swipe: boolean) {
|
||||
this._swipeGesture = swipe;
|
||||
|
||||
this.nativeEl.swipeHandler = swipe ? {
|
||||
canStart: () => this.stackCtrl.canGoBack(1) && !this.stackCtrl.hasRunningTask(),
|
||||
onStart: () => this.stackCtrl.startBackTransition(),
|
||||
onEnd: shouldContinue => this.stackCtrl.endBackTransition(shouldContinue)
|
||||
} : undefined;
|
||||
this.nativeEl.swipeHandler = swipe
|
||||
? {
|
||||
canStart: () => this.stackCtrl.canGoBack(1) && !this.stackCtrl.hasRunningTask(),
|
||||
onStart: () => this.stackCtrl.startBackTransition(),
|
||||
onEnd: (shouldContinue) => this.stackCtrl.endBackTransition(shouldContinue),
|
||||
}
|
||||
: undefined;
|
||||
}
|
||||
|
||||
constructor(
|
||||
@ -93,12 +114,12 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
// If the outlet was not instantiated at the time the route got activated we need to populate
|
||||
// the outlet when it is initialized (ie inside a NgIf)
|
||||
const context = this.getContext();
|
||||
if (context && context.route) {
|
||||
if (context?.route) {
|
||||
this.activateWith(context.route, context.resolver || null);
|
||||
}
|
||||
}
|
||||
|
||||
new Promise(resolve => componentOnReady(this.nativeEl, resolve)).then(() => {
|
||||
new Promise((resolve) => componentOnReady(this.nativeEl, resolve)).then(() => {
|
||||
if (this._swipeGesture === undefined) {
|
||||
this.swipeGesture = this.config.getBoolean('swipeBackEnabled', (this.nativeEl as any).mode === 'ios');
|
||||
}
|
||||
@ -109,7 +130,7 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
return !!this.activated;
|
||||
}
|
||||
|
||||
get component(): object {
|
||||
get component(): Record<string, unknown> {
|
||||
if (!this.activated) {
|
||||
throw new Error('Outlet is not activated');
|
||||
}
|
||||
@ -140,13 +161,15 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
/**
|
||||
* Called when the `RouteReuseStrategy` instructs to re-attach a previously detached subtree
|
||||
*/
|
||||
attach(_ref: ComponentRef<any>, _activatedRoute: ActivatedRoute) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
attach(_ref: ComponentRef<any>, _activatedRoute: ActivatedRoute): void {
|
||||
throw new Error('incompatible reuse strategy');
|
||||
}
|
||||
|
||||
deactivate(): void {
|
||||
if (this.activated) {
|
||||
if (this.activatedView) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const context = this.getContext()!;
|
||||
this.activatedView.savedData = new Map(context.children['contexts']);
|
||||
|
||||
@ -172,7 +195,7 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
const contextSnapshot = context.route.snapshot;
|
||||
|
||||
this.activatedView.savedExtras.queryParams = contextSnapshot.queryParams;
|
||||
this.activatedView.savedExtras.fragment = contextSnapshot.fragment;
|
||||
(this.activatedView.savedExtras.fragment as string | null) = contextSnapshot.fragment;
|
||||
}
|
||||
}
|
||||
const c = this.component;
|
||||
@ -183,7 +206,7 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
activateWith(activatedRoute: ActivatedRoute, resolver: ComponentFactoryResolver | null) {
|
||||
activateWith(activatedRoute: ActivatedRoute, resolver: ComponentFactoryResolver | null): void {
|
||||
if (this.isActivated) {
|
||||
throw new Error('Cannot activate an already activated outlet');
|
||||
}
|
||||
@ -196,6 +219,7 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
const saved = enteringView.savedData;
|
||||
if (saved) {
|
||||
// self-restore
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const context = this.getContext()!;
|
||||
context.children['contexts'] = saved;
|
||||
}
|
||||
@ -203,6 +227,7 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
this.updateActivatedRouteProxy(cmpRef.instance, activatedRoute);
|
||||
} else {
|
||||
const snapshot = (activatedRoute as any)._futureSnapshot;
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const component = snapshot.routeConfig!.component as any;
|
||||
resolver = resolver || this.resolver;
|
||||
|
||||
@ -230,7 +255,7 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
}
|
||||
|
||||
this.activatedView = enteringView;
|
||||
this.stackCtrl.setActive(enteringView).then(data => {
|
||||
this.stackCtrl.setActive(enteringView).then((data) => {
|
||||
this.navCtrl.setTopOutlet(this);
|
||||
this.activateEvents.emit(cmpRef.instance);
|
||||
this.stackEvents.emit(data);
|
||||
@ -313,11 +338,11 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
private proxyObservable(component$: Observable<any>, path: string): Observable<any> {
|
||||
return component$.pipe(
|
||||
// First wait until the component instance is pushed
|
||||
filter(component => !!component),
|
||||
switchMap(component =>
|
||||
filter((component) => !!component),
|
||||
switchMap((component) =>
|
||||
this.currentActivatedRoute$.pipe(
|
||||
filter(current => current !== null && current.component === component),
|
||||
switchMap(current => current && (current.activatedRoute as any)[path]),
|
||||
filter((current) => current !== null && current.component === component),
|
||||
switchMap((current) => current && (current.activatedRoute as any)[path]),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
)
|
||||
@ -344,11 +369,7 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
}
|
||||
|
||||
class OutletInjector implements Injector {
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private childContexts: ChildrenOutletContexts,
|
||||
private parent: Injector
|
||||
) { }
|
||||
constructor(private route: ActivatedRoute, private childContexts: ChildrenOutletContexts, private parent: Injector) {}
|
||||
|
||||
get(token: any, notFoundValue?: any): any {
|
||||
if (token === ActivatedRoute) {
|
||||
@ -359,7 +380,6 @@ class OutletInjector implements Injector {
|
||||
return this.childContexts;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line
|
||||
return this.parent.get(token, notFoundValue);
|
||||
}
|
||||
}
|
||||
|
@ -8,54 +8,53 @@ import { StackEvent } from './stack-utils';
|
||||
|
||||
@Component({
|
||||
selector: 'ion-tabs',
|
||||
template: `
|
||||
<ng-content select="[slot=top]"></ng-content>
|
||||
template: ` <ng-content select="[slot=top]"></ng-content>
|
||||
<div class="tabs-inner">
|
||||
<ion-router-outlet #outlet tabs="true" (stackEvents)="onPageSelected($event)"></ion-router-outlet>
|
||||
</div>
|
||||
<ng-content></ng-content>`,
|
||||
styles: [`
|
||||
:host {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
styles: [
|
||||
`
|
||||
:host {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
||||
flex-direction: column;
|
||||
flex-direction: column;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
contain: layout size style;
|
||||
z-index: $z-index-page-container;
|
||||
}
|
||||
.tabs-inner {
|
||||
position: relative;
|
||||
contain: layout size style;
|
||||
z-index: $z-index-page-container;
|
||||
}
|
||||
.tabs-inner {
|
||||
position: relative;
|
||||
|
||||
flex: 1;
|
||||
flex: 1;
|
||||
|
||||
contain: layout size style;
|
||||
}`
|
||||
]
|
||||
contain: layout size style;
|
||||
}
|
||||
`,
|
||||
],
|
||||
})
|
||||
// eslint-disable-next-line @angular-eslint/component-class-suffix
|
||||
export class IonTabs {
|
||||
|
||||
@ViewChild('outlet', { read: IonRouterOutlet, static: false }) outlet: IonRouterOutlet;
|
||||
@ContentChild(IonTabBar, { static: false }) tabBar: IonTabBar | undefined;
|
||||
|
||||
@Output() ionTabsWillChange = new EventEmitter<{ tab: string }>();
|
||||
@Output() ionTabsDidChange = new EventEmitter<{ tab: string }>();
|
||||
|
||||
constructor(
|
||||
private navCtrl: NavController,
|
||||
) { }
|
||||
constructor(private navCtrl: NavController) {}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
onPageSelected(detail: StackEvent) {
|
||||
onPageSelected(detail: StackEvent): void {
|
||||
const stackId = detail.enteringView.stackId;
|
||||
if (detail.tabSwitch && stackId !== undefined) {
|
||||
if (this.tabBar) {
|
||||
@ -87,9 +86,9 @@ export class IonTabs {
|
||||
* to the default tabRootUrl
|
||||
*/
|
||||
@HostListener('ionTabButtonClick', ['$event'])
|
||||
select(tabOrEvent: string | CustomEvent) {
|
||||
select(tabOrEvent: string | CustomEvent): Promise<boolean> | undefined {
|
||||
const isTabString = typeof tabOrEvent === 'string';
|
||||
const tab = (isTabString) ? tabOrEvent : (tabOrEvent as CustomEvent).detail.tab;
|
||||
const tab = isTabString ? tabOrEvent : (tabOrEvent as CustomEvent).detail.tab;
|
||||
const alreadySelected = this.outlet.getActiveStackId() === tab;
|
||||
const tabRootUrl = `${this.outlet.tabsPrefix}/${tab}`;
|
||||
|
||||
@ -108,12 +107,14 @@ export class IonTabs {
|
||||
const activeView = this.outlet.getLastRouteView(activeStackId);
|
||||
|
||||
// If on root tab, do not navigate to root tab again
|
||||
if (activeView.url === tabRootUrl) { return; }
|
||||
if (activeView?.url === tabRootUrl) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rootView = this.outlet.getRootView(tab);
|
||||
const navigationExtras = rootView && tabRootUrl === rootView.url && rootView.savedExtras;
|
||||
return this.navCtrl.navigateRoot(tabRootUrl, {
|
||||
...(navigationExtras),
|
||||
...navigationExtras,
|
||||
animated: true,
|
||||
animationDirection: 'back',
|
||||
});
|
||||
@ -123,11 +124,11 @@ export class IonTabs {
|
||||
* If there is a lastRoute, goto that, otherwise goto the fallback url of the
|
||||
* selected tab
|
||||
*/
|
||||
const url = lastRoute && lastRoute.url || tabRootUrl;
|
||||
const navigationExtras = lastRoute && lastRoute.savedExtras;
|
||||
const url = lastRoute?.url || tabRootUrl;
|
||||
const navigationExtras = lastRoute?.savedExtras;
|
||||
|
||||
return this.navCtrl.navigateRoot(url, {
|
||||
...(navigationExtras),
|
||||
...navigationExtras,
|
||||
animated: true,
|
||||
animationDirection: 'back',
|
||||
});
|
||||
|
@ -1,15 +1,30 @@
|
||||
import { ComponentFactoryResolver, Directive, ElementRef, Injector, ViewContainerRef } from '@angular/core';
|
||||
import { ComponentFactoryResolver, ElementRef, Injector, ViewContainerRef, Directive } from '@angular/core';
|
||||
|
||||
import { AngularDelegate } from '../../providers/angular-delegate';
|
||||
import { ProxyCmp, proxyOutputs } from '../angular-component-lib/utils';
|
||||
|
||||
@ProxyCmp({
|
||||
inputs: ['animated', 'animation', 'root', 'rootParams', 'swipeGesture'],
|
||||
methods: ['push', 'insert', 'insertPages', 'pop', 'popTo', 'popToRoot', 'removeIndex', 'setRoot', 'setPages', 'getActive', 'getByIndex', 'canGoBack', 'getPrevious']
|
||||
methods: [
|
||||
'push',
|
||||
'insert',
|
||||
'insertPages',
|
||||
'pop',
|
||||
'popTo',
|
||||
'popToRoot',
|
||||
'removeIndex',
|
||||
'setRoot',
|
||||
'setPages',
|
||||
'getActive',
|
||||
'getByIndex',
|
||||
'canGoBack',
|
||||
'getPrevious',
|
||||
],
|
||||
})
|
||||
@Directive({
|
||||
selector: 'ion-nav'
|
||||
selector: 'ion-nav',
|
||||
})
|
||||
// eslint-disable-next-line @angular-eslint/directive-class-suffix
|
||||
export class NavDelegate {
|
||||
protected el: HTMLElement;
|
||||
constructor(
|
||||
@ -21,6 +36,6 @@ export class NavDelegate {
|
||||
) {
|
||||
this.el = ref.nativeElement;
|
||||
ref.nativeElement.delegate = angularDelegate.create(resolver, injector, location);
|
||||
proxyOutputs(this, this.el, ['ionNavDidChange' , 'ionNavWillChange' ]);
|
||||
proxyOutputs(this, this.el, ['ionNavDidChange', 'ionNavWillChange']);
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,7 @@
|
||||
* ```
|
||||
*/
|
||||
export class NavParams {
|
||||
|
||||
constructor(public data: {[key: string]: any} = {}) {}
|
||||
constructor(public data: { [key: string]: any } = {}) {}
|
||||
|
||||
/**
|
||||
* Get the value of a nav-parameter for the current view
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { LocationStrategy } from '@angular/common';
|
||||
import { Directive, ElementRef, HostListener, Optional } from '@angular/core';
|
||||
import { ElementRef, OnChanges, OnDestroy, OnInit, Directive, HostListener, Input, Optional } from '@angular/core';
|
||||
import { Router, RouterLink } from '@angular/router';
|
||||
import { AnimationBuilder, RouterDirection } from '@ionic/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
@ -8,13 +8,14 @@ import { NavController } from '../../providers/nav-controller';
|
||||
|
||||
@Directive({
|
||||
selector: '[routerLink]',
|
||||
inputs: ['routerDirection', 'routerAnimation']
|
||||
})
|
||||
export class RouterLinkDelegate {
|
||||
|
||||
export class RouterLinkDelegateDirective implements OnInit, OnChanges, OnDestroy {
|
||||
private subscription?: Subscription;
|
||||
|
||||
@Input()
|
||||
routerDirection: RouterDirection = 'forward';
|
||||
|
||||
@Input()
|
||||
routerAnimation?: AnimationBuilder;
|
||||
|
||||
constructor(
|
||||
@ -22,18 +23,18 @@ export class RouterLinkDelegate {
|
||||
private navCtrl: NavController,
|
||||
private elementRef: ElementRef,
|
||||
private router: Router,
|
||||
@Optional() private routerLink?: RouterLink,
|
||||
) { }
|
||||
@Optional() private routerLink?: RouterLink
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
ngOnInit(): void {
|
||||
this.updateTargetUrlAndHref();
|
||||
}
|
||||
|
||||
ngOnChanges(): any {
|
||||
ngOnChanges(): void {
|
||||
this.updateTargetUrlAndHref();
|
||||
}
|
||||
|
||||
ngOnDestroy(): any {
|
||||
ngOnDestroy(): void {
|
||||
if (this.subscription) {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
@ -50,7 +51,7 @@ export class RouterLinkDelegate {
|
||||
* @internal
|
||||
*/
|
||||
@HostListener('click', ['$event'])
|
||||
onClick(ev: UIEvent) {
|
||||
onClick(ev: UIEvent): void {
|
||||
this.navCtrl.setDirection(this.routerDirection, undefined, undefined, this.routerAnimation);
|
||||
ev.preventDefault();
|
||||
}
|
||||
|
@ -6,10 +6,18 @@ import { AnimationBuilder, RouterDirection } from '@ionic/core';
|
||||
import { bindLifecycleEvents } from '../../providers/angular-delegate';
|
||||
import { NavController } from '../../providers/nav-controller';
|
||||
|
||||
import { RouteView, StackEvent, computeStackId, destroyView, getUrl, insertView, isTabSwitch, toSegments } from './stack-utils';
|
||||
import {
|
||||
RouteView,
|
||||
StackEvent,
|
||||
computeStackId,
|
||||
destroyView,
|
||||
getUrl,
|
||||
insertView,
|
||||
isTabSwitch,
|
||||
toSegments,
|
||||
} from './stack-utils';
|
||||
|
||||
export class StackController {
|
||||
|
||||
private views: RouteView[] = [];
|
||||
private runningTask?: Promise<any>;
|
||||
private skipTransition = false;
|
||||
@ -30,7 +38,7 @@ export class StackController {
|
||||
|
||||
createView(ref: ComponentRef<any>, activatedRoute: ActivatedRoute): RouteView {
|
||||
const url = getUrl(this.router, activatedRoute);
|
||||
const element = (ref && ref.location && ref.location.nativeElement) as HTMLElement;
|
||||
const element = ref?.location?.nativeElement as HTMLElement;
|
||||
const unlistenEvents = bindLifecycleEvents(this.zone, ref.instance, element);
|
||||
return {
|
||||
id: this.nextId++,
|
||||
@ -44,7 +52,7 @@ export class StackController {
|
||||
|
||||
getExistingView(activatedRoute: ActivatedRoute): RouteView | undefined {
|
||||
const activatedUrlKey = getUrl(this.router, activatedRoute);
|
||||
const view = this.views.find(vw => vw.url === activatedUrlKey);
|
||||
const view = this.views.find((vw) => vw.url === activatedUrlKey);
|
||||
if (view) {
|
||||
view.ref.changeDetectorRef.reattach();
|
||||
}
|
||||
@ -65,17 +73,14 @@ export class StackController {
|
||||
|
||||
let currentNavigation;
|
||||
|
||||
const router = (this.router as any);
|
||||
const router = this.router as any;
|
||||
|
||||
// Angular >= 7.2.0
|
||||
if (router.getCurrentNavigation) {
|
||||
currentNavigation = router.getCurrentNavigation();
|
||||
|
||||
// Angular < 7.2.0
|
||||
} else if (
|
||||
router.navigations &&
|
||||
router.navigations.value
|
||||
) {
|
||||
} else if (router.navigations?.value) {
|
||||
currentNavigation = router.navigations.value;
|
||||
}
|
||||
|
||||
@ -86,11 +91,7 @@ export class StackController {
|
||||
* we remove the last item
|
||||
* from our views stack
|
||||
*/
|
||||
if (
|
||||
currentNavigation &&
|
||||
currentNavigation.extras &&
|
||||
currentNavigation.extras.replaceUrl
|
||||
) {
|
||||
if (currentNavigation?.extras?.replaceUrl) {
|
||||
if (this.views.length > 0) {
|
||||
this.views.splice(-1, 1);
|
||||
}
|
||||
@ -114,12 +115,7 @@ export class StackController {
|
||||
* provided another animation.
|
||||
*/
|
||||
const customAnimation = enteringView.animationBuilder;
|
||||
if (
|
||||
animationBuilder === undefined &&
|
||||
direction === 'back' &&
|
||||
!tabSwitch &&
|
||||
customAnimation !== undefined
|
||||
) {
|
||||
if (animationBuilder === undefined && direction === 'back' && !tabSwitch && customAnimation !== undefined) {
|
||||
animationBuilder = customAnimation;
|
||||
}
|
||||
|
||||
@ -148,7 +144,7 @@ export class StackController {
|
||||
enteringView,
|
||||
direction,
|
||||
animation,
|
||||
tabSwitch
|
||||
tabSwitch,
|
||||
}));
|
||||
});
|
||||
});
|
||||
@ -158,7 +154,7 @@ export class StackController {
|
||||
return this.getStack(stackId).length > deep;
|
||||
}
|
||||
|
||||
pop(deep: number, stackId = this.getActiveStackId()) {
|
||||
pop(deep: number, stackId = this.getActiveStackId()): Promise<boolean> {
|
||||
return this.zone.run(() => {
|
||||
const views = this.getStack(stackId);
|
||||
if (views.length <= deep) {
|
||||
@ -170,13 +166,7 @@ export class StackController {
|
||||
const viewSavedData = view.savedData;
|
||||
if (viewSavedData) {
|
||||
const primaryOutlet = viewSavedData.get('primary');
|
||||
if (
|
||||
primaryOutlet &&
|
||||
primaryOutlet.route &&
|
||||
primaryOutlet.route._routerState &&
|
||||
primaryOutlet.route._routerState.snapshot &&
|
||||
primaryOutlet.route._routerState.snapshot.url
|
||||
) {
|
||||
if (primaryOutlet?.route?._routerState?.snapshot.url) {
|
||||
url = primaryOutlet.route._routerState.snapshot.url;
|
||||
}
|
||||
}
|
||||
@ -185,7 +175,7 @@ export class StackController {
|
||||
});
|
||||
}
|
||||
|
||||
startBackTransition() {
|
||||
startBackTransition(): Promise<boolean> | Promise<void> {
|
||||
const leavingView = this.activeView;
|
||||
if (leavingView) {
|
||||
const views = this.getStack(leavingView.stackId);
|
||||
@ -206,7 +196,7 @@ export class StackController {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
endBackTransition(shouldComplete: boolean) {
|
||||
endBackTransition(shouldComplete: boolean): void {
|
||||
if (shouldComplete) {
|
||||
this.skipTransition = true;
|
||||
this.pop(1);
|
||||
@ -215,7 +205,7 @@ export class StackController {
|
||||
}
|
||||
}
|
||||
|
||||
getLastUrl(stackId?: string) {
|
||||
getLastUrl(stackId?: string): RouteView | undefined {
|
||||
const views = this.getStack(stackId);
|
||||
return views.length > 0 ? views[views.length - 1] : undefined;
|
||||
}
|
||||
@ -223,7 +213,7 @@ export class StackController {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
getRootUrl(stackId?: string) {
|
||||
getRootUrl(stackId?: string): RouteView | undefined {
|
||||
const views = this.getStack(stackId);
|
||||
return views.length > 0 ? views[0] : undefined;
|
||||
}
|
||||
@ -236,7 +226,8 @@ export class StackController {
|
||||
return this.runningTask !== undefined;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
destroy(): void {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
this.containerEl = undefined!;
|
||||
this.views.forEach(destroyView);
|
||||
this.activeView = undefined;
|
||||
@ -244,7 +235,7 @@ export class StackController {
|
||||
}
|
||||
|
||||
private getStack(stackId: string | undefined) {
|
||||
return this.views.filter(v => v.stackId === stackId);
|
||||
return this.views.filter((v) => v.stackId === stackId);
|
||||
}
|
||||
|
||||
private insertView(enteringView: RouteView, direction: RouterDirection) {
|
||||
@ -285,7 +276,7 @@ export class StackController {
|
||||
direction,
|
||||
showGoBack,
|
||||
progressAnimation,
|
||||
animationBuilder
|
||||
animationBuilder,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -297,15 +288,15 @@ export class StackController {
|
||||
await this.runningTask;
|
||||
this.runningTask = undefined;
|
||||
}
|
||||
const promise = this.runningTask = task();
|
||||
promise.finally(() => this.runningTask = undefined);
|
||||
const promise = (this.runningTask = task());
|
||||
promise.finally(() => (this.runningTask = undefined));
|
||||
return promise;
|
||||
}
|
||||
}
|
||||
|
||||
const cleanupAsync = (activeRoute: RouteView, views: RouteView[], viewsSnapshot: RouteView[], location: Location) => {
|
||||
if (typeof (requestAnimationFrame as any) === 'function') {
|
||||
return new Promise<any>(resolve => {
|
||||
return new Promise<void>((resolve) => {
|
||||
requestAnimationFrame(() => {
|
||||
cleanup(activeRoute, views, viewsSnapshot, location);
|
||||
resolve();
|
||||
@ -316,11 +307,9 @@ const cleanupAsync = (activeRoute: RouteView, views: RouteView[], viewsSnapshot:
|
||||
};
|
||||
|
||||
const cleanup = (activeRoute: RouteView, views: RouteView[], viewsSnapshot: RouteView[], location: Location) => {
|
||||
viewsSnapshot
|
||||
.filter(view => !views.includes(view))
|
||||
.forEach(destroyView);
|
||||
viewsSnapshot.filter((view) => !views.includes(view)).forEach(destroyView);
|
||||
|
||||
views.forEach(view => {
|
||||
views.forEach((view) => {
|
||||
/**
|
||||
* In the event that a user navigated multiple
|
||||
* times in rapid succession, we want to make sure
|
||||
|
@ -2,7 +2,7 @@ import { ComponentRef } from '@angular/core';
|
||||
import { ActivatedRoute, NavigationExtras, Router } from '@angular/router';
|
||||
import { AnimationBuilder, NavDirection, RouterDirection } from '@ionic/core';
|
||||
|
||||
export const insertView = (views: RouteView[], view: RouteView, direction: RouterDirection) => {
|
||||
export const insertView = (views: RouteView[], view: RouteView, direction: RouterDirection): RouteView[] => {
|
||||
if (direction === 'root') {
|
||||
return setRoot(views, view);
|
||||
} else if (direction === 'forward') {
|
||||
@ -13,7 +13,7 @@ export const insertView = (views: RouteView[], view: RouteView, direction: Route
|
||||
};
|
||||
|
||||
const setRoot = (views: RouteView[], view: RouteView) => {
|
||||
views = views.filter(v => v.stackId !== view.stackId);
|
||||
views = views.filter((v) => v.stackId !== view.stackId);
|
||||
views.push(view);
|
||||
return views;
|
||||
};
|
||||
@ -21,7 +21,7 @@ const setRoot = (views: RouteView[], view: RouteView) => {
|
||||
const setForward = (views: RouteView[], view: RouteView) => {
|
||||
const index = views.indexOf(view);
|
||||
if (index >= 0) {
|
||||
views = views.filter(v => v.stackId !== view.stackId || v.id <= view.id);
|
||||
views = views.filter((v) => v.stackId !== view.stackId || v.id <= view.id);
|
||||
} else {
|
||||
views.push(view);
|
||||
}
|
||||
@ -31,25 +31,25 @@ const setForward = (views: RouteView[], view: RouteView) => {
|
||||
const setBack = (views: RouteView[], view: RouteView) => {
|
||||
const index = views.indexOf(view);
|
||||
if (index >= 0) {
|
||||
return views.filter(v => v.stackId !== view.stackId || v.id <= view.id);
|
||||
return views.filter((v) => v.stackId !== view.stackId || v.id <= view.id);
|
||||
} else {
|
||||
return setRoot(views, view);
|
||||
}
|
||||
};
|
||||
|
||||
export const getUrl = (router: Router, activatedRoute: ActivatedRoute) => {
|
||||
export const getUrl = (router: Router, activatedRoute: ActivatedRoute): string => {
|
||||
const urlTree = router.createUrlTree(['.'], { relativeTo: activatedRoute });
|
||||
return router.serializeUrl(urlTree);
|
||||
};
|
||||
|
||||
export const isTabSwitch = (enteringView: RouteView, leavingView: RouteView | undefined) => {
|
||||
export const isTabSwitch = (enteringView: RouteView, leavingView: RouteView | undefined): boolean => {
|
||||
if (!leavingView) {
|
||||
return true;
|
||||
}
|
||||
return enteringView.stackId !== leavingView.stackId;
|
||||
};
|
||||
|
||||
export const computeStackId = (prefixUrl: string[] | undefined, url: string) => {
|
||||
export const computeStackId = (prefixUrl: string[] | undefined, url: string): string | undefined => {
|
||||
if (!prefixUrl) {
|
||||
return undefined;
|
||||
}
|
||||
@ -65,14 +65,14 @@ export const computeStackId = (prefixUrl: string[] | undefined, url: string) =>
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const toSegments = (path: string) => {
|
||||
export const toSegments = (path: string): string[] => {
|
||||
return path
|
||||
.split('/')
|
||||
.map(s => s.trim())
|
||||
.filter(s => s !== '');
|
||||
.map((s) => s.trim())
|
||||
.filter((s) => s !== '');
|
||||
};
|
||||
|
||||
export const destroyView = (view: RouteView | undefined) => {
|
||||
export const destroyView = (view: RouteView | undefined): void => {
|
||||
if (view) {
|
||||
// TODO lifecycle event
|
||||
view.ref.destroy();
|
||||
|
@ -1,12 +1,66 @@
|
||||
/* eslint-disable */
|
||||
/* tslint:disable */
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ElementRef, EventEmitter, NgZone, TemplateRef } from "@angular/core";
|
||||
import { ProxyCmp, proxyOutputs } from "../angular-component-lib/utils";
|
||||
import { Components } from "@ionic/core";
|
||||
export declare interface IonModal extends Components.IonModal {
|
||||
}
|
||||
@ProxyCmp({ inputs: ["animated", "backdropBreakpoint", "backdropDismiss", "breakpoints", "cssClass", "enterAnimation", "event", "handle", "initialBreakpoint", "isOpen", "keyboardClose", "leaveAnimation", "mode", "presentingElement", "showBackdrop", "swipeToClose", "translucent", "trigger"], "methods": ["present", "dismiss", "onDidDismiss", "onWillDismiss"] })
|
||||
@Component({ selector: "ion-modal", changeDetection: ChangeDetectionStrategy.OnPush, template: `<ng-container [ngTemplateOutlet]="template" *ngIf="isCmpOpen"></ng-container>`, inputs: ["animated", "backdropBreakpoint", "backdropDismiss", "breakpoints", "cssClass", "enterAnimation", "event", "handle", "initialBreakpoint", "isOpen", "keyboardClose", "leaveAnimation", "mode", "presentingElement", "showBackdrop", "swipeToClose", "translucent", "trigger"] })
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ContentChild,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
NgZone,
|
||||
TemplateRef,
|
||||
} from '@angular/core';
|
||||
import { ProxyCmp, proxyOutputs } from '../angular-component-lib/utils';
|
||||
import { Components } from '@ionic/core';
|
||||
export declare interface IonModal extends Components.IonModal {}
|
||||
@ProxyCmp({
|
||||
inputs: [
|
||||
'animated',
|
||||
'backdropBreakpoint',
|
||||
'backdropDismiss',
|
||||
'breakpoints',
|
||||
'cssClass',
|
||||
'enterAnimation',
|
||||
'event',
|
||||
'handle',
|
||||
'initialBreakpoint',
|
||||
'isOpen',
|
||||
'keyboardClose',
|
||||
'leaveAnimation',
|
||||
'mode',
|
||||
'presentingElement',
|
||||
'showBackdrop',
|
||||
'swipeToClose',
|
||||
'translucent',
|
||||
'trigger',
|
||||
],
|
||||
methods: ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss'],
|
||||
})
|
||||
@Component({
|
||||
selector: 'ion-modal',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
template: `<ng-container [ngTemplateOutlet]="template" *ngIf="isCmpOpen"></ng-container>`,
|
||||
inputs: [
|
||||
'animated',
|
||||
'backdropBreakpoint',
|
||||
'backdropDismiss',
|
||||
'breakpoints',
|
||||
'cssClass',
|
||||
'enterAnimation',
|
||||
'event',
|
||||
'handle',
|
||||
'initialBreakpoint',
|
||||
'isOpen',
|
||||
'keyboardClose',
|
||||
'leaveAnimation',
|
||||
'mode',
|
||||
'presentingElement',
|
||||
'showBackdrop',
|
||||
'swipeToClose',
|
||||
'translucent',
|
||||
'trigger',
|
||||
],
|
||||
})
|
||||
export class IonModal {
|
||||
@ContentChild(TemplateRef, { static: false }) template: TemplateRef<any>;
|
||||
|
||||
@ -34,6 +88,15 @@ export class IonModal {
|
||||
c.detectChanges();
|
||||
});
|
||||
|
||||
proxyOutputs(this, this.el, ["ionModalDidPresent", "ionModalWillPresent", "ionModalWillDismiss", "ionModalDidDismiss", "didPresent", "willPresent", "willDismiss", "didDismiss"]);
|
||||
proxyOutputs(this, this.el, [
|
||||
'ionModalDidPresent',
|
||||
'ionModalWillPresent',
|
||||
'ionModalWillDismiss',
|
||||
'ionModalDidDismiss',
|
||||
'didPresent',
|
||||
'willPresent',
|
||||
'willDismiss',
|
||||
'didDismiss',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,66 @@
|
||||
/* eslint-disable */
|
||||
/* tslint:disable */
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ElementRef, EventEmitter, NgZone, TemplateRef } from "@angular/core";
|
||||
import { ProxyCmp, proxyOutputs } from "../angular-component-lib/utils";
|
||||
import { Components } from "@ionic/core";
|
||||
export declare interface IonPopover extends Components.IonPopover {
|
||||
}
|
||||
@ProxyCmp({ inputs: ["alignment", "animated", "arrow", "backdropDismiss", "cssClass", "dismissOnSelect", "enterAnimation", "event", "isOpen", "keyboardClose", "leaveAnimation", "mode", "showBackdrop", "translucent", "trigger", "triggerAction", "reference", "size"], "methods": ["present", "dismiss", "onDidDismiss", "onWillDismiss"] })
|
||||
@Component({ selector: "ion-popover", changeDetection: ChangeDetectionStrategy.OnPush, template: `<ng-container [ngTemplateOutlet]="template" *ngIf="isCmpOpen"></ng-container>`, inputs: ["alignment", "animated", "arrow", "backdropDismiss", "cssClass", "dismissOnSelect", "enterAnimation", "event", "isOpen", "keyboardClose", "leaveAnimation", "mode", "showBackdrop", "translucent", "trigger", "triggerAction", "reference", "size"] })
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ContentChild,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
NgZone,
|
||||
TemplateRef,
|
||||
} from '@angular/core';
|
||||
import { ProxyCmp, proxyOutputs } from '../angular-component-lib/utils';
|
||||
import { Components } from '@ionic/core';
|
||||
export declare interface IonPopover extends Components.IonPopover {}
|
||||
@ProxyCmp({
|
||||
inputs: [
|
||||
'alignment',
|
||||
'animated',
|
||||
'arrow',
|
||||
'backdropDismiss',
|
||||
'cssClass',
|
||||
'dismissOnSelect',
|
||||
'enterAnimation',
|
||||
'event',
|
||||
'isOpen',
|
||||
'keyboardClose',
|
||||
'leaveAnimation',
|
||||
'mode',
|
||||
'showBackdrop',
|
||||
'translucent',
|
||||
'trigger',
|
||||
'triggerAction',
|
||||
'reference',
|
||||
'size',
|
||||
],
|
||||
methods: ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss'],
|
||||
})
|
||||
@Component({
|
||||
selector: 'ion-popover',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
template: `<ng-container [ngTemplateOutlet]="template" *ngIf="isCmpOpen"></ng-container>`,
|
||||
inputs: [
|
||||
'alignment',
|
||||
'animated',
|
||||
'arrow',
|
||||
'backdropDismiss',
|
||||
'cssClass',
|
||||
'dismissOnSelect',
|
||||
'enterAnimation',
|
||||
'event',
|
||||
'isOpen',
|
||||
'keyboardClose',
|
||||
'leaveAnimation',
|
||||
'mode',
|
||||
'showBackdrop',
|
||||
'translucent',
|
||||
'trigger',
|
||||
'triggerAction',
|
||||
'reference',
|
||||
'size',
|
||||
],
|
||||
})
|
||||
export class IonPopover {
|
||||
@ContentChild(TemplateRef, { static: false }) template: TemplateRef<any>;
|
||||
|
||||
@ -34,6 +88,15 @@ export class IonPopover {
|
||||
c.detectChanges();
|
||||
});
|
||||
|
||||
proxyOutputs(this, this.el, ["ionPopoverDidPresent", "ionPopoverWillPresent", "ionPopoverWillDismiss", "ionPopoverDidDismiss", "didPresent", "willPresent", "willDismiss", "didDismiss"]);
|
||||
proxyOutputs(this, this.el, [
|
||||
'ionPopoverDidPresent',
|
||||
'ionPopoverWillPresent',
|
||||
'ionPopoverWillDismiss',
|
||||
'ionPopoverDidDismiss',
|
||||
'didPresent',
|
||||
'willPresent',
|
||||
'willDismiss',
|
||||
'didDismiss',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -205,8 +205,8 @@ export class IonVirtualScroll {
|
||||
case 'item': return this.itmTmp.templateRef;
|
||||
case 'header': return this.hdrTmp.templateRef;
|
||||
case 'footer': return this.ftrTmp.templateRef;
|
||||
default: throw new Error('template for virtual item was not provided');
|
||||
}
|
||||
throw new Error('template for virtual item was not provided');
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user