collapsible

Tree view with file actions

Tree view with file actions

Загрузка превью…

src/collapsible/c-collapsible-10.vue

<!--
  Расхождение с апстримом: `IconPlaceholder` заменена инлайновым `<svg>`
  (lucide-react v0.545.0 "chevron-right"/"folder"/"file"/"download"/"trash")
  — см. docs/PORTING.md §5. Ни один `Collapsible` здесь не раскрыт по
  умолчанию, поэтому иконки вложенных файлов/папок (button.tsx, card.tsx,
  dialog.tsx, login-form.tsx, utils.ts, ...) не монтируются — видны только
  иконки 5 корневых пунктов (components/lib/hooks — папки, app.tsx/
  package.json — файлы). `ItemActions` у файлов всегда в DOM (видимость —
  через `opacity-0`/hover, не условный рендер), поэтому download/trash
  адаптированы и для корневых файлов.
-->
<script setup lang="ts">
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader } from "@/components/ui/card"
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"
import { Item, ItemActions, ItemMedia, ItemTitle } from "@/components/ui/item"
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"
</script>

<template>
  <div class="min-h-64 w-72">
    <Card size="sm" class="gap-1 p-1">
      <CardHeader class="p-0">
        <Tabs default-value="explorer">
          <TabsList class="bg-accent h-8 w-full p-1">
            <TabsTrigger value="explorer" class="text-xs">Explorer</TabsTrigger>
            <TabsTrigger value="outline" class="text-xs">Outline</TabsTrigger>
          </TabsList>
        </Tabs>
      </CardHeader>
      <CardContent class="p-0">
        <div class="flex flex-col gap-0.5">
          <Collapsible class="group/collapsible">
            <CollapsibleTrigger as-child>
              <Item size="xs" class="hover:bg-accent data-[state=open]:bg-accent cursor-pointer py-1.5" :style="{ paddingLeft: '8px' }">
                <ItemMedia variant="icon">
                  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="text-muted-foreground size-3 transition-transform in-data-[state=open]:rotate-90">
                    <path d="m9 18 6-6-6-6" />
                  </svg>
                  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="text-muted-foreground group-hover/item:text-foreground size-3.5">
                    <path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z" />
                  </svg>
                </ItemMedia>
                <ItemTitle class="text-sm">components</ItemTitle>
              </Item>
            </CollapsibleTrigger>
            <CollapsibleContent class="data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down overflow-hidden pt-0.5">
              <div class="flex flex-col gap-0.5 ps-1.5" />
            </CollapsibleContent>
          </Collapsible>

          <Collapsible class="group/collapsible">
            <CollapsibleTrigger as-child>
              <Item size="xs" class="hover:bg-accent data-[state=open]:bg-accent cursor-pointer py-1.5" :style="{ paddingLeft: '8px' }">
                <ItemMedia variant="icon">
                  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="text-muted-foreground size-3 transition-transform in-data-[state=open]:rotate-90">
                    <path d="m9 18 6-6-6-6" />
                  </svg>
                  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="text-muted-foreground group-hover/item:text-foreground size-3.5">
                    <path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z" />
                  </svg>
                </ItemMedia>
                <ItemTitle class="text-sm">lib</ItemTitle>
              </Item>
            </CollapsibleTrigger>
            <CollapsibleContent class="data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down overflow-hidden pt-0.5">
              <div class="flex flex-col gap-0.5 ps-1.5" />
            </CollapsibleContent>
          </Collapsible>

          <Collapsible class="group/collapsible">
            <CollapsibleTrigger as-child>
              <Item size="xs" class="hover:bg-accent data-[state=open]:bg-accent cursor-pointer py-1.5" :style="{ paddingLeft: '8px' }">
                <ItemMedia variant="icon">
                  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="text-muted-foreground size-3 transition-transform in-data-[state=open]:rotate-90">
                    <path d="m9 18 6-6-6-6" />
                  </svg>
                  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="text-muted-foreground group-hover/item:text-foreground size-3.5">
                    <path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z" />
                  </svg>
                </ItemMedia>
                <ItemTitle class="text-sm">hooks</ItemTitle>
              </Item>
            </CollapsibleTrigger>
            <CollapsibleContent class="data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down overflow-hidden pt-0.5">
              <div class="flex flex-col gap-0.5 ps-1.5" />
            </CollapsibleContent>
          </Collapsible>

          <Item class="group/item hover:bg-accent data-[active=true]:bg-accent cursor-pointer py-1.5" :data-active="false" :style="{ paddingLeft: '9px' }">
            <ItemMedia variant="icon">
              <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="text-muted-foreground group-hover/item:text-foreground group-data-[active=true]/item:text-foreground size-4">
                <path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" />
                <path d="M14 2v4a2 2 0 0 0 2 2h4" />
              </svg>
            </ItemMedia>
            <ItemTitle class="text-secondary-foreground group-hover/item:text-foreground group-data-[active=true]/item:text-foreground text-sm">app.tsx</ItemTitle>
            <ItemActions class="-mr-2 ml-auto gap-0 opacity-0 transition-opacity group-hover/item:opacity-100 group-data-[active=true]/item:opacity-100">
              <Button size="icon-xs" variant="ghost">
                <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M12 15V3" />
                  <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
                  <path d="m7 10 5 5 5-5" />
                </svg>
              </Button>
              <Button variant="ghost" size="icon-xs">
                <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" />
                  <path d="M3 6h18" />
                  <path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
                </svg>
              </Button>
            </ItemActions>
          </Item>

          <Item class="group/item hover:bg-accent data-[active=true]:bg-accent cursor-pointer py-1.5" :data-active="false" :style="{ paddingLeft: '9px' }">
            <ItemMedia variant="icon">
              <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="text-muted-foreground group-hover/item:text-foreground group-data-[active=true]/item:text-foreground size-4">
                <path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" />
                <path d="M14 2v4a2 2 0 0 0 2 2h4" />
              </svg>
            </ItemMedia>
            <ItemTitle class="text-secondary-foreground group-hover/item:text-foreground group-data-[active=true]/item:text-foreground text-sm">package.json</ItemTitle>
            <ItemActions class="-mr-2 ml-auto gap-0 opacity-0 transition-opacity group-hover/item:opacity-100 group-data-[active=true]/item:opacity-100">
              <Button size="icon-xs" variant="ghost">
                <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M12 15V3" />
                  <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
                  <path d="m7 10 5 5 5-5" />
                </svg>
              </Button>
              <Button variant="ghost" size="icon-xs">
                <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" />
                  <path d="M3 6h18" />
                  <path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
                </svg>
              </Button>
            </ItemActions>
          </Item>
        </div>
      </CardContent>
    </Card>
  </div>
</template>

Установка

npx shadcn-vue@latest add https://revueui.rootapi.dev/r/c-collapsible-10.json

Зависимости реестра

Источник: порт из ReUI (Keenthemes, MIT)