Vai al contenuto

Avatar

Un'immagine utente con le iniziali come alternativa per i menu del profilo, i thread dei commenti e gli elenchi dei team — con il bordo spesso in stile neobrutalista.

import {
  Avatar,
  AvatarBadge,

L’avatar mostra l’immagine di un utente e mette al suo posto AvatarFallback — iniziali o un’icona — mentre l’immagine si carica o quando il caricamento fallisce, senza spostamenti di layout. Costruito sul componente Base UI Avatar e rifinito secondo la ricetta neobrutalista: un bordo spesso di 2px e iniziali in grassetto nel carattere dei titoli.

Quando usarlo:

  • Menu del profilo — l’avatar nell’header che apre le azioni dell’account; vedi l’esempio Dropdown.
  • Thread di commenti e feed di attività — un volto accanto a ogni riga d’autore, con le iniziali a coprire foto mancanti o non caricate.
  • Elenchi di team e membri — sovrapponi i collaboratori con AvatarGroup e riassumi quelli in eccesso con AvatarGroupCount.

Installazione

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

Installa le seguenti dipendenze:

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

Copia e incolla il seguente codice nel tuo progetto.

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,
}

Aggiorna i percorsi di import in base alla struttura del tuo progetto.

Utilizzo

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

Composizione

Usa la seguente composizione per costruire un Avatar:

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

Usa la seguente composizione per costruire un AvatarGroup:

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

Esempi

Base

Un componente avatar di base con un'immagine e un fallback.

NB
import {
  Avatar,
  AvatarFallback,

Badge

Usa il componente AvatarBadge per aggiungere un badge all'avatar. Il badge si posiziona in basso a destra dell'avatar.

import {
  Avatar,
  AvatarBadge,

Usa la prop className per applicare stili personalizzati al badge, come colori, dimensioni, ecc.

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

Badge con icona

Puoi anche usare un'icona dentro <AvatarBadge>.

import { PlusIcon } from "lucide-react"

import {

Gruppo di avatar

Usa il componente AvatarGroup per aggiungere un gruppo di avatar.

import {
  Avatar,
  AvatarFallback,

Contatore del gruppo di avatar

Usa <AvatarGroupCount> per aggiungere un contatore al gruppo.

import {
  Avatar,
  AvatarFallback,

Gruppo di avatar con icona

Puoi anche usare un'icona dentro <AvatarGroupCount>.

import { PlusIcon } from "lucide-react"

import {

Dimensioni

Usa la prop size per cambiare la dimensione dell'avatar.

import {
  Avatar,
  AvatarFallback,

Puoi usare il componente Avatar come trigger per un menu a discesa.

"use client"

import {

RTL

Per abilitare il supporto RTL in Neobrutalism, consulta la guida alla configurazione RTL.

"use client"

import * as React from "react"

Accessibilità

Un avatar è un’immagine, quindi valgono le regole delle immagini: dai ad AvatarImage un alt con il nome della persona quando l’avatar è l’unica cosa che la identifica, e alt="" quando un nome visibile le sta proprio accanto — altrimenti gli screen reader annunciano il nome due volte. Le iniziali di AvatarFallback sono testo semplice e vengono lette ad alta voce, quindi falle restare significative. Quando l’avatar apre un menu (vedi Dropdown), metti il nome accessibile sul pulsante trigger, non sull’immagine.

Riferimento API

Avatar

Il componente Avatar è il componente radice che avvolge l'immagine e il fallback dell'avatar.

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

AvatarImage

Il componente AvatarImage mostra l'immagine dell'avatar. Accetta tutte le prop di Base UI Avatar Image.

PropTypeDefault
srcstring-
altstring-
classNamestring-

AvatarFallback

Il componente AvatarFallback mostra un fallback quando l'immagine non riesce a caricarsi. Accetta tutte le prop di Base UI Avatar Fallback.

PropTypeDefault
classNamestring-

AvatarBadge

Il componente AvatarBadge mostra un indicatore badge sull'avatar, tipicamente posizionato in basso a destra.

PropTypeDefault
classNamestring-

AvatarGroup

Il componente AvatarGroup mostra un gruppo di avatar con uno stile sovrapposto.

PropTypeDefault
classNamestring-

AvatarGroupCount

Il componente AvatarGroupCount mostra un indicatore contatore in un gruppo di avatar, tipicamente indicando il numero di avatar aggiuntivi.

PropTypeDefault
classNamestring-

Per maggiori informazioni sulle prop di Base UI Avatar, consulta la documentazione di Base UI.