Skip to content

UAccordion + useSortable causes DOM desync when reordering and adding items #5819

@beingmomen

Description

@beingmomen

Description

When using useSortable (SortableJS / VueUse) with UAccordion, sorting works initially, but adding a new item after sorting causes it to appear in an incorrect position in the UI, even though the underlying array order is correct.

This seems to be caused by a DOM ↔ Vue state desynchronization related to how UAccordion renders its internal structure.


Reproduction

<UAccordion
  ref="accordion"
  :items="items"
/>

<script setup>
useSortable(accordion, items, { animation: 150 })
</script>

Steps:

  1. Render a single UAccordion with an items array
  2. Attach useSortable to it
  3. Reorder items via drag & drop
  4. Push a new item to the array

Result: new item renders in a random position in the UI.


Root Cause

  • useSortable / SortableJS mutates DOM directly
  • UAccordion is a single component that renders its items internally
  • The ref points to the component instance, not the actual sortable DOM children
  • Vue is not aware of DOM reordering done by SortableJS

When Vue re-renders after adding an item, the DOM no longer matches Vue’s expectations.


Working Workaround

Render one accordion per item so each is a direct DOM child:

<div ref="sortableContainer">
  <UAccordion
    v-for="item in items"
    :key="item.id"
    :items="[item]"
  />
</div>

<script setup>
useSortable(sortableContainer, items, { animation: 150 })
</script>

This works because SortableJS can safely operate on direct DOM children and Vue can correctly track them via keys.


Suggestion

  • Document that UAccordion is not compatible with useSortable when using the items prop
  • Or expose refs / slots that allow sortable-friendly DOM structures

Environment

  • @nuxt/ui: v3
  • Vue: 3.x
  • SortableJS via VueUse

Metadata

Metadata

Assignees

No one assigned

    Labels

    duplicateThis issue or pull request already existstriageAwaiting initial review and prioritization

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions