-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ion-router-outlet): adds router-outlet
- Loading branch information
1 parent
17a3001
commit c03afab
Showing
6 changed files
with
324 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# ion-router-outlet | ||
|
||
|
||
|
||
<!-- Auto Generated Below --> | ||
|
||
|
||
## Properties | ||
|
||
#### animated | ||
|
||
boolean | ||
|
||
|
||
#### animationBuilder | ||
|
||
|
||
|
||
|
||
#### delegate | ||
|
||
|
||
|
||
|
||
## Attributes | ||
|
||
#### animated | ||
|
||
boolean | ||
|
||
|
||
#### animation-builder | ||
|
||
|
||
|
||
|
||
#### delegate | ||
|
||
|
||
|
||
|
||
## Methods | ||
|
||
#### commit() | ||
|
||
|
||
#### getRouteId() | ||
|
||
|
||
#### setRoot() | ||
|
||
|
||
#### setRouteId() | ||
|
||
|
||
|
||
---------------------------------------------- | ||
|
||
*Built with [StencilJS](https://stenciljs.com/)* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
import { Component, Element, Method, Prop } from '@stencil/core'; | ||
import { transition } from '../../utils'; | ||
import { NavDirection } from '../nav/nav-util'; | ||
import { AnimationBuilder, Config, FrameworkDelegate, NavOutlet } from '../..'; | ||
import { attachComponent, detachComponent } from '../../utils/overlays'; | ||
|
||
import iosTransitionAnimation from '../nav/animations/ios.transition'; | ||
import mdTransitionAnimation from '../nav/animations/md.transition'; | ||
import { RouteID, RouteWrite } from '../router/utils/interfaces'; | ||
|
||
@Component({ | ||
tag: 'ion-router-outlet' | ||
}) | ||
export class RouterOutlet implements NavOutlet { | ||
|
||
private isTransitioning = false; | ||
private activeEl: HTMLElement = undefined; | ||
|
||
mode: string; | ||
|
||
@Element() el: HTMLElement; | ||
|
||
@Prop({context: 'config'}) config: Config; | ||
@Prop({connect: 'ion-animation-controller'}) animationCtrl: HTMLIonAnimationControllerElement; | ||
|
||
@Prop() animated = true; | ||
@Prop() animationBuilder: AnimationBuilder; | ||
@Prop() delegate: FrameworkDelegate; | ||
|
||
componentDidUnload() { | ||
this.activeEl = undefined; | ||
} | ||
|
||
@Method() | ||
async setRoot(component: HTMLElement|string, params?: {[key: string]: any}, opts?: RouterOutletOptions): Promise<boolean> { | ||
if (this.isTransitioning) { | ||
return false; | ||
} | ||
// attach entering view to DOM | ||
const enteringEl = await attachComponent(this.delegate, this.el, component, NAV_CLASSES, params); | ||
const leavingEl = this.activeEl; | ||
|
||
// commit animation | ||
await this.commit(enteringEl, opts); | ||
|
||
// remove leaving view | ||
detachComponent(this.delegate, leavingEl); | ||
|
||
return true; | ||
} | ||
|
||
@Method() | ||
async commit(enteringEl: HTMLElement, opts?: RouterOutletOptions): Promise<boolean> { | ||
// isTransitioning acts as a lock to prevent reentering | ||
if (this.isTransitioning || this.activeEl === enteringEl) { | ||
return false; | ||
} | ||
this.isTransitioning = true; | ||
|
||
opts = opts || {}; | ||
|
||
await transition({ | ||
animationBuilder: this.getAnimationBuilder(opts), | ||
direction: opts.direction, | ||
duration: opts.duration, | ||
easing: opts.easing, | ||
|
||
animationCtrl: this.animationCtrl, | ||
enteringEl: enteringEl, | ||
leavingEl: this.activeEl, | ||
baseEl: this.el, | ||
}); | ||
this.activeEl = enteringEl; | ||
this.isTransitioning = false; | ||
return true; | ||
} | ||
|
||
@Method() | ||
async setRouteId(id: string, data: any, direction: number): Promise<RouteWrite> { | ||
const changed = await this.setRoot(id, data, { | ||
duration: direction === 0 ? 0 : undefined, | ||
direction: direction === -1 ? NavDirection.back : NavDirection.forward, | ||
}); | ||
return { | ||
changed, | ||
element: this.activeEl | ||
}; | ||
} | ||
|
||
@Method() | ||
getRouteId(): RouteID|undefined { | ||
const active = this.activeEl; | ||
return active ? { | ||
id: active.tagName, | ||
element: active, | ||
} : undefined; | ||
} | ||
|
||
private getAnimationBuilder(opts: RouterOutletOptions) { | ||
if (opts.duration === 0 || this.animated === false || this.activeEl === undefined) { | ||
return undefined; | ||
} | ||
const mode = opts.mode || this.config.get('pageTransition', this.mode); | ||
return opts.animationBuilder | ||
|| this.animationBuilder | ||
|| mode === 'ios' ? iosTransitionAnimation : mdTransitionAnimation; | ||
} | ||
|
||
render() { | ||
return [ | ||
this.mode === 'ios' && <div class='nav-decor'/>, | ||
<slot/> | ||
]; | ||
} | ||
} | ||
|
||
export interface RouterOutletOptions { | ||
animationBuilder?: AnimationBuilder; | ||
duration?: number; | ||
easing?: string; | ||
direction?: NavDirection; | ||
mode?: 'md' | 'ios'; | ||
} | ||
|
||
const NAV_CLASSES = {'ion-page': true, 'hide-page': true}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
<!DOCTYPE html> | ||
<html dir="ltr"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>Nav</title> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> | ||
<script src="/dist/ionic.js"></script> | ||
<script> | ||
class PageOne extends HTMLElement { | ||
connectedCallback() { | ||
this.innerHTML = ` | ||
<ion-header> | ||
<ion-toolbar> | ||
<ion-title>Page One</ion-title> | ||
</ion-toolbar> | ||
</ion-header> | ||
<ion-content padding> | ||
<h1>Page One</h1> | ||
<ion-button href="#/two">Go to Page Two</ion-button> | ||
</ion-content> | ||
`; | ||
} | ||
} | ||
class PageTwo extends HTMLElement { | ||
connectedCallback() { | ||
this.innerHTML = ` | ||
<ion-header> | ||
<ion-toolbar> | ||
<ion-buttons slot="start"> | ||
<ion-back-button text="Page One"></ion-back-button> | ||
</ion-buttons> | ||
<ion-title>Page Two</ion-title> | ||
</ion-toolbar> | ||
</ion-header> | ||
<ion-content padding> | ||
<h1>Page Two</h1> | ||
<div> | ||
<ion-nav-push component="page-three"> | ||
<ion-button href="#/page-3">Go to Page Two</ion-button> | ||
</ion-nav-push> | ||
</div> | ||
</ion-content> | ||
`; | ||
} | ||
} | ||
class PageThree extends HTMLElement { | ||
connectedCallback() { | ||
this.innerHTML = ` | ||
<ion-header> | ||
<ion-toolbar> | ||
<ion-buttons slot="start"> | ||
<ion-back-button text="Page Two"></ion-back-button> | ||
</ion-buttons> | ||
<ion-title>Page Three</ion-title> | ||
</ion-toolbar> | ||
</ion-header> | ||
<ion-content padding> | ||
<h1>Page Three</h1> | ||
</ion-content> | ||
`; | ||
} | ||
} | ||
customElements.define('page-one', PageOne); | ||
customElements.define('page-two', PageTwo); | ||
customElements.define('page-three', PageThree); | ||
</script> | ||
</head> | ||
<body> | ||
<ion-app> | ||
<ion-router> | ||
<ion-route url="/" component="page-one"> </ion-route> | ||
<ion-route url="/two" component="page-two"> </ion-route> | ||
<ion-route url="/page-3" component="page-three"> </ion-route> | ||
</ion-router> | ||
<ion-router-outlet></ion-router-outlet> | ||
</ion-app> | ||
</body> | ||
</html> |