Radio

Stable

여러 개의 선택지 중 오직 하나의 항목만 상호 배타적으로 선택할 때 사용하는 컴포넌트입니다.

DESIGN & DEVELOPMENTUpdated Sep 2026

Overview

Radio는 여러 개의 선택지 중 사용자가 단 하나의 옵션만 상호 배타적으로 선택해야 할 때 사용합니다. 모든 옵션이 화면에 바로 노출되어 선택지 간의 비교가 쉬우며, RadioGroup 컨테이너로 감싸 손쉽게 상태를 동기화할 수 있습니다.

LIVE PREVIEW마우스 클릭 또는 키보드 방향키(↑/↓/←/→)로 선택해 보세요

선택된 결제 수단: 신용/체크카드

TSX / CSS
<RadioGroup
  name="payment-method"
  size="md"
  direction="vertical"
  value="card"
  onChange={(val) => setSelectedValue(val)}
>
  <Radio
    value="card"
    label="신용/체크카드"
    description="국내외 모든 카드사 무이자 할부 지원"
  />
  <Radio
    value="pay"
    label="간편결제"
    description="카카오페이, 네이버페이, 토스페이"
  />
  <Radio
    value="transfer"
    label="실시간 계좌이체"
    description="이체 수수료 무료"
  />
</RadioGroup>

RadioGroup은 WAI-ARIA role="radiogroup"을 준수합니다. 그룹 내에서 키보드 화살표 키(↑, ↓, ←, →)를 눌러 이전/다음 항목으로 즉시 포커스 및 선택을 이동할 수 있습니다.

Anatomy

번호구성 요소역할
1외곽 원 (Outer Circle)라디오 컨트롤의 범위를 표시하는 원형 컨테이너 (호버, 포커스, 에러 테두리 반영)
2도트 인디케이터 (Dot Indicator)선택(Checked) 상태 시 중앙에 채워지는 원형 불릿
3레이블 (Label)선택하려는 옵션의 이름 또는 텍스트 (클릭 시 해당 옵션 선택)
4보조 설명 (Description)옵션에 대한 상세 부가 정보 (스크린 리더 aria-describedby 자동 연결)

Sizes

화면의 정보 밀도와 배치 공간에 맞춰 3가지 크기를 제공합니다. 기본값은 md(20px)입니다.

Size규격 (외곽 / 도트)미리보기 (Preview)권장 적용 맥락
sm (16px)16px / 8px테이블 셀 내부, 데이터 밀도가 높은 압축 목록
md (20px)20px / 10px (기본)일반 웹 폼, 설정 다이얼로그, 기본 표준 선택지
lg (24px)24px / 12px모바일 터치 중심 화면, 결제 수단 등 시각적 강조 영역

States

사용자의 상호작용 및 폼 유효성 검증 상태를 원형 인디케이터와 색상으로 명확히 전달합니다.

상태 (State)미리보기 (Preview)동작 및 가이드
Unchecked사용자의 선택을 기다리는 기본 대기 상태
Checked라디오 그룹 내에서 현재 활성화된 옵션
Error필수 선택이 누락되었거나 유효성 검증에 실패한 상태
Disabled조건 미충족 또는 비활성화되어 조작할 수 없는 상태

Variants

RadioGroup 컨테이너는 direction 속성을 통해 수직(기본값) 및 수평 배치를 손쉽게 전환할 수 있습니다.

1. Vertical Layout (수직 배치 - 권장)

항목마다 보조 설명이 있거나 옵션 수가 3개 이상일 때 사용하는 표준 레이아웃입니다.

2. Horizontal Layout (수평 배치)

레이블 길이가 짧고 2~3개의 단순 선택지(예: 공개 여부, 성별)일 때 공간 효율적으로 배치합니다.

Guidelines

권장해요

상호 배타적인 2~7개 이내의 옵션을 한눈에 비교해야 할 때 Radio를 사용합니다.

선택지 목록 중 가장 보편적인 기본값(Default)을 하나 미리 선택해 둡니다.

선택 해제가 필요한 경우, '선택 안 함' 옵션을 명시적으로 제공합니다.

옵션 레이블에 구체적인 부가 설명이 필요한 경우 수직(Vertical) 레이아웃을 사용합니다.

피해주세요

복수 선택이 가능해야 하는 경우 Radio 대신 Checkbox를 사용합니다.

선택지가 8개 이상으로 많다면 화면 공간을 위해 Select(드롭다운)를 사용합니다.

단독으로 On/Off 상태를 전환하는 설정에는 Radio 대신 Checkbox나 Switch를 사용합니다.

모든 라디오가 미선택된 빈 상태로 폼을 시작하지 않습니다.

API

RadioGroup Props

PropTypeDefaultDescription
namestringauto-generated라디오 그룹 내 모든 라디오를 묶어주는 고유 이름
valuestringundefined제어 컴포넌트용 현재 선택된 값
defaultValuestringundefined비제어 컴포넌트용 초기 선택 값
onChange(value: string) => voidundefined선택된 옵션 값 변경 시 호출되는 이벤트 콜백
size'sm' | 'md' | 'lg''md'그룹 내 라디오 항목들의 일괄 크기 지정
direction'vertical' | 'horizontal''vertical'라디오 목록 배치 방향
disabledbooleanfalse그룹 전체 비활성화 여부
errorbooleanfalse그룹 유효성 검사 오류 상태 여부

Radio Props

PropTypeDefaultDescription
valuestringundefined해당 라디오 옵션이 가진 고유 식별 값
size'sm' | 'md' | 'lg'group.size개별 라디오 외곽 원 크기 및 텍스트 스케일
labelReactNodeundefined라디오 우측 텍스트 (클릭 시 해당 옵션 선택)
descriptionReactNodeundefined레이블 하단 보조 설명 문구 (aria-describedby 자동 연결)
disabledbooleangroup.disabled해당 옵션 비활성화 여부
errorbooleangroup.error해당 옵션 오류 강조 여부
wrapperClassNamestring''외곽 라벨 래퍼 커스텀 클래스

Code Example

TSX / CSS
import { useState } from 'react';
import { Radio, RadioGroup } from '@/components/ui';

export function Example() {
  const [selectedPlan, setSelectedPlan] = useState('pro');

  return (
    <RadioGroup
      name="pricing-plan"
      direction="vertical"
      value={selectedPlan}
      onChange={setSelectedPlan}
    >
      <Radio
        value="basic"
        label="Basic 요금제 (무료)"
        description="개인 프로젝트 및 기본 문서 열람"
      />
      <Radio
        value="pro"
        label="Pro 요금제 (월 12,000원)"
        description="무제한 컴포넌트 복사 및 커스텀 토큰 내보내기"
      />
      <Radio
        value="enterprise"
        label="Enterprise 요금제"
        description="엔터프라이즈 전용 SSO 및 기술 지원"
        disabled
      />
    </RadioGroup>
  );
}
작은 원칙이 좋은 경험을 만듭니다.맨 위로