99 lines
5.2 KiB
Markdown
99 lines
5.2 KiB
Markdown
# Scroll Area
|
||
|
||
현재 HM 구현의 기준 문서. 공통 원칙은 `docs/guidelines/프로젝트-지침.md`(§6, §7), Token 구조 원칙은 `테마-토큰-가이드.md`를 따른다. 이 문서는 Scroll Area 고유의 API·Token·상태·결정만 기록한다.
|
||
|
||
## 1. 상태
|
||
|
||
| 항목 | 내용 |
|
||
|---|---|
|
||
| 구현 상태 | 구현 완료 (현재 HM 규격) |
|
||
| 기준일 | 2026-10-02 |
|
||
| 기반 | shadcn/ui Scroll Area (Radix `ScrollArea`) |
|
||
| 대표 Story | `Components/Data & Display/Scroll Area` → `All` (이름 "Scroll Area") |
|
||
| 보류 | 아래 §11 |
|
||
|
||
## 2. 적용 근거
|
||
|
||
- **참고 근거**: 외부 ui_viz Reference (ZIP 미포함)의 기존 테스트 규격에는 Scroll Area가 없다. 참고할 수치가 없었다.
|
||
- **현재 HM 규격**: 아래 §3. 현재 HM Primitive로 새로 정했다.
|
||
- **구현 방식**: shadcn / Radix ScrollArea 구조를 유지. scroll 동작(wheel, touch, native keyboard, viewport 측정, thumb drag)은 Radix가 소유하고 scrollbar 모양만 정한다.
|
||
- **보류**: §11.
|
||
|
||
## 3. 기본 규격 (현재 HM 규격)
|
||
|
||
| 항목 | 값 |
|
||
|---|---|
|
||
| Scrollbar | 두께 10px(`p-px`, 투명 border로 가장자리 여백), 트랙은 투명 |
|
||
| Thumb | `--hm-sem-stroke-default`, hover/drag 중 `--hm-sem-fg-secondary`, radius 9999px |
|
||
| 노출 | Radix 기본 `type="hover"`: 마우스가 올라가 있거나 scroll 중에만 scrollbar가 나타난다 |
|
||
| Orientation | 세로는 기본, 가로는 `<ScrollBar orientation="horizontal" />`를 추가 |
|
||
| Corner | Radix Corner |
|
||
| 크기 | 없음. Root에 `className`/`style`로 높이·폭 지정(Story의 크기는 Story 배치) |
|
||
|
||
## 4. 상태 규격
|
||
|
||
| 상태 | 값 |
|
||
|---|---|
|
||
| Scrollbar visible / hidden | Radix `data-state="visible" | "hidden"` |
|
||
| Thumb hover / active | 색이 한 단계 어두워짐 |
|
||
| Viewport focus | shadcn ring(`focus-visible:ring-[3px] ring-ring/50`) 유지 |
|
||
|
||
## 5. API
|
||
|
||
Radix ScrollArea props 그대로. export: `ScrollArea`, `ScrollBar`.
|
||
|
||
- `ScrollArea`: `type`(`hover` 기본 | `auto` | `always` | `scroll`), `scrollHideDelay`, `dir`. Viewport, 세로 ScrollBar, Corner를 내장한다.
|
||
- `ScrollBar`: `orientation` `"vertical"`(기본) | `"horizontal"`. 가로 scroll이 필요하면 소비자가 직접 추가한다(shadcn 구조).
|
||
- 출력 `data-slot="scroll-area|scroll-area-viewport|scroll-area-scrollbar|scroll-area-thumb"`, `data-orientation`.
|
||
- 새 prop은 만들지 않았다.
|
||
|
||
## 6. Token
|
||
|
||
Component Mapping 위치: `packages/ui/src/theme/scroll-area.css` (`--hm-scroll-area-*`).
|
||
|
||
`scrollbar-size`, `thumb-background`, `thumb-hover-background`, `thumb-radius`. Semantic(`--hm-sem-stroke-default`, `--hm-sem-fg-secondary`)을 참조한다. 신규 Primitive 없음.
|
||
|
||
## 7. shadcn / Radix에서 유지한 항목
|
||
|
||
Radix 구조·scroll 동작·scrollbar `type`, viewport의 focus ring, `touch-none select-none` scrollbar, `data-slot`, `cn(..., className)`.
|
||
|
||
## 8. HM에서 변경한 항목
|
||
|
||
- shadcn `bg-border` thumb과 scrollbar 두께 class(`w-2.5`/`h-2.5`)를 Token으로 이전, thumb 색을 베이지 배경에서 보이는 warm neutral로 지정.
|
||
- 노출 방식은 변경하지 않았다(Radix 기본 hover).
|
||
|
||
## 9. Storybook
|
||
|
||
- 대표 Story `All`("Scroll Area"): Vertical, Horizontal, Both axes, Table-like content를 한 페이지에 둔다.
|
||
- verification: `Vertical`, `Horizontal`.
|
||
- 영역 크기는 Story 배치(`style`)이며 Scroll Area의 크기 API가 아니다.
|
||
|
||
## 10. 사용자 확정 결정
|
||
|
||
- 2026-10-02: ui-viz는 참고 자료이며 최종 기준은 현재 HM 구현과 이 문서다(작업 지시). 개별 수치에 대한 별도 결정은 없다.
|
||
|
||
## 11. 미확정 / 보류
|
||
|
||
- 두께 10px, thumb 색, 항상 노출 vs hover 노출은 현재 HM 규격이며 디자인 확정 시 재검토(지금은 Radix 기본 hover).
|
||
- 터치 기기에서는 Radix가 native scroll을 쓰지만 scrollbar 노출은 `type`에 따른다.
|
||
- native 키보드 scroll: Viewport는 `tabindex=-1`이라 Tab 순서에 들어가지 않는다(shadcn 구조 그대로). 키보드 사용자를 위한 focus 가능 scroll 영역 정책(예: `tabIndex={0}`)은 사용처가 정해질 때 결정한다.
|
||
- 가로 scroll이 필요한 경우 `ScrollBar orientation="horizontal"` 추가를 잊기 쉽다(shadcn 구조).
|
||
|
||
## 12. 관련 파일
|
||
|
||
```
|
||
packages/ui/src/components/ui/scroll-area.tsx
|
||
packages/ui/src/theme/scroll-area.css
|
||
packages/ui/src/theme.css (import)
|
||
packages/ui/src/index.ts (export)
|
||
src/components/scroll-area.stories.tsx
|
||
```
|
||
|
||
## 13. 검증 상태
|
||
|
||
- `npm run typecheck`, `npm run build`: 통과(2026-10-02).
|
||
- 실제 interaction(Browser pane): 마우스 wheel로 세로 scroll(`scrollTop` 0 → 300), thumb 위에서 아래로 drag해 `scrollTop` 300 → 456, 가로 wheel로 `scrollLeft` 0 → 300, 마우스를 올리면 scrollbar가 `data-state="visible"`로 나타나고 thumb 7×39, 색 `rgb(154,146,132)`, scrollbar 폭 10px.
|
||
- 구조: 4개 Specimen에서 세로/가로/양방향 overflow가 각각 의도대로(세로만, 가로만, 둘 다) 생김. Viewport는 `focus()` 가능.
|
||
- Responsive(390×844): 영역이 고정 크기(280×200 등)로 유지되고 페이지 가로 overflow 없음.
|
||
- 미확인: 화살표 키 native scroll(도구의 합성 키 입력으로 확인되지 않음), 터치 scroll, 가로 scrollbar thumb drag, corner 시각.
|