import { Badge } from "@/components/ui/badge"
export function BadgeDemo() {배지는 짧은 인라인 레이블입니다. 아래에 깔린 프리미티브 없이 평범한 <span>을 렌더링하며, 네오브루탈리즘 공식(두꺼운 테두리, 선명한 그림자, 굵은 서체)에 맞춰 스타일을 입혔습니다. render prop(Base UI의 useRender를 통해)을 쓰면 링크든 버튼이든 어떤 요소에나 배지 스타일을 입힐 수 있습니다.
다음과 같은 경우에 사용합니다.
- 상태 표시 — 테이블 행과 카드에 붙는 "활성", "초안", "실패". 오류에는
destructive를 씁니다. - 개수 표시 — 읽지 않은 메시지, 장바구니 항목, 내비게이션 레이블 옆의 알림 개수.
- 태그와 메타데이터 — 블로그 카드의 카테고리, 요금제 등급, 문서의 버전 표시.
설치#
pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/badge.jsonnpx shadcn@latest add https://neobrutalism.com/r/base/badge.jsonyarn dlx shadcn@latest add https://neobrutalism.com/r/base/badge.jsonbunx --bun shadcn@latest add https://neobrutalism.com/r/base/badge.json
다음 코드를 복사해 프로젝트에 붙여넣습니다.
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { Slot } from "radix-ui"
import { cn } from "@/lib/utils"
const badgeVariants = cva(
"group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded border-2 px-2 py-0.5 text-xs font-head font-medium whitespace-nowrap shadow-sm transition-all focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive [&>svg]:pointer-events-none [&>svg]:size-3!",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
secondary:
"bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
destructive:
"bg-destructive text-destructive-foreground [a]:hover:bg-destructive/90",
outline:
"bg-transparent text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
ghost:
"border-transparent bg-transparent shadow-none hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
link: "border-transparent bg-transparent shadow-none text-primary underline-offset-4 hover:underline",
},
},
defaultVariants: {
variant: "default",
},
}
)
function Badge({
className,
variant = "default",
asChild = false,
...props
}: React.ComponentProps<"span"> &
VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
const Comp = asChild ? Slot.Root : "span"
return (
<Comp
data-slot="badge"
data-variant={variant}
className={cn(badgeVariants({ variant }), className)}
{...props}
/>
)
}
export { Badge, badgeVariants }
프로젝트 설정에 맞게 import 경로를 업데이트합니다.
사용법#
import { Badge } from "@/components/ui/badge"<Badge variant="default | outline | secondary | destructive">Badge</Badge>예제#
변형#
variant prop을 사용해 배지의 변형을 변경합니다.
import { Badge } from "@/components/ui/badge"
export function BadgeVariants() {아이콘 포함#
배지 안에 아이콘을 렌더링할 수 있습니다. data-icon="inline-start"로 아이콘을 왼쪽에, data-icon="inline-end"로 아이콘을 오른쪽에 렌더링합니다.
import { BadgeCheck, BookmarkIcon } from "lucide-react"
import { Badge } from "@/components/ui/badge"스피너 포함#
배지 안에 스피너를 렌더링할 수 있습니다. 스피너에 data-icon="inline-start" 또는 data-icon="inline-end" prop을 추가하는 것을 잊지 마세요.
import { Badge } from "@/components/ui/badge"
import { Spinner } from "@/components/ui/spinner"
링크#
render prop을 사용해 링크를 배지로 렌더링합니다.
import { ArrowUpRightIcon } from "lucide-react"
import { Badge } from "@/components/ui/badge"커스텀 색상#
Badge 컴포넌트에 bg-chart-2 text-primary-foreground 같은 커스텀 클래스를 추가하여 배지의 색상을 커스터마이즈할 수 있습니다.
import { Badge } from "@/components/ui/badge"
export function BadgeCustomColors() {RTL#
Neobrutalism에서 RTL을 활성화하는 방법은 RTL 설정 가이드를 참조하세요.
"use client"
import * as React from "react"접근성#
배지는 평범한 <span>을 렌더링합니다. 스크린 리더에는 그 안의 텍스트만 전달되므로 색만으로 의미를 전달하지 마세요. variant="destructive"는 default와 똑같이 읽히니, "실패"라는 사실은 텍스트가 말해 주어야 합니다. 숫자만 덩그러니 놓인 개수에는 맥락이 필요합니다. aria-label이나 시각적으로 숨긴 텍스트를 더해 "3"이 "읽지 않은 알림 3개"로 읽히게 하세요. render prop으로 링크로 렌더링하면 평범한 앵커이므로 링크의 일반적인 시맨틱이 그대로 적용됩니다.
API 참조#
Badge#
Badge 컴포넌트는 배지, 또는 배지처럼 보이는 컴포넌트를 표시합니다.
| Prop | Type | Default |
|---|---|---|
variant | "default" | "secondary" | "destructive" | "outline" | "ghost" | "link" | "default" |
className | string | - |