103 lines
4.7 KiB
Markdown
103 lines
4.7 KiB
Markdown
# Hover Card
|
||
|
||
현재 HM 구현의 기준 문서. 공통 원칙은 `docs/guidelines/프로젝트-지침.md`(§6, §7), Token 구조 원칙은 `테마-토큰-가이드.md`를 따른다. 이 문서는 Hover Card 고유의 API·Token·상태·결정만 기록한다.
|
||
|
||
## 1. 상태
|
||
|
||
| 항목 | 내용 |
|
||
|---|---|
|
||
| 구현 상태 | 구현 완료 (현재 HM 규격) |
|
||
| 기준일 | 2026-10-02 |
|
||
| 기반 | shadcn/ui Hover Card (Radix `HoverCard`) |
|
||
| 대표 Story | `Components/Overlay/Hover Card` → `All` (이름 "Hover Card") |
|
||
| 보류 | 아래 §11 |
|
||
|
||
## 2. 적용 근거
|
||
|
||
- **참고 근거**: 외부 ui_viz Reference (ZIP 미포함)의 기존 테스트 규격에는 Hover Card 규격이 없다. 참고할 수치가 없었다.
|
||
- **현재 HM 규격**: 아래 §3~§4. Popover와 같은 floating surface이며 현재 HM Semantic 체계로 새로 정했다.
|
||
- **구현 방식**: shadcn / Radix Hover Card 구조를 유지하고 theme CSS로 HM 스타일을 연결.
|
||
- **역할 구분**: Tooltip = 짧고 즉각적인 설명, Hover Card = 제목·설명·metadata를 가진 정보 미리보기(non-interactive 중심), Popover = click으로 여는 panel/form.
|
||
- **보류**: §11.
|
||
|
||
## 3. 기본 규격 (현재 HM 규격)
|
||
|
||
| 항목 | 값 |
|
||
|---|---|
|
||
| Surface | `--hm-sem-bg-surface` |
|
||
| 전경 | `--hm-sem-fg-primary` |
|
||
| Border | 1px `--hm-sem-floating-border-color` |
|
||
| Radius | `--hm-radius-container` (4px) |
|
||
| Shadow | `0 0 12px rgb(0 0 0 / .2)` |
|
||
| Padding | 16px |
|
||
| Width | 320px (viewport − 16px 이하로 제한), 긴 문자열은 줄바꿈 |
|
||
| Typography | 14 / 20 / 400 |
|
||
| Position | `sideOffset` 4, `align` center |
|
||
| Delay | Radix 기본 유지(open 700ms, close 300ms) |
|
||
|
||
## 4. 상태 규격
|
||
|
||
| 상태 | 값 |
|
||
|---|---|
|
||
| Open / Closed | Radix `data-state`, shadcn open/close animation |
|
||
| 열림 조건 | trigger hover 또는 keyboard focus |
|
||
| 유지 | trigger → content로 pointer 이동 시 유지(Radix hover bridge) |
|
||
| 닫힘 조건 | pointer가 trigger와 content를 떠난 뒤 close delay, blur, Escape |
|
||
|
||
## 5. API
|
||
|
||
Radix Hover Card props 그대로. export: `HoverCard`, `HoverCardTrigger`, `HoverCardContent`.
|
||
|
||
- `HoverCardContent`: `align` 기본 `center`, `sideOffset` 기본 4. `HoverCard`에 `openDelay`, `closeDelay`.
|
||
- 출력 속성: `data-slot="hover-card-*"`, Radix `data-state`·`data-side`·`data-align`.
|
||
- 접근성 주의: Hover Card는 sighted pointer user용 보조 정보이며 keyboard focus로도 열리지만 content 안으로 focus를 옮기지 않는다. 필수 정보나 interactive 요소는 넣지 않는다.
|
||
|
||
## 6. Token
|
||
|
||
Component Mapping 위치: `packages/ui/src/theme/hover-card.css` (`--hm-hover-card-*`).
|
||
|
||
`background`, `text`, `border-width`, `border-color`, `radius`, `shadow`, `padding`, `width`, `font-size`, `line-height`, `font-weight`. 다른 컴포넌트의 Component Token을 참조하지 않는다. 신규 Primitive 없음.
|
||
|
||
## 7. shadcn / Radix에서 유지한 항목
|
||
|
||
Radix 구조·delay·hover bridge·Escape·focus 열림, Portal·positioning·collision, `data-slot`, `cn(..., className)`, animation class, `z-50`.
|
||
|
||
## 8. HM에서 변경한 항목
|
||
|
||
- shadcn `w-64 rounded-md border p-2.5 shadow-md bg-popover` 등 시각 class 제거 → theme CSS.
|
||
- 폭 256 → 320px, padding 10 → 16px(Popover와 구분되는 미리보기 폭).
|
||
|
||
## 9. Storybook
|
||
|
||
- 대표 Story `All`("Hover Card"): 기본 preview(제목 / 설명 / metadata), 긴 콘텐츠 edge case.
|
||
- verification: `Open`(열린 상태).
|
||
|
||
## 10. 사용자 확정 결정
|
||
|
||
- 2026-10-02: ui-viz는 참고 자료이며 최종 기준은 현재 HM 구현과 이 문서다(작업 지시). 개별 수치에 대한 별도 결정은 없다.
|
||
|
||
## 11. 미확정 / 보류
|
||
|
||
- 수치(320px, 16px padding, 그림자)는 현재 HM 규격이며 디자인 확정 시 재검토.
|
||
- delay는 Radix 기본. HM delay 규칙은 없다.
|
||
- arrow 없음(shadcn 기본에 없음).
|
||
- Motion 규칙은 정의되지 않아 shadcn 기본 animation 유지.
|
||
- 제목·metadata 타이포 role은 소비 조합(Story는 shadcn Token 유틸 사용). 전용 slot 컴포넌트 없음.
|
||
|
||
## 12. 관련 파일
|
||
|
||
```
|
||
packages/ui/src/components/ui/hover-card.tsx
|
||
packages/ui/src/theme/hover-card.css
|
||
packages/ui/src/theme.css (import)
|
||
packages/ui/src/index.ts (export)
|
||
src/components/hover-card.stories.tsx
|
||
```
|
||
|
||
## 13. 검증 상태
|
||
|
||
- `npm run typecheck`, `npm run build`: 통과(2026-10-02).
|
||
- 실제 interaction(Browser pane): hover로 열림, trigger → content 이동 시 유지, 영역 이탈 후 닫힘, keyboard focus로 열림, Escape 닫힘.
|
||
- computed style: width 320px, white, border `rgb(222,219,210)` 1px, padding 16px, shadow `0 0 12px .2`.
|
||
- 미확인: open/close delay 시간의 정확한 측정, 긴 콘텐츠 시각, 좁은 viewport collision.
|