diff --git a/example/src/views/TabView.vue b/example/src/views/TabView.vue index 13f142b5..8a9a217c 100644 --- a/example/src/views/TabView.vue +++ b/example/src/views/TabView.vue @@ -96,9 +96,12 @@ const tabs = ref([ Tab 2 - Tab 3 - Tab 4 - Tab 5 + + Tab {{ n + 2 }} + ([ v-model="data.modelValue" data-cy="tab-items" > - - Tab 1 Content - - - Tab 2 Content - - - Tab 3 Content - - - Tab 4 Content + + Tab {{ n }} Content diff --git a/src/components/tabs/tab-items/RuiTabItems.vue b/src/components/tabs/tab-items/RuiTabItems.vue index 6211e525..918db183 100644 --- a/src/components/tabs/tab-items/RuiTabItems.vue +++ b/src/components/tabs/tab-items/RuiTabItems.vue @@ -23,14 +23,21 @@ watch(currIndex, (index) => { }); }); +// When using dynamic content with v-for the slot content can contain fragment, +// Go through the fragment and always return RuiTabItem only +function getChildrenTabs(children: VNode[]): VNode[] { + return children.flatMap((item) => { + if (item.type === Fragment && Array.isArray(item.children) && item.children.length > 0) + return getChildrenTabs(item.children.filter(isVNode)); + + return [item]; + }).flat(); +} + const children = computed(() => { const slotContent = slots.default?.() ?? []; - // When using dynamic content with v-for the slot content is a single fragment - // containing the children components. - const tabs = slotContent.length === 1 && slotContent[0].type === Fragment - ? Array.isArray(slotContent[0].children) ? slotContent[0].children.filter(isVNode) : [] - : slotContent; + const tabs = getChildrenTabs(slotContent); let anyActive = false; const children = tabs.map((tab, index) => { diff --git a/src/components/tabs/tabs/RuiTabs.vue b/src/components/tabs/tabs/RuiTabs.vue index 4bfbe5e8..171419f2 100644 --- a/src/components/tabs/tabs/RuiTabs.vue +++ b/src/components/tabs/tabs/RuiTabs.vue @@ -1,11 +1,11 @@