Lewati ke konten

Avatar

Gambar pengguna dengan opsi pengganti berupa inisial untuk menu profil, utas komentar, dan daftar tim — dengan sentuhan gaya neobrutalis berupa garis tepi tebal.

import {
  Avatar,
  AvatarBadge,

Avatar menampilkan gambar pengguna dan menggantinya dengan AvatarFallback — inisial atau ikon — selagi gambar dimuat atau ketika gagal dimuat, tanpa pergeseran tata letak. Dibangun di atas komponen Base UI Avatar dan ditata dengan resep neobrutalis: garis tepi tebal 2px dan inisial tebal dengan font judul.

Gunakan saat:

  • Menu profil — avatar di header yang membuka aksi akun; lihat contoh Dropdown.
  • Utas komentar dan umpan aktivitas — wajah di samping setiap baris penulis, dengan inisial menggantikan foto yang rusak atau hilang.
  • Daftar tim dan anggota — tumpuk kolaborator dengan AvatarGroup dan batasi luapannya dengan AvatarGroupCount.

Instalasi

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

Pasang dependensi berikut:

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

Salin dan tempel kode berikut ke proyek Anda.

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

Perbarui jalur import agar sesuai dengan struktur proyek Anda.

Penggunaan

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

Komposisi

Gunakan komposisi berikut untuk membangun Avatar:

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

Gunakan komposisi berikut untuk membangun AvatarGroup:

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

Contoh

Dasar

Komponen avatar dasar dengan gambar dan fallback.

NB
import {
  Avatar,
  AvatarFallback,

Badge

Gunakan komponen AvatarBadge untuk menambahkan badge ke avatar. Badge diposisikan di kanan bawah avatar.

import {
  Avatar,
  AvatarBadge,

Gunakan prop className untuk menambahkan gaya kustom ke badge seperti warna, ukuran, dan sebagainya.

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

Badge dengan Ikon

Anda juga bisa menggunakan ikon di dalam <AvatarBadge>.

import { PlusIcon } from "lucide-react"

import {

Grup Avatar

Gunakan komponen AvatarGroup untuk menambahkan sekelompok avatar.

import {
  Avatar,
  AvatarFallback,

Penghitung Grup Avatar

Gunakan <AvatarGroupCount> untuk menambahkan penghitung ke grup.

import {
  Avatar,
  AvatarFallback,

Grup Avatar dengan Ikon

Anda juga bisa menggunakan ikon di dalam <AvatarGroupCount>.

import { PlusIcon } from "lucide-react"

import {

Ukuran

Gunakan prop size untuk mengubah ukuran avatar.

import {
  Avatar,
  AvatarFallback,

Anda bisa menggunakan komponen Avatar sebagai trigger untuk menu dropdown.

"use client"

import {

RTL

Untuk mengaktifkan dukungan RTL di Neobrutalism, lihat panduan konfigurasi RTL.

"use client"

import * as React from "react"

Aksesibilitas

Avatar adalah gambar, jadi aturan gambar berlaku: beri AvatarImage teks alt berupa nama orangnya bila avatar adalah satu-satunya penanda identitasnya, dan alt="" bila nama sudah terlihat tepat di sebelahnya — jika tidak, pembaca layar akan mengumumkan nama itu dua kali. Inisial AvatarFallback adalah teks biasa dan ikut dibacakan, jadi pastikan tetap bermakna. Bila avatar membuka menu (lihat Dropdown), letakkan nama aksesibelnya pada tombol pemicu, bukan pada gambar.

Referensi API

Avatar

Komponen Avatar adalah komponen root yang membungkus gambar dan fallback avatar.

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

AvatarImage

Komponen AvatarImage menampilkan gambar avatar. Komponen ini menerima semua prop Base UI Avatar Image.

PropTypeDefault
srcstring-
altstring-
classNamestring-

AvatarFallback

Komponen AvatarFallback menampilkan fallback ketika gambar gagal dimuat. Komponen ini menerima semua prop Base UI Avatar Fallback.

PropTypeDefault
classNamestring-

AvatarBadge

Komponen AvatarBadge menampilkan indikator badge pada avatar, biasanya diposisikan di kanan bawah.

PropTypeDefault
classNamestring-

AvatarGroup

Komponen AvatarGroup menampilkan sekelompok avatar dengan gaya bertumpuk.

PropTypeDefault
classNamestring-

AvatarGroupCount

Komponen AvatarGroupCount menampilkan indikator penghitung dalam grup avatar, biasanya menunjukkan jumlah avatar tambahan.

PropTypeDefault
classNamestring-

Untuk informasi lebih lanjut tentang prop Base UI Avatar, lihat dokumentasi Base UI.