Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tabs and Subpages #86

Open
RingoRohe opened this issue Aug 28, 2023 · 6 comments
Open

Tabs and Subpages #86

RingoRohe opened this issue Aug 28, 2023 · 6 comments

Comments

@RingoRohe
Copy link

I'm trying to achieve a navigation stack with tabs and subpages but it seems like this is not possible at the current state. I took the tabs-demo and extended it with a subpage which is shown correctly but when navigating back the tab content stays blank because the ion-tab HTML element has still the tab-hidden class attached.

Demo here

So I decided to update ionic-svelte to the latest version but that made it even worse. With 0.5.82 I can't even navigate to a subpage. A button wich links to a subpage simply does nothing.

Is it me doing something wrong or is this simply not possible atm?

@Tommertom
Copy link
Owner

Hi there - I see indeed the class tab-hidden is added to the innertab. There is something in Tab.tsx that does that based on which tab is made active. And looking into Tab.tsx I see the activation is done by selecting the tab.

You can see this behaviour by invoking the blank page per your route change and then click the tab that should be shown.

So (in theory - I haven't tried this) - the button that says "go back" should bring the browser back to the /tab/test1 route and trigger the select method on the tabs, so ensure the tab is selected and shown again

Hope this helps

@burggraf
Copy link

Here's my workaround.
In my pages:

import { pushPathStack, popPathStack } from '$services/navigation.service'
const ionViewWillEnter = async () => {
	pushPathStack();
}

<ion-buttons slot="start">
	<ion-button
		on:click={() => {
			goto(popPathStack());
		}}>
		<ion-icon slot="icon-only" icon={allIonicIcons.arrowBackOutline} />
	</ion-button>
</ion-buttons>

navigation.service.ts:

export let pathStack: string[] = []

import { afterNavigate } from '$app/navigation';
import { base } from '$app/paths'

export const pushPathStack = async () => {
      afterNavigate(({from}) => {
        if (from !== null && from?.url !== null) {
            pathStack.push(from?.url.pathname || base || '/');
        } else {
            pathStack.push(base || '/');
        }
      });
}

export const popPathStack = () => {
    const path = pathStack.pop();
    return path || base || '/';
}

@RingoRohe
Copy link
Author

RingoRohe commented Aug 28, 2023

Thanks @Tommertom for pointing me into the right direction. I had a look into the IonTabs implementation and noticed that the goto (Line 32) was always pointing to the tab itself and not to the given path. Therefore navigating to subroutes of a tab was indeed not possible. I made my own implementation and changed it to navigate to the given path and selecting the related tab aftwerwards. Here is my Code:

<script lang="ts">
	// @ts-nocheck
	import { onMount } from 'svelte'
	import { page, navigating } from '$app/stores'

	import { goto } from '$app/navigation'

	export let ionTabsDidChange = () => {}
	export let ionTabsWillChange = () => {}
	export let slot = 'bottom'

	/**
    An array of tab objects containing label, icon, and tab properties.
    @type {{label: string; icon: string; tab: string;}[]}
    */
	export let tabs = []

	let ionTabBarElement
	let controller

	// we need relative path for the goto to function properly and to allow for relative tab definitions
	const { pathname } = $page.url
	const pathSplit = pathname.split('/')
	let currentTabName = pathSplit[pathSplit.length - 1] // we don't want to use at(-1) because of old browsers
	const relativePath = pathname.replace(currentTabName, '')

	// we need to capture the router changes - to support a-href navigation and other stuff
	$: if ($navigating && $navigating.to) {
		tabs.forEach(async (tab) => {
			console.log(tab.tab)
			if ($navigating.to.url.pathname.includes(relativePath + tab.tab)) {
				currentTabName = tab.tab
				await goto($navigating.to.url.pathname)
				controller.select(tab.tab)
			}
		})
	}

	onMount(async () => {
		// reassignment needed after onMount
		controller = ionTabBarElement
		controller.select(currentTabName)
	})

	const tabBarClick = async (selectedTab) => {
		currentTabName = selectedTab
		await goto(relativePath + selectedTab)
		controller.select(selectedTab)
	}
</script>

<ion-tabs
	on:ionTabsDidChange={ionTabsDidChange}
	on:ionTabsWillChange={ionTabsWillChange}
	bind:this={ionTabBarElement}
>
	<slot />

	{#if slot === 'bottom' || slot === ''}
		<ion-tab-bar slot="bottom">
			{#each tabs as tab}
				<ion-tab-button
					tab={tab.tab}
					on:keydown={() => {
						tabBarClick(tab.tab)
					}}
					on:click={() => {
						tabBarClick(tab.tab)
					}}
				>
					<ion-label>{tab.label}</ion-label>
					<ion-icon icon={tab.icon} />
				</ion-tab-button>
			{/each}
		</ion-tab-bar>
	{/if}

	{#if slot === 'top'}
		<ion-tab-bar slot="top">
			{#each tabs as tab}
				<ion-tab-button
					tab={tab.tab}
					on:keydown={() => {
						tabBarClick(tab.tab)
					}}
					on:click={() => {
						tabBarClick(tab.tab)
					}}
				>
					<ion-label>{tab.label}</ion-label>
					<ion-icon icon={tab.icon} />
				</ion-tab-button>
			{/each}
		</ion-tab-bar>
	{/if}
</ion-tabs>

I dont observed any side-effects by now and navigating throug the history also seem to work fine.

Thank you both. :)

@Tommertom
Copy link
Owner

Tommertom commented Jan 7, 2024

@RingoRohe - thx for the code contribution. I added it in IonTabs.svelte

And meanwhile I am also looking to rebuild ionic-svelte in order to resolve some of the issues with overlays and navigation.

This also means possible ditching IonTabs.svelte - see #91

What are you thoughts on this?

Happy hearing your views on a rebuild- #93

Same @burggraf ! Is your code snippet for Tabs or more for Nav? I rather rely on the router for IonTabs.

Thx

@MotionlessTrain
Copy link

@RingoRohe - thx for the code contribution. I added it in IonTabs.svelte

I was wondering whether there could be a release on NPM with this fix in it?
I was running into the same issue, with a tab "management" matching the "managementdetail" page, making it impossible to goto() the latter of those pages

@Tommertom
Copy link
Owner

@RingoRohe - thx for the code contribution. I added it in IonTabs.svelte

I was wondering whether there could be a release on NPM with this fix in it? I was running into the same issue, with a tab "management" matching the "managementdetail" page, making it impossible to goto() the latter of those pages

Released newest version with the pending PR and I believe also this change @MotionlessTrain

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants