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>
119 lines
9.8 KiB
Markdown
119 lines
9.8 KiB
Markdown
# 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만 확인).
|
||
- 스크린리더 실사용.
|