feat(all): add support for configuring animations on a per-page basis (#21433)

This commit is contained in:
Liam DeBeasi
2020-06-08 15:49:14 -04:00
committed by GitHub
parent c8db0d5eeb
commit f34d3752e3
34 changed files with 334 additions and 142 deletions

View File

@ -78,7 +78,7 @@ Type: `Promise<void>`
### `push(url: string, direction?: RouterDirection) => Promise<boolean>`
### `push(url: string, direction?: RouterDirection, animation?: AnimationBuilder | undefined) => Promise<boolean>`
Navigate to the specified URL.

View File

@ -1,6 +1,6 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
import { BackButtonEvent, RouteChain, RouterDirection, RouterEventDetail } from '../../interface';
import { AnimationBuilder, BackButtonEvent, RouteChain, RouterDirection, RouterEventDetail } from '../../interface';
import { debounce } from '../../utils/helpers';
import { ROUTER_INTENT_BACK, ROUTER_INTENT_FORWARD, ROUTER_INTENT_NONE } from './utils/constants';
@ -92,7 +92,7 @@ export class Router implements ComponentInterface {
* @param direction The direction of the animation. Defaults to `"forward"`.
*/
@Method()
push(url: string, direction: RouterDirection = 'forward') {
push(url: string, direction: RouterDirection = 'forward', animation?: AnimationBuilder) {
if (url.startsWith('.')) {
url = (new URL(url, window.location.href)).pathname;
}
@ -101,7 +101,7 @@ export class Router implements ComponentInterface {
const path = parsePath(url);
const queryString = url.split('?')[1];
this.setPath(path, direction, queryString);
return this.writeNavStateRoot(path, direction);
return this.writeNavStateRoot(path, direction, animation);
}
/**
@ -182,7 +182,7 @@ export class Router implements ComponentInterface {
}
}
private async writeNavStateRoot(path: string[] | null, direction: RouterDirection): Promise<boolean> {
private async writeNavStateRoot(path: string[] | null, direction: RouterDirection, animation?: AnimationBuilder): Promise<boolean> {
if (!path) {
console.error('[ion-router] URL is not part of the routing set');
return false;
@ -207,18 +207,19 @@ export class Router implements ComponentInterface {
}
// write DOM give
return this.safeWriteNavState(document.body, chain, direction, path, redirectFrom);
return this.safeWriteNavState(document.body, chain, direction, path, redirectFrom, 0, animation);
}
private async safeWriteNavState(
node: HTMLElement | undefined, chain: RouteChain, direction: RouterDirection,
path: string[], redirectFrom: string[] | null,
index = 0
index = 0,
animation?: AnimationBuilder
): Promise<boolean> {
const unlock = await this.lock();
let changed = false;
try {
changed = await this.writeNavState(node, chain, direction, path, redirectFrom, index);
changed = await this.writeNavState(node, chain, direction, path, redirectFrom, index, animation);
} catch (e) {
console.error(e);
}
@ -240,7 +241,7 @@ export class Router implements ComponentInterface {
private async writeNavState(
node: HTMLElement | undefined, chain: RouteChain, direction: RouterDirection,
path: string[], redirectFrom: string[] | null,
index = 0
index = 0, animation?: AnimationBuilder
): Promise<boolean> {
if (this.busy) {
console.warn('[ion-router] router is busy, transition was cancelled');
@ -254,7 +255,7 @@ export class Router implements ComponentInterface {
this.ionRouteWillChange.emit(routeEvent);
}
const changed = await writeNavState(node, chain, direction, index);
const changed = await writeNavState(node, chain, direction, index, false, animation);
this.busy = false;
if (changed) {

View File

@ -1,4 +1,4 @@
import { NavOutletElement, RouteChain, RouteID, RouterDirection } from '../../../interface';
import { AnimationBuilder, NavOutletElement, RouteChain, RouteID, RouterDirection } from '../../../interface';
import { ROUTER_INTENT_NONE } from './constants';
@ -7,7 +7,8 @@ export const writeNavState = async (
chain: RouteChain,
direction: RouterDirection,
index: number,
changed = false
changed = false,
animation?: AnimationBuilder
): Promise<boolean> => {
try {
// find next navigation outlet in the DOM
@ -20,7 +21,7 @@ export const writeNavState = async (
await outlet.componentOnReady();
const route = chain[index];
const result = await outlet.setRouteId(route.id, route.params, direction);
const result = await outlet.setRouteId(route.id, route.params, direction, animation);
// if the outlet changed the page, reset navigation to neutral (no direction)
// this means nested outlets will not animate
@ -30,7 +31,7 @@ export const writeNavState = async (
}
// recursively set nested outlets
changed = await writeNavState(result.element, chain, direction, index + 1, changed);
changed = await writeNavState(result.element, chain, direction, index + 1, changed, animation);
// once all nested outlets are visible let's make the parent visible too,
// using markVisible prevents flickering

View File

@ -1,11 +1,11 @@
import { ComponentProps } from '../../../interface';
import { AnimationBuilder, ComponentProps } from '../../../interface';
export interface HTMLStencilElement extends HTMLElement {
componentOnReady(): Promise<this>;
}
export interface NavOutlet {
setRouteId(id: string, params: ComponentProps | undefined, direction: RouterDirection): Promise<RouteWrite>;
setRouteId(id: string, params: ComponentProps | undefined, direction: RouterDirection, animation?: AnimationBuilder): Promise<RouteWrite>;
getRouteId(): Promise<RouteID | undefined>;
}