AI documents (packages/sw/ai)
- SWPopupPropertyRow, SWSelect, SWSlider in the catalog, usage table,
composition patterns and design rules; SWViewerSlider noted as SWSlider panel.
- Rule: the SWHeader layer / color dropdowns are header-only; popup layer /
color / line style use SWPopupPropertyRow (property window pickers).
- Footer rules: gra-border-orange surfaces, Model / Layout text unchanged on
hover, side button hover, vacant surface limited to the slot row.
- Header rules: measured More growing behavior (hysteresis fix A).
- Example E (custom popup) uses SWPopupPropertyRow, SWSelect and SWSlider
instead of SWHeaderLayerMenu in the popup.
Tests (packages/sw/tests)
- New footer-popup-viewer-refinement.browser.mjs (47 checks: footer stories,
hover / gradient / tab text / pocket, popup pickers vs property window rows,
SWSlider, unit SWSelect parity, Popup B, header trace, viewer title art).
- integrated-popup / integrated-consumer: popup pickers and SWSelect instead of
the header dropdown and the HM UI Select (same overlay / callback / Escape
requirements).
- integrated-improvement: default sections skip the retired SW/Tool story
('tool' still runs by name); storybook-inventory / simplification record the
retired footer IDs; theme-inheritance widths use sw-footer--full-footer.
Docs (docs/sw)
- sw-footer-popup-viewer-refinement-2026-10-20.md: causes, decisions (the
first-pass "header dropdown in popup" change is marked withdrawn),
verification and baseline failures; evidence footer-popup-viewer-refinement-qa
(47/47). Footer mapping document updated for the removed sections.
Baseline failures (unchanged by this work): home-menu-integration 1,
storybook-unused-removal 5 (10-19 snapshot comparisons), range-cross-browser and
property-panel-comparison open stories retired on 2026-10-19.
122 lines
17 KiB
Markdown
122 lines
17 KiB
Markdown
# SW Footer · Popup · Viewer 디자인 및 Storybook 정리 (2026-10-20)
|
||
|
||
범위: `feature/sw-package`, 기준 HEAD `2b0e1a2`. SW 패키지(`packages/sw`)와 SW Story(`src/sw`)만 변경했습니다. Web(UI)·OrgChart·CAD 렌더링·SW 기본 폰트 정책은 변경하지 않았습니다. Commit·Push 전(승인 대기). 같은 날 2차(Header·Footer·SWSelect)·3차(Footer 탭·Popup 컨트롤) 수정과 최종 통합 검증을 §8~§12에 이어 적었습니다.
|
||
|
||
## 1. Footer Story 정리
|
||
|
||
| Story (ID) | 처리 |
|
||
|---|---|
|
||
| `기본 Footer` (`sw-footer--default`) | 삭제. 화면(Figma 데이터만 넣은 `<SWFooter />` 1920 + Figma 26:10097 하단 렌더)은 `전체 Footer · 실제 조합`의 "전체 Footer — Figma 기본 구성" 섹션으로 이동 |
|
||
| `Hover / Active / Selected / Disabled` (`sw-footer--states`) | 삭제. 상태 셀(명령·빈 칸·분류·보조기능·측면 버튼의 Default / Hover·Active / Selected / Selected+Hover / Disabled)은 `전체 Footer · 실제 조합`의 "상태" 섹션으로, 보조기능 6종 Figma 비교(`aux-buttons/*.png`)는 숨김 `Figma 디자인별 Variant`로 이동. "하나만 선택" 데모(`AuxToggleDemo`)만 제거(보조기능 토글은 실제 조합에서 동작) |
|
||
| `전체 Footer · 실제 조합` (`sw-footer--full-footer`) | 메인. 섹션: 실제 Footer 조합(동작) → 전체 Footer(Figma 기본 구성) → 상태 → 실제 화면 참고. ID·이름 유지 |
|
||
| 나머지 (`tool-groups`, `figma-variants`, `custom-content`, `responsive`, `parts`) | 유지 |
|
||
|
||
- 삭제 Story만 쓰던 코드: `AuxToggleDemo`, Story CSS `.sw-footer-story-aux-demo` 제거. `FigmaFooter`·`StateCell`·`AUX_SETS`·`aux-buttons` 이미지는 이동한 섹션이 계속 사용합니다(Figma 기준 이미지 보존).
|
||
- Footer 컴포넌트 코드는 변경하지 않았습니다(Hover·Active·Selected·Disabled, 칸 영역 고정, ▲ 왼쪽부터 배치, 반응형, 공개 API 그대로).
|
||
- 참조 갱신: `docs/sw/sw-footer-figma-mapping-2026-10-20.md` §1·§2, `packages/sw/tests/theme-inheritance.browser.mjs`(폭별 검사 대상 `footer--default` → `footer--full-footer`), `storybook-inventory.mjs`(`retiredFooterIds`), `storybook-simplification.browser.mjs`(삭제 ID 검사 추가). 과거 증거 `docs/sw/storybook-simplification-qa/sidebar.json`은 당시 기록이라 수정하지 않았습니다.
|
||
|
||
## 2. Popup 안 SW Dropdown (레이어·색상) — **3차에서 철회, §10 참고**
|
||
|
||
> 2026-10-20 3차 사용자 확정: SWHeader 레이어·색상 Dropdown은 Header 전용입니다. 아래 1차 변경(필드 typography 규칙)은 제거했고, Popup의 레이어·색상은 속성창 컨트롤 `SWPopupPropertyRow`로 바꿨습니다.
|
||
|
||
|
||
- 원인: `.hm-sw-property`(Popup 프레임)가 `color: #000`(`--hm-sw-property-label`)·`line-height: 16px`·`letter-spacing: .02em`을 지정하고, Header 필드(`button.hm-sw-header__field`)는 SW 버튼 초기화(`color/font/letter-spacing: inherit`)로 이를 상속했습니다. Header 안에서는 `.hm-sw-header`의 `#F6F4F2`를 상속해서 문제가 없었고, Popup 안에서는 검정 글자 + 검정 외곽선(text-shadow)이 되어 글자가 뭉개졌습니다. 목록 패널은 이미 자기 색을 지정하고 있었습니다.
|
||
- 수정(`sw.css`): `:is(.hm-sw-header__field, .hm-sw-header__layer, .hm-sw-header__menu)`가 Header 글자색(`--hm-sw-header-text-color`)·글꼴 크기·400·`line-height/letter-spacing: normal`을 직접 지정. Header 안의 계산값은 이전과 같고(같은 값을 상속하던 것을 직접 지정), Hover·Selected·Expanded 규칙은 특이도가 더 높아 그대로 적용됩니다.
|
||
- 별도 컴포넌트·Story 전용 CSS 없음. `SWHeaderLayerMenu`·`SWHeaderColorMenu` 그대로 재사용, Popup 프레임·제목·닫기·고정 Overlay 동작 변경 없음.
|
||
- `레이어 속성 + 추가 콘텐츠`(SWHeaderPropertyPanel + children)의 레이어·색상은 속성창 자체 `picker` 디자인(Figma 속성창)이며 Header Dropdown이 아닙니다. 변경하지 않았습니다.
|
||
|
||
## 3. 투명도 게이지바 — `SWSlider`
|
||
|
||
| | 스타일 A `appearance="panel"`(기본) | 스타일 B `appearance="property"` |
|
||
|---|---|---|
|
||
| 출처 | 지금까지 SW Popup에서 쓰던 게이지바(`@hm-design/ui` Slider 실측) = `SWViewerSlider`와 같은 모양 | 속성창 4개 상태 비교의 게이지바(`SWHeaderPropertyPanel` slider) |
|
||
| 모양 | 6px 트랙 `#E0DACE`, Range `#266651`, 18px 흰 Thumb + 2px `#266651` | 6px 베이지 트랙 + 빨강 채움(Thumb 중심까지), Figma Thumb 14px + 그림자 |
|
||
| 토큰 | `--hm-sw-slider-panel-track` / `-range` / `-thumb` (기존 값만 사용) | `--hm-sw-property-range-fill` / `-fill-edge` / `-track` / `-highlight` (기존) |
|
||
|
||
- API: `value`(필수), `min`(0)·`max`(100)·`step`(1), `onValueChange(value)`, `onValueCommit(value)`(native `change`), `appearance`, `disabled`(40%), `input` 속성. 값·이벤트·키보드는 두 모양이 같습니다.
|
||
- 우선순위: ① `appearance` Prop → ② 기본 `"panel"`. 테마 연동은 토큰 범위(SWTheme `style`·Runtime 토큰 Override로 두 모양의 색 변경). 테마 전체의 기본 모양을 바꾸는 설정은 만들지 않았습니다.
|
||
- 중복 제거: 속성창 게이지바 CSS를 `:is(속성창 range, .hm-sw-slider[data-appearance="property"])`로 공유(속성창 86 × 16 그대로). `SWViewerSlider`는 `SWSlider appearance="panel"`을 렌더링하고 뷰어 토큰(`--hm-sw-viewer-panel-switch-on`, `--hm-sw-viewer-panel-background`)을 Slider 토큰에 연결합니다(모양·뷰어 테마 Override 동일, 내부 CSS 변수 `--hm-sw-viewer-slider-percent`는 제거).
|
||
- 기존 호환: 새 Export만 추가(`SWSlider`, `SWSliderProps`, `SWSliderAppearance`). `SWViewerSliderProps`·속성창 Props 변경 없음. Popup Story의 HM UI Slider 예제는 콘텐츠 자유 예시로 유지.
|
||
- Storybook: `SW/Popup → Custom Content`에 "투명도 게이지바 스타일" 섹션(A·B 비교 Popup, `appearance` 선택 Popup + Disabled).
|
||
|
||
## 4. Popup B (`SW/Popup → Multiple Popups`)
|
||
|
||
- 불일치 원인은 2절과 같습니다(레이어 필드 글자가 검정으로 뭉개짐). 2절 수정으로 해결.
|
||
- Popup B의 레이어 Dropdown이 고정값이라 선택해도 바뀌지 않던 것을 Popup A처럼 호스트 상태 + Callback(`b.layer=…`)으로 연결했습니다.
|
||
- 프레임(314, 면 `#E4DBC9`, 테두리 `#A67D03`, 제목 `#FFC600` 700, 제목줄 배경)·z-index(40, 목록 고정 Overlay 30)·Escape 스택은 A·C와 같습니다. 375px에서 페이지 가로 넘침 없음.
|
||
- `SWPopup`은 외형 고정 Non-modal 프레임이며 드래그·크기 조절·접기 기능이 없습니다(그 기능은 뷰어 `SWViewerPanel`). Popup B에 해당 기능을 추가하지 않았습니다.
|
||
|
||
## 5. Viewer 가변 크기 Popup 제목 배경
|
||
|
||
- 원인: 뷰어 패널은 Figma 제목 아트(`<img>`, 308px)를 오른쪽 정렬하고 왼쪽 20px을 `clip-path`로 숨긴 뒤, 남는 왼쪽을 `::before`(폭 `100% − 292px`)로 채웁니다. 호스트 전역 `img { max-width: 100% }`(Tailwind preflight, Storybook·소비 프로젝트)가 312px 미만 패널에서 아트를 패널 폭으로 줄였고, 그 결과 숨긴 20px이 패널 안으로 들어왔는데 `::before` 폭은 0이라 제목 앞 약 17px에 제목줄 녹색 배경이 드러났습니다.
|
||
- 수정(`sw-viewer.css`): 뷰어 패널 제목 아트에 `max-width: none`. Story 전용 보정 없음. 250 × auto: 아트 308px, -43px부터 표시(틈 0). 같은 문제가 `Popup Content Variants`의 300px 패널(약 10px)에도 있었고 같이 해결됩니다. 314px 이상 패널은 계산값 변화 없음.
|
||
- 최소 폭 250·자동 높이·접기/펼치기·드래그는 그대로입니다.
|
||
|
||
## 6. 검증
|
||
|
||
결과는 [footer-popup-viewer-refinement-qa/](./footer-popup-viewer-refinement-qa/) 참고. (아래 표는 2026-10-20 실제 실행 결과)
|
||
|
||
| 항목 | 결과 |
|
||
|---|---|
|
||
| `npm run typecheck`(전체 workspace, 패키지 build 포함) | PASS |
|
||
| `npm run build:sw` · `npm run build-storybook` | PASS |
|
||
| `npm run check:ai-docs` · `packages/sw/tests/ai-docs.check.mjs` | PASS · 37/37 |
|
||
| `footer-popup-viewer-refinement.browser.mjs`(신규) | **26/26 PASS**: Footer 삭제 ID·섹션·상태·칸 위치 고정·▲, Popup 필드 = Header 필드(색·면·테두리·높이·글자·외곽선·Hover·목록), SWSlider A/B·공통 값·Commit·선택·Disabled, 속성창 게이지 86 × 16, Popup B 프레임·선택·375px, Viewer 250 × auto 아트·접기·드래그, 300px 패널, SWViewerSlider 토큰 |
|
||
| `storybook-simplification.browser.mjs` | 9/9 PASS(삭제 Footer ID 검사 추가) |
|
||
| `theme-inheritance.browser.mjs` | 23/23 PASS(폭별 검사 대상 `footer--full-footer`) |
|
||
| `viewer.browser.mjs` | 70/70 PASS |
|
||
| `integrated-improvement.browser.mjs` | 61/62. FAIL 1 `resize: collapsed Open returns once…`(Header 반응형 Open 히스테리시스) — 이번 Dropdown 규칙을 뺀 빌드에서도 같은 trace로 실패해 **이번 변경과 무관**. 10-19 기록에서는 PASS였으므로 그 이후 변경에서 생긴 기존 문제로 별도 확인 필요 |
|
||
| `storybook-unused-removal.browser.mjs` | 93개 중 FAIL 5 — 10-20 간소화 보고와 같은 **기존** 스냅샷 비교 실패 |
|
||
| `range-cross-browser`, `property-panel-comparison` | 실행 불가(**기존**): 10-19 삭제된 Story(`sw-header--property-panel` 등)를 엶 |
|
||
| `viewer-regression.browser.mjs`(기준선 대비 픽셀) | 미실행 — 기준선 Storybook 빌드 필요. SWViewerSlider는 신규 검사(토큰·높이)와 viewer.browser 70/70으로 대신함 |
|
||
| Firefox 렌더링 | 미검증(Chrome만) |
|
||
|
||
## 7. 승인 필요
|
||
|
||
- `SWSlider` 신규 공개 API 이름·기본값(`appearance="panel"`)·`onValueCommit` 의미.
|
||
- 토큰 `--hm-sw-slider-panel-track/-range/-thumb` 추가(값은 기존 `#E0DACE`·`#266651`·`#FFFFFF`). 일반 모드 A 트랙은 HM UI Slider 실측 `#E0DACE`, 뷰어는 기존대로 `#E4DBC9`(뷰어 패널 면) — 의도된 차이 유지.
|
||
- 테마 전체 기본 `appearance` 설정은 만들지 않음(필요 시 별도 결정).
|
||
- `SWPopup`은 화면 폭 322px 미만에서 314px보다 좁아지면 제목 아트가 줄어듭니다(기존 동작, 이번 범위 밖).
|
||
|
||
## 8. 2차 — Header Open 히스테리시스 수정안 A (`SWHeader.tsx`, `sw.css`)
|
||
|
||
- 원인(별도 조사 세션, 첫 실패 Commit `170a5c2`): 넓어질 때 Print/K(640)·Color(900)·속성 블록(1080)이 고정 Breakpoint로 복귀하며 남은 공간을 음수로 만들고, 그때마다 Open이 먼저 More로 밀려남.
|
||
- 수정: ① 넓어지는 중 Breakpoint로 막 돌아온 부분은 측정 공간이 없으면 More에 hold(측정 공간이 생기면 복귀). 기본 레이아웃의 Print/K는 창 영역에 있어 hold 동안 창 영역만 640 미만 상태(`data-actions-held`). ② 넓어지는 중 복귀한 Open은 다른 부분 때문에 다시 밀리지 않음(후보가 없을 때만). ③ 좁아질 때는 Open 우선 이동 유지, 접힌 동안 더 좁아지면 복귀 기준 폭도 낮춤. ④ Open 복귀는 More 스택을 기다리지 않음(파일명 폭에서 가져감). ⑤ 마지막 항목 복귀 시 More 버튼이 사라지는 몫은 More를 잠시 빼고 실측. ⑥ 같은 폭에서 한 번 복귀한 항목은 다시 hold하지 않음(무한 업데이트 방지 — 중간 검증에서 `sw-header--responsive-more` React #185를 발견해 수정).
|
||
- Trace(테스트 조건 그대로 `[data-width="520"]` 프레임 520→1080): 수정 전 `[[520,0],[560,0],[600,1],[640,0],[680,0],[720,1],[760,1],[820,1],[900,0],[1080,0]]` → 수정 후 `[[520,0],[560,0],[600,1],[640,1],[680,1],[720,1],[760,1],[820,1],[900,1],[1080,1]]`(held: 640·680 Print/K, 900·1080 Color). 1920에서 모두 복귀, 1800으로 줄이면 Open 먼저 이동, 다시 넓히면 600에서 1회 복귀.
|
||
|
||
## 9. 2차 — Footer·SWSelect
|
||
|
||
- 토큰 `--hm-sw-footer-gra-border-orange`(Figma gra-border-orange, 기존 `--hm-sw-footer-aux-pressed-border` 값과 동일하며 그 토큰이 이를 참조). 전체보기 버튼 Hover·Pressed = 두 줄 `#FF5C00` + 주황 그라데이션 테두리. 분류 행 + Hover = 주황 + (`menu-add-hover.svg`). Layout + Hover = 그라데이션 면 + +. Model 선택·Hover, Layout(선택 아님) Hover = 그라데이션 면.
|
||
- Story 내부 5개 삭제: 전체 Footer — Figma 기본 구성 / 상태 / 참고: 실제 화면, 화면 폭 변화의 참고: 실제 좁은 화면 / Figma 기본 구성(명령창 없음). 기준 이미지 파일(`assets/footer-reference/*.png`)은 매핑 문서 기준이라 보존, Story import만 제거.
|
||
- `SWSelect`(신규): native select, 28px · 좌우 8 · 1px `#948871` · radius 4 · `#F1ECE1` · 12px 검정. Popup 도면 설정 단위(이전 HM UI Select)와 Viewer 축척 지정 단위(이전 Story 전용 CSS `.sw-viewer-story-select`, 제거)에 적용 — Default·Hover·Focus 계산값 차이 0.
|
||
- 미사용 자산(참조 0, Figma 원본 상태라 보존): `tab-model-on.svg`, `tab-slant-hover.svg`, `tab-add-hover.svg`.
|
||
|
||
## 10. 3차 — Footer 탭·Popup 컨트롤
|
||
|
||
- Footer 두 번째 분류 탭 배경 갈라짐: 원인은 탭 위치가 아니라 `bg_vacant`(마지막 명령 뒤 어두운 면)가 분류 행 아래까지 내려와 있던 것. 선택 탭의 Pocket은 위가 열린 모양이라 뒤가 비치고, `수정`(명령 1개)의 Pocket이 68px 칸 경계를 가로질러 왼쪽은 그룹 면·오른쪽은 vacant 면으로 갈라짐. vacant를 명령 칸 높이(46px)까지만 그려 모든 탭의 Pocket이 같은 그룹 면을 보임(도형·수정·편집·문자 검증). **영향:** 명령이 적은 분류(편집 등)의 Pocket 면이 이전의 어두운 vacant에서 그룹 면으로 바뀜 — 디자인 확인 권장.
|
||
- Model·Layout 텍스트: Model 선택·Hover와 Layout Hover의 글자를 Default와 같게(`#161410`, 12px, 400, 외곽선 없음, 위치·크기 불변). 이전 2차의 흰 글자·외곽선 규칙 대체. 선택된 Layout(갈색 면, 흰 글자 + 외곽선)과 이름 편집 상태는 그대로.
|
||
- Popup의 Header 전용 Dropdown 제거: 원인은 1차에서 Popup 안 `SWHeaderLayerMenu`·`SWHeaderColorMenu`를 Header처럼 보이게 한 `:is(.hm-sw-header__field, …__layer, …__menu)` typography 규칙(제거). Popup 전용 기준은 속성창 picker(`SWHeaderPropertyPickerField`, Figma 26:12250 / 26:12170)이며, 이를 SWPopup 안에서 쓰도록 공개 행 `SWPopupPropertyRow`(속성창 `PropertyEditor` 그대로)를 추가. 도면 설정·Popup B·AI Example E에 적용. 속성창 행과 계산값 동일, Popup 안 `.hm-sw-header__field` 0개, Header 필드는 변경 없음.
|
||
|
||
## 11. 최종 검증 (2026-10-20 15:00, Storybook static 재빌드 기준)
|
||
|
||
| 항목 | 결과 |
|
||
|---|---|
|
||
| `npm run typecheck`(workspace 전체) · `build-storybook` · `build:sw` | PASS |
|
||
| `check:ai-docs` · `packages/sw/tests/ai-docs.check.mjs` | PASS · 37/37 |
|
||
| `footer-popup-viewer-refinement.browser.mjs` | **47/47 PASS** (증거 [footer-popup-viewer-refinement-qa/](./footer-popup-viewer-refinement-qa/)) |
|
||
| `storybook-simplification` | 9/9 PASS |
|
||
| `integrated-improvement` (options) / (popup) | 61/61 / 26/26 PASS. 기본 섹션의 `tool`은 10-19 삭제된 `sw-tool--tool-buttons`를 열어 중단되던 **기준선 문제** → 기본 섹션에서 제외(이름으로는 계속 실행 가능) |
|
||
| `theme-inheritance` · `viewer.browser` | 23/23 · 70/70 PASS |
|
||
| `integrated-consumer`(npm pack → React 19 + Vite + Tailwind 4 새 프로젝트, tsc + vite build) + 브라우저 | build PASS, 46/46 PASS |
|
||
| `home-menu-integration` | 22/23, FAIL 1(`without homeMenu: logo click…`) = **기준선**(47972c5에서도 동일) |
|
||
| `storybook-unused-removal` | 93 중 FAIL 5 = **기준선**(10-19 inventory·source 스냅샷 비교). 중간 7건 중 추가 2건은 위 무한 업데이트였고 수정 후 5건으로 복귀 |
|
||
| `range-cross-browser`, `property-panel-comparison`, `followup-four`, `property-fields` | 실행 불가 = **기준선**(10-19 삭제 Story를 엶) |
|
||
| 실제 소비 프로젝트 `D:디자인시스템HMDesignSwTest-viewer`(Submodule `68fbcf6` + Workspace) | 사용 중인 SW API 14개 모두 현재 패키지에 존재(소스 호환). 해당 폴더에 미커밋 작업 20개·detached HEAD가 있어 Submodule 갱신·실행 검증은 하지 않음 — **미검증, 승인 필요** |
|
||
| Firefox, `viewer-regression`(기준선 픽셀 비교) | 미실행 |
|
||
|
||
## 12. 남은 항목 · 승인 필요
|
||
|
||
- SW 기본 글꼴: 현재 `--hm-sw-header-font-family: "Noto Sans KR", …`(`sw.css` 1곳), AI 문서는 "Dotum 기본 적용 승인 대기". 사용자 기준(SW = 돋움)과 다름. 바꾸면 SW 전체 글자 폭이 달라져 Header More 측정·Footer 칸·Popup 행 폭에 영향 → 별도 승인 후 토큰 1곳 변경 + 문서 4곳 + 회귀 검증 계획.
|
||
- 그라데이션 중복: Home Menu `--hm-sw-home-menu-item-hover-border`는 같은 색의 반올림 값(8.5/37.9/71.9/92.8%). 다른 컴포넌트의 승인 값이라 통합하지 않음(검토 필요).
|
||
- 디자인 확인: 전체보기 Hover 테두리, 분류 + Hover, Model 기본(선택 아님) 베이지 유지, 명령이 적은 분류의 Pocket 면 변화.
|