4.4 KiB
Radio Group
현재 HM 구현의 기준 문서. 공통 원칙은 docs/guidelines/프로젝트-지침.md(§6, §7), Token 구조 원칙은 테마-토큰-가이드.md를 따른다. 이 문서는 Radio Group 고유의 API·Token·상태·결정만 기록한다.
1. 상태
| 항목 | 내용 |
|---|---|
| 구현 상태 | 구현 완료 (현재 HM 규격) |
| 기준일 | 2026-10-02 |
| 기반 | shadcn/ui Radio Group (Radix RadioGroup) |
| 대표 Story | Components/Form/Radio Group → All (이름 "Radio Group") |
| 보류 | 아래 §11 |
2. 적용 근거
- 참고 근거: ui-viz 기존 테스트 규격에는 Radio 문서가 없다(
RADIO-01TBD, HOLD, group spacing·전경 role TBD). 확정 규격이 없어 참고만 했다. - 현재 HM 규격: §3~§4. Checkbox와 같은 HM Semantic 체계로 새로 정했다(Component Token은 따로 둔다).
- 구현 방식: Radix RadioGroup(roving focus, 방향키 선택,
role=radiogroup/radio,data-state,data-orientation)을 유지하고 theme CSS로 연결. shadcnCircleIcon을 inner dot으로 유지. - 보류: §11.
3. 기본 규격 (현재 HM 규격)
| 항목 | 값 |
|---|---|
| Outer | 18 × 18px 원, border 1px --hm-sem-stroke-default, face --hm-sem-bg-surface |
| Inner dot | 8px, --hm-sem-state-active (shadcn CircleIcon, fill) |
| Group gap | vertical 12px, horizontal 16px (wrap) |
| Orientation | Radix orientation prop → data-orientation. 기본 vertical(grid), horizontal은 flex |
4. 상태 규격
| 상태 | 값 |
|---|---|
| Unchecked | 위 기본 규격 |
| Checked | border --hm-sem-state-active + inner dot |
| Hover | border --hm-sem-action-primary |
Focus (:focus-visible) |
shadcn ring 유지 |
Error (aria-invalid="true" on item) |
border --hm-sem-action-destructive |
| Disabled | opacity: 0.6, cursor: not-allowed (항목 또는 그룹 disabled) |
5. API
Radix RadioGroup/RadioGroupItem props 그대로 (value/defaultValue/onValueChange, orientation, disabled, name, required, loop, value on item). 추가 prop 없음. 출력 속성: data-slot="radio-group", "radio-group-item", "radio-group-indicator". 그룹 이름은 aria-label 또는 aria-labelledby로 준다.
6. Token
packages/ui/src/theme/radio-group.css (--hm-radio-*): size, border-width, dot-size, background, border-color, hover-border-color, checked-border-color, dot-color, error-border-color, group-gap, group-gap-horizontal. Semantic 참조, Checkbox 등 다른 컴포넌트 Token 미사용. Primitive 신규 추가 없음.
7. shadcn / Radix에서 유지한 항목
Radix 구조·ARIA·roving tabindex·방향키 선택, data-slot, cn(..., className), transition-colors, CircleIcon, focus ring, disabled 커서.
8. HM에서 변경한 항목
shadcn size-4 border-input text-primary shadow-xs dark: class 제거 → theme CSS. Group gap gap-3 고정 대신 Token + horizontal 레이아웃. Disabled opacity 50 → 60.
9. Storybook
대표 Story All: vertical, horizontal, hover, focus, error, disabled-item, disabled-group. Focus는 play로 실제 focus. verification: Vertical, Horizontal, Disabled, Error.
10. 사용자 확정 결정
2026-10-02: ui-viz는 참고 자료이며 최종 기준은 현재 HM 구현과 이 문서(작업 지시). 개별 수치 결정 없음.
11. 미확정 / 보류
- 그룹 Label/Heading, Error·Helper 슬롯의 소유와 우선순위(컴포넌트 없음, 소비 조합).
- 수치(18px, 8px dot, gap 12/16)는 현재 HM 규격이며 디자인 확정 시 재검토.
- Hit area 확장 미적용.
12. 관련 파일
packages/ui/src/components/ui/radio-group.tsx
packages/ui/src/theme/radio-group.css
packages/ui/src/theme.css (import)
packages/ui/src/index.ts (export RadioGroup, RadioGroupItem)
src/components/radio-group.stories.tsx
13. 검증 상태
npm run typecheck,npm run build: 통과(2026-10-02).- computed style: 18×18, 50% radius, border 1px; Checked border
rgb(18,51,40), dot 8px; Uncheckedrgb(154,146,132); Errorrgb(211,47,47); Disabled opacity 0.6; vertical gap 12px, horizontalflexgap 16px. - interaction: 항목 click으로 선택 변경, ArrowUp으로 선택·focus가 이전 항목으로 이동, roving tabindex(선택 항목 0, 나머지 -1) 확인.
- 미확인: 실제 pointer hover·focus ring 시각, 사이드바 화면, 390px 폭.