콘텐츠로 건너뛰기

라디오 그룹

요금제, 배송 옵션 및 설정 양식을 위한 단일 선택형 라디오 버튼 세트 — 네오브루탈리즘 스타일의 테두리와 그림자 효과가 적용되었습니다.

import { Label } from "@/components/ui/label"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"

라디오 그룹은 서로 배타적인 옵션 집합을 보여 줍니다. 하나를 선택하면 나머지는 해제됩니다. Base UI Radio Group 프리미티브를 기반으로 하며, 네오브루탈리즘 공식(두꺼운 테두리, 선명한 그림자, 굵은 서체)에 맞춰 스타일을 입혔습니다.

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

  • 플랜 선택기 — free / pro / enterprise를 선택 카드로 두고 하나만 고르게 합니다.
  • 결제 옵션 — 배송 속도나 결제 수단처럼 모든 선택이 보여야 하는 경우.
  • 옵션 2–5개 설정 — 테마, 밀도, 알림 빈도. select보다 클릭이 적습니다.

설치

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

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

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

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

components/ui/radio-group.tsx
"use client"

import * as React from "react"
import { RadioGroup as RadioGroupPrimitive } from "radix-ui"

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

function RadioGroup({
  className,
  ...props
}: React.ComponentProps<typeof RadioGroupPrimitive.Root>) {
  return (
    <RadioGroupPrimitive.Root
      data-slot="radio-group"
      className={cn("grid w-full gap-2", className)}
      {...props}
    />
  )
}

function RadioGroupItem({
  className,
  ...props
}: React.ComponentProps<typeof RadioGroupPrimitive.Item>) {
  return (
    <RadioGroupPrimitive.Item
      data-slot="radio-group-item"
      className={cn(
        "group/radio-group-item peer relative flex aspect-square size-5 shrink-0 rounded-full border-2 bg-input shadow-sm outline-none 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",
        className
      )}
      {...props}
    >
      <RadioGroupPrimitive.Indicator
        data-slot="radio-group-indicator"
        className="flex size-4 items-center justify-center"
      >
        <span className="absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-primary" />
      </RadioGroupPrimitive.Indicator>
    </RadioGroupPrimitive.Item>
  )
}

export { RadioGroup, RadioGroupItem }

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

사용법

import { Label } from "@/components/ui/label"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
<RadioGroup defaultValue="option-one">
  <div className="flex items-center gap-3">
    <RadioGroupItem value="option-one" id="option-one" />
    <Label htmlFor="option-one">Option One</Label>
  </div>
  <div className="flex items-center gap-3">
    <RadioGroupItem value="option-two" id="option-two" />
    <Label htmlFor="option-two">Option Two</Label>
  </div>
</RadioGroup>

구성

RadioGroup을 만들려면 다음 구성을 사용합니다.

RadioGroup
├── RadioGroupItem
└── RadioGroupItem

예제

설명

Field 컴포넌트를 사용해서 설명을 붙인 라디오 그룹 항목입니다.

import {
  Field,
  FieldContent,

선택 카드

FieldLabelField 전체를 감싸면 클릭 가능한 카드 형태의 선택으로 만들 수 있습니다.

import {
  Field,
  FieldContent,

Fieldset

FieldSetFieldLegend를 사용해서 라벨과 설명과 함께 라디오 항목을 그룹화합니다.

import {
  Field,
  FieldDescription,

비활성화

RadioGroupdisabled prop을 사용해서 모든 항목을 비활성화합니다.

import { Field, FieldLabel } from "@/components/ui/field"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"

오류 상태

RadioGroupItemaria-invalid, Fielddata-invalid를 지정해서 유효성 검증 오류를 표시합니다.

import {
  Field,
  FieldDescription,

RTL

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

"use client"

import * as React from "react"

접근성

라디오 그룹은 WAI-ARIA Radio Group 패턴을 따릅니다. 컨테이너는 role="radiogroup", 각 항목은 aria-checked가 있는 role="radio" 버튼이며, 로빙 tabindex로 그룹 전체가 탭 스톱 하나입니다.

키보드 상호작용:

동작
Tab / Shift + Tab그룹으로 포커스 이동(선택된 항목, 없으면 첫 항목)/이탈
Space아직 아니면 포커스된 항목 선택
ArrowDown / ArrowRight다음 항목으로 포커스 이동 후 선택
ArrowUp / ArrowLeft이전 항목으로 포커스 이동 후 선택

좌우 화살표는 RTL에서 읽기 방향을 따릅니다.

API 참조

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