라디오

라디오 (Radio)

여러 옵션 중 하나의 상태를 선택하는 컴포넌트예요. Select와 달리 옵션이 사용자에게 그대로 보여서 선택을 비교하기 쉬워요.

출처: 문서

본문

언제 사용하나요 (When To Use)

  • 여러 옵션 중 하나의 상태를 선택할 때 사용해요.
  • Select와 달리 Radio는 사용자에게 그대로 보여서 선택을 비교하기 쉬워요. 그래서 옵션이 너무 많으면 안 돼요.
// When use Radio.Group, recommended ✅
return (
  <Radio.Group
    value={value}
    options={[
      { value: 1, label: 'A' },
      { value: 2, label: 'B' },
      { value: 3, label: 'C' },
    ]}
  />
);

// Not recommended 🙅🏼‍♀️
return (
  <Radio.Group value={value}>
    <Radio value={1}>A</Radio>
    <Radio value={2}>B</Radio>
    <Radio value={3}>C</Radio>
  </Radio.Group>
);

예시 (Examples)

기본 (Basic)

가장 단순한 사용이에요.

import React from 'react';
import { Radio } from 'antd';

const App: React.FC = () => <Radio>Radio</Radio>;

export default App;

비활성화 (disabled)

Radio를 사용할 수 없어요.

import React, { useState } from 'react';
import { Button, Radio } from 'antd';

const App: React.FC = () => {
  const [disabled, setDisabled] = useState(true);

  const toggleDisabled = () => {
    setDisabled(!disabled);
  };

  return (
    <>
      <Radio defaultChecked={false} disabled={disabled}>
        Disabled
      </Radio>
      <Radio defaultChecked disabled={disabled}>
        Disabled
      </Radio>
      <br />
      <Button type="primary" onClick={toggleDisabled} style={{ marginTop: 16 }}>
        Toggle disabled
      </Button>
    </>
  );
};

export default App;

Radio 그룹 (Radio Group)

라디오 컴포넌트들의 그룹이에요.

import React, { useState } from 'react';
import {
  BarChartOutlined,
  DotChartOutlined,
  LineChartOutlined,
  PieChartOutlined,
} from '@ant-design/icons';
import type { RadioChangeEvent } from 'antd';
import { Flex, Radio } from 'antd';

const App: React.FC = () => {
  const [value, setValue] = useState(1);

  const onChange = (e: RadioChangeEvent) => {
    setValue(e.target.value);
  };

  return (
    <Radio.Group
      onChange={onChange}
      value={value}
      options={[
        {
          value: 1,
          className: 'option-1',
          label: (
            <Flex gap="small" justify="center" align="center" vertical>
              <LineChartOutlined style={{ fontSize: 18 }} />
              LineChart
            </Flex>
          ),
        },
        {
          value: 2,
          className: 'option-2',
          label: (
            <Flex gap="small" justify="center" align="center" vertical>
              <DotChartOutlined style={{ fontSize: 18 }} />
              DotChart
            </Flex>
          ),
        },
        {
          value: 3,
          className: 'option-3',
          label: (
            <Flex gap="small" justify="center" align="center" vertical>
              <BarChartOutlined style={{ fontSize: 18 }} />
              BarChart
            </Flex>
          ),
        },
        {
          value: 4,
          className: 'option-4',
          label: (
            <Flex gap="small" justify="center" align="center" vertical>
              <PieChartOutlined style={{ fontSize: 18 }} />
              PieChart
            </Flex>
          ),
        },
      ]}
    />
  );
};

export default App;

세로 Radio.Group (Vertical Radio.Group)

세로 Radio.Group으로, 라디오가 더 많아요.

import React, { useState } from 'react';
import type { RadioChangeEvent, RadioGroupProps } from 'antd';
import { Flex, Input, Radio } from 'antd';

const labelStyle: React.CSSProperties = {
  height: 32,
  lineHeight: '32px',
};

const buttonOptions: RadioGroupProps['options'] = [
  { label: 'Apple', value: 'Apple', className: 'label-1' },
  { label: 'Pear', value: 'Pear', className: 'label-2' },
  { label: 'Orange', value: 'Orange', title: 'Orange', className: 'label-3' },
];

const App: React.FC = () => {
  const [value, setValue] = useState(1);

  const onChange = (e: RadioChangeEvent) => {
    setValue(e.target.value);
  };

  return (
    <Flex align="start" gap="large">
      <div style={{ flex: 1 }}>
        <Radio.Group
          vertical
          onChange={onChange}
          value={value}
          options={[
            { value: 1, style: labelStyle, label: 'Option A' },
            { value: 2, style: labelStyle, label: 'Option B' },
            { value: 3, style: labelStyle, label: 'Option C' },
            {
              value: 4,
              style: labelStyle,
              label: (
                <>
                  More...
                  {value === 4 && (
                    <Input
                      variant="filled"
                      placeholder="please input"
                      style={{ width: 120, marginInlineStart: 12 }}
                    />
                  )}
                </>
              ),
            },
          ]}
        />
      </div>
      <div style={{ flex: 1 }}>
        <Radio.Group options={buttonOptions} optionType="button" vertical />
      </div>
    </Flex>
  );
};

export default App;

블록 Radio.Group (Block Radio.Group)

block 속성은 Radio.Group을 부모 너비에 꽉 차게 만들어요.

import React from 'react';
import { Flex, Radio } from 'antd';
import type { CheckboxGroupProps } from 'antd/es/checkbox';

const options: CheckboxGroupProps<string>['options'] = [
  { label: 'Apple', value: 'Apple' },
  { label: 'Pear', value: 'Pear' },
  { label: 'Orange', value: 'Orange' },
];

const App: React.FC = () => (
  <Flex vertical gap="medium">
    <Radio.Group block options={options} defaultValue="Apple" />
    <Radio.Group
      block
      options={options}
      defaultValue="Apple"
      optionType="button"
      buttonStyle="solid"
    />
    <Radio.Group block options={options} defaultValue="Pear" optionType="button" />
  </Flex>
);

export default App;

Radio.Group 그룹 — 옵션 설정 (Radio.Group group - optional)

options 설정으로 라디오를 렌더링해요. optionType 매개변수로 Radio 타입도 설정할 수 있어요.

import React, { useState } from 'react';
import type { RadioChangeEvent } from 'antd';
import { Radio } from 'antd';
import type { CheckboxGroupProps } from 'antd/es/checkbox';

const plainOptions: CheckboxGroupProps<string>['options'] = ['Apple', 'Pear', 'Orange'];

const options: CheckboxGroupProps<string>['options'] = [
  { label: 'Apple', value: 'Apple', className: 'label-1' },
  { label: 'Pear', value: 'Pear', className: 'label-2' },
  { label: 'Orange', value: 'Orange', title: 'Orange', className: 'label-3' },
];

const optionsWithDisabled: CheckboxGroupProps<string>['options'] = [
  { label: 'Apple', value: 'Apple', className: 'label-1' },
  { label: 'Pear', value: 'Pear', className: 'label-2' },
  { label: 'Orange', value: 'Orange', className: 'label-3', disabled: true },
];

const App: React.FC = () => {
  const [value1, setValue1] = useState('Apple');
  const [value2, setValue2] = useState('Apple');
  const [value3, setValue3] = useState('Apple');
  const [value4, setValue4] = useState('Apple');

  const onChange1 = ({ target: { value } }: RadioChangeEvent) => {
    console.log('radio1 checked', value);
    setValue1(value);
  };

  const onChange2 = ({ target: { value } }: RadioChangeEvent) => {
    console.log('radio2 checked', value);
    setValue2(value);
  };

  const onChange3 = ({ target: { value } }: RadioChangeEvent) => {
    console.log('radio3 checked', value);
    setValue3(value);
  };

  const onChange4 = ({ target: { value } }: RadioChangeEvent) => {
    console.log('radio4 checked', value);
    setValue4(value);
  };

  return (
    <>
      <Radio.Group options={plainOptions} onChange={onChange1} value={value1} />
      <br />
      <Radio.Group options={optionsWithDisabled} onChange={onChange2} value={value2} />
      <br />
      <br />
      <Radio.Group options={options} onChange={onChange3} value={value3} optionType="button" />
      <br />
      <br />
      <Radio.Group
        options={optionsWithDisabled}
        onChange={onChange4}
        value={value4}
        optionType="button"
        buttonStyle="solid"
      />
    </>
  );
};

export default App;

radio 스타일 (radio style)

라디오 버튼 스타일의 조합이에요.

import React from 'react';
import type { RadioChangeEvent } from 'antd';
import { Flex, Radio } from 'antd';

const onChange = (e: RadioChangeEvent) => {
  console.log(`radio checked:${e.target.value}`);
};

const App: React.FC = () => (
  <Flex vertical gap="medium">
    <Radio.Group onChange={onChange} defaultValue="a">
      <Radio.Button value="a">Hangzhou</Radio.Button>
      <Radio.Button value="b">Shanghai</Radio.Button>
      <Radio.Button value="c">Beijing</Radio.Button>
      <Radio.Button value="d">Chengdu</Radio.Button>
    </Radio.Group>
    <Radio.Group onChange={onChange} defaultValue="a">
      <Radio.Button value="a">Hangzhou</Radio.Button>
      <Radio.Button value="b" disabled>
        Shanghai
      </Radio.Button>
      <Radio.Button value="c">Beijing</Radio.Button>
      <Radio.Button value="d">Chengdu</Radio.Button>
    </Radio.Group>
    <Radio.Group disabled onChange={onChange} defaultValue="a">
      <Radio.Button value="a">Hangzhou</Radio.Button>
      <Radio.Button value="b">Shanghai</Radio.Button>
      <Radio.Button value="c">Beijing</Radio.Button>
      <Radio.Button value="d">Chengdu</Radio.Button>
    </Radio.Group>
  </Flex>
);

export default App;

이름이 있는 Radio.Group (Radio.Group with name)

같은 Radio.Group 안에 있는 모든 input[type="radio"]에 name 속성을 전달해요. 보통 브라우저가 Radio.Group을 실제 "그룹"으로 보고 기본 동작을 유지하게 하기 위해 사용해요. 예를 들어 같은 Radio.Group 안에서 좌우 키보드 화살표로 선택을 바꾸는 것 같은 것.

import React from 'react';
import { Radio } from 'antd';

const App: React.FC = () => (
  <Radio.Group
    name="radiogroup"
    defaultValue={1}
    options={[
      { value: 1, label: 'A' },
      { value: 2, label: 'B' },
      { value: 3, label: 'C' },
      { value: 4, label: 'D' },
    ]}
  />
);

export default App;

크기 (Size)

large, medium, small 세 가지 크기가 있어요. 입력 상자와 조화롭게 사용할 수 있어요.

import React from 'react';
import { Flex, Radio } from 'antd';

const App: React.FC = () => (
  <Flex vertical gap="medium">
    <Radio.Group defaultValue="a" size="large">
      <Radio.Button value="a">Hangzhou</Radio.Button>
      <Radio.Button value="b">Shanghai</Radio.Button>
      <Radio.Button value="c">Beijing</Radio.Button>
      <Radio.Button value="d">Chengdu</Radio.Button>
    </Radio.Group>
    <Radio.Group defaultValue="a">
      <Radio.Button value="a">Hangzhou</Radio.Button>
      <Radio.Button value="b">Shanghai</Radio.Button>
      <Radio.Button value="c">Beijing</Radio.Button>
      <Radio.Button value="d">Chengdu</Radio.Button>
    </Radio.Group>
    <Radio.Group defaultValue="a" size="small">
      <Radio.Button value="a">Hangzhou</Radio.Button>
      <Radio.Button value="b">Shanghai</Radio.Button>
      <Radio.Button value="c">Beijing</Radio.Button>
      <Radio.Button value="d">Chengdu</Radio.Button>
    </Radio.Group>
  </Flex>
);

export default App;

솔리드 라디오 버튼 (Solid radio button)

솔리드(solid) 라디오 버튼 스타일이에요.

import React from 'react';
import { Flex, Radio } from 'antd';

const App: React.FC = () => (
  <Flex vertical gap="medium">
    <Radio.Group defaultValue="a" buttonStyle="solid">
      <Radio.Button value="a">Hangzhou</Radio.Button>
      <Radio.Button value="b">Shanghai</Radio.Button>
      <Radio.Button value="c">Beijing</Radio.Button>
      <Radio.Button value="d">Chengdu</Radio.Button>
    </Radio.Group>
    <Radio.Group defaultValue="c" buttonStyle="solid">
      <Radio.Button value="a">Hangzhou</Radio.Button>
      <Radio.Button value="b" disabled>
        Shanghai
      </Radio.Button>
      <Radio.Button value="c">Beijing</Radio.Button>
      <Radio.Button value="d">Chengdu</Radio.Button>
    </Radio.Group>
  </Flex>
);

export default App;

시맨틱 DOM 스타일링 (Custom semantic dom styling)

classNames와 styles로 객체나 함수를 전달해 radio의 시맨틱 DOM 스타일을 커스터마이즈할 수 있어요.

import React from 'react';
import { Flex, Radio } from 'antd';
import type { GetProp, RadioProps } from 'antd';
import { createStyles } from 'antd-style';
import { clsx } from 'clsx';

const useStyles = createStyles(({ token, css }) => ({
  root: css`
    border-radius: ${token.borderRadius}px;
    background-color: ${token.colorBgContainer};
  `,
  icon: css`
    border-color: ${token.colorWarning};
  `,
  label: css`
    color: ${token.colorTextDisabled};
    font-weight: bold;
  `,

  iconChecked: css`
    background-color: ${token.colorWarning};
  `,
  labelChecked: css`
    color: ${token.colorWarning};
  `,
}));

// Object style
const styles: RadioProps['styles'] = {
  icon: {
    borderRadius: 6,
  },
  label: {
    color: 'blue',
  },
};

const App: React.FC = () => {
  const [value, setValue] = React.useState<'styles' | 'classNames'>('styles');
  const { styles: classNamesStyles } = useStyles();

  // Function classNames - dynamically adjust based on checked state
  const classNamesFn: RadioProps['classNames'] = (
    info,
  ): GetProp<RadioProps, 'classNames', 'Return'> => {
    if (info.props.checked) {
      return {
        root: clsx(classNamesStyles.root),
        icon: clsx(classNamesStyles.icon, classNamesStyles.iconChecked),
        label: clsx(classNamesStyles.label, classNamesStyles.labelChecked),
      };
    }
    return {
      root: classNamesStyles.root,
      icon: classNamesStyles.icon,
      label: classNamesStyles.label,
    };
  };

  return (
    <Flex vertical gap="medium">
      <Radio
        name="style-class"
        styles={styles}
        checked={value === 'styles'}
        onChange={() => setValue('styles')}
      >
        Object styles
      </Radio>
      <Radio
        name="style-class"
        classNames={classNamesFn}
        checked={value === 'classNames'}
        onChange={() => setValue('classNames')}
      >
        Function classNames
      </Radio>
    </Flex>
  );
};

export default App;

API

공통 props는 Common props를 참고해요.

Radio/Radio.Button

속성 (Property) 설명 (Description) 타입 (Type) 기본값 (Default) 버전 (Version) 글로벌 설정
checked 라디오가 선택되었는지 여부 boolean false ×
classNames 컴포넌트 내부의 각 시맨틱 구조에 대한 class를 지정해요. 객체 또는 함수를 지원해요. Record<SemanticDOM, string> | (info: { props })=> Record<SemanticDOM, string> - 6.0.0 6.0.0
defaultChecked 초기 상태: 라디오 선택 여부 boolean false ×
disabled 라디오 비활성화 boolean false ×
styles 컴포넌트 내부의 각 시맨틱 구조에 대한 인라인 스타일을 지정해요. 객체 또는 함수를 지원해요. Record<SemanticDOM, CSSProperties> | (info: { props })=> Record<SemanticDOM, CSSProperties> - 6.0.0 6.0.0
value 비교를 위한 값으로, 선택 여부를 판단해요. any - ×

Radio.Group

라디오 그룹은 Radio들의 그룹을 감쌀 수 있어요.

속성 (Property) 설명 (Description) 타입 (Type) 기본값 (Default) 버전 (Version)
block RadioGroup 너비를 부모 너비에 맞추는 옵션 boolean false 5.21.0
buttonStyle 라디오 버튼의 스타일 타입 outline | solid outline
classNames 컴포넌트 내부의 각 시맨틱 구조에 대한 class를 지정해요. 객체 또는 함수를 지원해요. Record<SemanticDOM, string> | (info: { props })=> Record<SemanticDOM, string> - 6.0.0
defaultValue 기본 선택 값 any -
disabled 모든 라디오 버튼 비활성화 boolean false
name 모든 input[type="radio"] 자식의 name 속성이에요. 설정하지 않으면 무작위로 생성된 이름으로 대체돼요. string -
options 자식 옵션 설정 string[] | number[] | Array<CheckboxOptionType> -
optionType Radio optionType 설정 default | button default 4.4.0
orientation 방향 horizontal | vertical horizontal
size 라디오 버튼 스타일의 크기 large | medium | small -
styles 컴포넌트 내부의 각 시맨틱 구조에 대한 인라인 스타일을 지정해요. 객체 또는 함수를 지원해요. Record<SemanticDOM, CSSProperties> | (info: { props })=> Record<SemanticDOM, CSSProperties> - 6.0.0
value 현재 선택된 값을 설정하는 데 사용돼요. any -
vertical true이면 Radio 그룹이 세로가 돼요. orientation과 동시에 존재할 때 orientation이 우선해요. boolean false
onChange 상태가 변경될 때 트리거되는 콜백 함수 function(e:Event) -

CheckboxOptionType

속성 (Property) 설명 (Description) 타입 (Type) 기본값 (Default) 버전 (Version)
label Radio 옵션으로 표시할 텍스트 string - 4.4.0
value Radio 옵션과 연관된 값 string | number | boolean - 4.4.0
style Radio 옵션에 적용할 스타일 React.CSSProperties - 4.4.0
className Radio 옵션의 className string - 5.25.0
disabled Radio 옵션 비활성화 여부 boolean false 4.4.0
title Title 속성 값 추가 string - 4.4.0
id Radio Id 속성 값 추가 string - 4.4.0
onChange Radio 그룹의 값이 변경될 때 트리거돼요. (e: CheckboxChangeEvent) => void; - 4.4.0
required Radio 옵션이 필수인지 여부 boolean false 4.4.0

메서드 (Methods)

Radio

이름 (Name) 설명 (Description)
blur() 포커스 제거
focus() 포커스 획득

시맨틱 DOM (Semantic DOM)

시맨틱 DOM 구조는 https://ant.design/components/radio/semantic.md 에서 확인할 수 있어요.

디자인 토큰 (Design Token)

컴포넌트 토큰 (Radio) (Component Token)

토큰 이름 (Token Name) 설명 (Description) 타입 (Type) 기본값 (Default Value)
buttonBg Radio 버튼의 배경색 string #ffffff
buttonCheckedBg 선택된 Radio 버튼의 배경색 string #ffffff
buttonCheckedBgDisabled 선택되고 비활성화된 Radio 버튼의 배경색 string rgba(0,0,0,0.15)
buttonCheckedColorDisabled 선택되고 비활성화된 Radio 버튼 텍스트의 색 string rgba(0,0,0,0.25)
buttonColor Radio 버튼 텍스트의 색 string rgba(0,0,0,0.88)
buttonPaddingInline Radio 버튼의 가로 패딩 number 15
buttonSolidCheckedActiveBg 활성 시 선택된 solid Radio 버튼 텍스트의 배경색 string #0958d9
buttonSolidCheckedBg 선택된 solid Radio 버튼 텍스트의 배경색 string #1677ff
buttonSolidCheckedColor 선택된 solid Radio 버튼 텍스트의 색 string #fff
buttonSolidCheckedHoverBg hover 시 선택된 solid Radio 버튼 텍스트의 배경색 string #4096ff
dotColorDisabled 비활성 Radio 점의 색 string rgba(0,0,0,0.25)
dotSize Radio 점의 크기 number 8
radioSize Radio 크기 number 16
wrapperMarginInlineEnd Radio 버튼의 오른쪽 여백 number 8

글로벌 토큰 (Global Token)

토큰 이름 (Token Name) 설명 (Description) 타입 (Type) 기본값 (Default Value)
borderRadius 기본 컴포넌트의 테두리 반경 number
borderRadiusLG LG 크기 테두리 반경이에요. Card, Modal 등 큰 테두리 반경을 가진 컴포넌트에 사용돼요. number
borderRadiusSM SM 크기 테두리 반경이에요. Button, Input, Select 등 작은 크기의 입력 컴포넌트에 사용돼요. number
colorBgContainer 컨테이너 배경색이에요. 기본 버튼, 입력 상자 등. colorBgElevated와 혼동하지 마세요. string
colorBgContainerDisabled 비활성 상태에서 컨테이너의 배경색을 제어해요. string
colorBorder 기본 테두리 색이에요. 폼 구분선, 카드 구분선처럼 서로 다른 요소를 구분하는 데 사용돼요. string
colorPrimary 브랜드 색은 제품의 특성과 커뮤니케이션을 반영하는 가장 직접적인 시각 요소 중 하나예요. 브랜드 색을 선택하면 자동으로 완전한 색 팔레트가 생성되고 유효한 디자인 시맨틱이 부여돼요. string
colorPrimaryActive 메인 색 그라데이션 아래의 어두운 활성 상태 string
colorPrimaryBorder 메인 색 그라데이션 아래의 스트로크 색이에요. Slider 같은 컴포넌트의 stroke에 사용돼요. string
colorPrimaryHover 메인 색 그라데이션 아래의 Hover 상태 string
colorText W3C 표준을 따르는 기본 텍스트 색이에요. 가장 어두운 중성색이기도 해요. string
colorTextDisabled 비활성 상태의 텍스트 색을 제어해요. string
controlHeight Ant Design에서 버튼, 입력 상자 같은 기본 컨트롤의 높이 number
controlHeightLG LG 컴포넌트 높이 number
controlHeightSM SM 컴포넌트 높이 number
controlOutline 입력 컴포넌트의 outline 색을 제어해요. string
controlOutlineWidth 입력 컴포넌트의 outline 너비를 제어해요. number
fontFamily Ant Design의 글꼴은 시스템의 기본 인터페이스 글꼴을 우선시하고, 화면 표시에 적합한 대체 글꼴 라이브러리를 제공해 플랫폼과 브라우저에 따라 가독성을 유지하며 친근하고 안정적이며 전문적인 특성을 반영해요. string
fontSize 디자인 시스템에서 가장 널리 쓰이는 글자 크기로, 여기서 텍스트 그라데이션이 파생돼요. number
fontSizeLG 큰 글자 크기 number
lineHeight 텍스트의 줄 높이예요. number
lineType 기본 컴포넌트의 테두리 스타일 string
lineWidth 기본 컴포넌트의 테두리 두께 number
lineWidthFocus 컴포넌트가 포커스 상태일 때 선의 너비를 제어해요. number
marginXS 작은 크기의 요소 여백을 제어해요. number
motionDurationMid 동작 속도, 중간 속도예요. 중간 요소의 애니메이션 상호작용에 사용돼요. string
motionDurationSlow 동작 속도, 느린 속도예요. 큰 요소의 애니메이션 상호작용에 사용돼요. string
motionEaseInOutCirc 미리 정의된 모션 곡선이에요. string
paddingXS 요소의 아주 작은 패딩을 제어해요. number

더 알아보기 (Learn more)