Jacobs63 / vue3-tabs-component

Vue 3 tabs component
MIT License
96 stars 27 forks source link

Remembering the last tab... with two Tabs component instances on a page #43

Closed karlskidmore closed 1 year ago

karlskidmore commented 1 year ago

Remembering the last tab when there are two Tabs component instances on a page results in the last tab selected being remembered. I've worked around this, but think it would be great if, say, an id prop was embedded in the cache key. Good for nested tab UIs too.

Jacobs63 commented 1 year ago

Hello,

it is true that the tabs component has the same cache key for all instances.

I agree, that perhaps the computed ID could serve as a unique key for storing the active tab, preferably with an option to set the key explicitly, in case the user would purposely like to have multiple tabs components share the active tab.

I'll take a look next week, as I'm currently unable to.

Thank you for the report.

karlskidmore commented 1 year ago

Great component BTW!

preferably with an option to set the key explicitly, in case the user would purposely like to have multiple tabs components share the active tab

I can see how that would be a very useful feature.

FYI, and in case you think it a good idea to add for others.... I wrote a small wrapper around your component that supports nested tabs (i.e. Tabs → Tab → Tabs → Tab...). The nested Tabs Wrapper takes two props parentTabHash and parentTabsRef and brings forward the parent tab if the url fragment matches a nested Tab hash. This could actually live inside your Tabs component though. I'd do a PR but I'm not familiar with ts and don't have a build env setup either 🤷‍♂️

<template>
    <Tabs
        v-bind="$attrs"
        ref="tabs"
        :cache-lifetime="parentTabHash ? 0 : 5"
        @changed="tabChanged"
    >
        <slot></slot>
    </Tabs>
</template>

<script>
import { Tabs } from "vue3-tabs-component";

export default {
    name: "TabsWrapper",
    props: {
        parentTabsRef: {
            type: Function,
            default: () => ({}),
        },
        parentTabHash: {
            type: String,
            default: null,
        },
    },
    methods: {
        tabChanged() {
            // Called implicitly on page load by tabs component emitting very first 'changed' event
            // and again whenever tab is changed

            // If we're a nested tabs component and the fragment is one of our tabs
            // then inform the parent component to bring forward the relevant parent tab
            if (this.parentTabHash) {
                ((hash = window.location.hash) => {
                    if (hash && this.$refs.tabs.findTab(hash)) {
                        this.parentTabsRef().$refs.tabs.selectTab(this.parentTabHash);
                    }
                })();
            }
        },
    },
    ...
    ...
    ...
Jacobs63 commented 1 year ago

Hello,

latest version 1.3.6 now includes the calculcated storage key from an id Tabs component prop and also an option to set the storage key explicitly via the options.storageKey prop.

karlskidmore commented 1 year ago

Nice one!