User-requested SW Viewer changes (2026-10-21); no new Props, public .d.ts unchanged. - Layer popup visibility: AI docs (VIEWER §4.1, catalog, design rules, patterns, AI_GUIDE) require the Eye / EyeOff icon button, never a switch; example H now renders a real layer list with eye buttons; Storybook eye button gets the pointer. - Viewer header hover: text and icon #FFC600, the #266651 hover face removed; size and position unchanged. Status stays display only. - Trailing strip: status, the trailing icon button (info / license) and SWHeader minimize / close are full-height (48px) segments on the window-area face, no gap, top and bottom on the object surface border; no line around the license button. - File name: the measured steps use the file-name basis (header width), not the text width, so a short and a long name give the same Open / file-name widths. - File open icon: the black icon outline of every viewer icon (SWViewerIcon), no frame.
182 lines
38 KiB
Markdown
182 lines
38 KiB
Markdown
# @hm-design/sw 컴포넌트 카탈로그
|
||
|
||
기준: `@hm-design/sw` 0.2.0, `dist/index.d.ts` 공개 Export(2026-10-19 통합 개선 반영). 출처 Commit·빌드 도구 버전은 `dist/build-info.json`에 있습니다. 모든 Import는 `from "@hm-design/sw"`이며 CSS는 `@hm-design/sw/styles.css` 한 개입니다. 이 표에 없는 이름은 공개 API가 아닙니다.
|
||
|
||
- **단독 사용:** `SWHeader` 밖에서는 `<SWTheme>` 안에 둡니다(토큰·글꼴·버튼 초기화).
|
||
- **상태 소유:** 값은 Props, 사용자 행동은 Callback입니다. 컴포넌트는 CAD 데이터를 바꾸지 않습니다. 호스트가 Callback을 받아 Props를 갱신합니다.
|
||
- **열림 상태:** Dropdown은 `open` / `onOpenChange`(Controlled)를 주지 않으면 내부 상태로 동작합니다.
|
||
- **공통 키보드:** Click·Enter·Space 열기/닫기(Hover로는 열리지 않음), ArrowDown 열고 첫(현재) 항목 Focus, Arrow 이동, Escape·바깥 클릭·Tab 이탈 닫기(Escape는 Trigger로 Focus 복귀).
|
||
- **검증 표시:** ✅ = 2026-10-19 독립 소비 프로젝트(Tarball 설치)에서 브라우저 검증, ◻ = 소비 검증 범위 밖(Storybook 검증 기록만 있음).
|
||
- **먼저 모드:** SW 일반 모드(편집) / SW 뷰어 모드(도면 보기)를 [AI_USAGE.md](./AI_USAGE.md) §0으로 정합니다. **뷰어 모드는 §9(`SWViewer*`)만** 쓰고(예외: 창 최소화·닫기 버전의 `trailing` 끝 `SWHeaderWindowControls`, [VIEWER.md](./VIEWER.md) §2.1), 아래 §1~8은 일반 모드용입니다. 두 모드를 한 화면에 섞지 않습니다.
|
||
- **무엇을 쓸까(일반 모드):** Header 전체 → `SWHeader`(1). Header 부품 조합 → 개별 컨트롤(2). 팝업·설정창·정보창 → `SWPopup`(3). 도구 막대·탭·토글 → `SWToolButton` / `SWToolGroup`(4). 로고 클릭 2단 메뉴·최근파일 → `SWHeader homeMenu` / `SWHomeMenu`(5). 게이지바(투명도 등)는 `SWSlider`, 선택 목록(단위 등)은 `SWSelect`(3). Switch·Badge·Progress·Dialog(모달)·Label·FilterBar는 SW에 없습니다 → `@hm-design/ui`를 그대로 씁니다(필요하면 `SWPopup` children 안에).
|
||
- **무엇을 쓸까(일반 모드 하단):** 하단 명령 막대(보조기능·명령 칸·분류 탭·명령어 전체보기) → `SWFooter`, 도면 공간 탭(Model/Layout) → `SWFooterLayoutTabs`, 명령창 → `SWFooterCommandLine`(10, [FOOTER.md](./FOOTER.md)).
|
||
- **무엇을 쓸까(뷰어 모드):** Header → `SWViewerHeader`(`groups` + `trailing`), Dropdown·우클릭 → `SWViewerMenu`, 팝업·설정창·모달 → `SWViewerPanel` + `SWViewerSection`/`SWViewerField`/`SWViewerSwitch`/`SWViewerSlider`/`SWViewerInput`/`SWViewerButton`, 상태 → `SWViewerStatus`(9).
|
||
|
||
## 1. 완성형 템플릿
|
||
|
||
### `SWHeader` ✅
|
||
SW 공식 기준 Header(Figma 26:8944, 1920 × 49). 로고 · 파일 · 객체 수정 영역(그리기모드, 레이어/색상/선/문자/치수스타일, 상세보기) · 창 영역(인쇄·K, 창 이동, 최소화, 종료)과 반응형 More, 속성Bar, 속성창을 포함합니다.
|
||
|
||
| 구분 | Props / Callback |
|
||
|---|---|
|
||
| 필수 | `documentTitle: string` |
|
||
| 구성 | `hiddenControls?: SWHeaderHideableControlId[]`(로고 외 부품 제거, `home` 제거 시 정적 로고. 하위 항목 `documentNew`·`documentOpen`·`layerFreeze`·`layerLock`도 제거 — 레이아웃 변화 없음), `menuOrder?: SWHeaderMenuId[]`(5개 메뉴끼리 순서), `controls?: SWHeaderControlConfig[]`(객체 영역 전체 allowlist·순서·label) |
|
||
| 로고 오른쪽 | `documentOpenPlacement?: "menu" \| "header"`(기본 `menu` = 기존 Dropdown 하단. `header` = 로고 바로 오른쪽에 파일명과 같은 면의 Open 버튼, Dropdown의 Open은 숨김. 둘 다 `onDocumentOpen`·`documentOpenLabel`), `leading?: ReactNode`(Open 뒤·파일명 앞 추가 부품, 예: `SWToolButton appearance="document"`) |
|
||
| 로고 | `logo?: ReactNode`, `logoSrc?: string`, `logoAlt?: string`, `onHomeClick`(`homeMenu`가 없을 때만 호출) |
|
||
| 로고 클릭 메뉴 | `homeMenu?: SWHeaderHomeMenu`(= `SWHomeMenu` Props에서 열림 상태 제외, 5절), `homeMenuOpen`, `defaultHomeMenuOpen`(기본 false), `onHomeMenuOpenChange(open, reason: SWHeaderHomeMenuChangeReason)` |
|
||
| 파일 | `documents`, `activeDocumentId`, `documentMenuOpen`, `onDocumentMenuOpenChange`, `onDocumentSelect`, `onDocumentClose`, `onDocumentNew`, `onDocumentOpen`, `onDocumentClick`, `documentIcon`, `documentNewLabel`, `documentOpenLabel` |
|
||
| 레이어 | `layer`, `layers`, `activeLayerId`, `layerMenuOpen`, `onLayerMenuOpenChange`, `onLayerSelect`, `onLayerVisibilityChange`, `onLayerFreezeChange`, `onLayerLockChange`, `onLayerDetail`, `onLayerOpen` |
|
||
| 색상 | `color`, `colors`, `userColors`, `colorMode`, `colorMenuOpen`, `onColorMenuOpenChange`, `onColorSelect`, `onColorModeChange`, `onColorInput`, `onColorPick`, `onColorDetail`, `onColorOpen` |
|
||
| 선스타일 | `lineStyle`, `lineTypes`, `lineWeights`, `activeLineTypeId`, `activeLineWeightId`, `lineStyleMenuOpen`, `onLineStyleMenuOpenChange`, `onLineTypeSelect`, `onLineWeightSelect`, `onLineWeightValueChange`, `onLineScaleChange`, `onLineStyleDetail`, `onLineStyleOpen` |
|
||
| 문자/치수 | `textStyle`, `textStyles`, `activeTextStyleId`, `textStyleMenuOpen`, `onTextStyleMenuOpenChange`, `onTextStyleSelect`, `onTextStyleDetail`, `onTextStyleOpen` / `dimensionStyle`, `dimensionStyles`, `activeDimensionStyleId`, `dimensionStyleMenuOpen`, `onDimensionStyleMenuOpenChange`, `onDimensionStyleSelect`, `onDimensionStyleDetail`, `onDimensionStyleOpen` |
|
||
| 상세 | `propertyBar`, `propertyBarOpen`, `defaultPropertyBarOpen`, `onPropertyBarOpenChange`, `onPropertyBarToggle`, `propertyPanel`, `propertyPanelOpen`, `onPropertyPanelOpenChange`, `onPropertyPanelToggle` |
|
||
| 창 | `onPrint`, `onPopupGuide`, `onWindowMoveStart(PointerEvent)`, `onMinimize`, `onClose` |
|
||
| 기타 | `activeMenu`, `disabled`(창 버튼 제외), `drawingModeLabel`, `tools?: ReactNode`(객체 영역 메뉴 뒤), `<header>` HTML 속성·`ref` |
|
||
|
||
- 데이터 배열(`layers`, `colors`, `lineTypes`/`lineWeights`, `textStyles`, `dimensionStyles`, `documents`)을 주지 않으면 해당 필드는 Dropdown 없는 버튼입니다.
|
||
- 반응형(2026-10-21): Header 폭 760px 이상에서는 More로 옮기지 않습니다. 레이어·색상·선스타일·문자스타일·치수스타일 5개 메뉴와 타이틀은 항상 보이고, 좁아지면 그리기모드 텍스트·선/치수 그림 숨김 → 파일명 축소(최소 96px, `…`) → 메뉴 값 `…` 순으로 줄입니다. 1080px 미만(1024 등)은 아이콘·색상 칩·폰트명을 숨긴 텍스트만, 900px 이하는 선스타일 필드에서 가중치·스케일을 숨깁니다. 모든 값과 타이틀이 잘리지 않는 폭은 약 1,200px 이상입니다. 760px 미만은 기존 More 동작을 유지합니다.
|
||
- 반응형(More·대표 필드 전환·창 영역 축소)은 **`SWHeader` 안에서만** 동작합니다(CSS container `hm-sw-header`). 조합형 구성이 반응형이어야 하면 `controls` + `documentOpenPlacement` + `leading` + `tools`로 `SWHeader` 안에서 구성합니다(예제 F).
|
||
- (760px 미만) 로고 옆 Open은 실제 공간을 측정해 넘칠 때만 More로 이동하고, 그 시점보다 Open 폭만큼 넓어지면 돌아옵니다. Open이 보이는 동안 파일명이 먼저 줄고 레이어 필드는 Figma 폭을 유지합니다.
|
||
- (760px 미만) 메뉴도 고정 폭만이 아니라 실제 남은 공간을 기준으로 More에 옮기고 공간이 생기면 원래 자리·순서로 돌려놓습니다(Breakpoint는 그대로, 추가 Prop 없음). 메뉴를 열고 닫아도 Header 요소의 위치·폭은 바뀌지 않습니다.
|
||
```tsx
|
||
<SWHeader documentTitle={name} logoSrc={logo} logoAlt="제품명" layers={layers} activeLayerId={id} onLayerSelect={l => setId(l.id)} onClose={closeWindow} />
|
||
```
|
||
|
||
## 2. 개별 컨트롤 (조합용)
|
||
|
||
| 컴포넌트 | 용도 | 주요 Props / Callback | 크기(Figma) | 상태 | 검증 |
|
||
|---|---|---|---|---|---|
|
||
| `SWTheme` | 단독 사용 범위(토큰·글꼴·초기화). 배치는 정하지 않음 | `div` HTML 속성, `className`, `style`(토큰 override — 가장 바깥 SW 범위에서 지정하면 안쪽 Header·Dropdown·More·Panel·명령창이 상속, [AI_USAGE.md](./AI_USAGE.md) §3.1) | — | — | ✅ |
|
||
| `SWHeaderHome` | 로고 슬롯 + 홈 버튼 | `logo`, `logoSrc`, `logoAlt`, `onClick`, `interactive`(false = 정적 로고) | 80 × 48, 로고 슬롯 32 × 17, 오른쪽 −17px로 다음 파일 면과 겹침 | Hover 배경 교체, Focus | ✅ |
|
||
| `SWHeaderDocumentTitle` | 파일명 + 문서 Dropdown(+ New / Open) | `title`(필수), `documents`, `activeDocumentId`, `menuOpen`, `onMenuOpenChange`, `onDocumentSelect`, `onDocumentClose`, `onNew`, `onOpen`, `onClick`, `documentIcon`, `newLabel`, `openLabel`, `label`, `showNew` / `showOpen`(기본 true, 둘 다 false면 하단 없음) | 높이 48, 폭 190–310(반응형 clamp), 메뉴 310 | 텍스트만 Hover #FFC600, 열림 화살표 회전 | ✅ |
|
||
| `SWHeaderLayerMenu` | 레이어 필드 + Dropdown | `value`(필수), `layers`(필수), `activeLayerId`, `open`, `onOpenChange`, `onClick`, `selected`, `disabled`, `onLayerSelect`, `onVisibilityChange`, `onFreezeChange`, `onLockChange`, `onDetail`, `label`, `showFreeze` / `showLock`(기본 true. false = 그 상태를 그리지 않고 20px 자리만 유지) | 필드 234 × 38, 메뉴 234 | Hover 링, Selected, Expanded, 행 Hover | ✅ |
|
||
| `SWHeaderColorMenu` | 색상 필드 + Dropdown(ByLayer/ByBlock, 팔레트, 사용자 색, 추출, RGB 입력) | `value`, `colors`(필수), `userColors`, `mode`, `open`, `onOpenChange`, `onClick`, `selected`, `disabled`, `onColorSelect`, `onModeChange`, `onColorInput`, `onPick`, `onDetail`, `label` | 필드 192 × 38 | 칩 선택 시 열림 유지 | ✅ |
|
||
| `SWHeaderLineStyleMenu` | 선스타일 필드 + 3열 Dropdown | `value`, `lineTypes`, `lineWeights`, `activeLineTypeId`, `activeLineWeightId`, `open`, `onOpenChange`, `onClick`, `selected`, `disabled`, `onLineTypeSelect`, `onLineWeightSelect`, `onLineWeightValueChange`, `onScaleChange`, `onDetail`, `label` | 필드 284 × 38, 열 182·142·142(필드 중앙 정렬) | 열별 선택, 열림 유지 | ✅ |
|
||
| `SWHeaderTextStyleMenu` | 문자스타일 필드 + 목록 | `value`, `textStyles`(필수), `activeTextStyleId`, `onTextStyleSelect`, `open`, `onOpenChange`, `onClick`, `selected`, `disabled`, `onDetail`, `label` | 필드 164 × 38 | 선택 시 닫힘 | ✅ |
|
||
| `SWHeaderDimensionStyleMenu` | 치수스타일 필드 + 목록 | `value`, `dimensionStyles`(필수), `activeDimensionStyleId`, `onDimensionStyleSelect`, 열림·`onDetail`·`label` 동일 | 필드 164 × 38 | 선택 시 닫힘 | ✅ |
|
||
| `SWHeaderLayerControl` · `SWHeaderColorControl` · `SWHeaderLineStyle` · `SWHeaderTextStyle` · `SWHeaderDimensionStyle` | Dropdown 없는 필드 버튼(호스트가 자체 팝업을 열 때) | `value`(필수), `label`, `selected`, `disabled`, `onClick`, `expanded`, `controls`, `buttonRef` / `SWHeaderLayerControl`은 `state`(표시·동결·잠금), `showFreeze` / `showLock` | 위 필드 크기와 같음 | Hover 링, Selected | ◻ |
|
||
| `SWHeaderActions` | 인쇄·K 버튼 pill | `onPrint`, `onPopupGuide`, `disabled`, `showPrint`, `showPopupGuide`(하나만 남기면 pill이 축소) | pill 85 × 42(버튼 40 × 38) | 아이콘 Hover, Hover 링, K 가이드 미리보기(반복 Motion, Reduced Motion 정적) | ✅ |
|
||
| `SWHeaderWindowControls` | 창 이동·최소화·종료 | `onWindowMoveStart`, `onMinimize`, `onClose`, `showWindowMove`, `showMinimize`, `showClose` | 이동 88 × 48, 버튼 32 × 48 | 창 이동 Hover Motion 1.4s, 종료 Hover 자산 | ◻ |
|
||
| `SWHeaderProperties` | 상세보기 / 속성Bar · 속성창 토글 | `barOpen`, `panelOpen`, `panelId`, `disabled`, `onBarToggle`, `onPanelToggle`, `showCaption`, `showBar`, `showPanel` | 157 × 38 | 텍스트 Hover #FFC600 | ◻ |
|
||
| `SWHeaderPropertyBar` | 28px 속성 편집 띠 | `selection`, `properties`, `onPropertyChange`, `readOnly`, `disabled`, `div` 속성 | 높이 28, 콘텐츠 폭 | Input 상태 | ◻ |
|
||
| `SWHeaderPropertyPanel` | 데이터 기반 속성창(필드 타입 6종 `text`·`number`·`select`·`color`·`slider`·`computed` + picker, 그룹 레이아웃 `rows`·`circle`·`position`, 형상 Slot) | `selection`·`properties`·`groups`(0.2.0부터 선택), `title`, `children`(그룹 뒤 자유 콘텐츠), `autoFocus`, `onPropertyChange`, `menus`(`showLayerFreeze`/`showLayerLock` 포함), `expandedGroupIds`/`defaultExpandedGroupIds`/`onExpandedGroupsChange`, `toolActive`/`onToolActiveChange`, `toolLabel`, `onOverviewClick`, `shapeContent`, `onClose`, `id`, `anchorRef`, `style` | 314 폭, 높이는 콘텐츠(최대 화면, 본문 스크롤). `anchorRef`가 있으면 고정 위치 Overlay, 없으면 문서 흐름(위치는 `style`) | 4가지 선택 상태 | ✅ |
|
||
| `SWHeaderInput` | 수정 가능한 SW Input | `value`(필수), `onValueChange`, `onCommit`(Enter·Blur, 유효 + 변경 시), `onCancel`(Escape 복원), `valueType`(`text`/`number`), `parse`, `readOnly`, `disabled`, `commitOnUnmount`, `input` 속성 | 58 × 20 기준, Hover/편집 24px | Default/Hover/편집/ReadOnly/Disabled, IME 조합 중 Enter 무시 | ✅ |
|
||
| `parseSWHeaderColor` · `parseSWHeaderNumber` | Input 검증 도우미 | `r,g,b` / `#rrggbb`, 숫자(`min`, `max`) | — | — | ◻ |
|
||
| `SWHeaderLinePreview` · `swHeaderLinePatterns` | 70 × 2 선 미리보기, CENTER/HIDDEN 패턴 | `pattern?: number[]` | 70 × 2 | — | ◻(패턴 상수만 예제 데이터에서 사용) |
|
||
|
||
## 3. Popup — 외형 고정, 콘텐츠 자유
|
||
|
||
속성창(Figma 26:11822)의 외형과 공통 동작을 그대로 쓰는 Popup입니다. Header 없이 `<SWTheme>` 안에서 씁니다. 내용은 `children`으로 자유롭게 구성합니다(SW 컨트롤, `@hm-design/ui` 컴포넌트, 소비 프로젝트 요소 모두 가능, 구조 제한 없음).
|
||
|
||
| 컴포넌트 | 용도 | 주요 Props | 크기·동작 | 검증 |
|
||
|---|---|---|---|---|
|
||
| `SWPopup` | 설정·정보·사용자 정의 Popup 프레임 | `title`(필수), `children`, `onClose`(닫기 버튼·Escape), `closeLabel`(기본 `닫기`), `titleActions`(제목 막대 닫기 버튼 앞 추가 버튼), `footer`(본문 뒤 고정 영역, 본문이 스크롤해도 보임), `autoFocus`(열릴 때 Focus, 안에서 닫히면 원래 위치로 복귀. 기본: `anchorRef`가 있으면 true, 없으면 false), `anchorRef`(기준 요소 아래 고정 Overlay), `style`·`className`·`div` 속성 | 폭 314, 제목줄 30, 높이는 콘텐츠(최대 화면 − 8px, `style.maxHeight`로 더 줄일 수 있음) → 본문 스크롤. Non-modal(Dim·Portal·Focus trap 없음) | ✅ |
|
||
| `SWPopupSection` | 속성창 그룹 면(제목 + 내용) | `title`, `children`, `section` 속성 | 그룹 제목 700·70% 검정, 내용 면 `--hm-sw-property-content` | ✅ |
|
||
| `SWPopupRow` | 속성창 한 줄(라벨 + 값) | `label`(필수), `htmlFor`, `children`(값 컨트롤, SW 필드는 `SWHeaderInput`), `unit`, `field`(`box` 기본 · `compact` · `none`), `numeric`(숫자 편집 On), `readOnly`, `disabled` | 행 최소 32, 라벨 72, 값 상자 28(Default·Hover 테두리, 숫자 편집 시 #0F0D0A). `compact` = 41px hug 숫자 필드 | ✅ |
|
||
| `SWSlider` | 게이지바(native range, 2026-10-20). `SWPopupRow field="none"` 안이나 `SWTheme` 안 어디든 | `value`(필수), `min`(0)·`max`(100)·`step`(1), `onValueChange`(드래그·키보드마다), `onValueCommit`(값 확정 = native `change`), `appearance`(`"panel"` 기본 · `"property"`), `disabled`, `aria-label`, `input` 속성 | 모양만 다르고 값·이벤트·키보드는 같음. `panel` = 지금까지 Popup에서 쓰던 게이지바(6px 트랙 · 18px 흰 Thumb + 2px 녹색 테두리, `SWViewerSlider`와 같은 모양), `property` = 속성창 게이지바(베이지 트랙 · 빨강 채움 · Figma Thumb 14px). 폭은 행을 채움(호스트가 `style.width`로 지정 가능). Disabled 40% | ◻ |
|
||
| `SWPopupPropertyRow` | **Popup 안 레이어·색상·선스타일 선택 행의 공식 컴포넌트**(2026-10-20). 속성창 한 줄 | `property`(`SWHeaderProperty`: `name`·`value`·`type`. 레이어 = `type: "select"` + `picker: "layer"` + `options`, 색상 = `type: "color"`(picker 자동), 선스타일 = `type: "select"` + `linePreview: true` 또는 `picker: "lineStyle"`), `menus`(`SWHeaderPropertyMenus`: `layers`·`colors`·`lineTypes`·…), `onPropertyChange(property, value)`(선택한 행 id 또는 입력값, 호스트가 `property`를 갱신), `className` | `SWHeaderPropertyPanel` 행과 같은 DOM·모양·동작(속성창 `picker` 필드, 목록은 고정 Overlay라 스크롤 본문에 잘리지 않음). **SWHeader 필드 Dropdown(`SWHeaderLayerMenu` 등)을 Popup에 넣지 않습니다** | ◻ |
|
||
| `SWSelect` | 선택 목록(native select, 2026-10-20). `SWPopupRow field="none"`, `SWViewerField`, `SWTheme` 안 어디든 | `value`/`defaultValue`, `options`(`SWSelectOption[]` = `{ value, label?, disabled? }`) 또는 `<option>` children, `onValueChange(value)`, `disabled`, `id`·`aria-label`, `select` 속성 | 28px, 좌우 8, 1px `#948871`, radius 4, 면 `#F1ECE1`, 12px 검정, 플랫폼 화살표·옵션 목록. Popup 도면 설정 단위 = Viewer 축척 지정 단위. Disabled 40% | ◻ |
|
||
| `SWHeaderPropertyPanel` | 데이터 기반 속성창(2절). 같은 프레임이며 `children`도 받음 | 2절 | 같은 DOM·class | ✅ |
|
||
|
||
- **Escape·Focus:** Popup 안의 Escape는 그 Popup만 닫습니다. 바깥의 Escape는 가장 최근에 열리거나 사용한(Focus·클릭) Popup 하나만 닫습니다. Dropdown·편집 중인 Input처럼 Escape를 이미 처리한 요소(`preventDefault` / 전파 중단)가 있으면 Popup은 닫히지 않습니다.
|
||
- **Popup 안 선택 필드(2026-10-20 사용자 확정, [DESIGN_RULES.md](./DESIGN_RULES.md) §8):** Popup의 레이어·색상·선스타일은 `SWPopupPropertyRow`로 둡니다. SWHeader 필드 Dropdown(`SWHeaderLayerMenu`·`SWHeaderColorMenu`·`SWHeaderLineStyleMenu`·`SWHeaderTextStyleMenu`·`SWHeaderDimensionStyleMenu`)은 Header 전용 디자인이라 Popup에 넣지 않습니다(Popup 안에서도 열리기는 하지만 지원하는 조합이 아닙니다). 이름 목록에서 고르는 일반 선택은 `SWSelect`입니다. 문자·치수 스타일의 속성창 `picker`는 없으므로, Popup에 문자·치수 스타일 선택 행이 필요하면 새로 만들지 말고 부족한 API로 보고해 사용자에게 확인합니다.
|
||
- **Popup 하단 버튼(적용·취소)의 일반 모드 SW 전용 디자인은 아직 없습니다.** 자리는 `footer`(또는 `children`)이고 버튼은 소비 프로젝트 버튼이나 `@hm-design/ui`의 `Button`을 둡니다. 뷰어 전용 `SWViewerButton`을 일반 모드 Popup에 쓰지 않습니다. 어두운 `SWToolButton`을 밝은 Popup에 강제로 쓰지 않습니다.
|
||
|
||
## 4. 도구 막대 — 기존 SW 버튼 3종
|
||
|
||
**일반 모드** 도구 막대입니다. 새 디자인 값 없이 기존 SW 버튼 모양을 공개 버튼으로 씁니다(일반 모드 `SWHeader`에 더하는 Model/Layout, Fit, 2.5D, 파일 열기 등). 뷰어 모드 화면은 §9 `SWViewerHeader` 항목을 씁니다. `SWHeader`의 `tools`·`leading` 안이나 `<SWTheme>` 안에 둡니다.
|
||
|
||
| 컴포넌트 | 용도 | 주요 Props | 모양(기존 기준) | 검증 |
|
||
|---|---|---|---|---|
|
||
| `SWToolButton` | 버튼·토글 | `appearance`(`text` 기본 / `pill` / `document`), `pressed`(토글·선택), `children`(글자. `pill`은 접근성 이름으로만 사용), `icon`·`hoverIcon`(`pill`), `button` 속성 | `text` = 속성Bar·속성창 글자 토글(700, Hover·선택 #FFC600, 행 19px). `pill` = 인쇄·K 40 × 38(노란 Hover 링, 아이콘 24 × 23 영역). `document` = 파일명 면(48px, 글자만 Hover #FFC600). Home 바로 뒤에 두면 로고 사선 접점을 그대로 공유 | ✅ |
|
||
| `SWToolGroup` | 버튼 묶음 | `appearance`(`text` 기본 = 상세보기 묶음, `pill` = 인쇄·K pill), `label`(`text`의 12px 캡션·접근성 이름), `selection`(`single` = radiogroup, 화살표·Home·End로 이동·선택), `div` 속성 | 버튼 사이 1px 구분선(`text`), 내용 폭 pill | ✅ |
|
||
|
||
- 탭(Model / Layout)은 별도 컴포넌트 없이 `SWToolGroup selection="single"` + `SWToolButton pressed`입니다.
|
||
- 일반 모드의 상태 표시(로드 상태 등) 전용 SW 디자인은 아직 없습니다(디자인 확정 후 검토). 뷰어 모드는 `SWViewerStatus`(§9)가 있으며 일반 모드 Header에 가져오지 않습니다.
|
||
|
||
## 5. 로고 클릭 메뉴 — Figma 2단 Header 메뉴 (SW 일반 모드 전용)
|
||
|
||
> **SW 일반 모드(`SWHeader`)에서만 씁니다.** SW 뷰어 모드(§9 `SWViewer*`)에는 홈 메뉴가 없으며 이 절의 컴포넌트를 뷰어 화면에 넣지 않습니다([AI_USAGE.md](./AI_USAGE.md) §0.3).
|
||
|
||
Figma 26:10591(home on), 타일 15종 26:11355 … 26:11631, 섹션 제목 26:12604 … 26:12622, 최근파일 상태 662:67267 · 목록 662:67331 · 2뎁스 미리보기 662:67471을 **공통 컴포넌트 4개**로 표현합니다. 메뉴 항목·아이콘·제목·Active·이벤트·최근파일은 모두 데이터입니다(패키지에는 항목·아이콘이 없음). 운영체제 파일 선택창이 아니며, "찾아열기" 등의 실제 동작은 호스트가 `onSelect`에서 수행합니다.
|
||
|
||
| 컴포넌트 | 용도 | 주요 Props | 크기·동작 | 검증 |
|
||
|---|---|---|---|---|
|
||
| `SWHomeMenu` | 2단 메뉴 전체(섹션 여러 개). 보통 `SWHeader homeMenu`로 씀 | `sections`(`SWHomeMenuSectionData[]`) 또는 `children`, `open`/`defaultOpen`(false)/`onOpenChange(open, reason)`, `activeIds`/`defaultActiveIds`/`onActiveChange`, `selection`(`multiple` 기본 / `single`), `onItemSelect`, `closeOnBackgroundClick`(true), `closeOnSelect`(false), `closeOnEscape`(true), `closeOnOutsideClick`(false), `autoFocus`(true), `returnFocusRef`, `accent`(`auto`/`sections`/`outline`), `moreLabel`("더보기") | 높이 77(섹션 75 + 강조 2), 섹션 폭은 타일 수로 자동. 좁으면 들어가는 섹션만 표시하고 나머지는 더보기(⋯) Dropdown의 텍스트 메뉴(섹션 제목 + 항목, 같은 Active·Callback·하위 패널)로 이동(가로 스크롤 없음, 넓어지면 복귀) | ✅ |
|
||
| `SWHomeMenuSection` | 섹션(제목 badge + 타일 그룹) | `title`, `children` | badge 폭 = 글자 + 46px | ✅ |
|
||
| `SWHomeMenuItem` | 80 × 46 타일(Default / Hover / Active) | 데이터 `SWHomeMenuItemData`: `id`, `label`, `icon`, `hoverIcon`, `toggle`(기본: `panel` 있는 항목만 true = 패널이 열린 동안 Active, 나머지는 실행 버튼 = 클릭 후 ON 없음. true = 켜고 끄기 유지), `panel`, `panelLabel`, `disabled`, `hidden`, `title`, `onSelect`. 메뉴 밖 단독이면 `active`/`defaultActive`/`onActiveChange` | Hover·Active = 주황 gradient 1px 테두리 + `#FF5C00` 아이콘·글자 | ✅ |
|
||
| `SWRecentFiles` | 선택 하위 패널: 최근파일 목록(2026-10-21부터 `files` 중 앞 **최대 3개**만 표시, 배열 자체는 자르지 않음). Hover·Focus한 행 옆에 2뎁스 미리보기 패널(310 × 270)을 표시합니다: 제목 = `previewTitle`, 없으면 **`path` + 파일명**(`path`가 이미 파일명으로 끝나면 그대로, `path`가 없으면 `name`), 본문 = 미리보기 없음 표시(**갈색 패널 `#62533D` 가운데 빨간 금지 표시 `#FF0000`**). `preview`·`renderPreview`는 호환용으로 받기만 하고 이미지·썸네일을 렌더링하지 않음(타입 변경 없음) | `files`(`SWFileEntry[]`: `id`, `name`, `path`, `badge`, `preview`, `previewTitle`, `disabled`), `onFileOpen`, `onFileHover`, `renderPreview`, `closeOnOpen`(true), `emptyText` | 폭 354, 행 50, 미리보기 310 × 270 | ✅ |
|
||
|
||
- **Header 연결:** `SWHeader`의 `homeMenu`에 `SWHomeMenu` Props를 주면 됩니다. 기본 숨김, 로고 클릭 열기, 다시 클릭 닫기. 위치는 SWHeader가 실제 DOM으로 정합니다(객체 수정 영역 −2px ~ 창 영역, 고정 x 없음. `controls`에 `document`가 있으면 파일명 오른쪽 −2px부터). 로고·파일명·창 영역은 가리지 않습니다.
|
||
- **이벤트 우선순위:** `homeMenu`가 있으면 로고 클릭은 메뉴 열기·닫기만 하고 `onHomeClick`을 호출하지 않습니다(의도하지 않은 홈 이동 방지). 상태 알림은 `onHomeMenuOpenChange`(`reason`: `home`, `escape`, `background`, `outside`, `select`, `file`, `document`).
|
||
- **New / Open:** 기존 문서 Dropdown 안(`documentOpenPlacement="menu"` 기본) 그대로입니다. 메뉴의 "찾아열기"·"새파일"에 같은 동작이 필요하면 호스트가 `onDocumentOpen`·`onDocumentNew`와 같은 함수를 `onSelect`에 연결합니다. 메뉴가 열리면 필드 Dropdown·문서 Dropdown이 닫히고, 문서 Dropdown을 열면 메뉴가 닫힙니다(`reason: "document"`).
|
||
- **Escape·Focus:** 메뉴 안의 Escape는 열린 하위 패널 → 메뉴 순서로 하나씩 닫고, 메뉴가 닫히면 로고로 Focus를 돌립니다. 메뉴는 Popup Escape 순서(3절)에 함께 들어가므로 Focus가 메뉴·Popup 밖이면 가장 최근에 열거나 사용한 하나만 닫힙니다. Popup 안의 Escape는 그 Popup만 닫습니다.
|
||
- **하위 패널 닫기:** 패널 안 콘텐츠는 `useSWHomeMenuClose()`로 메뉴 전체를 닫을 수 있습니다(`SWRecentFiles`는 파일을 열면 자동).
|
||
|
||
## 6. 공개 타입
|
||
|
||
`SWHeaderProps`, 각 컴포넌트 Props(`SWHeaderHomeProps`, `SWHeaderDocumentTitleProps`, `SWHeaderLayerControlProps`, `SWHeaderLayerMenuProps`, `SWHeaderColorMenuProps`, `SWHeaderLineStyleMenuProps`, `SWHeaderTextStyleMenuProps`, `SWHeaderDimensionStyleMenuProps`, `SWHeaderInputProps`, `SWHeaderPropertiesProps`, `SWHeaderPropertyPanelProps`, `SWHeaderPropertyBarProps`, `SWHeaderActionsProps`, `SWHeaderWindowControlsProps`), `SWThemeProps`, `SWPopupProps`, `SWPopupSectionProps`, `SWPopupRowProps`, `SWPopupPropertyRowProps`, `SWSliderProps`, `SWSliderAppearance`(`"panel"` / `"property"`), `SWSelectProps`, `SWSelectOption`, `SWToolButtonProps`, `SWToolButtonAppearance`, `SWToolGroupProps`, `SWHeaderMenuId`, `SWHeaderControlId`, `SWHeaderControlConfig`, `SWHeaderFrameControlId`, `SWHeaderSubControlId`, `SWHeaderHideableControlId`, `SWHeaderDocument`, `SWHeaderLayer`, `SWHeaderLayerValue`, `SWHeaderColorValue`, `SWHeaderColorOption`, `SWHeaderColorMode`, `SWHeaderColorInputValue`, `SWHeaderLineStyleValue`, `SWHeaderLineType`, `SWHeaderLineWeight`, `SWHeaderTextStyleValue`, `SWHeaderTextStyleOption`, `SWHeaderDimensionStyleValue`, `SWHeaderDimensionStyleOption`, `SWHeaderInputValueType`, `SWHeaderProperty`, `SWHeaderPropertyType`, `SWHeaderPropertyPicker`, `SWHeaderPropertyMenus`, `SWHeaderPropertyGroup`, `SWHeaderPropertySelection`, `SWHeaderPropertyShapeContent`, `SWHeaderPropertyShapeContext`, `SWHeaderHomeMenu`, `SWHeaderHomeMenuChangeReason`, `SWHomeMenuProps`, `SWHomeMenuSectionProps`, `SWHomeMenuItemProps`, `SWHomeMenuItemData`, `SWHomeMenuSectionData`, `SWHomeMenuSelectEvent`, `SWHomeMenuCloseReason`, `SWHomeMenuAccent`, `SWRecentFilesProps`, `SWFileEntry`. 뷰어 모드 타입은 §9.
|
||
|
||
## 7. 공개하지 않은 것 (사용 금지)
|
||
|
||
`useSWPopupStack`, `SWHeaderMore`, `SWHeaderField`/`SWHeaderFieldText`, `SWHeaderKGuide`, `useSWHeaderDropdown`, `SWHeaderMenuDetail`, `SWHeaderColorChip`, `SWHeaderLayerRows`, `SWHeaderColorPanelBody`, `SWHeaderLineStyleColumns`, `SWPopupFrame`, `useSWFixedDropdownPosition`, 속성창 내부 Picker, `useSWHeaderOverlay` 등은 내부 구현입니다. 필요하면 공개 컴포넌트로 대체하거나, 부족한 API로 보고합니다.
|
||
|
||
## 8. 알려진 단독 사용 제약
|
||
|
||
| 항목 | 내용 | 대응 |
|
||
|---|---|---|
|
||
| 반응형 More | `SWHeader` 전용. `SWTheme`로 직접 배치한 조합 Header에는 More·필드 이동이 없음 | 반응형이 필요하면 `SWHeader`의 `controls`·`documentOpenPlacement`·`leading`·`tools`로 구성(예제 F). 직접 배치하면 폭은 소비 앱이 정함 |
|
||
| `SWHeaderDocumentTitle` 왼쪽 테두리 | 앞의 로고와 겹치는 전제로 왼쪽 테두리가 없음 | 로고 없이 첫 칸이면 소비 레이아웃 wrapper에 1px 테두리(예제 C) |
|
||
| `SWHeaderDocumentTitle` 폭 | `clamp(190px, 100cqw − 1610px, 310px)`; Header 밖에서는 cqw가 뷰포트 기준 | flex 부모 안에 둔다. 1920 뷰포트에서 310px |
|
||
| 창 영역 배경 | 배경·테두리는 `SWHeader`의 창 영역에 있음 | 소비 레이아웃이 토큰으로 표면 작성(예제 B·C) |
|
||
| Dropdown 위치 | `SWHeader` 안이면 헤더, 밖이면 뷰포트 안으로 좌우 보정. `SWPopup`·속성창 안이면 고정 위치 Overlay | Popup 밖에서는 부모에 `overflow: hidden`을 두지 않는다 |
|
||
| 파일 열기 뒤 파일명 여백 | `SWToolButton appearance="document"` 바로 뒤의 파일명은 왼쪽 여백 12px(로고 아래가 아니므로) | 패키지 CSS가 처리. 소비 코드에서 조정하지 않음 |
|
||
|
||
## 9. 뷰어 모드 (`SWViewer*`)
|
||
|
||
SW **뷰어 모드** 전용 Export입니다(2026-10-19 추가, 참고 DWG/DXF 뷰어 실측 기준). 모드 선택은 [AI_USAGE.md](./AI_USAGE.md) §0, Props 상세·상태·금지 사항은 [VIEWER.md](./VIEWER.md), 토큰은 [DESIGN_RULES.md](./DESIGN_RULES.md) §11, 조합은 [COMPOSITION_PATTERNS.md](./COMPOSITION_PATTERNS.md) 7과 [예제 H](./examples/ExampleH-ViewerMode.tsx)를 봅니다. 일반 모드 화면에서는 쓰지 않습니다. `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`은 루트에 `hm-sw-theme`을 가지므로 `<SWTheme>`가 필요 없습니다.
|
||
|
||
| 컴포넌트 | 용도 | 주요 Props | 검증 |
|
||
|---|---|---|---|
|
||
| `SWViewerHeader` | 52px 뷰어 Header(로고 면 → 파일명 면 → 메뉴 그룹 → 오른쪽 끝), 반응형 More. 로고 클릭 = 파일 열기 메뉴(`SWHeader` `...` 메뉴 모양), 파일명 클릭 = 문서 목록(`SWHeaderDocumentTitle`, + New 없음, `onDocumentOpen`이 있으면 아래 Open), 두 메뉴는 동시에 열리지 않음 | `groups: SWViewerHeaderGroup[]`(필수), `onCommand(SWViewerCommand)`, `documentTitle`(`string \| null`), `documentPlaceholder`, `documentTooltip`, `document`, `logoMenu`(`{ title?, items: { id, label, icon?, value?, checked?, disabled?, hidden?, onSelect? }[] }`, 기본 없음), `documents`(`SWHeaderDocument[]`), `activeDocumentId`, `onDocumentSelect`, `onDocumentOpen`(있을 때만 목록 아래 Open), `documentOpenLabel`(기본 `Open`), `logo`, `logoSrc`, `logoAlt`, `onHomeClick`, `trailing`, `moreLabel`, `toolbarLabel`, `<header>` 속성·`ref` | ◻ |
|
||
| `SWViewerHeaderButton` | `trailing`·`custom` 항목용 Header 버튼(정보 버튼 등) | `label`(필수), `icon`, `iconOnly`(`true` = 32 × 40, `"compact"` = 34 × 34), `pressed`(주면 토글), `button` 속성 | ◻ |
|
||
| `SWViewerMenu` | 단독 Dropdown·우클릭 메뉴(Header `type: "menu"`와 같은 메뉴) | `entries: SWViewerMenuEntry[]`, `open`, `onOpenChange`(필수), `anchorRef` 또는 `anchorPoint`, `align`(`start`/`end`), `width`, `surface`(`light` 기본 / `beige` = More 면), `label`, `onEntrySelect`, `initialFocus`(`first`/`menu`), `id`, `className` | ◻ |
|
||
| `SWViewerIcon` | 직접 그린 아이콘에 SW 아이콘 외곽선(SVG stroke) 적용 | `children`(필수), `className` | ◻ |
|
||
| `SWViewerPanel` | 뷰어 팝업·설정창·모달(프레임은 `SWPopup`) | `title`·`open`·`onClose`(필수), `closeLabel`, `headerActions`, `children`, `footer`, `width`(314)·`height`(420 / `"auto"`)·`minWidth`·`minHeight`, `defaultPosition`(`{ left, top }` 또는 `SWViewerPanelPlacement`), `inset`, `strategy`(`fixed`/`absolute`), `draggable`, `resizable`, `collapsible`, `defaultCollapsed`, `collapsed`, `onCollapsedChange`, `modal`, `autoFocus`, `onPositionChange`, `onSizeChange`, `div` 속성 | ◻ |
|
||
| `SWViewerSection` | 패널 콘텐츠 묶음(12px 700 제목) | `title`, `surface`(`card` 기본 / `plain`), `children`, `section` 속성 | ◻ |
|
||
| `SWViewerField` | 라벨 + 컨트롤 행 | `label`(필수), `children`(노드 또는 `(id) => 노드`), `htmlFor`, `layout`(`inline` 기본 / `stacked`), `unit`, `below`, `disabled` | ◻ |
|
||
| `SWViewerSwitch` | 스위치 | `checked`(필수), `onCheckedChange`, `button` 속성 | ◻ |
|
||
| `SWViewerSlider` | 슬라이더(native range). 내부는 `SWSlider appearance="panel"` + 뷰어 패널 토큰(2026-10-20, 모양 동일) | `value`·`min`·`max`(필수), `step`, `onValueChange`, `input` 속성 | ◻ |
|
||
| `SWViewerInput` | 28px 패널 Input(native input) | `input` 속성 전체 | ◻ |
|
||
| `SWViewerButton` | 패널 버튼 | `variant`(`outline` / `primary` / `ghost`), `tone`(`"green"`), `icon`, `button` 속성 | ◻ |
|
||
| `SWViewerBadge` | 개수 Badge | `children`(필수), `span` 속성 | ◻ |
|
||
| `SWViewerHint` | 12px 보조 설명 | `p` 속성 | ◻ |
|
||
| `SWViewerStatus` | Header 불러오기 상태(`trailing`) | `state: SWViewerStatusState`(`idle`/`loading`/`ready`/`error`, 필수), `label`, `detail`, `div` 속성 | ◻ |
|
||
|
||
- **공개 타입:** `SWViewerHeaderProps`, `SWViewerHeaderButtonProps`, `SWViewerMenuProps`, `SWViewerIconProps`, `SWViewerPanelProps`, `SWViewerPanelPlacement`(`"top-end"` / `"top-start"` / `"center"`), `SWViewerSectionProps`, `SWViewerFieldProps`, `SWViewerSwitchProps`, `SWViewerSliderProps`, `SWViewerInputProps`, `SWViewerButtonProps`, `SWViewerBadgeProps`, `SWViewerStatusProps`, `SWViewerStatusState`, `SWViewerHeaderItem`(`button`·`toggle`·`menu`·`tabs`·`switch`·`custom`), `SWViewerHeaderGroup`, `SWViewerMenuEntry`(`item`·`checkbox`·`radio`·`submenu`·`label`·`separator`), `SWViewerCommand`(`id`, `itemId`, `value`).
|
||
- **검증 표시:** 뷰어 Export는 이 카탈로그 기준의 독립 소비 프로젝트(Tarball) 브라우저 검증 기록이 없어 ◻입니다. 예제 H는 공개 Export만 사용합니다.
|
||
- 상세 크기·상태는 [VIEWER.md](./VIEWER.md) §2~4가 기준입니다. 이 표에 없는 Props(`items`, `content`, `renderBody` 등)는 없습니다.
|
||
|
||
- **레이어 Popup 가시성(필수):** SW Viewer 레이어 Popup에서 레이어 표시·숨김 기능은 반드시 HMDesign의 눈(Eye/EyeOff) 아이콘 버튼을 사용한다. Toggle Switch로 대체하지 않는다. 행 구성·크기·접근성 이름은 [VIEWER.md](./VIEWER.md) §4.1, 예제 H. `SWViewerSwitch`는 옵션 ON/OFF 전용입니다.
|
||
|
||
## 10. Footer (`SWFooter*`, SW 일반 모드)
|
||
|
||
하단 명령 막대(2026-10-20 추가, Figma 이지빔-SW 26:10097 하단 72px + 부품 34개, 바 안 명령창·좁은 폭은 사용자 제공 실제 화면). 상세 Props·상태·키보드·금지 사항은 [FOOTER.md](./FOOTER.md), 토큰은 [DESIGN_RULES.md](./DESIGN_RULES.md) §13, 조합은 [COMPOSITION_PATTERNS.md](./COMPOSITION_PATTERNS.md) 10과 [예제 I](./examples/ExampleI-Footer.tsx). 뷰어 모드 화면에서는 쓰지 않습니다. `SWFooter`·`SWFooterCommandLine`은 루트에 `hm-sw-theme`이 있어 `<SWTheme>`가 필요 없고, 나머지 부품은 `<SWTheme>` 안에 둡니다.
|
||
|
||
| 컴포넌트 | 용도 | 주요 Props | 검증 |
|
||
|---|---|---|---|
|
||
| `SWFooter` | 72px 하단 막대: 보조기능 버튼 → 3 × 2 보조기능 → (바 안 명령창) → 명령 칸(68 × 47) + 분류 행(24) → 명령어 전체보기, 위 오른쪽 끝 Layout 탭 | `categories: SWFooterCategory[]`(필수), `categoryId`/`defaultCategoryId`/`onCategoryChange`, `activeToolId`, `onToolSelect(toolId, categoryId, tool)`, `slotCount`(최대 칸 수, 17 / `command`가 있으면 제한 없음 — 칸 영역 폭은 바 폭으로만 결정), `onSlotAdd(slotIndex, categoryId)`, `slotGuide`(`SWFooterGuideContent \| false`), `onCategoryAdd`, `auxItems`, `onAuxPressedChange`, `onAuxItemClick`, `auxAll`/`commandAll`(`SWFooterSideAction \| false`), `command`(바 안 명령창), `status`(바 위 왼쪽 좌표), `layoutTabs`, `trailing`, `label`, `<footer>` 속성·`ref`. 좁은 폭: 빈 칸 축소 → ▲ 패널, 분류 ◀ ▶, 보조기능 아이콘만 | ◻ |
|
||
| `SWFooterSideButton` | 양끝 74 × 71 버튼(보조기능 / 명령어 전체보기) | `title`(필수), `subtitle`, `side`(`start`/`end`), `tooltip`, `button` 속성 | ◻ |
|
||
| `SWFooterAuxGroup` | 보조기능 토글 격자(Figma 3 × 2) | `items: SWFooterAuxItem[]`(필수), `onPressedChange`, `onItemClick`, `columns`(3), `label` | ◻ |
|
||
| `SWFooterAuxButton` | 보조기능 104 × 33 버튼(Hover 노랑 테두리, `pressed` = 주황 테두리·아이콘·글자) | `label`(필수), `icon`(`currentColor` 아이콘이면 상태 색 적용), `pressed`, `button` 속성 | ◻ |
|
||
| `SWFooterToolButton` | 명령 칸 68 × 47 | `label`(필수), `icon`, `activeIcon`, `pressed`, `button` 속성 | ◻ |
|
||
| `SWFooterAddSlot` | 빈 칸(+), Hover 가이드 | `guide`(기본 `false` = 없음, `{}` = Figma 가이드), `guideOpen`, `onGuideOpenChange`, `button` 속성 | ◻ |
|
||
| `SWFooterGuide` | 빈 칸 안내 카드 208 × 149 | `title`(`명령어 등록`), `caption`(`빠른사용`), `media`, `div` 속성 | ◻ |
|
||
| `SWFooterMenu` | 분류 행(현재 탭 Pocket, 넘치면 ◀ ▶) | `items: SWFooterMenuItem[]`·`value`(필수), `onValueChange`, `onAdd`, `addLabel`, `label`, `panelId`, `tabIdPrefix` | ◻ |
|
||
| `SWFooterLayoutTabs` | 도면 공간 탭(+ · Layout · Model) | `layouts: SWFooterLayout[]`·`value`(필수), `onValueChange`, `onAdd`, `onRemove`, `onRename`, `editingId`/`onEditingChange`, `modelLabel`(`"Model"` / `false`), `label`, `addLabel`, `removeLabel` | ◻ |
|
||
| `SWFooterCommandLine` | 명령창 566 × 71(접힘) / 270(펼침) | `history: ReactNode[]`(필수), `value`/`onValueChange`, `onSubmit`, `prompt`(`Command:`), `expanded`/`defaultExpanded`/`onExpandedChange`, `inputProps`, `historyLabel`, `expandLabel`, `collapseLabel` | ◻ |
|
||
|
||
- **상수·아이콘:** `SW_FOOTER_MODEL`(`"model"`, Model 탭의 `value`), `swFooterToolIcons`(`line`·`pline`·`arc`·`circle`·`ellipse`·`rect`·`poly`·`point`·`hatch`·`ncopy` → `{ icon, activeIcon }`), `swFooterAuxIcons`(`objectSnap`·`selectionEffect`·`orthogonal`·`gridSnap`·`gridBackground`·`lineWeight`, 인라인 SVG·채움 `currentColor`).
|
||
- **공개 타입:** `SWFooterProps`, `SWFooterSideAction`, `SWFooterSideButtonProps`, `SWFooterAuxGroupProps`, `SWFooterAuxButtonProps`, `SWFooterToolButtonProps`, `SWFooterAddSlotProps`, `SWFooterGuideProps`, `SWFooterGuideContent`, `SWFooterMenuProps`, `SWFooterMenuItem`, `SWFooterLayoutTabsProps`, `SWFooterCommandLineProps`, `SWFooterTool`(`id`, `label`, `icon`, `activeIcon`, `title`, `ariaLabel`, `disabled`), `SWFooterCategory`(`id`, `label`, `tools`, `disabled`), `SWFooterAuxItem`(`id`, `label`, `icon`, `pressed`, `title`, `disabled`), `SWFooterLayout`(`id`, `label`, `locked`, `shape`), `SWFooterToolIconName`, `SWFooterAuxIconName`.
|
||
- **검증 표시:** Footer Export는 Storybook(`SW/Footer`)과 저장소 안 Import·Build 검증만 있고 독립 소비 프로젝트(Tarball) 브라우저 검증 기록이 없어 ◻입니다.
|