diff --git a/packages/core/scripts/test-components/src/components.d.ts b/packages/core/scripts/test-components/src/components.d.ts new file mode 100644 index 0000000000..cf59e4ae6c --- /dev/null +++ b/packages/core/scripts/test-components/src/components.d.ts @@ -0,0 +1,166 @@ +/** + * This is an autogenerated file created by the Stencil build process. + * It contains typing information for all components that exist in this project + * and imports for stencil collections that might be configured in your stencil.config.js file + */ + + +declare global { + interface HTMLStencilElement extends HTMLElement { + componentOnReady(): Promise; + componentOnReady(done: (ele?: this) => void): void; + } +} + + + +import { + PageOne as PageOne +} from './components/page-one/page-one'; + +declare global { + interface HTMLPageOneElement extends PageOne, HTMLStencilElement { + } + var HTMLPageOneElement: { + prototype: HTMLPageOneElement; + new (): HTMLPageOneElement; + }; + interface HTMLElementTagNameMap { + "page-one": HTMLPageOneElement; + } + interface ElementTagNameMap { + "page-one": HTMLPageOneElement; + } + namespace JSX { + interface IntrinsicElements { + "page-one": JSXElements.PageOneAttributes; + } + } + namespace JSXElements { + export interface PageOneAttributes extends HTMLAttributes { + + } + } +} + + +import { + PageTwo as PageTwo +} from './components/page-two/page-two'; + +declare global { + interface HTMLPageTwoElement extends PageTwo, HTMLStencilElement { + } + var HTMLPageTwoElement: { + prototype: HTMLPageTwoElement; + new (): HTMLPageTwoElement; + }; + interface HTMLElementTagNameMap { + "page-two": HTMLPageTwoElement; + } + interface ElementTagNameMap { + "page-two": HTMLPageTwoElement; + } + namespace JSX { + interface IntrinsicElements { + "page-two": JSXElements.PageTwoAttributes; + } + } + namespace JSXElements { + export interface PageTwoAttributes extends HTMLAttributes { + + } + } +} + + +import { + TabOne as TabOne +} from './components/tab-one/tab-one'; + +declare global { + interface HTMLTabOneElement extends TabOne, HTMLStencilElement { + } + var HTMLTabOneElement: { + prototype: HTMLTabOneElement; + new (): HTMLTabOneElement; + }; + interface HTMLElementTagNameMap { + "tab-one": HTMLTabOneElement; + } + interface ElementTagNameMap { + "tab-one": HTMLTabOneElement; + } + namespace JSX { + interface IntrinsicElements { + "tab-one": JSXElements.TabOneAttributes; + } + } + namespace JSXElements { + export interface TabOneAttributes extends HTMLAttributes { + + } + } +} + + +import { + TabThree as TabThree +} from './components/tab-three/tab-three'; + +declare global { + interface HTMLTabThreeElement extends TabThree, HTMLStencilElement { + } + var HTMLTabThreeElement: { + prototype: HTMLTabThreeElement; + new (): HTMLTabThreeElement; + }; + interface HTMLElementTagNameMap { + "tab-three": HTMLTabThreeElement; + } + interface ElementTagNameMap { + "tab-three": HTMLTabThreeElement; + } + namespace JSX { + interface IntrinsicElements { + "tab-three": JSXElements.TabThreeAttributes; + } + } + namespace JSXElements { + export interface TabThreeAttributes extends HTMLAttributes { + + } + } +} + + +import { + TabTwo as TabTwo +} from './components/tab-two/tab-two'; + +declare global { + interface HTMLTabTwoElement extends TabTwo, HTMLStencilElement { + } + var HTMLTabTwoElement: { + prototype: HTMLTabTwoElement; + new (): HTMLTabTwoElement; + }; + interface HTMLElementTagNameMap { + "tab-two": HTMLTabTwoElement; + } + interface ElementTagNameMap { + "tab-two": HTMLTabTwoElement; + } + namespace JSX { + interface IntrinsicElements { + "tab-two": JSXElements.TabTwoAttributes; + } + } + namespace JSXElements { + export interface TabTwoAttributes extends HTMLAttributes { + + } + } +} + +declare global { namespace JSX { interface StencilJSX {} } } diff --git a/packages/core/scripts/test-components/src/components/tab-one/tab-one.tsx b/packages/core/scripts/test-components/src/components/tab-one/tab-one.tsx new file mode 100644 index 0000000000..b65f38ff0e --- /dev/null +++ b/packages/core/scripts/test-components/src/components/tab-one/tab-one.tsx @@ -0,0 +1,22 @@ +import { Component } from '@stencil/core'; + +@Component({ + tag: 'tab-one', +}) +export class TabOne { + + render() { + return [ + + + + Page One + + + + tab one + + + ]; + } +} diff --git a/packages/core/scripts/test-components/src/components/tab-three/tab-three.tsx b/packages/core/scripts/test-components/src/components/tab-three/tab-three.tsx new file mode 100644 index 0000000000..bd91cb4558 --- /dev/null +++ b/packages/core/scripts/test-components/src/components/tab-three/tab-three.tsx @@ -0,0 +1,22 @@ +import { Component } from '@stencil/core'; + +@Component({ + tag: 'tab-three', +}) +export class TabThree { + + render() { + return [ + + + + Tab 3 + + + + tab three + + + ]; + } +} diff --git a/packages/core/scripts/test-components/src/components/tab-two/tab-two.tsx b/packages/core/scripts/test-components/src/components/tab-two/tab-two.tsx new file mode 100644 index 0000000000..5530c7a39c --- /dev/null +++ b/packages/core/scripts/test-components/src/components/tab-two/tab-two.tsx @@ -0,0 +1,22 @@ +import { Component } from '@stencil/core'; + +@Component({ + tag: 'tab-two', +}) +export class TabTwo { + + render() { + return [ + + + + Tab two (2) + + + + + + + ]; + } +} diff --git a/packages/core/src/components.d.ts b/packages/core/src/components.d.ts index 3ab8c6e870..29a595e193 100644 --- a/packages/core/src/components.d.ts +++ b/packages/core/src/components.d.ts @@ -2437,9 +2437,9 @@ declare global { } namespace JSXElements { export interface IonRouteAttributes extends HTMLAttributes { - component?: string; path?: string; props?: any; + sel?: string; } } } @@ -3002,7 +3002,7 @@ declare global { delegate?: FrameworkDelegate; disabled?: boolean; icon?: string; - path?: string; + name?: string; selected?: boolean; show?: boolean; tabsHideOnSubPages?: boolean; diff --git a/packages/core/src/components/route/readme.md b/packages/core/src/components/route/readme.md index aec9f098b8..b6c8c1a78f 100644 --- a/packages/core/src/components/route/readme.md +++ b/packages/core/src/components/route/readme.md @@ -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 + + ---------------------------------------------- diff --git a/packages/core/src/components/route/route.tsx b/packages/core/src/components/route/route.tsx index 8ae3d6b60f..75e3562ccc 100644 --- a/packages/core/src/components/route/route.tsx +++ b/packages/core/src/components/route/route.tsx @@ -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 = {}; } diff --git a/packages/core/src/components/router/router-utils.ts b/packages/core/src/components/router/router-utils.ts index c6d89e805d..6c36ad11e6 100644 --- a/packages/core/src/components/router/router-utils.ts +++ b/packages/core/src/components/router/router-utils.ts @@ -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) })); diff --git a/packages/core/src/components/router/router.tsx b/packages/core/src/components/router/router.tsx index 5e1076a0b4..1f1de328cd 100644 --- a/packages/core/src/components/router/router.tsx +++ b/packages/core/src/components/router/router.tsx @@ -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 { - const chain = matchRouteChain(path, this.routes); + private writeNavState(node: any, path: string[], routes: RouterEntries): Promise { + const chain = matchRouteChain(path, routes); this.busy = true; return writeNavState(node, chain) diff --git a/packages/core/src/components/router/test/basic/index.html b/packages/core/src/components/router/test/basic/index.html new file mode 100644 index 0000000000..2633b7a9e0 --- /dev/null +++ b/packages/core/src/components/router/test/basic/index.html @@ -0,0 +1,70 @@ + + + + + Nav + + + + + + + + + + + + + + + + + + + + + + + + + + + + + INLINE CONTENT + + + + + + + + + + diff --git a/packages/core/src/components/tab/readme.md b/packages/core/src/components/tab/readme.md index f4679940bd..9af52ed68a 100644 --- a/packages/core/src/components/tab/readme.md +++ b/packages/core/src/components/tab/readme.md @@ -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() diff --git a/packages/core/src/components/tab/tab.tsx b/packages/core/src/components/tab/tab.tsx index 6fe90e2d13..61ca95fc66 100644 --- a/packages/core/src/components/tab/tab.tsx +++ b/packages/core/src/components/tab/tab.tsx @@ -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 { diff --git a/packages/core/src/components/tabs/readme.md b/packages/core/src/components/tabs/readme.md index d8376922cb..dbdccbecee 100644 --- a/packages/core/src/components/tabs/readme.md +++ b/packages/core/src/components/tabs/readme.md @@ -217,6 +217,9 @@ Only affects `ios` mode. Defaults to `false`. Emitted when the tab changes. +#### ionNavChanged + + ## Methods #### getByIndex() diff --git a/packages/core/src/components/tabs/tabs.tsx b/packages/core/src/components/tabs/tabs.tsx index ba3aa0ee1e..6107c6f57c 100644 --- a/packages/core/src/components/tabs/tabs.tsx +++ b/packages/core/src/components/tabs/tabs.tsx @@ -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; 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);