Files
HMDesign/docs/sw/sw-storybook-property-panel-comparison-2026-10-19.md
T
shkim4andClaude Opus 5.5 c8e5fbeebc refactor(storybook): consolidate property panel comparison layout
Keep sw-header--property-panel-compare as the single property panel state
page: the four existing SWHeaderPropertyPanel states in 2 columns x 2 rows
at their original size, inside a scrolling Inner. Remove the duplicate
Property Panel Variants and the four single-state Stories (SW 24 -> 19).
Storybook-only change; SW runtime and public API untouched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 12:52:29 +09:00

119 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SW Storybook — 속성창 4개 상태 비교 통합 (2026-10-19)
- 브랜치: `feature/sw-package` · 시작 HEAD `c705a1fc59fe8ecbce663bf4601638fde43553a1` · 시작 시 Working Tree Clean
- 범위: Storybook 전용 코드(`src/sw/sw-header.stories.tsx`, `src/sw/sw-stories.css`)와 검증 스크립트. SW 패키지 런타임·공개 API·AI 템플릿·Overview·Dropdown Story는 변경하지 않음.
- 증거: `docs/sw/property-panel-comparison-qa/` (기존 QA 폴더는 덮어쓰지 않음)
## 1. 수정 전 속성창 관련 Story 목록 (실제 선언 기준)
| Story ID | 이름 | 실제 기능·목적 | 분류 |
| --- | --- | --- | --- |
| `sw-header--property-panel-compare` | Property Panel · 4개 비교 | 같은 `SWHeaderPropertyPanel` 4개 상태를 한 화면에 실측 크기와 함께 표시 | **유지** |
| `sw-header--property-panel-variants` | Property Panel Variants | `PropertyPanelDemo standalone`: 상태 전환 버튼으로 **한 번에 1개** 단독 패널. 데이터 조작 버튼은 `Property Panel`과 동일 | **삭제** (중복) |
| `sw-header--property-panel-none` | Property Panel · 선택 없음 | 314×256 단독 패널 1개 | **삭제** (비교 화면과 중복) |
| `sw-header--property-panel-all` | Property Panel · 전체 선택 | 314×361 단독 패널 1개 | **삭제** (중복) |
| `sw-header--property-panel-circle` | Property Panel · 원 1개 | 314×658 단독 패널 1개 | **삭제** (중복) |
| `sw-header--property-panel-expanded` | Property Panel · 모두 펼침 | 314×754 단독 패널 1개 | **삭제** (중복) |
| `sw-header--property-panel` | Property Panel | Header 연결 열기/닫기, Controlled/Uncontrolled, 외부 Open, 폭 전환, 속성 추가·삭제·순서·제한 상태 | **보존** (Header 연동·API 검증) |
| `sw-header--property-shape-slot` | Property Panel · 형상 Slot | `shapeContent` 확장 계약(기본/null/ReactNode/Render Prop) | **보존** (API 검증) |
| `sw-header--property-fields` | Property Panel · 필드 13개 | 필드 Default/Hover 표본 + 실제 조작 | **보존** (필드 검증) |
| `sw-header--property-bar` | Property Bar | 속성Bar 독립 기능 | **보존** |
| `sw-header--layer-detail-input` | Layer Detail · Input | Input 독립 검증 | **보존** |
| `sw-header--interactive-states` | Interactive States | Header 공통 Hover/Selected(속성창 토글 포함) | **보존** |
| `sw-header--detail-buttons` | Detail Buttons (Shared States) | 공통 상세 버튼 상태 | **보존** |
삭제한 5개는 모두 비교 화면과 같은 `PropertyState`/`SWHeaderPropertyPanel` + 같은 fixture를 렌더링했고, 고유 기능 검증은 없었습니다(Variants의 데이터 조작 버튼은 `Property Panel`에 동일하게 남아 있음).
## 2. 유지한 4개 상태 비교 Story
- ID `sw-header--property-panel-compare`, 이름 `Property Panel · 4개 비교`, 페이지 제목 `속성창 4개 상태 비교` — 모두 유지.
- 상태명·순서 유지(코드 `PROPERTY_STATES`): ① 선택된 객체 없음 ② 전체 객체 선택 ③ 원 1개 선택 ④ 모든 항목 펼침. 각 카드 상단 캡션(상태명 · Figma 노드 · 크기 · 측정값)은 패널 밖 `figcaption`이라 제품 디자인에 영향 없음.
- 변경: 줄바꿈 flex → 2열 × 2행 grid(간격 24px, 패널 원래 크기). 페이지를 뷰포트 높이로 고정하고 Inner 스크롤 영역(`[data-compare-scroll]`)만 가로·세로 스크롤. 설명 문구에서 "폭이 부족하면 줄바꿈합니다" 등 불필요한 문장 제거. 삭제된 개별 Story가 보여주던 Callback 기록을 대신해 한 줄 로그(`상태: callback`)를 추가.
- Storybook 전용 배치 예외 1건: 제품 CSS의 `.hm-sw-property { max-height: calc(100dvh - 8px) }`가 낮은 뷰포트에서 754px 패널을 줄이지 않도록 비교 grid 안에서만 `max-height: none` (Overview Stage와 같은 방식). 패키지 CSS는 미변경.
## 3·4. 삭제한 Popup 시연 / 삭제된 Story ID
`sw-header--property-panel-variants`, `sw-header--property-panel-none`, `sw-header--property-panel-all`, `sw-header--property-panel-circle`, `sw-header--property-panel-expanded`
함께 정리한 Story 전용 코드: `PropertyStateStory`(삭제된 4개 전용), `PropertyPanelDemo`의 `standalone` 분기(Variants 전용). 제품 컴포넌트·타입·CSS·SVG·형상 Slot은 삭제하지 않음.
## 5. 최종 Story 개수
| | 수정 전 | 수정 후 |
| --- | --- | --- |
| SW Story | 24 | **19** |
| 전체 저장소 Story | 343 | **338** |
남은 19개의 ID·이름·title·tags는 수정 전과 동일(자동 비교 PASS). Dropdown(`sw-header--composed-controls`, 이름 `Dropdown`, title `SW/Header`) 동일.
## 6~8. 배치·크기·스크롤 검증 (실제 좌표, Chrome, 높이 900)
| 폭 | ①(x,y) | ②(x,y) | ③(x,y) | ④(x,y) | 열/열/행 간격 | Inner client→scroll (W / H) |
| --- | --- | --- | --- | --- | --- | --- |
| 390 | 16,213 | 354,213 | 16,664 | 354,664 | 24/24/24 | 358→652 / 672→1271 |
| 768 | 23,200 | 361,200 | 23,651 | 361,651 | 24/24/24 | 722→722 / 677→1271 |
| 1280 | 38,215 | 376,215 | 38,666 | 376,666 | 24/24/24 | 1203→1203 / 647→1271 |
| 1440 | 120,217 | 458,217 | 120,668 | 458,668 | 24/24/24 | 1200→1200 / 644→1271 |
- 같은 행 y 일치, 같은 열 x 일치, 2열이 1열 오른쪽·2행이 1행 아래 → 4개 폭 모두 **2열 × 2행 PASS**.
- 패널 크기(모든 폭): 314×256 / 314×361 / 314×658 / 314×754 **PASS**.
- 문서 자체는 가로·세로 스크롤 없음(페이지 높이 무제한 확장 없음). Inner 끝까지 스크롤 시 754px 패널 하단·우측이 스크롤 영역 안에 완전히 보임. 390px은 Inner 가로 스크롤로 2열 유지(1열 전환·축소 없음) **PASS**.
## 9. Dropdown / Input / Focus / 닫기
- Input: 원 1개 패널 반지름 Enter 확정 → Callback 기록, 모두 펼침 패널 값 불변(상태 독립). Escape 편집 취소, Focus 패널 내부 유지, Tab 이동 정상.
- Dropdown(레이어): 1행 패널·2행 패널 모두 열림·항목 표시·뷰포트 내부. 열린 채 Inner를 120px 스크롤해도 필드에 붙어 이동(fixed overlay가 분리되지 않음). Escape 닫힘 + 필드로 Focus 복귀. 항목 선택 시 해당 패널에만 Callback.
- 도구 토글 `aria-pressed` 패널별 독립, 그룹 펼침 후 접으면 256px 복귀(다른 패널 361px 유지), 닫기 버튼 → 해당 패널 `onClose` Callback.
## 10. 기존 Header / Overview 보존
- Overview: Header 49px·Stage 렌더 PASS. Dropdown Story: composed controls 렌더 PASS, 기존 기능 스크립트(`dropdown-consolidation.browser.mjs`) 223개 기능 체크 PASS.
- Window Move Motion·K Guide·Property Bar·Layer Detail · Input·형상 Slot·필드 13개 렌더 PASS. `Property Panel`(Header 연결) 열기/Escape 닫기 PASS.
## 11. 제품 런타임·API 미변경
`git diff HEAD -- packages/sw/src packages/sw/ai packages/sw/package.json packages/ui packages/org-chart packages/org-chart-react docs/sw/ai-template src/sw/sw-header-overview.tsx src/sw/sw-header-dropdown.stories.tsx .storybook` → 변경 없음.
## 12. 변경 파일
- `src/sw/sw-header.stories.tsx` — 5개 Story·전용 헬퍼 삭제, 비교 화면 grid·스크롤·로그
- `src/sw/sw-stories.css` — 비교 페이지 레이아웃(Story 전용)
- `packages/sw/tests/storybook-inventory.mjs` — `retiredPropertyPanelIds` 추가
- `packages/sw/tests/followup-four.browser.mjs`, `packages/sw/tests/detail-buttons.browser.mjs` — 삭제된 ID 참조를 비교 Story의 `[data-compare]` 범위로 교체, 기대 개수 24→19
- `packages/sw/tests/property-panel-comparison.browser.mjs` — 신규 검증 스크립트(`before` / `verify`)
- `docs/sw/property-panel-comparison-qa/` — 수정 전후 증거
- 과거 검토·검증 문서(`sw-first-pass-cleanup-review`, `sw-storybook-screen-review` 등)의 옛 ID는 당시 기록으로 보존.
## 13. Typecheck / Build
| 항목 | 결과 |
| --- | --- |
| `npm run typecheck:sw` | PASS |
| `npm run build:sw` | PASS |
| Storybook Typecheck `npx tsc -b` | PASS |
| `npm run build-storybook` | PASS |
| `git diff --check` | PASS |
## 14. 브라우저 검증 (Chrome headless, 새 static build)
| 스크립트 | 결과 | 증거 |
| --- | --- | --- |
| `property-panel-comparison.browser.mjs verify` | **59/59 PASS**, 콘솔 오류 0 | `verify/` |
| `followup-four.browser.mjs` (비교 Story로 이전) | 39/39 PASS | `legacy-followup-four/` |
| `detail-buttons.browser.mjs preservation` | 15/15 PASS | `legacy-detail-buttons-preservation/` |
| `property-fields.browser.mjs` | 77/77 PASS | `legacy-property-fields/` |
| `property-close.browser.mjs` | 6/6 PASS | `legacy-property-close/` |
| `dropdown-consolidation.browser.mjs` | 223 PASS / 4 FAIL (아래) | `legacy-dropdown/` |
`dropdown-consolidation`의 4개 FAIL은 이전 단계 기준선에 고정된 단언입니다: 28→24 / 24 개수 2건, "삭제 외 선언 동일" 1건(이번에 선언 삭제), "`src/sw/sw-stories.css` 미변경" 1건(이번에 Story CSS 수정). 이번 작업의 의도된 변경이며 Dropdown 기능 체크는 모두 PASS입니다. 이 스크립트는 당시 단계 기록이라 수정하지 않았습니다.
수정 전 스크린샷: `before/before-compare-1440.png`(4개가 한 줄), `before/before-property-panel-*.png`. 수정 후: `verify/compare-<폭>-top.png` / `-end.png`, `dropdown-*.png`.
## 15. NOT VERIFIED
- Firefox·Safari 등 Chrome 외 브라우저(이번 작업에서 실행하지 않음).
- 개발 서버(6024) 화면 — 다른 worktree의 서버일 수 있어 사용하지 않고 static build로만 검증.
- 실제 Storybook Manager UI에서의 사이드바 표시(index.json으로 목록만 검증).
- `overview.browser.mjs`, `overview-firefox.browser.mjs`, `storybook-cleanup-stage1.browser.mjs`, `ai-template-*` 스크립트는 재실행하지 않음(Overview는 신규 스크립트에서 렌더·Header 49px만 확인).
- 스크린리더 실사용.