Skip to content

Tree List

KTreeList is 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": "Components",
    "id": "components-folder",
    "children": [
      {
        "name": "ProfileCard.vue",
        "id": "profile-card"
      }
    ]
  },
  {
    "name": "Pages",
    "id": "pages-folder",
    "children": [
      {
        "name": "Home.vue",
        "id": "home"
      },
      {
        "name": "User",
        "id": "user-folder",
        "children": [
          {
            "name": "UserList.vue",
            "id": "user-list"
          },
          {
            "name": "UserDetail.vue",
            "id": "user-detail"
          },
          {
            "name": "Settings",
            "id": "settings-folder"
          }
        ]
      }
    ]
  },
  {
    "name": "Types",
    "id": "types-folder",
    "children": [
      {
        "name": "user.d.ts",
        "id": "user-types"
      }
    ]
  }
]
vue
<template>
  <KTreeList v-model="myList" />
  <KButton @click="reset">Reset</KButton>
  <b>Value:</b>
  <pre>{{ JSON.stringify(myList) }}</pre>
</template>

<script lang="ts" setup>
import type { TreeListItem } from '@kong/kongponents'

const items: TreeListItem[] = [
  {
    name: 'Components',
    id: 'components-folder',
    children: [
      {
        name: 'ProfileCard.vue',
        id: 'profile-card',
      },
    ],
  },
  {
    name: 'Pages',
    id: 'pages-folder',
    children: [
      {
        name: 'Home.vue',
        id: 'home',
      },
      ...
    ]
  }
]

const myList = ref<TreeListItem[]>(JSON.parse(JSON.stringify(items)))

const reset = (): void => {
  myList.value = JSON.parse(JSON.stringify(items))
}
</script>

items

An array of items that make up the tree.

ts
interface TreeListItem {
  name: string // text displayed as the label for the item
  id: string // a unique `string` used to identify the item (note: `id`'s must be unique across all items and their children)
  selected?: boolean
  children?: TreeListItem[] // an array of items that will be treated as children of the current item
}

DANGER

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

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

<script setup lang="ts">
import type { TreeListItem } from '@kong/kongponents'

const items = ref<TreeListItem[]>([
  {
    name: 'Components',
    id: 'components-folder',
    children: [
      {
        name: 'ProfileCard.vue',
        id: 'profile-card',
      },
    ],
  },
  {
    name: 'Pages',
    id: 'pages-folder',
    children: [
      {
        name: 'Home.vue',
        id: 'home',
      },
      {
        name: 'User',
        id: 'user-folder',
        children: [
          {
            name: 'UserList.vue',
            id: 'user-list',
          },
          {
            name: 'UserDetail.vue',
            id: 'user-detail',
          },
          {
            name: 'Settings',
            id: 'settings-folder',
          },
        ],
      },
    ],
  },
  {
    name: 'Types',
    id: 'types-folder',
    children: [{
      name: 'user.d.ts',
      id: 'user-types',
    }],
  },
])
</script>

disableDrag

Boolean to turn off drag-n-drop reordering of the list. Defaults to false.

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

maxDepth

Use this prop to customize the maximum supported depth of the tree. The default value is 3. The maximum supported value for maxDepth is 5.

NOTE

Try moving any item under the Settings item in the example below and compare it to any other example on this page.

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

width

You can pass a width string for the entire tree. By default it will take the full width.

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

hideIcons

Boolean to hide icons. Defaults to false.

html
<KTreeList hide-icons :items="items" />

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.

NOTE

When you provide an icon through item-icon slot it will be displayed regardless what hideIcons prop value is.

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 }">
    <InboxIcon v-if="item.id.includes('folder')" />
    <DataObjectIcon
      v-else
      :color="item.selected ? KUI_COLOR_TEXT_DECORATIVE_PURPLE : KUI_COLOR_TEXT_DECORATIVE_PURPLE_STRONG"
    />
  </template>
  <template #item-label="{ item }">
    <span v-if="item.id.includes('folder')">
      <strong>{{ item.name }}</strong>
    </span>
    <span v-else>
      {{ item.name }}
    </span>
  </template>
</KTreeList>

Events

change

Emitted when there is a change to the root level items. Event payload is object instance of ChangeEvent.

ts
interface ChangeEvent {
  items: TreeListItem[]
  target: TreeListItem // the changed item
}

child-change

Emitted when an item is added or removed at the non-root level. Event payload is object instance of ChildChangeEvent.

ts
interface ChildChangeEvent {
  parentId: string // id of the parent item
  children: TreeListItem[]
  target: TreeListItem // 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.

Released under the Apache-2.0 License.