Files
HMDesign/docs/sw/sw-viewer-panel-region-styles.md
T
shkim4 db03e155dd
Deploy Storybook / deploy (push) Successful in 1m10s
feat(sw): refine headers, status label, popups and AI guide rules
- SW Header: the five field previews hide and return together in one
  measured step; from 760 to 1920px the groups from 레이어 to 치수스타일
  share the room left before 속성보기, above 1920px they keep the 1920
  widths (controls bars and < 760px unchanged)
- SW Viewer Header Model / Layout: long names ellipsize in equal buttons
  (minmax(0, 1fr), name counted at --hm-sw-viewer-tab-name-basis) so they
  never change the box or the measured steps; green outer outline and its
  tokens removed; 378px / 42px, text-shadow and state unchanged
- SWViewerStatus: the label keeps the width of its widest real state text
  (idle keeps its icon slot), so a state change never moves the header;
  with too little room it ellipsizes after the file name gives way
- Popups: body inset shadow removed, title SVG drop shadow removed, viewer
  panel title icons use --hm-sw-viewer-panel-icon-color (#c7bda9)
- Storybook: SW/Viewer › Model / Layout story removed
- AI guide (docs/ai + package copies): design-only changes for every
  component, content limits for Submodule consumers (Header excluded),
  Submodule usage rules; VIEWER / DESIGN_RULES synced
- viewer.browser.mjs: explicit 1920 / 1440 labels and approved 1280
  icon-only expectations
2026-10-23 18:18:17 +09:00

73 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SW Viewer 설정창(SWViewerPanel) 영역 구분 스타일
> 작성 2026-10-23. **현재 구현 조사 문서**이며 새 규칙을 정하지 않습니다. 값은 아래 소스와 Storybook `SW/Viewer › Settings Popup`(`sw-viewer--content-variants`)의 Computed Style 실측(Chromium, 2026-10-23)으로 확인했습니다. 구현으로 확인되지 않거나 기준이 불명확한 부분은 §6 확인 필요 항목에만 적습니다.
>
> - 공통(패키지) 스타일: `packages/sw/src/theme/sw.css`(SWPopup 프레임 `.hm-sw-property*`), `packages/sw/src/theme/sw-viewer.css`(뷰어 패널·콘텐츠 `.hm-sw-viewer-*`)
> - 컴포넌트: `packages/sw/src/components/sw-viewer/SWViewerPanel.tsx`(프레임 = `SWPopup`), `SWViewerControls.tsx`(`SWViewerSection`, `SWViewerField`, `SWViewerInput`, `SWViewerBadge`, `SWViewerHint` 등)
> - Storybook 전용 스타일: `src/sw/sw-viewer-stories.css`(`.sw-viewer-story-*`), 콘텐츠 구성 `src/sw/sw-viewer-fixture.tsx`(`LayerPanel`, `PropertiesPanel`, `OptionsPanel`)
>
> 실측의 `0.666667px` 테두리는 기기 배율(DPR 1.5)에서 1px CSS 값이 그려진 결과입니다. 아래 표에는 CSS 선언값을 적습니다.
## 1. 구조 요약
```
SWViewerPanel (= SWPopup, .hm-sw-property.hm-sw-viewer-panel) ← 테두리 박스(프레임)
├─ .hm-sw-property__titlebar ← 배경(그라데이션)만
├─ .hm-sw-property__body ← 배경·간격만(본문 스크롤)
│ └─ children: SWViewerSection(card | plain) / SWViewerField / 목록 …
└─ footer → .hm-sw-viewer-panel__footer ← 위쪽 선
.hm-sw-viewer-panel__resize ← 모서리 Grip(빗금)
```
## 2. 선(Border/Divider)으로 구분되는 영역
| 영역 | 목적 | 선택자 | 실제 값 | 조건·예외 | 구분 | Storybook 예시 |
|---|---|---|---|---|---|---|
| Footer 위 구분선 | 스크롤 본문과 하단 버튼 영역 분리 | `.hm-sw-viewer-panel__footer` | `border-top: 1px solid var(--hm-sw-viewer-panel-inner-border)`(#948871), `padding: 7px`, `gap: 8px`, 오른쪽 정렬 | `footer` Prop이 있고 접힘(`collapsed`)이 아닐 때만 렌더링 | 공통 | `SW/Viewer › Viewer Header`의 `모듈 구성 · 라이선스 고지` modal(`AboutPanel`, `확인` 버튼). Settings Popup 3개에는 footer 없음 |
| 전체 레이어 행 아래 선 | 고정 행(검색·전체 레이어)과 레이어 목록 분리 | `.sw-viewer-story-layers .sw-viewer-story-all` | `border-bottom: 1px solid var(--hm-sw-property-table)`(#d2c8b4), `padding-bottom: 8px`(실측 `padding: 0 6px 8px 0`) | 레이어 Popup에만 해당. 검색과 전체 레이어 사이에는 선 없음 | **Storybook 전용** | Settings Popup › `레이어 (9개)` |
| 속성 행 사이 선 | 속성 키/값 행 구분 | `.sw-viewer-story-props > div` | `border-bottom: 1px solid var(--hm-sw-property-table)`(#d2c8b4), `padding: 6px 0`, `gap: 12px`, 이름 왼쪽·값 오른쪽(말줄임) | 각 Card의 마지막 행에는 선 없음(2026-10-23, 뷰어 화면 기준) | **Storybook 전용** | Settings Popup › `속성` |
## 3. 선이 표시되지 않는 영역
| 영역 | 목적 | 선택자 | 실제 값 | 조건·예외 | 구분 | Storybook 예시 |
|---|---|---|---|---|---|---|
| Plain Section | 패널 본문에 카드 없이 콘텐츠를 바로 배치 | `.hm-sw-viewer-section[data-surface="plain"]` | 전용 규칙 없음 → 기본 `.hm-sw-viewer-section`만 적용: `display: flex; flex-direction: column; gap: 12px`, 테두리·배경·padding 0 | `SWViewerSection surface="plain"`을 명시했을 때 | 공통 | 레이어 Popup의 목록 Section |
| 제목줄 ↔ 본문 경계 | — | `.hm-sw-property__titlebar` / `.hm-sw-property__body` | 경계선 없음. 제목줄은 배경 그라데이션, 본문은 위쪽 inset 하이라이트(§5)로만 구분 | 모든 패널 | 공통(SWPopup) | Settings Popup 전체 |
| 검색 ↔ 전체 레이어 | 고정 행 두 개 | `.sw-viewer-story-toolbar` | 선 없음, `gap: 12px 4px` | 레이어 Popup | Storybook 전용 | `레이어 (9개)` |
| 레이어 목록 행 사이 | 레이어 항목 나열 | `.sw-viewer-story-list`, `li` | 선 없음, 목록 `gap: 4px`, 행 `padding: 4px 6px` | — | Storybook 전용 | `레이어 (9개)` |
| 카드 Section 사이 | 옵션 그룹 나열 | 본문 `.hm-sw-property__body` | 선 없음, 본문 `gap: 8px`로만 분리(각 카드는 자기 테두리를 가짐) | `surface="card"` 연속 배치 | 공통 | `옵션` |
## 4. 테두리가 있는 박스 영역
| 영역 | 목적 | 선택자 | Border | Background | Radius | Padding·기타 | 조건·예외 | 구분 | 예시 |
|---|---|---|---|---|---|---|---|---|---|
| 패널 프레임 | 팝업 전체 외곽 | `.hm-sw-property`(SWPopup) + `.hm-sw-viewer-panel` | `1px solid var(--hm-sw-property-border)`(#a67d03) + `box-shadow: inset 0 0 0 1px #000`(안쪽 검정 1px) | `var(--hm-sw-property-surface)`(#e4dbc9) | 4px | padding 0, `overflow: hidden` | 모든 SWViewerPanel. modal이면 뒤에 `.hm-sw-viewer-panel-backdrop`(`rgba(0,0,0,.1)`) | 공통(SWPopup 그대로) | Settings Popup 3개 |
| Card Section | 설정 그룹 묶음 | `.hm-sw-viewer-section[data-surface="card"]` | `1px solid var(--hm-sw-viewer-panel-inner-border)`(#948871) | `var(--hm-sw-viewer-panel-field-background)`(#f1ece1) | `var(--hm-sw-viewer-radius)` 4px | `padding: var(--hm-sw-viewer-panel-spacing)` 12px, `gap: 12px`, `box-shadow: inset 0 1px 0 #fff`, `margin-top: 0`(2026-10-23: 그룹 박스 사이는 본문 gap 8px만, 소비 앱 단일 class의 상단 여백 무시) | `SWViewerSection`의 **기본값**(`surface` 생략 시 card). plain Section의 상단 여백은 유지 | 공통 | `옵션`의 `선가중치`·`표시`·`2.5D`, `속성`의 `일반 정보 (GENERAL)`·`기하 속성 (GEOMETRY)`(2026-10-23) |
| 검색 입력 | 레이어 검색 | `.hm-sw-theme .hm-sw-viewer-input[type="search"]` | `1px solid var(--hm-sw-viewer-panel-inner-border)` | field-background #f1ece1 | 4px | 80px 기본 폭, 높이 28px, `padding: 0 10px` | `type="search"`만. 값 입력(§5)과 다름 | 공통 | `레이어 (9개)` |
| 패널 버튼 outline | 보조 버튼 | `.hm-sw-theme .hm-sw-viewer-button` | `1px solid var(--hm-sw-viewer-panel-primary)`(#123328) | #fff (`primary`는 #123328) | 4px | 높이 24px, `padding: 0 8px` | 제목줄의 `variant="ghost"`는 테두리·배경 없음(26 × 26) | 공통 | `모듈 구성` modal의 `확인`(primary). Settings Popup에는 ghost만 |
## 5. 배경색·간격만으로 구분되는 영역
| 영역 | 목적 | 선택자 | 실제 값 | 조건·예외 | 구분 | 예시 |
|---|---|---|---|---|---|---|
| 제목줄 | 제목·닫기·동작 버튼 | `.hm-sw-property__titlebar` | 높이 30px, `background: var(--hm-sw-header-document-background)`(녹색 세로 그라데이션), Figma 제목 아트(`property-title-single.svg`, 314px 초과 폭은 왼쪽 늘림 복제 `::before`) | 모든 패널. 드래그 가능하면 `cursor: grab` | 공통 | 전체 |
| 본문 | 스크롤 콘텐츠 영역 | `.hm-sw-property__body` + `.hm-sw-viewer-panel .hm-sw-property__body` | `padding: 7px 7px 0`, `border-bottom: 8px solid transparent`(스크롤 영역 밖 하단 여백), `gap: 8px`, 그림자 없음(2026-10-23 사용자 요청으로 `box-shadow: inset 0 2px 2px rgba(255,255,255,.6)` 제거), 배경은 프레임 surface | 접힘이면 `display: none` | 공통(SWPopup 7px + 뷰어 하단 8px 덮어쓰기) | 전체 |
| Field | 라벨 + 컨트롤 행 | `.hm-sw-viewer-field`, `__row` | 선·배경 없음, field `gap: 6px`, row `gap: 8px`, `min-height: 20px` | disabled면 `opacity: .5` | 공통 | `옵션` |
| 값 입력·단위 칸 | 숫자 입력 | `.hm-sw-viewer-input:not([type="search"])`, `.hm-sw-viewer-field__control:has(> unit)` | 기본 **투명 테두리**(1px transparent), radius 2px, 높이 28px. Hover/편집 시에만 `--hm-sw-property-field-hover-border-color` 테두리, 편집 중 배경 `--hm-sw-property-field-editing-background` | 상태가 바뀔 때만 박스로 보임 | 공통 | `옵션`의 `표시 배율`(px/mm) |
| Badge | 개수·유형 표시 | `.hm-sw-viewer-badge` | 테두리 없음, `background: var(--hm-sw-viewer-panel-badge-background)`(#d2c8b4), radius 4px, `padding: 2px 8px` | — | 공통 | 레이어 개수, `LINE · h=2F1A`(`속성` 맨 위, Card 밖, 자기 폭) |
| 레이어 행 Hover | 행 강조 | `.sw-viewer-story-list li:hover` | `background: rgba(154,146,132,.25)`, radius 3px | Hover일 때만. 숨긴 레이어는 `opacity: .45` | Storybook 전용 | `레이어 (9개)` |
| 속성 그룹 간격 | 두 속성 그룹 분리 | Card Section 사이 | 본문 `gap` 8px만(Card `margin-top: 0`, 2026-10-23 `.sw-viewer-story-props-next` 제거) | 두 Card 사이 | Storybook 전용 | `속성` |
| Hint | 보조 설명 | `.hm-sw-viewer-hint` | 선·배경 없음, 12px | — | 공통 | `옵션` |
| 빈 상태 | 선택 없음 안내 | `.sw-viewer-story-empty` | 선·배경 없음, `padding: 40px 0`, 가운데 정렬 | `PropertiesPanel selected={false}` | Storybook 전용 | `SW/Viewer › States` 등 |
| Resize Grip | 크기 조절 | `.hm-sw-viewer-panel__resize` | 14 × 14, inner-border 색 빗금 그라데이션(선 아님) | `resizable` 이고 접힘이 아닐 때 | 공통 | 전체 |
## 6. 확인 필요 항목
1. **Card가 기본값인 이유:** `SWViewerSection`의 기본 `surface`는 `card`입니다. 그러나 레이어·속성 Popup은 모두 `plain`을 명시하고, card는 `옵션` Popup만 씁니다. 어느 콘텐츠에 card/plain을 쓰는지에 대한 디자인 기준 문서는 확인되지 않았습니다.
2. **레이어 구분선 위치:** "전체 레이어 행 아래 `#d2c8b4` 1px 선, 검색과 사이에는 없음" 규칙은 `packages/sw/ai/VIEWER.md`에 소비 앱 규칙으로 적혀 있습니다. 실제 구현은 Storybook/예제의 소비 앱 CSS뿐이고 패키지 공통 스타일은 아닙니다.
3. **구분선 색 두 가지:** 레이어 구분선·속성 행 선(2026-10-23)은 `--hm-sw-property-table`(#d2c8b4)이고, Footer 선·Card 테두리는 `--hm-sw-viewer-panel-inner-border`(#948871)입니다. 용도별로 색을 나누는 기준은 문서화되어 있지 않습니다.
4. **속성 행 마지막 선:** 2026-10-23 뷰어 화면 기준으로 각 Card의 마지막 행에는 선을 그리지 않습니다(Storybook 전용 CSS).
5. **Footer 예시 부족:** Footer 구분선은 대표 Settings Popup에 없습니다. `Viewer Header` Story의 modal에서만 보이며, 비-modal 패널 Footer의 디자인 기준 화면은 확인되지 않았습니다.
6. **입력 박스 두 형태:** 검색 입력은 항상 테두리 박스이고, 값 입력은 Hover/편집 때만 테두리가 생깁니다(2026-10-22 사용자 요청 주석). 다른 텍스트 입력(예: 검색이 아닌 일반 text)에 어느 쪽을 쓸지는 `type="search"` 여부로만 갈립니다.
7. **Card 안쪽 하이라이트:** `box-shadow: inset 0 1px 0 #fff`는 하드코드 값이고 대응 토큰이 없습니다.