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)