콘텐츠로 건너뛰기

아바타

프로필 메뉴, 댓글 스레드 및 팀 목록에 이니셜 대체 이미지가 적용되며, 네오브루탈리즘 스타일의 두꺼운 테두리 처리가 적용됩니다.

import {
  Avatar,
  AvatarBadge,

아바타는 사용자 이미지를 보여 주고, 이미지가 로드되는 중이거나 로드에 실패하면 이니셜이나 아이콘이 담긴 AvatarFallback으로 바꿔 줍니다. 레이아웃이 흔들리는 일은 없습니다. Base UI Avatar 컴포넌트를 기반으로 하며, 네오브루탈리즘 공식에 맞춰 두꺼운 2px 테두리와 굵은 제목 서체 이니셜을 적용했습니다.

다음과 같은 경우에 사용합니다.

  • 프로필 메뉴 — 계정 관련 동작을 여는 헤더 아바타입니다. Dropdown 예제를 참고하세요.
  • 댓글 스레드와 활동 피드 — 작성자 이름 옆마다 얼굴을 두고, 사진이 깨졌거나 없을 때는 이니셜이 자리를 채웁니다.
  • 팀과 멤버 목록AvatarGroup으로 참여자를 겹쳐 배치하고 AvatarGroupCount로 넘치는 인원을 정리합니다.

설치

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

다음 의존성을 설치합니다:

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

다음 코드를 복사해 프로젝트에 붙여넣습니다.

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

프로젝트 설정에 맞게 import 경로를 업데이트합니다.

사용법

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

구성

Avatar를 만들려면 다음 구성을 사용합니다:

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

AvatarGroup을 만들려면 다음 구성을 사용합니다:

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

예제

기본

이미지와 폴백을 갖춘 기본적인 아바타 컴포넌트입니다.

NB
import {
  Avatar,
  AvatarFallback,

배지

AvatarBadge 컴포넌트를 사용해 아바타에 배지를 추가합니다. 배지는 아바타의 오른쪽 아래에 배치됩니다.

import {
  Avatar,
  AvatarBadge,

className prop을 사용해 색상, 크기 등 커스텀 스타일을 배지에 추가할 수 있습니다.

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

아이콘 포함 배지

<AvatarBadge> 안에 아이콘을 사용할 수도 있습니다.

import { PlusIcon } from "lucide-react"

import {

아바타 그룹

AvatarGroup 컴포넌트를 사용해 아바타 그룹을 추가합니다.

import {
  Avatar,
  AvatarFallback,

아바타 그룹 카운트

<AvatarGroupCount>를 사용해 그룹에 카운트를 추가합니다.

import {
  Avatar,
  AvatarFallback,

아이콘 포함 아바타 그룹

<AvatarGroupCount> 안에 아이콘을 사용할 수도 있습니다.

import { PlusIcon } from "lucide-react"

import {

크기

size prop을 사용해 아바타의 크기를 변경합니다.

import {
  Avatar,
  AvatarFallback,

드롭다운

Avatar 컴포넌트를 드롭다운 메뉴의 트리거로 사용할 수 있습니다.

"use client"

import {

RTL

Neobrutalism에서 RTL을 활성화하는 방법은 RTL 설정 가이드를 참조하세요.

"use client"

import * as React from "react"

접근성

아바타는 이미지이므로 이미지에 적용되는 규칙이 그대로 통합니다. 아바타만으로 사람을 식별해야 한다면 AvatarImagealt에 그 사람의 이름을 넣고, 바로 옆에 이름이 눈에 보이게 표시된다면 alt=""로 두세요. 그렇지 않으면 스크린 리더가 이름을 두 번 읽습니다. AvatarFallback의 이니셜은 일반 텍스트라서 소리로 읽히므로 의미가 통하게 유지하세요. 아바타가 메뉴를 여는 경우(Dropdown 참고)에는 접근 가능한 이름을 이미지가 아니라 트리거 버튼에 지정하세요.

API 참조

Avatar

Avatar 컴포넌트는 아바타 이미지와 폴백을 감싸는 루트 컴포넌트입니다.

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

AvatarImage

AvatarImage 컴포넌트는 아바타 이미지를 표시합니다. Base UI Avatar Image의 모든 prop을 받습니다.

PropTypeDefault
srcstring-
altstring-
classNamestring-

AvatarFallback

AvatarFallback 컴포넌트는 이미지 로드에 실패했을 때 폴백을 표시합니다. Base UI Avatar Fallback의 모든 prop을 받습니다.

PropTypeDefault
classNamestring-

AvatarBadge

AvatarBadge 컴포넌트는 아바타 위에 배지 표시기를 표시하며, 보통 오른쪽 아래에 배치됩니다.

PropTypeDefault
classNamestring-

AvatarGroup

AvatarGroup 컴포넌트는 겹치는 스타일로 아바타 그룹을 표시합니다.

PropTypeDefault
classNamestring-

AvatarGroupCount

AvatarGroupCount 컴포넌트는 아바타 그룹 안에 카운트 표시기를 표시하며, 보통 추가 아바타의 수를 나타냅니다.

PropTypeDefault
classNamestring-

Base UI Avatar prop에 대한 자세한 내용은 Base UI 문서를 참조하세요.