bestguy / sveltestrap

Bootstrap 4 & 5 components for Svelte
https://sveltestrap.js.org
MIT License
1.3k stars 183 forks source link

Question: how to update the TabContent active tab programmatically? #485

Open jcalfee opened 2 years ago

jcalfee commented 2 years ago

I see the TabContent is reactive and using a context but the active boolean seems to have been missed. Should the active boolean be reactive?

TabPane


onMount(() => {
if (active) setActiveTab(tabId);
});

let tabOpen = active; //??? $: if ($activeTabId !== undefined) tabOpen = $activeTabId === tabId; $: classes = classnames('tab-pane', className, { active: tabOpen, show: tabOpen }); ...


How to update the active tab without clicking?  Changing the active property is not working.  Shouldn't the TabPane update the activeTabId in the context on any `active` that changes to true?
jcalfee commented 2 years ago

Here is a work-around that re-renders the TabContent only when the exported changeTab is called with a tab name that is not already showing:

<script>
  export let tab = 'one'

  let activeTab = tab
  let updateTab = 1

  export function changeTab(tabId) {
    if(activeTab !== tabId) {
      activeTab = tabId

      // https://github.com/bestguy/sveltestrap/issues/485
      updateTab++
    }
  }

  function tabChanged(tabId) {
    activeTab = tabId.detail
  }
</script>

{#key updateTab}
  <TabContent on:tab={tabChanged}>
    <TabPane tabId="join" tab="Join" active={activeTab === 'one'}>
      // ...
    </TabPane>
    // ...
  </TabContent>
{/key}
1u0n commented 2 years ago

Agree the active attribute should be reactive but it's currently not.

The {#key} approach crashed my app, so in order to programatically change the acive tab I had to resort to finding the <a> element inside the tab I want to move to and .click() on it. It works as expected.

nikolas commented 1 year ago

I ran into this issue as well. It's related to #319