fix(sw): preserve theme token inheritance across viewer components
This commit is contained in:
1 parent
40c5b89814
commit
41e963a12a
17 files changed
+445
-21
No files matched your search
@@ -133,7 +133,7 @@
|
||||
| 패키지 | 스타일이 적용되는 범위 | 주의 |
|
||||
|---|---|---|
|
||||
| Web | `theme.css`의 토큰은 `:root, [data-hm-theme]`. `tailwind.css`는 Tailwind base에서 `*`(border·outline), `body`(배경·글자), `html`(글꼴)을 **문서 전체에** 적용. 앱이 import하는 `tailwindcss`의 Preflight도 전역 | Web CSS를 넣은 문서에서는 다른 영역에도 전역 초기화가 적용됨 |
|
||||
| SW(일반·뷰어 공통) | 토큰은 `.hm-sw-header`와 `.hm-sw-theme`에만 정의(뷰어 토큰 `--hm-sw-viewer-*`도 같은 범위). 전역 선택자 없음. `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`은 자기 root에 `hm-sw-theme`를 가짐 | 일반 모드의 Header 밖 SW 부품은 반드시 `<SWTheme>` 안 |
|
||||
| SW(일반·뷰어 공통) | 토큰은 `.hm-sw-header`와 `.hm-sw-theme`에만 정의(뷰어 토큰 `--hm-sw-viewer-*`도 같은 범위). 전역 선택자 없음. `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`은 자기 root에 `hm-sw-theme`를 가짐. 토큰 기본값은 가장 바깥 SW 범위에서만 선언되고 안쪽 SW 범위는 상속(변경은 가장 바깥 범위의 `style`, SW `AI_USAGE.md` §3.1) | 일반 모드의 Header 밖 SW 부품은 반드시 `<SWTheme>` 안 |
|
||||
| OrgChart | Core가 자기 open Shadow DOM에만 CSS 로드. 호스트 CSS selector는 안쪽에 닿지 않고 **Custom Property 상속만** 통과 | 호스트 class로 카드 모양을 바꾸려 하지 않음 |
|
||||
|
||||
혼합 규칙:
|
||||
|
||||
@@ -103,6 +103,7 @@ import "@hm-design/sw/styles.css" // 앱 진입점에서 한 번
|
||||
- Peer: `react`, `react-dom` `^19.0.0`. 런타임 dependency 없음. `@hm-design/ui`·조직도 패키지와 무관하다.
|
||||
- SVG·PNG 자산은 JS에 data URI로 포함되어 별도 설정이 없다.
|
||||
- 글꼴 파일은 포함하지 않는다. 앱에서 Noto Sans KR(400/500/700)을 로드한다(없으면 Malgun Gothic → Apple SD Gothic Neo).
|
||||
- SW 기본 글꼴은 Noto Sans KR이다(Figma는 Dotum). **Dotum을 기본으로 쓸지는 디자인 승인 대기**이므로 AI가 임의로 Dotum을 적용하지 않는다. 프로그램(사용자)이 글꼴을 정한 경우에만 §3.1 방법으로 `--hm-sw-header-font-family`를 바꾸고, 결과 보고에 "글꼴 변경 — 디자인 승인 대기 항목"으로 적는다.
|
||||
- CSS는 전역(`html`, `body`, `*`)을 건드리지 않는다. `body` margin 등 페이지 기본값은 소비 앱이 정한다.
|
||||
- 스크롤바: SW 전용 스크롤바 디자인은 없다. 기존 SW 컴포넌트는 브라우저 기본 스크롤바를 쓰며(속성Bar만 `scrollbar-width: thin`), Popup 본문 스크롤은 `SWPopup`이 처리한다. 새 스크롤 영역에 임의 스크롤바 색·두께를 만들지 않는다.
|
||||
- TypeScript에서 CSS side-effect import 오류가 나면 Vite의 `vite/client` 타입을 포함한다.
|
||||
@@ -112,9 +113,27 @@ import "@hm-design/sw/styles.css" // 앱 진입점에서 한 번
|
||||
- `SWHeader` 밖에서 하위 컴포넌트를 쓰면 반드시 `<SWTheme>`로 감싼다. 토큰·글꼴·버튼 초기화가 이 범위에서만 적용된다.
|
||||
- 소비 코드는 `hm-sw-*` class를 붙이거나 재정의하지 않는다. 배치는 자기 class(`className`)와 `style`로 한다.
|
||||
- 뷰어 모드 컴포넌트(`SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`)는 자체 `hm-sw-theme` 범위를 가지므로 `<SWTheme>`로 감싸지 않아도 된다. 소비 코드는 `hm-sw-viewer-*` class도 붙이거나 재정의하지 않는다.
|
||||
- 외형 변경은 `--hm-sw-header-*`(뷰어 모드는 `--hm-sw-viewer-*`) 토큰을 `SWTheme`/`SWHeader`(뷰어 모드는 해당 컴포넌트)의 `style`로 바꾸는 방법만 쓴다. 사용자 확정 면(파일명·객체 수정·속성 입력)은 기본값 유지를 권장한다.
|
||||
- 외형 변경은 §3.1의 방법만 쓴다. 사용자 확정 면(파일명·객체 수정·속성 입력)은 기본값 유지를 권장한다.
|
||||
- Light/Dark 분기는 없다. SW 디자인은 하나다.
|
||||
|
||||
### 3.1 테마(토큰) 설정 — 공식 방법 (2026-10-20)
|
||||
|
||||
SW 토큰(`--hm-sw-header-*`, `--hm-sw-property-*`, `--hm-sw-viewer-*`, `--hm-sw-footer-*`)의 기본값은 **가장 바깥 SW 범위**(`<SWTheme>`, 또는 단독으로 쓴 `SWHeader`·`SWViewerHeader`·`SWViewerPanel`·`SWViewerMenu`·`SWFooter`의 루트)에서 한 번만 선언됩니다. 그 안의 SW 요소 — Header의 Dropdown·More, `SWViewerMenu`, `SWViewerPanel`과 안쪽 컨트롤, `SWFooterCommandLine`, Tooltip·안내 — 는 자기 루트에 `hm-sw-theme`이 있어도 값을 다시 정하지 않고 **상속**합니다.
|
||||
|
||||
1. 화면 전체(Header·Panel·Menu가 같은 값)를 바꾸려면 화면을 `<SWTheme style={theme}>` 하나로 감싸고 거기서만 토큰을 정합니다. 프로그램 class(`<SWTheme className="app-sw-theme">` + `.app-sw-theme { --hm-sw-header-font-family: … }`)도 됩니다.
|
||||
```tsx
|
||||
const appSWTheme = { "--hm-sw-header-font-family": '"Noto Sans KR", sans-serif' } as CSSProperties
|
||||
<SWTheme style={appSWTheme}>
|
||||
<SWViewerHeader … /> {/* Dropdown·More 포함 */}
|
||||
<SWViewerPanel …>…</SWViewerPanel>
|
||||
</SWTheme>
|
||||
```
|
||||
2. 컴포넌트 하나만 쓰면 그 컴포넌트의 `style`로 정해도 됩니다(그 루트가 가장 바깥 범위). 안쪽 Dropdown·More·명령창에도 적용됩니다.
|
||||
3. **Portal:** 상속은 DOM 위치를 따릅니다. 프로그램이 `createPortal`로 SW 요소를 범위 밖(`document.body` 등)에 렌더링하면 값이 전달되지 않으므로, Portal 내용을 같은 theme 객체의 `<SWTheme style={appSWTheme}>`으로 감쌉니다(예제 [ExampleJ-Theme.tsx](./examples/ExampleJ-Theme.tsx)). SW 패키지 컴포넌트 자체는 Portal을 쓰지 않습니다(Dropdown·More·Panel 모두 범위 안에 렌더링).
|
||||
4. 영역마다 다른 값이 필요하면 영역별 `<SWTheme>`을 둡니다. 옆 영역끼리 섞이지 않고, 안쪽 `<SWTheme style>`은 그 안에서만 적용됩니다.
|
||||
5. **하지 않음:** `hm-sw-*` class를 선택자로 쓴 CSS(`.hm-sw-header, .hm-sw-theme { --… }` 등), `!important`, 안쪽 컴포넌트마다 같은 값을 반복 지정, SW 범위가 아닌 조상(`body`, 앱 루트 `div`)에만 토큰 지정(SW 범위가 기본값을 다시 선언하므로 적용되지 않음).
|
||||
- 다른 토큰을 참조하는 토큰(예: `--hm-sw-viewer-panel-background` = `var(--hm-sw-property-surface)`)은 가장 바깥 범위에서 계산됩니다. 참조되는 토큰을 바꿀 때도 가장 바깥 범위에서 바꿉니다.
|
||||
|
||||
## 4. 판단 기록 남기기
|
||||
|
||||
새 UI를 만들 때 결과 보고에 다음을 남긴다.
|
||||
|
||||
@@ -45,7 +45,7 @@ SW 공식 기준 Header(Figma 26:8944, 1920 × 49). 로고 · 파일 · 객체
|
||||
|
||||
| 컴포넌트 | 용도 | 주요 Props / Callback | 크기(Figma) | 상태 | 검증 |
|
||||
|---|---|---|---|---|---|
|
||||
| `SWTheme` | 단독 사용 범위(토큰·글꼴·초기화). 배치는 정하지 않음 | `div` HTML 속성, `className`, `style`(토큰 override) | — | — | ✅ |
|
||||
| `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 | ✅ |
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## 0. 어떤 패턴을 고를까
|
||||
|
||||
먼저 SW 모드를 정합니다([AI_USAGE.md](./AI_USAGE.md) §0). 1~6과 8·10은 **SW 일반 모드**, 7은 **SW 뷰어 모드**이며 한 화면에서 섞지 않습니다.
|
||||
먼저 SW 모드를 정합니다([AI_USAGE.md](./AI_USAGE.md) §0). 1~6과 8·10은 **SW 일반 모드**, 7은 **SW 뷰어 모드**이며 한 화면에서 섞지 않습니다. 11(테마 설정)은 두 모드 공통입니다.
|
||||
|
||||
| 요청 | 모드 | 패턴 |
|
||||
|---|---|---|
|
||||
@@ -17,6 +17,7 @@
|
||||
| 뷰어·DWG/DXF 보기·도면 뷰어·읽기 전용 화면(Header 메뉴, 패널, 모달, 불러오기 상태) | 뷰어 | 7. 뷰어 모드 기본 조합 |
|
||||
| 일반 모드 `SWHeader`에서 로고를 누르면 열리는 2단 메뉴(저장·내보내기·찾아열기·최근파일 등) | 일반 | 8. 로고 클릭 메뉴 |
|
||||
| 화면 하단 명령 막대(Line·Arc 등 명령, 분류 탭, 보조기능 토글, 명령창), Model/Layout 탭 | 일반 | 10. Footer |
|
||||
| 글꼴 등 SW 토큰을 화면 전체(Header·Dropdown·More·Panel·명령창)에 같은 값으로 바꾸기, Portal 요소 포함 | 일반·뷰어 공통 | 11. 테마(토큰) 설정 |
|
||||
|
||||
## 1. 완성형 SW Header — [ExampleA-DefaultHeader.tsx](./examples/ExampleA-DefaultHeader.tsx)
|
||||
|
||||
@@ -224,9 +225,28 @@ const sections: SWHomeMenuSectionData[] = [
|
||||
4. 좁은 화면 처리(빈 칸 축소, ▲ 패널, 분류 ◀ ▶, 보조기능 아이콘만)는 `SWFooter`가 합니다. 소비 코드에서 명령 수를 줄이거나 media query로 다시 배치하지 않습니다.
|
||||
5. 일부만 필요하면(보조기능만, 분류 탭만) `<SWTheme>` 안에서 `SWFooterAuxGroup`·`SWFooterMenu`·`SWFooterToolButton`을 씁니다. `SWFooterMenu` 단독은 부모 면을 `var(--hm-sw-footer-group-background)`로 둡니다.
|
||||
|
||||
## 11. 테마(토큰) 설정 — [ExampleJ-Theme.tsx](./examples/ExampleJ-Theme.tsx)
|
||||
|
||||
일반·뷰어 모드 공통입니다. 토큰 기본값은 가장 바깥 SW 범위에서만 선언되고 안쪽 SW 요소는 상속합니다([AI_USAGE.md](./AI_USAGE.md) §3.1).
|
||||
|
||||
```tsx
|
||||
const appSWTheme = { "--hm-sw-header-font-family": '"Noto Sans KR", sans-serif' } as CSSProperties // 프로그램이 정한 값만
|
||||
|
||||
<SWTheme style={appSWTheme}> {/* 가장 바깥 범위: 여기서만 지정 */}
|
||||
<SWViewerHeader … /> {/* Dropdown·More까지 상속 */}
|
||||
<SWViewerPanel …>…</SWViewerPanel> {/* 패널·안쪽 컨트롤 상속 */}
|
||||
</SWTheme>
|
||||
|
||||
{createPortal(<SWTheme style={appSWTheme}>…</SWTheme>, document.body)} {/* Portal은 같은 객체로 다시 감쌈 */}
|
||||
```
|
||||
|
||||
- 일반 모드도 같습니다: `<SWTheme style={appSWTheme}>` 안의 `SWHeader`(Dropdown·창 이동 Tooltip)·`SWFooter`(`SWFooterCommandLine`·명령 등록 안내)가 같은 값을 씁니다.
|
||||
- 기본 글꼴은 Noto Sans KR입니다. Dotum 기본 적용은 디자인 승인 대기이므로 AI가 임의로 Dotum을 넣지 않습니다.
|
||||
- `hm-sw-*` class 선택자로 토큰을 덮거나 `!important`, 컴포넌트마다 같은 값 반복 지정을 하지 않습니다.
|
||||
|
||||
## 9. 하지 말 것
|
||||
|
||||
- `hm-sw-*` class를 소비 코드에 쓰거나 CSS로 덮어쓰기
|
||||
- `hm-sw-*` class를 소비 코드에 쓰거나 CSS로 덮어쓰기(토큰 변경도 class 선택자가 아니라 가장 바깥 SW 범위의 `style` — 11)
|
||||
- `dist` 구현·`styles.css` 블록 복사로 같은 컴포넌트 재작성
|
||||
- `@hm-design/sw/dist/...`·`src/...` 내부 경로 Import
|
||||
- 문서에 없는 Props 추측, 새 색·크기 값 도입
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
출처: `@hm-design/sw` `styles.css`(원본 `src/theme/sw.css`)의 토큰과 규칙, Figma 이지빔 SW `rj6wpsfk24lOWvWiVRAANP` node `26:8944`와 사용자 확정값. 이 문서에 없는 값은 확정값이 아닙니다. 새 컴포넌트에 임의 값을 만들지 말고 아래 토큰을 `var(--…)`로 읽으세요. 참고할 토큰·값이 없을 때만 [AI_USAGE.md](./AI_USAGE.md) §0.4 ③으로 구성하고 "AI 구성 값 — 디자인 확인 필요"로 보고합니다.
|
||||
|
||||
- 토큰은 `.hm-sw-header`와 `.hm-sw-theme`(`<SWTheme>`)에만 정의됩니다. 새 컴포넌트는 그 안에 렌더링합니다.
|
||||
- 기본값은 가장 바깥 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.
|
||||
@@ -43,7 +44,7 @@
|
||||
|
||||
| 항목 | 값 |
|
||||
|---|---|
|
||||
| 글꼴 | Noto Sans KR → Malgun Gothic → Apple SD Gothic Neo (Figma Dotum 대체, 의도된 결정). 폰트 파일은 앱이 로드 |
|
||||
| 글꼴 | Noto Sans KR → Malgun Gothic → Apple SD Gothic Neo (`--hm-sw-header-font-family`, Figma Dotum 대체 — 현재 패키지 기본값). 폰트 파일은 앱이 로드. **Dotum 기본 적용 여부는 디자인 승인 대기**: 기본값을 바꾸지 않으며, 프로그램이 정한 경우에만 [AI_USAGE.md](./AI_USAGE.md) §3.1 방법으로 변경 |
|
||||
| 기본 / 라벨 | 14px / 12px (`--hm-sw-header-font-size` / `--hm-sw-header-label-size`) |
|
||||
| Weight | 400, 500, 700만 사용(600 없음). 값·제목·토글 700 |
|
||||
| 자간 | 값 0.04em, 라벨 0.02em, 파일명 0.06em |
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
|
||||
`entries`: `item`(`icon?`, `shortcut?`, `onSelect`), `checkbox`(`checked`, `onCheckedChange`), `radio`(`checked`, `onSelect`), `submenu`(`entries` — 다단계), `label`, `separator`. 공통 `disabled?`, `hidden?`, `keepOpen?`.
|
||||
|
||||
- **테마:** `SWViewerMenu`에는 `style` Prop이 없습니다. 토큰은 메뉴를 감싼 바깥 SW 범위(`SWViewerHeader`·`SWViewerPanel`·`<SWTheme>`)에서 상속됩니다. 단독 우클릭 메뉴의 값을 바꾸려면 메뉴를 `<SWTheme style={theme}>` 안에 둡니다([AI_USAGE.md](./AI_USAGE.md) §3.1).
|
||||
- Header의 `type: "menu"`가 이 Dropdown을 엽니다. 다른 위치(도면 우클릭 등)는 `SWViewerMenu`를 `open` / `onOpenChange` + `anchorRef`(버튼 아래 4px) 또는 `anchorPoint`(포인터 위치)로 씁니다. `surface="beige"`는 More 면, `initialFocus`는 `first`(키보드 열기) / `menu`(클릭 열기).
|
||||
- 키보드: Enter·Space·ArrowDown 열기, ↑↓ Home End 이동, → 서브메뉴 열기, ← 한 단계 닫기, Escape 닫고 Trigger로 Focus 복귀, Tab·바깥 클릭 닫기. 화면 끝에서는 위/왼쪽으로 뒤집혀 화면 안에 남습니다.
|
||||
|
||||
@@ -99,7 +100,8 @@ const groups: SWViewerHeaderGroup[] = [
|
||||
| 뷰어 화면에 로고(홈) 메뉴(`SWHomeMenu`·`SWRecentFiles`, `SWHeader homeMenu`) 넣기 또는 비슷한 2단 메뉴 직접 만들기 | 홈 메뉴는 SW 일반 모드 전용입니다. 뷰어 로고 클릭은 `onHomeClick`, 파일 열기·샘플은 `groups`의 `button`·`menu` 항목 |
|
||||
| 뷰어 Header를 `div` + `button`으로 다시 만들기, `hm-sw-viewer-*` class를 소비 코드에 붙이기 | 데이터(`groups`)와 `custom` / `trailing`으로 구성 |
|
||||
| Header 버튼 글자에 `-webkit-text-stroke`·`border`로 외곽선 만들기 | 외곽선은 패키지 토큰이 이미 적용합니다 |
|
||||
| 메뉴 색·간격을 `#123456`, `margin` 등 임의 값으로 덮기 | 토큰 `--hm-sw-viewer-*` / `--hm-sw-header-*`만 `style`로 조정(기본값 유지 권장) |
|
||||
| 메뉴 색·간격을 `#123456`, `margin` 등 임의 값으로 덮기 | 토큰 `--hm-sw-viewer-*` / `--hm-sw-header-*`만 가장 바깥 SW 범위(`<SWTheme>` 또는 단독 컴포넌트 루트)의 `style`로 조정(기본값 유지 권장, [AI_USAGE.md](./AI_USAGE.md) §3.1) |
|
||||
| Header·Dropdown·More·Panel의 글꼴을 각각 따로 지정, `.hm-sw-viewer-menu` 등 class로 덮기 | 화면을 `<SWTheme style={theme}>` 하나로 감싸면 Header·Dropdown·More·Panel이 같은 값을 상속합니다. 글꼴 기본값은 Noto Sans KR이며 Dotum 기본 적용은 디자인 승인 대기 |
|
||||
| 존재하지 않는 Props 추측(`items`, `content`, `renderBody` …) | 위 표와 `dist/index.d.ts`가 전부 |
|
||||
| 일반 모드 화면에서 `SWViewerHeader` 사용, 뷰어에서 `SWHeader` 재스타일 | 모드별 Header를 바꿔 끼웁니다 |
|
||||
| 기능 없는 메뉴를 가짜 동작으로 연결 | 항목 제외 또는 `disabled` + 미연결 보고 |
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
// Example J — SW theme tokens (both modes). The only official way to change SW tokens: `style` (or the program's own
|
||||
// class) on the OUTERMOST SW scope. Here one <SWTheme> wraps the viewer screen, so the header, its dropdowns, More,
|
||||
// and every panel read the same value. Portals leave the DOM tree: wrap their content in <SWTheme> with the same style.
|
||||
// The font below is a placeholder for a program decision: the SW default stays Noto Sans KR (a Dotum default is
|
||||
// pending design approval), so only set it when the program has decided to.
|
||||
import { useState, type CSSProperties } from "react"
|
||||
import { createPortal } from "react-dom"
|
||||
import {
|
||||
SWTheme, SWViewerButton, SWViewerHeader, SWViewerHint, SWViewerPanel, SWViewerSection,
|
||||
type SWViewerHeaderGroup,
|
||||
} from "@hm-design/sw"
|
||||
|
||||
/** One theme object for the screen and for every portal. Token names only (`--hm-sw-*`), never `hm-sw-*` classes. */
|
||||
export const appSWTheme = {
|
||||
"--hm-sw-header-font-family": '"Noto Sans KR", "Malgun Gothic", "Apple SD Gothic Neo", sans-serif',
|
||||
} as CSSProperties
|
||||
|
||||
export function ExampleJTheme({ onEvent }: { onEvent?: (name: string) => void }) {
|
||||
const [options, setOptions] = useState(false)
|
||||
const [notice, setNotice] = useState(false)
|
||||
const groups: SWViewerHeaderGroup[] = [
|
||||
{ id: "file", label: "파일", items: [
|
||||
{ type: "menu", id: "samples", label: "샘플", collapseBelow: 1180, entries: [
|
||||
{ type: "item", id: "sample-a", label: "기본 도면 · DWG", onSelect: () => onEvent?.("sample-a") },
|
||||
] },
|
||||
] },
|
||||
{ id: "panels", label: "패널", placement: "end", items: [
|
||||
{ type: "toggle", id: "options", label: "설정", pressed: options, collapseBelow: 900, onPressedChange: setOptions },
|
||||
{ type: "button", id: "notice", label: "알림", onSelect: () => setNotice(true) },
|
||||
] },
|
||||
]
|
||||
return (
|
||||
// Outermost SW scope: header, dropdown, More and panel inherit `appSWTheme`.
|
||||
<SWTheme style={appSWTheme}>
|
||||
<SWViewerHeader documentTitle="BasicSample.dwg" groups={groups} onCommand={command => onEvent?.(command.id)} />
|
||||
<SWViewerPanel title="옵션" open={options} onClose={() => setOptions(false)} width={320} height="auto">
|
||||
<SWViewerSection title="표시"><SWViewerHint>Header와 같은 토큰 값을 씁니다.</SWViewerHint></SWViewerSection>
|
||||
</SWViewerPanel>
|
||||
{/* A program portal renders outside the scope above: give it its own <SWTheme> with the same style. */}
|
||||
{notice && createPortal(
|
||||
<SWTheme style={{ ...appSWTheme, position: "fixed", right: 24, bottom: 24 }}>
|
||||
<SWViewerSection title="알림">
|
||||
<SWViewerHint>Portal 안에서도 같은 SW 토큰이 적용됩니다.</SWViewerHint>
|
||||
<SWViewerButton variant="primary" onClick={() => setNotice(false)}>확인</SWViewerButton>
|
||||
</SWViewerSection>
|
||||
</SWTheme>,
|
||||
document.body,
|
||||
)}
|
||||
</SWTheme>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user