fix(routing): tabs integration

This commit is contained in:
Manu Mtz.-Almeida
2018-02-08 19:43:29 +01:00
parent bf143fe96a
commit a337bd019c
14 changed files with 356 additions and 51 deletions

View File

@@ -7,11 +7,6 @@
## Properties
#### component
string
#### path
string
@@ -22,13 +17,13 @@ string
any
#### sel
string
## Attributes
#### component
string
#### path
string
@@ -39,6 +34,11 @@ string
any
#### sel
string
----------------------------------------------

View File

@@ -7,7 +7,7 @@ import { Component, Prop } from '@stencil/core';
export class Route {
@Prop() path: string;
@Prop() component: string;
@Prop() sel: string;
@Prop() props: any = {};
}

View File

@@ -70,11 +70,11 @@ export function readNavState(node: HTMLElement) {
}
return {
stack: stack,
pivot: pivot
pivot: pivot,
};
}
export function matchPath(stack: string[], routes: RouterEntries): string[] {
export function matchPath(stack: string[], routes: RouterEntries) {
const path: string[] = [];
for (const id of stack) {
const route = routes.find(r => r.id === id);
@@ -85,7 +85,10 @@ export function matchPath(stack: string[], routes: RouterEntries): string[] {
break;
}
}
return path;
return {
path: path,
routes: routes,
};
}
export function matchRouteChain(path: string[], routes: RouterEntries): RouterEntries {
@@ -140,7 +143,7 @@ export function readRoutes(root: Element): RouterEntries {
.filter(el => el.tagName === 'ION-ROUTE')
.map(el => ({
path: parsePath(el.path),
id: el.component,
id: el.sel,
props: el.props,
subroutes: readRoutes(el)
}));

View File

@@ -46,15 +46,15 @@ export class Router {
console.debug('[IN] nav changed -> update URL');
const { stack, pivot } = this.readNavState();
const { path, routes} = matchPath(stack, this.routes);
if (pivot) {
// readNavState() found a pivot that is not initialized
console.debug('[IN] pivot uninitialized -> write partial nav state');
this.writeNavState(pivot, []);
this.writeNavState(pivot, [], routes);
}
const isPop = ev.detail.isPop === true;
const segments = matchPath(stack, this.routes);
this.writePath(segments, isPop);
this.writePath(path, isPop);
}
@@ -62,13 +62,13 @@ export class Router {
const node = document.querySelector('ion-app') as HTMLElement;
const currentPath = this.readPath();
if (currentPath) {
return this.writeNavState(node, currentPath);
return this.writeNavState(node, currentPath, this.routes);
}
return Promise.resolve();
}
private writeNavState(node: any, path: string[]): Promise<any> {
const chain = matchRouteChain(path, this.routes);
private writeNavState(node: any, path: string[], routes: RouterEntries): Promise<any> {
const chain = matchRouteChain(path, routes);
this.busy = true;
return writeNavState(node, chain)

View File

@@ -0,0 +1,70 @@
<!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 src="/test-components/build/app.js"></script>
</head>
<body>
<ion-app>
<ion-router>
<ion-route path="/" sel="tab1"> </ion-route>
<ion-route path="/two" sel="tab2">
<ion-route path="/" sel="page-one"> </ion-route>
<ion-route path="/second-page" sel="page-two"> </ion-route>
</ion-route>
<ion-route path="/three" sel="tab-three"> </ion-route>
<ion-route path="/four" sel="tab4"> </ion-route>
</ion-router>
<ion-tabs>
<ion-tab name="tab1"
title="Plain List"
icon="star"
component="tab-one"></ion-tab>
<ion-tab name="tab2"
title="Schedule"
icon="globe"
component="tab-two"></ion-tab>
<ion-tab
title="Stopwatch"
icon="logo-facebook"
component="tab-three"></ion-tab>
<ion-tab name="tab4"
title="Messages"
icon="chatboxes"
name="tab-four">
INLINE CONTENT
</ion-tab>
</ion-tabs>
</ion-app>
<style>
f {
display: block;
margin: 15px auto;
max-width: 150px;
height: 150px;
background: blue;
}
f:last-of-type {
background: yellow;
}
</style>
</body>
<script>
</script>
</html>

View File

@@ -97,12 +97,10 @@ string
The icon for the tab button.
#### path
#### name
string
The URL path name to represent this tab within the URL.
#### selected
@@ -180,12 +178,10 @@ string
The icon for the tab button.
#### path
#### name
string
The URL path name to represent this tab within the URL.
#### selected
@@ -223,7 +219,7 @@ Emitted when the current tab is selected.
## Methods
#### getPath()
#### getRouteId()
#### setActive()

View File

@@ -19,11 +19,6 @@ export class Tab {
*/
@Prop() btnId: string;
/**
* The URL path name to represent this tab within the URL.
*/
@Prop() path: string;
/**
* The title of the tab button.
*/
@@ -43,6 +38,7 @@ export class Tab {
* The badge for the tab button.
*/
@Prop() component: any;
@Prop() name: string;
/**
* The badge color for the tab button.
@@ -102,7 +98,18 @@ export class Tab {
return promise.then(() => this.fireChildren());
}
fireChildren() {
@Method()
getRouteId(): string|null {
if (this.name) {
return this.name;
}
if (typeof this.component === 'string') {
return this.component;
}
return null;
}
private fireChildren() {
const nav = getNavAsChildIfExists(this.el);
if (nav && nav.getViews().length === 0 && nav.root) {
// we need to initialize
@@ -112,17 +119,6 @@ export class Tab {
return Promise.resolve();
}
@Method()
getPath(): string {
if (this.path != null) {
return this.path;
}
if (this.title) {
return this.title.toLowerCase();
}
return '';
}
hostData() {
const visible = this.active && this.selected;
return {

View File

@@ -217,6 +217,9 @@ Only affects `ios` mode. Defaults to `false`.
Emitted when the tab changes.
#### ionNavChanged
## Methods
#### getByIndex()

View File

@@ -1,5 +1,5 @@
import { Component, Element, Event, EventEmitter, Listen, Method, Prop, State } from '@stencil/core';
import { Config, NavOutlet } from '../../index';
import { Config, NavOutlet, NavEventDetail } from '../../index';
@Component({
@@ -66,6 +66,7 @@ export class Tabs implements NavOutlet {
* Emitted when the tab changes.
*/
@Event() ionChange: EventEmitter;
@Event() ionNavChanged: EventEmitter<NavEventDetail>;
componentDidLoad() {
this.loadConfig('tabsPlacement', 'bottom');
@@ -116,10 +117,10 @@ export class Tabs implements NavOutlet {
return promise.then(() => {
this.ionChange.emit(selectedTab);
this.ionNavChanged.emit({isPop: false});
});
}
/**
* @param {number} index Index of the tab you want to get
* @returns {HTMLIonTabElement} Returns the tab who's index matches the one passed
@@ -152,14 +153,15 @@ export class Tabs implements NavOutlet {
if (this.selectedTab === id) {
return Promise.resolve();
}
return this.select(id);
const tab = this.tabs.find(t => id === t.getRouteId());
return this.select(tab);
}
@Method()
getRouteId(): string|null {
if (this.selectedTab) {
return this.selectedTab.tagName;
return this.selectedTab.getRouteId();
}
return null;
}
@@ -180,6 +182,9 @@ export class Tabs implements NavOutlet {
}
private initSelect() {
if (document.querySelector('ion-router')) {
return;
}
// find pre-selected tabs
const selectedTab = this.tabs.find(t => t.selected) ||
this.tabs.find(t => t.show && !t.disabled);