refactor(sw): simplify storybook navigation and examples
This commit is contained in:
1 parent
47972c55ff
commit
2b0e1a2262
19 files changed
+438
-92
No files matched your search
@@ -46,6 +46,8 @@ const preview: Preview = {
|
||||
"OrgChart",
|
||||
["Overview", "Department Colors", "Full Composition", "Expanded OrgChart"],
|
||||
"Center Graphic",
|
||||
"SW",
|
||||
["Header", "Footer", "Popup", "Viewer", "Theme"],
|
||||
"*",
|
||||
],
|
||||
},
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 97 KiB |
@@ -0,0 +1,71 @@
|
||||
[
|
||||
{
|
||||
"n": "direct URL render: 42 SW Stories, no error display / page error",
|
||||
"ok": true,
|
||||
"d": []
|
||||
},
|
||||
{
|
||||
"n": "removed Home Menu IDs absent from index",
|
||||
"ok": true
|
||||
},
|
||||
{
|
||||
"n": "Popup › Property Panel: four states none/all/circle/expanded at 314 × 256/361/658/754",
|
||||
"ok": true,
|
||||
"d": [
|
||||
[
|
||||
"none",
|
||||
314,
|
||||
256
|
||||
],
|
||||
[
|
||||
"all",
|
||||
314,
|
||||
361
|
||||
],
|
||||
[
|
||||
"circle",
|
||||
314,
|
||||
658
|
||||
],
|
||||
[
|
||||
"expanded",
|
||||
314,
|
||||
754
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"n": "sidebar SW order Header → Footer → Popup → Viewer → Theme",
|
||||
"ok": true,
|
||||
"d": [
|
||||
"Header",
|
||||
"Footer",
|
||||
"Popup",
|
||||
"Viewer",
|
||||
"Theme"
|
||||
]
|
||||
},
|
||||
{
|
||||
"n": "verification Stories not in sidebar",
|
||||
"ok": true,
|
||||
"d": []
|
||||
},
|
||||
{
|
||||
"n": "Popup children order: Custom Content, Multiple Popups, Property Panel",
|
||||
"ok": true,
|
||||
"d": [
|
||||
"sw-popup--custom-content",
|
||||
"sw-popup--multiple-popups",
|
||||
"sw-header--property-panel-compare"
|
||||
]
|
||||
},
|
||||
{
|
||||
"n": "Property Panel listed once (under Popup only)",
|
||||
"ok": true
|
||||
},
|
||||
{
|
||||
"n": "sidebar link opens moved Story with same ID",
|
||||
"ok": true,
|
||||
"d": "http://127.0.0.1:4479/?path=/story/sw-header--property-panel-compare"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,182 @@
|
||||
[
|
||||
[
|
||||
"sw-header",
|
||||
"component",
|
||||
"Header"
|
||||
],
|
||||
[
|
||||
"sw-header--composed-controls",
|
||||
"story",
|
||||
"Dropdown"
|
||||
],
|
||||
[
|
||||
"sw-header--home-menu",
|
||||
"story",
|
||||
"Home Menu"
|
||||
],
|
||||
[
|
||||
"sw-header--home-menu-standalone",
|
||||
"story",
|
||||
"Home Menu · 단독 사용 · 조합형"
|
||||
],
|
||||
[
|
||||
"sw-header--document-open",
|
||||
"story",
|
||||
"Document Open"
|
||||
],
|
||||
[
|
||||
"sw-header--hidden-sub-controls",
|
||||
"story",
|
||||
"Hidden Sub Controls"
|
||||
],
|
||||
[
|
||||
"sw-header--overview",
|
||||
"story",
|
||||
"Overview"
|
||||
],
|
||||
[
|
||||
"sw-header--interactive-states",
|
||||
"story",
|
||||
"Interactive States"
|
||||
],
|
||||
[
|
||||
"sw-header--logo-slot",
|
||||
"story",
|
||||
"Logo Slot"
|
||||
],
|
||||
[
|
||||
"sw-header--document-dropdown",
|
||||
"story",
|
||||
"Document Dropdown"
|
||||
],
|
||||
[
|
||||
"sw-header--responsive-more",
|
||||
"story",
|
||||
"Responsive More"
|
||||
],
|
||||
[
|
||||
"sw-footer",
|
||||
"component",
|
||||
"Footer"
|
||||
],
|
||||
[
|
||||
"sw-footer--default",
|
||||
"story",
|
||||
"기본 Footer"
|
||||
],
|
||||
[
|
||||
"sw-footer--full-footer",
|
||||
"story",
|
||||
"전체 Footer · 실제 조합"
|
||||
],
|
||||
[
|
||||
"sw-footer--tool-groups",
|
||||
"story",
|
||||
"도구 그룹별 표시"
|
||||
],
|
||||
[
|
||||
"sw-footer--states",
|
||||
"story",
|
||||
"Hover / Active / Selected / Disabled"
|
||||
],
|
||||
[
|
||||
"sw-footer--custom-content",
|
||||
"story",
|
||||
"도구 및 메뉴 변경 예제"
|
||||
],
|
||||
[
|
||||
"sw-footer--responsive",
|
||||
"story",
|
||||
"화면 폭 변화"
|
||||
],
|
||||
[
|
||||
"sw-footer--parts",
|
||||
"story",
|
||||
"개별 부품 (조합용)"
|
||||
],
|
||||
[
|
||||
"sw-popup",
|
||||
"component",
|
||||
"Popup"
|
||||
],
|
||||
[
|
||||
"sw-popup--custom-content",
|
||||
"story",
|
||||
"Custom Content"
|
||||
],
|
||||
[
|
||||
"sw-popup--multiple-popups",
|
||||
"story",
|
||||
"Multiple Popups"
|
||||
],
|
||||
[
|
||||
"sw-header--property-panel-compare",
|
||||
"story",
|
||||
"Property Panel · 4개 비교"
|
||||
],
|
||||
[
|
||||
"sw-viewer",
|
||||
"component",
|
||||
"Viewer"
|
||||
],
|
||||
[
|
||||
"sw-viewer--viewer-header",
|
||||
"story",
|
||||
"Viewer Header"
|
||||
],
|
||||
[
|
||||
"sw-viewer--menu-groups",
|
||||
"story",
|
||||
"Menu Groups"
|
||||
],
|
||||
[
|
||||
"sw-viewer--states",
|
||||
"story",
|
||||
"Item States"
|
||||
],
|
||||
[
|
||||
"sw-viewer--dropdowns",
|
||||
"story",
|
||||
"Header + Dropdown"
|
||||
],
|
||||
[
|
||||
"sw-viewer--settings-panel",
|
||||
"story",
|
||||
"Settings Popup"
|
||||
],
|
||||
[
|
||||
"sw-viewer--content-variants",
|
||||
"story",
|
||||
"Popup Content Variants"
|
||||
],
|
||||
[
|
||||
"sw-viewer--variable-size",
|
||||
"story",
|
||||
"Variable Size Popups"
|
||||
],
|
||||
[
|
||||
"sw-viewer--responsive",
|
||||
"story",
|
||||
"Responsive Widths"
|
||||
],
|
||||
[
|
||||
"sw-viewer--compare-with-sw-header",
|
||||
"story",
|
||||
"SWHeader vs Viewer Header"
|
||||
],
|
||||
[
|
||||
"sw-viewer--logo",
|
||||
"story",
|
||||
"Logo"
|
||||
],
|
||||
[
|
||||
"sw-theme",
|
||||
"component",
|
||||
"Theme"
|
||||
],
|
||||
[
|
||||
"sw-theme--theme-inheritance",
|
||||
"story",
|
||||
"Theme Inheritance"
|
||||
]
|
||||
]
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 303 KiB |
@@ -455,7 +455,9 @@ Tooltip은 45 × 17px, 검정 80% 배경과 흰색 12px/400 글자입니다. Too
|
||||
npm run storybook
|
||||
```
|
||||
|
||||
현재(2026-10-19, 홈 메뉴 통합 후) `SW / Header`에는 27개 Story가 있습니다(사이드바 기본 표시 12개 + `verification` 태그 15개). 이전 시점의 Story 표는 [1차 정리 보고 §2](./sw-first-pass-cleanup-review-2026-10-19.md#2-storybook-전체-목록-및-분류), 홈 메뉴 통합 후 목록은 [홈 메뉴 통합·실측 More 보고](./sw-header-home-menu-responsive-2026-10-19.md)를 봅니다. 아래 문단은 Story를 추가한 시점별 설명입니다.
|
||||
> **현재 기준(2026-10-20 SW Storybook 간소화):** SW 메뉴 순서는 `Header → Footer → Popup → Viewer → Theme`입니다. `SW / Header`에는 20개 Story가 있습니다(사이드바 기본 표시 10개 + `verification` 태그 10개). `Property Panel · 4개 비교`는 사이드바에서 `SW / Popup` 아래로 옮겼고 ID(`sw-header--property-panel-compare`)는 그대로입니다. `Window Move Motion`·`K Guide`는 `verification` 태그로 숨겼고, `Home Menu · 단독 사용 · 조합형`은 개별 부품 예제로 사이드바에 표시합니다. 테스트·문서에서 쓰지 않던 Home Menu Figma 비교 Story 6개(`sw-header--home-menu-figma`, `-capture-active`, `-capture-outline`, `-capture-recent`, `-variants`, `-recent-files`)와 `Home Menu`의 Figma 스크린샷 비교 섹션은 제거했습니다. Figma 원본은 `docs/sw/figma-additional/screenshots/`에 있습니다. 상세: [SW Storybook 간소화 보고](./sw-storybook-simplification-2026-10-20.md). 아래는 작성 당시 기록입니다.
|
||||
|
||||
(2026-10-19 기록) 홈 메뉴 통합 후 `SW / Header`에는 27개 Story가 있습니다(사이드바 기본 표시 12개 + `verification` 태그 15개). 이전 시점의 Story 표는 [1차 정리 보고 §2](./sw-first-pass-cleanup-review-2026-10-19.md#2-storybook-전체-목록-및-분류), 홈 메뉴 통합 후 목록은 [홈 메뉴 통합·실측 More 보고](./sw-header-home-menu-responsive-2026-10-19.md)를 봅니다. 아래 문단은 Story를 추가한 시점별 설명입니다.
|
||||
|
||||
2026-10-19 홈 메뉴 통합: 기존 `SW / Home Menu` 메뉴는 사이드바에서 제거하고 `SW / Header`로 옮겼습니다. 사이드바에는 `Home Menu`(`sw-header--home-menu`: 로고 클릭 열기/닫기·이벤트 기록, 헤더 폭 조절, Figma 26:10591 비교, Default/Hover/Active, 최근파일 하위 패널, 속성창·SWPopup·Escape 통합) 하나만 표시합니다. Figma 비교 캔버스·Variant·데이터 변경·단독 사용·속성Bar 비교 등은 `sw-header--home-menu-*` ID의 `verification` 태그 Story로 남아 직접 URL과 사이드바 태그 필터로 엽니다. `Overview`의 로고도 같은 홈 메뉴를 엽니다. `Responsive More` 첫 섹션 "실제 사용 가능한 공간 기준"은 헤더 폭 Range와 로고 오른쪽 버튼·추가 도구·홈 메뉴 On/Off로 실측 More의 이동·복귀를 확인합니다. 홈 메뉴는 SW 일반 모드 전용이며 `SW / Viewer`에는 없습니다.
|
||||
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
# SW Storybook 메뉴·콘텐츠 간소화 (2026-10-20)
|
||||
|
||||
범위: SW Storybook(`src/sw/*.stories.tsx`, `.storybook/preview.tsx` storySort) 정리만 합니다. SW 컴포넌트 소스, 공개 Props/Events, Token, Web(UI)·OrgChart는 변경하지 않았습니다. 기준 HEAD `47972c5`(`feature/sw-package`). Home Menu는 2026-10-19 결정대로 `SW / Header` 아래에 유지합니다.
|
||||
|
||||
## 1. 메뉴 구조
|
||||
|
||||
| | 변경 전 | 변경 후 |
|
||||
|---|---|---|
|
||||
| SW 순서 | Footer → Header → Popup → Theme → Viewer (알파벳) | **Header → Footer → Popup → Viewer → Theme** (`storySort`) |
|
||||
| SW/Header | 표시 12 + verification 15 | 표시 10 + verification 10 |
|
||||
| SW/Footer | 표시 8 | 표시 7 + verification 1 |
|
||||
| SW/Popup | 표시 2 | 표시 3 (`Property Panel · 4개 비교` 이동) |
|
||||
| SW/Viewer / SW/Theme | 10 / 1 | 변경 없음 |
|
||||
|
||||
변경 후 사이드바 (`storybook-simplification-qa/sidebar.json`):
|
||||
|
||||
- **Header:** Dropdown · Home Menu · Home Menu · 단독 사용 · 조합형 · Document Open · Hidden Sub Controls · Overview · Interactive States · Logo Slot · Document Dropdown · Responsive More
|
||||
- **Footer:** 기본 Footer · 전체 Footer · 실제 조합 · 도구 그룹별 표시 · Hover / Active / Selected / Disabled · 도구 및 메뉴 변경 예제 · 화면 폭 변화 · 개별 부품 (조합용)
|
||||
- **Popup:** Custom Content · Multiple Popups · Property Panel · 4개 비교
|
||||
- **Viewer:** Viewer Header · Menu Groups · Item States · Header + Dropdown · Settings Popup · Popup Content Variants · Variable Size Popups · Responsive Widths · SWHeader vs Viewer Header · Logo
|
||||
- **Theme:** Theme Inheritance
|
||||
|
||||
## 2. 변경 내용
|
||||
|
||||
| 구분 | Story (ID) | 처리 | 근거 |
|
||||
|---|---|---|---|
|
||||
| 이동 | `sw-header--property-panel-compare` | 사이드바만 `SW/Popup`으로 이동. 새 파일 `sw-property-panel.stories.tsx`(meta `id: "sw-header"`), 렌더 코드는 `sw-header.stories.tsx`의 `PropertyPanelComparePage`(excludeStories) 그대로 | 사용자 요청. ID·이름·4상태 화면 유지 |
|
||||
| 숨김 | `sw-header--window-move-motion` | `verification` 태그 | GIF 프레임 검증. 테스트 5개가 URL로 사용 |
|
||||
| 숨김 | `sw-header--k-guide` | `verification` 태그 | Overview와 같은 Header 화면. 테스트 3개가 URL로 사용 |
|
||||
| 숨김 | `sw-footer--figma-variants` | `verification` 태그 (삭제 안 함) | Figma 35노드 비교. [Footer Figma 매핑 문서](./sw-footer-figma-mapping-2026-10-20.md)가 참조하며 이를 대신할 자동 검증이 없음 |
|
||||
| 표시 | `sw-header--home-menu-standalone` | `verification` 태그 제거 | Header 없이 쓰는 개별 부품(SWHomeMenuSection / SWHomeMenuItem) 예제 |
|
||||
| 삭제 | `sw-header--home-menu-figma` | Story 삭제 | Figma 1:1 스크린샷 비교. 테스트·문서 참조 없음 |
|
||||
| 삭제 | `sw-header--home-menu-capture-active` / `-capture-outline` / `-capture-recent` | Story 삭제 | 비교 캔버스. 참조 없음 (`-capture-default`는 테스트가 사용하므로 유지) |
|
||||
| 삭제 | `sw-header--home-menu-variants` | Story 삭제 | `Home Menu`의 Default / Variant2 / Variant3 섹션과 중복 |
|
||||
| 삭제 | `sw-header--home-menu-recent-files` | Story 삭제 | `Home Menu`의 최근파일 섹션과 중복 + Figma 스크린샷 |
|
||||
| 섹션 정리 | `sw-header--home-menu` | "Figma 26:10591 비교" 섹션의 Figma 이미지를 빼고 "열림 (현재 폭)"으로 변경. 최근파일 섹션의 Figma 이미지 2개 제거 | 사용법 중심. 구현 화면은 그대로 |
|
||||
|
||||
삭제한 파일 (`src/sw/assets/home-menu/`): `figma-26-10591.png`, `figma-662-67267.png`, `662-67331_recent-files.png`, `662-67471_file-preview-2depth.png`. 네 파일 모두 `docs/sw/figma-additional/screenshots/`의 원본(`26-10591_home-on.png`, `662-67267_home-on-popup-guide.png`, `662-67331_recent-files.png`, `662-67471_file-preview-2depth.png`)과 md5가 같은 복사본이며, 원본은 보존합니다. 사용하지 않게 된 Story CSS 2개(`sw-home-menu-story__figma-row`, `__figma-fit`)도 제거했습니다.
|
||||
|
||||
## 3. 유지한 검증용 Story (verification, URL로 접근 가능)
|
||||
|
||||
`sw-header--home-menu-capture-default` · `-header-composition` · `-integration` · `-capture-responsive` (home-menu-integration 테스트) · `-dynamic-data` (Props 데이터 변경 예제) · `-property-bar-check` · `-capture-property-bar` (속성Bar 차이 3건 **승인 대기**, [Home Menu 통합 보고](./sw-home-menu-integration-2026-10-19.md)) · `sw-header--detail-buttons` · `sw-header--window-move-motion` · `sw-header--k-guide` · `sw-footer--figma-variants`.
|
||||
|
||||
## 4. Story ID
|
||||
|
||||
- 367 → 361개. 삭제한 6개를 뺀 나머지 ID는 모두 유지되었습니다. 바뀐 항목은 tags 4개, title 1개(`property-panel-compare`: SW/Header → SW/Popup)뿐입니다.
|
||||
- SW 외 index 항목 319개(Web·OrgChart·Center Graphic·Theme 등)는 값과 순서가 바뀌지 않았습니다.
|
||||
- 삭제한 ID는 `packages/sw/tests/storybook-inventory.mjs`의 `retiredHomeMenuCompareIds`, 이동한 ID는 `movedToPopupIds`에 기록했습니다.
|
||||
|
||||
## 5. 검증 (2026-10-20 실제 실행)
|
||||
|
||||
| 항목 | 결과 |
|
||||
|---|---|
|
||||
| `npm run build-storybook` | PASS |
|
||||
| `npm run typecheck` | PASS |
|
||||
| `npm run check:ai-docs` | PASS |
|
||||
| `packages/sw/tests/storybook-simplification.browser.mjs` (신규) | **8/8 PASS**: SW Story 42개 직접 URL 렌더·오류 0, 삭제 ID 없음, Popup의 4상태 314 × 256/361/658/754, 사이드바 순서, 숨김 Story 미표시, Popup 순서, 중복 표시 없음, 이동 Story 링크 ID 유지 |
|
||||
| `home-menu-integration.browser.mjs` | 22/23. FAIL 1건(`without homeMenu: logo click…`)은 기준선 `47972c5`에서도 같은 결과로 실패하는 **기존 실패** |
|
||||
| `storybook-unused-removal.browser.mjs` | render 순회에 `movedToPopupIds`를 추가해서 Popup으로 옮긴 `property-panel-compare`도 검사합니다(신규 검사 1건 PASS). 검사 수 98 → 93: 의도적으로 삭제한 6개 render만 빠졌고, 나머지 검사 이름과 PASS/FAIL 상태는 기준선과 같습니다. FAIL 5건은 모두 기준선 `47972c5`에서도 실패하는 **기존 실패**(10-19 시점 inventory·source 스냅샷 비교)입니다. 그중 `byte-identical` 항목의 목록에는 이번에 의도적으로 수정한 export(`WindowMoveMotion`, `KGuide`, `PropertyPanelCompare`)가 추가로 들어 있습니다 |
|
||||
| `dropdown-consolidation.browser.mjs` | 기준선에서도 같은 inventory 스냅샷 FAIL 5건 (기존 실패). 변경 후에는 실행하지 않음 |
|
||||
| `followup-four`, `property-fields` | 실행 불가 (기존): 첫 단계에서 10-19에 retired된 `property-bar` / `property-fields` Story를 엶 |
|
||||
| SW Viewer·Footer·Theme 기능 회귀 | 재실행하지 않음. 컴포넌트·Story 렌더 코드가 바뀌지 않았고, 이번 직접 URL 렌더 검사로 대신함 |
|
||||
|
||||
증거: [storybook-simplification-qa/](./storybook-simplification-qa/) (`result.json`, `sidebar.json`, `sidebar.png`, `popup-property-panel-compare.png`).
|
||||
|
||||
## 6. 남은 개선 항목
|
||||
|
||||
- Footer Story 이름만 한국어(`기본 Footer` 등)이고 다른 SW 메뉴는 영어입니다. 이름은 바뀌어도 ID가 유지되지만, Footer Figma 매핑 문서가 이름으로 참조하고 있어 이번에는 바꾸지 않았습니다.
|
||||
- SW Story는 모두 `controls: { disable: true }`라서 Controls와 Props를 대조할 Playground Story가 없습니다.
|
||||
- 과거 시점 스냅샷과 비교하는 테스트(`storybook-unused-removal`, `dropdown-consolidation`, `overview`, `detail-buttons`)와, retired Story를 여는 테스트(`followup-four`, `property-fields`)는 현재 상태 기준으로 다시 정리할 필요가 있습니다.
|
||||
@@ -21,6 +21,11 @@ export const retiredToolIds = ["sw-tool--tool-buttons"]
|
||||
// SW/Header as sw-header--home-menu (sidebar) and sw-header--home-menu-* (verification tag, reachable by URL).
|
||||
export const movedHomeMenuIds = Object.fromEntries(["figma-home-on:figma", "capture-default", "capture-active", "capture-outline", "capture-recent", "header-composition", "variants", "dynamic-data", "standalone", "recent-files-panel:recent-files", "property-bar-check", "capture-property-bar", "integration", "capture-responsive"]
|
||||
.map(entry => entry.split(":")).map(([from, to = from]) => [`sw-home-menu--${from}`, `sw-header--home-menu-${to}`]))
|
||||
// 2026-10-20 (SW Storybook simplification, user request): Figma screenshot comparisons and duplicate Variant pages that
|
||||
// no test or document used were removed; the Figma originals stay in docs/sw/figma-additional/screenshots/.
|
||||
export const retiredHomeMenuCompareIds = ["figma", "capture-active", "capture-outline", "capture-recent", "variants", "recent-files"].map(id => `sw-header--home-menu-${id}`)
|
||||
// 2026-10-20: Property Panel · 4개 비교 moved to SW/Popup in the sidebar; its ID is unchanged (meta id "sw-header").
|
||||
export const movedToPopupIds = ["sw-header--property-panel-compare"]
|
||||
export const integratedChangedFiles = [
|
||||
'packages/sw/README.md', 'packages/sw/package.json', 'packages/sw/build.mjs',
|
||||
'packages/sw/ai/AI_USAGE.md', 'packages/sw/ai/COMPONENT_CATALOG.md', 'packages/sw/ai/COMPOSITION_PATTERNS.md', 'packages/sw/ai/DESIGN_RULES.md',
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
// 2026-10-20 SW Storybook simplification: sidebar order, hidden verification Stories, removed IDs, direct URL render of
|
||||
// every SW Story and the moved Property Panel (SW/Popup, ID sw-header--property-panel-compare).
|
||||
// Usage: build Storybook first, then node packages/sw/tests/storybook-simplification.browser.mjs [evidence-dir]
|
||||
import { createRequire } from 'node:module'
|
||||
import { readFile, writeFile, mkdir } from 'node:fs/promises'
|
||||
import path from 'node:path'
|
||||
import http from 'node:http'
|
||||
const runtime = process.env.SW_RUNTIME_MODULES ?? 'C:/Users/user/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules'
|
||||
const require = createRequire(path.join(runtime, 'index.js'))
|
||||
const { chromium } = require('playwright')
|
||||
const out = path.resolve(process.argv[2] ?? 'docs/sw/storybook-simplification-qa'); await mkdir(out, { recursive: true })
|
||||
const root = path.resolve('storybook-static'), mime = { '.html': 'text/html', '.js': 'text/javascript', '.css': 'text/css', '.json': 'application/json', '.svg': 'image/svg+xml', '.png': 'image/png', '.ttf': 'font/ttf', '.woff2': 'font/woff2' }
|
||||
const server = http.createServer(async (req, res) => { try { const p = new URL(req.url, 'http://localhost').pathname, file = path.resolve(root, '.' + decodeURIComponent(p === '/' ? '/index.html' : p)); res.setHeader('Content-Type', mime[path.extname(file)] ?? 'application/octet-stream'); res.end(await readFile(file)) } catch { res.writeHead(404).end() } })
|
||||
await new Promise(r => server.listen(0, '127.0.0.1', r)); const base = `http://127.0.0.1:${server.address().port}`
|
||||
const browser = await chromium.launch({ headless: true, executablePath: process.env.SW_CHROME_PATH ?? 'C:/Program Files/Google/Chrome/Application/chrome.exe' })
|
||||
const checks = []; const check = (n, ok, d) => { checks.push({ n, ok, d }); console.log(ok ? 'PASS' : 'FAIL', n, ok ? '' : JSON.stringify(d)) }
|
||||
const index = JSON.parse(await readFile(path.join(root, 'index.json'), 'utf8'))
|
||||
const sw = Object.values(index.entries).filter(e => e.type === 'story' && e.title.startsWith('SW/'))
|
||||
// 1. every SW story renders by direct URL without page errors
|
||||
const page = await browser.newPage({ viewport: { width: 1920, height: 1000 } })
|
||||
let errors = []; page.on('pageerror', e => errors.push(e.message)); page.on('console', m => { if (m.type() === 'error') errors.push(m.text()) })
|
||||
const bad = []
|
||||
for (const e of sw) {
|
||||
errors = []
|
||||
await page.goto(`${base}/iframe.html?id=${e.id}&viewMode=story`)
|
||||
try { await page.locator('#storybook-root > *').first().waitFor({ timeout: 15000 }) } catch { bad.push([e.id, 'no root']) ; continue }
|
||||
await page.waitForTimeout(150)
|
||||
const err = await page.locator('.sb-show-errordisplay').count()
|
||||
if (err || errors.length) bad.push([e.id, errors.slice(0, 2)])
|
||||
}
|
||||
check(`direct URL render: ${sw.length} SW Stories, no error display / page error`, bad.length === 0, bad)
|
||||
// 2. removed IDs are gone
|
||||
const removed = ['figma', 'capture-active', 'capture-outline', 'capture-recent', 'variants', 'recent-files'].map(id => `sw-header--home-menu-${id}`)
|
||||
check('removed Home Menu IDs absent from index', removed.every(id => !index.entries[id]))
|
||||
// 3. Property panel in Popup: four states
|
||||
await page.goto(`${base}/iframe.html?id=sw-header--property-panel-compare&viewMode=story`)
|
||||
await page.locator('[data-compare]').first().waitFor()
|
||||
await page.waitForTimeout(300)
|
||||
const cells = await page.locator('[data-compare]').evaluateAll(list => list.map(c => { const r = c.querySelector('.hm-sw-property').getBoundingClientRect(); return [c.dataset.compare, Math.round(r.width), Math.round(r.height)] }))
|
||||
check('Popup › Property Panel: four states none/all/circle/expanded at 314 × 256/361/658/754', JSON.stringify(cells) === JSON.stringify([['none', 314, 256], ['all', 314, 361], ['circle', 314, 658], ['expanded', 314, 754]]), cells)
|
||||
await page.screenshot({ path: path.join(out, 'popup-property-panel-compare.png'), fullPage: true })
|
||||
// 4. manager sidebar
|
||||
const m = await browser.newPage({ viewport: { width: 1600, height: 2400 } })
|
||||
await m.goto(`${base}/?path=/story/sw-header--overview`)
|
||||
await m.locator('[data-item-id="sw-header--overview"]').waitFor()
|
||||
for (const c of ['sw-footer', 'sw-popup', 'sw-viewer', 'sw-theme']) { const b = m.locator(`[data-item-id="${c}"] > button[aria-expanded="false"]`); if (await b.count()) await b.click() }
|
||||
await m.waitForTimeout(500)
|
||||
const rows = await m.locator('#storybook-explorer-tree [data-item-id^="sw-"]').evaluateAll(list => list.map(e => [e.dataset.itemId, e.dataset.nodetype, e.textContent.replace('Skip to content', '').trim()]))
|
||||
await writeFile(path.join(out, 'sidebar.json'), JSON.stringify(rows, null, 1))
|
||||
const comps = rows.filter(r => r[1] === 'component').map(r => r[2])
|
||||
check('sidebar SW order Header → Footer → Popup → Viewer → Theme', JSON.stringify(comps) === JSON.stringify(['Header', 'Footer', 'Popup', 'Viewer', 'Theme']), comps)
|
||||
const hidden = ['sw-header--window-move-motion', 'sw-header--k-guide', 'sw-footer--figma-variants', 'sw-header--detail-buttons', 'sw-header--home-menu-capture-default']
|
||||
check('verification Stories not in sidebar', rows.every(r => !hidden.includes(r[0])), rows.filter(r => hidden.includes(r[0])))
|
||||
const popupRows = await m.locator('#storybook-explorer-tree [data-item-id]').evaluateAll(list => list.map(e => e.dataset.itemId))
|
||||
const pi = popupRows.indexOf('sw-popup')
|
||||
check('Popup children order: Custom Content, Multiple Popups, Property Panel', JSON.stringify(popupRows.slice(pi + 1, pi + 4)) === JSON.stringify(['sw-popup--custom-content', 'sw-popup--multiple-popups', 'sw-header--property-panel-compare']), popupRows.slice(pi + 1, pi + 4))
|
||||
const headerIds = rows.filter(r => r[0].startsWith('sw-header--')).map(r => r[0])
|
||||
check('Property Panel listed once (under Popup only)', headerIds.filter(id => id === 'sw-header--property-panel-compare').length === 1)
|
||||
await m.locator('[data-item-id="sw-header--property-panel-compare"]').click(); await m.waitForTimeout(800)
|
||||
check('sidebar link opens moved Story with same ID', m.url().includes('sw-header--property-panel-compare'), m.url())
|
||||
await m.screenshot({ path: path.join(out, 'sidebar.png'), clip: { x: 0, y: 0, width: 320, height: 2400 } })
|
||||
await writeFile(path.join(out, 'result.json'), JSON.stringify(checks, null, 1))
|
||||
console.log(checks.filter(c => c.ok).length + '/' + checks.length + ' PASS')
|
||||
await browser.close(); server.close()
|
||||
@@ -8,7 +8,7 @@ import { execFileSync } from 'node:child_process'
|
||||
import path from 'node:path'
|
||||
import http from 'node:http'
|
||||
import { parse } from '@babel/parser'
|
||||
import { swStoryEntries, retiredUnusedDemoIds, integratedStoryIds, integratedChangedFiles } from './storybook-inventory.mjs'
|
||||
import { swStoryEntries, retiredUnusedDemoIds, integratedStoryIds, integratedChangedFiles, movedToPopupIds } from './storybook-inventory.mjs'
|
||||
|
||||
const out = path.resolve(process.argv[2] ?? 'docs/sw/storybook-unused-story-removal-qa/verify')
|
||||
const qa = 'docs/sw/storybook-unused-story-removal-qa/before'
|
||||
@@ -92,7 +92,10 @@ try {
|
||||
check('removed URL renders no SW Story', await page.locator('.hm-sw-header, .hm-sw-theme').count() === 0)
|
||||
report.errors.length = 0 // the missing-story error above is expected; start the regression clean
|
||||
|
||||
for (const entry of afterSW) {
|
||||
// 2026-10-20: Property Panel · 4개 비교 moved to SW/Popup (same sw-header-- ID), so it is added to the render pass.
|
||||
const moved = movedToPopupIds.map(id => afterIndex.entries[id]).filter(Boolean)
|
||||
check('inventory: moved Popup Story keeps its sw-header-- ID under SW/Popup', moved.length === movedToPopupIds.length && moved.every(e => e.title === 'SW/Popup'), moved.map(e => [e.id, e.title]))
|
||||
for (const entry of [...afterSW, ...moved]) {
|
||||
await goto(entry.id.replace('sw-header--', ''))
|
||||
check(`render ${entry.id}`, !(await page.locator('.sb-errordisplay').isVisible()))
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 170 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 105 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 123 KiB |
@@ -221,6 +221,8 @@ const SMALL_COMMAND = { width: 120, ["--hm-sw-footer-command-expanded-height" as
|
||||
|
||||
export const FigmaVariants: Story = {
|
||||
name: "Figma 디자인별 Variant (35 노드)",
|
||||
// 2026-10-20 sidebar simplification: Figma node verification; ID and direct URL kept.
|
||||
tags: ["verification"],
|
||||
render: () => (
|
||||
<StoryPage>
|
||||
<StoryPageHeader kicker={KICKER} title="Figma 디자인별 Variant" description={<>요청된 35개 노드 전체. 왼쪽 = Figma 렌더(get_screenshot), 오른쪽 = 같은 순서의 구현 상태(Hover는 Story 전용 <code>data-sb-hover</code>로 고정). 노드 → 컴포넌트·Props 매핑은 <code>docs/sw/sw-footer-figma-mapping-2026-10-20.md</code>.</>} />
|
||||
|
||||
@@ -13,15 +13,13 @@ import {
|
||||
figmaHomeMenuItemIds, figmaHomeMenuSections, figmaRecentFiles, figmaTileNodes, figmaTitleNodes, withRecentFiles,
|
||||
} from "./sw-home-menu-fixture"
|
||||
import placeholderLogo from "./assets/sw-header-logo-placeholder.svg"
|
||||
import figmaHomeOn from "./assets/home-menu/figma-26-10591.png"
|
||||
import figmaHomeOnOutline from "./assets/home-menu/figma-662-67267.png"
|
||||
import figmaRecent from "./assets/home-menu/662-67331_recent-files.png"
|
||||
import figmaPreview from "./assets/home-menu/662-67471_file-preview-2depth.png"
|
||||
import figmaPropertyBar from "./assets/home-menu/figma-26-10492.png"
|
||||
|
||||
// Owner: docs/sw/figma-additional/analysis-report.md (Figma rj6wpsfk24lOWvWiVRAANP 26:10591 / 662:67267).
|
||||
// 2026-10-19: the former SW/Home Menu Stories live under SW/Header (SW normal mode only; SW/Viewer has no logo menu).
|
||||
// "Home Menu" is the sidebar Story; the other Stories keep their checks reachable by URL (verification tag).
|
||||
// "Home Menu" and "Home Menu · 단독 사용 · 조합형" are the sidebar Stories; the other Stories keep their checks reachable
|
||||
// by URL (verification tag). 2026-10-20: Figma screenshot comparisons that no test or document used were removed;
|
||||
// the Figma originals stay in docs/sw/figma-additional/screenshots/.
|
||||
const KICKER = "HM DESIGN SYSTEM / SW"
|
||||
|
||||
const meta = {
|
||||
@@ -136,21 +134,16 @@ export const HomeMenu: Story = {
|
||||
<StorySection title="반응형 · 헤더 폭 조절 · 더보기(⋯)" description="메뉴 위치와 폭은 고정 x가 아니라 Header를 측정해 정합니다(객체 수정 영역 −2px ~ 창 영역). 폭이 부족한 Header에서는 기존 더보기(…) 규칙이 그대로 동작하고, 메뉴는 가로 스크롤 없이 들어가는 섹션만 앞에서부터 보여 주며 나머지는 끝의 더보기(⋯) 섹션으로 옮깁니다. 더보기를 누르면 옮긴 섹션이 텍스트 메뉴(섹션 제목 + 기능 목록, 그룹 사이 구분선)로 아래에 열리고(Hover·Active·클릭은 타일과 같음, 최근파일은 기존 목록을 엶), 폭이 넓어지면 원래 자리로 돌아갑니다. 브라우저 폭이나 슬라이더로 확인합니다(슬라이더 최대 = 현재 페이지 폭).">
|
||||
<ResizableHeaderWithMenu />
|
||||
</StorySection>
|
||||
<StorySection title="Figma 26:10591 비교 (현재 폭)" description="위는 구현(열림, 현재 폭), 아래는 Figma 스크린샷(1920px을 현재 폭에 맞춰 축소)입니다. 1:1 비교는 'Home Menu · Figma 재현 (26:10591)' Story(1920px)에서 합니다. 열림 동안 로고는 Home On(노란 테두리), Header 상·하단에 #5F4B0F 2px 선이 표시되고 닫으면 기본으로 돌아갑니다(Figma 662:67267).">
|
||||
<StorySection title="열림 (현재 폭)" description="열림 동안 로고는 Home On(노란 테두리), Header 상·하단에 #5F4B0F 2px 선이 표시되고 닫으면 기본으로 돌아갑니다(Figma 26:10591 / 662:67267).">
|
||||
<HeaderWithMenu defaultOpen autoFocus={false} />
|
||||
<img className="sw-home-menu-story__figma-fit" src={figmaHomeOn} alt="Figma 26:10591 home on" width={1920} height={78} />
|
||||
</StorySection>
|
||||
<StorySection title="Default / Variant2 · Hover / Variant3 · Active" description="Figma 버튼 세트 15개(26:11355 … 26:11631)는 모두 같은 SWHomeMenuItem입니다. Variant2(Hover)는 마우스를 올려 확인하며 Figma에서 Variant3와 시각 속성이 같습니다. Variant3는 activeIds로 지정합니다.">
|
||||
<SWTheme className="sw-home-menu-story__stage"><SWHomeMenu defaultOpen autoFocus={false} sections={figmaHomeMenuSections} closeOnBackgroundClick={false} aria-label="Default" /></SWTheme>
|
||||
<SWTheme className="sw-home-menu-story__stage"><SWHomeMenu defaultOpen autoFocus={false} sections={figmaHomeMenuSections} activeIds={figmaHomeMenuItemIds} closeOnBackgroundClick={false} aria-label="Active" /></SWTheme>
|
||||
{tileTable}
|
||||
</StorySection>
|
||||
<StorySection title="최근파일 하위 패널 (662:67267)" description="최근파일 타일을 누르면(Variant3) 메뉴 하단 강조가 전체 2px 외곽선으로 바뀌고 그 아래에 최근파일 목록이 열립니다. 행에 마우스를 올리면 2뎁스 미리보기가 옆에 나타납니다. 다시 누르거나 Escape로 닫습니다. 최근파일이 더보기 안에 있으면 목록은 더보기 타일 아래에 열리고 더보기 타일이 Variant3가 됩니다. 목록과 미리보기 이미지는 Story 데이터입니다. 1920px 1:1은 'Home Menu · 최근파일 하위 패널' Story입니다.">
|
||||
<StorySection title="최근파일 하위 패널 (662:67267)" description="최근파일 타일을 누르면(Variant3) 메뉴 하단 강조가 전체 2px 외곽선으로 바뀌고 그 아래에 최근파일 목록이 열립니다. 행에 마우스를 올리면 2뎁스 미리보기가 옆에 나타납니다. 다시 누르거나 Escape로 닫습니다. 최근파일이 더보기 안에 있으면 목록은 더보기 타일 아래에 열리고 더보기 타일이 Variant3가 됩니다. 목록과 미리보기 이미지는 Story 데이터입니다.">
|
||||
<div className="sw-home-menu-story__tall"><HeaderWithMenu defaultOpen autoFocus={false} defaultActiveIds={["recent"]}>{log => log}</HeaderWithMenu></div>
|
||||
<div className="sw-home-menu-story__figma-row">
|
||||
<img src={figmaRecent} alt="Figma 662:67331 최근파일" width={362} height={758} />
|
||||
<img src={figmaPreview} alt="Figma 662:67471 파일출력 2뎁스" width={315} height={276} />
|
||||
</div>
|
||||
</StorySection>
|
||||
<StorySection title="통합 · 속성창 · SWPopup · Escape" description="Escape는 Focus가 있는 곳을 먼저 닫습니다(메뉴 안: 하위 패널 → 메뉴, Popup 안: 그 Popup). Focus가 모두의 밖이면 가장 최근에 열거나 사용한 하나만 닫습니다.">
|
||||
<IntegrationDemo />
|
||||
@@ -159,38 +152,16 @@ export const HomeMenu: Story = {
|
||||
),
|
||||
}
|
||||
|
||||
export const HomeMenuFigma: Story = {
|
||||
name: "Home Menu · Figma 재현 (26:10591)",
|
||||
tags: ["verification"],
|
||||
render: () => (
|
||||
<StoryPage>
|
||||
<StoryPageHeader kicker={KICKER} title="로고 클릭 메뉴 — Figma 26:10591 재현"
|
||||
description="1920px Header 위에 SWHomeMenu를 겹친 상태입니다. 위는 구현, 아래는 Figma 스크린샷(1x)입니다. 로고를 다시 누르면 닫힙니다." />
|
||||
<StorySection title="구현 (1920px)" description="SWHeader가 객체 수정 영역 시작(−2px)~창 영역 시작을 DOM에서 측정해 메뉴를 놓습니다. 열림 동안 로고는 Home On(노란 테두리), Header 상·하단에 #5F4B0F 2px 선이 표시되고 닫으면 기본으로 돌아갑니다(Figma 662:67267).">
|
||||
<div className="sw-home-menu-story__scroll"><HeaderWithMenu width={1920} defaultOpen /></div>
|
||||
</StorySection>
|
||||
<StorySection title="Figma 26:10591">
|
||||
<div className="sw-home-menu-story__scroll"><img className="sw-home-menu-story__figma" src={figmaHomeOn} alt="Figma 26:10591 home on" width={1920} height={78} /></div>
|
||||
</StorySection>
|
||||
</StoryPage>
|
||||
),
|
||||
}
|
||||
|
||||
/** 1:1 capture canvas for pixel comparison with the Figma 1920 x 77 frame (no story page chrome). */
|
||||
function FigmaCanvas({ active, accent, recent }: { active?: boolean; accent?: SWHomeMenuAccent; recent?: boolean }) {
|
||||
const sections = recent ? withRecentFiles(figmaHomeMenuSections, <SWRecentFiles files={figmaRecentFiles} />) : figmaHomeMenuSections
|
||||
/** 1:1 capture canvas at the Figma 1920 x 77 frame (no story page chrome); home-menu-integration.browser.mjs measures it. */
|
||||
function FigmaCanvas() {
|
||||
return (
|
||||
<div className="sw-home-menu-story__frame" style={{ width: 1920, height: recent ? 840 : 80 }}>
|
||||
<div className="sw-home-menu-story__frame" style={{ width: 1920, height: 80 }}>
|
||||
{/* The integrated placement (measured by SWHeader), not a fixed x: it must land on Figma x 375. */}
|
||||
<SWHeader {...headerArgs} defaultHomeMenuOpen homeMenu={{ sections, accent, autoFocus: false,
|
||||
activeIds: active ? figmaHomeMenuItemIds : recent ? ["recent"] : undefined }} />
|
||||
<SWHeader {...headerArgs} defaultHomeMenuOpen homeMenu={{ sections: figmaHomeMenuSections, autoFocus: false }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export const HomeMenuCaptureDefault: Story = { name: "Home Menu · 비교 캔버스 · Default", tags: ["!autodocs", "verification"], render: () => <FigmaCanvas /> }
|
||||
export const HomeMenuCaptureActive: Story = { name: "Home Menu · 비교 캔버스 · Variant3", tags: ["!autodocs", "verification"], render: () => <FigmaCanvas active /> }
|
||||
export const HomeMenuCaptureOutline: Story = { name: "Home Menu · 비교 캔버스 · outline", tags: ["!autodocs", "verification"], render: () => <FigmaCanvas accent="outline" /> }
|
||||
export const HomeMenuCaptureRecent: Story = { name: "Home Menu · 비교 캔버스 · 최근파일", tags: ["!autodocs", "verification"], render: () => <FigmaCanvas recent /> }
|
||||
|
||||
export const HomeMenuHeaderComposition: Story = {
|
||||
name: "Home Menu · Header 조합 · 로고 클릭",
|
||||
@@ -206,27 +177,6 @@ export const HomeMenuHeaderComposition: Story = {
|
||||
),
|
||||
}
|
||||
|
||||
export const HomeMenuVariants: Story = {
|
||||
name: "Home Menu · 3가지 Variant",
|
||||
tags: ["verification"],
|
||||
render: () => (
|
||||
<StoryPage>
|
||||
<StoryPageHeader kicker={KICKER} title="Default / Variant2 / Variant3"
|
||||
description="Figma 버튼 세트 15개(26:11355 … 26:11631)는 모두 같은 SWHomeMenuItem입니다. Variant2(Hover)는 마우스를 올려 확인하며, Figma에서 Variant3와 시각 속성이 같습니다. Variant3는 activeIds로 지정합니다." />
|
||||
<StorySection title="Default">
|
||||
<SWTheme className="sw-home-menu-story__stage"><SWHomeMenu defaultOpen sections={figmaHomeMenuSections} closeOnBackgroundClick={false} aria-label="Default" /></SWTheme>
|
||||
</StorySection>
|
||||
<StorySection title="Variant2 · Hover" description="마우스를 올린 타일만 Variant2입니다. 누르는 동안 Variant3이고 클릭 후에는 Default로 돌아갑니다(실행 버튼). 최근파일만 목록이 열린 동안 Variant3입니다.">
|
||||
<SWTheme className="sw-home-menu-story__stage"><SWHomeMenu defaultOpen sections={figmaHomeMenuSections} closeOnBackgroundClick={false} aria-label="Hover" /></SWTheme>
|
||||
</StorySection>
|
||||
<StorySection title="Variant3 · Active (activeIds = 15개 전체)" description="Figma Variant3 시각 확인용으로 host가 activeIds를 직접 지정한 상태입니다(표시 전용). 클릭으로는 바뀌지 않습니다.">
|
||||
<SWTheme className="sw-home-menu-story__stage"><SWHomeMenu defaultOpen sections={figmaHomeMenuSections} activeIds={figmaHomeMenuItemIds} closeOnBackgroundClick={false} aria-label="Active" /></SWTheme>
|
||||
</StorySection>
|
||||
<StorySection title="Figma 노드 대응" description="섹션 제목 tit_* 와 타일 세트">{tileTable}</StorySection>
|
||||
</StoryPage>
|
||||
),
|
||||
}
|
||||
|
||||
function DynamicDemo() {
|
||||
const [sections, setSections] = useState<SWHomeMenuSectionData[]>(figmaHomeMenuSections)
|
||||
const [selection, setSelection] = useState<"multiple" | "single">("multiple")
|
||||
@@ -304,7 +254,6 @@ function StandaloneDemo() {
|
||||
|
||||
export const HomeMenuStandalone: Story = {
|
||||
name: "Home Menu · 단독 사용 · 조합형",
|
||||
tags: ["verification"],
|
||||
render: () => (
|
||||
<StoryPage>
|
||||
<StoryPageHeader kicker={KICKER} title="SWTheme 안에서 단독 사용"
|
||||
@@ -314,27 +263,6 @@ export const HomeMenuStandalone: Story = {
|
||||
),
|
||||
}
|
||||
|
||||
export const HomeMenuRecentFiles: Story = {
|
||||
name: "Home Menu · 최근파일 하위 패널 (662:67267)",
|
||||
tags: ["verification"],
|
||||
render: () => (
|
||||
<StoryPage>
|
||||
<StoryPageHeader kicker={KICKER} title="최근파일 — Figma 662:67267 + 662:67331 + 662:67471"
|
||||
description="Figma 주석 '최근파일' 상태입니다. 최근파일 타일을 누르면(Variant3) 메뉴 하단 강조가 전체 2px 외곽선으로 바뀌고 그 아래에 최근파일 목록이 열립니다. 행에 마우스를 올리면 2뎁스 미리보기가 옆에 나타납니다. 다시 누르거나 Escape로 닫습니다. 목록과 미리보기 이미지는 Story 데이터입니다. K 미리보기(Variant5)는 기존 SWHeader K 가이드 Hover가 담당합니다." />
|
||||
<StorySection title="구현 (1920px)">
|
||||
<div className="sw-home-menu-story__scroll sw-home-menu-story__tall"><HeaderWithMenu width={1920} defaultOpen defaultActiveIds={["recent"]}>{log => log}</HeaderWithMenu></div>
|
||||
</StorySection>
|
||||
<StorySection title="Figma 662:67267 · 662:67331 · 662:67471">
|
||||
<div className="sw-home-menu-story__scroll"><img className="sw-home-menu-story__figma" src={figmaHomeOnOutline} alt="Figma 662:67267" width={1935} height={193} /></div>
|
||||
<div className="sw-home-menu-story__figma-row">
|
||||
<img src={figmaRecent} alt="Figma 662:67331 최근파일" width={362} height={758} />
|
||||
<img src={figmaPreview} alt="Figma 662:67471 파일출력 2뎁스" width={315} height={276} />
|
||||
</div>
|
||||
</StorySection>
|
||||
</StoryPage>
|
||||
),
|
||||
}
|
||||
|
||||
// Property bar check (Figma 26:10492) against the current SWHeaderPropertyBar. Values are the Figma sample; the
|
||||
// bar itself is unchanged (3 differences, awaiting approval: home-menu-integration report §속성Bar).
|
||||
const barProperties: SWHeaderProperty[] = [
|
||||
|
||||
@@ -65,7 +65,7 @@ const callbacks = {
|
||||
|
||||
const meta = {
|
||||
title: "SW/Header",
|
||||
excludeStories: ["ComposedDemo"],
|
||||
excludeStories: ["ComposedDemo", "PropertyPanelComparePage"],
|
||||
component: SWHeader,
|
||||
parameters: { layout: "fullscreen" },
|
||||
args: { ...figmaArgs, ...callbacks },
|
||||
@@ -289,6 +289,8 @@ function MotionSpecimen({ time }: { time?: number }) {
|
||||
|
||||
export const WindowMoveMotion: Story = {
|
||||
name: "Window Move Motion",
|
||||
// 2026-10-20 sidebar simplification: GIF frame verification; ID and direct URL kept.
|
||||
tags: ["verification"],
|
||||
parameters: { controls: { disable: true } },
|
||||
render: () => (
|
||||
<StoryPage>
|
||||
@@ -939,6 +941,8 @@ function usePropertyMenus(record: (line: string) => void, setProperties: (update
|
||||
|
||||
export const KGuide: Story = {
|
||||
name: "K Guide",
|
||||
// 2026-10-20 sidebar simplification: the same Header as Overview (K guide on hover); ID and direct URL kept.
|
||||
tags: ["verification"],
|
||||
parameters: { controls: { disable: true } },
|
||||
render: () => <StoryPage><StoryPageHeader kicker={KICKER} title="K 가이드 반복 애니메이션" description="기존 K 버튼 Hover/Focus → 원본 이미지 Pan·Zoom 반복. 영역을 벗어나면 정지, 재진입은 처음부터. Reduced Motion은 정지 이미지." /><div className="sw-story-property-room"><SWHeader {...figmaArgs} {...callbacks} /></div></StoryPage>,
|
||||
}
|
||||
@@ -992,8 +996,7 @@ function PropertyCompare() {
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
export const PropertyPanelCompare: Story = {
|
||||
name: "Property Panel · 4개 비교",
|
||||
parameters: { controls: { disable: true } },
|
||||
render: () => <StoryPage className="sw-story-compare-page"><StoryPageHeader kicker={KICKER} title="속성창 4개 상태 비교" description="네 패널은 같은 SWHeaderPropertyPanel입니다. 실제 Header에서는 현재 선택 객체의 패널 하나만 표시합니다." /><PropertyCompare /></StoryPage>,
|
||||
/** Rendered by SW/Popup › Property Panel · 4개 비교 (sw-property-panel.stories.tsx, ID sw-header--property-panel-compare). */
|
||||
export function PropertyPanelComparePage() {
|
||||
return <StoryPage className="sw-story-compare-page"><StoryPageHeader kicker={KICKER} title="속성창 4개 상태 비교" description="네 패널은 같은 SWHeaderPropertyPanel입니다. 실제 Header에서는 현재 선택 객체의 패널 하나만 표시합니다." /><PropertyCompare /></StoryPage>
|
||||
}
|
||||
@@ -11,8 +11,5 @@
|
||||
.sw-home-menu-story__table { border-collapse: collapse; font-size: 13px; }
|
||||
.sw-home-menu-story__table :is(th, td) { padding: 4px 8px; border: 1px solid #ccc; text-align: left; }
|
||||
.sw-home-menu-story__tall .sw-home-menu-story__frame { height: 860px; }
|
||||
.sw-home-menu-story__figma-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 16px; margin-top: 12px; }
|
||||
.sw-home-menu-story__figma-row > img { max-width: 100%; height: auto; }
|
||||
.sw-home-menu-story__figma-fit { display: block; width: 100%; height: auto; margin-top: 12px; }
|
||||
.sw-home-menu-story__width { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; font-size: 13px; }
|
||||
.sw-home-menu-story__width input { width: min(480px, 60vw); }
|
||||
@@ -0,0 +1,17 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite"
|
||||
import { PropertyPanelComparePage } from "./sw-header.stories"
|
||||
|
||||
const meta = {
|
||||
title: "SW/Popup",
|
||||
// 2026-10-20: moved from SW/Header to SW/Popup in the sidebar only; the id keeps sw-header--property-panel-compare
|
||||
// for existing tests, documents and bookmarks. The file name sorts after sw-popup.stories.tsx, so this Story follows
|
||||
// Custom Content and Multiple Popups.
|
||||
id: "sw-header",
|
||||
parameters: { layout: "fullscreen", controls: { disable: true } },
|
||||
} satisfies Meta
|
||||
export default meta
|
||||
|
||||
export const PropertyPanelCompare: StoryObj<typeof meta> = {
|
||||
name: "Property Panel · 4개 비교",
|
||||
render: () => <PropertyPanelComparePage />,
|
||||
}
|
||||
Reference in new issue
Block a user