diff --git a/packages/core/src/components/nav/nav.tsx b/packages/core/src/components/nav/nav.tsx index bae73fff57..c01eaed855 100644 --- a/packages/core/src/components/nav/nav.tsx +++ b/packages/core/src/components/nav/nav.tsx @@ -223,6 +223,11 @@ export class NavControllerBase implements NavOutlet { return null; } + @Method() + markVisible() { + return Promise.resolve(); + } + @Method() getContentElement(): HTMLElement { const active = this.getActive(); diff --git a/packages/core/src/components/nav/readme.md b/packages/core/src/components/nav/readme.md index e93d32fb64..764ff09032 100644 --- a/packages/core/src/components/nav/readme.md +++ b/packages/core/src/components/nav/readme.md @@ -71,6 +71,9 @@ Return a view controller #### insertPages() +#### markVisible() + + #### pop() diff --git a/packages/core/src/components/router/utils/dom.ts b/packages/core/src/components/router/utils/dom.ts index 58811dfa1a..32f42bdff2 100644 --- a/packages/core/src/components/router/utils/dom.ts +++ b/packages/core/src/components/router/utils/dom.ts @@ -18,9 +18,11 @@ export function writeNavState(root: HTMLElement, chain: RouteChain, index: numbe } const nextEl = node.getContentElement(); if (nextEl) { - return writeNavState(nextEl, chain, index + 1, direction); + return writeNavState(nextEl, chain, index + 1, direction) + .then(() => node.markVisible()); + } else { + return node.markVisible(); } - return null; }); } diff --git a/packages/core/src/components/router/utils/interfaces.ts b/packages/core/src/components/router/utils/interfaces.ts index 27ff638cc5..a53d676113 100644 --- a/packages/core/src/components/router/utils/interfaces.ts +++ b/packages/core/src/components/router/utils/interfaces.ts @@ -1,7 +1,9 @@ export interface NavOutlet { setRouteId(id: any, data: any, direction: number): Promise; + markVisible(): Promise; getRouteId(): string; + getContentElement(): HTMLElement | null; } diff --git a/packages/core/src/components/tab/tab.tsx b/packages/core/src/components/tab/tab.tsx index 8b8c877d04..3d8659570a 100644 --- a/packages/core/src/components/tab/tab.tsx +++ b/packages/core/src/components/tab/tab.tsx @@ -9,7 +9,7 @@ import { asyncRaf } from '../../utils/helpers'; export class Tab { private loaded = false; - @Element() el: HTMLElement; + @Element() el: HTMLIonTabElement; @State() init = false; @@ -92,7 +92,7 @@ export class Tab { } @Method() - setActive(): Promise { + setActive(): Promise { return this.prepareLazyLoaded().then(() => this.showTab()); } @@ -104,9 +104,9 @@ export class Tab { return Promise.resolve(); } - private showTab(): Promise { + private showTab(): Promise { this.active = true; - return Promise.resolve(); + return Promise.resolve(this.el); } hostData() { diff --git a/packages/core/src/components/tabs/readme.md b/packages/core/src/components/tabs/readme.md index 6fbb10994c..c3424fd3f4 100644 --- a/packages/core/src/components/tabs/readme.md +++ b/packages/core/src/components/tabs/readme.md @@ -240,6 +240,9 @@ Emitted when the tab changes. #### getTabs() +#### markVisible() + + #### select() diff --git a/packages/core/src/components/tabs/tabs.tsx b/packages/core/src/components/tabs/tabs.tsx index d195063eb2..28439114aa 100644 --- a/packages/core/src/components/tabs/tabs.tsx +++ b/packages/core/src/components/tabs/tabs.tsx @@ -9,6 +9,8 @@ import { Config, NavOutlet } from '../../index'; export class Tabs implements NavOutlet { private ids = -1; private transitioning = false; + private routingView: HTMLIonTabElement; + private tabsId: number = (++tabIds); @Element() el: HTMLElement; @@ -73,10 +75,7 @@ export class Tabs implements NavOutlet { } componentDidLoad() { - return this.initTabs().then(() => { - const useRouter = !!document.querySelector('ion-router'); - return useRouter ? this.initSelect() : Promise.resolve(); - }); + return this.initTabs().then(() => this.initSelect()); } componentDidUnload() { @@ -95,37 +94,8 @@ export class Tabs implements NavOutlet { */ @Method() select(tabOrIndex: number | HTMLIonTabElement): Promise { - if (this.transitioning) { - return Promise.resolve(false); - } - const selectedTab = (typeof tabOrIndex === 'number' ? this.getByIndex(tabOrIndex) : tabOrIndex); - if (!selectedTab) { - return Promise.resolve(false); - } - - // Reset rest of tabs - for (const tab of this.tabs) { - if (selectedTab !== tab) { - tab.selected = false; - } - } - - const leavingTab = this.selectedTab; - this.transitioning = true; - return selectedTab.setActive().then(() => { - this.transitioning = false; - selectedTab.selected = true; - if (leavingTab !== selectedTab) { - if (leavingTab) { - leavingTab.active = false; - } - this.selectedTab = selectedTab; - this.ionChange.emit(selectedTab); - this.ionNavChanged.emit({isPop: false}); - return true; - } - return false; - }); + return this.setActive(tabOrIndex) + .then(selectedTab => this.tabSwitch(selectedTab)); } /** @@ -161,9 +131,18 @@ export class Tabs implements NavOutlet { return Promise.resolve(false); } const tab = this.tabs.find(t => id === t.getRouteId()); - return this.select(tab).then(() => true); + return this.setActive(tab).then(() => { + this.routingView = tab; + return true; + }); } + @Method() + markVisible(): Promise { + this.tabSwitch(this.routingView); + this.routingView = null; + return Promise.resolve(); + } @Method() getRouteId(): string|null { @@ -176,7 +155,7 @@ export class Tabs implements NavOutlet { @Method() getContentElement(): HTMLElement { - return this.selectedTab; + return this.routingView || this.selectedTab; } private initTabs() { @@ -191,7 +170,7 @@ export class Tabs implements NavOutlet { return Promise.all(tabPromises); } - private initSelect() { + private initSelect(): Promise { if (document.querySelector('ion-router')) { return Promise.resolve(); } @@ -205,7 +184,7 @@ export class Tabs implements NavOutlet { tab.selected = false; } } - const promise = selectedTab ? selectedTab.setActive() : Promise.resolve(); + const promise = selectedTab ? selectedTab.setActive() : Promise.resolve(null); return promise.then(() => { this.selectedTab = selectedTab; if (selectedTab) { @@ -222,6 +201,45 @@ export class Tabs implements NavOutlet { } } + private setActive(tabOrIndex: number | HTMLIonTabElement): Promise { + if (this.transitioning) { + return Promise.resolve(null); + } + const selectedTab = (typeof tabOrIndex === 'number' ? this.getByIndex(tabOrIndex) : tabOrIndex); + if (!selectedTab) { + return Promise.resolve(null); + } + + // Reset rest of tabs + for (const tab of this.tabs) { + if (selectedTab !== tab) { + tab.selected = false; + } + } + + this.transitioning = true; + return selectedTab.setActive(); + } + + private tabSwitch(selectedTab: HTMLIonTabElement | null): boolean { + this.transitioning = false; + if (!selectedTab) { + return false; + } + const leavingTab = this.selectedTab; + selectedTab.selected = true; + if (leavingTab !== selectedTab) { + if (leavingTab) { + leavingTab.active = false; + } + this.selectedTab = selectedTab; + this.ionChange.emit(selectedTab); + this.ionNavChanged.emit({isPop: false}); + return true; + } + return false; + } + render() { const dom = [