Naar inhoud

Avatar

Een gebruikersafbeelding met initialen als alternatief voor profielmenu’s, reactiethreads en teamlijsten — met die neobrutalistische stijl met dikke randen.

import {
  Avatar,
  AvatarBadge,

De avatar toont een gebruikersafbeelding en schakelt over op AvatarFallback — initialen of een pictogram — terwijl de afbeelding laadt of wanneer het laden mislukt, zonder dat de lay-out verspringt. Gebouwd op de Base UI Avatar-component en vormgegeven volgens het neobrutalistische recept: een dikke rand van 2px en vette initialen in het koplettertype.

Gebruik deze component bij:

  • Profielmenu’s — de avatar in de header die accountacties opent; zie het Dropdown-voorbeeld.
  • Reactiethreads en activiteitenfeeds — een gezicht naast elke auteursregel, met initialen als vangnet voor kapotte of ontbrekende foto’s.
  • Team- en ledenlijsten — laat teamleden overlappen met AvatarGroup en vang het restant af met AvatarGroupCount.

Installatie

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

Installeer de volgende afhankelijkheden:

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

Kopieer en plak de volgende code in je project.

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

Werk de import-paden bij zodat ze overeenkomen met je projectstructuur.

Gebruik

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

Compositie

Gebruik de volgende compositie om een Avatar te bouwen:

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

Gebruik de volgende compositie om een AvatarGroup te bouwen:

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

Voorbeelden

Basis

Een eenvoudige avatar-component met een afbeelding en een fallback.

NB
import {
  Avatar,
  AvatarFallback,

Badge

Gebruik de component AvatarBadge om een badge aan de avatar toe te voegen. De badge wordt rechtsonder op de avatar geplaatst.

import {
  Avatar,
  AvatarBadge,

Gebruik de prop className om aangepaste stijlen aan de badge toe te voegen, zoals kleuren, groottes enz.

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

Badge met pictogram

Je kunt ook een pictogram binnen <AvatarBadge> gebruiken.

import { PlusIcon } from "lucide-react"

import {

Avatar-groep

Gebruik de component AvatarGroup om een groep avatars toe te voegen.

import {
  Avatar,
  AvatarFallback,

Teller avatar-groep

Gebruik <AvatarGroupCount> om een teller aan de groep toe te voegen.

import {
  Avatar,
  AvatarFallback,

Avatar-groep met pictogram

Je kunt ook een pictogram binnen <AvatarGroupCount> gebruiken.

import { PlusIcon } from "lucide-react"

import {

Groottes

Gebruik de prop size om de grootte van de avatar te wijzigen.

import {
  Avatar,
  AvatarFallback,

Je kunt de component Avatar gebruiken als trigger voor een dropdownmenu.

"use client"

import {

RTL

Om RTL-ondersteuning in Neobrutalism in te schakelen, zie de RTL-configuratiegids.

"use client"

import * as React from "react"

Toegankelijkheid

Een avatar is een afbeelding, dus gelden de regels voor afbeeldingen: geef AvatarImage een alt met de naam van de persoon wanneer de avatar het enige is dat diegene identificeert, en alt="" wanneer er direct naast een zichtbare naam staat — anders kondigen schermlezers de naam twee keer aan. De initialen in AvatarFallback zijn gewone tekst en worden voorgelezen, dus houd ze betekenisvol. Wanneer de avatar een menu opent (zie Dropdown), zet de toegankelijke naam dan op de triggerknop, niet op de afbeelding.

API-referentie

Avatar

De component Avatar is de wortelcomponent die de avatarafbeelding en fallback omhult.

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

AvatarImage

De component AvatarImage toont de avatarafbeelding. Hij accepteert alle props van Base UI Avatar Image.

PropTypeDefault
srcstring-
altstring-
classNamestring-

AvatarFallback

De component AvatarFallback toont een fallback wanneer de afbeelding niet kan laden. Hij accepteert alle props van Base UI Avatar Fallback.

PropTypeDefault
classNamestring-

AvatarBadge

De component AvatarBadge toont een badge-indicator op de avatar, meestal rechtsonder geplaatst.

PropTypeDefault
classNamestring-

AvatarGroup

De component AvatarGroup toont een groep avatars met een overlappende stijl.

PropTypeDefault
classNamestring-

AvatarGroupCount

De component AvatarGroupCount toont een teller-indicator in een avatar-groep, meestal het aantal extra avatars.

PropTypeDefault
classNamestring-

Voor meer informatie over de props van Base UI Avatar, zie de Base UI-documentatie.