feat(sw): add SW Footer component and Storybook stories

This commit is contained in:
shkim4 committed 2026-10-20 09:41:12 +09:00
1 parent 77a809baa3
commit 6cf885412e
105 files changed
+3288 -3

No files matched your search

@@ -0,0 +1,82 @@
# SW Footer — Figma 35개 노드 매핑·구현 기록 (2026-10-20)
- Figma: 이지빔-SW `rj6wpsfk24lOWvWiVRAANP`. 35개 노드 모두 Figma MCP(`get_metadata`, `get_design_context`, `get_screenshot`)로 읽었고, 글자 stroke·변형 레이어·opacity는 Plugin API(`use_figma` 읽기 전용)로 확인했습니다. Figma 파일은 수정하지 않았습니다.
- 추가 기준(사용자 제공, 2026-10-20): 실제 SW 화면 `src/sw/assets/footer-reference/composition-2026-10-20.png`(1915 × 1030), 좁은 화면 `narrow-2026-10-20.png`(952 × 183). 바 안 명령창·좌표·보조기능 켜짐·좁은 폭 동작은 이 화면을 따르고, Figma와 다르면 Figma가 우선입니다.
- 구현: `packages/sw/src/components/sw-footer/`, `packages/sw/src/theme/sw-footer.css`, 자산 `packages/sw/src/components/sw-footer/assets/`(Figma SVG 48개).
- Storybook: `SW/Footer` — Figma 렌더 비교 이미지는 `src/sw/assets/figma-reference/footer/<node>.png`(35개).
## 1. 노드 → 구현 → Story
35개 노드는 34개 Component Set/부품과 1개 전체 화면입니다. 같은 UI의 상태 변화는 별도 컴포넌트가 아니라 Props·CSS 상태로 구현했습니다.
| # | Node | 이름 | 분류 | 구현 (컴포넌트 · Props) | Figma 상태 → 구현 | Story |
|---|---|---|---|---|---|---|
| 1 | 26:9776 | btn_add_layout | Layout 탭 | `SWFooterLayoutTabs onAdd` | Default / Variant2(Hover) → CSS hover | Figma Variant · Layout 탭 |
| 2 | 26:9785 | btn_delete | Layout 탭 | 둥근 탭 ×(`onRemove`) | Default / Variant2(Hover, 노랑 ×) | 〃 |
| 3 | 26:9931 | btn_close2 | Layout 탭 | 사선 탭 ×(`onRemove`) | Default / Variant2(Hover) | 〃 |
| 4 | 26:9794 | layout01 | Layout 탭 | 마지막 탭 `shape="slant"` | default · hover · on · on hover · Variant5(이름 편집) · Variant6(편집 + hover) → `value`, `editingId`, hover | 〃 |
| 5 | 26:9837 | layout02 | Layout 탭 | `shape="rounded"` | 같은 6상태 | 〃 |
| 6 | 26:9885 | layout03 | Layout 탭 | `shape="rounded"` | default · hover · on · on hover | 〃 |
| 7 | 26:9914 | model | Layout 탭 | `modelLabel`, `value === SW_FOOTER_MODEL` | Default · hover · on | 〃 |
| 8 | 26:9942 | 예시) 탭 상태변화 | Layout 탭 | `SWFooterLayoutTabs layouts value onAdd` | Model / Layout 01 / 02 / 03 선택 | 〃, 전체 Footer |
| 9–18 | 26:9459, 26:9466, 26:9473, 26:9480, 26:9487, 26:9494, 26:9501, 26:9508, 26:9515, 26:9522 | text_도형 … text_구조배근 | 분류 탭 | `SWFooterMenu` 항목(`SWFooter categories`) | Default(#D4CBBD) · Variant2(Hover) · Variant3(현재, Pocket) | Figma Variant · 분류 탭 |
| 19–27 | 26:9529, 26:9551, 26:9576, 26:9601, 26:9629, 26:9651, 26:9673, 26:9689, 26:9702 | line · Pline · Arc · circle · ellipse · rect · poly · point · hatch | 명령 | `SWFooterToolButton`(`SWFooterTool` + `swFooterToolIcons.*`) | Default · Variant2(Hover) · Variant3(선택) → hover, `activeToolId`/`pressed` | Figma Variant · 명령 |
| 28 | 26:9739 | Ncopy | 명령 | 〃 (`swFooterToolIcons.ncopy`, Story 수정 분류) | 같은 3상태 | 〃 |
| 29 | 26:9971 | btn_add_menu | 빈 칸 | `SWFooterAddSlot` / `SWFooter onSlotAdd` | Default · hover(주황 점선 링) | Figma Variant · 빈 칸 |
| 30 | 26:9242 | 가이드 영상 보기 | 빈 칸 가이드 | `SWFooterAddSlot guide` / `SWFooter slotGuide` | Default · Variant2(가이드 표시) → hover·focus·`guideOpen` | 〃, 전체 Footer |
| 31 | 26:9096 | guide_바로가기 등록 | 빈 칸 가이드 | `SWFooterGuide media` | Variant5·6·4·9·8·9 = 가이드 영상 프레임 → `media`(프로그램 제공), Story는 6프레임 순환 | 〃 |
| 32 | 26:10023 | ico_arrow | 명령창·▲ | `SWFooterCommandLine` 펼치기, `SWFooter` ▲ 칸 | Default ↑ · hover · on ↓ · Variant4(on hover) → `expanded` / ▲ 패널 열림 | Figma Variant · 명령창, 화면 폭 |
| 33 | 26:10048 | command (접힘) | 명령창 | `SWFooterCommandLine` | 71px, 마지막 3줄 | Figma Variant · 명령창 |
| 34 | 26:10056 | command (펼침) | 명령창 | `SWFooterCommandLine expanded` | 270px | 〃 |
| 35 | 26:10097 | 레이아웃 분리 | 전체 | `SWFooter`(+ `SWFooterLayoutTabs`) | 하단 72px 전체 | 기본 Footer, Figma Variant · Footer 전체 |
26:10097 안의 보조기능 버튼(btn_객체스냅 …, 26:10104)·측면 버튼(26:10189 / 26:10192)·구분선·bg_vacant·menu_bg도 같은 노드에서 읽어 `SWFooterAuxGroup`·`SWFooterSideButton`·`SWFooterMenu` 면으로 구현했습니다.
## 2. Storybook `SW/Footer`
| Story | 내용 |
|---|---|
| 기본 Footer | Figma 데이터만 넣은 `<SWFooter />` 1920 + Figma 26:10097 하단 렌더 |
| 전체 Footer · 실제 조합 | 실제 화면 구성(SWHeader + 도면 + 좌표 + 바 안 명령창 + 명령 10개 + 분류 12개 + Layout 탭), 모든 Callback 동작, 실제 화면 이미지 |
| 도구 그룹별 표시 | 도형(9) · 수정(NCopy) · 빈 분류, 보조기능·측면 버튼 없는 구성 |
| Figma 디자인별 Variant (35 노드) | 노드마다 Figma 렌더 ↔ 구현 상태 |
| Hover / Active / Selected / Disabled | 명령·빈 칸·분류·보조기능·측면 버튼 상태 |
| 도구 및 메뉴 변경 예제 | 사용자 분류·lucide 아이콘·slotCount 10·빈 칸으로 명령 추가·분류 추가·문구 변경·trailing·잠긴 Layout |
| 화면 폭 변화 | 실제 조합 1920 / 1440 / 1280 / 950, 좁은 실제 화면 이미지, Figma 구성 1920 / 1280 / 1024 / 820 |
| 개별 부품 (조합용) | `SWFooterAuxGroup`(3·2열), `SWFooterMenu` + `SWFooterToolButton`, `SWFooterCommandLine` |
## 3. Figma·실제 화면과 구현의 차이
| 항목 | Figma / 실제 화면 | 구현 | 이유 |
|---|---|---|---|
| 글꼴 | Dotum | Noto Sans KR(SW 공통) | SW Header와 같은 확정 대체. 글자 폭·굵기 차이로 분류 탭 위치가 끝에서 최대 12px 차이 |
| 글자 stroke | 검정 1.3 / 1px + 자기 색 0.3 / 0.4px | 검정 외곽선만(Header 토큰) | Header 2026-10-16 수정과 동일 |
| 분류 탭 자간 | 앞 4개 4%, 나머지 10% | 모두 10% | 데이터 기반 탭 하나의 규칙. 10%일 때 Figma 상자 폭(45/61/43/84)에 가장 가까움 |
| Layout 01 vs 02 Hover | layout01 Hover = 주황 면 + 검정 글자, layout02 Hover = 어두운 베이지 + 주황 글자 | 모양별로 Figma 그대로 | Figma 두 컴포넌트가 다르게 그려짐 → 검토 필요 |
| Model 선택 | Figma On = 갈색 / 실제 화면 = 주황 | Figma(갈색) | Figma 우선 |
| Layout 01 단독 | 26:10097에는 Model 없이 Layout 01만 | `modelLabel={false}` 지원, 마지막 탭은 항상 사선 | 두 구성 모두 표현 |
| Variant5 / 6 의미 | 이름 없음(검정 면 + 빨강 글자) | 이름 편집 상태로 해석(Header 입력 편집 `#0F0D0A`·`#E60403`과 같은 값) | 해석 — 검토 필요 |
| 보조기능 켜짐 | Figma 없음 / 실제 화면 주황 테두리·글자 | 실제 화면 적용(아이콘은 자산 색 유지) | 주황 아이콘 자산 없음 |
| Hover(보조기능·측면 버튼), Disabled | Figma 없음 | 글자 `#FF5C00`, 40% | AI 구성 값 — 디자인 확인 필요 |
| 좁은 폭 | Figma 없음 / 실제 화면 | 빈 칸 축소 → ▲ 패널, 분류 ◀ ▶, 보조기능 아이콘만(1279px 이하), 명령창 최소 280 | 전환 폭·최소 폭은 AI 구성 값 |
| 명령창 줄 수 | Figma 3줄(줄 14px) / 실제 화면 접힘 5줄 | Figma 3줄 | Figma 우선 |
| 가이드 영상 | Figma는 6프레임 스토리보드(래스터) | `media`로 프로그램이 제공, Story만 프레임 순환 | 영상 자산은 프로그램 소유 |
| WIPEOUT · 객체스냅추적 아이콘 | 실제 화면에만 있음 | Story에서 lucide 아이콘(프로그램 제공 방식) | Figma 자산 없음 |
## 4. 검증 (2026-10-20, 이 작업에서 실행한 것만)
| 항목 | 결과 |
|---|---|
| 35개 노드 읽기·매핑 | PASS (§1) |
| `npx tsc -p packages/sw/tsconfig.json --noEmit` | PASS |
| `npm run build:sw` (dist·d.ts, CSS 자산 data URI 인라인) | PASS |
| 루트 `npx tsc -b` (Storybook·Story 코드, `@hm-design/sw` 패키지 Import) | PASS |
| `npm run check:ai-docs` | PASS |
| Storybook 렌더링(8개 Story, 실행 중인 6024) | PASS — Story별 Footer 수·콘솔 오류 확인 |
| Figma ↔ 구현 1:1 비교(기본 Footer, 35 노드 Story) | PASS — 위치 측정: 보조기능 (76, 2), 명령 칸 396·y 1, 명령어 전체보기 1552, 분류 탭 Figma 대비 ≤ 12px |
| 동작(실제 조합 Story) | PASS — 명령 선택, 분류 ←/→, 빈 칸 가이드 위치(가운데·4px 위)·클릭, 보조기능 토글, Layout 선택·F2 이름 변경·Delete·추가, 명령창 Enter·펼치기, ▲ 패널 열기·선택 후 닫힘·Escape 복귀 |
| 화면 폭 | PASS — 실제 조합 1920 → 12칸, 1440 → 10칸, 1280 → 명령 6 + ▲, 950 → 명령 4 + ▲·보조기능 아이콘만·분류 ◀ ▶ |
| Header·Popup 영향 | 수정 없음(기존 파일 변경 없음, Footer CSS는 `hm-sw-footer*`와 새 토큰만) |
| 독립 소비 프로젝트(Tarball) 설치·빌드 | 미검증 |
| `npm run build-storybook` (정적 빌드) | 미검증 |
| Firefox·Safari | 미검증 (Chromium Storybook만) |