Full Redraw + State Preservation

After drag-drop, save to database and reload the entire tree. Expanded folders are preserved automatically.

Use case: When your backend owns the data and you need a full refresh after changes (e.g., server-side sorting, computed paths).

Events: onNodeDrop(dropNode, draggedNode, position, event, operation)
Your code:
1. Call getExpandedPaths() before changes
2. Save to DB
3. Reload data array
4. await tick(), then setExpandedPaths()
Key methods: getExpandedPaths() / setExpandedPaths()

Source Tree (drag from here)

Target Tree

Activity Log

No activity yet. Try dragging nodes or using the controls above.

Mock Database (9 records)
[
  {
    "id": 100,
    "path": "1",
    "name": "Projects",
    "icon": "📁",
    "sortOrder": 10
  },
  {
    "id": 101,
    "path": "1.1",
    "name": "Project Alpha",
    "icon": "📁",
    "sortOrder": 10
  },
  {
    "id": 102,
    "path": "1.1.1",
    "name": "Specs.doc",
    "icon": "📄",
    "sortOrder": 10
  },
  {
    "id": 103,
    "path": "1.1.2",
    "name": "Design.fig",
    "icon": "🎨",
    "sortOrder": 20
  },
  {
    "id": 104,
    "path": "1.2",
    "name": "Project Beta",
    "icon": "📁",
    "sortOrder": 20
  },
  {
    "id": 105,
    "path": "1.2.1",
    "name": "README.md",
    "icon": "📄",
    "sortOrder": 10
  },
  {
    "id": 106,
    "path": "2",
    "name": "Archive",
    "icon": "📁",
    "sortOrder": 20
  },
  {
    "id": 107,
    "path": "2.1",
    "name": "Old Files",
    "icon": "📁",
    "sortOrder": 10
  },
  {
    "id": 108,
    "path": "2.1.1",
    "name": "Legacy.zip",
    "icon": "📦",
    "sortOrder": 10
  }
]

Full Code Example - Scenario A

<script>
  import { tick } from 'svelte';
  import { Tree } from '@keenmate/svelte-treeview';

  let treeRef;
  let treeData = $state([...initialData]);
  let isLoading = $state(false);

  async function handleDrop(dropNode, draggedNode, position, event, operation) {
    // 1. Save expanded state BEFORE any changes
    const expandedPaths = treeRef.getExpandedPaths();

    isLoading = true;

    // 2. Save to database
    await saveToDatabase({
      nodeId: draggedNode.data.id,
      newParentPath: dropNode?.path,
      position: position // 'above' | 'below' | 'child'
    });

    // 3. Reload FULL tree from database
    treeData = await fetchTreeFromDatabase();

    // 4. Restore expanded state after data updates
    await tick();
    treeRef.setExpandedPaths(expandedPaths);

    isLoading = false;
  }
</script>

<Tree
  bind:this={treeRef}
  data={treeData}
  idMember="id"
  pathMember="path"
  orderMember="sortOrder"
  onNodeDrop={handleDrop}
  {isLoading}
/>