Skip to content

shadcn.io is an independent project built on shadcn/ui

Free

Left Drawer File Explorer for Vue

A left Files drawer where Projects starts open and holds the Website and App folders and their files.

UI library: Ark UI

A left panel titled Files. Projects starts open and holds Website and App, and each of those folders opens to its files. The chevron turns as a folder opens.

Use it when files are a side task on a phone. A large tree with selection fits a Tree View better. In Vue, Ark UI does not select a file.

Preview

Preview width

Installation

MCP ยท Pro
Make your AI a shadcn expert
Your agent installs components, builds pages and restyles your app from one prompt, in Claude Code, Cursor or VS Code.
Part of Pro

Anatomy

Drawer anatomy: grabber, title, description, content, close

Usage

<Drawer swipeDirection="left">
  <DrawerTrigger :asChild="true">
    <Button aria-label="Open files" size="icon-md" variant="outline">
      <MenuIcon aria-hidden="true" />
    </Button>
  </DrawerTrigger>
  <DrawerContent :showBar="false">
    <div class="flex flex-col gap-4 p-4">
      <DrawerTitle class="font-semibold text-lg">Files</DrawerTitle>
      <Collapsible :defaultOpen="true">
        <CollapsibleTrigger :asChild="true">
          <Button class="group w-full justify-start" size="sm" variant="ghost">
            <ChevronRightIcon aria-hidden="true" class="size-3 transition-transform group-aria-expanded:rotate-90" /><FolderIcon aria-hidden="true" class="size-3" />Projects
          </Button>
        </CollapsibleTrigger>
        <CollapsibleContent class="ms-4">
          <div class="flex flex-col gap-1">
            <Collapsible v-for="folder in FOLDERS" :key="folder.name">
              <CollapsibleTrigger :asChild="true">
                <Button class="group w-full justify-start" size="sm" variant="ghost">
                  <ChevronRightIcon aria-hidden="true" class="size-3 transition-transform group-aria-expanded:rotate-90" /><FolderIcon aria-hidden="true" class="size-3" />{{ folder.name }}
                </Button>
              </CollapsibleTrigger>
              <CollapsibleContent class="ms-4">
                <div class="flex flex-col gap-1">
                  <Button
                    v-for="file in folder.files"
                    class="w-full justify-start"
                    :key="file"
                    size="sm"
                    variant="ghost"
<!-- The rest of the file is under Installation. -->

FAQ

How is the tree built?

From nested Collapsibles. Projects sets defaultOpen, and Website and App map from a static list of folders, each with its files inside CollapsibleContent.

How is each level indented?

Every CollapsibleContent has ms-4, so each level starts a step further in, on the reading side.

How does the chevron show a folder's state?

The trigger has aria-expanded while the folder is open, and the chevron's group-aria-expanded:rotate-90 turns it down.

Do the files open anything?

No, they're ghost buttons with a file icon and no handler. Open the file from each one, and close the drawer if it should get out of the way. Pass open to Drawer and listen to @open-change, which receives details.open.

How is the files button labeled?

An outline icon button opens the drawer. Its aria-label, Open files, is the accessible name; the icon is aria-hidden. DrawerTrigger takes asChild and merges onto the one Button inside it.

Where is the drawer's title?

Files, above the tree, is the DrawerTitle. DrawerTitle names the dialog for assistive tech, so every drawer renders one; give it sr-only when the design has no visible heading.

API Reference

Drawer

Sets swipeDirection="left" and asChild. The rest is on the Drawer page.

Button

Sets aria-label="Open files", size="icon-md", variant="outline", size="sm", variant="ghost" and v-for="file in folder.files". The rest is on the Button page.

Collapsible

Sets defaultOpen, asChild, v-for="folder in FOLDERS" and key="folder.name". The rest is on the Collapsible page.