Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/runtime/components/Accordion.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ export interface AccordionItem {
trailingIcon?: IconProps['name']
slot?: string
content?: string
/** A unique value for the accordion item. Defaults to the index. */
/**
* A unique value for the accordion item. Defaults to the index.
* Also used as the Vue `key` for this item, so providing a stable value prevents
* accordion content (and its local state) from remounting when items are added, removed,
* or reordered.
*/
value?: string
disabled?: boolean
class?: any
Expand Down Expand Up @@ -106,7 +111,7 @@ const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.accordion ||
<AccordionItem
v-for="(item, index) in props.items"
v-slot="{ open }"
:key="index"
:key="get(item, props.valueKey as string) ?? index"
:value="get(item, props.valueKey as string) ?? String(index)"
:disabled="item.disabled"
data-slot="item"
Expand Down
10 changes: 7 additions & 3 deletions src/runtime/components/Tabs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ export interface TabsItem {
badge?: string | number | BadgeProps
slot?: string
content?: string
/** A unique value for the tab item. Defaults to the index. */
/**
* A unique value for the tab item. Defaults to the index.
* Also used as the Vue `key` for this item, so providing a stable value prevents tab
* content (and its local state) from remounting when items are added, removed, or reordered.
*/
value?: string | number
disabled?: boolean
class?: any
Expand Down Expand Up @@ -154,7 +158,7 @@ defineExpose({

<TabsTrigger
v-for="(item, index) of items"
:key="index"
:key="get(item, props.valueKey as string) ?? index"
:ref="el => setTriggerRef(index, el)"
:value="get(item, props.valueKey as string) ?? String(index)"
:disabled="item.disabled"
Expand Down Expand Up @@ -187,7 +191,7 @@ defineExpose({
</TabsList>

<template v-if="!!content">
<TabsContent v-for="(item, index) of items" :key="index" :value="get(item, props.valueKey as string) ?? String(index)" data-slot="content" :class="ui.content({ class: [uiProp?.content, item.ui?.content, item.class] })">
<TabsContent v-for="(item, index) of items" :key="get(item, props.valueKey as string) ?? index" :value="get(item, props.valueKey as string) ?? String(index)" data-slot="content" :class="ui.content({ class: [uiProp?.content, item.ui?.content, item.class] })">
<slot :name="((item.slot || 'content') as keyof TabsSlots<T>)" :item="(item as Extract<T, { slot: string; }>)" :index="index" :ui="ui">
{{ item.content }}
</slot>
Expand Down
Loading