콘텐츠로 건너뛰기

체크박스

동의 체크박스, 다중 선택 필터, 일괄 행 선택을 위한 이진 토글 — 네오브루탈리즘 스타일의 테두리와 그림자 효과가 적용되었습니다.

"use client"

import { Checkbox } from "@/components/ui/checkbox"

체크박스는 둘 중 하나를 고르는 표준 컨트롤입니다. 선택, 선택 해제, 그리고 일부만 선택된 상태를 나타내는 중간 상태를 지원합니다. Base UI Checkbox 프리미티브를 기반으로 하며, 네오브루탈리즘 공식(두꺼운 테두리, 선명한 그림자, 굵은 서체)에 맞춰 스타일을 입혔습니다.

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

  • 약관과 동의 — 가입과 결제 흐름의 "동의합니다" 체크박스로, 폼과 함께 전송됩니다.
  • 다중 선택 필터 — 어떤 조합이든 유효한 사이드바의 카테고리, 태그, 가격대.
  • 테이블의 일괄 선택 — 행마다 놓인 체크박스와 헤더의 중간 상태 전체 선택.

설치

pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/checkbox.json
npx shadcn@latest add https://neobrutalism.com/r/base/checkbox.json
yarn dlx shadcn@latest add https://neobrutalism.com/r/base/checkbox.json
bunx --bun shadcn@latest add https://neobrutalism.com/r/base/checkbox.json

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

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

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

components/ui/checkbox.tsx
"use client"

import * as React from "react"
import { CheckIcon } from "lucide-react"
import { Checkbox as CheckboxPrimitive } from "radix-ui"

import { cn } from "@/lib/utils"

function Checkbox({
  className,
  ...props
}: React.ComponentProps<typeof CheckboxPrimitive.Root>) {
  return (
    <CheckboxPrimitive.Root
      data-slot="checkbox"
      className={cn(
        "peer relative flex size-5 shrink-0 items-center justify-center rounded border-2 bg-input shadow-sm transition-colors outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive data-checked:border-border data-checked:bg-primary data-checked:text-primary-foreground",
        className
      )}
      {...props}
    >
      <CheckboxPrimitive.Indicator
        data-slot="checkbox-indicator"
        className="grid place-content-center text-current transition-none [&>svg]:size-3.5"
      >
        <CheckIcon />
      </CheckboxPrimitive.Indicator>
    </CheckboxPrimitive.Root>
  )
}

export { Checkbox }

임포트 경로를 프로젝트 구성에 맞게 수정합니다.

사용법

import { Checkbox } from "@/components/ui/checkbox"
<Checkbox />

체크 상태

비제어 체크박스에는 defaultChecked 를 사용하고, 상태를 제어하려면 checkedonCheckedChange 를 사용합니다.

import * as React from "react"
 
export function Example() {
  const [checked, setChecked] = React.useState(false)
 
  return <Checkbox checked={checked} onCheckedChange={setChecked} />
}

유효하지 않은 상태

유효하지 않은 상태의 스타일을 표시하려면 체크박스에 aria-invalid 를, 필드 래퍼에 data-invalid 를 설정합니다.

import { Checkbox } from "@/components/ui/checkbox"
import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"

예제

기본

적절한 레이아웃과 레이블링을 위해 체크박스를 FieldFieldLabel 과 함께 사용합니다.

import { Checkbox } from "@/components/ui/checkbox"
import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"

설명

보조 텍스트에는 FieldContentFieldDescription 을 사용합니다.

import { Checkbox } from "@/components/ui/checkbox"
import {
  Field,

비활성화

조작을 막으려면 disabled prop 을 사용하고, 비활성화 스타일을 적용하려면 <Field> 컴포넌트에 data-disabled 속성을 추가합니다.

import { Checkbox } from "@/components/ui/checkbox"
import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"

그룹

여러 필드를 사용해 체크박스 목록을 만듭니다.

import { Checkbox } from "@/components/ui/checkbox"
import {
  Field,

테이블

"use client"

import * as React from "react"

RTL

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

"use client"

import * as React from "react"

접근성

체크박스는 WAI-ARIA Checkbox 패턴을 따릅니다. 프리미티브는 aria-checked(중간 상태를 뜻하는 "mixed" 포함)를 갖춘 role="checkbox" 요소를 렌더링하고, 숨겨진 네이티브 input과 값을 동기화해 폼과 함께 전송되게 합니다.

키보드 상호작용:

동작
Tab / Shift + Tab체크박스로 포커스 이동, 또는 체크박스에서 포커스 이탈
Space선택 상태 전환(중간 상태 → 선택)

Enter로는 체크박스가 전환되지 않습니다. 버그가 아니라 ARIA 패턴에 따른 동작입니다.

API 참조

자세한 내용은 Base UI 문서를 참고하세요.