dropdown-menu

Notifications dropdown menu

Notifications dropdown menu

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

src/dropdown-menu/c-dropdown-menu-11.vue

<!--
  Расхождение с апстримом: `IconPlaceholder` заменена инлайновым `<svg>`
  (lucide-react v0.545.0 "bell") — см. docs/PORTING.md §5. Сетевые
  изображения unsplash (только в закрытом состоянии не рендерятся)
  заменены локальным 1x1 data-URI (`PIXEL`).
-->
<script setup lang="ts">
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, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"

const PIXEL = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAUwAOw=="

const notifications = [
  { id: "1", user: "Sarah", avatar: PIXEL, initials: "SC", action: "commented on", target: "Design System v2", time: "2 min ago", unread: false },
  { id: "2", user: "James Wilson", avatar: PIXEL, initials: "JW", action: "shared", target: "Q4 Report", time: "1 hour ago", unread: true },
  { id: "3", user: "Emily Davis", avatar: PIXEL, initials: "ED", action: "invited you to", target: "Project Alpha", time: "3 hours ago", unread: false },
]
</script>

<template>
  <div class="flex items-center justify-center">
    <DropdownMenu>
      <DropdownMenuTrigger as-child>
        <Button variant="outline" size="icon" class="relative">
          <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-bell">
            <path d="M10.268 21a2 2 0 0 0 3.464 0" />
            <path d="M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326" />
          </svg>
          <Badge variant="destructive" size="sm" class="absolute -top-1.5 -right-2 rounded-full px-1" aria-hidden="true">8</Badge>
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent class="w-80" align="end" :side-offset="8">
        <DropdownMenuGroup>
          <DropdownMenuLabel class="flex items-center justify-between">
            <span>Notifications</span>
            <button class="text-foreground text-xs font-normal underline-offset-2 hover:underline">Mark all as read</button>
          </DropdownMenuLabel>
          <DropdownMenuSeparator />
          <DropdownMenuGroup>
            <DropdownMenuItem v-for="notification in notifications" :key="notification.id" class="flex items-start gap-2 py-1">
              <Avatar class="mt-0.5 size-6 shrink-0">
                <AvatarImage :src="notification.avatar" :alt="notification.user" />
                <AvatarFallback>{{ notification.initials }}</AvatarFallback>
              </Avatar>
              <div class="flex flex-1 flex-col gap-px">
                <p class="leading-snug">
                  <span class="font-medium">{{ notification.user }}</span>
                  <span class="text-muted-foreground">{{ ` ${notification.action} ` }}</span>
                  <span class="font-medium">{{ notification.target }}</span>
                </p>
                <span class="text-muted-foreground">{{ notification.time }}</span>
              </div>
              <span v-if="notification.unread" class="bg-primary mt-2 size-1.5 shrink-0 rounded-full" />
            </DropdownMenuItem>
          </DropdownMenuGroup>
          <DropdownMenuSeparator />
          <DropdownMenuItem class="justify-center">View all notifications</DropdownMenuItem>
        </DropdownMenuGroup>
      </DropdownMenuContent>
    </DropdownMenu>
  </div>
</template>

Установка

npx shadcn-vue@latest add https://revueui.rootapi.dev/r/c-dropdown-menu-11.json

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

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