bug: Tab navigation issue when running IONIC within Lit-Elements
See original GitHub issueHi. I am using IONIC within Lit-Element components and while most of the things work great, I have had a huge challenge in making Tab navigations work properly and had to hack around to make it work and what I have done so far does not seem right (code below).
There are quite a few problems:
-
The first tab contents do not load by default. Have tried a lot of different ways to make it work. But the content is always empty (unless I use the hack below)
-
Hash in the url does not change if I switch between the tabs. Again, tried multiple ways to make it work.
-
If you have a hash which, say points to the 3rd tab or so, it still ends up redirecting to the first tab when you load the page.
I am not sure if I am making the issue clear, but here is the code snippet.
/// <reference path="../../../types/graphql.d.ts" />
import { css, customElement, html, property } from 'lit-element';
import { checkLoginStatus } from '../../../scripts/auth.js';
import { TimecampusElement } from '../../../scripts/classes.js';
// Importing all components here.. Removed imports for brevity.
import '../../my-component/src/MyComponent.js';
@customElement('timecampus-landing')
export class TimecampusLanding extends TimecampusElement {
firstUpdated() {
let tabsController: any = this.shadowRoot.querySelector('ion-tabs');
let currentHash = window.location.hash;
// I HAVE TO MANUALLY CHECK THE CURRENT HASH HERE AND SELECT THE RIGHT TAB BASED ON THAT
switch (currentHash) {
case '#/landing/dashboard':
tabsController.select('tab-dashboard');
break;
case '#/landing/channels':
tabsController.select('tab-channels');
break;
case '#/landing/feeds':
tabsController.select('tab-feeds');
break;
case '#/landing/calendar':
tabsController.select('tab-calendar');
break;
default:
tabsController.select('tab-dashboard');
break;
}
this.emitEvent('ask-webpush', {});
}
// I WILL FILE A SEPARATE ISSUE FOR THIS, BUT THE IONIC VARIABLES (GLOBAL CSS FILE) DO NOT GO THROUGH SHADOW DOM.
static get styles() {
return css`
ion-buttons {
display: block !important;
}
ion-back-button {
display: block !important;
}
ion-tabs {
margin-top: 60px;
}
ion-tab-bar {
margin-bottom: 60px;
}
`;
}
emitEvent(eventKey, payload) {
console.log(`Emitting ${eventKey} with payload ${JSON.stringify(payload)}`);
let event = new CustomEvent(eventKey, {
detail: payload,
bubbles: true,
composed: true
});
this.dispatchEvent(event);
}
// THIS IS A TAB CHANGE HANDLER FUNCTION WHICH LISTENS TO CHANGES AND SETS THE URL MANUALLY SINCE THE URL WAS NOT CHANGING BY ITSELF.
tabChangeHandler(event) {
switch (event.detail.tab) {
case 'tab-dashboard':
this.currentTabTitle = 'Dashboard';
window.history.pushState({}, "Dashboard", "#/landing/dashboard");
break;
case 'tab-channels':
this.currentTabTitle = 'Channels';
window.history.pushState({}, "Channels", "#/landing/channels");
break;
case 'tab-feeds':
this.currentTabTitle = 'Feeds';
window.history.pushState({}, "Feeds", "#/landing/feeds");
break;
case 'tab-calendar':
this.currentTabTitle = 'Calendar';
window.history.pushState({}, "Calendar", "#/landing/calendar");
break;
default:
break;
}
}
@property({ type: String }) title;
@property({ type: String }) currentTabTitle = '';
render() {
return html`
<timecampus-header id="landingHeader"
page_title=${this.currentTabTitle}
back_button="disabled"
search_bar="enabled"
notification_button="enabled"
applaunch_button="enabled"
>
</timecampus-header>
<ion-tabs @ionTabsDidChange="${this.tabChangeHandler}">
<ion-tab tab="tab-dashboard" component="me-dashboard">
</ion-tab>
<ion-tab tab="tab-channels" component="me-channels">
</ion-tab>
<ion-tab tab="tab-feeds" component="me-feeds">
</ion-tab>
<ion-tab tab="tab-calendar" component="me-calendar">
</ion-tab>
<ion-tab-bar slot="bottom">
<ion-tab-button tab="tab-dashboard">
<ion-label>Dashboard</ion-label>
<ion-icon name="home"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="tab-channels">
<ion-label>Channels</ion-label>
<ion-icon name="watch"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="tab-feeds">
<ion-label>Feeds</ion-label>
<ion-icon name="contacts"></ion-icon>
</ion-tab-button>
<ion-tab-button tab="tab-calendar">
<ion-label>Calendar</ion-label>
<ion-icon name="calendar"></ion-icon>
</ion-tab-button>
</ion-tab-bar>
</ion-tabs>
`;
}
}
And I have something like this in my ion-router
which is what I am using to enable navigation. I tried what was given in the docs like providing the tab navigations nested within the the route but faced a lot of issues with that and hence had to resort to this.
<ion-router>
<ion-route url="/landing/:tabID" component="timecampus-landing"></ion-route>
</ion-router>
While the product is not completely ready, you can see a live demo of this at https://app.timecampus.com/
Issue Analytics
- State:
- Created 4 years ago
- Comments:5 (1 by maintainers)
Top GitHub Comments
@TimPietrusky All these problems arise because of the lack of native shadow dom support: https://github.com/ionic-team/ionic-framework/issues/22122#issuecomment-696130707
I ended up using vaadin-router and am using IONIC just for UI now because of this.
Thanks for the issue! This issue is being closed due to the lack of a reply. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.
Thank you for using Ionic!