chore(sw): organize Storybook components and documentation

First-pass cleanup only; no design, behavior, public API or Story ID change.
- Stories: correct stale Text Stroke / Colorize / "latest" texts, reuse
  parseSWHeaderColor, derive the field fixture from PROPERTY_FIXTURE
- Comments: date the "Latest request" notes in sw.css and the color menu
- Docs: fix removed text-stroke tokens in spec/usage/README, add spec §18
  (property fields), current-state index banners, Storybook 33 pointer
- Add docs/sw/sw-first-pass-cleanup-review-2026-10-19.md (Story table,
  structure, SAFE / REVIEW list for the second pass)

Checks: SW + app typecheck, SW build, Storybook build, 33 Story IDs
unchanged, property fields 77/77, detail-buttons verify 257 checks, 111 doc
links 0 broken.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shkim4andClaude Opus 5.5 committed 2026-10-19 09:52:46 +09:00
1 parent 0029cef60c
commit 92830fe11d
7 files changed
+267 -39

No files matched your search

@@ -0,0 +1,218 @@
# SW 1차 Storybook·컴포넌트·문서 정리 보고 (2026-10-19)
이번 정리는 디자인·동작·공개 API·Story ID를 그대로 두고 관리 구조만 정리했습니다. 삭제, 이름 변경, 분류 이동, 통합은 하지 않았습니다. 그런 작업은 [§8 2차 검토 목록](#8-2차-검토-목록)에 사용자 결정 대상으로 남겼습니다.
- 시작: Branch `feature/sw-package`, HEAD `0029cef60c46d3b7e7ffb2795e31357958ab3b81`, 작업 트리 clean
- 범위: `packages/sw`, `src/sw`, `docs/sw` (다른 패키지·루트 설정은 변경하지 않음)
## 1. 현재 SW 프로젝트 구조
| 경로 | 역할 |
|---|---|
| `packages/sw/src/index.ts` | 패키지 진입점(`sw.css` import, 공개 export) |
| `packages/sw/src/components/sw-header/SWHeader.tsx` | Header 조립·반응형·More·구성(`controls`/`hiddenControls`/`menuOrder`)·속성Bar/속성창 열림 (461줄) |
| `packages/sw/src/components/sw-header/components/` | 하위 컴포넌트 19개 파일 (아래 §3) |
| `packages/sw/src/components/sw-header/types.ts` | `SWHeaderProps`와 데이터 타입 |
| `packages/sw/src/components/sw-theme/SWTheme.tsx` | 하위 컴포넌트 단독 사용 시 토큰 범위 |
| `packages/sw/src/theme/sw.css` | 전체 스타일·토큰 (1842줄) |
| `packages/sw/src/assets/` | Figma SVG/PNG 50개 |
| `packages/sw/tests/` | 브라우저 검증 스크립트 5개 |
| `src/sw/sw-header.stories.tsx` | Storybook `SW / Header` 33개 Story (약 1860줄) |
| `src/sw/sw-stories.css`, `src/sw/assets/` | Story 전용 배치 CSS, 임시 로고, Figma 비교 PNG 3개 |
| `docs/sw/` | 사용 가이드, 디자인 명세, 검증 보고 15개, 증거 폴더 5개 |
## 2. Storybook 전체 목록 및 분류
모두 `SW / Header` 아래에 있습니다. 주소는 `iframe.html?id=<ID>`입니다. 분류 기준은 기본 화면 / 상태 / 기능 예제 / Figma 비교 / QA·검증 / 중복 검토입니다. "테스트 사용"은 `packages/sw/tests`가 그 ID를 직접 연다는 뜻입니다. 이 Story들은 이름을 바꾸면 테스트도 고쳐야 합니다. 추가로 `detail-buttons` 검증은 33개 ID 전체를 기준 목록과 비교합니다.
| # | Story ID | 메뉴 이름 | 분류 | 목적 · 주요 컴포넌트 | Figma | 테스트 사용 | 1차 의견 |
|---|---|---|---|---|---|---|---|
| S1 | `sw-header--detail-buttons` | Detail Buttons (Shared States) | Figma 비교 · QA | 상세 버튼 5종 공통 상태, `SWHeaderMenuDetail` | 26:10789 / 26:10792 | ○ | 유지, QA 분류 검토 |
| S2 | `sw-header--overview` | Overview | 기본 화면 | 1920 Header + 선택 상태 | 26:8944 | | 유지(대표) |
| S3 | `sw-header--default` | Default | 기본 화면(Args) | `SWHeader` 1920 프레임 | 26:8944 | ○ | 중복 검토(S2·S4) |
| S4 | `sw-header--controls` | Controls | 기능 예제(Args) | 프레임 없는 `SWHeader` + Controls 패널 | — | ○ | 중복 검토(S3) |
| S5 | `sw-header--interactive-states` | Interactive States | 상태 | Default/Hover/Selected/Disabled, 창 버튼 Callback | 26:10655 | | 유지 |
| S6 | `sw-header--responsive` | Responsive | 기능 예제 | 18개 폭 반응형 | 26:8944 | | 유지, S15와 인접 배치 검토 |
| S7 | `sw-header--window-move-motion` | Window Move Motion | 상태(Motion) | 창 이동 GIF 모션 1400ms | 26:10220 | | 유지 |
| S8 | `sw-header--composed-controls` | Composed Controls | 기능 예제 | 공개 하위 컴포넌트 재사용, 그룹 필드 Hover | — | | 유지 |
| S9 | `sw-header--logo-slot` | Logo Slot | 기능 예제 | `logoSrc` / `logo` / 미전달 | 26:8944 | | 유지 |
| S10 | `sw-header--document-dropdown` | Document Dropdown | 상태 + 기능 | 문서 목록 섹션 18개 | 26:10662 | | 유지, 섹션 분할 검토 |
| S11 | `sw-header--layer-dropdown` | Layer Dropdown | 상태 + 기능 | 레이어 목록 섹션 13개 | 26:10940 | | 유지 |
| S12 | `sw-header--color-dropdown` | Color Dropdown | 상태 + 기능 | 색상 목록·RGB 입력 | 26:10986 / 26:11036 | ○ | 유지 |
| S13 | `sw-header--line-style-dropdown` | Line Style Dropdown | 상태 + 기능 | 3열 선스타일 목록 | 26:11104 | | 유지 |
| S14 | `sw-header--text-dimension-style-dropdown` | Text · Dimension Style Dropdown | 상태 + 기능 | 문자·치수스타일 목록 | 26:11181 / 26:11215 | ○ | 유지 |
| S15 | `sw-header--responsive-more` | Responsive More | 기능 예제 | More 대표 필드 전환 | — | | 유지, S6과 통합 검토 |
| S16 | `sw-header--text-stroke` | Text Stroke | Figma 비교 · QA | 검정 외곽선 확대 비교 | 26:8944 | | 유지, QA 분류 검토 |
| S17 | `sw-header--layer-detail-input` | Layer Detail · Input | 상태 | 레이어 상세 버튼, `SWHeaderInput` | 26:10767 / 26:11656 | ○ | 이름 변경 검토(Input 중심) |
| S18 | `sw-header--dynamic-data` | Dynamic Data | 기능 예제 | 목록 추가·삭제·순서 | — | | 유지 |
| S19 | `sw-header--property-panel` | Property Panel | 기능 예제 | Header 연결 속성창, 폭 전환 | 26:11822 | ○ | 유지(대표) |
| S20 | `sw-header--property-panel-variants` | Property Panel Variants | 중복 검토 | 단독 패널 + 같은 조작 버튼 | 26:11822 | | 통합 검토(S27~S31) |
| S21 | `sw-header--k-guide` | K Guide | 상태(Motion) | K 버튼 가이드 반복 | 26:11698 / 26:11669 | | 유지 |
| S22 | `sw-header--additional-hover` | Additional Hover | QA · 중복 검토 | 상세 Hover·Selected·색상 기준 필수 선택 | — | ○ | 통합 검토(S1·S12) |
| S23 | `sw-header--property-bar` | Property Bar | 기능 예제 | 속성Bar 동적 편집 | 26:10492 | ○ | 유지 |
| S24 | `sw-header--dynamic-controls` | Dynamic Controls | 기능 예제 · 중복 검토 | `controls` allowlist | — | | 통합 검토(S26) |
| S25 | `sw-header--colorize` | Colorize | Figma 비교 | btn_colorize Default/Hover | 26:11302 / 26:11305 | ○ | 통합 검토(S12) |
| S26 | `sw-header--composition` | Composition (Visibility · Order) | 기능 예제 | `hiddenControls`, `menuOrder` | 26:8944 | | 유지 |
| S27 | `sw-header--property-panel-none` | Property Panel · 선택 없음 | 상태 | 26:11886 314×256 | 26:11886 | ○ | 유지 또는 S31로 통합 검토 |
| S28 | `sw-header--property-panel-all` | Property Panel · 전체 선택 | 상태 | 26:11823 314×361 | 26:11823 | ○ | 위와 같음 |
| S29 | `sw-header--property-panel-circle` | Property Panel · 원 1개 | 상태 | 26:11932 314×658 | 26:11932 | ○ | 위와 같음 |
| S30 | `sw-header--property-panel-expanded` | Property Panel · 모두 펼침 | 상태 | 26:12035 314×754 | 26:12035 | ○ | 위와 같음 |
| S31 | `sw-header--property-panel-compare` | Property Panel · 4개 비교 | Figma 비교 | 4상태 실측 비교 | 위 4개 | ○ | 유지 |
| S32 | `sw-header--property-shape-slot` | Property Panel · 형상 Slot | 기능 예제 | `shapeContent` | 26:11932 | | 유지 |
| S33 | `sw-header--property-fields` | Property Panel · 필드 13개 | Figma 비교 + 기능 | 필드 Default/Hover 표본 + 실제 조작 | 26:12388 ~ 26:12649 | ○ | 유지 |
### 사용 편의성 조사 결과
- **한 메뉴에 모두 있음:** 33개가 `SW / Header` 한 단계에 섞여 있습니다. 사용자용 예제(S2, S8, S9, S19, S23, S26)와 검증 화면(S1, S16, S22, S31)이 같은 목록에 나옵니다.
- **비슷한 Story가 흩어짐:** 속성창 관련 Story가 9개(S19, S20, S27~S33)이고 메뉴 순서상 S21~S26 사이에 끊겨 있습니다. 반응형(S6, S15)과 구성(S24, S26)도 떨어져 있습니다.
- **같은 디자인이 반복됨:** S3, S4는 S2와 같은 Header이고, S20은 S27~S30과 같은 4상태입니다. S22의 상세 Hover는 S1, 색상 기준은 S12에도 있습니다. S25 Colorize는 S12 안에서도 보입니다.
- **이름만으로 알기 어려움:** `Additional Hover`, `Dynamic Controls`, `Property Panel Variants`, `Layer Detail · Input`.
- **Default/Hover 확인:** 대부분 "Hover (고정)" 섹션이 있어 편합니다. 다만 섹션이 많은 Story(S10 18개, S11 13개)는 스크롤이 깁니다.
- **실험용 후보:** 명확한 실험 Story는 없습니다. S20, S22는 구현 시점의 검증 용도가 강합니다.
- **설명 형식:** Story 설명은 대부분 "Figma 노드 → 동작 → 데이터 소유" 순서입니다. 다만 S3, S4, S27~S30은 Story 머리말 설명이 없습니다(Args·개별 상태 Story).
## 3. 컴포넌트 구조와 재사용 관계
| 파일 | 줄 | 역할 | 사용하는 내부 모듈 |
|---|---|---|---|
| `SWHeader.tsx` | 461 | Header 조립 | 아래 대부분 |
| `SWHeaderField.tsx` / `SWHeaderFields.tsx` | 52 / 79 | 필드 버튼 공통 표면, 5개 필드 | Field, LayerIcons |
| `SWHeaderDropdown.tsx` | 156 | `useSWHeaderDropdown`(열기·키보드·바깥 클릭), `SWHeaderMenuDetail`(상세 버튼 공통), `SWHeaderColorChip` | — |
| `SWHeaderLayerMenu.tsx` | 264 | 레이어 필드 + 목록, **`SWHeaderLayerRows`(공유)** | Dropdown, Fields, LayerIcons |
| `SWHeaderColorMenu.tsx` | 211 | 색상 필드 + 목록, **`SWHeaderColorPanelBody`·`useSWHeaderColorMode`(공유)** | Dropdown, Fields, Input |
| `SWHeaderLineStyleMenu.tsx` | 192 | 선스타일 필드 + 목록, **`SWHeaderLineStyleColumns`·`SWHeaderLinePreview`(공유)** | Dropdown, Fields, Input |
| `SWHeaderStyleListMenus.tsx` | 150 | 문자·치수스타일 목록 | Dropdown, Fields |
| `SWHeaderInput.tsx` | 163 | 편집 Input, `parseSWHeaderColor`, `parseSWHeaderNumber` | — |
| `SWHeaderPropertyPanel.tsx` | 327 | 속성창, `useSWHeaderOverlay`(속성창·K 가이드 위치) | Input, LineStyleMenu, PropertyFields |
| `SWHeaderPropertyFields.tsx` | 221 | 속성창 레이어·선스타일·색상 필드 Dropdown | Layer/Color/LineStyle 공유 본문, Dropdown, Input |
| `SWHeaderPropertyBar.tsx` | 53 | 속성Bar | Input |
| `SWHeaderMore.tsx`, `SWHeaderKGuide.tsx`, `SWHeaderActions.tsx` | 118 / 77 / 26 | More, K 가이드, 인쇄·팝업 가이드 | KGuide → PropertyPanel(overlay) |
| `SWHeaderDocumentTitle.tsx`, `SWHeaderHome.tsx`, `SWHeaderWindowControls.tsx`, `SWHeaderProperties.tsx`, `SWHeaderLayerIcons.tsx` | 219 / 39 / 43 / 30 / 87 | 문서·홈·창 제어·상세보기 토글·레이어 아이콘 | — |
점검 결과:
- **사용하지 않는 Import/로컬:** 없음. `tsc --noUnusedLocals --noUnusedParameters`를 패키지와 앱 양쪽에서 확인했습니다.
- **사용하지 않는 CSS class:** 없음. `sw.css`의 174개 class가 모두 TSX에서 쓰이거나 `--${variant}` 형태로 동적으로 만들어집니다.
- **사용하지 않는 Token:** 없음. 108개 모두 `var()`로 참조됩니다.
- **같은 Selector가 반복됨:** 44건입니다. 대부분은 의도된 구조입니다. 같은 class를 `@container` 반응형, `prefers-reduced-motion`, keyframes 단계, 추가 수정 덮어쓰기에서 다시 선언합니다(예: `.hm-sw-header__document` 7회). 한곳으로 합치는 것은 광범위한 CSS 구조 변경이므로 R-C2로 남깁니다.
- **공통화가 덜 된 곳:**
- `SWHeaderLayerMenu`가 `useSWHeaderDropdown`과 거의 같은 열기·바깥 클릭·위치 계산을 따로 구현합니다. 2차원 화살표 키 이동 때문입니다.
- 속성Bar와 속성창이 같은 `parse` 규칙을 각자 갖고 있습니다. 속성창에만 `decimals`와 선스타일 목록 검사가 있어 동작이 다르므로, 합치면 속성Bar 동작이 바뀝니다.
- `useSWHeaderOverlay`는 폭 값 314/208로 사용처를 구분합니다.
- **공개 export 중 패키지 밖에서 쓰지 않는 Props 타입:** `SWHeaderMoreProps`, `SWHeaderMenuDetailProps` 등은 같은 파일 안에서만 쓰입니다. 공개 API이므로 그대로 둡니다.
### 자산
- 50개 중 48개가 코드나 CSS에서 쓰입니다.
- 미참조 2개: `color-pick.svg`는 `colorize-default.svg`와 바이트가 같은 중복이고, `dropdown-arrow.svg`도 쓰이지 않습니다. 둘 다 삭제하지 않았습니다(R-A1, R-A2).
- `src/sw/assets/figma-reference/header-26-8944.png`는 Text Stroke Story에서 이미지 블록을 뺀 뒤 참조가 없습니다. 원본 보존 지시에 따라 남겼습니다(R-A3).
- Text Stroke 상태: `sw.css`에 `-webkit-text-stroke` 선언이 없고 검정 `text-shadow`만 남아 있습니다.
- SVG 캔버스 배경 제거: 2026-10-19 후속 수정 상태 그대로이며, 이번에 변경하지 않았습니다.
## 4. 문서 목록 및 분류
| 문서 | 구분 | 상태 |
|---|---|---|
| `packages/sw/README.md` | 개요 + API 요약 | 날짜별 절이 쌓여 있음 → 상단에 현재 기준 색인 추가 |
| `docs/sw/sw-header-usage.md` (629줄) | 사용 가이드 + API + Storybook 안내 | 날짜별 절이 누적됨 → 색인 추가, 사실 오류 수정 |
| `docs/sw/sw-header-design-spec.md` (690줄대) | 디자인 명세 | Text Stroke 표 오류 수정, §18 속성 필드 추가, 색인 추가 |
| `sw-header-*-verification-2026-10-16.md` 11개 | 검증 보고(과거 기록) | 변경 없음 |
| `sw-header-firefox-range-close-…-2026-10-19.md`, `sw-header-followup-four-…-2026-10-19.md`, `sw-property-fields-verification-2026-10-19.md` | 검증 보고(현재) | 변경 없음 |
| `docs/sw/{detail-button,firefox-range,followup-four,property-close,property-fields}-qa/` | 증거 자료(PNG·JSON·log) | 변경 없음, 삭제 없음 |
| 이 문서 | 정리 보고 · 2차 검토표 | 신규 |
- 링크 검사: SW 문서 17개의 상대 링크와 앵커를 모두 확인했습니다. 이번 수정 전후 모두 깨진 링크가 없습니다.
- 문서가 겹치는 구조: README·사용 가이드·디자인 명세에 같은 주제(속성창, Text Stroke, 상세 버튼)가 날짜별로 여러 번 나옵니다. "최신 기준" 안내가 각 문서 상단에 4~6개 쌓여 있어, 어느 설명이 현재인지 찾기 어렵습니다. 1차에서는 색인만 추가했고, 재구성은 R-D1~R-D3입니다.
## 5. 1차에서 실제 수정한 내용
| 파일 | 수정 | 영향 |
|---|---|---|
| `src/sw/sw-header.stories.tsx` | Text Stroke Story 설명: 이미 제거된 자기 색 Stroke(0.3/0.4px)를 표시한다는 오래된 문구 수정 | 문구만 |
| 〃 | Color Dropdown 섹션 제목·설명의 "최신 예외 정책"을 날짜 기준으로 바꿈. "추출 버튼은 기존 정책 유지"를 실제 상태(btn_colorize Hover 26:11305)로 수정 | 문구만 |
| 〃 | Line Style Dropdown 섹션 설명의 "최신 요청"을 날짜 기준으로 바꿈 | 문구만 |
| 〃 | Story 전용 `hexToRgbText`를 지우고 공개 `parseSWHeaderColor`를 재사용 | 같은 결과(6자리 hex) |
| 〃 | `FIELD_FIXTURE`가 `PROPERTY_FIXTURE`를 다시 쓰던 것을 파생 방식으로 변경(다양함 행 + Figma 색상 예시만 덮어씀) | 표시 동일, 필드 테스트 77/77 재확인 |
| `packages/sw/src/theme/sw.css` | "Latest request" 주석 3개를 날짜 기준 주석으로 바꿈 | 주석만 |
| `packages/sw/src/components/sw-header/components/SWHeaderColorMenu.tsx` | 같은 주석 1개를 날짜 기준으로 바꾸고 칩·추출 버튼 Hover 상태를 정확히 적음 | 주석만 |
| `docs/sw/sw-header-design-spec.md` | §6.1 표·토큰 표에서 제거된 `-webkit-text-stroke-width`·`--hm-sw-header-text-stroke-width`·`--hm-sw-header-solid-stroke-width`를 현재 상태로 수정. §18 속성 필드 13개 추가. 상단 색인 추가 | 문서 |
| `docs/sw/sw-header-usage.md` | Text Stroke 문단의 자기 색 Stroke·제거된 변수 설명 수정. §12에 현재 33개 안내 추가. 상단 색인 추가 | 문서 |
| `packages/sw/README.md` | Text Stroke·독립 버튼 Hover의 오래된 문구에 현재 상태 보충. 2026-10-19 속성 필드·게이지 절 추가. 상단 색인 추가 | 문서 |
| `docs/sw/sw-first-pass-cleanup-review-2026-10-19.md` | 이 보고서 | 신규 |
Story ID, 메뉴 이름, Story 수(33), 공개 export, Props, 컴포넌트 렌더링, CSS 규칙, 자산은 바꾸지 않았습니다.
## 6. 변경하지 않고 보류한 내용
- Story 삭제·이름 변경·분류(`SW/Header/...` 하위 그룹) 이동·통합
- 과거 검증 보고서 본문(당시 기록이므로 오래된 Stroke 설명이 있어도 그대로 둠)
- 사용 가이드·명세의 날짜별 절 재구성
- 미참조 자산 2개와 비교 PNG 1개의 삭제·이동
- CSS 중복 Selector 합치기, Dropdown 위치 계산 공통화, parse 공통화
- 섹션이 없는 Story(S3, S4, S27~S30)의 머리말 형식 통일(내용 추가가 필요해 2차로 넘김)
## 7. SAFE / REVIEW REQUIRED
**KEEP:** 위 컴포넌트 전부, 사용 중인 자산 48개, 33개 Story, 검증 보고 14개, 증거 폴더 5개, 테스트 스크립트 5개.
**SAFE (이번에 적용함):** §5 표의 항목. 모두 문구·주석·Story 내부 데이터 정의만 바꿨고, 실제 참조를 확인했습니다.
**REVIEW REQUIRED (손대지 않음):** 아래 §8의 R 번호 항목.
## 8. 2차 검토 목록
번호나 파일명을 지정해 주시면 2차에서 그 항목만 진행합니다. "판단"은 사용자 결정이 필요한 종류입니다.
| 번호 | 구분 | 현재 이름/경로 | 현재 역할 | 권장 정리 | 판단 | 영향도 |
|---|---|---|---|---|---|---|
| R-S1 | Storybook | 33개 전체 (`SW / Header`) | 한 단계 메뉴 | `SW/Header/기본`, `/Dropdown`, `/속성창`, `/구성·반응형`, `/QA` 하위 그룹. Story ID가 바뀌므로 테스트 스크립트·baseline 갱신이 필요 | 분류 변경 검토 | 중간 |
| R-S2 | Storybook | S3 `sw-header--default`, S4 `sw-header--controls` | Args 예제 | 하나로 통합(Controls 패널이 있는 1920 프레임). 테스트가 두 ID를 사용 | 통합 검토 | 낮음 |
| R-S3 | Storybook | S20 `sw-header--property-panel-variants` | 단독 4상태 + 조작 버튼 | S27~S31과 겹침. 삭제하거나 S31에 조작 버튼 합치기 | 통합 / 삭제 검토 | 낮음 |
| R-S4 | Storybook | S22 `sw-header--additional-hover` | 추가 수정 검증 | 상세 Hover는 S1, 색상 기준 필수 선택은 S12로 옮기기. 테스트 사용 | 통합 검토 | 낮음 |
| R-S5 | Storybook | S25 `sw-header--colorize` | btn_colorize 비교 | S12 Color Dropdown의 섹션으로 합치기. 테스트 사용 | 통합 검토 | 낮음 |
| R-S6 | Storybook | S24 `sw-header--dynamic-controls`, S26 `sw-header--composition` | 구성 API 2종 | 한 Story에 `controls` / `hiddenControls`·`menuOrder` 섹션으로 정리 | 통합 검토 | 낮음 |
| R-S7 | Storybook | S6 `sw-header--responsive`, S15 `sw-header--responsive-more` | 반응형 | 이웃 배치 또는 통합 | 분류 변경 검토 | 낮음 |
| R-S8 | Storybook | S17 `Layer Detail · Input` | 상세 버튼 + Input | `Editable Input` 등 이름 변경. 상세 버튼 부분은 S1과 겹침. 테스트 사용 | 이름 변경 검토 | 낮음 |
| R-S9 | Storybook | S1 `Detail Buttons`, S16 `Text Stroke`, S31 `4개 비교` | 검증 화면 | QA 그룹으로 이동(R-S1과 함께) | 분류 변경 검토 | 낮음 |
| R-S10 | Storybook | S10 `Document Dropdown`(18개 섹션), S11 `Layer Dropdown`(13개 섹션) | 상태 전체 | 상태 섹션과 Callback·예외 섹션으로 나누기 | 통합 / 분할 검토 | 낮음 |
| R-S11 | Storybook | S3, S4, S27~S30 | 머리말 없음 | 다른 Story와 같은 "Figma 노드 · 동작 · 데이터" 머리말 추가 | 이름·설명 검토 | 낮음 |
| R-C1 | Component | `packages/sw/src/components/sw-header/components/SWHeaderLayerMenu.tsx` | 레이어 Dropdown 동작 | 열기·바깥 클릭·위치 계산을 `useSWHeaderDropdown`으로 합치고 2차원 키 이동만 남기기 | 통합 검토 | 중간 |
| R-C2 | Component(CSS) | `packages/sw/src/theme/sw.css` | 전체 스타일 | 같은 Selector가 여러 곳에서 덮어쓰는 영역(문서·창·More·Motion) 정리, 날짜별 추가 절을 컴포넌트 절로 재배치 | 구조 변경 검토 | 중간 |
| R-C3 | Component | `SWHeaderPropertyBar.tsx` / `SWHeaderPropertyPanel.tsx` | 같은 parse 규칙 2벌 | 공통 parse로 합치기. 속성Bar도 `decimals`를 따르게 되는 동작 변경 | 통합 검토 | 낮음 |
| R-C4 | Component | `SWHeaderPropertyPanel.tsx` `useSWHeaderOverlay` | 속성창·K 위치 | 폭 314/208로 사용처를 판별하던 방식을 명시적 옵션으로 바꾸기 | 구조 변경 검토 | 낮음 |
| R-C5 | Component | `SWHeader.tsx` (461줄) | Header 조립 | 구성·반응형 계산 분리 검토(렌더링 구조 변경) | 구조 변경 검토 | 중간 |
| R-A1 | Asset | `packages/sw/src/assets/color-pick.svg` | 미참조, `colorize-default.svg`와 같은 파일 | 삭제 | 삭제 검토 | 낮음 |
| R-A2 | Asset | `packages/sw/src/assets/dropdown-arrow.svg` | 미참조 | 삭제 또는 사용처 확인 | 삭제 검토 | 낮음 |
| R-A3 | Asset | `src/sw/assets/figma-reference/header-26-8944.png` | 미참조 Figma 원본 | 보존 위치를 `docs/sw` 증거로 옮기거나 유지 | 유지 권장 / 이동 검토 | 낮음 |
| R-D1 | Document | `docs/sw/sw-header-usage.md` | 사용 가이드 | 날짜별 절을 기능별 장(설치·Props·Dropdown·속성창·구성·Storybook)으로 재구성, 날짜 기록은 변경 이력 절로 | 통합 검토 | 낮음 |
| R-D2 | Document | `docs/sw/sw-header-design-spec.md` | 디자인 명세 | 같은 방식으로 재구성, 상단 안내 6개를 색인 하나로 | 통합 검토 | 낮음 |
| R-D3 | Document | `packages/sw/README.md` | 개요 | 날짜별 절을 요약 한 페이지 + 문서 링크로 줄이기 | 통합 검토 | 낮음 |
| R-D4 | Document | `docs/sw/sw-header-*-verification-2026-10-16.md` 11개 | 과거 검증 | `docs/sw/verification/` 하위로 이동(링크 갱신 필요) | 분류 변경 검토 | 낮음 |
| R-D5 | Document | `docs/sw/*-qa/` 5개 | 증거 | `docs/sw/evidence/` 하위로 이동(테스트 기본 출력 경로 갱신 필요) | 분류 변경 검토 | 낮음 |
### 2차 우선순위 제안
1. R-S1 메뉴 분류. 사용자가 가장 자주 보는 부분이며, R-S9도 같이 해결됩니다.
2. R-S2 ~ R-S6 중복 Story 통합. 테스트 ID 갱신이 함께 필요합니다.
3. R-D1 ~ R-D3 문서 재구성.
4. R-A1, R-A2 미참조 자산 삭제.
5. R-C1 ~ R-C5 코드 구조. 디자인 회귀 검증을 다시 해야 하므로 마지막에 둡니다.
## 9. 기존 PASS 결과 영향 여부
| 기존 결과 | 이번 영향 | 처리 |
|---|---|---|
| 구성 시나리오 77/77, 기본 Header 10개 폭 비교 | 코드·CSS 규칙 변경 없음 | 기존 PASS 재사용(재실행 안 함) |
| Header 브라우저 검증 271건 | 같은 이유 | 기존 PASS 재사용 |
| Chrome/Firefox 게이지바 | 같은 이유 | 기존 PASS 재사용 |
| 속성 필드 77/77 | Story fixture를 바꿨으므로 영향 있음 | 이번에 재실행 |
| detail-buttons verify(33개 Story ID·상세 버튼 상태) | Story 파일을 수정함 | 이번에 재실행 |
| Typecheck / Build / Storybook Build | 주석·Story 수정 | 이번에 재실행 |
이번 실행 결과는 커밋 메시지와 최종 보고에 적습니다.
## 10. 미검증 사항
- Firefox에서 Storybook을 다시 보지 않았습니다(CSS 규칙 변경 없음).
- 구성 시나리오 77개, 10개 폭 비교, Header 271건은 다시 실행하지 않았고 기존 PASS를 재사용합니다.
- 문서 재구성 후의 가독성은 2차 결정 사항이라 평가하지 않았습니다.
+18 -6
View File
@@ -1,5 +1,7 @@
# SW Header 디자인 명세
> **현재 기준 색인(2026-10-19 1차 정리):** 아래 날짜별 안내 중 최신 항목이 같은 주제의 이전 본문보다 우선합니다. 주제별 최신 근거는 속성 필드 13개 [§18](#18-속성창-입력선택-필드-2026-10-19), 게이지·속성Bar·도구 아이콘 [후속 4건 기록](./sw-header-followup-four-design-fixes-verification-2026-10-19.md), Firefox 게이지·닫기 버튼 [기록](./sw-header-firefox-range-close-verification-2026-10-19.md), 상세 버튼 공통화 [기록](./sw-header-detail-buttons-verification-2026-10-16.md), 구성·메뉴 순서·형상 Slot [3차 기준](#3차-기준--구성요소-표시메뉴-순서속성창-상태형상-slot-2026-10-16)입니다. Text Stroke는 검정 외곽선만 적용하며 자기 색 Stroke는 없습니다([§6.1](#61-text-stroke-2026-10-16)). 문서·Storybook 전체 현황과 2차 검토 목록은 [1차 정리 보고](./sw-first-pass-cleanup-review-2026-10-19.md)를 봅니다.
> **후속 디자인 수정 4건(2026-10-19):** 속성Bar는 Figma 1222px 고정 폭 대신 마지막 필드에서 끝나는 콘텐츠 폭(공간 부족 시 내부 스크롤)을 사용합니다. 속성창 도구 아이콘 SVG의 Figma 캔버스 배경을 제거했고, 레이어·색상·문자·치수스타일 필드는 자기 Dropdown이 열린 동안 Hover를 적용하지 않으며, 게이지는 빨강 채움 + 베이지 Track입니다. 아래 26:10492의 "최대 1222" 설명보다 우선합니다. [검증 기록](./sw-header-followup-four-design-fixes-verification-2026-10-19.md).
> **상세 버튼 공통화 기준(2026-10-16, 이번 요청):** 상세 5개는 기존 `SWHeaderMenuDetail`을 공유하며 **현재 문자스타일 상세**를 우선합니다. Default는 배경 `rgba(197,177,158,.15)`·radius 24·글자 35%·아이콘 SVG 20%, Hover는 배경 .25·radius 25·글자 35%·아이콘 SVG 35%입니다. Disabled는 Default 외형과 클릭 차단을 사용합니다. Callback이 없어도 Hover되며 클릭은 무동작입니다. 치수 상세의 글자 100% Hover와 Callback 부재에 따른 비활성 설명은 이 기준으로 대체합니다. 기존 폭 113/99/128/142/142px·높이 24px, 제거된 Text Stroke 선언을 유지합니다. 과거 검증 문서는 당시 기록으로 보존합니다. [이번 검증 기록](./sw-header-detail-buttons-verification-2026-10-16.md).
@@ -237,17 +239,17 @@ Figma Plugin API로 26:8944와 메뉴 8개·문서·레이어 Component Set의
| 영역 | Figma 구조 | 구현 |
|---|---|---|
| 14px 값(파일명, 그리기모드, 레이어·색상·선/문자/치수 값, 가중치·스케일 값, 속성Bar·속성창, 문서·레이어 목록 이름, 새 Dropdown 행·ByLayer/ByBlock) | 같은 글자 2층: 아래층 검정 Stroke 1.3px, 위층 채움 + 같은 색 Stroke 0.3px | `text-shadow` 16방향 1.3px 검정 원(`--hm-sw-header-text-outline`) + `-webkit-text-stroke-width: 0.6px`(가운데 정렬 → 바깥 0.3px, `currentColor`) |
| 16px 글꼴 미리보기(필드·문자스타일 행) | 14px과 같음(1.3 + 0.3) | 같음 |
| 14px 값(파일명, 그리기모드, 레이어·색상·선/문자/치수 값, 가중치·스케일 값, 속성Bar·속성창, 문서·레이어 목록 이름, 새 Dropdown 행·ByLayer/ByBlock) | 같은 글자 2층: 아래층 검정 Stroke 1.3px, 위층 채움 + 같은 색 Stroke 0.3px | `text-shadow` 16방향 1.3px 검정 원(`--hm-sw-header-text-outline`). 자기 색 0.3px Stroke는 2026-10-16 추가 수정으로 제거 |
| 16px 글꼴 미리보기(필드·문자스타일 행) | 14px과 같음(1.3 + 0.3) | 14px과 같음(검정 1.3px만) |
| 12px 라벨(레이어·색상·선스타일·가중치·스케일·문자스타일·치수스타일·상세보기) | 채움 + 검정 Stroke 1px | `--hm-sw-header-label-outline`(1px 검정 16방향), 자기 색 Stroke 없음 |
| 수정 가능 글자(색상·가중치·스케일·상세 Input) | 아래층 검정 1.3px + 위층 `#E60403` 0.3px | 14px과 같음(`SWHeaderInput`) |
| `… 상세` pill(레이어·색상·선/문자/치수) | 흰색 + 흰색 Stroke 0.4px, 검정 없음, 35% | `-webkit-text-stroke-width: 0.8px`(바깥 0.4px) |
| 수정 가능 글자(색상·가중치·스케일·상세 Input) | 아래층 검정 1.3px + 위층 `#E60403` 0.3px | 14px과 같음(`SWHeaderInput`). 속성창 행 입력은 Default·Hover 외곽선 없음, On(편집·Dropdown)에서만 외곽선([§18](#18-속성창-입력선택-필드-2026-10-19)) |
| `… 상세` pill(레이어·색상·선/문자/치수) | 흰색 + 흰색 Stroke 0.4px, 검정 없음, 35% | 미적용: 자기 색 0.4px Stroke 선언과 `--hm-sw-header-solid-stroke-width`는 2026-10-16 후속 수정으로 제거 |
| `+ New` / `Open` | 검정 70% + 검정 0.4px | **미적용**(2026-10-16 추가 요청: 두 버튼은 기존 상태 유지) |
| 더보기 메뉴, 창 이동 Tooltip | Figma에 없음 / Stroke 없음 | 미적용 |
- `-webkit-text-stroke` 단독은 획 중심 기준이라 글자 안쪽을 깎으므로 검정 외곽선은 `text-shadow`로 그립니다(글자 뒤, 글자 모양을 덮지 않음). Hover·Selected·행 Hover는 채움색만 바뀌고 외곽선은 검정 그대로입니다. Input의 caret·선택 영역은 shadow 위에 그려져 가려지지 않습니다.
- 말줄임 텍스트(`overflow`)는 `overflow: clip` + `overflow-clip-margin: 2px`로 외곽선이 상자 경계에서 잘리지 않게 했습니다(`overflow-clip-margin` 미지원 Safari 등에서는 가장자리 1px 내외가 잘릴 수 있음 — NOT VERIFIED).
- 글꼴·크기·자간·기준선·Font Weight(400/700)는 바꾸지 않았습니다. Figma는 Dotum Regular + Stroke로 굵기를 표현하고 구현은 Noto Sans KR 700 + 같은 Stroke이므로, 구현 글자가 Figma보다 약간 굵게 보입니다(남은 차이, `--hm-sw-header-text-stroke-width`로 조정 가능).
- 글꼴·크기·자간·기준선·Font Weight(400/700)는 바꾸지 않았습니다. Figma는 Dotum Regular + Stroke로 굵기를 표현하고 구현은 Noto Sans KR 700 + 같은 Stroke이므로, 구현 글자가 Figma보다 약간 굵게 보입니다(남은 차이. 조정 변수였던 `--hm-sw-header-text-stroke-width`는 2026-10-16 추가 수정으로 제거).
- 레이어 Dropdown 이름·레이어 상세에도 같은 기준이 적용됩니다(CSS만, 레이어 컴포넌트·매핑 코드는 변경 없음).
## 7. Color · Gradient
@@ -560,7 +562,7 @@ Composed Controls의 기존 레이어·색상·상세보기 예제는 보존하
| `--hm-sw-header-window-icon-color` | `#ADB0AF` | 최소화 막대 |
| `--hm-sw-header-window-button-hover-background` / `-window-icon-hover-color` | `rgba(0,0,0,.2)` / `#FFF` | 최소화 Hover(Figma 26:12159). 종료 Hover는 Figma SVG(`close-hover.svg`) |
| `--hm-sw-header-text-outline-color` / `-text-outline` / `-label-outline` | `#000` / 1.3px 16방향 / 1px 16방향 | Text Stroke 검정 외곽선(§6.1) |
| `--hm-sw-header-text-stroke-width` / `-solid-stroke-width` / `-text-outline-room` | 0.6px / 0.8px / 2px | 자기 색 Stroke(바깥 0.3 / 0.4px), 말줄임 상자 외곽선 여유 |
| `--hm-sw-header-text-outline-room` | 2px | 말줄임 상자 외곽선 여유. 이전 `--hm-sw-header-text-stroke-width`(0.6px) / `-solid-stroke-width`(0.8px)는 2026-10-16 제거 |
| `--hm-sw-header-menu-divider-color` / `-menu-divider-strong-color` | `rgba(197,177,158,.15)` / `.25` | 새 Dropdown 열 구분선·하단 테두리(§5.3) |
| `--hm-sw-header-menu-list-max-height` / `-color-palette-max-height` | 240px / 118px | 긴 목록·사용자 색상 내부 스크롤 시작(구현값) |
| `--hm-sw-header-color-mode-color` / `-color-mode-background` / `-color-mode-on-background` | `#D4CBBD` / `rgba(98,83,61,.3)` / `#62533D` | ByLayer / ByBlock |
@@ -681,3 +683,13 @@ SW Header는 Figma Node 26:8944를 기준으로 구현한다. 사용자가 확
- **속성창 4상태:** 26:11886 314×256, 26:11823 314×361, 26:11932 314×658, 26:12035 314×754 — 같은 SWHeaderPropertyPanel과 데이터로 구성하며 Storybook 실측이 일치합니다.
- **형상 Slot:** Figma 26:11932 `Group 2937`(219×260) 안 `Group 2920` 208×208 그림 영역을 `.hm-sw-property__shape`(그룹 콘텐츠 기준 39, 26)로 분리했습니다. 기본 내용은 기존 Figma 원형 SVG(`property-circle.svg`)입니다. 비움·외부 컴포넌트에도 라벨 위치와 패널 높이는 같습니다.
- **Figma와 남은 차이(기존 구현 유지):** Figma 라벨 x 위치는 원주 111.5/지름 102/반지름 152.5/면적 98.5이고 구현은 113/100/154/100(1~2px, 기존 값), 지름 y는 Figma 108·구현 110입니다. 이번 범위에서 값 변경은 하지 않았습니다.
## 18. 속성창 입력·선택 필드 (2026-10-19)
Figma 26:12388 ~ 26:12649의 필드 13개 상태입니다. 상세 수치·검증은 [속성 필드 검증 기록](./sw-property-fields-verification-2026-10-19.md)을 따릅니다.
- 공통 행 필드: 200 × 28, radius 2. Default는 값만, Hover는 `1px rgba(33,29,19,.4)`. 테두리는 Default에도 투명 1px로 있어 상태가 바뀌어도 값이 움직이지 않습니다.
- 숫자 편집 On(선축적 26:12314, 두께 26:12590, 선가중치·투명도 26:12649): `#0F0D0A`, 단위 흰색, 값 검정 외곽선, 빨간 caret. 선가중치·투명도 값은 41px 내외 Hug(pl 6 / pr 4).
- Dropdown On(레이어 26:12265 / 26:12291, 선스타일 26:12404, 색상 26:12184): `#211D13`. 레이어·선스타일 목록은 필드 오른쪽 끝, 색상 목록은 왼쪽 끝에 맞춰 필드 바로 아래에 열립니다. 목록 내용은 Header Dropdown과 같은 공유 컴포넌트입니다.
- 하이퍼링크(26:12583)·재료(26:12574)는 Figma에 On이 없어 Default·Hover만 적용합니다.
- 색상 26:12170의 `255,259,0`은 Figma 표기 예시이며 입력 검증은 0~255를 유지합니다.
+5 -1
View File
@@ -1,5 +1,7 @@
# SW Header 사용 가이드
> **현재 기준 색인(2026-10-19 1차 정리):** 아래 날짜별 안내 중 최신 항목이 같은 주제의 이전 설명보다 우선합니다. 속성 필드 13개·필드 Dropdown(`picker`·`menus`·`decimals`)은 [속성창·K 가이드 추가 연결](#속성창k-가이드-추가-연결-2026-10-16)의 2026-10-19 항목, 표시·숨김(`hiddenControls`)·메뉴 순서(`menuOrder`)·속성창 4상태·형상 Slot은 [3차 절](#구성요소-표시메뉴-순서속성창-4상태형상-slot-2026-10-16-3차), 속성Bar·`controls`·Colorize는 [후속 절](#후속-5개-요구사항-연결-2026-10-16)을 봅니다. 현재 Storybook 33개 목록은 [§12](#12-storybook)와 [1차 정리 보고](./sw-first-pass-cleanup-review-2026-10-19.md)에 있습니다.
> **상세 버튼 최신 기준(2026-10-16):** 레이어·색상·선·문자·치수 상세는 문자스타일 디자인의 `SWHeaderMenuDetail`을 공통 사용합니다. `on*Detail` 미전달 시 Hover 유지·클릭 무동작이며, Callback 전달 시 기존 1회 호출·닫힘·Focus 복귀를 유지합니다. 내부 공통 컴포넌트는 `label`, `icon`, `onClick`, `disabled`, `className`, `aria-label` 등 native 버튼 Props를 지원합니다. 새 공개 export는 추가하지 않았습니다. 비교 Story는 `SW/Header → Detail Buttons (Shared States)`(verification 태그, 직접 ID `sw-header--detail-buttons`)입니다. 과거의 Callback 미전달=Disabled 및 치수만 밝은 Hover 설명보다 이 기준이 우선합니다. [이번 검증 기록](./sw-header-detail-buttons-verification-2026-10-16.md).
> **3차 기준(2026-10-16):** 로고 외 개별 제거 `hiddenControls`, 유사 메뉴 순서 `menuOrder`, 속성창 4상태 Story·비교, 형상 Slot `shapeContent`를 추가했습니다. [3차 절](#구성요소-표시메뉴-순서속성창-4상태형상-slot-2026-10-16-3차)과 [3차 검증 기록](./sw-header-composition-shape-verification-2026-10-16.md)이 같은 주제의 이전 설명보다 우선합니다.
@@ -415,7 +417,7 @@ import type { CSSProperties } from "react"
- Focus: 키보드 Focus 윤곽선은 Hover 테두리 위에 표시됩니다.
- Hover 테두리 색은 `--hm-sw-header-hover-border-gradient` 토큰, 최소화 Hover 배경·막대 색은 `--hm-sw-header-window-button-hover-background` / `--hm-sw-header-window-icon-hover-color` 토큰으로 바꿀 수 있습니다. 종료·인쇄·팝업 가이드 Hover 아이콘은 패키지 SVG Asset입니다. 대상·제외 목록은 [디자인 명세 §11.1](./sw-header-design-spec.md#111-hover-테두리-공통-상호작용-규칙)을 따릅니다.
- Text Stroke(2026-10-16): Figma에 Stroke가 있는 헤더·Dropdown 텍스트는 검정 외곽선(14·16px 1.3px, 12px 라벨 1px)과 자기 색 0.3px Stroke를 표시합니다. Hover·Selected는 채움색만 바뀌고 외곽선은 유지됩니다. 더보기 메뉴·창 이동 Tooltip은 Figma에 Stroke가 없어 적용하지 않고, `+ New` / `Open`은 요청에 따라 기존 그대로입니다. 외곽선 색·굵기는 `--hm-sw-header-text-outline-color`, `--hm-sw-header-text-stroke-width` 등으로 바꿀 수 있습니다([명세 §6.1](./sw-header-design-spec.md#61-text-stroke-2026-10-16)).
- Text Stroke(2026-10-16): Figma에 Stroke가 있는 헤더·Dropdown 텍스트는 검정 외곽선(14·16px 1.3px, 12px 라벨 1px)을 표시합니다(자기 색 0.3px Stroke는 2026-10-16 추가 수정으로 제거). Hover·Selected는 채움색만 바뀌고 외곽선은 유지됩니다. 더보기 메뉴·창 이동 Tooltip은 Figma에 Stroke가 없어 적용하지 않고, `+ New` / `Open`은 요청에 따라 기존 그대로입니다. 외곽선 색은 `--hm-sw-header-text-outline-color`, 외곽선 전체는 `--hm-sw-header-text-outline` / `--hm-sw-header-label-outline`으로 바꿀 수 있습니다(`--hm-sw-header-text-stroke-width`는 제거됨)([명세 §6.1](./sw-header-design-spec.md#61-text-stroke-2026-10-16)).
## 10.2 창 이동 Hover Motion
@@ -450,6 +452,8 @@ Tooltip은 45 × 17px, 검정 80% 배경과 흰색 12px/400 글자입니다. Too
npm run storybook
```
현재(2026-10-19) `SW / Header`에는 33개 Story가 있습니다. Story ID·분류·용도 전체 표는 [1차 정리 보고 §2](./sw-first-pass-cleanup-review-2026-10-19.md#2-storybook-전체-목록-및-분류)를 봅니다. 아래 문단은 Story를 추가한 시점별 설명입니다.
`SW / Header` 아래 Story: Overview, Default, Controls, Interactive States(인쇄·팝업 가이드·최소화·종료 Default/Hover 비교와 Callback 기록 포함), Responsive, Composed Controls, Logo Slot(기본 임시 로고 / 사용자 지정 로고 / 로고 미전달), Document Dropdown(Default / Hover / Open / 선택 / 여러 문서 / 문서 없음 / 긴 파일명 / 좁은 화면), Layer Dropdown(Layer Default / Hover / Open(Figma 8행) / Row Hover / 전구·눈꽃·자물쇠 4상태 3배 확대 / 선택·Toggle Callback 기록과 상태표 / 여러 상태·현재 레이어 / 긴 레이어명 / 20개 스크롤 / 레이어 없음 / 레이어 상세 / 상태 표시 전용 / 좁은 화면 1440–390). Responsive Story는 헤더 폭 18개(1920–390, 각 단계 경계 전후 포함) 프레임을 나열합니다. 모든 단계가 헤더 폭 기준이므로 Viewport를 바꾸지 않아도 확인할 수 있습니다.
`Window Move Motion`은 GIF 주요 3상태와 속도 변경 후 약 0 / 205 / 410 / 444 / 683 / 888 / 1366 / 1400ms 프레임, 실제 Hover·Drag·최소화·종료 Callback 및 반복(`motion cycle`) 기록, 축소 폭 예제를 제공합니다. 내부 고정 시간은 원본 GIF 시간 × 1400/1640의 정확한 값입니다. 고정 프레임은 Storybook 전용 Hover attribute와 Web Animations API로 시간을 멈춥니다. Reduced Motion에서는 기본 아이콘·정적 Tooltip 정책을 따르므로 정상 타임라인 비교는 해당 설정을 끄고 Story를 다시 로드합니다.
+11 -3
View File
@@ -1,5 +1,7 @@
# @hm-design/sw
> **현재 기준 색인(2026-10-19 1차 정리):** 아래 날짜별 안내는 작성 당시 기록입니다. 현재 기준은 [사용 가이드](../../docs/sw/sw-header-usage.md), [디자인 명세](../../docs/sw/sw-header-design-spec.md) 상단 색인, 속성 필드 13개 [검증 기록](../../docs/sw/sw-property-fields-verification-2026-10-19.md), 게이지·속성Bar [후속 4건 기록](../../docs/sw/sw-header-followup-four-design-fixes-verification-2026-10-19.md)·[Firefox 게이지 기록](../../docs/sw/sw-header-firefox-range-close-verification-2026-10-19.md)입니다. Storybook은 `SW / Header` 33개 Story이며 전체 목록과 2차 검토 대상은 [1차 정리 보고](../../docs/sw/sw-first-pass-cleanup-review-2026-10-19.md)에 있습니다.
> **3차 구현(2026-10-16):** `hiddenControls`(로고 외 모든 구성요소 개별 제거, 로고 필수), `menuOrder`(레이어·색상·선/문자/치수스타일 순서), 속성창 `shapeContent` Slot, 속성창 4상태 개별·비교 Story를 추가했습니다. 미지정 시 기존 디자인과 같습니다. [사용법](../../docs/sw/sw-header-usage.md#구성요소-표시메뉴-순서속성창-4상태형상-slot-2026-10-16-3차), [3차 검증 기록](../../docs/sw/sw-header-composition-shape-verification-2026-10-16.md).
> **후속 구현(2026-10-16):** 속성Bar(`SWHeaderPropertyBar`), 메뉴 단위 `controls` allowlist, Colorize 원본 Default/Hover를 추가했습니다. 상세 pill의 미사용 Stroke 선언·변수는 원본에서 제거했습니다. [사용법](../../docs/sw/sw-header-usage.md#후속-5개-요구사항-연결-2026-10-16), [새 검증 기록](../../docs/sw/sw-header-followup-five-verification-2026-10-16.md)을 따릅니다. 이전 설명과 PASS 로그는 보존합니다.
@@ -24,7 +26,7 @@ import "@hm-design/sw/styles.css"
- Hover는 Figma 홈 버튼의 노란 gradient 1px 테두리를 SW Header의 테두리 있는 버튼에 공통 적용합니다(디자인 명세 §11.1).
- 창 이동 Hover Motion은 GIF의 경로를 유지하고 후속 사용자 요청으로 1.64 → **1.4초**로 단축했습니다. 커서 상승 → 약 444ms 문구 등장 → 오른쪽 위로 이동 → 약 888ms부터 512ms 유지 → 반복입니다. 기존 SVG·줄무늬·Tooltip·`onWindowMoveStart`·Drag 중 정지·Reduced Motion·88px/24px/숨김 정책은 유지합니다. 실제 창 이동은 호스트 책임이며 [사용 가이드 §10.2](../../docs/sw/sw-header-usage.md#102-창-이동-hover-motion), [현재 검증 기록](../../docs/sw/sw-header-speed-composed-hover-verification-2026-10-16.md)을 따릅니다.
- 그룹 필드 Hover는 텍스트와 선/폰트/치수 미리보기를 `#FFC600`으로 표시합니다. 기존 Gradient Border·검정 외곽선·색상 견본·레이어 상태·Disabled/Selected 정책을 유지하며 상세보기는 기존 텍스트 전용 Hover 그대로입니다([명세 §11.5](../../docs/sw/sw-header-design-spec.md#115-현재-추가-기준--1400ms-및-그룹-필드-hover-2026-10-16)).
- 색상·선스타일·문자스타일·치수스타일 Dropdown(2026-10-16, Figma 26:10986 / 26:11036 / 26:12666 / 26:12659 / 26:11104 / 26:10702 / 26:11181 / 26:11215): `colors`·`userColors`·`colorMode`, `lineTypes`·`lineWeights`, `textStyles`, `dimensionStyles`를 주면 각 필드가 Dropdown이 됩니다(주지 않으면 기존 버튼). 모든 항목은 `id` 기반 배열 Props이며 추가·삭제·이름/값 변경·재정렬에 소스 수정이 필요 없습니다. 선택·입력은 `onColorSelect` / `onColorModeChange` / `onColorInput` / `onColorPick`, `onLineTypeSelect` / `onLineWeightSelect` / `onLineWeightValueChange` / `onLineScaleChange`, `onTextStyleSelect`, `onDimensionStyleSelect`, 하단 `… 상세`는 `on*Detail`로 각 프로그램이 연결합니다(상세 팝업은 미제공). Dropdown 안 독립 버튼은 Hover 효과가 없고 목록 행·Input은 Figma Hover를 유지합니다([명세 §5.3](../../docs/sw/sw-header-design-spec.md#53-색상--선스타일--문자스타일--치수스타일-dropdown-2026-10-16), [사용 가이드 §7](../../docs/sw/sw-header-usage.md#색상--선문자치수스타일-dropdown-예-2026-10-16)).
- 색상·선스타일·문자스타일·치수스타일 Dropdown(2026-10-16, Figma 26:10986 / 26:11036 / 26:12666 / 26:12659 / 26:11104 / 26:10702 / 26:11181 / 26:11215): `colors`·`userColors`·`colorMode`, `lineTypes`·`lineWeights`, `textStyles`, `dimensionStyles`를 주면 각 필드가 Dropdown이 됩니다(주지 않으면 기존 버튼). 모든 항목은 `id` 기반 배열 Props이며 추가·삭제·이름/값 변경·재정렬에 소스 수정이 필요 없습니다. 선택·입력은 `onColorSelect` / `onColorModeChange` / `onColorInput` / `onColorPick`, `onLineTypeSelect` / `onLineWeightSelect` / `onLineWeightValueChange` / `onLineScaleChange`, `onTextStyleSelect`, `onDimensionStyleSelect`, 하단 `… 상세`는 `on*Detail`로 각 프로그램이 연결합니다(상세 팝업은 미제공). Dropdown 안 독립 버튼은 Hover 효과가 없고 목록 행·Input은 Figma Hover를 유지합니다(이후 2026-10-16 추가 수정: ByLayer/ByBlock·`… 상세` 버튼은 Figma Hover 적용, 색상 추출은 Colorize Hover, 색상 칩은 Hover 없음)([명세 §5.3](../../docs/sw/sw-header-design-spec.md#53-색상--선스타일--문자스타일--치수스타일-dropdown-2026-10-16), [사용 가이드 §7](../../docs/sw/sw-header-usage.md#색상--선문자치수스타일-dropdown-예-2026-10-16)).
```tsx
<SWHeader
@@ -38,7 +40,7 @@ import "@hm-design/sw/styles.css"
/>
```
- 반응형 More: 좁은 헤더에서 더보기의 필드를 고르면 그 필드가 첫 칸(레이어 자리)에 표시되고 Dropdown이 바로 아래 열립니다. 레이어는 더보기에서 다시 고를 수 있으며, 전환은 UI 상태라 데이터 Callback을 호출하지 않습니다([명세 §5.4](../../docs/sw/sw-header-design-spec.md#54-반응형-more--대표-필드-전환-2026-10-16)).
- Text Stroke: Figma에 Stroke가 있는 텍스트만 검정 외곽선(14·16px 1.3px, 12px 1px) + 자기 색 0.3px를 표시합니다. 더보기·Tooltip·`+ New`/`Open`은 제외([명세 §6.1](../../docs/sw/sw-header-design-spec.md#61-text-stroke-2026-10-16)).
- Text Stroke: Figma에 Stroke가 있는 텍스트만 검정 외곽선(14·16px 1.3px, 12px 1px)을 표시합니다. 자기 색 0.3px Stroke는 2026-10-16 추가 수정으로 제거했습니다. 더보기·Tooltip·`+ New`/`Open`은 제외([명세 §6.1](../../docs/sw/sw-header-design-spec.md#61-text-stroke-2026-10-16)).
- `SWHeaderInput`: 레이어 상세 등 상세 영역에서 쓰는 수정 가능 Input(Figma 26:11656, Default / Hover / 편집, caret `#E60403`). `value`(확정값) · `onValueChange`(임시값) · `onCommit`(Enter·Focus 이동, 유효 + 변경 시) · `onCancel`(Escape) · `valueType`(`text` / `number`) · `parse` · `readOnly` · `disabled`([명세 §5.5](../../docs/sw/sw-header-design-spec.md#55-레이어-상세-버튼--수정-가능한-input-2026-10-16)).
- Peer: `react`, `react-dom` `^19.0.0`. 런타임 dependency는 없습니다.
- 출력: `dist/index.js`(ESM, Figma SVG asset은 data URI로 포함, 임시 Figma URL 없음), `dist/*.d.ts`, `dist/styles.css`.
@@ -57,7 +59,7 @@ npm run typecheck -w @hm-design/sw
- Text/Number/Select/Color/Slider/Computed, id 기반 동적 항목, 검증·확정·취소·외부 변경·ReadOnly/Disabled·그룹 펼침을 지원합니다. CAD 계산·선택·객체 변경은 호스트가 담당합니다.
- 상세 5개는 Figma 고정 크기와 Hover를 적용합니다. ByLayer/ByBlock은 정확히 하나가 표시되며, 기존 null 직접 색상 의미는 보존합니다. 레이어/선/문자/치수 목록은 Hover와 Selected 디자인이 같습니다.
- K는 기존 버튼을 재사용하고 원본 이미지 Pan/Zoom을 반복합니다. 640px 미만에서는 기존 More 항목에서도 같은 가이드를 표시합니다. Reduced Motion은 정적 이미지이며 기존 창 이동 1400ms는 유지합니다.
- 지정된 일반 text-stroke-width 선언·변수는 제거했고 검정 text-shadow와 상세 pill의 별도 Stroke는 보존했습니다.
- 지정된 일반 text-stroke-width 선언·변수는 제거했고 검정 text-shadow와 상세 pill의 별도 Stroke는 보존했습니다(상세 pill Stroke도 아래 후속 5개 요구사항에서 제거됨).
- 사용 예시와 API는 [가이드 추가 절](../../docs/sw/sw-header-usage.md#속성창k-가이드-추가-연결-2026-10-16), 디자인 값은 [명세 추가 절](../../docs/sw/sw-header-design-spec.md#추가-수정-기준--속성창k-가이드-2026-10-16)을 확인하세요.
- 검증: 기존 17 + 신규 4 Story, [현재 실행 결과 및 NOT VERIFIED](../../docs/sw/sw-header-additional-verification-2026-10-16.md). 과거 로그는 보존합니다.
@@ -79,3 +81,9 @@ npm run typecheck -w @hm-design/sw
- `SWHeaderPropertyPanelProps.shapeContent?: SWHeaderPropertyShapeContent` — `undefined` Figma 원형, `null`/`false` 빈 208×208 영역, ReactNode 또는 `(context: SWHeaderPropertyShapeContext) => ReactNode`. `SWHeader.propertyPanel`로도 전달됩니다.
- 하위 공개 컴포넌트에 선택적 표시 Props 추가(기본 true): `SWHeaderHome.interactive`, `SWHeaderProperties.showCaption/showBar/showPanel`, `SWHeaderActions.showPrint/showPopupGuide`, `SWHeaderWindowControls.showWindowMove/showMinimize/showClose`.
- Storybook: 기존 24개 + Composition, Property Panel 개별 4개, 4개 비교, 형상 Slot = 31개.
## 속성 필드·게이지 (2026-10-19)
- 속성창 공통 행은 Figma 26:12388 ~ 26:12649의 Default / Hover / On을 따릅니다. 숫자는 편집 On(`#0F0D0A`), 레이어·선스타일·색상은 Dropdown On(`#211D13`)이며 하이퍼링크·재료는 Default·Hover만 있습니다.
- 추가 API(모두 선택): `SWHeaderProperty.picker`(`"layer" | "lineStyle" | "color" | false`), `SWHeaderProperty.decimals`, `SWHeaderPropertyPanelProps.menus`(`SWHeaderPropertyMenus`). 필드 Dropdown은 Header Dropdown과 같은 목록 컴포넌트를 씁니다. [사용법](../../docs/sw/sw-header-usage.md#속성창k-가이드-추가-연결-2026-10-16), [검증 기록](../../docs/sw/sw-property-fields-verification-2026-10-19.md).
- 투명도 게이지는 빨강 채움 + 베이지 Track이며 Chrome·Firefox가 같은 그림을 씁니다([Firefox 게이지 기록](../../docs/sw/sw-header-firefox-range-close-verification-2026-10-19.md)).
@@ -46,7 +46,7 @@ const optionValue = (option: SWHeaderColorOption) => option.value ?? parseSWHead
* ByBlock (26:12666 / 26:12659), 22px palette, user color rows, color pick + RGB input, "색상 상세".
* Every control only reports through its callback; the host updates `value` / `mode`. Choosing a
* color or a mode keeps the dropdown open (several properties can be set in a row).
* Latest request restores Figma hover for the mode pair and detail pill; chips/pick remain unchanged.
* 2026-10-16 additional fix: Figma hover for the mode pair and the detail pill; chips keep no hover (pick has its own Colorize hover).
*/
export function SWHeaderColorMenu({
value, label, colors, userColors, mode, open: openProp, onOpenChange, onClick, selected = false, disabled = false,
+3 -3
View File
@@ -121,7 +121,7 @@
/* Figma text strokes (26:8944 and its menus, Plugin API 2026-10-16), all OUTSIDE:
14 / 16px text = black 1.3px under the text + 0.3px of its own color; 12px labels = black 1px;
"... 상세" pills = 0.4px of their own color, no black. Outline: 16 shadows on a 1.3px / 1px circle
(never clipped by the glyph like a centered -webkit-text-stroke). Latest request removes the
(never clipped by the glyph like a centered -webkit-text-stroke). The 2026-10-16 additional fix removed the
own-color stroke, including the detail pills. Black text-shadow remains unchanged. */
--hm-sw-header-text-outline-color: #000;
--hm-sw-header-text-outline:
@@ -773,7 +773,7 @@ button.hm-sw-header__layer-toggle[data-on="false"] > .hm-sw-header__layer-toggle
/* Row hover (26:10695): brown background, orange name. Size and icon positions stay. */
.hm-sw-header__layer-row:is(:hover, [data-active="true"]):not([data-disabled]) { background: var(--hm-sw-header-layer-row-hover-background); }
.hm-sw-header__layer-row:is(:hover, [data-active="true"]):not([data-disabled]) .hm-sw-header__layer-name { color: var(--hm-sw-header-layer-row-hover-color); }
/* Latest request: selected layer rows use the same emphasis as hover. */
/* 2026-10-16 additional fix: selected layer rows use the same emphasis as hover (rule above). */
.hm-sw-header__layer-footer {
position: relative;
display: flex;
@@ -941,7 +941,7 @@ div.hm-sw-header__menu-row { justify-content: space-between; gap: 8px; padding-l
.hm-sw-header__menu-row:is(:hover, [data-active="true"]):not([data-disabled]) .hm-sw-header__line-preview > i { background: var(--hm-sw-header-layer-row-hover-color); }
.hm-sw-header__menu-row:is(:hover, [data-active="true"]):not([data-disabled]) .hm-sw-header__menu-dimension-default { visibility: hidden; }
.hm-sw-header__menu-row:is(:hover, [data-active="true"]):not([data-disabled]) .hm-sw-header__menu-dimension-hover { visibility: visible; }
/* Latest request: selected style rows use the same emphasis as hover. */
/* 2026-10-16 additional fix: selected style rows use the same emphasis as hover (rules above). */
/* Footer (40px, "... 상세" pill). Border / padding / alignment per Figma menu. */
.hm-sw-header__menu-footer {
+11 -25
View File
@@ -2,7 +2,7 @@ import { useEffect, useRef, useState, type ReactNode } from "react"
import type { Meta, StoryObj } from "@storybook/react-vite"
import {
SWHeader, SWHeaderColorControl, SWHeaderLayerControl, SWHeaderLineStyle, SWHeaderTextStyle, SWHeaderDimensionStyle,
SWHeaderProperties, SWHeaderWindowControls, SWTheme, SWHeaderLayerMenu, SWHeaderInput, swHeaderLinePatterns, SWHeaderPropertyPanel, SWHeaderPropertyBar,
SWHeaderProperties, SWHeaderWindowControls, SWTheme, SWHeaderLayerMenu, SWHeaderInput, parseSWHeaderColor, swHeaderLinePatterns, SWHeaderPropertyPanel, SWHeaderPropertyBar,
type SWHeaderColorMode, type SWHeaderColorOption, type SWHeaderColorValue, type SWHeaderDimensionStyleOption,
type SWHeaderDocument, type SWHeaderLayer, type SWHeaderLineStyleValue, type SWHeaderLineType, type SWHeaderLineWeight,
type SWHeaderMenuId, type SWHeaderProps, type SWHeaderTextStyleOption, type SWHeaderProperty, type SWHeaderPropertyGroup, type SWHeaderPropertySelection, type SWHeaderPropertyMenus, type SWHeaderControlConfig, type SWHeaderHideableControlId, type SWHeaderPropertyShapeContent,
@@ -852,13 +852,6 @@ const FIGMA_DIMENSION_STYLES: SWHeaderDimensionStyleOption[] = [
type StyleHostProps = Partial<SWHeaderProps> & { onLog?: (line: string) => void; showState?: boolean; initialColorMode?: SWHeaderColorMode | null }
/** `#rrggbb` → `r,g,b` (sample data helper; other CSS colors are passed through). */
function hexToRgbText(color: string) {
const match = /^#([0-9a-f]{6})$/i.exec(color)
if (!match) return color
return [0, 2, 4].map(index => parseInt(match[1].slice(index, index + 2), 16)).join(",")
}
/**
* Host-owned field data: the SW program keeps color, line / text / dimension style and the lists. The
* header only reports; this example writes each report back (an explicit color clears ByLayer / ByBlock,
@@ -891,7 +884,7 @@ function StyleHeader({ onLog, showState, initialColorMode = null, ...props }: St
colorMode={colorMode}
onColorOpen={() => log("onColorOpen")}
onColorMenuOpenChange={open => log(`onColorMenuOpenChange(${open})`)}
onColorSelect={option => { log(`onColorSelect(${option.id})`); setColor({ value: option.value ?? hexToRgbText(option.color), swatch: option.color }); setColorMode(null) }}
onColorSelect={option => { log(`onColorSelect(${option.id})`); setColor({ value: option.value ?? parseSWHeaderColor(option.color)?.value ?? option.color, swatch: option.color }); setColorMode(null) }}
onColorModeChange={mode => { log(`onColorModeChange(${mode})`); setColorMode(mode); setColor(current => ({ ...current, value: mode === "byLayer" ? "ByLayer" : "ByBlock" })) }}
onColorInput={value => { log(`onColorInput(${value.value})`); setColor({ value: value.value, swatch: value.hex }); setColorMode(null) }}
onColorPick={() => log("onColorPick")}
@@ -980,7 +973,7 @@ export const ColorDropdown: Story = {
<StorySection title="ByLayer On (Figma on 26:12671)" description="colorMode='byLayer': #62533D 배경 + 밝은 inner shadow. 텍스트 #D4CBBD + 검정 Stroke. ByBlock은 Default(rgba(98,83,61,.3) + 어두운 inner shadow).">
<MenuFrame width={1920}><StyleHeader initialColorMode="byLayer" colorMenuOpen /></MenuFrame>
</StorySection>
<StorySection title="내부 버튼 Hover (고정) — 최신 예외 정책" description="ByLayer / ByBlock 글자 #FF5C00. 선택 배경과 Inset Shadow는 유지합니다. 색상 상세는 배경 .25·radius 25·Hover 아이콘으로 변합니다. 색상 칩·추출 버튼은 기존 정책을 유지합니다.">
<StorySection title="내부 버튼 Hover (고정) — 2026-10-16 추가 수정 정책" description="ByLayer / ByBlock 글자 #FF5C00. 선택 배경과 Inset Shadow는 유지합니다. 색상 상세는 배경 .25·radius 25·Hover 아이콘으로 변합니다. 색상 칩은 Hover가 없고, 색상 추출은 btn_colorize Hover(26:11305)입니다.">
<MenuFrame width={1920}><PinHover selectors={MENU_BUTTON_HOVER}><StyleHeader colorMenuOpen /></PinHover></MenuFrame>
</StorySection>
<StorySection title="RGB 입력 Hover (고정)" description="입력은 수정 가능함을 알리는 Figma Hover를 유지합니다(header/menu/색상/input hover: 1px rgba(197,177,158,.2)). 편집 중(Focus)에는 값 영역이 검정이 되고 커서는 #E60403입니다 — 아래 실제 예제에서 클릭해 확인합니다.">
@@ -1022,7 +1015,7 @@ export const LineStyleDropdown: Story = {
<StorySection title="현재 행 Hover (고정)" description="현재 선 종류(Continuous)는 Hover 및 Mouse Leave 뒤에도 갈색 배경·주황 선·이름을 유지합니다.">
<MenuFrame width={1920}><PinHover selectors={[".hm-sw-header__menu-row[data-active]"]}><StyleHeader lineStyleMenuOpen /></PinHover></MenuFrame>
</StorySection>
<StorySection title="상세 버튼 Hover (고정)" description="최신 요청에 따라 선스타일 상세의 Figma 배경 .25·radius 25·Hover 아이콘을 적용합니다.">
<StorySection title="상세 버튼 Hover (고정)" description="2026-10-16 추가 수정 기준으로 선스타일 상세의 Figma 배경 .25·radius 25·Hover 아이콘을 적용합니다.">
<MenuFrame width={1920}><PinHover selectors={MENU_BUTTON_HOVER}><StyleHeader lineStyleMenuOpen /></PinHover></MenuFrame>
</StorySection>
<StorySection title="선 종류 · 가중치 · 스케일 선택 Callback" description="선 종류 → onLineTypeSelect(가중치·스케일 유지), 가중치 → onLineWeightSelect(선 종류·스케일 유지), User 입력 → onLineWeightValueChange(0 이상), 스케일 입력 → onLineScaleChange(0 초과). 입력은 Enter/Focus 이동으로 확정, Escape는 취소. ↓↑로 항목 이동.">
@@ -1108,7 +1101,7 @@ export const TextStroke: Story = {
<StoryPageHeader
kicker={KICKER}
title="Text Stroke"
description="Figma 26:8944와 메뉴의 텍스트 Stroke(모두 OUTSIDE)를 복원했습니다: 14 · 16px = 검정 1.3px + 자기 색 0.3px, 12px 라벨 = 검정 1px, '… 상세' = 자기 색 0.4px(검정 없음). 글꼴·크기·굵기·자간·기준선·말줄임은 그대로이며 Hover/Selected는 채움색만 바뀝니다."
description="Figma 26:8944와 메뉴의 텍스트 Stroke(모두 OUTSIDE) 중 검정 외곽선을 text-shadow로 표시합니다: 14 · 16px 값 = 검정 1.3px, 12px 라벨 = 검정 1px. 자기 색 Stroke(0.3px · '… 상세' 0.4px)는 2026-10-16 추가 수정으로 제거했습니다. 글꼴·크기·굵기·자간·기준선·말줄임은 그대로이며 Hover/Selected는 채움색만 바뀝니다."
/>
<StorySection title="구현 (1920)">
<Frame width={1920}><SWHeader {...figmaArgs} {...callbacks} /></Frame>
@@ -1800,19 +1793,12 @@ const FIELD_NODES = [
{ node: "26:12590", name: "두께", states: "Default · Hover · On(편집)" },
{ node: "26:12574", name: "재료", states: "Default · Hover (Figma On 없음)" },
]
const FIELD_FIXTURE: SWHeaderProperty[] = [
{ id: "layer-mixed", name: "레이어", value: "0_Layer_Cludmark", mixed: true, type: "text", groupId: "common", picker: "layer" },
{ id: "layer", name: "레이어", value: "0_Layer_Cludmark", type: "text", groupId: "common", picker: "layer" },
// Figma sample text 255,259,0 is out of range: shown as host text only, never accepted as input.
{ id: "color", name: "색상", value: "255,259,0", swatch: "#ffe500", type: "color", groupId: "common" },
{ id: "line", name: "선스타일", value: "Continuous", type: "select", groupId: "common", unit: "(ByL)", linePreview: true, options: PROPERTY_LINE_TYPES.map(({ id, name }) => ({ id, name })) },
{ id: "weight", name: "선가중치", value: "0.25", type: "number", groupId: "common", min: 0 },
{ id: "scale", name: "선축적", value: "1.0000", type: "number", groupId: "common", min: .0001, decimals: 4, unit: "(LTscale:1)" },
{ id: "opacity", name: "투명도", value: "0.25", type: "slider", groupId: "common", min: 0, max: 1, step: .01, annotation: "(ByL)", unit: "%" },
{ id: "link", name: "하이퍼링크", value: "--", type: "text", groupId: "common" },
{ id: "thickness", name: "두께", value: "0.25", type: "number", groupId: "common", unit: "mm", min: 0 },
{ id: "material", name: "재료", value: "-", type: "computed", groupId: "common", unit: "(ByL)" },
]
// The common rows of PROPERTY_FIXTURE plus a mixed layer row. Figma sample text 255,259,0 is out of range:
// shown as host text only, never accepted as input.
const FIELD_FIXTURE: SWHeaderProperty[] = PROPERTY_FIXTURE.filter(item => item.groupId === "common").flatMap(item =>
item.id === "layer" ? [{ ...item, id: "layer-mixed", mixed: true }, item]
: item.id === "color" ? [{ ...item, value: "255,259,0", swatch: "#ffe500" }]
: [item])
const FIELD_HOVER = [".hm-sw-property__value[data-field]", ".hm-sw-property__compact"]
function FieldPanel({ title, properties, onChange, menus }: { title: string; properties: SWHeaderProperty[]; onChange?: (property: SWHeaderProperty, value: string) => void; menus?: SWHeaderPropertyMenus }) {
return <SWTheme><SWHeaderPropertyPanel selection={{ id: title, title, kind: "none" }} properties={properties} groups={[{ id: "common" }]} onPropertyChange={onChange} menus={menus} /></SWTheme>