102 lines
5.8 KiB
Markdown
102 lines
5.8 KiB
Markdown
# Progress
|
||
|
||
> 2026-10-10 추가 수정 요청 기준: `asChild` 단일 소비자 요소와 자식을 보존하고 Indicator를 추가한다. 채워진 막대 우측 끝에 기존 Progress radius를 적용하며 색·높이·진행률 API는 유지. 과거 검증 기록은 당시 결과이며 현재 검증은 [추가 수정 보고서](../guidelines/publisher-additional-review-2026-10-10.md)를 따릅니다.
|
||
|
||
현재 HM 구현의 기준 문서. 공통 원칙은 `docs/guidelines/프로젝트-지침.md`(§6, §7), Token 구조 원칙은 `테마-토큰-가이드.md`를 따른다. 이 문서는 Progress 고유의 API·Token·상태·결정만 기록한다.
|
||
|
||
## 1. 상태
|
||
|
||
| 항목 | 내용 |
|
||
|---|---|
|
||
| 구현 상태 | 구현 완료 (현재 HM 규격, 기본 Progress 하나) |
|
||
| 기준일 | 2026-10-02 |
|
||
| 기반 | shadcn/ui Progress (Radix `Progress`) |
|
||
| 대표 Story | `Components/Data & Display/Progress` → `All` (이름 "Progress") |
|
||
| 보류 | 아래 §11 |
|
||
|
||
## 2. 적용 근거
|
||
|
||
- **참고 근거**: 외부 ui_viz Reference (ZIP 미포함)의 기존 테스트 규격에는 Progress가 컴포넌트 이름으로만 있고 규격은 없다. 참고할 수치가 없었다.
|
||
- **현재 HM 규격**: 아래 §3~§4. 현재 HM Semantic/Primitive로 새로 정했다.
|
||
- **구현 방식**: shadcn / Radix Progress 구조(Root + Indicator)를 유지하고 theme CSS로 연결.
|
||
- **보류**: §11.
|
||
|
||
## 3. 기본 규격 (현재 HM 규격)
|
||
|
||
| 항목 | 값 |
|
||
|---|---|
|
||
| Track | 높이 8px, radius 9999px, 배경 `--hm-sem-palette-warm-neutral-light` |
|
||
| Indicator | 배경 `--hm-sem-state-active`(현재 Active와 Progress의 색 정책이 같아 같은 Semantic을 쓴다. 의미가 달라지면 별도 Semantic으로 분리), 폭 = value/max 비율(`translateX`), `transition-all`(shadcn 기본) |
|
||
| 폭 | 부모 폭 100% |
|
||
|
||
## 4. 상태 규격
|
||
|
||
| 상태 | 값 |
|
||
|---|---|
|
||
| Loading / Complete | Radix `data-state="loading"`(0 ≤ value < max), `"complete"`(value = max) |
|
||
| Indeterminate | `value`를 주지 않으면 Radix `data-state="indeterminate"`. 현재는 Indicator가 비어 있다(별도 표현 없음) |
|
||
| Success / Warning / Error | 만들지 않았다(HM 상태색 미확정) |
|
||
|
||
## 5. API
|
||
|
||
Radix Progress props 그대로. export: `Progress`.
|
||
|
||
- `value`, `max`(기본 100), `getValueLabel`, `asChild`. Indicator는 내부에서 렌더하며 별도 export 없음(shadcn 구조).
|
||
- ARIA: `role="progressbar"`, `aria-valuemin`, `aria-valuemax`, `aria-valuenow`(Radix). 접근 가능한 이름은 소비자가 `aria-label`/`aria-labelledby`로 지정.
|
||
- `variant`, `size`, `status` 같은 prop은 만들지 않았다. 높이나 색을 바꾸려면 `--hm-progress-*` Token을 덮는다(unlayered theme 규칙이라 `className`의 높이 utility는 이기지 못한다).
|
||
|
||
## 6. Token
|
||
|
||
Component Mapping 위치: `packages/ui/src/theme/progress.css` (`--hm-progress-*`).
|
||
|
||
`height`, `radius`, `track-background`, `indicator-background`. Semantic과 Theme palette(`--hm-sem-palette-warm-neutral-light`)만 참조한다. 신규 Primitive 없음.
|
||
|
||
## 7. shadcn / Radix에서 유지한 항목
|
||
|
||
Radix 구조·ARIA·`data-state`, Indicator의 `translateX` 표현(폭 계산은 HM에서 value/max 비율로 보정), `transition-all`, `overflow-hidden`, `data-slot`, `cn(..., className)`.
|
||
|
||
## 8. HM에서 변경한 항목
|
||
|
||
- shadcn `h-1 rounded-full bg-muted`, Indicator `bg-primary` class를 제거하고 theme CSS로 이전. 높이를 4px에서 8px로 키웠다.
|
||
- 트랙색을 `muted`가 아닌 `--hm-sem-palette-warm-neutral-light`로 정했다(`muted`는 베이지 배경에서 거의 안 보임).
|
||
|
||
## 9. Storybook
|
||
|
||
- 대표 Story `All`("Progress"): 0%, 50%, 100%, max=200, Interactive value(`-25`/`+25` 버튼, local state)를 한 페이지에 둔다.
|
||
- verification: `Zero`, `Middle`, `Full`, `NonDefaultMax`(max=200의 0/50/200/indeterminate). 대표 Story에도 동일 specimen을 둔다.
|
||
|
||
## 10. 사용자 확정 결정
|
||
|
||
- 2026-10-02: ui-viz는 참고 자료이며 최종 기준은 현재 HM 구현과 이 문서다(작업 지시). 개별 수치에 대한 별도 결정은 없다.
|
||
|
||
## 11. 미확정 / 보류
|
||
|
||
- 수치(8px, 트랙색)는 현재 HM 규격이며 디자인 확정 시 재검토.
|
||
- 상태 variant(success/warning/error)는 HM 상태색 확정 후.
|
||
- Indeterminate 표현(움직이는 막대)은 없다. Motion 규칙이 정해지면 검토.
|
||
- 값 label/퍼센트 텍스트는 소비 조합(컴포넌트에 없음).
|
||
- `prefers-reduced-motion` 대응은 추가하지 않았다(`transition-all`은 shadcn 기본).
|
||
|
||
## 12. 관련 파일
|
||
|
||
```
|
||
packages/ui/src/components/ui/progress.tsx
|
||
packages/ui/src/theme/progress.css
|
||
packages/ui/src/theme.css (import)
|
||
packages/ui/src/index.ts (export)
|
||
src/components/progress.stories.tsx
|
||
```
|
||
|
||
## 13. 검증 상태
|
||
|
||
- `npm run typecheck`, `npm run build`: 통과(2026-10-02).
|
||
- 실제 DOM(Browser pane): `role="progressbar"`, `aria-valuemin=0`, `aria-valuemax=100`, `aria-valuenow`가 0/50/100/30(interactive), `data-state` loading/complete, indicator 채움이 0/50/100%.
|
||
- value 변경: `+25` 클릭으로 `aria-valuenow`가 30 → 55, 이어서 100으로 클램프되고 indicator transform이 `translateX(0%)`, 렌더 후 채움 100%. 0과 max 경계 확인.
|
||
- computed style: 높이 8px, radius 9999px, 트랙 `rgb(224,218,206)`, indicator `rgb(18,51,40)`.
|
||
- Responsive(390×844): 트랙이 부모 폭 358px을 따르고 가로 overflow 없음.
|
||
- 미확인: indeterminate 표시, `max`를 100이 아닌 값으로 쓴 경우(Indicator 계산이 value를 %로 간주하므로 `max≠100`이면 소비자가 환산해야 함).
|
||
|
||
### 2026-10-06 정합성 감사 수정
|
||
|
||
위 2026-10-02 검증 이력의 max≠100 제한은 해소했다. Indicator는 Radix와 같은 유효 범위/기본 max를 사용하여 value/max 비율로 채운다. max=200, value=50은 ARIA 50/200과 25% 채움이 일치하며 값 없음은 기존 indeterminate 빈 Track을 유지한다.
|