Skip to content

Conversation

J-Sek
Copy link
Contributor

@J-Sek J-Sek commented Aug 30, 2025

  • ensure "register" is always called after "unregister" when moving nodes around
  • detect changed ID (when items are swapped or prepended to the list)

fixes #20934
closes #21890

Markup:

<template>
  <v-app theme="dark">
    <v-container class="d-flex flex-column ga-3" max-width="600">

      <v-alert color="blue-darken-3" text="1. move [Calendar] left" />
      <v-alert color="blue-darken-3" text="2. move [Dev Tools] right few times" />

      <v-treeview
        v-model:activated="activated"
        :items="items"
        item-value="title"
        activatable
        open-all
      >
        <template #append="{ item, depth, isFirst, isLast }">
          <v-icon-btn :disabled="!depth" icon="mdi-arrow-left" @click.stop="move(item, 'left')" />
          <v-icon-btn :disabled="isFirst" icon="mdi-arrow-up" @click.stop="move(item, 'up')" />
          <v-icon-btn :disabled="isLast" icon="mdi-arrow-down" @click.stop="move(item, 'down')" />
          <v-icon-btn :disabled="isFirst" icon="mdi-arrow-right" @click.stop="move(item, 'right')" />
        </template>
      </v-treeview>

    </v-container>
  </v-app>
</template>
<script setup>
  import { ref, shallowRef } from 'vue'

  const activated = ref([])
  const root = {
    id: 0,
    children: [
      {
        id: 1,
        title: 'Office Tools',
        children: [
          {
            id: 2,
            title: 'Calendar',
            children: [
              { id: 3, title: 'Notepad' },
            ],
          },
        ],
      },
      {
        id: 4,
        title: 'Dev Tools',
        children: [
          { id: 5, title: 'VS Code' },
          { id: 6, title: 'Figma' },
          { id: 7, title: 'Webstorm' },
        ],
      },
    ],
  }
  const items = shallowRef([...root.children])

  function findParent (id, items = [root]) {
    if (items.length === 0) return null
    return items.find(item => item.children?.some(c => c.id === id)) ??
      findParent(id, items.flatMap(item => item.children ?? []))
  }

  function findItemBefore (item) {
    return findParent(item.id).children
      .find((_, i, all) => all[i + 1]?.id === item.id)
  }

  function findItemAfter (item) {
    return findParent(item.id).children
      .find((_, i, all) => all[i - 1]?.id === item.id)
  }

  function detach (item) {
    const parent = findParent(item.id)
    parent.children.splice(parent.children.indexOf(item), 1)
    if (parent.children.length === 0) parent.children = undefined
  }

  function injectNextTo (item, target, after = true) {
    if (!target || target === root) return
    detach(item)
    const targetParent = findParent(target.id)
    targetParent.children.splice(targetParent.children.indexOf(target) + (after ? 1 : 0), 0, item)
    activated.value = [item.id]
  }

  function appendTo (item, target) {
    if (!target) return
    detach(item)
    target.children ??= []
    target.children.push(item)
    activated.value = [item.id]
  }

  function move (item, direction) {
    switch (direction) {
      case 'left':
        injectNextTo(item, findParent(item.id))
        break
      case 'up':
        injectNextTo(item, findItemBefore(item), false)
        break
      case 'right':
        appendTo(item, findItemBefore(item))
        break
      case 'down':
        injectNextTo(item, findItemAfter(item))
        break
    }
    items.value = [...root.children]
  }
</script>

@J-Sek J-Sek self-assigned this Aug 30, 2025
@J-Sek J-Sek added T: bug Functionality that does not work as intended/expected C: VTreeview C: VList labels Aug 30, 2025
@J-Sek J-Sek requested a review from KaelWD August 30, 2025 19:36
@J-Sek J-Sek added the E: nested Nested composable label Aug 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C: VList C: VTreeview E: nested Nested composable T: bug Functionality that does not work as intended/expected
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug Report][3.7.8] VTreeview: Unnecessary console warnings when adding node
1 participant