Przejdź do treści

Awatar

Zdjęcie użytkownika z inicjałami jako opcją zastępczą w menu profilu, wątkach komentarzy i listach zespołów — z grubą ramką w stylu neobrutalistycznym.

import {
  Avatar,
  AvatarBadge,

Awatar wyświetla zdjęcie użytkownika i podmienia je na AvatarFallback — inicjały lub ikonę — na czas ładowania obrazu albo gdy nie uda się go wczytać, bez przeskoku układu. Zbudowany na komponencie Base UI Avatar i ostylowany zgodnie z neobrutalistyczną recepturą: grube obramowanie 2px i inicjały wyrazistym krojem nagłówkowym.

Sięgnij po ten komponent, gdy:

  • Menu profilu — awatar w nagłówku otwierający akcje konta; zobacz przykład Dropdown.
  • Wątki komentarzy i strumienie aktywności — twarz przy każdej linii autora, z inicjałami w miejsce uszkodzonych lub brakujących zdjęć.
  • Listy zespołów i członków — nachodzące na siebie awatary współpracowników w AvatarGroup, z nadmiarem uciętym przez AvatarGroupCount.

Instalacja

pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/avatar.json
npx shadcn@latest add https://neobrutalism.com/r/base/avatar.json
yarn dlx shadcn@latest add https://neobrutalism.com/r/base/avatar.json
bunx --bun shadcn@latest add https://neobrutalism.com/r/base/avatar.json

Zainstaluj następujące zależności:

pnpm add @base-ui/react
npm install @base-ui/react
yarn add @base-ui/react
bun add @base-ui/react

Skopiuj i wklej poniższy kod do swojego projektu.

components/ui/avatar.tsx
"use client"

import * as React from "react"
import { Avatar as AvatarPrimitive } from "radix-ui"

import { cn } from "@/lib/utils"

function Avatar({
  className,
  size = "default",
  ...props
}: React.ComponentProps<typeof AvatarPrimitive.Root> & {
  size?: "default" | "sm" | "lg"
}) {
  return (
    <AvatarPrimitive.Root
      data-slot="avatar"
      data-size={size}
      className={cn(
        "group/avatar relative flex size-8 shrink-0 rounded-full border-2 select-none data-[size=lg]:size-10 data-[size=sm]:size-6",
        className
      )}
      {...props}
    />
  )
}

function AvatarImage({
  className,
  ...props
}: React.ComponentProps<typeof AvatarPrimitive.Image>) {
  return (
    <AvatarPrimitive.Image
      data-slot="avatar-image"
      className={cn(
        "aspect-square size-full rounded-full object-cover",
        className
      )}
      {...props}
    />
  )
}

function AvatarFallback({
  className,
  ...props
}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
  return (
    <AvatarPrimitive.Fallback
      data-slot="avatar-fallback"
      className={cn(
        "flex size-full items-center justify-center rounded-full bg-muted font-head text-sm text-muted-foreground group-data-[size=sm]/avatar:text-xs",
        className
      )}
      {...props}
    />
  )
}

function AvatarBadge({ className, ...props }: React.ComponentProps<"span">) {
  return (
    <span
      data-slot="avatar-badge"
      className={cn(
        "absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-primary text-primary-foreground bg-blend-color ring-2 ring-background select-none",
        "group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden",
        "group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2",
        "group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2",
        className
      )}
      {...props}
    />
  )
}

function AvatarGroup({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="avatar-group"
      className={cn(
        "group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background",
        className
      )}
      {...props}
    />
  )
}

function AvatarGroupCount({
  className,
  ...props
}: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="avatar-group-count"
      className={cn(
        "relative flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-sm text-muted-foreground ring-2 ring-background group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3",
        className
      )}
      {...props}
    />
  )
}

export {
  Avatar,
  AvatarImage,
  AvatarFallback,
  AvatarGroup,
  AvatarGroupCount,
  AvatarBadge,
}

Zaktualizuj ścieżki importów, aby pasowały do struktury twojego projektu.

Użycie

import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
<Avatar>
  <AvatarImage src="https://github.com/shadcn.png" />
  <AvatarFallback>CN</AvatarFallback>
</Avatar>

Kompozycja

Użyj następującej kompozycji, aby zbudować Avatar:

Avatar
├── AvatarImage
├── AvatarFallback
└── AvatarBadge

Użyj następującej kompozycji, aby zbudować AvatarGroup:

AvatarGroup
├── Avatar
│   ├── AvatarImage
│   ├── AvatarFallback
│   └── AvatarBadge
├── Avatar
│   ├── AvatarImage
│   ├── AvatarFallback
│   └── AvatarBadge
└── AvatarGroupCount

Przykłady

Podstawowy

Podstawowy komponent avatara z obrazem i elementem zastępczym.

NB
import {
  Avatar,
  AvatarFallback,

Badge

Użyj komponentu AvatarBadge, aby dodać badge do avatara. Badge jest umieszczany w prawym dolnym rogu avatara.

import {
  Avatar,
  AvatarBadge,

Użyj propa className, aby dodać do badge niestandardowe style, takie jak kolory, rozmiary itp.

<Avatar>
  <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
  <AvatarFallback>CN</AvatarFallback>
  <AvatarBadge className="bg-green-600 dark:bg-green-800" />
</Avatar>

Badge z ikoną

Możesz też użyć ikony wewnątrz <AvatarBadge>.

import { PlusIcon } from "lucide-react"

import {

Grupa avatarów

Użyj komponentu AvatarGroup, aby dodać grupę avatarów.

import {
  Avatar,
  AvatarFallback,

Licznik grupy avatarów

Użyj <AvatarGroupCount>, aby dodać licznik do grupy.

import {
  Avatar,
  AvatarFallback,

Grupa avatarów z ikoną

Możesz też użyć ikony wewnątrz <AvatarGroupCount>.

import { PlusIcon } from "lucide-react"

import {

Rozmiary

Użyj propa size, aby zmienić rozmiar avatara.

import {
  Avatar,
  AvatarFallback,

Możesz użyć komponentu Avatar jako wyzwalacza menu rozwijanego.

"use client"

import {

RTL

Aby włączyć obsługę RTL w Neobrutalism, zobacz przewodnik konfiguracji RTL.

"use client"

import * as React from "react"

Dostępność

Awatar to obraz, więc obowiązują zasady dla obrazów: nadaj AvatarImage atrybut alt z nazwą osoby, gdy awatar jest jedynym elementem, który ją identyfikuje, oraz alt="", gdy widoczna nazwa stoi tuż obok — inaczej czytniki ekranu odczytają ją dwukrotnie. Inicjały w AvatarFallback to zwykły tekst czytany na głos, więc zadbaj, by coś znaczyły. Gdy awatar otwiera menu (zobacz Dropdown), umieść dostępną nazwę na przycisku wyzwalacza, nie na obrazie.

Referencja API

Avatar

Komponent Avatar to komponent główny, który otacza obraz avatara i element zastępczy.

PropTypeDefault
size"default" | "sm" | "lg""default"
classNamestring-

AvatarImage

Komponent AvatarImage wyświetla obraz avatara. Przyjmuje wszystkie propy Base UI Avatar Image.

PropTypeDefault
srcstring-
altstring-
classNamestring-

AvatarFallback

Komponent AvatarFallback wyświetla element zastępczy, gdy obraz nie może się załadować. Przyjmuje wszystkie propy Base UI Avatar Fallback.

PropTypeDefault
classNamestring-

AvatarBadge

Komponent AvatarBadge wyświetla wskaźnik badge na avatarze, zwykle umieszczony w prawym dolnym rogu.

PropTypeDefault
classNamestring-

AvatarGroup

Komponent AvatarGroup wyświetla grupę avatarów z nakładającym się stylem.

PropTypeDefault
classNamestring-

AvatarGroupCount

Komponent AvatarGroupCount wyświetla wskaźnik licznika w grupie avatarów, zwykle pokazujący liczbę dodatkowych avatarów.

PropTypeDefault
classNamestring-

Więcej informacji o propach Base UI Avatar znajdziesz w dokumentacji Base UI.