# 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을 유지한다.