Radio Button
여러 항목 중 정확히 하나를 고릅니다. 옵션이 5개를 넘으면 Dropdown 을 씁니다.
1. Default
선택하지 않은 기본 상태입니다.
HTML
<label class="radio"><input type="radio" name="rd"><span>표준 모드</span></label>CSS · .radio, .radio-group
/* JS Design System v0.6 · .radio, .radio-group · 토큰(var(--*))은 assets/style.css :root 참고 */
.radio{display:inline-flex;align-items:flex-start;gap:8px;font-size:14px;cursor:pointer;line-height:1.4}
.radio input{appearance:none;-webkit-appearance:none;flex:none;width:16px;height:16px;margin:2px 0 0;border:1.5px solid var(--border-strong);border-radius:50%;background:var(--bg-surface);cursor:inherit;display:grid;place-items:center;transition:background var(--motion-fast),border-color var(--motion-fast)}
.radio input:hover{border-color:var(--border-strong)}
.radio input:checked{border-color:var(--accent);background:var(--accent)}
.radio input:checked::after{content:"";width:8px;height:8px;border-radius:50%;background:var(--accent-on)}
.radio input:disabled{opacity:.4;cursor:not-allowed}
.radio input:disabled+span{color:var(--text-disabled)}
.radio small{display:block;color:var(--text-tertiary);font-size:12px;font-weight:400}
.radio-group{display:flex;flex-direction:column;gap:12px}
.radio-group.row{flex-direction:row;gap:24px}
.radio.card{padding:14px 16px;border:1px solid var(--border-default);border-radius:var(--radius-md);background:var(--bg-surface);min-width:220px;flex-direction:row;gap:8px;box-shadow:none;position:static}
.radio.card:has(input:checked){border-color:var(--accent);background:var(--accent-subtle)}React · @jiran/ds-react
import { Radio } from "@jiran/ds-react";
export default function Example() {
return <Radio name="rd">표준 모드</Radio>;
}2. State
HTML
<label class="radio"><input type="radio" name="r1"><span>Unchecked</span></label>
<label class="radio"><input type="radio" name="r1" checked><span>Checked</span></label>
<label class="radio"><input type="radio" name="r2" disabled><span>Disabled</span></label>
<label class="radio"><input type="radio" name="r3" checked disabled><span>Disabled checked</span></label>CSS · .radio, .radio-group
/* JS Design System v0.6 · .radio, .radio-group · 토큰(var(--*))은 assets/style.css :root 참고 */
.radio{display:inline-flex;align-items:flex-start;gap:8px;font-size:14px;cursor:pointer;line-height:1.4}
.radio input{appearance:none;-webkit-appearance:none;flex:none;width:16px;height:16px;margin:2px 0 0;border:1.5px solid var(--border-strong);border-radius:50%;background:var(--bg-surface);cursor:inherit;display:grid;place-items:center;transition:background var(--motion-fast),border-color var(--motion-fast)}
.radio input:hover{border-color:var(--border-strong)}
.radio input:checked{border-color:var(--accent);background:var(--accent)}
.radio input:checked::after{content:"";width:8px;height:8px;border-radius:50%;background:var(--accent-on)}
.radio input:disabled{opacity:.4;cursor:not-allowed}
.radio input:disabled+span{color:var(--text-disabled)}
.radio small{display:block;color:var(--text-tertiary);font-size:12px;font-weight:400}
.radio-group{display:flex;flex-direction:column;gap:12px}
.radio-group.row{flex-direction:row;gap:24px}
.radio.card{padding:14px 16px;border:1px solid var(--border-default);border-radius:var(--radius-md);background:var(--bg-surface);min-width:220px;flex-direction:row;gap:8px;box-shadow:none;position:static}
.radio.card:has(input:checked){border-color:var(--accent);background:var(--accent-subtle)}React · @jiran/ds-react
import { Radio } from "@jiran/ds-react";
export default function Example() {
return (
<>
<Radio name="r1">Unchecked</Radio>
<Radio name="r1" defaultChecked>Checked</Radio>
<Radio name="r2" disabled>Disabled</Radio>
<Radio name="r3" defaultChecked disabled>Disabled checked</Radio>
</>
);
}3. Group
같은 name 으로 묶고 fieldset/legend 로 질문을 붙입니다. 설명은 small.
HTML
<fieldset class="radio-group" style="border:0;padding:0;margin:0">
<legend class="t-label-1" style="margin-bottom:8px">탐지 시 동작</legend>
<label class="radio"><input type="radio" name="act" checked><span>차단 후 알림<small>실행을 즉시 중단하고 관리자에게 알립니다</small></span></label>
<label class="radio"><input type="radio" name="act"><span>알림만<small>기록과 알림만, 실행은 허용</small></span></label>
<label class="radio"><input type="radio" name="act"><span>기록만</span></label>
</fieldset>CSS · .radio, .radio-group
/* JS Design System v0.6 · .radio, .radio-group · 토큰(var(--*))은 assets/style.css :root 참고 */
.radio{display:inline-flex;align-items:flex-start;gap:8px;font-size:14px;cursor:pointer;line-height:1.4}
.radio input{appearance:none;-webkit-appearance:none;flex:none;width:16px;height:16px;margin:2px 0 0;border:1.5px solid var(--border-strong);border-radius:50%;background:var(--bg-surface);cursor:inherit;display:grid;place-items:center;transition:background var(--motion-fast),border-color var(--motion-fast)}
.radio input:hover{border-color:var(--border-strong)}
.radio input:checked{border-color:var(--accent);background:var(--accent)}
.radio input:checked::after{content:"";width:8px;height:8px;border-radius:50%;background:var(--accent-on)}
.radio input:disabled{opacity:.4;cursor:not-allowed}
.radio input:disabled+span{color:var(--text-disabled)}
.radio small{display:block;color:var(--text-tertiary);font-size:12px;font-weight:400}
.radio-group{display:flex;flex-direction:column;gap:12px}
.radio-group.row{flex-direction:row;gap:24px}
.radio.card{padding:14px 16px;border:1px solid var(--border-default);border-radius:var(--radius-md);background:var(--bg-surface);min-width:220px;flex-direction:row;gap:8px;box-shadow:none;position:static}
.radio.card:has(input:checked){border-color:var(--accent);background:var(--accent-subtle)}React · @jiran/ds-react
import { Radio, RadioGroup } from "@jiran/ds-react";
export default function Example() {
return (
<RadioGroup legend="탐지 시 동작" name="act" defaultValue="block">
<Radio value="block" description="실행을 즉시 중단하고 관리자에게 알립니다">차단 후 알림</Radio>
<Radio value="notify" description="기록과 알림만, 실행은 허용">알림만</Radio>
<Radio value="log">기록만</Radio>
</RadioGroup>
);
}4. Card Radio
옵션마다 설명이 길거나 비교가 필요할 때 카드형.
HTML
<div class="radio-group row">
<label class="radio card"><input type="radio" name="plan" checked><span>표준 모드<small>권장. 알려진 위협 차단</small></span></label>
<label class="radio card"><input type="radio" name="plan"><span>강화 모드<small>의심 행위까지 차단, 오탐 증가</small></span></label>
</div>CSS · .radio, .radio-group
/* JS Design System v0.6 · .radio, .radio-group · 토큰(var(--*))은 assets/style.css :root 참고 */
.radio{display:inline-flex;align-items:flex-start;gap:8px;font-size:14px;cursor:pointer;line-height:1.4}
.radio input{appearance:none;-webkit-appearance:none;flex:none;width:16px;height:16px;margin:2px 0 0;border:1.5px solid var(--border-strong);border-radius:50%;background:var(--bg-surface);cursor:inherit;display:grid;place-items:center;transition:background var(--motion-fast),border-color var(--motion-fast)}
.radio input:hover{border-color:var(--border-strong)}
.radio input:checked{border-color:var(--accent);background:var(--accent)}
.radio input:checked::after{content:"";width:8px;height:8px;border-radius:50%;background:var(--accent-on)}
.radio input:disabled{opacity:.4;cursor:not-allowed}
.radio input:disabled+span{color:var(--text-disabled)}
.radio small{display:block;color:var(--text-tertiary);font-size:12px;font-weight:400}
.radio-group{display:flex;flex-direction:column;gap:12px}
.radio-group.row{flex-direction:row;gap:24px}
.radio.card{padding:14px 16px;border:1px solid var(--border-default);border-radius:var(--radius-md);background:var(--bg-surface);min-width:220px;flex-direction:row;gap:8px;box-shadow:none;position:static}
.radio.card:has(input:checked){border-color:var(--accent);background:var(--accent-subtle)}React · @jiran/ds-react
import { Radio, RadioGroup } from "@jiran/ds-react";
export default function Example() {
return (
<RadioGroup row card name="plan" defaultValue="standard">
<Radio value="standard" description="권장. 알려진 위협 차단">표준 모드</Radio>
<Radio value="hardened" description="의심 행위까지 차단, 오탐 증가">강화 모드</Radio>
</RadioGroup>
);
}Props
HTML 에서는 클래스와 속성으로, React(@jiran/ds-react)에서는 같은 이름의 prop(variant · size …)으로 변형·상태를 지정합니다.
| Prop / Class | Type · Values | Default | Description |
|---|---|---|---|
| .radio | label wrapper | — | input[type=radio] + span(라벨, small) |
| name | attribute | — | 같은 그룹은 같은 name |
| .card | boolean | false | 카드형(보더 + 선택 시 accent) |
| .radio-group | container | — | 세로 12px. .row 로 가로 |
Usage
React: @jiran/ds-react 패키지를 설치하고 style.css 를 한 번 import 하면 위 React 탭 코드를 그대로 쓸 수 있습니다(React Package). HTML: assets/style.css 를 연결하고(일부만 필요하면 아래 컴포넌트 CSS 복사), 동작이 필요하면 assets/ds.js 를 함께 넣습니다 — 이 페이지의 프리뷰가 그 스크립트로 동작합니다. 색은 전부 토큰(var(--accent) 등)을 참조하므로 --accent-* 만 제품 컬러로 바꾸면 됩니다.
React @jiran/ds-react
npm i @jiran/ds-react
// main.tsx — 앱 진입점에서 한 번
import "@jiran/ds-react/style.css";
// 컴포넌트
import { Radio, RadioGroup } from "@jiran/ds-react";HTML
<!-- 1) 토큰 + 전체 컴포넌트 스타일 한 번에 연결 -->
<link rel="stylesheet" href="assets/style.css">
<!-- 동작(드롭다운·탭·달력·표 정렬/선택·토스트 등) — 순수 JS 한 파일. React 제품은 불필요 -->
<script src="assets/ds.js" defer></script>
<!-- 2) 또는 아래 "Component CSS" 만 프로젝트 CSS 에 붙이고,
:root 토큰은 Foundations › Design Token 에서 복사 -->Component CSS .radio, .radio-group
/* JS Design System v0.6 · .radio, .radio-group · 토큰(var(--*))은 assets/style.css :root 참고 */
.radio{display:inline-flex;align-items:flex-start;gap:8px;font-size:14px;cursor:pointer;line-height:1.4}
.radio input{appearance:none;-webkit-appearance:none;flex:none;width:16px;height:16px;margin:2px 0 0;border:1.5px solid var(--border-strong);border-radius:50%;background:var(--bg-surface);cursor:inherit;display:grid;place-items:center;transition:background var(--motion-fast),border-color var(--motion-fast)}
.radio input:hover{border-color:var(--border-strong)}
.radio input:checked{border-color:var(--accent);background:var(--accent)}
.radio input:checked::after{content:"";width:8px;height:8px;border-radius:50%;background:var(--accent-on)}
.radio input:disabled{opacity:.4;cursor:not-allowed}
.radio input:disabled+span{color:var(--text-disabled)}
.radio small{display:block;color:var(--text-tertiary);font-size:12px;font-weight:400}
.radio-group{display:flex;flex-direction:column;gap:12px}
.radio-group.row{flex-direction:row;gap:24px}
.radio.card{padding:14px 16px;border:1px solid var(--border-default);border-radius:var(--radius-md);background:var(--bg-surface);min-width:220px;flex-direction:row;gap:8px;box-shadow:none;position:static}
.radio.card:has(input:checked){border-color:var(--accent);background:var(--accent-subtle)}