# Skeleton 현재 HM 구현의 기준 문서. 공통 원칙은 `docs/guidelines/프로젝트-지침.md`(§6, §7), Token 구조 원칙은 `테마-토큰-가이드.md`를 따른다. 이 문서는 Skeleton 고유의 API·Token·상태·결정만 기록한다. ## 1. 상태 | 항목 | 내용 | |---|---| | 구현 상태 | 구현 완료 (현재 HM 규격) | | 기준일 | 2026-10-02 | | 기반 | shadcn/ui Skeleton (`div` + `animate-pulse`, Radix 없음) | | 대표 Story | `Components/Data & Display/Skeleton` → `All` (이름 "Skeleton") | | 보류 | 아래 §11 | ## 2. 적용 근거 - **참고 근거**: 외부 ui_viz Reference (ZIP 미포함)의 기존 테스트 규격에는 Skeleton이 컴포넌트 이름으로만 있고 규격은 없다. 참고할 수치가 없었다. - **현재 HM 규격**: 아래 §3. 현재 HM Primitive로 새로 정했다. - **구현 방식**: shadcn Skeleton을 유지. loading 로직이 없는 시각 placeholder primitive이며 크기·모양은 `className`으로 정한다. - **보류**: §11. ## 3. 기본 규격 (현재 HM 규격) | 항목 | 값 | |---|---| | 배경 | `--hm-sem-palette-warm-neutral-light` | | Radius | `--hm-radius-control-md` (4px). 원형은 `className="rounded-full"` | | Animation | shadcn `animate-pulse`(2s). `prefers-reduced-motion: reduce`에서는 animation 없음 | | 크기 | 없음. `className`으로 `h-*`, `w-*`, `size-*` 지정 | ## 4. 상태 규격 상태 없음(placeholder). 배경과 radius는 `@layer components`에 있어 `className`의 utility(`rounded-full`, `bg-*`)가 이긴다. 다른 컴포넌트의 theme CSS(레이어 없음)와 달리 Skeleton은 모양을 소비자가 정하는 것이 역할이기 때문이다. ## 5. API export: `Skeleton`. `div` props 그대로. 출력 `data-slot="skeleton"`. - `width`/`height`/`variant` prop은 만들지 않았다. Text line, Avatar, Card 등은 Story처럼 `className`으로 조합한다. - 접근성: placeholder 자체에는 ARIA를 두지 않는다. loading 영역의 `aria-busy` 등은 소비자 책임. ## 6. Token Component Mapping 위치: `packages/ui/src/theme/skeleton.css` (`--hm-skeleton-*`). `background`, `radius`. Theme palette(`--hm-sem-palette-warm-neutral-light`)와 공통 control radius만 참조한다. 신규 Primitive 없음. ## 7. shadcn에서 유지한 항목 `div` 구조, `animate-pulse`, `data-slot`, `cn(..., className)`. ## 8. HM에서 변경한 항목 - shadcn `bg-muted rounded-md`(또는 `bg-accent`) class를 제거하고 Token으로 연결(배경 `--hm-warm-neutral-light`, radius 4px). - reduced-motion에서 pulse를 끈다(shadcn 기본에는 대응이 없다). 새 Motion token은 만들지 않았다. - 배경·radius 규칙을 `@layer components`에 둔 것은 이 컴포넌트만의 결정이다(§4). ## 9. Storybook - 대표 Story `All`("Skeleton"): Text(3줄), Avatar + text, Card/list loading(Card 안 조합)을 한 페이지에 둔다. 데이터 fetch는 없다. - verification: `Text`, `Card List`. ## 10. 사용자 확정 결정 - 2026-10-02: ui-viz는 참고 자료이며 최종 기준은 현재 HM 구현과 이 문서다(작업 지시). 개별 수치에 대한 별도 결정은 없다. ## 11. 미확정 / 보류 - 배경색과 radius는 현재 HM 규격이며 디자인 확정 시 재검토. - Pulse 속도·형태(shimmer 등)는 Motion 규칙이 정해질 때 다룬다. - Text line 높이 등 사전 정의된 크기 preset은 만들지 않았다. - 전체 loading 영역의 ARIA(`aria-busy`, live region) 가이드는 Data Table Pattern 등 조합 단계에서 정한다. ## 12. 관련 파일 ``` packages/ui/src/components/ui/skeleton.tsx packages/ui/src/theme/skeleton.css packages/ui/src/theme.css (import) packages/ui/src/index.ts (export) src/components/skeleton.stories.tsx ``` ## 13. 검증 상태 - `npm run typecheck`, `npm run build`: 통과(2026-10-02). - 실제 렌더(Browser pane): 배경 `rgb(224,218,206)`, radius 4px, animation `pulse 2s`. `className="size-10 rounded-full"`이 radius override를 받아 원형으로 표시(처음에는 unlayered CSS가 `rounded-full`을 덮는 문제가 있어 `@layer components`로 수정). - Responsive(390×844): Text, Avatar+text, Card 구성이 부모 폭 안에 들어가고 가로 overflow 없음. - 미확인: 실제 `prefers-reduced-motion` 환경에서의 animation 정지(CSS만 작성).