title: File Tree
description: A component used to showcase the folder and file structure of a directory.
---

```vue
<template>
  <Tree
    class="overflow-hidden rounded-md bg-background p-2"
    :initial-selected-id="'1'"
    :initial-expanded-items="[
      '1',
      '2',
      '3',
      '4',
      '5',
      '6',
      '7',
      '8',
      '9',
      '10',
      '11',
      '12',
      '13',
      '14',
      '15',
      '16',
      '17',
      '18',
      '19',
    ]"
    :elements="ELEMENTS"
  >
    <Folder
      id="1"
      name="root"
    >
      <Folder
        id="2"
        name="components"
      >
        <Folder
          id="3"
          name="ui"
        >
          <File
            id="4"
            name="Button.vue"
          />
          <File
            id="5"
            name="Card.vue"
          />
          <File
            id="6"
            name="Input.vue"
          />
        </Folder>
        <File
          id="7"
          name="Header.vue"
        />
        <File
          id="8"
          name="Footer.vue"
        />
      </Folder>
      <Folder
        id="9"
        name="composables"
      >
        <File
          id="10"
          name="useAuth.ts"
          :is-selectable="false"
        />
        <File
          id="11"
          name="useTheme.ts"
        />
      </Folder>
      <Folder
        id="12"
        name="layouts"
      >
        <File
          id="13"
          name="default.vue"
        />
        <File
          id="14"
          name="auth.vue"
          :is-selectable="false"
        />
      </Folder>
      <Folder
        id="15"
        name="pages"
      >
        <File
          id="16"
          name="index.vue"
        />
        <File
          id="17"
          name="about.vue"
        />
        <Folder
          id="18"
          name="auth"
          :is-selectable="false"
        >
          <File
            id="19"
            name="login.vue"
          />
          <File
            id="20"
            name="register.vue"
          />
        </Folder>
      </Folder>
      <File
        id="21"
        name="app.vue"
      />
      <File
        id="22"
        name="nuxt.config.ts"
      />
    </Folder>
  </Tree>
</template>

<script setup lang="ts">
import type { TreeViewElement } from "~/components/content/inspira/ui/file-tree/index";

const ELEMENTS: TreeViewElement[] = [
  {
    id: "1",
    isSelectable: true,
    name: "root",
    children: [
      {
        id: "2",
        isSelectable: true,
        name: "components",
        children: [
          {
            id: "3",
            isSelectable: true,
            name: "ui",
            children: [
              { id: "4", isSelectable: true, name: "Button.vue" },
              { id: "5", isSelectable: true, name: "Card.vue" },
              { id: "6", isSelectable: true, name: "Input.vue" },
            ],
          },
          { id: "7", isSelectable: true, name: "Header.vue" },
          { id: "8", isSelectable: true, name: "Footer.vue" },
        ],
      },
      {
        id: "9",
        isSelectable: true,
        name: "composables",
        children: [
          { id: "10", isSelectable: false, name: "useAuth.ts" },
          { id: "11", isSelectable: true, name: "useTheme.ts" },
        ],
      },
      {
        id: "12",
        isSelectable: true,
        name: "layouts",
        children: [
          { id: "13", isSelectable: true, name: "default.vue" },
          { id: "14", isSelectable: false, name: "auth.vue" },
        ],
      },
      {
        id: "15",
        isSelectable: true,
        name: "pages",
        children: [
          { id: "16", isSelectable: true, name: "index.vue" },
          { id: "17", isSelectable: true, name: "about.vue" },
          {
            id: "18",
            isSelectable: false,
            name: "auth",
            children: [
              { id: "19", isSelectable: true, name: "login.vue" },
              { id: "20", isSelectable: true, name: "register.vue" },
            ],
          },
        ],
      },
      { id: "21", isSelectable: true, name: "app.vue" },
      { id: "22", isSelectable: true, name: "nuxt.config.ts" },
    ],
  },
];
</script>

```

## Install using CLI

```vue
<InstallationCli component-id="file-tree" />
```

## Install Manually

Copy and paste the following code in the same folder

::code-group

:CodeViewerTab{label="Tree.vue" language="vue" componentName="Tree" type="ui" id="file-tree"}
:CodeViewerTab{label="Folder.vue" language="vue" componentName="Folder" type="ui" id="file-tree"}
:CodeViewerTab{label="File.vue" language="vue" componentName="File" type="ui" id="file-tree"}
:CodeViewerTab{label="TreeIndicator.vue" language="vue" componentName="TreeIndicator" type="ui" id="file-tree"}

```ts [index.ts]
import type { HTMLAttributes } from "vue";

export interface TreeProps {
  class?: HTMLAttributes["class"];
  initialSelectedId: string;
  indicator?: boolean;
  elements: TreeViewElement[];
  initialExpandedItems: string[];
  openIcon?: string;
  closeIcon?: string;
  fileIcon?: string;
  direction?: "rtl" | "ltr";
}

export interface TreeContextProps {
  selectedId: Ref<string | undefined>;
  expandedItems: Ref<string[] | undefined>;
  indicator: boolean;
  openIcon: string;
  closeIcon: string;
  fileIcon: string;
  direction: "rtl" | "ltr";
  handleExpand: (id: string) => void;
  selectItem: (id: string) => void;
  setExpandedItems: (items: string[] | undefined) => void;
}

export interface TreeViewElement {
  id: string;
  name: string;
  isSelectable?: boolean;
  children?: TreeViewElement[];
}

export interface BaseItemProps {
  class?: HTMLAttributes["class"];
  id: string;
  name: string;
  isSelectable?: boolean;
  isSelect?: boolean;
}

export interface FolderProps extends BaseItemProps {}

export interface FileProps extends BaseItemProps {}

export const TREE_CONTEXT_SYMBOL = Symbol("TREE_CONTEXT_SYMBOL");

export { default as Tree } from "./Tree.vue";
export { default as Folder } from "./Folder.vue";
export { default as File } from "./File.vue";
```

::

## API

::steps

### `Tree`

The `Tree` component serves as a container for displaying a hierarchical file/folder structure.

#### Props

| Prop Name              | Type                | Default                | Description                                        |
| ---------------------- | ------------------- | ---------------------- | -------------------------------------------------- |
| `class`                | `string`            | -                      | Additional classes for styling the tree container. |
| `initialSelectedId`    | `string`            | -                      | ID of the initially selected item.                 |
| `indicator`            | `boolean`           | `true`                 | Whether to show the tree indicator line.           |
| `elements`             | `TreeViewElement[]` | -                      | Array of tree elements to display.                 |
| `initialExpandedItems` | `string[]`          | -                      | Array of IDs of initially expanded folders.        |
| `openIcon`             | `string`            | `"lucide:folder-open"` | Icon to show for open folders.                     |
| `closeIcon`            | `string`            | `"lucide:folder"`      | Icon to show for closed folders.                   |
| `fileIcon`             | `string`            | `"lucide:file"`        | Icon to show for files.                            |
| `direction`            | `"rtl" \| "ltr"`    | `"ltr"`                | Text direction of the tree.                        |

#### Usage

```vue [MyComponent.vue]
<Tree initialSelectedId="1" :initial-expanded-items="['1', '2']" :elements="ELEMENTS">
  <!-- Your structure here -->
</Tree>
```

### `Folder` and `File`

The `Folder` and `File` components represent folders and files in the file tree. Folders can contain other `Folder` and `File` components.

#### Props

| Prop Name      | Type      | Default | Description                             |
| -------------- | --------- | ------- | --------------------------------------- |
| `class`        | `string`  | -       | Additional classes for custom styling.  |
| `id`           | `string`  | -       | Unique identifier for the item.         |
| `name`         | `string`  | -       | Display name of the folder/file.        |
| `isSelectable` | `boolean` | `true`  | Whether the item can be selected.       |
| `isSelect`     | `boolean` | `false` | Whether the item is currently selected. |

#### Usage

```vue [MyComponent.vue]
<Folder id="1" name="root">
  <Folder id="2" name="components">
    <File id="3" name="Button.vue" />
    <File id="4" name="Card.vue" />
  </Folder>
</Folder>
```

::

## Credits

- Inspired by [Magic UI](https://magicui.design/docs/components/file-tree).
- Credit to [kalix127](https://github.com/kalix127) for porting this component.