Skip to main content

Installation

npx shadcn-svelte@latest add https://acme.com/r/file-tree

Usage

<script lang="ts">
  import { FileTree, Folder, File } from "magic/file-tree";
  import type { TreeViewElement } from "magic/file-tree";

  const elements: TreeViewElement[] = [
    {
      id: "1",
      name: "src",
      children: [
        { id: "2", name: "components", children: [
          { id: "3", name: "Button.svelte" },
          { id: "4", name: "Input.svelte" }
        ]},
        { id: "5", name: "App.svelte" }
      ]
    }
  ];
</script>

<FileTree {elements}>
  <Folder value="1" element="src">
    <Folder value="2" element="components">
      <File value="3">Button.svelte</File>
      <File value="4">Input.svelte</File>
    </Folder>
    <File value="5">App.svelte</File>
  </Folder>
</FileTree>

Examples

Basic File Tree

<script lang="ts">
  import { FileTree, Folder, File } from "magic/file-tree";
</script>

<FileTree initialExpandedItems={["root"]}>
  <Folder value="root" element="project">
    <Folder value="src" element="src">
      <File value="app">App.svelte</File>
      <File value="main">main.ts</File>
    </Folder>
    <Folder value="public" element="public">
      <File value="index">index.html</File>
    </Folder>
    <File value="package">package.json</File>
  </Folder>
</FileTree>

With Initial Selection

<FileTree initialSelectedId="app" initialExpandedItems={["root", "src"]}>
  <Folder value="root" element="project">
    <Folder value="src" element="src">
      <File value="app">App.svelte</File>
      <File value="main">main.ts</File>
    </Folder>
  </Folder>
</FileTree>

Custom Icons

<script lang="ts">
  import { FileTree, Folder, File } from "magic/file-tree";
  import { FolderOpen, FolderClosed, FileIcon } from "@lucide/svelte";
</script>

<FileTree>
  {#snippet openIcon()}
    <FolderOpen class="h-4 w-4" />
  {/snippet}
  {#snippet closeIcon()}
    <FolderClosed class="h-4 w-4" />
  {/snippet}

  <Folder value="src" element="src">
    <File value="app">
      {#snippet fileIcon()}
        <FileIcon class="h-4 w-4" />
      {/snippet}
      App.svelte
    </File>
  </Folder>
</FileTree>

Non-Selectable Items

<FileTree>
  <Folder value="root" element="project" isSelectable={false}>
    <File value="readme" isSelectable={false}>README.md</File>
    <File value="app">App.svelte</File>
  </Folder>
</FileTree>

Component API

FileTree

children
Snippet
required
Child components (Folder and File components).
initialSelectedId
string
ID of the initially selected item.
initialExpandedItems
string[]
default:"[]"
Array of IDs for initially expanded folders.
elements
TreeViewElement[]
Tree structure data (optional, used for data-driven rendering).
indicator
boolean
default:"true"
Whether to show the vertical indicator line for nested items.
openIcon
Snippet
Custom icon snippet for open folders.
closeIcon
Snippet
Custom icon snippet for closed folders.
dir
'rtl' | 'ltr'
default:"'ltr'"
Text direction for the tree.
class
string
Additional CSS classes to apply to the container.

Folder

element
string
required
The folder name/label to display.
value
string
required
Unique identifier for this folder.
isSelectable
boolean
default:"true"
Whether the folder can be selected.
isSelect
boolean
Override to manually control selection state.
children
Snippet
required
Child components (nested Folder and File components).
class
string
Additional CSS classes to apply to the folder.

File

value
string
required
Unique identifier for this file.
isSelectable
boolean
default:"true"
Whether the file can be selected.
isSelect
boolean
Override to manually control selection state.
fileIcon
Snippet
Custom icon snippet for the file.
children
Snippet
required
File name/label content.
class
string
Additional CSS classes to apply to the file.

Features

  • Smooth expand/collapse animations with motion-sv
  • Vertical indicator lines for nested structure
  • Selectable files and folders with visual feedback
  • Support for non-selectable items
  • Custom icon support for folders and files
  • RTL support
  • Keyboard accessible
  • Context-based state management
  • Default SVG icons included

Type Definitions

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

Animation Details

Folder expansion uses:
  • Initial: height: 0, opacity: 0
  • Animate: height: "auto", opacity: 1
  • Exit: height: 0, opacity: 0
  • Duration: 0.2s with easeInOut easing

Dependencies

  • @lucide/svelte
  • motion-sv

Build docs developers (and LLMs) love