dropdown-menu
User profile dropdown menu with theme toggle and status selector
User profile dropdown menu with theme toggle and status selector
Загрузка превью…
src/dropdown-menu/c-dropdown-menu-14.vue
<!--
Расхождение с апстримом: `IconPlaceholder` заменена инлайновым `<svg>`
(lucide-react v0.545.0 "chevrons-up-down"/"sun"/"moon"/"monitor"/
"building"/"phone"/"check"/"settings"/"life-buoy"/"log-out") — см.
docs/PORTING.md §5. Сетевое изображение github.com/shadcn.png заменено
локальным 1x1 data-URI (`PIXEL`).
-->
<script setup lang="ts">
import { computed, ref } from "vue"
import { Badge } from "@/components/reui/badge"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"
const PIXEL = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAUwAOw=="
const statuses = [
{ value: "available", label: "Available", color: "bg-green-500" },
{ value: "away", label: "Away", color: "bg-amber-500" },
{ value: "busy", label: "Busy", color: "bg-red-500" },
{ value: "offline", label: "Offline", color: "bg-gray-400" },
]
const status = ref("available")
const theme = ref("light")
const activeStatus = computed(() => statuses.find((s) => s.value === status.value) || statuses[0]!)
</script>
<template>
<div class="flex items-center justify-center">
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button variant="outline" class="w-40">
<Avatar class="size-4">
<AvatarImage :src="PIXEL" />
<AvatarFallback>CN</AvatarFallback>
</Avatar>
<span class="text-sm font-medium">shadcn</span>
<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="lucide lucide-chevrons-up-down ml-auto opacity-60">
<path d="m7 15 5 5 5-5" />
<path d="m7 9 5-5 5 5" />
</svg>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent class="w-60" align="start" :side-offset="8">
<div class="flex items-center gap-3 px-1 pt-1.5">
<Avatar class="size-8">
<AvatarImage :src="PIXEL" />
<AvatarFallback>CN</AvatarFallback>
</Avatar>
<div class="flex flex-col">
<span class="text-foreground text-sm font-medium">shadcn</span>
<span class="text-muted-foreground text-xs">ui@shadcn.com</span>
</div>
</div>
<div class="py-2.5">
<Tabs v-model="theme">
<TabsList class="w-full">
<TabsTrigger value="light" class="h-6 flex-1">
<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="lucide lucide-sun size-4">
<circle cx="12" cy="12" r="4" />
<path d="M12 2v2" />
<path d="M12 20v2" />
<path d="m4.93 4.93 1.41 1.41" />
<path d="m17.66 17.66 1.41 1.41" />
<path d="M2 12h2" />
<path d="M20 12h2" />
<path d="m6.34 17.66-1.41 1.41" />
<path d="m19.07 4.93-1.41 1.41" />
</svg>
</TabsTrigger>
<TabsTrigger value="dark" class="h-6 flex-1">
<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="lucide lucide-moon size-4">
<path d="M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401" />
</svg>
</TabsTrigger>
<TabsTrigger value="system" class="h-6 flex-1">
<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="lucide lucide-monitor size-4">
<rect width="20" height="14" x="2" y="3" rx="2" />
<line x1="8" x2="16" y1="21" y2="21" />
<line x1="12" x2="12" y1="17" y2="21" />
</svg>
</TabsTrigger>
</TabsList>
</Tabs>
</div>
<DropdownMenuGroup>
<DropdownMenuItem class="justify-between" @select="(e: Event) => e.preventDefault()">
<span class="flex items-center gap-2">
<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="lucide lucide-building">
<path d="M12 10h.01" />
<path d="M12 14h.01" />
<path d="M12 6h.01" />
<path d="M16 10h.01" />
<path d="M16 14h.01" />
<path d="M16 6h.01" />
<path d="M8 10h.01" />
<path d="M8 14h.01" />
<path d="M8 6h.01" />
<path d="M9 22v-3a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v3" />
<rect x="4" y="2" width="16" height="20" rx="2" />
</svg>
Your Companies
</span>
<Badge variant="secondary" size="sm" class="rounded-full px-1.5">12</Badge>
</DropdownMenuItem>
<DropdownMenuItem class="justify-between" @select="(e: Event) => e.preventDefault()">
<span class="flex items-center gap-2">
<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="lucide lucide-phone">
<path d="M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384" />
</svg>
Your Numbers
</span>
<Badge variant="secondary" size="sm" class="rounded-full px-1.5">2</Badge>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
<span class="flex items-center gap-2">
<span class="size-2 rounded-full" :class="activeStatus.color" />
{{ activeStatus.label }}
</span>
</DropdownMenuSubTrigger>
<DropdownMenuSubContent class="w-40">
<DropdownMenuItem v-for="s in statuses" :key="s.value" class="justify-between" @click="status = s.value">
<span class="flex items-center gap-2">
<span class="size-2 rounded-full" :class="s.color" />
{{ s.label }}
</span>
<svg v-if="status === s.value" 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="lucide lucide-check text-muted-foreground size-4">
<path d="M20 6 9 17l-5-5" />
</svg>
</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuSub>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<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="lucide lucide-settings">
<path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" />
<circle cx="12" cy="12" r="3" />
</svg>
Settings
</DropdownMenuItem>
<DropdownMenuItem>
<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="lucide lucide-life-buoy">
<circle cx="12" cy="12" r="10" />
<path d="m4.93 4.93 4.24 4.24" />
<path d="m14.83 9.17 4.24-4.24" />
<path d="m14.83 14.83 4.24 4.24" />
<path d="m9.17 14.83-4.24 4.24" />
<circle cx="12" cy="12" r="4" />
</svg>
Help Center
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive">
<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="lucide lucide-log-out">
<path d="m16 17 5-5-5-5" />
<path d="M21 12H9" />
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" />
</svg>
Logout
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</template>
Установка
npx shadcn-vue@latest add https://revueui.rootapi.dev/r/c-dropdown-menu-14.jsonЗависимости реестра
Источник: порт из ReUI (Keenthemes, MIT)