# 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-01` TBD, 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로 연결. shadcn `CircleIcon`을 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; Unchecked `rgb(154,146,132)`; Error `rgb(211,47,47)`; Disabled opacity 0.6; vertical gap 12px, horizontal `flex` gap 16px. - interaction: 항목 click으로 선택 변경, ArrowUp으로 선택·focus가 이전 항목으로 이동, roving tabindex(선택 항목 0, 나머지 -1) 확인. - 미확인: 실제 pointer hover·focus ring 시각, 사이드바 화면, 390px 폭.