88 lines
4.4 KiB
Markdown
88 lines
4.4 KiB
Markdown
# 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 폭.
|