Skip to content

Tree List

KTreeList - A drag-n-drop reorderable list component.

html
<KTreeList :items="items" />

Props

v-model

KTreeList works with v-model for data binding.

NOTE

The value provided to v-model should adhere to all the same constraints of the items property.


Value:
[{"name":"Cats","id":"cats","selected":true},{"name":"Dogs","id":"dogs","children":[{"name":"Puppies","id":"puppies"}]},{"name":"Bunnies","id":"bunnies"}]
html
<template>
  <KTreeList v-model="myList" />
  <KButton @click="reset">Reset</KButton>
  <b>Value:</b>
  <pre>{{ JSON.stringify(myList) }}</pre>
</template>

<script lang="ts" setup>
import { ref } from 'vue'

const myList = ref([
  {
    name: "Cats",
    id: 'cats'
    selected: true
  },
  {
    name: "Dogs",
    id: 'dogs',
    children: [{
      name: "Puppies",
      id: 'puppies'
    }]
  },
  {
    name: "Bunnies",
    id: 'bunnies'
  }])

  const reset = () => {
    myList.value = [{
      name: "Cats",
      id: 'cats',
      selected: true
    },
    {
      name: "Dogs",
      id: 'dogs',
      children: [{
        name: "Puppies",
        id: 'puppies'
      }]
    },
    {
      name: "Bunnies",
      id: 'bunnies'
    }
  ]
}
</script>

items

An array of items that make up the tree.

Item properties:

  • name (required) - text displayed as the label for the item
  • id (required) - a unique string used to identify the item (Note: id's must be unique across all items and their children)
  • selected - boolean to indicate whether the current item is selected or not
  • icon - string of the KIcon icon name to be displayed to the left of the item name (defaults to documentList, specify none to not display any icon)
  • children - an array of items that will be styled as children of the current item (Note: all children must have the same property constraints as items)

DANGER

You cannot use v-model with the items prop. You must use one or the other.

html
<template>
  <KTreeList :items="items" />
</template>

<script setup lang="ts">
import { ref } from 'vue'

const items = ref([
  {
    name: "Cats",
    id: 'cats'
  },
  {
    name: "Dogs",
    id: 'dogs',
    children: [{
      name: "Puppies",
      id: 'puppies'
    }]
  },
  {
    name: "Bunnies",
    id: 'bunnies'
  }
])
</script>

disableDrag

Boolean (defaults to false) to turn off drag-n-drop reordering of the list.

html
<KTreeList disable-drag :items="items" />

maxDepth

Use this prop to customize the maximum supported depth of the tree. We default to a max depth of 3.

NOTE

The maximum supported value for maxDepth is 5.

html
<KTreeList :items="items" :max-depth="5" />

width

You can pass a width string for the entire tree. By default it will take the full width. Currently we support numbers (will be converted to px), auto, and percentages for width.

html
<KTreeList :items="items" width="70%" />

Slots

KTreeList allows you to customize individual tree items via the item slots. The slots provide the current item data as a slot param.

  • item-icon - slot for content displayed to the left of the item name in place of the default icon
  • item-label - slot for the main content of an item (defaults to the name of the item)
html
<KTreeList :items="items">
  <template #item-icon="{ item }">
    {{ item.id === 'cats' ? '😸' : item.id === 'bunnies' ? '🐰' : '🐶' }}
  </template>
  <template #item-label="{ item }">
    <span class="slot-color-purple">
    Animal: {{ item.name }}
    </span>
  </template>
</KTreeList>

Events

  • @change - emitted when there is a change to the root level items
    • returns items - an array of tree items; target - the changed item
  • @child-change - emitted when an item is added or removed at the non-root level
    • returns parentId - id of the parent item; children - an array of tree items; target - the changed item
    • Note: two separate child-change events will fire if an item is moved from one parent to another
  • @selected - emitted when you click (and don't drag) an item; returns the selected item's data

[{"name":"Cats","id":"cats"},{"name":"Dogs","id":"dogs","children":[{"name":"Puppies","id":"puppies"}]},{"name":"Bunnies","id":"bunnies"}]
html
<template>
  <KLabel>Selected: </KLabel> {{ mySelection && mySelection.name || '' }}
  <KLabel>Items: </KLabel> {{ myItems }}
  <KTreeList
    :items="myItems"
    @selected="(item) => mySelection = item"
    @change="({ items }) => myItems = items"
    @child-change="handleChildChange"
  />
</template>

<script lang="ts" setup>
  import { ref } from 'vue'

  const mySelection = ref(null)
  const handleChildChange = (data) => {
    const { parentId, children, target } = data
    const changedParent = myItems.value.find(item => item.id === parentId)
    changedParent.children = children
  }
</script>

Theming

VariablePurpose
--KTreeListItemTextText color for the item name
--KTreeListItemSelectedBorderBorder color of a selected item and color of indicator bar when dragging an item
--KTreeListItemSelectedBackgroundBackground color of a selected item
--KTreeListItemUnselectedBorderBorder color of an unselected item and color of connecting line between parents and children
--KTreeListItemUnselectedBackgroundBackground color of an unselected item
--KTreeListDropZoneHeightNumber of pixels between tree items

An example of changing the theming might look like this:

html
<template>
  <KTreeList class="themed-tree" :items="items" />
</template>

<style>
.themed-tree {
  --KTreeListItemText: #473cfb;
  --KTreeListItemSelectedBorder: #ffd68c;
  --KTreeListItemSelectedBackground: #ffe6ba;
  --KTreeListItemUnselectedBorder: #9396fc;
  --KTreeListItemUnselectedBackground: #eaf4fb;
  --KTreeListDropZoneHeight: 8px;
}
</style>

Released under the Apache-2.0 License.