-
-
Save jamesdeantv/6607f0e252da9bc1fb9aed6cffbd78bd to your computer and use it in GitHub Desktop.
Hacky swipeable Ionic/Stencil tabs
This file contains hidden or 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
import { Component } from "@stencil/core"; | |
@Component({ tag: "page-tabs", styleUrl: "page-tabs.scss" }) | |
export class PageTabs | |
{ | |
private tabNames: Array<string>; | |
private slides: HTMLIonSlidesElement; | |
private tabs:HTMLIonTabsElement; | |
private getTabNames(tabs: HTMLIonTabsElement) | |
{ | |
this.tabs = tabs; | |
this.tabNames = []; | |
tabs.childNodes.forEach(node => | |
{ | |
if(node.nodeName === "ION-TAB") | |
{ | |
this.tabNames.push((node as HTMLIonTabElement).tab); | |
} | |
}); | |
} | |
private async slideChanged(slides: HTMLIonSlidesElement) | |
{ | |
const selectedSlideIndex = await slides.getActiveIndex(); | |
const selectedTabName = this.tabNames[selectedSlideIndex]; | |
this.tabs.select(selectedTabName); | |
} | |
private async tabBarChanged(tabBar: HTMLIonTabBarElement) | |
{ | |
if(!this.tabNames) return; | |
const selectedTabIndex = this.tabNames.indexOf(tabBar.selectedTab); | |
const selectedSlideIndex = await this.slides.getActiveIndex(); | |
if(selectedSlideIndex === selectedTabIndex) return; | |
await this.slides.slideTo(selectedTabIndex); | |
} | |
protected render() | |
{ | |
return ( | |
<ion-tabs ref={el => this.getTabNames(el as HTMLIonTabsElement)}> | |
<ion-slides ref={el => this.slides = el as HTMLIonSlidesElement} onIonSlideDidChange={e => this.slideChanged(e.srcElement as HTMLIonSlidesElement)}> | |
<ion-slide><page-home /></ion-slide> | |
<ion-slide><page-places /></ion-slide> | |
<ion-slide><page-search /></ion-slide> | |
<ion-slide><page-menu-chooser /></ion-slide> | |
<ion-slide><page-profile /></ion-slide> | |
</ion-slides> | |
<ion-tab tab="tab-home" component="div" style={{ "display": "none" }} /> | |
<ion-tab tab="tab-places" component="div" style={{ "display": "none" }} /> | |
<ion-tab tab="tab-search" component="div" style={{ "display": "none" }} /> | |
<ion-tab tab="tab-menu-chooser" component="div" style={{ "display": "none" }} /> | |
<ion-tab tab="tab-profile" component="div" style={{ "display": "none" }} /> | |
<ion-tab-bar slot="bottom" onIonTabBarChanged={e => this.tabBarChanged(e.srcElement as HTMLIonTabBarElement)}> | |
<ion-tab-button tab="tab-home"> | |
<ion-icon src="assets/svg/logo-icon.svg" /> | |
<ion-label>Início</ion-label> | |
</ion-tab-button> | |
<ion-tab-button tab="tab-places"> | |
<ion-icon src="./assets/places.svg" /> | |
<ion-label>Locais</ion-label> | |
</ion-tab-button> | |
<ion-tab-button tab="tab-search"> | |
<ion-icon src="./assets/search.svg" /> | |
<ion-label>Pesquisar</ion-label> | |
</ion-tab-button> | |
<ion-tab-button tab="tab-menu-chooser"> | |
<ion-icon src="./assets/menu-chooser.svg" /> | |
<ion-label>Cardápio</ion-label> | |
</ion-tab-button> | |
<ion-tab-button tab="tab-profile"> | |
<ion-icon src="./assets/profile.svg" /> | |
<ion-label>Perfil</ion-label> | |
</ion-tab-button> | |
</ion-tab-bar> | |
</ion-tabs> | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment