106 lines
8.4 KiB
Markdown
106 lines
8.4 KiB
Markdown
# Table
|
||
|
||
현재 HM 구현의 기준 문서. 공통 원칙은 `docs/guidelines/프로젝트-지침.md`(§6, §7), Token 구조 원칙은 `테마-토큰-가이드.md`를 따른다. 이 문서는 Table 고유의 API·Token·상태·결정만 기록한다.
|
||
|
||
## 1. 상태
|
||
|
||
| 항목 | 내용 |
|
||
|---|---|
|
||
| 구현 상태 | 구현 완료 (현재 HM 규격) |
|
||
| 기준일 | 2026-10-02 |
|
||
| 기반 | shadcn/ui Table (semantic HTML table, Radix 없음) |
|
||
| 대표 Story | `Components/Data & Display/Table` → `All` (이름 "Table") |
|
||
| 보류 | 아래 §11 |
|
||
|
||
## 2. 적용 근거
|
||
|
||
- **참고 근거**: 외부 ui_viz Reference (ZIP 미포함)의 기존 테스트 규격(`docs/components/table.md`)을 참고했다: 연한 녹색 header 띠, 1px 행 구분선, 셀 padding 14/12, 기본 최소 폭 520px, radius 없음, 행 hover는 면만 변경, header 13/20/700, 셀 14/20/400, 숫자 tabular numerals. 값은 현재 HM Token(Primitive 조합)으로 다시 연결했다.
|
||
- **현재 HM 규격**: 아래 §3~§4. ui-viz에 없던 selected row와 footer는 새로 정했다.
|
||
- **구현 방식**: shadcn Table 구조(container div + table 요소들)를 유지하고 theme CSS로 연결. **정적 표시 primitive**이며 이후 Data Table Pattern(정렬·필터·선택 state·페이지·열 표시)의 기반이다.
|
||
- **보류**: §11.
|
||
|
||
## 3. 기본 규격 (현재 HM 규격)
|
||
|
||
| 항목 | 값 |
|
||
|---|---|
|
||
| Table | min-width 520px(기본값, 덮어쓸 수 있음), 폭 100%, 배경 `--hm-sem-bg-surface`, 글자 `--hm-sem-fg-primary`, radius 없음, `border-collapse: collapse` |
|
||
| Header cell | 13 / 20 / 700, 글자 `--hm-sem-palette-green-light-1`, 배경 흰색에 `--hm-sem-palette-green-tint` 30% 섞은 연한 면, 위 1px `--hm-sem-palette-green-light-2`, 아래 1px 같은 색 20% |
|
||
| Cell | 14 / 20 / 400, padding `14px 12px`, 위 1px `--hm-sem-stroke-input-default` 구분선(첫 body 행은 header 경계가 대신함), `tabular-nums` |
|
||
| Footer | 배경 `--hm-sem-bg-subtle`, weight 500, 위 1px 구분선 |
|
||
| Caption | 12 / 18, `--hm-sem-fg-secondary`, 왼쪽 정렬, 표 아래(caption-bottom), 위 간격 12px |
|
||
| 긴 텍스트 | Cell은 줄바꿈(`overflow-wrap: anywhere`), Header는 `nowrap` |
|
||
| 숫자 열 | 소비자가 `className="text-right"` 지정 |
|
||
|
||
## 4. 상태 규격
|
||
|
||
| 상태 | 값 |
|
||
|---|---|
|
||
| Row Hover | body 행 배경 `--accent` 45%(`color-mix`, 면만 변경, header 제외) |
|
||
| Selected (`data-state="selected"`) | 행 배경 `--accent` 45%. 소비자가 속성을 붙인다 |
|
||
| Selected + Hover | `--accent` 45% 유지(농도 변화 없음) |
|
||
| Focus / Disabled / Loading | Table 자체에는 없음(셀 안 content가 각자 가진다) |
|
||
|
||
## 5. API
|
||
|
||
shadcn 구조 그대로. export: `Table`, `TableHeader`, `TableBody`, `TableFooter`, `TableHead`, `TableRow`, `TableCell`, `TableCaption`.
|
||
|
||
- `Table`: `table` props. `div[data-slot=table-container]`(overflow-x auto)로 감싼다.
|
||
- `TableRow`: `data-state="selected"`를 지원하는 스타일(shadcn 규칙). 선택 state 관리는 소비자.
|
||
- `density`, `variant`, `striped`, `interactive` 같은 prop은 만들지 않았다. 정렬·필터·선택·column visibility·페이지·resize·server loading은 넣지 않았다(Data Table Pattern에서 조합).
|
||
- Checkbox 등 셀 안 요소는 소비 조합이며 Table은 runtime 의존이 없다. `[role=checkbox]` 포함 셀은 오른쪽 padding을 줄이고 checkbox를 2px 내리는 shadcn 규칙만 유지.
|
||
|
||
## 6. Token
|
||
|
||
Component Mapping 위치: `packages/ui/src/theme/table.css` (`--hm-table-*`).
|
||
|
||
`min-width`, `background`, `text`, `font-size|line-height|font-weight`, `cell-padding-y|x`, `divider-width|color`, `header-background|text|font-size|font-weight|border-top|border-bottom`, `row-hover-background`, `row-selected-background`, `footer-background|font-weight`, `caption-*`. Semantic과 Theme palette(`--hm-sem-palette-green-*`, `--hm-sem-stroke-input-default`, `--hm-sem-palette-white`)를 참조하고 다른 컴포넌트 Token을 쓰지 않는다. 신규 Primitive 없음(ui-viz의 `#EDF4F1`은 기존 Primitive의 `color-mix`로 표현). row hover / selected는 shadcn `--accent`의 `color-mix` 45%(Select·Menu·Pagination hover와 같은 Soft Surface 규칙, 공통 `--hm-sem-surface-highlight`를 Component Token이 참조).
|
||
|
||
## 7. shadcn에서 유지한 항목
|
||
|
||
container(`overflow-x-auto`)와 table 구조, `caption-bottom`, Head/Cell의 checkbox 보정 class, `data-slot`, `cn(..., className)`, `data-state="selected"` 규칙.
|
||
|
||
## 8. HM에서 변경한 항목
|
||
|
||
- shadcn의 `text-sm`, `h-10 px-2 font-medium`, `p-2`, `border-b`, `hover:bg-muted/50`, `bg-muted/50`, Caption `mt-4 text-muted-foreground` class를 제거하고 theme CSS로 이전.
|
||
- Cell의 `whitespace-nowrap`을 제거해 긴 텍스트가 줄바꿈되게 했다(Header는 nowrap 유지).
|
||
- Header 띠 스타일과 숫자 `tabular-nums`, 최소 폭 520px은 ui-viz를 참고한 신규 규격.
|
||
|
||
## 9. Storybook
|
||
|
||
- 대표 Story `All`("Table"): Basic(Badge, 숫자 열, footer, caption), Selected row(Checkbox, local state), Long text, Horizontal overflow(1100px 표)를 한 페이지에 둔다.
|
||
- verification: `Basic`, `Selected`, `Long Text`, `Horizontal Overflow`.
|
||
- Checkbox·Badge는 Story 조합이다. Story의 폭 wrapper에는 `minWidth: 0`이 필요하다(grid item의 `min-width:auto`가 Table 최소 폭만큼 부모를 넓힘).
|
||
|
||
## 10. 사용자 확정 결정
|
||
|
||
- 2026-10-02: ui-viz는 참고 자료이며 최종 기준은 현재 HM 구현과 이 문서다(작업 지시). 개별 수치에 대한 별도 결정은 없다.
|
||
- 2026-10-06 (컬러 역할 정리): 행은 넓은 Soft Surface이므로 Hover·Selected·Selected+Hover 모두 `--accent` 45%를 쓴다(이전 `--hm-green-tint` 18% / 40%). Active State Semantic(Light 2)은 쓰지 않는다. 선택 구분은 면 색이 아니라 행 안의 Checkbox(Active Semantic)가 담당한다. `--accent` 값 자체는 바꾸지 않았다. Table row highlight surface는 Select Highlight / Selected와 동일한 Accent 45% 정책을 사용한다.
|
||
|
||
## 11. 미확정 / 보류
|
||
|
||
- 수치(520px, 14/12 padding, header 띠 색)는 현재 HM 규격이며 디자인 확정 시 재검토.
|
||
- zebra, sticky header, 정렬/필터/선택/페이지, column resize, empty/loading 표현: 이후 Data Table Pattern.
|
||
- 모바일: Table을 카드로 자동 변환하지 않는다. container 가로 scroll만 제공하며 모바일용 Data Table 패턴은 Layout/Data Table 단계에서 정한다.
|
||
- header 수치 13px는 ui-viz 참고값이며 공통 typography role과 연결하지 않았다.
|
||
- 말줄임(ellipsis) 셀 규칙 없음.
|
||
|
||
## 12. 관련 파일
|
||
|
||
```
|
||
packages/ui/src/components/ui/table.tsx
|
||
packages/ui/src/theme/table.css
|
||
packages/ui/src/theme.css (import)
|
||
packages/ui/src/index.ts (export)
|
||
src/components/table.stories.tsx
|
||
```
|
||
|
||
## 13. 검증 상태
|
||
|
||
- `npm run typecheck`, `npm run build`: 통과(2026-10-02).
|
||
- 구조/스타일(Browser pane): `th`/`td` 구조, header 13/700 `rgb(32,82,65)`, 위 border `rgb(38,102,81)`, cell 14/20·padding 14/12, 표 폭 100%·최소 520px, caption bottom·왼쪽 정렬.
|
||
- 선택 행: Checkbox Space로 선택하면 해당 행이 `data-state="selected"`가 되고 header Checkbox가 `mixed`, header Checkbox 클릭으로 전체 선택. Tab이 행 Checkbox로 이동.
|
||
- Responsive(390×844): container 폭 358px에 표 520px(1100px 표)이 container 안에서 가로 scroll, 페이지(`scrollWidth` 390) 가로 overflow 없음, 긴 텍스트는 셀 안에서 줄바꿈(89px 행).
|
||
- 2026-10-06 ui_viz Storybook 화면 비교(1280/768/390, Chromium): header·cell padding/typography/색, divider, 텍스트 행 49px, 실제 pointer hover 면 `rgba(189,223,212,.18)` 일치. header/첫 행 경계는 ui_viz가 td 위 선을 두고 HM은 없애지만 border-collapse에서 header 하단선이 이기므로 렌더 픽셀이 같음(197,215,208 / 196,216,209). header 면 ±2 차이는 §6 `color-mix` 근사. 390px에서 ui_viz Story는 페이지가 544px로 넘치고 HM은 container scroll만 생김.
|
||
- 2026-10-06 Accent 45% 전환(실제 pointer hover): Hover·Selected·Selected+Hover 모두 `color(srgb 0.741 0.875 0.831 / 0.45)`(= `#bddfd4` 45%). Data Table 선택 행 동일 + 선택 Checkbox `rgb(38,102,81)` + focus ring 기존 그대로. Dialog Wide Content: header·cell typography·padding·행 높이 49px 유지, hover 동일 값, 좁은 Dialog에서 container만 가로 scroll(1600 / 750).
|
||
- 미확인: 가로 scroll을 사용자가 끝까지 끌었을 때의 clipping, Dropdown Menu·Pagination 조합(Story에 없음).
|