feat(sw): add step header with multi-step and split layout support
This commit is contained in:
1 parent
6ca92c5d55
commit
adbb034cb1
28 files changed
+2477
-7
No files matched your search
@@ -48,15 +48,16 @@ SW 패키지에는 Header·Popup 계열이 두 벌 있습니다. 화면마다 **
|
||||
| 아이콘 | 패키지 자산(필드 안 아이콘) | 프로그램 아이콘 16px, 직접 그린 아이콘은 `SWViewerIcon`으로 감쌈 |
|
||||
| 범위 | Header 밖 부품은 `<SWTheme>` 안 | `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`은 루트에 `hm-sw-theme`이 있어 `<SWTheme>` 불필요. 패널 컨트롤은 `SWViewerPanel` 안 |
|
||||
| 토큰 | `--hm-sw-header-*`, Popup 콘텐츠 `--hm-sw-property-*` | `--hm-sw-viewer-*` + 공유 `--hm-sw-header-*`(아래 0.3) |
|
||||
| 읽을 문서 | [COMPONENT_CATALOG.md](./COMPONENT_CATALOG.md) §1~8·§10, [DESIGN_RULES.md](./DESIGN_RULES.md) §1~10·§12·§13, [COMPOSITION_PATTERNS.md](./COMPOSITION_PATTERNS.md) 1~6·8·10, [FOOTER.md](./FOOTER.md), 예제 A~G·I | [VIEWER.md](./VIEWER.md), [COMPONENT_CATALOG.md](./COMPONENT_CATALOG.md) §9, [DESIGN_RULES.md](./DESIGN_RULES.md) §11, [COMPOSITION_PATTERNS.md](./COMPOSITION_PATTERNS.md) 7, [예제 H](./examples/ExampleH-ViewerMode.tsx) |
|
||||
| 읽을 문서 | [COMPONENT_CATALOG.md](./COMPONENT_CATALOG.md) §1~8·§10·§11, [DESIGN_RULES.md](./DESIGN_RULES.md) §1~10·§12·§13·§14, [COMPOSITION_PATTERNS.md](./COMPOSITION_PATTERNS.md) 1~6·8·10·12, [FOOTER.md](./FOOTER.md), 예제 A~G·I | [VIEWER.md](./VIEWER.md), [COMPONENT_CATALOG.md](./COMPONENT_CATALOG.md) §9, [DESIGN_RULES.md](./DESIGN_RULES.md) §11, [COMPOSITION_PATTERNS.md](./COMPOSITION_PATTERNS.md) 7, [예제 H](./examples/ExampleH-ViewerMode.tsx) |
|
||||
|
||||
- **프로세스 단계 Header**(로고 · 파일명 · 01 Modeling → 02 Analysis Result 같은 단계 탭 · Layer 필드 · 도구 pill · 최소화 · 최대화/복원 · 종료, Strana Main Header) 요청은 일반 모드의 독립 Header `SWProcessHeader`입니다(카탈로그 §11, DESIGN_RULES §14, PATTERNS 12). 그룹·단계가 많은 다중 Step 화면(StrAna-SW)은 같은 컴포넌트의 `appearance="multi"`입니다(별도 컴포넌트를 만들지 않음). `SWHeader` 대신 쓰며 같은 화면에 함께 두지 않습니다.
|
||||
- **하단 명령 막대(Footer)** 요청은 일반 모드입니다: [FOOTER.md](./FOOTER.md) §1 순서로 `SWFooter`가 있는지 확인하고, 명령·분류·보조기능·문구·아이콘만 Props로 바꿉니다. Footer 외형을 새로 그리지 않습니다.
|
||||
- **일반 모드 Header에 도구 막대를 더한 구성**(로고 옆 파일 열기 + Model/Layout·Fit·2.5D 버튼을 `SWHeader`에 추가)은 **일반 모드**입니다: `SWHeader`의 `documentOpenPlacement`·`leading`·`tools` + `SWToolButton` / `SWToolGroup`(PATTERNS 6, 예제 F). "뷰어"·"도면 보기" 화면을 요청받았다면 이 구성이 아니라 뷰어 모드(`SWViewer*`)를 씁니다.
|
||||
- 모드 진입·종료, 파일 처리, 도면 렌더링, 메뉴 명령 실행은 어느 모드든 **프로그램 담당**입니다.
|
||||
|
||||
### 0.3 모드 혼합 금지
|
||||
|
||||
- **한 화면에 Header 하나.** `SWHeader`와 `SWViewerHeader`를 같은 화면에 함께 두지 않습니다. 두 모드를 오가는 프로그램은 상태를 유지한 채 Header 컴포넌트만 바꿉니다(VIEWER.md §1).
|
||||
- **한 화면에 Header 하나.** `SWHeader`·`SWProcessHeader`·`SWViewerHeader` 중 둘 이상을 같은 화면에 함께 두지 않습니다. 두 모드를 오가는 프로그램은 상태를 유지한 채 Header 컴포넌트만 바꿉니다(VIEWER.md §1).
|
||||
- **뷰어 화면:** `SWHeader`에 뷰어 메뉴를 넣거나 `SWHeader`·`SWPopup`을 뷰어처럼 재스타일하지 않습니다. 뷰어 팝업은 `SWViewerPanel`입니다. 예외: 창 최소화·닫기 버전은 `SWViewerHeader`의 `trailing` 맨 끝에 `SWHeaderWindowControls`(`showWindowMove={false}`)를 그대로 둡니다(VIEWER.md §2.1, 2026-10-21).
|
||||
- **일반 화면:** `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`과 패널 컨트롤(`SWViewerSection` …)을 쓰지 않습니다.
|
||||
- **로고(홈) 메뉴는 SW 일반 모드 전용:** `SWHomeMenu`·`SWHomeMenuSection`·`SWHomeMenuItem`·`SWRecentFiles`·`useSWHomeMenuClose`와 `SWHeader`의 `homeMenu`·`homeMenuOpen`·`defaultHomeMenuOpen`·`onHomeMenuOpenChange`는 일반 모드 `SWHeader` 화면에서만 씁니다. 뷰어 화면에는 홈 메뉴를 만들지 않고(`SWViewerHeader` 옆·`custom` 항목·`SWViewerPanel` 안에 넣거나 비슷하게 다시 만들지 않음), 뷰어 Header와 기능은 그대로 둡니다.
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
- **검증 표시:** ✅ = 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 안에).
|
||||
- **무엇을 쓸까(일반 모드, 프로세스 단계 Header):** 로고 · 파일명 · 프로세스 단계 탭(01 Modeling → 02 Analysis Result 등) · Layer 필드 · 도구 pill · 창 이동 · 최소화 · 최대화/복원 · 종료 구성(Strana Main Header) → `SWProcessHeader`, 프로세스 영역만 → `SWProcessBar`(11). `SWHeader`와 같은 화면에 함께 두지 않습니다(Header는 화면에 하나).
|
||||
- **무엇을 쓸까(일반 모드 하단):** 하단 명령 막대(보조기능·명령 칸·분류 탭·명령어 전체보기) → `SWFooter`, 도면 공간 탭(Model/Layout) → `SWFooterLayoutTabs`, 명령창 → `SWFooterCommandLine`(10, [FOOTER.md](./FOOTER.md)).
|
||||
- **무엇을 쓸까(뷰어 모드):** Header → `SWViewerHeader`(`groups` + `trailing`), Dropdown·우클릭 → `SWViewerMenu`, 팝업·설정창·모달 → `SWViewerPanel` + `SWViewerSection`/`SWViewerField`/`SWViewerSwitch`/`SWViewerInput`/`SWViewerButton`, 옵션 패널 게이지 → `SWSlider appearance="property"`, 상태 → `SWViewerStatus`(9).
|
||||
|
||||
@@ -88,7 +89,7 @@ SW 공식 기준 Header(Figma 26:8944, 1920 × 49). 로고 · 파일 · 객체
|
||||
|
||||
| 컴포넌트 | 용도 | 주요 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 바로 뒤에 두면 로고 사선 접점을 그대로 공유 | ✅ |
|
||||
| `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 영역, `hoverIcon` 생략 시 Hover에도 기본 아이콘 유지). `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`입니다.
|
||||
@@ -180,3 +181,24 @@ SW **뷰어 모드** 전용 Export입니다(2026-10-19 추가, 참고 DWG/DXF
|
||||
- **상수·아이콘:** `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) 브라우저 검증 기록이 없어 ◻입니다.
|
||||
|
||||
## 11. Process Header (`SWProcessHeader` · `SWProcessBar`, SW 일반 모드)
|
||||
|
||||
프로세스 단계 Header(2026-11-03 추가). Strana Main Header 디자인을 SW 일반 모드의 **독립 Header**로 옮긴 것으로, `SWHeader`·`SWViewerHeader`와 같은 층위입니다. 한 화면에는 Header 하나만 둡니다. 토큰·상태는 [DESIGN_RULES.md](./DESIGN_RULES.md) §14, 조합은 [COMPOSITION_PATTERNS.md](./COMPOSITION_PATTERNS.md) 12.
|
||||
|
||||
| 컴포넌트 | 용도 | 주요 Props | 크기 | 검증 |
|
||||
|---|---|---|---|---|
|
||||
| `SWProcessHeader` | 49px Header: 로고 → 파일명 → 프로세스 영역 · Layer 면 → 창 영역(도구 pill · 창 이동 · 최소화 · 최대화/복원 · 종료) | `appearance`(`"default"` Strana · `"multi"` StrAna-SW 다중 Step, 기본 `default`, `process.appearance`가 없으면 프로세스 영역에도 적용), `documentTitle`(필수, 문서가 없으면 `""`), `documentEmptyLabel`(제목이 비었을 때 파일명 면 오른쪽 위 10px 표시, 예: `프로젝트 생성 전`), `onDocumentClick`, `logo` / `logoText`(글자 로고) / `logoSrc`(SWHeader 로고 칸: 높이 17·로고 비율 폭, 32 × 17 → 홈 80, 두 타입 공통. 글자 로고는 58px 칸 → 홈 106), `logoAlt`(기본 `logoText`), `onHomeClick`, `homeMenuOpen`(로고 메뉴는 호스트 소유), `process: SWProcessBarProps`(필수), `layer?: SWProcessHeaderLayer`(`label` 기본 `레이어`, `value`, `visible`, `open`, `disabled`), `onLayerClick`, `onLayerVisibilityChange(next)`, `tools?: ReactNode`(`SWToolButton appearance="pill"`, Header가 pill로 감쌈), `toolsLabel`(기본 `도구`), `onWindowMoveStart`, `maximized`(기본 false = 최대화 글리프, true = 복원 글리프), `onMinimize`, `onMaximizeToggle`, `onClose`, `hiddenControls?: SWProcessHeaderHideableControlId[]`(`layer`·`tools`·`windowMove`·`minimize`·`maximize`·`close`), `disabled`(프로세스·Layer만, 로고·파일명·도구·창 버튼 제외), `<header>` HTML 속성·`ref` | 높이 49. `default`: 면 48, 파일명 286 : 가운데 1260(프로세스 1003 : Layer 257) 비율, 파일명 100~286, Layer 칸 152~257, 창 영역 약 312(도구 3개). `multi`: 면 49, 파일명 189 : 프로세스 1278, 파일명 100~189, SW pill(버튼 40 × 37), 창 영역 367(도구 5개, 최대화 숨김) | ◻ |
|
||||
| `SWProcessSplitButton` | 화면 분할 도구(Strana 화면 분할, StrAna-SW 6758:12510): `tools` pill 안 버튼 + 233 × 36 선택 패널(칸 6개). 열리면 버튼이 어두운 면 + 금색 위·양옆으로 바뀌고 Header 끝까지 이어진 뒤 패널이 Header 바로 아래에 붙음 | `value: SWProcessSplitType`(필수, 버튼 아이콘·선택 칸), `onValueChange(value)`(다른 칸 선택, 패널은 열린 채), `open` / `defaultOpen` / `onOpenChange(open)`, `label`(기본 `화면 분할`), `typeLabels`, `disabled`. 키보드: Enter·Space 열기/닫기, ArrowDown 열고 선택 칸으로, 방향키·Home·End 선택, Escape 닫고 버튼으로, Tab 이탈·바깥 클릭 닫기. 실제 창 분할은 호스트 | 버튼 40 × 38(`multi` 37), 패널 233 × 36, 칸 38.5 × 34 | ◻ |
|
||||
| `SWProcessBar` | 프로세스 영역: 그룹(번호·이름·단계 탭) + 그룹 사이 화살표, 활성 그룹 발광 면, 비활성 덮개. 단계 하나만 선택(radiogroup) | `appearance`(`"default"` · `"multi"`, 기본 `default`), `groups: SWProcessGroup[]`(필수, `id`·`number`·`label`·`labelHidden`(이름을 보조기술용으로만 둠, `multi`는 제목 줄 높이 유지)·`steps: SWProcessStep[]`(`id`·`label`·`disabled`)·`disabled`), `activeStepId`, `activeGroupId`(기본 = `activeStepId`가 속한 그룹), `onStepSelect(step, group)`(이미 선택된 단계를 다시 누르면 호출 안 함), `disabled`, `aria-label`(기본 `프로세스`), `div` 속성 | `default`: 높이 48, 탭 32(넓을 때 127). `multi`: 높이 49, 제목 12px 위 + 탭 25(글자 폭 + 25, 간격 0). 그룹은 자연 폭까지·좁으면 비례 축소 | ◻ |
|
||||
|
||||
- **`default` 확정 디자인은 2그룹**(01 Modeling: Structure · Loads / 02 Analysis Result: Results)입니다. 1그룹·3그룹 이상은 렌더링되지만 디자인 미확정입니다.
|
||||
- **사다리꼴(그룹 면) 배치 확정(2026-11-03):** 시작(첫 그룹)과 끝(마지막 그룹)에만 둡니다(켜졌으면 발광 면, 아니면 비활성 면). 가운데 그룹은 켜져 있어도 도형 없이 밝은 바탕만 보입니다. 그룹 수와 관계없이, `default`·`multi` 공통입니다. 그룹 사이 화살표·비활성 덮개·선택 상태는 그대로입니다.
|
||||
- **`multi`**(Figma StrAna-SW 873:16481 · 873:16254 · 873:17421): 그룹 수·단계 수는 데이터대로이며, 켜진 그룹보다 앞 그룹은 진행 완료(제목 700 흰색·밝은 탭), 뒤 그룹은 미진행(제목 500 `#C3EBDF`·70% 탭)으로 표시합니다. 바탕·덮개·발광·화살표·선택·키보드는 `default`와 같은 구현입니다.
|
||||
- **키보드:** 탭 사이 Arrow(좌우·상하)·Home·End 이동 + 선택(비활성 단계 건너뜀), Tab은 선택된 단계 하나로만 들어갑니다.
|
||||
- **반응형:** 숨김·More·스크롤 없음. 보장 폭 1100px 이상이며 더 좁으면 Header 안에서 잘립니다. 탭 글자·파일명·Layer 이름은 `…` 말줄임. 공간이 부족하면 선택된 탭도 다른 탭과 같은 비율로 줄어듭니다(2026-11-03 개정): `default`는 모든 탭이 같은 폭, `multi`는 글자 폭에 비례하며 이름이 들어가지 않으면 `…`. 선택이 바뀌어도 탭 폭은 그대로입니다. 그룹은 이름 + 모든 탭 여백보다 좁아지지 않아 겹치지 않습니다. 그룹 사이 화살표·간격은 고정입니다. **넘침 정책 확정(2026-11-03): 그룹 접기·좌우 스크롤·More 메뉴를 추가하지 않습니다.**
|
||||
- **범위 밖(호스트 소유):** 로고 메뉴 본체, Layer Popup, 실제 화면 분할 실행, 도구 아이콘(소비 측이 `tools`에 넣는 요소). 화면 분할 선택 UI는 `SWProcessSplitButton`(2026-11-03 추가). `SWHomeMenu`는 이 Header에 쓰지 않습니다(2단 타일 디자인이 다름).
|
||||
- **SWHeader와 같은 상호작용(2026-11-03):** 창 이동은 `SWHeaderWindowControls`의 창 이동(Hover 1.4s Motion·툴팁)을 그대로 씁니다. 글자 외곽선·Hover·Focus도 SWHeader 규칙(DESIGN_RULES §14). 도구 아이콘이 이미지면 `SWToolButton`의 `hoverIcon`으로 노란 그림(`#B6D0C9 → #FFC600`)을 함께 주고, 단색 SVG면 `currentColor`로 칠합니다.
|
||||
- **단독 사용:** `SWProcessBar`만 쓸 때는 `<SWTheme>` 안에 둡니다. `SWProcessHeader`는 루트에 `hm-sw-theme`이 있어 `<SWTheme>`이 필요 없습니다.
|
||||
- **공개 타입:** `SWProcessHeaderProps`, `SWProcessHeaderLayer`, `SWProcessHeaderHideableControlId`, `SWProcessBarProps`, `SWProcessGroup`, `SWProcessStep`, `SWProcessAppearance`(`"default" | "multi"`), `SWProcessSplitType`(`single` · `columns` · `rows` · `topWide` · `leftTall` · `grid` = Strana Type01~06), `SWProcessSplitButtonProps`.
|
||||
- **검증 표시:** Storybook(`SW/Step Header`)과 저장소 안 Typecheck·Build 검증만 있고 독립 소비 프로젝트(Tarball) 브라우저 검증 기록이 없어 ◻입니다.
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## 0. 어떤 패턴을 고를까
|
||||
|
||||
먼저 SW 모드를 정합니다([AI_USAGE.md](./AI_USAGE.md) §0). 1~6과 8·10은 **SW 일반 모드**, 7은 **SW 뷰어 모드**이며 한 화면에서 섞지 않습니다. 11(테마 설정)은 두 모드 공통입니다.
|
||||
먼저 SW 모드를 정합니다([AI_USAGE.md](./AI_USAGE.md) §0). 1~6과 8·10·12는 **SW 일반 모드**, 7은 **SW 뷰어 모드**이며 한 화면에서 섞지 않습니다. 11(테마 설정)은 두 모드 공통입니다.
|
||||
|
||||
| 요청 | 모드 | 패턴 |
|
||||
|---|---|---|
|
||||
@@ -18,6 +18,7 @@
|
||||
| 일반 모드 `SWHeader`에서 로고를 누르면 열리는 2단 메뉴(저장·내보내기·찾아열기·최근파일 등) | 일반 | 8. 로고 클릭 메뉴 |
|
||||
| 화면 하단 명령 막대(Line·Arc 등 명령, 분류 탭, 보조기능 토글, 명령창), Model/Layout 탭 | 일반 | 10. Footer |
|
||||
| 글꼴 등 SW 토큰을 화면 전체(Header·Dropdown·More·Panel·명령창)에 같은 값으로 바꾸기, Portal 요소 포함 | 일반·뷰어 공통 | 11. 테마(토큰) 설정 |
|
||||
| 프로세스 단계(01 Modeling → 02 Analysis Result 등) 탭이 있는 Header, Strana Main Header | 일반 | 12. 프로세스 단계 Header |
|
||||
|
||||
## 1. 완성형 SW Header — [ExampleA-DefaultHeader.tsx](./examples/ExampleA-DefaultHeader.tsx)
|
||||
|
||||
@@ -248,6 +249,49 @@ const appSWTheme = { "--hm-sw-header-font-family": '"Malgun Gothic", sans-serif'
|
||||
- 기본 글꼴은 Noto Sans KR입니다(2026-10-20 확정). 기본값을 쓸 때는 글꼴 토큰을 지정하지 않습니다. Web UI 글꼴 토큰(`--hm-font-family-base`)을 SW 화면에 넣지 않습니다.
|
||||
- `hm-sw-*` class 선택자로 토큰을 덮거나 `!important`, 컴포넌트마다 같은 값 반복 지정을 하지 않습니다.
|
||||
|
||||
## 12. 프로세스 단계 Header (일반 모드)
|
||||
|
||||
`SWHeader` 대신 쓰는 독립 Header입니다(한 화면에 Header 하나). 상태는 모두 프로그램이 갖고 Callback으로 갱신합니다. 로고 메뉴·Layer Popup·도구 Popup은 프로그램이 직접 엽니다([COMPONENT_CATALOG.md](./COMPONENT_CATALOG.md) §11).
|
||||
|
||||
```tsx
|
||||
const groups: SWProcessGroup[] = [
|
||||
{ id: "modeling", number: "01", label: "Modeling", steps: [{ id: "structure", label: "Structure" }, { id: "loads", label: "Loads" }] },
|
||||
{ id: "analysis", number: "02", label: "Analysis Result", steps: [{ id: "results", label: "Results" }] },
|
||||
]
|
||||
|
||||
<SWProcessHeader
|
||||
documentTitle={fileName} logoSrc={logoUrl} logoAlt={productName} onHomeClick={toggleFileMenu} homeMenuOpen={fileMenuOpen}
|
||||
process={{ groups, activeStepId: step, onStepSelect: s => setStep(s.id) }}
|
||||
layer={{ label: "Layer", value: layerName, visible: layerVisible, open: layerPopupOpen }}
|
||||
onLayerClick={toggleLayerPopup} onLayerVisibilityChange={setLayerVisible}
|
||||
tools={<>
|
||||
{/* ViewPropertyIcon: the program's own icon (the package ships no product icons). */}
|
||||
<SWToolButton appearance="pill" icon={<ViewPropertyIcon />} pressed={viewProperty} onClick={toggleViewProperty}>View Property</SWToolButton>
|
||||
<SWProcessSplitButton value={split} onValueChange={setSplit} open={splitOpen} onOpenChange={setSplitOpen} />
|
||||
</>}
|
||||
onWindowMoveStart={startWindowDrag} maximized={maximized}
|
||||
onMinimize={minimize} onMaximizeToggle={toggleMaximize} onClose={closeWindow} />
|
||||
```
|
||||
|
||||
1. 도구 아이콘은 프로그램이 그린 24 × 24 요소입니다. 버튼 상태 색(기본 `#B6D0C9`, Hover·눌림 `#FFC600`)을 따르려면 `currentColor`로 칠하고, 색이 고정된 이미지 아이콘이면 `hoverIcon`에 `#FFC600` 그림을 함께 줍니다(SW 인쇄 버튼과 같은 방식).
|
||||
2. 화면 분할은 `SWProcessSplitButton`을 `tools`의 원하는 자리에 둡니다(두 appearance 공통). 고른 값으로 실제 창을 나누는 일은 프로그램이 합니다. 분할 아이콘·선택 패널을 직접 그리지 않습니다.
|
||||
3. 프로세스 영역만 다른 곳에 둘 때는 `<SWTheme>` 안에 `SWProcessBar`를 둡니다.
|
||||
4. 다른 테마(Strana Dark 등)는 11처럼 가장 바깥 범위 `style`에 `--hm-sw-process-*`·`--hm-sw-header-*` 토큰을 지정합니다.
|
||||
5. `SWHeader`의 메뉴(레이어·색상·선/문자/치수스타일 Dropdown)를 이 Header에 넣지 않습니다. 필요하면 `SWHeader`를 씁니다.
|
||||
6. **그룹·단계가 많은 다중 Step 화면**(StrAna-SW Figma 873:16481 등)은 `appearance="multi"`입니다. 같은 `process` 데이터 구조를 쓰고, 제목이 없는 그룹은 `labelHidden`, 아직 열 수 없는 단계는 `disabled`, 문서가 없을 때는 `documentTitle=""` + `documentEmptyLabel`입니다. Figma 프레임에는 Layer 필드와 최대화 버튼이 없으므로 `layer`를 주지 않고 `hiddenControls={["maximize"]}`를 씁니다. 그룹·단계가 많아도 데이터를 줄이거나 접기·스크롤·More를 만들지 않습니다(넘침 정책: 선택 단계 포함 비례 축소 + `…`, 2026-11-03 개정).
|
||||
|
||||
```tsx
|
||||
<SWProcessHeader appearance="multi" documentTitle={projectName ?? ""} documentEmptyLabel="프로젝트 생성 전"
|
||||
logoSrc={logoUrl} logoAlt={productName} onHomeClick={toggleFileMenu}
|
||||
process={{ groups: [
|
||||
{ id: "data", label: "데이터 구축", steps: [{ id: "input", label: "데이터입력" }, { id: "check", label: "데이터확인" }] },
|
||||
{ id: "alignment", label: "선형 입력", labelHidden: true, steps: [{ id: "alignment", label: "선형입력" }] },
|
||||
{ id: "analysis", label: "해석 및 성과품", labelHidden: true, disabled: true, steps: [{ id: "model", label: "해석모델" }] },
|
||||
], activeStepId: step, onStepSelect: s => setStep(s.id) }}
|
||||
tools={<SWToolButton appearance="pill" icon={<img src={helpIcon} alt="" />} hoverIcon={<img src={helpIconHover} alt="" />} onClick={openHelp}>도움말</SWToolButton>}
|
||||
hiddenControls={["maximize"]} onWindowMoveStart={startWindowDrag} onMinimize={minimize} onClose={closeWindow} />
|
||||
```
|
||||
|
||||
## 9. 하지 말 것
|
||||
|
||||
- `hm-sw-*` class를 소비 코드에 쓰거나 CSS로 덮어쓰기(토큰 변경도 class 선택자가 아니라 가장 바깥 SW 범위의 `style` — 11)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
- 기본값은 가장 바깥 SW 범위에서만 선언되고 안쪽 SW 범위(Dropdown·More·Panel·명령창)는 상속합니다(2026-10-20). 값을 바꿀 때는 가장 바깥 범위의 `style`만 씁니다 — [AI_USAGE.md](./AI_USAGE.md) §3.1.
|
||||
- SW는 `@hm-design/ui` 토큰을 쓰지 않습니다. UI 패키지 토큰을 복제하거나 섞지 않습니다.
|
||||
- Light/Dark 분기 없음. 전역 선택자(`html`, `body`, `*`) 없음.
|
||||
- **모드:** §1~10과 §12·§13은 SW **일반 모드**(`SWHeader`·`SWPopup`·`SWToolButton`·`SWHomeMenu`·`SWFooter`) 기준입니다. SW **뷰어 모드**(`SWViewer*`)의 토큰·상태는 §11과 [VIEWER.md](./VIEWER.md)를 봅니다. 모드 선택·혼합 금지는 [AI_USAGE.md](./AI_USAGE.md) §0.
|
||||
- **모드:** §1~10과 §12·§13·§14는 SW **일반 모드**(`SWHeader`·`SWPopup`·`SWToolButton`·`SWHomeMenu`·`SWFooter`·`SWProcessHeader`) 기준입니다. SW **뷰어 모드**(`SWViewer*`)의 토큰·상태는 §11과 [VIEWER.md](./VIEWER.md)를 봅니다. 모드 선택·혼합 금지는 [AI_USAGE.md](./AI_USAGE.md) §0.
|
||||
|
||||
## 1. 크기·간격
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
| appearance | 기존 기준 | 상태 |
|
||||
|---|---|---|
|
||||
| `text` | 속성Bar·속성창 토글: 19px 행, 14px 700, 자간 0.04em, 묶음 위 12px 캡션, 버튼 사이 1px 구분선 | Hover·`pressed` 글자 `#FFC600`, 테두리·배경 변화 없음 |
|
||||
| `pill` | 인쇄·K: pill(`rgba(0,0,0,.8)`, 1px `#092920`, radius 4px) 안 40 × 38 버튼, 아이콘 영역 24 × 23 | Hover 노란 gradient 링 + `hoverIcon`. 아이콘 색은 기존 인쇄 아이콘 `#B6D0C9` → Hover `#FFC600`(`--hm-sw-header-selected-color`) |
|
||||
| `pill` | 인쇄·K: pill(`rgba(0,0,0,.8)`, 1px `#092920`, radius 4px) 안 40 × 38 버튼, 아이콘 영역 24 × 23 | Hover 노란 gradient 링 + `hoverIcon`(생략 시 기본 아이콘 유지). 아이콘 색은 기존 인쇄 아이콘 `#B6D0C9` → Hover `#FFC600`(`--hm-sw-header-selected-color`) |
|
||||
| `document` | 파일명 면: 48px, gradient 표면, 위·오른쪽·아래 1px gradient 테두리(`--hm-sw-header-document-border-gradient`), 글자 `#F0F7F5` 700 · 자간 0.06em | 글자만 Hover `#FFC600`. Home 바로 뒤면 로고 사선 접점 공유, 그 뒤 파일명은 왼쪽 여백 12px |
|
||||
|
||||
## 10. 새 컴포넌트 체크리스트
|
||||
@@ -214,3 +214,44 @@
|
||||
|
||||
- Figma에 없는 값: 실제 화면에서 가져온 값(바 안 명령창 배치, 좌표, ▲ 패널, 분류 ◀ ▶, 보조기능 아이콘만)과 AI 구성 값 — 디자인 확인 필요(측면 버튼 Hover 글자 `#FF5C00`·주황 테두리, 분류 행 `+` Hover, Disabled 40%, 명령창 최소 280px, 칸 영역 비율 0.57(두 실제 화면 재현 값), 보조기능 아이콘 전환 1279px, Layout 탭 이름 편집 입력의 동작).
|
||||
- 새 하단 UI는 위 토큰을 `var(--…)`로 읽고 `hm-sw-footer*` class를 쓰거나 덮어쓰지 않습니다.
|
||||
|
||||
## 14. Process Header (`SWProcessHeader` · `SWProcessBar`) — SW 일반 모드 전용
|
||||
|
||||
원본 `src/theme/sw-process-header.css`(2026-11-03). Strana Main Header(Hanmac 테마)의 값입니다. 새 토큰은 `--hm-sw-process-*`(`.hm-sw-header`, `.hm-sw-theme` 범위)이고, 값이 같은 곳은 SW Header 토큰을 그대로 읽습니다(파일명 면·테두리, 객체 면·테두리, 속성 필드 면·그림자, Hover gradient, 선택 `#FFC600`, 제목·글자, 창 이동 줄무늬, 창 버튼 글리프 `#ADB0AF`·Hover 배경). Light/Dark preset은 없으며 다른 Strana 테마는 가장 바깥 범위 `style`에 같은 토큰을 지정합니다([AI_USAGE.md](./AI_USAGE.md) §3.1).
|
||||
|
||||
| 항목 | 값 | 토큰 |
|
||||
|---|---|---|
|
||||
| 배치 | 홈·파일명 글자 = SWHeader 그대로(두 타입 공통, 2026-11-03): 홈 12 + 로고(32 × 17 → 80) + 36, 파일명은 홈과 15 겹친 뒤 2 간격(x 65), padding 5 / 12, 14px 700·자간 0.06em·SW 외곽선, 화살표 없음(글자 로고 18px 700 → 홈 106) → 프로세스 → Layer 면(객체 면, 양옆 1) → 창 영역(파일명 면 + 테두리 1px) | SW 토큰 |
|
||||
| 프로세스 바탕 | 세로 `#0C5941 → #19BF8D 10.1% → #109069 18.27% → #0C5941`, 파일명 테두리 1px, 위 모서리 6 | `--hm-sw-process-base-background`, `-base-border-gradient` |
|
||||
| 비활성 덮개 | `rgba(0, 68, 48, .902)`: 비활성 그룹, 화살표 꼭지(앞 그룹 비활성)·홈(뒤 그룹 비활성), 비활성 바깥 그룹 쪽 남는 폭 | `--hm-sw-process-dim` |
|
||||
| 그룹 글자 | 번호 12px 500 `#69C2A6`, 이름 12px(최대 56, 줄바꿈) 활성 700 `#FFF` / 비활성 500 `#C3EBDF`, 위 10.67(한 줄)·8.67(두 줄), 그룹 좌우 20, 이름 뒤 12 | `--hm-sw-process-number-color`, `-group-color`, `-group-active-color` |
|
||||
| 활성 그룹 면 | 기운 변 도형, 3층 면(85·80·45%), 발광 `drop-shadow(0 0 30px rgba(88,181,153,.85))`, 가장자리 빛 3px Blur 5, 화살표 쪽 76px에 걸쳐 사라짐. 첫 그룹 왼쪽 40px 밖, 마지막 그룹 좌우 반전·44px 밖 | `--hm-sw-process-glow-*` |
|
||||
| 비활성 바깥 그룹 면 | Blur 4 면 + `drop-shadow(0 0 15px rgba(17,105,79,.8))` + 테두리 빛 1.5px, 바깥에서 안쪽으로 사라짐(79.8→198.4 / 반전 236.7→273.1) | `--hm-sw-process-idle-*` |
|
||||
| 사다리꼴 배치(확정 2026-11-03) | 그룹 면(사다리꼴)은 프로세스 영역의 **시작(첫 그룹)과 끝(마지막 그룹)에만** 둡니다. 그 그룹이 켜져 있으면 발광 면, 아니면 비활성 면. 가운데 그룹에는 켜져 있어도 도형이 없고 밝은 바탕(덮개 없음)만 보입니다(Figma 873:17421). 그룹 수와 관계없이 같으며 `default`·`multi` 공통. 화살표·비활성 덮개·선택 상태는 그대로 |
|
||||
| 화살표 | 16 × 48. On 채움 `#27D9A5`, Dim 채움 `#ABC7BF` 25%·선 50%, 그늘이 다음 그룹 위로 20% | `--hm-sw-process-arrow-*`, `-shade*` |
|
||||
| 탭 | 높이 32, padding 0 12 2.67, 16px 700 `#F0F7F5`, 간격 1, 넓을 때 127. 모서리: 단독 16 / 첫 16 4 4 16 / 마지막 4 16 16 4 / 가운데 4 | `--hm-sw-process-tab-*` |
|
||||
| 선택 탭 폭(공통, 2026-11-03 개정) | 선택된 탭도 다른 탭과 같은 비율로 줄어듦(우선 배정 없음). 넓을 때 `default`는 127 균등 그대로. 좁으면 모든 탭이 여백 폭까지 줄고 `…`. 그룹은 이름 + 모든 탭 여백보다 좁아지지 않음(측정) | — |
|
||||
| 화면 분할 도구 | 버튼 = SW pill 버튼(Hover 링·노란 아이콘). 열림 = 면 `--hm-sw-process-tool-open-background` + 금색 위·양옆(`--hm-sw-header-hover-border-gradient`), 링 없음, 아이콘 `#FFC600`. 버튼 아래 연장(면 `#081813` + 금색 양옆)이 Header 끝까지, 패널 233 × 36(면 `#082018`, 금색 양옆·아래, 위 오른쪽·아래 radius 2, 그림자 `0 2px 4px rgba(0,0,0,.6)`)이 Header 바로 아래 버튼 왼쪽에, 버튼 오른쪽부터 패널 끝까지 금색 위 선. 칸 38.5 × 34: 밝은 틀 32 × 22(`#B6D0C9`, 검정 1px, 정수 크기 — 배율 100%에서 아래 밝은 줄 유지) 안에 그림 29.6 × 19.73 + 초록 창(`#1B6B53`, 안쪽 검정 30% 1px) + 왼쪽 위 광택, Hover·선택 = 창만 `#FFC600`. 버튼 아이콘 창 `#003425` | `--hm-sw-process-split-*`, `--hm-sw-process-tool-open-*` |
|
||||
| 탭 상태 | 기본 층 70%. Hover 글자 `#FFC600`. 선택 = 층 100%, 바탕 `--hm-sw-process-tab-active-base`, 위 5·왼쪽 6 안쪽 그림자 75%, 테두리 2px 25%, 글자 `#FFC600`. Disabled = 층 50%, 글자 `#64A491`(SW 기본 40% 대신). Focus 2px `#F0F7F5` | `--hm-sw-process-tab-*` |
|
||||
| Layer 필드 | 최대 234 × 38, 면 안 양옆 8, padding 12 / 10, 속성 필드 면 + 테두리 `#08251C → #0E3D2F → #1E7C60 → #08241C → #051612`, 전구 20 + 8 + 라벨 12/14 · 값 14/16(400). Hover·열림 = 노란 gradient 링 + 글자 `#FFC600`, Disabled 40% | `--hm-sw-process-layer-border-gradient` |
|
||||
| 도구 pill | 위·왼쪽 3, 높이 42, radius 4, 면 `rgba(0,0,0,.851)`(위 2px) → `.8`(4px), 테두리 `#092920 → #1C6F56`. 버튼 40 × 38 간격 1, 파일명 면 + 테두리 `#08251C → #208769 → #08241C → #051612`, 아이콘 24 `#B6D0C9`. Hover·눌림 = 노란 링 + 아이콘 `#FFC600` | `--hm-sw-process-pill-*`, `-tool-*` |
|
||||
| 창 이동 | SWHeader 창 이동 그대로(`SWHeaderWindowControls` 창 이동만): 88 × 48, 줄무늬 82 × 37(3, 6), 아이콘 (28, 13), Hover 1.4s Motion + 툴팁, Drag 중 정지, 해제 즉시 복원 | §6, `--hm-sw-header-stripe-color` |
|
||||
| 캡션 버튼 | 32 × 48 × 3. Hover 배경 `rgba(0,0,0,.2)` + 흰 글리프, 종료 Hover `#E40000` + 흰 글리프, Disabled 40% | `--hm-sw-header-window-*`, `--hm-sw-process-close-hover-background`, `-close-icon-hover` |
|
||||
|
||||
- 글자 외곽선은 두 appearance 모두 SW 규칙(`--hm-sw-header-text-outline` 14·16·18px, `--hm-sw-header-label-outline` 10·12px)입니다. Strana 원본(DropShadow Blur 2), multi Figma(Stroke 없음)와 다른 의도된 차이입니다(2026-11-03).
|
||||
- 도구 아이콘은 어떤 상태에서도 사라지지 않습니다: `hoverIcon`이 없는 `currentColor` 아이콘은 Hover에도 그대로 보이고 색만 `#FFC600`(`SWToolButton`은 `hoverIcon`이 있을 때만 Hover 아이콘 교체에 참여, SWHeader `tools`와 공통, 2026-11-03).
|
||||
- Hover·Focus는 SWHeader와 같습니다: 도구 버튼 노란 링 + 노란 아이콘(`hoverIcon` 또는 `currentColor`, 눌림도 같은 모양), 로고 금색 테두리, 파일명·탭 글자 `#FFC600`, 최소화·최대화 어두운 배경 + 흰 글리프, 종료 `#E40000`, Focus 2px `#F0F7F5`.
|
||||
- 파일 없음(`documentEmptyLabel`): 파일명 면 오른쪽 위 10px 700 `#AEDBCC`(`--hm-sw-process-document-empty-color`), 자간 −0.1px, 위 7px. 두 appearance 공통.
|
||||
|
||||
**`appearance="multi"`**(StrAna-SW Figma 873:16481 · 873:16254 · 873:17421, 2026-11-03). 바탕·덮개·발광·비활성 면·화살표·선택·키보드는 위 `default` 규칙과 같은 구현입니다. 아래만 다릅니다.
|
||||
|
||||
| 항목 | 값 | 토큰 |
|
||||
|---|---|---|
|
||||
| 프레임 | 면 49(아래 1px 없음), 파일명 최대 189(테두리 단색 `#0E4C3A`, 로고·글자 위치는 default·SWHeader와 같음), 프로세스 1278 비율, 창 영역 테두리 단색 | `--hm-sw-header-bar-height`, `--hm-sw-header-document-border-color` |
|
||||
| 도구 pill | SW pill 그대로(`#092920`, `rgba(0,0,0,.8)`, 안쪽 그림자) 높이 41, 위 4 · 왼쪽 5 · 오른쪽 2, 버튼 40 × 37(단색 `#08251C`) | `--hm-sw-header-pill-*` |
|
||||
| 창 이동 | SWHeader 창 이동(Motion 포함) 위치만: 줄무늬 82 × 39(3, 5), 아이콘·Motion 3px 위(28, 10) | `--hm-sw-header-stripe-color` |
|
||||
| 그룹 | 좌우 10, 위 3.8: 제목 줄 14(12px, 번호와 간격 2, 한 줄 `…`) → 1.9 → 탭 25(위 19.7). 화살표 칸 16, 그룹 내용 사이 36. 발광 면 왼쪽 50 · 반전 오른쪽 48 밖 | — |
|
||||
| 그룹 상태 | 켜진 그룹 = 제목 700 흰색, 진행 완료(켜진 그룹 앞) = 같은 제목 + 밝은 탭(바탕은 덮개), 미진행 = 제목 500 `#C3EBDF` | — |
|
||||
| 탭 | 높이 25, 글자 폭 + 25(padding 13 / 12), 14px 700, 간격 0. 모서리: 단독 50, 첫 50 0 0 50, 마지막 0 50 50 0, 가운데 0. 좁으면 선택 탭 포함 비례 축소 + `…`. 화살표 칸·그룹 사이 36 고정. 그룹 접기·좌우 스크롤·More 없음(넘침 정책 확정 2026-11-03) | — |
|
||||
| 탭 상태 | 기본(미진행) 70% `rgba(52,143,114,.8) → rgba(2,50,35,.8)` · `#0C3125`. 밝음(켜진·진행 완료) 100% `rgba(68,178,143,.8) → rgba(0,61,41,.8)` · `#0A5940`. 선택 `#113228 → #28735C`(아래 → 위) · `#001E15` · 안쪽 그림자, 글자 `#FFC600`. Disabled 50% 속성 필드 면 · `#021912`, 글자 `#7D9F91`. 공통 그림자 `1px 1px 1px rgba(31,148,113,.7)`. Hover 글자 `#FFC600`, Focus 2px `#F0F7F5` | `--hm-sw-process-multi-tab-*`, `--hm-sw-header-property-background` |
|
||||
- 새 프로세스 UI는 위 토큰을 `var(--…)`로 읽고 `hm-sw-process-*` class를 쓰거나 덮어쓰지 않습니다.
|
||||
Reference in new issue
Block a user