From e27385e0f07e6ad5d58d5ba81cfcbef800997ec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=88=98=ED=98=84?= Date: Mon, 19 Oct 2026 11:22:07 +0900 Subject: [PATCH] feat(sw): prepare reusable AI-friendly component package - Ship an AI guide in the package (ai/: usage rules, component catalog, design rules, composition patterns) via package.json files. - Add examples A-D that import only public exports: default header, viewer header, feature header, and a consumer-side search extension that reuses SWHeaderInput and the public SW tokens. - Add SW-only checks: docs/API consistency, tarball consumer project (React 19 + TS + Vite typecheck/build) and a browser check (27/27). - No runtime source or public API change; README gains a pointer section. Co-Authored-By: Claude Opus 5.5 --- docs/sw/ai-template/README.md | 116 ++++++++ .../ai-template/evidence/A-default-1920.png | Bin 0 -> 41247 bytes docs/sw/ai-template/evidence/B-k-guide.png | Bin 0 -> 32073 bytes docs/sw/ai-template/evidence/B-layer-open.png | Bin 0 -> 33120 bytes .../sw/ai-template/evidence/B-viewer-1920.png | Bin 0 -> 19060 bytes .../ai-template/evidence/C-feature-1920.png | Bin 0 -> 25477 bytes .../sw/ai-template/evidence/D-search-1920.png | Bin 0 -> 10858 bytes .../ai-template/evidence/D-search-hover.png | Bin 0 -> 11649 bytes docs/sw/ai-template/evidence/report.json | 276 ++++++++++++++++++ packages/sw/README.md | 4 + packages/sw/ai/AI_USAGE.md | 54 ++++ packages/sw/ai/COMPONENT_CATALOG.md | 75 +++++ packages/sw/ai/COMPOSITION_PATTERNS.md | 82 ++++++ packages/sw/ai/DESIGN_RULES.md | 94 ++++++ .../sw/ai/examples/ExampleA-DefaultHeader.tsx | 40 +++ .../sw/ai/examples/ExampleB-ViewerHeader.tsx | 50 ++++ .../sw/ai/examples/ExampleC-FeatureHeader.tsx | 46 +++ .../ai/examples/ExampleD-SearchExtension.tsx | 30 ++ packages/sw/ai/examples/SWSearchControl.tsx | 41 +++ packages/sw/ai/examples/example-layout.css | 36 +++ packages/sw/ai/examples/sample-data.ts | 52 ++++ packages/sw/ai/examples/sw-search-control.css | 48 +++ packages/sw/package.json | 3 +- packages/sw/tests/ai-docs.check.mjs | 53 ++++ .../sw/tests/ai-template-consumer.browser.mjs | 180 ++++++++++++ packages/sw/tests/ai-template-consumer.mjs | 70 +++++ 26 files changed, 1349 insertions(+), 1 deletion(-) create mode 100644 docs/sw/ai-template/README.md create mode 100644 docs/sw/ai-template/evidence/A-default-1920.png create mode 100644 docs/sw/ai-template/evidence/B-k-guide.png create mode 100644 docs/sw/ai-template/evidence/B-layer-open.png create mode 100644 docs/sw/ai-template/evidence/B-viewer-1920.png create mode 100644 docs/sw/ai-template/evidence/C-feature-1920.png create mode 100644 docs/sw/ai-template/evidence/D-search-1920.png create mode 100644 docs/sw/ai-template/evidence/D-search-hover.png create mode 100644 docs/sw/ai-template/evidence/report.json create mode 100644 packages/sw/ai/AI_USAGE.md create mode 100644 packages/sw/ai/COMPONENT_CATALOG.md create mode 100644 packages/sw/ai/COMPOSITION_PATTERNS.md create mode 100644 packages/sw/ai/DESIGN_RULES.md create mode 100644 packages/sw/ai/examples/ExampleA-DefaultHeader.tsx create mode 100644 packages/sw/ai/examples/ExampleB-ViewerHeader.tsx create mode 100644 packages/sw/ai/examples/ExampleC-FeatureHeader.tsx create mode 100644 packages/sw/ai/examples/ExampleD-SearchExtension.tsx create mode 100644 packages/sw/ai/examples/SWSearchControl.tsx create mode 100644 packages/sw/ai/examples/example-layout.css create mode 100644 packages/sw/ai/examples/sample-data.ts create mode 100644 packages/sw/ai/examples/sw-search-control.css create mode 100644 packages/sw/tests/ai-docs.check.mjs create mode 100644 packages/sw/tests/ai-template-consumer.browser.mjs create mode 100644 packages/sw/tests/ai-template-consumer.mjs diff --git a/docs/sw/ai-template/README.md b/docs/sw/ai-template/README.md new file mode 100644 index 0000000..60b18a5 --- /dev/null +++ b/docs/sw/ai-template/README.md @@ -0,0 +1,116 @@ +# SW AI 재사용 템플릿 — 조사·구현·검증 기록 (2026-10-19) + +> 범위: `@hm-design/sw`만. `@hm-design/ui`·조직도·Center Graphic·DWG/DXF Viewer는 변경하지 않았습니다. 작업 Worktree `D:\디자인시스템\HMDesign-SW-AI-Template`, 브랜치 `feature/sw-ai-template`, 시작 HEAD `50bf5bda8e956a4973b923d64131f2f2285bd38c`(`feature/sw-package`). +> +> AI용 사용 규칙·카탈로그·디자인 규칙·조합 패턴의 **원본은 패키지 안 [`packages/sw/ai/`](../../../packages/sw/ai/AI_USAGE.md)** 이며 npm 패키지에 포함됩니다. 이 문서는 조사 결과와 검증 기록만 담고 원본 내용을 반복하지 않습니다. + +## 1. 결론 + +- 기존 공개 Export만으로 재사용(예제 A)·조합(예제 B·C)·확장(예제 D)이 모두 가능했습니다. **런타임 소스(`packages/sw/src`)와 공개 API는 변경하지 않았습니다.** 그래서 기존 SW Header의 디자인·기능·Props·Callback은 그대로입니다. +- 변경은 패키지 배포 범위(`files`에 `ai` 추가), AI 가이드 문서 4종, 공개 API만 쓰는 예제, README 안내 1절, SW 전용 검증 스크립트 3개입니다. +- 공개 API가 부족한 부분(More, 범용 필드 면, Header 면 레이아웃 등)은 내부 Import로 우회하지 않았습니다. §3 EXPORT CANDIDATE / MISSING으로 보고합니다. + +## 2. 기존 구성 분석 요약 + +- 진입점: `src/index.ts` → `components/sw-header/index.ts`, `SWTheme`. 배포는 `exports` `"."`(ESM `dist/index.js` + `dist/index.d.ts`)와 `"./styles.css"` 두 개입니다. `main`·`types`가 있고 `module` 필드는 없습니다(ESM 전용 `"type": "module"`, `exports`가 우선). Peer는 `react`/`react-dom` `^19.0.0`, 런타임 dependency는 없습니다. +- 자산: SVG·PNG 48개는 Vite library build에서 data URI로 JS에 포함됩니다(소비 프로젝트 33개 이미지 디코드 확인). 글꼴은 포함하지 않습니다. +- CSS: 토큰은 `.hm-sw-header`와 `.hm-sw-theme`에만 정의됩니다. 컴포넌트 규칙은 대부분 `hm-sw-header__*` class 단위라서 `SWTheme` 안에서 단독 렌더링됩니다. 반응형은 `@container hm-sw-header`(12개 규칙)라 `SWHeader` 안에서만 적용됩니다. 전역 선택자는 없습니다. +- Overlay: 필드 Dropdown은 absolute(필드 아래, `z-index` 30)이고 `closest(".hm-sw-header") ?? documentElement` 기준으로 좌우를 보정하므로 Header 밖에서도 동작합니다. 속성창·K 가이드는 `position: fixed`(`useSWHeaderOverlay`)이며 Portal·Dim은 없습니다. +- `dist`에는 내부 모듈 `.d.ts`도 생성되지만 `exports`가 deep import를 막습니다. + +## 3. 분류 + +### PUBLIC READY (현재 외부 재사용 가능) + +| 컴포넌트 | 근거 | +|---|---| +| `SWHeader` | 공식 기준 템플릿. 예제 A에서 1920 좌표가 Figma와 일치(0·80 / 65·310 / 377·1301 / 1680·240, 49px) | +| `SWTheme` | 단독 사용 토큰 범위. 소비 프로젝트에서 토큰·글꼴 확인 | +| `SWHeaderHome`, `SWHeaderDocumentTitle` | 예제 B·C 렌더링, 문서 Dropdown `+ New` Callback | +| `SWHeaderLayerMenu`, `SWHeaderColorMenu`, `SWHeaderLineStyleMenu`, `SWHeaderTextStyleMenu`, `SWHeaderDimensionStyleMenu` | 예제 B·C·D에서 열기·선택 Callback·Escape Focus 복귀 | +| `SWHeaderActions` | `showPrint` / `showPopupGuide`로 K만·인쇄만. K 가이드 Hover·Click | +| `SWHeaderInput`, `parseSWHeaderColor`, `parseSWHeaderNumber` | Input은 예제 D에서 Enter 확정·Escape 복원 확인. 파서는 이번 미검증 | +| `SWHeaderLayerControl` 외 필드 버튼 4종, `SWHeaderWindowControls`, `SWHeaderProperties`, `SWHeaderPropertyBar`, `SWHeaderPropertyPanel`, `SWHeaderLinePreview`, `swHeaderLinePatterns`, 공개 타입 | 공개·문서화 상태(기존 사용 가이드 §4·§8). 이번 소비 검증 범위 밖 | + +### EXPORT CANDIDATE (내부 구현 있음, 공개 API 정비 필요) + +| 내부 구현 | 재사용 가치 | 공개 전 필요한 정비 | +|---|---|---| +| `SWHeaderMore` | 조합 Header의 Overflow | tier·`data-visible`·container 규칙이 `SWHeader` 구조에 결합. 항목 visibility API 설계 필요 | +| `SWHeaderField` / `SWHeaderFieldText` | 새 필드형 컨트롤이 같은 면을 재사용(예제 D 표면 CSS 대체) | `variant`가 5개 고정 폭. 범용 폭·`children` 계약 필요 | +| `SWHeaderKGuide` | pill 없는 K 단독 버튼 | 현재 `SWHeaderActions showPrint={false}`로 대체 가능. 수요 확인 후 | +| `useSWHeaderDropdown`, `SWHeaderMenuDetail`, `SWHeaderColorChip` | 새 Dropdown 동작·`… 상세` pill·색상 칩 | 반환값 계약(ref·style·shifted)과 CSS 의존 정리 | +| Header 면(객체 수정 / 창 영역 / 막대) | 조합 Header 배치 | 현재 `SWHeader` 내부 DOM. 예제는 소비 CSS + 공개 토큰으로 구성 | + +### INTERNAL ONLY + +`SWHeaderLayerRows`, `SWHeaderColorPanelBody`, `SWHeaderLineStyleColumns`(헤더 Dropdown과 속성창 Picker의 공유 본문), `SWHeaderPropertyPickerField`, `propertyPicker`, `propertyLineTypes`, `SWHeaderLayerIconArt`, `SWHeaderLayerToggle`, `layerIconOn`, `SWHeaderCommitPresence`, `useSWHeaderOverlay`, `useSWHeaderColorMode`, `SWHeaderKGuidePreview`. 상위 공개 컴포넌트의 상태·Focus 계약에 묶여 있어 단독 공개 시 중복 상태 위험이 있습니다. + +### MISSING (SW 패키지에 없음) + +검색 컨트롤(예제 D에서 소비 프로젝트 확장으로 작성), 범용 SW Button / IconButton, 범용 Tooltip 컴포넌트(창 이동 Tooltip은 CSS 전용), 조합 Header용 반응형 More, Header 면 레이아웃 컴포넌트. + +### 발견한 재사용 제약 (코드 미변경, 문서화) + +1. `SWHeaderDocumentTitle`은 앞의 로고와 겹치는 전제로 왼쪽 테두리가 없습니다 → 첫 칸이면 소비 wrapper에 테두리(예제 C). +2. `SWHeaderDocumentTitle` 폭은 `100cqw` 기반이라 Header 밖에서는 뷰포트 폭을 기준으로 계산합니다. +3. 창 영역 배경·테두리는 `SWHeader` DOM에 있어 `SWHeaderActions`/`SWHeaderWindowControls` 단독 사용 시 소비 면이 필요합니다. +4. `body` margin 등 페이지 기본값은 소비 앱 책임입니다(첫 소비 실행에서 8px 오프셋으로 확인 → 테스트 앱에서 지정). + +## 4. 변경 파일 + +| 파일 | 내용 | +|---|---| +| `packages/sw/package.json` | `files`: `["dist"]` → `["dist", "ai"]` | +| `packages/sw/README.md` | 끝에 "AI 코딩 도구용 가이드" 절 추가(기존 본문 무변경) | +| `packages/sw/ai/AI_USAGE.md`, `COMPONENT_CATALOG.md`, `DESIGN_RULES.md`, `COMPOSITION_PATTERNS.md` | AI 가이드(배포 포함) | +| `packages/sw/ai/examples/*` | 예제 A~D, `SWSearchControl`(소비 확장), 소비 배치 CSS, 샘플 데이터 | +| `packages/sw/tests/ai-docs.check.mjs` | 문서·예제와 공개 Export·링크 일치 검사 | +| `packages/sw/tests/ai-template-consumer.mjs` | `npm pack` → 저장소 밖 독립 React 19 + TS 7 + Vite 8 프로젝트 생성, Tarball 설치, 설치된 `ai/examples` 복사, `tsc`·`vite build` | +| `packages/sw/tests/ai-template-consumer.browser.mjs` | 소비 빌드 브라우저 검증(Chrome, Playwright) | +| `docs/sw/ai-template/` | 이 기록과 `evidence/`(스크린샷 7장, `report.json`) | + +## 5. 이번에 실행한 검증 (2026-10-19) + +| 항목 | 결과 | +|---|---| +| `npm run typecheck -w @hm-design/sw` | PASS | +| `npm run build -w @hm-design/sw` | PASS(`dist/index.js` 712.25 kB, `styles.css` 102.25 kB) | +| `npm pack`(실제 tarball, Publish 없음) | PASS — 40개 파일, `ai/` 문서 4 + 예제 7, `dist`, `README.md`, `package.json` | +| `node packages/sw/tests/ai-docs.check.mjs` | 19/19 PASS — 문서에 쓴 SW 이름 전부 공개 Export, "공개하지 않은 것" 목록에 Export 없음, 예제 Import 전부 공개·deep import 없음, 패키지 상대 링크 정상 | +| 독립 소비 프로젝트 설치(`react@19.3.0`, `typescript@7.0.2`, `vite@8.3.0`, `@vitejs/plugin-react@6.1.1`) | PASS | +| 소비 프로젝트 `tsc`(strict, `noUnusedLocals`, `skipLibCheck: false`) | PASS — 설치된 패키지의 예제를 그대로 컴파일 | +| 소비 프로젝트 Production Build | PASS(번들 500 kB 경고만, 오류 없음) | +| 소비 빌드 브라우저(Chrome 1920 × 1080) | 27/27 PASS([report.json](./evidence/report.json)) | + +브라우저 27개 항목: 자산 33개 data URI 디코드 · CSS/토큰 로딩 · A 기본 Header 좌표 = Figma · A 레이어 선택 / 종료 Callback · B 순서(DOM) · B 크기(49 / 80 / 파일 x65 / 234·192 × 38) · B 문서 `+ New` · B 레이어 열림 · Escape 닫힘 + Focus 복귀 · B 색상 선택(열림 유지) · B K 가이드 Hover · B K Click · C 순서 · C 파일 왼쪽 테두리 · C 선·문자·치수 선택과 필드 값 반영 · C 인쇄 · D 검색 필드 표면 = 레이어 필드(높이·위치·테두리·radius·배경·그림자·라벨 12px) · D Hover 링(테두리만 노랑, 내부 픽셀 불변) · D Enter → 검색 · D 버튼 검색 · D Escape 복원 · D 색상 선택 · B Tab 순서 = 표시 순서 · 페이지/콘솔 오류 0. + +중간 실패와 수정: 첫 실행 24/27(소비 앱 `body` 8px margin, 예제 막대 `box-sizing`, favicon 404) → 소비 앱·예제 CSS 수정. 육안 확인 중 D의 Hover 링이 필드 전체를 덮는 문제(표준 `mask` 뒤에 `-webkit-mask` 선언) 발견 → 선언 순서 수정, 테스트에 픽셀 검사 추가 후 재실행 PASS. + +증거: [A](./evidence/A-default-1920.png) · [B](./evidence/B-viewer-1920.png) · [B 레이어](./evidence/B-layer-open.png) · [B K](./evidence/B-k-guide.png) · [C](./evidence/C-feature-1920.png) · [D](./evidence/D-search-1920.png) · [D Hover](./evidence/D-search-hover.png). + +재현: + +```bash +npm run build -w @hm-design/sw +node packages/sw/tests/ai-docs.check.mjs +node packages/sw/tests/ai-template-consumer.mjs <저장소 밖 빈 폴더> +node packages/sw/tests/ai-template-consumer.browser.mjs <같은 폴더> <증거 폴더> +``` + +## 6. NOT VERIFIED + +- Firefox·Safari에서 소비 빌드(이번에는 Chrome만). 예제 D의 mask는 표준 + prefix 둘 다 선언했으나 Firefox 미실행. +- 이번 소비 검증에서 직접 렌더링하지 않은 공개 컴포넌트: 필드 버튼 5종 단독, `SWHeaderWindowControls` 단독(창 이동 Motion), `SWHeaderProperties`, `SWHeaderPropertyBar`, `SWHeaderPropertyPanel`(13개 필드·4상태), `SWHeaderLinePreview`, 파서 함수. 기존 Storybook 검증 기록만 있습니다. +- `SWHeader`의 반응형 More·10개 폭, Colorize, 게이지바, 속성창 연결: 런타임 코드를 바꾸지 않았으므로 이번에 다시 실행하지 않았습니다(과거 PASS 기록은 기존 문서). +- Noto Sans KR 실제 로드(소비 테스트는 시스템 대체 글꼴). +- 저장소 루트 전체 `npm run typecheck`·Storybook build(SW 패키지 단위만 실행). +- `README.md`의 기존 `../../docs/...` 링크는 Tarball 안에서 열리지 않습니다(기존 상태, `ai/` 문서는 패키지 내부 링크만 사용). + +## 7. 추가 개선 후보 + +1. `SWHeaderField` 범용 폭 공개 → 새 필드형 컨트롤이 표면 CSS를 다시 쓰지 않도록. +2. 조합 Header용 More(또는 `SWHeaderMore` 공개 API) 설계. +3. `SWHeaderDocumentTitle`에 단독 첫 칸용 왼쪽 테두리 옵션 검토(기본 Header 픽셀 영향 확인 필요). +4. Header 면(막대·객체 수정·창 영역) 레이아웃 컴포넌트 검토. +5. 소비 검증을 Firefox와 속성창 단독 사용까지 확장. diff --git a/docs/sw/ai-template/evidence/A-default-1920.png b/docs/sw/ai-template/evidence/A-default-1920.png new file mode 100644 index 0000000000000000000000000000000000000000..eb4a525cdec73fd38cbed6d1af189fc570d46963 GIT binary patch literal 41247 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 literal 0 HcmV?d00001 diff --git a/docs/sw/ai-template/evidence/B-k-guide.png b/docs/sw/ai-template/evidence/B-k-guide.png new file mode 100644 index 0000000000000000000000000000000000000000..a7a024bc5513c309bca38ff338992d41c36654ad GIT binary patch literal 32073 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 LMe%ac&jJ4jm3w`Z literal 0 HcmV?d00001 diff --git a/docs/sw/ai-template/evidence/D-search-hover.png b/docs/sw/ai-template/evidence/D-search-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..3354dca9c1dc08fa806b6b45f8828e9b2b1fdd2f GIT binary patch literal 11649 zcmXwVh8q!|2sF^Nm@9WZPd?XZ*)0HCvkqBK$$ozzXi#bNWKneqBKn&Oro=bWeZ8ehRZ+X3+`;g#$HE7i`NoOBQro_ zut2~pC9@sZETmKL`BtIBAg&s5qJTJdOWS0Ysj7Qyw_@?sp=jkDq-r(#(G@MA^aFen zh6E@iHsLBgxbOg4jP_lrLh+Hg-tfmLwmzV#Bsvmc$3EGoi4=7PI~+!sKY+>$XRH~H ziD@F>W+@o!PAL-@T*wVzi=m##j|FX3sMgT#8E^;Zw!j9ulq8QT;MyAjG%xG12Yk z#apr$l}RCD8l|WZB~3GJ(h2+Rz+gKlww%%z#*)E|kR#^7W#tO`&g|6W(>Eu^BV;-7B=DTE$oMipl_)QDO(RRAtfcfCxTBX0 zE{lnjP?Ybd85V5*M`$=3n@fCZDmu=EFJnI;FW*ILSI#o$aB;{piELJ^beJmre)Z5D zCxH!+`PB`DM&Tc$jPh-7KX8D*+s@Sow@TPs_p%O=N_YGKmnPOfkn=?JU92eI?_OjV zx#c_43j;m~Mf>q2c1%^-l_H{Oz?lFs{9Y1M+7lpW!h@@yuk z37gJeRapV68>?Sv)uY-DdCsdz+99ciY4gTF2V-x8NG0-tIv%0KtjUB3S6XrnXFLC=UW4rv)+$hC| zB^L_7)aTIoB)WDqVO_SczWnB5B~Vo+|I>7^fZ=1@y;3!Z$YUy-6M4{7X^1YGqNz$3 z^?uV^Gn7#>fx26`-;8{&K>B)M7_MKn5F~H6XUo^pGLMQGqZltc*GxC5=DDi}4U>5ok*(D%{Nrl7B(O^T zCkl-&v%l?p(jGRieqqFy>bS%T0{^-sILWKcZ@5EfkzdNGyw=bxo4(&zxs4|Bz)*k3 z&Sks>_7V=GEZ%E&HPw~Wv2e9AN>XYuu%7jQj!kUoyqtjadf_3e#K?Sh(t#yI z=j14?2z3KiK$)Ls9A&!oe3jC&^){AFyeW3?R(Rfron_@l-lcJU@uEMdl+{PRh}39% z@>RYPkC)2G%yejhQao2&xN$e__aTp^QoB9OgTJndV1@2O-oW*kR1AMxn~A7Q|K5AN zj7*ug1qU*z^SMfOGoPx8mwp77(=&Jwf+Z zM<^Y^c)naEV2(?p_EeMYSlCdy?0=p4PR^H2iC7i-o@{6_TMuMUF6fj^pLw$;-A!Mv zs_d@G&LXpcncrh3_CHxkiJ6#a*rfmYvq76M?kBT9bAXpU5uo#Art+Fv0OS)TjkA*ecb%I(*dT#JP z9@kUL_0e`;G@RQS36fkApn;)#a$52N1qeN-=kNC6aSxa^oU=IcQ}*@#*!tNuMe=(T zw;4uTs5eb#+?t_5LA&evxAyXWg`mR*=Nb5Z+yrZ2vZ}0A{yVj4%fh?yiN`n-eSq6W zRXCFWYdm^-SF6*U(plPU zkd}lqNoLQ3vJ1r(UAYz{L-mXULcnSBx5hU-s+pwpJE1bb@;-+#&2oLc;i=7-e zdjs)`OIpuHapR#1c5@trEf`%c=8P{^|K&Ji&i67hT&62rI;l9A-3^!}Gs94}Jiw4U zgYX5B^w|UyBIt-M#_y&z{3>D(Ja7Xrj*)F}xZE*U!Rq?+_|cI#cNr}$t2LFeL@$B-|v`2ON4j_ClzUjv9mF zv&H=A5y0ckR31>_Rm)ea;>B-*r50O<9-(Qe50J&N6UI-fkCD8Az)%P}t3LUN(hkaBUfMSzk^sztUU; z$B#$wZ0o)DSqzlRO=T}@K4;y>3$c=sa1@cC8wCXij6Uo1=NwhT)n9 z7jTqxgi|kMQp!jVzRQhaD=tGF-`JAwViHCxBD<#_0-1Sh5}Q0npQSWIolMaQK^MYKPyM*oiU`tMqKd-ENl z@;Gfv>|YrB>Zv2})#p981MT}((UlzSS2wdCZsKs0yw2~J!$Nf z8w5f~%t`b!bQaB#BgS!4C>uM^Wj&o5b)tY5(Gw=(*)wSAcw2}amJdmqN3#mYk_cbb z);}-jjkewi)bi6ai?D1-)!<51f6ydks9hMA#82K4@AlUlxZqP8?I=~be=6?mga{2O z(JrO~Jegoyp&ZEzxuAGNjo^&pNKurN5pF<-{rBWjkg|D`d^w#G>oT=S+kA?-0v)!v zy&GI+cxb~40$-$x*ek4I=&T<9m)Y&5^UO=-zQU!AfbF(>?%W$Z>c1e8)yK1>(}t|H zDNozi-J`&BTCVmUj)FvE(nV^~4cGQ32|4M1zr zRC>VU9tF@194{=wpAf|h$cbba7Z6c-mvEF!$EQ*76;k@lfpVZgbD76B^a$Vhzn(mV ztyEVIzuRJrA5J8&Z$a;btq!ArU%X{!-OvwsIjfk+J570;o=36dCpmk1t><#5?Wk~6 zia@~zA=On#E7>jw({d59*CcQ_3*SlYpGH))$A`a#IlqF6<}~1ht=u-dD5!dfx_O!| z3zDc=9K=d%E*6?*xS`?ejpaAuzxPb|Q#W1KCk>_G45&pRlYH{U+PMy+L<~x}kvU?T zD+Xa>KAtq}=9~MFiM7{;Qm(tiPcB=ory2(1+u+6NAoref@{^B2mDBV3cfzoEzb0Ce zv{D%6aDI|q6z1`N4GHz$^%RvrG>RRx>#UnT>z5Hy%B01Y`I`o;r-~3qOJelYhU3ec zI;Li*tkv5O2uOWo>MeB7%S4wJ>$?8e;XZ+b9};HNo_{#}{_nM7&KX$S+15&xl->qq z$X~MiF;}OPKWrV-^y-4_r}iw$#nHL{Wkr?1EEYzb ztNhycIbG@Lm1IAuj{q7{N;G=pu4@+~if*_Z>Hm_ex7umGy;fg1K*hJN)9^dQ#!+Lz zke}*)AYS-Kg)nmGrsuky%YNr|-uneBrf4nXyi2al9`XhqIB2d~z3T9Wt3{8@qL!LL zl6ya2>Eq6{`l$U^KitD2rY{A>2GSGf4-W8pvzng4? zAlKgyoxh~PC*`~(LG;QcT)k6CXx9g<-Qv(N_Moh(4uJ(TQauFGQ)}*a+a)q2Y3zVl z{0r8Z1d-6c^a)0$%VDRK{8JZOTX0NN-Ayp@3+{JTm}k1OXz&e(Kb%@}1l#e11fY?v zcr=2qL(8bF`eXj(=)1Ntj}vtJ&87XSr|@;NoLmZb3WO&W8{_$Q(IL%oXsF-LqNMM* zUA57{TKll~3dNafEaJHwJy%ns_qI8&E_5Eb7QRTL6s1^IaoZ%A$>XvEa%!WRUS}WL z_C2|e7r3>sbG~6wKTn>)ubyqB|6OGY7fwTV8cKElE!09zWZ;mEeAUW(w2lEi0RiZm z>r|`NW2?HZrg>1sS5Bmm^*A(ym*->pT=#4<_-dBe5uR|v{a^#0~f48txph(5fI{}k;<6~w-mSRmrJU#V+2I$ib$ z(EqxGBU%FgLiuM9g3eg8yh;Mo<)2}3<6h_Z{r{f@Xx|A!&Qf8B@`IF%Oeu`UOJP}8 z3bZkAy#oAg8-PDrf03zBcxtKb1u!Y-XqdeYNd>&8(OPrXix;vx>CPT{1YJFfwSNrf z)HJ&<U1@%D;n~Q9{7Bht&XtPqbK*6(P3p}1C_tTtRJDwxYrh<3go5zQubIRD6C0) zwP3w-w(kx|T>Yo9Yy0l(@%Gk5T4fMDAi&@KL@vRLP^oF{mw9jqEPu!XEz&6*T^FZD z#38)wA4*^GNdbI!{t$ybU5}DrS}3ilz|gS#j(N$ameM3GIEd~tS4LanMOiRqa=ArV z%FS=jVtep$d-+XyE^-!t$GYu3#~x`6A~apeuIf%clie9y^Yz%~QZ>s!JWihgK(+F{ zUy!wOA@v0Ii-8ug<>Dt&L!=Nx2mh7}3_u%F_=NGNgn9`=M(~Efm^$@lI+Tc9)hJd` zT?$yl0S%!fkjz`+2w7xYMMh68Dr!8=_qvep>*_PcieHns51oh!PLg~6+jO+Q&Ev@c zy$7>zhFhCNj$%1q>uUioau17MF8C?upZ(K+zh45{=)jT6*jO1?xN01HIIiV?T~Da} zOG?dXNR#a~#2$P3P|$b+Z*_A=S>e(TXl2)JEe7ugbCos3?DoS;hGEVIlR zXWTapa|TsPviC$Q0daAm*e6ML=p0291kP2o-Xp?&f7*{R2cS;RHpO$l?N;Ck+RI!3 zWpc-YDc?c4-}vM90-N&K9X25a)iH#l>ALy<;)M!+V0hMaeD6x(v7dAaDg+ zykGN;+1$NZ{`iz(=j(boPnZI&P{!?Z{o?i3BWi5-q7a`O`Gu8o(8s!Tvc7cMz&{2m zbBqwn5Qf&)NIi=$GG?jU(X>Ar;Tvk?4Odf;R}9>^A1^fmhYIGTn@@Rri7TF!8#T<8 zw)3I65Bk(_+U$0l&o{y^y@RMj&PM985|eks_Um=?@BhqDpQ>C#)|Sp1U#7r#idT7}fObvGbLW&v%Vec|GyA6N$W52x!MJsT6s0up_p1#f=gY z2V-coAk(;%p{UsuA#@#mH!3MtO0Pdrrxzl^AvbAOim#7=Q{f|g;fc{rCwc_l(<~Rb zew@?b)h+jBLHmPyDv(y_%N|Fn25V6*-0DW+8z^!04UJYf(t4|plZWOWOb@(fV?y?P zYsZMwd{gV$>hHad3!FlCL@@(lwh!Rqk9V=ZDm6)D)Q|r0*A)AVj&Q8V^xKUs8=C z6|Hi5Ty8~{9zHDby7Frt9C4`G{ZR&Il}2$6KiAowwkdBkMA?1;hnj-1_IMX{vF^oMdfA8cCYFW5@Ln8WqyJIt;;Bb&b%>QMC zG_`j}lO(KZl$r^NBz^ebMeD!wQ}-=fS>}#EYY24r?pFtmojt?(TVL z25NBgR4cNHnR<)~0YX)v8R+0t2|EM}2Ng_BMB8J#+YpzAgI1^1CA zh9owCm;}wTAhmXvY*yaft=9b-am$(QPP@6_Ik(akYq#X{fJ+aedDdwe#I80z%T@FQ~6DmZs_4d=G61Z!N} zGsjI}Ouo zdWg)KRxW4D%JiV&k0{H!^3~@F++vKbL#_XMEA8&h1*CcIXT?`joabbRUHfSqqs-a7 zPDN8H{jt_7L=Ya<~yw+h;BOYaE1EUOU-G0>>h%#3!DXvy0}VECZ_H= zyTFoFPtvZ(x<>oC&Km;FSojz@uI{UB(c~_Fg3HkQq;I}>&@A@$j6yl`(1e@brD?iF4B56wAxp z>FXA|33{%+_9ag6}T~UszH8dSR`ZmrTKxQA)=4xb*#vC}gY@0zx>H6iG4@hjIW? zsFW1Q5~5dl@dAHn>|(1QZGAOflUD={)uV)kphKizNPjwii{33%>aB^sl zlSu!*+|GSYZ3nVjZWn_uH6ahGl7qlpXzVV8Vq~V@a`2)DjBPEz&}V1QY@?f4c1v_S zi^<%cL2c0MD51T+8YV6-q`8b@aRrRSJ(Zgbg+zRv=ehbXZvVNm<=jE;iilW$_z~Ko zl9tG*l3$+*Z>I>3O3L~KMwf7J(3{I|_NIzOXe=UNXm5?jkCvz5T|$@ULg9;t#&Y#a z0rxtmpg#N>lPIara;!&2OV#VjKN$b)4m#|spih7x`LfrS@yAm^cOLn>hnTq z-)8=Rv!v&|hxK!a-eXm~wz>w0^ZeTSbFH@f`D=jp)}!+7h>I&FZNPDq#O!Y5h}}eE zKAl2GX2tVi{=PLIz_punVpu|}^7uM>lF$Zz^`F^*NJt+BRc&&=fg=2;obR`%rp$B( zXjx8?7pF86iGru~=NC$+CxOBOCkD6t`tmS5q^`dFQ(x10?%V$S9j`z0d&0X`n$mCC zKRdNKGw`3xe0+uxN`?I}ST;TZg{NFtG*9B<8OzVk)`cn8m@$+9X$Bp^tfbT?sd{~u z?R00mbC&h!Y~13{dIK%@WMp$W`EJ(}TYegs{`AQh|KB&)T>+@{^$3+~I-5fU^zmqZHl8*(D0m3f@ z|2Pd+@rXGzLrP;C>gH!g@^;ob#NB4e=73xha#~ zi--N)u^eVU+J#QGrpcbIK)6^tFoBvzUzr}ib33FJc&6pCTdP)B<&&$F*StdAZu{AA z{e26SZqct2PQehzle{D#KH5jG#F$(7>K^`VWKuB+-YHYIxw_MT=$H*|ZG+*T1FC1B zg;+zQB_TLaoBqAacVkffa|WX3%YqHMqK_^7Y;@dD!gv8e%w6F}0<9ZQ`>%$ew@l0) zrg)Cbj9gQ>Vv`iR(KC#YW4*=iA|!s^AT53S%G*H$UOGACihJS;=*a3kY8bZ;L&GLQ ziP-lhK36vsmj?T`ZprR_%OE{P?9{ZF9ac%H?uISeh<_d8Wz;n2iX=pcQ}gfyQNwb0 z=blG%{TeiQJR_{1+?iLpqLpXu9=%qtJRV(g^Au=!vn-_ZwdJUA@u7j!o%bs=KXEd3rl9**e~p`Mv_X(_%rj~Z*iu~wC(<1Usa{1)MW z79eG=ts%^!*vL=(>_JvG$HIcf&o|6<(N6jwzZn%4}P2w?cPPubRndFfe4FxH zWtq&3A#jsAAu&?9LK51(8o?y)z;4vAT}(}%E|zcKc~YtO2G0ApysfV#ReOw7TqLCg3@0QQ)HJ|oFk z-2!jsAL%#KY!E*My_-&;6uMZkn^U58I!e007+wNmT|@t{ImC1Z zt_x11b`Cw_)|pQ>h6SncwaUDa64>qGP%NjNdz;m?%!xkMh5&4;Bc5Y78 z0nn}P+gGrbUMs!OjoRVJK0It;$j<7r0?K(z%SMdH33w~B3%6h*;B}te*_2Upr*;oU zb9iPyBVd^{C1&eXff=kL!iWo*DDxodayIMCNIy8r+F`$7MYYl;7&^qhT6ewvD|Npl zEbE^v${fv07^q+2dy?C7wmOs<8?r}6?+h>4UpP`i=AefG2q%WEP6YhOkSZ_dJ1MUj zgMfCFb6Rw;?O+s7L7T$a`njv~>RVW%+vXG#A{c9Wi#XyQ@6S8^Rk~@ErLaQ2l)}j5 zc|rNVF^9t^RCvDl9cRN#j7I+5qpPk&WY~f`;)eLV8qJVZ`D}RJ^4ChzRrg9R@}m9v z?N9?cz|U`DD(T43Am@wlE!4c3YPqjLK2?trL>K=dMtH6=GCPtk+C*^32>xkvC>9kS z5|kSHa~A^*i;`tj;)f|!?||MQeStN1F_vlzGPZb=nO!3l1^ws9e{L;4xOM3v%sipb zV%_AZupW~=QvUyHy`B$C3DsPjN#Wwxk!4BN+RvvFiyCURn~97Z{&-ykR02%*137!a zWU*ZgmGx7cjvsZiY5Ay6i^*QAT;Iz!1lV(^W+X81@=eb`LJbnXQ%<1nqW zMJlDPH&qJSx0{`(%a&dF_PqnQ6M7N3hg?_y0b?C0zd8piuigCZPNgt?WVg2~1K^KT ze7g=V-{q(rGpsJ(F$hZNQ|^M`($~NY*g}KEZxCs})UEFL9Qp^X*kX ziQ6#j2Pvs1l05Ksg0JzV-}3LsW%}8f*}{~g5VZ^Nwzv&o#-+UHumJr6%9hJ`k4LO; z&(ZkXOKtkP1H%2nr(YS~lD+~!_FyO4z|MOm2Yye;AuE2HT8@C#%KecnfTCYHd7&ra zqvm<*VEMI z{es|s5Ja{P{Gin-d;=TzOZ#!Rx+TOw`hJOJUm`rbR(3*lhkhBRLlq*Y!A6|4?4!IG#4Z z_?lhL(_BAhK@@QR;;y03dHQ&8V%VOvomIQW&w6BX4B?iNy4+Jo4&Qh&2r2#8^ROAZ zyGnbcRkf@3U|_cspw4M*}xBv-8h?RKb+$QTt2DfP=oz69Ya&Bw@n~#6eiVdAoQ&O-+oNz3K-U zs(Cr#U6|0${4Gsccs{8WCArR}jc?|VY#oS1{DUo`P{DiXOd zRbxw9uEuCf_3`g-rnWlYvcaZ|g4#cDfHq-;Jt3jtgno%*L+n2-GhgB|lGsKZ@!I5b zZ}r=p@qp$2?Wwg>;GipSnS9@qilr{66iCtI1}~p%1<&={&nJOKOoC>!quSiDwNBfy zy0xQUI}FRsS4^sE!&cAfU!MS-{FN2omn13BWHEHXxjbiKky$;wWG5V9gC-XfrnVG#gD!aEpZW8ukbah1UD&bo z3}F_!=AX$NK^oNkekcT4N7QD1=rD9l2kTmP`!?_tc)NkzDnorjl;McB#y;k#bYem@ zVBh26daCmhcUW<6KS6&-yw#K&^|cQNh#DHc;}ISk4^~g9$>lV0TNykuHSsFb!3e`I zu$*ix=5+QNp=K34llk3D8Gk63G#MAX6ouecx_<-3b_v#DCWVUQ1gQ!pRF(XM?Z@xA zkT)uqoSHst`;vQ|T+3(C8^2X#Dka}#4`YSAp^T{>{b7Z1^1-18x*|7Mz;BcjxA z_UBrXFO$76v16B|8!xJMO^$QNvB+%fVX<-0Q#-m#orpZuGC~$n;P9pi2m@3P1?26V zM@Y(~%3$EDuWQW|@9m?AbrrQ(8%ms9%mJkei1ckY04w7$52JEvRPJw4zpj3O(rob+ z;ph#CfuC#b*aoM!9MEqh<5z=q} zm2EjiR=56NbUSPpwG}Vlukj8<)ll%Fh_2!S0Y=vD9&*-0Ut$C3!pyyzC4V>X!FOCm z4{6#VHiAmf_Ife)!X>YCM1fnR#H4+!)mIIeVDBqQgiwLtT}+tbKQ&6%9$Nef(?72f zKgG=;iij$n;k$AX|R7C&a zvs8F;5BC%~EeMN?TjO;T^@?5T1OF?VY+Oo1V5~0(PllZYPENWir=fQ3 zhoV#-e3W*o<6e;eWg?>TYP@39$CF;QrIdMrAp}Kf<#;xPNgio`rsAs1i+%qgsbc>|;OFrXx<1eQ>B2?6J zqTsGTl@!ItcYJ|DvF?PBSh{s(b~kDLUm7sj>+nS5k2k}#+k15n!f;~dhsz!MK;@3z zl+qio*_kB%p}=*k_~NP#^1Ou9-AU|`K{Im|s@pm`Z|W3$OXpi!Zn*^Y)GH2WtUQU2 zu8G0@$AD_Aq^%Q)i18uJ{6drT2>GnI)Cy1YgAz|c5;BU^-|jTEBdj*tcxHqYl+S8{6( z27CcRebeWFhQ^&KpN{w#=W@Q~3qN9$14{ee8dpQi4&VU!{@B50sviL4jfhBjjoQ!S zk?!;h|Ao*G$}}Rs*_9QX*1Tth7Wl!Vu8I;74~?7*>x&IZUph95aBYUka)hrCNyfvg z`g$&F;5T8CUcoSQa|35mcGy=f>uOvxf-CSw^S5FM( zMdG6WBe10?F)`BrC`t(V_)z(Ob)&5;6(0OQDx41H`~R=@!<`2g{9n@z`Eh9f*L2>W qcX$Bc{T^X}favFkYxnU4AS0` 안에 배치한다. 배치용 CSS만 소비 프로젝트에 작성한다([COMPOSITION_PATTERNS.md](./COMPOSITION_PATTERNS.md)). +4. **조합으로도 안 될 때만 새로 만든다(3순위).** 새 컴포넌트는 **소비 프로젝트**에 작성하고, 공개 컴포넌트(예: `SWHeaderInput`)를 내부에 재사용하며, 외형은 공개 토큰 `--hm-sw-header-*`만 읽는다([DESIGN_RULES.md](./DESIGN_RULES.md), 예제 D). +5. **새 디자인 값을 만들지 않는다.** 크기·색·간격은 토큰과 DESIGN_RULES의 확인값만 쓴다. 값이 없으면 추측하지 말고 사용자에게 확인한다. +6. **존재하지 않는 API를 추측하지 않는다.** 카탈로그와 `dist/index.d.ts`에 없는 Export·Props는 없는 것이다. +7. **패키지 코드를 복사하지 않는다.** `node_modules/@hm-design/sw/dist`의 구현이나 `hm-sw-*` CSS 블록을 복사해 같은 컴포넌트를 다시 만들지 않는다. +8. **실제로 검증한다.** 소비 프로젝트에서 `tsc`, Production Build, 브라우저 렌더링(Dropdown 열기·Callback·Focus)을 확인한 뒤 완료로 보고한다. 실행하지 않은 검증은 PASS로 적지 않는다. + +## 2. 설치·Import 규칙 + +```tsx +import { SWHeader, SWTheme, SWHeaderLayerMenu } from "@hm-design/sw" +import "@hm-design/sw/styles.css" // 앱 진입점에서 한 번 +``` + +- 공식 진입점은 `@hm-design/sw`(JS·타입)와 `@hm-design/sw/styles.css` 두 개뿐이다. `package.json`의 `exports`가 다른 경로를 막는다. +- **금지:** `@hm-design/sw/src/...`, `@hm-design/sw/dist/components/...` 같은 내부 경로 Import. `dist`에 내부 모듈의 `.d.ts`가 보여도 공개 API가 아니다. +- 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). +- CSS는 전역(`html`, `body`, `*`)을 건드리지 않는다. `body` margin 등 페이지 기본값은 소비 앱이 정한다. +- TypeScript에서 CSS side-effect import 오류가 나면 Vite의 `vite/client` 타입을 포함한다. + +## 3. 스타일 규칙 + +- `SWHeader` 밖에서 하위 컴포넌트를 쓰면 반드시 ``로 감싼다. 토큰·글꼴·버튼 초기화가 이 범위에서만 적용된다. +- 소비 코드는 `hm-sw-*` class를 붙이거나 재정의하지 않는다. 배치는 자기 class(`className`)와 `style`로 한다. +- 외형 변경은 `--hm-sw-header-*` 토큰을 `SWTheme`/`SWHeader`의 `style`로 바꾸는 방법만 쓴다. 사용자 확정 면(파일명·객체 수정·속성 입력)은 기본값 유지를 권장한다. +- Light/Dark 분기는 없다. SW 디자인은 하나다. + +## 4. 판단 기록 남기기 + +새 UI를 만들 때 결과 보고에 다음을 남긴다. + +| 요청 항목 | 판단 | 근거 | +|---|---|---| +| 예: 레이어 | 재사용 | `SWHeaderLayerMenu` | +| 예: 검색 | 신규(소비 프로젝트) | 카탈로그 MISSING. `SWHeaderInput` 재사용 + 토큰 기반 표면 | + +새 컴포넌트를 SW 패키지 공식 컴포넌트로 승격할지는 별도 검토 대상이다. 임의로 패키지에 추가하지 않는다. diff --git a/packages/sw/ai/COMPONENT_CATALOG.md b/packages/sw/ai/COMPONENT_CATALOG.md new file mode 100644 index 0000000..999b020 --- /dev/null +++ b/packages/sw/ai/COMPONENT_CATALOG.md @@ -0,0 +1,75 @@ +# @hm-design/sw 컴포넌트 카탈로그 + +기준: `@hm-design/sw` 0.1.0, `dist/index.d.ts` 공개 Export(2026-10-19). 모든 Import는 `from "@hm-design/sw"`이며 CSS는 `@hm-design/sw/styles.css` 한 개입니다. 이 표에 없는 이름은 공개 API가 아닙니다. + +- **단독 사용:** `SWHeader` 밖에서는 `` 안에 둡니다(토큰·글꼴·버튼 초기화). +- **상태 소유:** 값은 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 검증 기록만 있음). + +## 1. 완성형 템플릿 + +### `SWHeader` ✅ +SW 공식 기준 Header(Figma 26:8944, 1920 × 49). 로고 · 파일 · 객체 수정 영역(그리기모드, 레이어/색상/선/문자/치수스타일, 상세보기) · 창 영역(인쇄·K, 창 이동, 최소화, 종료)과 반응형 More, 속성Bar, 속성창을 포함합니다. + +| 구분 | Props / Callback | +|---|---| +| 필수 | `documentTitle: string` | +| 구성 | `hiddenControls?: SWHeaderHideableControlId[]`(로고 외 부품 제거, `home` 제거 시 정적 로고), `menuOrder?: SWHeaderMenuId[]`(5개 메뉴끼리 순서), `controls?: SWHeaderControlConfig[]`(객체 영역 전체 allowlist·순서·label) | +| 로고 | `logo?: ReactNode`, `logoSrc?: string`, `logoAlt?: string`, `onHomeClick` | +| 파일 | `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`(객체 영역 메뉴 뒤), `

` HTML 속성·`ref` | + +- 데이터 배열(`layers`, `colors`, `lineTypes`/`lineWeights`, `textStyles`, `dimensionStyles`, `documents`)을 주지 않으면 해당 필드는 Dropdown 없는 버튼입니다. +- 반응형(More·대표 필드 전환·창 영역 축소)은 **`SWHeader` 안에서만** 동작합니다(CSS container `hm-sw-header`). + +```tsx + setId(l.id)} onClose={closeWindow} /> +``` + +## 2. 개별 컨트롤 (조합용) + +| 컴포넌트 | 용도 | 주요 Props / Callback | 크기(Figma) | 상태 | 검증 | +|---|---|---|---|---|---| +| `SWTheme` | 단독 사용 범위(토큰·글꼴·초기화). 배치는 정하지 않음 | `div` HTML 속성, `className`, `style`(토큰 override) | — | — | ✅ | +| `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` | 높이 48, 폭 190–310(반응형 clamp), 메뉴 310 | 텍스트만 Hover #FFC600, 열림 화살표 회전 | ✅ | +| `SWHeaderLayerMenu` | 레이어 필드 + Dropdown | `value`(필수), `layers`(필수), `activeLayerId`, `open`, `onOpenChange`, `onClick`, `selected`, `disabled`, `onLayerSelect`, `onVisibilityChange`, `onFreezeChange`, `onLockChange`, `onDetail`, `label` | 필드 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`(표시·동결·잠금) | 위 필드 크기와 같음 | 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` | 속성창(13개 필드 타입, 그룹, 형상 Slot) | `selection`, `properties`, `groups`, `onPropertyChange`, `menus`, `expandedGroupIds`/`defaultExpandedGroupIds`/`onExpandedGroupsChange`, `toolActive`/`onToolActiveChange`, `toolLabel`, `onOverviewClick`, `shapeContent`, `onClose`, `id`, `anchorRef`, `style` | 고정 위치 Overlay(Portal·Dim 없음) | 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. 공개 타입 + +`SWHeaderProps`, 각 컴포넌트 `*Props`, `SWThemeProps`, `SWHeaderMenuId`, `SWHeaderControlId`, `SWHeaderControlConfig`, `SWHeaderFrameControlId`, `SWHeaderHideableControlId`, `SWHeaderDocument`, `SWHeaderLayer`, `SWHeaderLayerValue`, `SWHeaderColorValue`, `SWHeaderColorOption`, `SWHeaderColorMode`, `SWHeaderColorInputValue`, `SWHeaderLineStyleValue`, `SWHeaderLineType`, `SWHeaderLineWeight`, `SWHeaderTextStyleValue`, `SWHeaderTextStyleOption`, `SWHeaderDimensionStyleValue`, `SWHeaderDimensionStyleOption`, `SWHeaderInputValueType`, `SWHeaderProperty`, `SWHeaderPropertyType`, `SWHeaderPropertyPicker`, `SWHeaderPropertyMenus`, `SWHeaderPropertyGroup`, `SWHeaderPropertySelection`, `SWHeaderPropertyShapeContent`, `SWHeaderPropertyShapeContext`. + +## 4. 공개하지 않은 것 (사용 금지) + +`SWHeaderMore`, `SWHeaderField`/`SWHeaderFieldText`, `SWHeaderKGuide`, `useSWHeaderDropdown`, `SWHeaderMenuDetail`, `SWHeaderColorChip`, `SWHeaderLayerRows`, `SWHeaderColorPanelBody`, `SWHeaderLineStyleColumns`, 속성창 내부 Picker, `useSWHeaderOverlay` 등은 내부 구현입니다. 필요하면 공개 컴포넌트로 대체하거나, 부족한 API로 보고합니다. + +## 5. 알려진 단독 사용 제약 + +| 항목 | 내용 | 대응 | +|---|---|---| +| 반응형 More | `SWHeader` 전용. 조합 Header에서는 More·필드 이동이 없음 | 조합 Header의 폭은 소비 앱이 정함(필요 없는 컨트롤을 빼거나 가로 공간 확보) | +| `SWHeaderDocumentTitle` 왼쪽 테두리 | 앞의 로고와 겹치는 전제로 왼쪽 테두리가 없음 | 로고 없이 첫 칸이면 소비 레이아웃 wrapper에 1px 테두리(예제 C) | +| `SWHeaderDocumentTitle` 폭 | `clamp(190px, 100cqw − 1610px, 310px)`; Header 밖에서는 cqw가 뷰포트 기준 | flex 부모 안에 둔다. 1920 뷰포트에서 310px | +| 창 영역 배경 | 배경·테두리는 `SWHeader`의 창 영역에 있음 | 소비 레이아웃이 토큰으로 표면 작성(예제 B·C) | +| Dropdown 위치 | `SWHeader` 안이면 헤더, 밖이면 뷰포트 안으로 좌우 보정 | 부모에 `overflow: hidden`을 두지 않는다 | diff --git a/packages/sw/ai/COMPOSITION_PATTERNS.md b/packages/sw/ai/COMPOSITION_PATTERNS.md new file mode 100644 index 0000000..179a409 --- /dev/null +++ b/packages/sw/ai/COMPOSITION_PATTERNS.md @@ -0,0 +1,82 @@ +# SW 조합 패턴 + +모든 패턴은 공개 Export만 사용합니다. 전체 코드는 [examples/](./examples)에 있으며, 설치된 패키지에서 꺼낸 그대로 독립 React 19 + TypeScript + Vite 프로젝트의 `tsc`·Production Build·브라우저 검증을 통과했습니다(2026-10-19). + +## 0. 어떤 패턴을 고를까 + +| 요청 | 패턴 | +|---|---| +| 기존 SW Header 전체(일부 부품 제거·메뉴 순서 변경 포함) | 1. 완성형 | +| 기존 컨트롤 일부만, 다른 배치·순서 | 2. 조합 Header | +| 기존 Dropdown을 툴바·패널 등 다른 곳에 | 3. 개별 컨트롤 | +| 패키지에 없는 기능 | 4. 확장(소비 프로젝트 신규 컴포넌트) | + +## 1. 완성형 SW Header — [ExampleA-DefaultHeader.tsx](./examples/ExampleA-DefaultHeader.tsx) + +```tsx + +``` + +- 부품 제거: `hiddenControls={["print", "popupGuide"]}`(로고는 항상 표시, `"home"`은 정적 로고). +- 메뉴 순서: `menuOrder={["color", "layer"]}`(5개 메뉴끼리, 누락분은 기본 순서로 뒤에). +- 객체 영역 전체를 직접 나열: `controls={[{ id: "document" }, { id: "layer" }, { id: "print" }]}`. +- 추가 도구: `tools={}`(객체 영역 메뉴 뒤). 새 도구는 아래 4의 규칙을 따른다. +- 이 경우에만 반응형 More가 동작합니다. + +## 2. 조합 Header (간소화·기능 중심) + +``을 Header 막대로 쓰고, 막대·면 배치 CSS는 소비 프로젝트가 작성합니다([example-layout.css](./examples/example-layout.css)). 이 CSS는 `--hm-sw-header-*` 토큰만 읽고 `hm-sw-*` class를 건드리지 않습니다. + +```tsx + {/* 49px, #060606, flex, gap 2px */} + {/* 80px, 다음 파일 면과 겹침 */} + +
{/* 객체 수정 면 토큰 */} + + +
+
{/* 창 영역 면 토큰 */} + +
+
+``` + +- 간소화 Viewer: [ExampleB-ViewerHeader.tsx](./examples/ExampleB-ViewerHeader.tsx) — 로고 → 파일 → 레이어 → 색상 → K. +- 기능 중심: [ExampleC-FeatureHeader.tsx](./examples/ExampleC-FeatureHeader.tsx) — 파일 → 선 → 문자 → 치수스타일 → 인쇄. +- 순서는 JSX 순서입니다(DOM·Tab 순서 동일). CSS `order`로 바꾸지 않습니다. +- 로고 없이 파일 면이 처음이면 왼쪽 테두리가 없으므로 wrapper에 1px 테두리를 둡니다(예제 C `app-sw-file-edge`). +- K만/인쇄만: `SWHeaderActions`의 `showPrint={false}` / `showPopupGuide={false}`. +- 창 제어: ``(창 영역 면 안). +- 조합 Header에는 반응형 More가 없습니다. 좁은 화면이 필요하면 완성형을 쓰거나 표시할 컨트롤을 줄입니다. + +## 3. 기존 Dropdown을 다른 레이아웃에서 + +```tsx + + + +``` + +- Dropdown은 필드 바로 아래에 열리고 뷰포트 안으로 좌우 보정됩니다. 부모에 `overflow: hidden`을 두지 않습니다. +- Controlled가 필요하면 `open` / `onOpenChange`를 함께 줍니다. +- Dropdown이 필요 없고 호스트가 자체 팝업을 열면 `SWHeaderLayerControl` 등 필드 버튼만 씁니다. + +## 4. 확장 — 없는 컨트롤 새로 만들기 — [SWSearchControl.tsx](./examples/SWSearchControl.tsx), [ExampleD-SearchExtension.tsx](./examples/ExampleD-SearchExtension.tsx) + +요청 예: "레이어와 색상은 기존 SW 컴포넌트, 검색 버튼은 SW 디자인으로 새로." + +1. 카탈로그 검색: 검색 컴포넌트 없음(MISSING). +2. 조합 검토: 텍스트 입력·확정·취소·IME는 `SWHeaderInput`으로 충족 → 재사용. 필드 면과 검색 아이콘 버튼은 공개 컴포넌트가 없음 → 신규. +3. 신규 부분은 **소비 프로젝트**에 작성: 38px 속성 필드 면, 12px 라벨, gradient Hover 링, 아이콘 버튼은 글자색 Hover `#FFC600`. 모든 값은 토큰([sw-search-control.css](./examples/sw-search-control.css)). +4. 기존 컨트롤과 같은 면(`app-sw-surface`)에 나란히 배치. +5. 검증: 레이어 필드와 높이·위치·테두리·radius·배경·그림자·라벨 크기 일치, Hover 링, Enter 확정 → `onSearch`, Escape 복원. + +새 컨트롤은 패키지 공식 컴포넌트로 자동 등록하지 않습니다. 여러 프로젝트에서 반복되면 SW 패키지 승격을 별도로 검토합니다. + +## 5. 하지 말 것 + +- `hm-sw-*` class를 소비 코드에 쓰거나 CSS로 덮어쓰기 +- `dist` 구현·`styles.css` 블록 복사로 같은 컴포넌트 재작성 +- `@hm-design/sw/dist/...`·`src/...` 내부 경로 Import +- 문서에 없는 Props 추측, 새 색·크기 값 도입 +- 같은 화면에 `SWHeader`와 조합 Header를 겹쳐 두 개의 Header 만들기 diff --git a/packages/sw/ai/DESIGN_RULES.md b/packages/sw/ai/DESIGN_RULES.md new file mode 100644 index 0000000..b3323bc --- /dev/null +++ b/packages/sw/ai/DESIGN_RULES.md @@ -0,0 +1,94 @@ +# SW 디자인 규칙 + +출처: `@hm-design/sw` `styles.css`(원본 `src/theme/sw.css`)의 토큰과 규칙, Figma 이지빔 SW `rj6wpsfk24lOWvWiVRAANP` node `26:8944`와 사용자 확정값. 이 문서에 없는 값은 확정값이 아닙니다. 새 컴포넌트에 임의 값을 만들지 말고 아래 토큰을 `var(--…)`로 읽으세요. + +- 토큰은 `.hm-sw-header`와 `.hm-sw-theme`(``)에만 정의됩니다. 새 컴포넌트는 그 안에 렌더링합니다. +- SW는 `@hm-design/ui` 토큰을 쓰지 않습니다. UI 패키지 토큰을 복제하거나 섞지 않습니다. +- Light/Dark 분기 없음. 전역 선택자(`html`, `body`, `*`) 없음. + +## 1. 크기·간격 + +| 항목 | 값 | 토큰 | +|---|---|---| +| Header 높이 / 면 높이 | 49px / 48px | `--hm-sw-header-height` / `--hm-sw-header-bar-height` | +| 면 사이 간격 | 2px | (Header bar `gap`) | +| 필드 높이 | 38px(면 안 위아래 5px) | `--hm-sw-header-field-height` | +| 필드 사이 간격 | 4px | `--hm-sw-header-gap` | +| 로고 슬롯 | 32 × 17 (홈 80 × 48 안 12, 16) | `--hm-sw-header-logo-width` / `-height` | +| 필드 폭 | 레이어 234, 색상 192, 선스타일 284, 문자·치수스타일 164 | — | +| 상세보기 / 창 영역 | 157 × 38 / 240 × 48(pill 85 × 42, 창 이동 88, 버튼 32 × 2) | — | +| 필드 내부 | padding 0 10px 0 11px, 텍스트 사이 12px | — | + +## 2. 색·표면 + +| 역할 | 값 | 토큰 | +|---|---|---| +| Header 배경 | `#060606` | `--hm-sw-header-background` | +| 기본 글자 / 제목 | `#F6F4F2` / `#F0F7F5` | `--hm-sw-header-text-color` / `--hm-sw-header-title-color` | +| Selected·On·Hover 글자 | `#FFC600` | `--hm-sw-header-selected-color` | +| 화살표 | `#47AF91` | `--hm-sw-header-arrow-color` | +| 파일명 면 | 세로 gradient, 테두리 `#0E4C3A` | `--hm-sw-header-document-background`, `--hm-sw-header-document-border-color` | +| 객체 수정 면 | gradient, 테두리 `#135643`, radius 6px | `--hm-sw-header-object-background`, `-object-border-color`, `-object-radius` | +| 속성 필드 면 | 검정 45–40% gradient, 테두리 `#08251C`, radius 3px, shadow `0 1px 4px rgba(9,39,30,.7)` | `--hm-sw-header-property-background`, `-property-border-color`, `-property-radius`, `-property-shadow` | +| 인쇄·K pill | `rgba(0,0,0,.8)`, 테두리 `#092920` | `--hm-sw-header-pill-background`, `-pill-border-color` | +| 문서 Dropdown | `#103127`, 테두리 `#041611` | `--hm-sw-header-document-menu-*` | +| 필드 Dropdown(레이어·색상·선·문자·치수) | `#27241D`, 테두리 `#000`, radius 3px, 행 Hover `#62533D` + 글자 `#FF5C00` | `--hm-sw-header-layer-menu-*`, `--hm-sw-header-layer-row-hover-*` | +| Input | 글자 `#E60403`, 편집 `#0F0D0A` | `--hm-sw-header-input-*` | +| Tooltip | `rgba(0,0,0,.8)` / `#FFF` | `--hm-sw-header-tooltip-*` | + +사용자 확정 면 3개(파일명·객체 수정·속성 필드)는 기본값 유지를 권장합니다. + +## 3. Typography + +| 항목 | 값 | +|---|---| +| 글꼴 | Noto Sans KR → Malgun Gothic → Apple SD Gothic Neo (Figma Dotum 대체, 의도된 결정). 폰트 파일은 앱이 로드 | +| 기본 / 라벨 | 14px / 12px (`--hm-sw-header-font-size` / `--hm-sw-header-label-size`) | +| Weight | 400, 500, 700만 사용(600 없음). 값·제목·토글 700 | +| 자간 | 값 0.04em, 라벨 0.02em, 파일명 0.06em | +| Text Stroke | Figma Stroke가 있는 텍스트만 검정 외곽선: 14·16px `--hm-sw-header-text-outline`(1.3px), 12px `--hm-sw-header-label-outline`(1px). 자기 색 Stroke 없음. More·Tooltip·`+ New`/`Open` 제외 | +| 말줄임 | 값은 한 줄 `ellipsis`, `title`로 전체 표시 | + +## 4. 상태 + +| 상태 | 규칙 | +|---|---| +| Hover(테두리 있는 버튼·필드·More·인쇄·K) | 1px 테두리가 노란 세로 gradient로 바뀜(`--hm-sw-header-hover-border-gradient`, 폭 `--hm-sw-header-hover-border-width`). 크기·배경·그림자 변화 없음, 자기 Dropdown이 열린 필드는 Hover 없음 | +| Hover(파일명, 속성Bar/속성창 토글) | 글자만 `#FFC600`. 링·배경 없음 | +| Hover(필드 미리보기) | 텍스트·선/폰트/치수 미리보기 `#FFC600` | +| Selected / On | 글자·단색 아이콘 `#FFC600`(`data-selected="true"`), 배경·테두리 변화 없음 | +| Expanded(Dropdown 열림) | 필드 테두리 `#081813`, 아래 모서리 직각, 필드+목록을 감싸는 1px 노란 링 | +| Focus | 2px `#F0F7F5` outline, offset −2px(`:focus-visible`) | +| Disabled | opacity 0.4, 커서 기본. 창 버튼은 `disabled` 영향 없음 | +| 목록 행 | Hover와 Selected가 같은 강조(`#62533D` + `#FF5C00`) | + +## 5. Overlay·Dropdown + +- 필드 Dropdown은 필드 바로 아래(`top: 100%`)에 겹쳐 열립니다. Portal·Dim 없음, `z-index` 30. 화면(또는 Header) 밖으로 나가면 좌우만 보정합니다. 부모에 `overflow: hidden`을 두지 않습니다. +- 목록 최대 높이 240px(8행), 넘치면 내부 스크롤. 색상 팔레트 118px. +- 속성창·K 가이드는 `position: fixed` Overlay(뷰포트 안 보정, Portal·Dim 없음). +- 한 번에 하나의 Dropdown(SWHeader). 단독 사용 시 각 컴포넌트가 바깥 클릭으로 스스로 닫힙니다. + +## 6. Motion + +| 대상 | 규칙 | +|---|---| +| 창 이동 Hover | 1.4s 반복(커서 상승 → 약 444ms 문구 → 오른쪽 위 이동 → 약 888ms부터 유지). Drag(`:active`) 중 정지. Reduced Motion: 원본 아이콘과 정적 Tooltip | +| K 가이드 | 원본 이미지 Pan/Zoom 반복(400ms 대기 후 1022·1022·511·511ms 전환). Reduced Motion 정적 | +| 레이어 토글 | 배경·아이콘 300ms ease-out | +| 기타 | Hover·Selected는 즉시 전환(Transition 없음) | + +## 7. 반응형 (`SWHeader` 전용) + +Container `hm-sw-header` 기준 Breakpoint: **< 1800** 선/문자/치수스타일 → More, **< 1180** 그리기모드 숨김, **< 1080** 상세보기 → More·창 이동 24px(창 영역 176), **< 900** 색상 → More, **< 640** 인쇄·K → More·창 이동 숨김(창 영역 64), **< 520** 레이어 상태 아이콘 숨김. More에서 고른 필드는 첫 칸(레이어 자리)에 표시되고 Dropdown이 바로 열립니다(UI 상태만, 데이터 Callback 없음). + +조합 Header(개별 컴포넌트)에는 이 규칙이 적용되지 않습니다. 필요한 컨트롤만 배치하고 폭 정책은 소비 앱이 정합니다. + +## 8. 새 컴포넌트 체크리스트 + +1. ``(또는 `SWHeader`의 `tools`) 안에서 렌더링한다. +2. 표면·크기·색은 위 토큰만 쓴다. 필드형이면 38px·속성 필드 면·12px 라벨 + 14px 700 값. +3. Hover/Focus/Disabled/Selected를 §4 규칙대로 구현한다(테두리형은 gradient 링, 텍스트형은 글자만 `#FFC600`). +4. 입력이 필요하면 `SWHeaderInput`을 재사용한다. +5. 값은 Props, 동작은 Callback. CAD 데이터를 내부에서 바꾸지 않는다. +6. `hm-sw-*` class를 새로 쓰거나 덮어쓰지 않는다(자기 접두사 사용, 예: `app-`). diff --git a/packages/sw/ai/examples/ExampleA-DefaultHeader.tsx b/packages/sw/ai/examples/ExampleA-DefaultHeader.tsx new file mode 100644 index 0000000..5ffdc9b --- /dev/null +++ b/packages/sw/ai/examples/ExampleA-DefaultHeader.tsx @@ -0,0 +1,40 @@ +// Example A — reuse (1st priority): the complete SW Header, unchanged. Existing projects keep this code. +import { useState } from "react" +import { SWHeader, type SWHeaderColorMode, type SWHeaderColorValue } from "@hm-design/sw" +import { colors, dimensionStyles, documents, layers, lineTypes, lineWeights, textStyles } from "./sample-data" + +export function ExampleADefaultHeader({ onEvent }: { onEvent?: (name: string) => void }) { + const [activeDocumentId, setActiveDocumentId] = useState(documents[0].id) + const [activeLayerId, setActiveLayerId] = useState("0") + const [color, setColor] = useState({ value: "ByLayer", swatch: "#ffffff" }) + const [colorMode, setColorMode] = useState("byLayer") + const log = (name: string) => () => onEvent?.(name) + return ( + item.id === activeDocumentId)?.name ?? ""} + logoAlt="예제 SW" + documents={documents} + activeDocumentId={activeDocumentId} + onDocumentSelect={document => { setActiveDocumentId(document.id); onEvent?.(`document:${document.id}`) }} + onDocumentNew={log("document:new")} + onDocumentOpen={log("document:open")} + layers={layers} + activeLayerId={activeLayerId} + onLayerSelect={layer => { setActiveLayerId(layer.id); onEvent?.(`layer:${layer.id}`) }} + color={color} + colors={colors} + colorMode={colorMode} + onColorSelect={option => { setColor({ value: option.label ?? option.color, swatch: option.color }); setColorMode(null); onEvent?.(`color:${option.id}`) }} + onColorModeChange={mode => { setColorMode(mode); onEvent?.(`colorMode:${mode}`) }} + lineTypes={lineTypes} + lineWeights={lineWeights} + textStyles={textStyles} + dimensionStyles={dimensionStyles} + onHomeClick={log("home")} + onPrint={log("print")} + onPopupGuide={log("popupGuide")} + onMinimize={log("minimize")} + onClose={log("close")} + /> + ) +} diff --git a/packages/sw/ai/examples/ExampleB-ViewerHeader.tsx b/packages/sw/ai/examples/ExampleB-ViewerHeader.tsx new file mode 100644 index 0000000..ce40206 --- /dev/null +++ b/packages/sw/ai/examples/ExampleB-ViewerHeader.tsx @@ -0,0 +1,50 @@ +// Example B — composition (2nd priority): a simplified viewer header +// Logo → File → Layer → Color → K +// Only public components; the layout is the consumer's (example-layout.css) and provides tokens. +import { useState } from "react" +import { + SWHeaderActions, SWHeaderColorMenu, SWHeaderDocumentTitle, SWHeaderHome, SWHeaderLayerMenu, SWTheme, + type SWHeaderColorMode, type SWHeaderColorValue, +} from "@hm-design/sw" +import { colors, documents, layers } from "./sample-data" +import "./example-layout.css" + +export function ExampleBViewerHeader({ onEvent }: { onEvent?: (name: string) => void }) { + const [activeDocumentId, setActiveDocumentId] = useState(documents[0].id) + const [activeLayerId, setActiveLayerId] = useState("0") + const [color, setColor] = useState({ value: "ByLayer", swatch: "#ffffff" }) + const [colorMode, setColorMode] = useState("byLayer") + return ( + + onEvent?.("home")} /> + item.id === activeDocumentId)?.name ?? ""} + documents={documents} + activeDocumentId={activeDocumentId} + onDocumentSelect={document => { setActiveDocumentId(document.id); onEvent?.(`document:${document.id}`) }} + onNew={() => onEvent?.("document:new")} + onOpen={() => onEvent?.("document:open")} + /> +
+ { setActiveLayerId(layer.id); onEvent?.(`layer:${layer.id}`) }} + onVisibilityChange={(layer, next) => onEvent?.(`layer-visible:${layer.id}:${next}`)} + /> + { setColor({ value: option.label ?? option.color, swatch: option.color }); setColorMode(null); onEvent?.(`color:${option.id}`) }} + onModeChange={mode => { setColorMode(mode); onEvent?.(`colorMode:${mode}`) }} + /> +
+
+ {/* K only: the existing actions pill with print removed. */} + onEvent?.("popupGuide")} /> +
+
+ ) +} diff --git a/packages/sw/ai/examples/ExampleC-FeatureHeader.tsx b/packages/sw/ai/examples/ExampleC-FeatureHeader.tsx new file mode 100644 index 0000000..40d07e4 --- /dev/null +++ b/packages/sw/ai/examples/ExampleC-FeatureHeader.tsx @@ -0,0 +1,46 @@ +// Example C — composition (2nd priority): a feature-focused header in a different order +// File → Line style → Text style → Dimension style → Print +import { useState } from "react" +import { + SWHeaderActions, SWHeaderDimensionStyleMenu, SWHeaderDocumentTitle, SWHeaderLineStyleMenu, SWHeaderTextStyleMenu, SWTheme, + type SWHeaderDimensionStyleValue, type SWHeaderLineStyleValue, type SWHeaderTextStyleValue, +} from "@hm-design/sw" +import { dimensionStyles, lineTypes, lineWeights, textStyles } from "./sample-data" +import "./example-layout.css" + +export function ExampleCFeatureHeader({ onEvent }: { onEvent?: (name: string) => void }) { + const [lineStyle, setLineStyle] = useState({ name: "ByLayer", weight: "ByLayer", scale: "1.00" }) + const [textStyle, setTextStyle] = useState({ font: "Arial", name: "Standard" }) + const [dimensionStyle, setDimensionStyle] = useState({ name: "Standard" }) + return ( + + {/* No logo before the file well, so the consumer layout gives it its own left edge. */} +
+ onEvent?.("document")} /> +
+
+ { setLineStyle(current => ({ ...current, name: type.name })); onEvent?.(`lineType:${type.id}`) }} + onLineWeightSelect={weight => { setLineStyle(current => ({ ...current, weight: weight.name })); onEvent?.(`lineWeight:${weight.id}`) }} + onScaleChange={scale => { setLineStyle(current => ({ ...current, scale })); onEvent?.(`lineScale:${scale}`) }} + /> + { setTextStyle({ font: style.font, name: style.name }); onEvent?.(`textStyle:${style.id}`) }} + /> + { setDimensionStyle({ name: style.name }); onEvent?.(`dimensionStyle:${style.id}`) }} + /> +
+
+ onEvent?.("print")} /> +
+
+ ) +} diff --git a/packages/sw/ai/examples/ExampleD-SearchExtension.tsx b/packages/sw/ai/examples/ExampleD-SearchExtension.tsx new file mode 100644 index 0000000..2cdebbe --- /dev/null +++ b/packages/sw/ai/examples/ExampleD-SearchExtension.tsx @@ -0,0 +1,30 @@ +// Example D — existing Layer / Color components next to a NEW consumer control (SWSearchControl). +import { useState } from "react" +import { SWHeaderColorMenu, SWHeaderLayerMenu, SWTheme, type SWHeaderColorValue } from "@hm-design/sw" +import { colors, layers } from "./sample-data" +import { SWSearchControl } from "./SWSearchControl" +import "./example-layout.css" + +export function ExampleDSearchExtension({ onEvent }: { onEvent?: (name: string) => void }) { + const [activeLayerId, setActiveLayerId] = useState("0") + const [color, setColor] = useState({ value: "ByLayer", swatch: "#ffffff" }) + const [query, setQuery] = useState("") + return ( + +
+ { setActiveLayerId(layer.id); onEvent?.(`layer:${layer.id}`) }} + /> + { setColor({ value: option.label ?? option.color, swatch: option.color }); onEvent?.(`color:${option.id}`) }} + /> + onEvent?.(`search:${text}`)} /> +
+
+ ) +} diff --git a/packages/sw/ai/examples/SWSearchControl.tsx b/packages/sw/ai/examples/SWSearchControl.tsx new file mode 100644 index 0000000..77f96ee --- /dev/null +++ b/packages/sw/ai/examples/SWSearchControl.tsx @@ -0,0 +1,41 @@ +// Example D extension — a NEW control written in the consuming project (3rd priority). +// Decision record: the package has no search component (MISSING). Its editable SWHeaderInput covers the +// text entry (Enter / blur commit, Escape cancel, IME), so it is reused; only the field surface and the +// search icon button are new. They read the public SW tokens (sw-search-control.css) — no copied +// package code, no hm-sw-* class, no new design values. Not registered as a package component. +import { SWHeaderInput } from "@hm-design/sw" +import "./sw-search-control.css" + +export interface SWSearchControlProps { + /** Committed query (host state). */ + value: string + /** A new query was committed with Enter or by leaving the input. */ + onValueChange?: (value: string) => void + /** Search with the current query (icon button or a committed query). */ + onSearch?: (query: string) => void + label?: string + disabled?: boolean +} + +export function SWSearchControl({ value, onValueChange, onSearch, label = "검색", disabled }: SWSearchControlProps) { + return ( +
+ + + { onValueChange?.(next); onSearch?.(next) }} + /> + + +
+ ) +} diff --git a/packages/sw/ai/examples/example-layout.css b/packages/sw/ai/examples/example-layout.css new file mode 100644 index 0000000..b55633b --- /dev/null +++ b/packages/sw/ai/examples/example-layout.css @@ -0,0 +1,36 @@ +/* Consumer layout for the composed examples (B, C, D). It belongs to the consuming project: it only + arranges public SW components and reads the public --hm-sw-header-* tokens provided by . + It never styles hm-sw-* classes and adds no new design values. */ +.app-sw-bar { + display: flex; + align-items: stretch; + gap: 2px; + box-sizing: border-box; + height: var(--hm-sw-header-height); + padding-bottom: 1px; /* 48px surfaces in the 49px header, like SWHeader */ + background: var(--hm-sw-header-background); +} +/* Object (editing) surface, the same tokens as the SWHeader object area. */ +.app-sw-surface { + display: flex; + align-items: center; + gap: var(--hm-sw-header-gap); + flex: 1 1 0; + min-width: 0; + padding: 4px; + border: 1px solid var(--hm-sw-header-object-border-color); + border-radius: var(--hm-sw-header-object-radius); + background: var(--hm-sw-header-object-background); +} +/* Window-area surface for print / K / window buttons. */ +.app-sw-window { + display: flex; + flex: 0 0 auto; + background: var(--hm-sw-header-document-background); + box-shadow: inset 0 0 0 1px var(--hm-sw-header-document-border-color); /* 1px edge without moving the parts */ +} +/* File well placed first (no home overlap): its own left edge. */ +.app-sw-file-edge { + display: flex; + border-left: 1px solid var(--hm-sw-header-document-border-color); +} diff --git a/packages/sw/ai/examples/sample-data.ts b/packages/sw/ai/examples/sample-data.ts new file mode 100644 index 0000000..c0261fe --- /dev/null +++ b/packages/sw/ai/examples/sample-data.ts @@ -0,0 +1,52 @@ +// Sample host data for the examples. Every type comes from the public package API. +import { + swHeaderLinePatterns, + type SWHeaderColorOption, type SWHeaderDimensionStyleOption, type SWHeaderDocument, type SWHeaderLayer, + type SWHeaderLineType, type SWHeaderLineWeight, type SWHeaderTextStyleOption, +} from "@hm-design/sw" + +export const documents: SWHeaderDocument[] = [ + { id: "doc-1", name: "C0020101-006-평면및종단면도(06)" }, + { id: "doc-2", name: "C0020101-007-횡단면도(07)" }, +] + +export const layers: SWHeaderLayer[] = [ + { id: "0", name: "0", color: "#ffffff" }, + { id: "center", name: "CENTER", color: "#ff0000" }, + { id: "hidden", name: "HIDDEN", color: "#ffe500", visible: false }, + { id: "dim", name: "DIM", color: "#00ff00", locked: true }, +] + +export const colors: SWHeaderColorOption[] = [ + { id: "white", color: "#ffffff", label: "흰색" }, + { id: "red", color: "#ff0000", label: "빨강" }, + { id: "green", color: "#00ff00", label: "초록" }, + { id: "yellow", color: "#ffff00", label: "노랑" }, + { id: "blue", color: "#0000ff", label: "파랑" }, + { id: "magenta", color: "#ff00ff", label: "자홍" }, + { id: "cyan", color: "#00ffff", label: "청록" }, +] + +export const lineTypes: SWHeaderLineType[] = [ + { id: "bylayer", name: "ByLayer" }, + { id: "continuous", name: "Continuous" }, + { id: "center", name: "CENTER", pattern: swHeaderLinePatterns.center }, + { id: "hidden", name: "HIDDEN", pattern: swHeaderLinePatterns.hidden }, +] + +export const lineWeights: SWHeaderLineWeight[] = [ + { id: "bylayer", name: "ByLayer" }, + { id: "byblock", name: "ByBlock" }, + { id: "default", name: "ByDefault", value: "0.25" }, + { id: "user", name: "User", value: "0.50", editable: true }, +] + +export const textStyles: SWHeaderTextStyleOption[] = [ + { id: "standard", name: "Standard", font: "Arial" }, + { id: "dotum", name: "Dotum", font: "돋움" }, +] + +export const dimensionStyles: SWHeaderDimensionStyleOption[] = [ + { id: "standard", name: "Standard" }, + { id: "iso", name: "ISO-25" }, +] diff --git a/packages/sw/ai/examples/sw-search-control.css b/packages/sw/ai/examples/sw-search-control.css new file mode 100644 index 0000000..fc1e4a3 --- /dev/null +++ b/packages/sw/ai/examples/sw-search-control.css @@ -0,0 +1,48 @@ +/* Consumer extension styles. Every value is a public SW token (see ../DESIGN_RULES.md); the + 38px field height, 12px label / 14px bold value and 1px gradient hover ring follow the SW field rules. */ +.app-sw-search { + position: relative; + display: flex; + align-items: center; + gap: 8px; + flex: 0 0 auto; + height: var(--hm-sw-header-field-height); + padding: 0 6px 0 11px; + border: 1px solid var(--hm-sw-header-property-border-color); + border-radius: var(--hm-sw-header-property-radius); + background: var(--hm-sw-header-property-background); + box-shadow: var(--hm-sw-header-property-shadow); +} +/* Hover: the bordered-control rule — the 1px border becomes the yellow gradient; nothing moves. */ +.app-sw-search::after { + content: ""; + position: absolute; + inset: calc(-1 * var(--hm-sw-header-hover-border-width)); + padding: var(--hm-sw-header-hover-border-width); + border-radius: inherit; + background: var(--hm-sw-header-hover-border-gradient); + /* Ring only: the content box is cut out (prefixed first, the standard declaration last wins). */ + -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); + -webkit-mask-composite: xor; + mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); + opacity: 0; + pointer-events: none; +} +.app-sw-search:hover:not([data-disabled])::after { opacity: 1; } +.app-sw-search__text { display: flex; flex-direction: column; min-width: 0; } +.app-sw-search__label { + height: 14px; + font-size: var(--hm-sw-header-label-size); + line-height: 14px; + letter-spacing: 0.02em; + text-shadow: var(--hm-sw-header-label-outline); +} +.app-sw-search__button { + display: grid; + place-items: center; + width: 24px; + height: 24px; + border-radius: var(--hm-sw-header-property-radius); +} +/* Text-only hover / selected color, like the SW toggles. */ +.app-sw-search__button:hover:not(:disabled) { color: var(--hm-sw-header-selected-color); } diff --git a/packages/sw/package.json b/packages/sw/package.json index f27169a..84801af 100644 --- a/packages/sw/package.json +++ b/packages/sw/package.json @@ -15,7 +15,8 @@ "./styles.css": "./dist/styles.css" }, "files": [ - "dist" + "dist", + "ai" ], "scripts": { "typecheck": "tsc -p tsconfig.json", diff --git a/packages/sw/tests/ai-docs.check.mjs b/packages/sw/tests/ai-docs.check.mjs new file mode 100644 index 0000000..e91e172 --- /dev/null +++ b/packages/sw/tests/ai-docs.check.mjs @@ -0,0 +1,53 @@ +// Checks that the shipped AI guide matches the built public API (2026-10-19). +// Usage: node packages/sw/tests/ai-docs.check.mjs (build first: npm run build -w @hm-design/sw) +// 1. Every SW identifier named in ai/*.md is a real export, unless the doc lists it as not public. +// 2. Every import from "@hm-design/sw" in ai/examples is a real export; no deep package import. +// 3. Every relative link in ai/*.md and README.md resolves inside the package (tarball-safe). +import { readdir, readFile } from "node:fs/promises" +import { existsSync } from "node:fs" +import path from "node:path" +import { fileURLToPath } from "node:url" + +const root = fileURLToPath(new URL("../", import.meta.url)) +const declarations = await readFile(path.join(root, "dist/index.d.ts"), "utf8") +const nested = [...declarations.matchAll(/from\s+["'](\.[^"']+)["']/g)].map(match => match[1]) +let exported = declarations +for (const file of nested) exported += await readFile(path.join(root, "dist", file.replace(/\.js$/, ".d.ts")), "utf8") +const names = new Set() +for (const block of exported.matchAll(/export\s*(?:type\s*)?\{([^}]*)\}/g)) for (const part of block[1].split(",")) { const name = part.trim().replace(/^type\s+/, "").split(/\s+as\s+/).pop(); if (name) names.add(name) } +for (const match of exported.matchAll(/export\s+(?:declare\s+)?(?:const|function|interface|type)\s+(\w+)/g)) names.add(match[1]) +// Only names re-exported by the entry are public: collect the entry's re-export lists. +const publicNames = new Set() +for (const block of declarations.matchAll(/export\s*(?:type\s*)?\{([^}]*)\}/g)) for (const part of block[1].split(",")) { const name = part.trim().replace(/^type\s+/, "").split(/\s+as\s+/).pop(); if (name) publicNames.add(name) } +for (const match of declarations.matchAll(/export\s+\*\s+from\s+["']([^"']+)["']/g)) { + const text = await readFile(path.join(root, "dist", match[1].replace(/\.js$/, ".d.ts")), "utf8") + for (const block of text.matchAll(/export\s*(?:type\s*)?\{([^}]*)\}/g)) for (const part of block[1].split(",")) { const name = part.trim().replace(/^type\s+/, "").split(/\s+as\s+/).pop(); if (name) publicNames.add(name) } +} +void names + +const results = [] +const check = (name, ok, data) => { results.push(ok); console.log(ok ? "PASS" : "FAIL", name, data === undefined ? "" : JSON.stringify(data)) } +const docs = (await readdir(path.join(root, "ai"))).filter(name => name.endsWith(".md")) +for (const doc of docs) { + const text = await readFile(path.join(root, "ai", doc), "utf8") + const notPublic = new Set([...(text.split(/^## .*공개하지 않은 것.*$/m)[1]?.split(/^## /m)[0] ?? "").matchAll(/`(\w+)`/g)].map(match => match[1])) + const mentioned = [...new Set([...text.matchAll(/`((?:SW|parseSW|swHeader|useSW)\w+)/g)].map(match => match[1]))] + const unknown = mentioned.filter(name => !publicNames.has(name) && !notPublic.has(name) && !/^SWSearchControl/.test(name)) + check(`${doc}: named SW identifiers are public exports`, unknown.length === 0, { mentioned: mentioned.length, unknown }) + const leaked = [...notPublic].filter(name => publicNames.has(name)) + check(`${doc}: "not public" list contains no export`, leaked.length === 0, leaked) +} +for (const file of (await readdir(path.join(root, "ai/examples"))).filter(name => /\.tsx?$/.test(name))) { + const text = await readFile(path.join(root, "ai/examples", file), "utf8") + const imports = [...text.matchAll(/import\s*\{([^}]*)\}\s*from\s*"@hm-design\/sw"/g)].flatMap(match => match[1].split(",").map(part => part.trim().replace(/^type\s+/, "")).filter(Boolean)) + const deep = /from\s*"@hm-design\/sw\/(?!styles\.css)/.test(text) + check(`examples/${file}: imports only public exports`, !deep && imports.every(name => publicNames.has(name)), { imports, missing: imports.filter(name => !publicNames.has(name)), deep }) +} +for (const doc of [...docs.map(name => path.join("ai", name)), "README.md"]) { + const text = await readFile(path.join(root, doc), "utf8") + const links = [...text.matchAll(/\]\((\.\/[^)#\s]+)/g)].map(match => match[1]) + const broken = links.filter(link => !existsSync(path.resolve(root, path.dirname(doc), link))) + check(`${doc}: package-relative links resolve`, broken.length === 0, { links: links.length, broken }) +} +console.log(`${results.filter(Boolean).length}/${results.length} PASS`) +process.exitCode = results.every(Boolean) ? 0 : 1 diff --git a/packages/sw/tests/ai-template-consumer.browser.mjs b/packages/sw/tests/ai-template-consumer.browser.mjs new file mode 100644 index 0000000..b4b1abf --- /dev/null +++ b/packages/sw/tests/ai-template-consumer.browser.mjs @@ -0,0 +1,180 @@ +// Browser check of the independent consumer built by ai-template-consumer.mjs. +// Usage: node packages/sw/tests/ai-template-consumer.browser.mjs +// Serves /dist and checks examples A–D (rendering, assets, dropdowns, callbacks, focus, styles). +import { createRequire } from "node:module" +import { createServer } from "node:http" +import { mkdir, readFile, writeFile } from "node:fs/promises" +import path from "node:path" + +const dist = path.resolve(process.argv[2], "dist") +const out = path.resolve(process.argv[3]) +const { chromium } = createRequire(import.meta.url)(process.env.SW_PLAYWRIGHT_PATH ?? "C:/Users/user/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright") +await mkdir(out, { recursive: true }) +const types = { ".html": "text/html", ".js": "text/javascript", ".css": "text/css" } +const server = createServer(async (request, response) => { + const pathname = decodeURIComponent(new URL(request.url, "http://x").pathname) + const file = path.join(dist, pathname === "/" ? "/index.html" : pathname) + let body + try { body = await readFile(file) } catch { response.writeHead(404); response.end(); return } + response.writeHead(200, { "content-type": types[path.extname(file)] ?? "application/octet-stream" }) + response.end(body) +}).listen(0, "127.0.0.1") +await new Promise(resolve => server.once("listening", resolve)) +const base = `http://127.0.0.1:${server.address().port}/` + +const browser = await chromium.launch({ executablePath: process.env.SW_CHROME_PATH ?? "C:/Program Files/Google/Chrome/Application/chrome.exe" }) +const page = await browser.newPage({ viewport: { width: 1920, height: 1080 } }) +const report = { checks: [], errors: [], warnings: [] } +page.on("pageerror", error => report.errors.push(error.message)) +page.on("console", message => { if (message.type() === "error") report.errors.push(message.text()); if (message.type() === "warning") report.warnings.push(message.text()) }) +const check = (name, ok, data) => { report.checks.push({ name, status: ok ? "PASS" : "FAIL", data }); console.log(ok ? "PASS" : "FAIL", name, JSON.stringify(data ?? "")) } +const events = async () => (await page.locator("#events").textContent()).split("\n").filter(Boolean) +const lastEvent = async () => (await events()).at(-1) +const section = id => page.locator(`[data-example="${id}"]`) +const rect = (locator) => locator.evaluate(node => { const r = node.getBoundingClientRect(); return { x: Math.round(r.left), y: Math.round(r.top), w: Math.round(r.width), h: Math.round(r.height) } }) + +await page.goto(base) +await page.locator('[data-example="d"] .app-sw-search').waitFor() +await page.evaluate(() => document.fonts.ready) + +// 1. Assets and CSS +const assets = await page.evaluate(() => [...document.images].map(image => ({ src: image.currentSrc.slice(0, 30), ok: image.complete && image.naturalWidth > 0 }))) +check("1 all SVG/PNG assets decode (data URI, no external path)", assets.length > 0 && assets.every(item => item.ok && item.src.startsWith("data:")), { count: assets.length, broken: assets.filter(item => !item.ok) }) +const tokens = await page.evaluate(() => { const s = getComputedStyle(document.querySelector('[data-example="b"] .hm-sw-theme')); return { height: s.getPropertyValue("--hm-sw-header-height").trim(), font: s.fontFamily } }) +check("1 styles.css loaded; SWTheme provides tokens", tokens.height === "49px" && tokens.font.includes("Noto Sans KR"), tokens) + +// 2. Example A: default header unchanged (Figma 1920 coordinates) +const a = section("a") +const geometry = { + header: await rect(a.locator(".hm-sw-header")), home: await rect(a.locator(".hm-sw-header__home")), + document: await rect(a.locator(".hm-sw-header__document")), object: await rect(a.locator(".hm-sw-header__object-area")), + window: await rect(a.locator(".hm-sw-header__window")), +} +check("2 A default header 1920 geometry = Figma (49 / 0·80 / 65·310 / 377·1301 / 1680·240)", + geometry.header.h === 49 && geometry.home.x === 0 && geometry.home.w === 80 && geometry.document.x === 65 && geometry.document.w === 310 + && geometry.object.x === 377 && geometry.object.w === 1301 && geometry.window.x === 1680 && geometry.window.w === 240, geometry) +await a.locator(".hm-sw-header").screenshot({ path: path.join(out, "A-default-1920.png") }) +await a.locator(".hm-sw-header__field--layer").click() +await a.getByRole("button", { name: "CENTER" }).first().click() +check("2 A layer dropdown select callback", (await lastEvent()) === "layer:center", await lastEvent()) +await a.getByRole("button", { name: "종료" }).click() +check("2 A close callback", (await lastEvent()) === "close", await lastEvent()) + +// 3. Example B: Logo → File → Layer → Color → K +const b = section("b") +const order = await b.locator(".hm-sw-theme").evaluate(bar => [...bar.querySelectorAll(".hm-sw-header__home, .hm-sw-header__document, .hm-sw-header__field, .hm-sw-header__action")].map(node => node.getAttribute("aria-label") ?? node.className.split(" ")[0])) +check("3 B order Logo → File → Layer → Color → K (DOM)", JSON.stringify(order) === JSON.stringify(["뷰어 홈", "hm-sw-header__document", "레이어", "색상", "팝업 가이드"]), order) +const bGeo = { bar: await rect(b.locator(".hm-sw-theme")), home: await rect(b.locator(".hm-sw-header__home")), document: await rect(b.locator(".hm-sw-header__document")), layer: await rect(b.locator(".hm-sw-header__field--layer")), color: await rect(b.locator(".hm-sw-header__field--color")) } +check("3 B sizes keep SW rules (bar 49, home 80 overlapping file 15px, fields 234/192 x 38)", bGeo.bar.h === 49 && bGeo.home.w === 80 && bGeo.document.x - bGeo.home.x === 65 && bGeo.layer.w === 234 && bGeo.layer.h === 38 && bGeo.color.w === 192, bGeo) +await b.locator(".hm-sw-header__document-button").click() +await b.getByRole("menuitem", { name: /New/ }).or(b.getByRole("button", { name: /New/ })).first().click() +check("3 B document dropdown New callback", (await lastEvent()) === "document:new", await lastEvent()) +const layerField = b.locator(".hm-sw-header__field--layer") +await layerField.click() +const layerPanel = b.locator(".hm-sw-header__layer [id], .hm-sw-header__layer-menu").first() +check("3 B layer dropdown opens under the field", await layerField.getAttribute("aria-expanded") === "true", await layerField.getAttribute("aria-expanded")) +await page.screenshot({ path: path.join(out, "B-layer-open.png"), clip: { x: 0, y: (await rect(b)).y, width: 1000, height: 360 } }) +await page.keyboard.press("Escape") +check("3 B Escape closes and returns focus to the field", await layerField.getAttribute("aria-expanded") === "false" && await layerField.evaluate(node => node === document.activeElement), null) +void layerPanel +await b.locator(".hm-sw-header__field--color").click() +await b.getByRole("button", { name: "빨강" }).click() +check("3 B color chip callback (dropdown stays open)", (await lastEvent()) === "color:red" && await b.locator(".hm-sw-header__field--color").getAttribute("aria-expanded") === "true", await lastEvent()) +await page.mouse.click(1800, 900) +const k = b.getByRole("button", { name: "팝업 가이드" }) +await k.hover() +await page.waitForTimeout(500) +const guide = await page.locator(".hm-sw-k-guide__panel").first().isVisible() +check("3 B K guide preview on hover (animation frame advances)", guide && Number(await page.locator(".hm-sw-k-guide__panel").first().getAttribute("data-frame")) >= 1, { guide }) +await page.waitForTimeout(1000) +await page.screenshot({ path: path.join(out, "B-k-guide.png"), clip: { x: 1300, y: (await rect(b)).y, width: 620, height: 340 } }) +await k.click() +check("3 B K click callback", (await lastEvent()) === "popupGuide", await lastEvent()) +await page.mouse.move(1, 1) +await b.locator(".hm-sw-theme").screenshot({ path: path.join(out, "B-viewer-1920.png") }) + +// 4. Example C: File → Line → Text → Dimension → Print +const c = section("c") +const cOrder = await c.locator(".hm-sw-theme").evaluate(bar => [...bar.querySelectorAll(".hm-sw-header__document, .hm-sw-header__field, .hm-sw-header__action")].map(node => node.getAttribute("aria-label") ?? "file")) +check("4 C order File → 선 → 문자 → 치수 → 인쇄", JSON.stringify(cOrder) === JSON.stringify(["file", "선스타일", "문자스타일", "치수스타일", "인쇄"]), cOrder) +const fileEdge = await c.locator(".app-sw-file-edge").evaluate(node => getComputedStyle(node).borderLeftWidth) +check("4 C first file well has a left edge (consumer wrapper)", fileEdge === "1px", fileEdge) +await c.locator(".hm-sw-header__field--line-style").click() +await c.getByRole("button", { name: "CENTER" }).first().click() +check("4 C line type callback + field value", (await lastEvent()) === "lineType:center" && (await c.locator(".hm-sw-header__field--line-style").textContent()).includes("CENTER"), await lastEvent()) +await page.keyboard.press("Escape") +await c.locator(".hm-sw-header__field--text-style").click() +await c.getByRole("button", { name: "Dotum" }).click() +check("4 C text style callback + field value", (await lastEvent()) === "textStyle:dotum" && (await c.locator(".hm-sw-header__field--text-style").textContent()).includes("Dotum"), await lastEvent()) +await c.locator(".hm-sw-header__field--dimension-style").click() +await c.getByRole("button", { name: "ISO-25" }).click() +check("4 C dimension style callback", (await lastEvent()) === "dimensionStyle:iso", await lastEvent()) +await c.getByRole("button", { name: "인쇄" }).click() +check("4 C print callback", (await lastEvent()) === "print", await lastEvent()) +await page.mouse.move(1, 1) +await c.locator(".hm-sw-theme").screenshot({ path: path.join(out, "C-feature-1920.png") }) + +// 5. Example D: existing layer / color + new SWSearchControl +const d = section("d") +const style = await d.locator(".hm-sw-theme").evaluate(bar => { + const pick = node => { const s = getComputedStyle(node), r = node.getBoundingClientRect(); return { h: Math.round(r.height), top: Math.round(r.top), border: `${s.borderTopWidth} ${s.borderTopColor}`, radius: s.borderTopLeftRadius, bg: s.backgroundImage.slice(0, 40), shadow: s.boxShadow } } + return { layer: pick(bar.querySelector(".hm-sw-header__field--layer")), search: pick(bar.querySelector(".app-sw-search")), + label: getComputedStyle(bar.querySelector(".app-sw-search__label")).fontSize, fieldLabel: getComputedStyle(bar.querySelector(".hm-sw-header__field-label")).fontSize } +}) +const same = ["h", "top", "border", "radius", "bg", "shadow"].every(key => style.layer[key] === style.search[key]) +check("5 D new search field matches the SW field surface (height/top/border/radius/background/shadow/label)", same && style.label === style.fieldLabel, style) +// Pixels of an element screenshot: the inside must not change on hover, only the 1px edge turns yellow. +const samplePixels = async (locator) => { + const buffer = await locator.screenshot() + return page.evaluate(async b64 => { + const image = new Image(); image.src = `data:image/png;base64,${b64}`; await image.decode() + const canvas = document.createElement("canvas"); canvas.width = image.width; canvas.height = image.height + const context = canvas.getContext("2d"); context.drawImage(image, 0, 0) + const at = (x, y) => [...context.getImageData(x, y, 1, 1).data].slice(0, 3) + return { inside: at(Math.round(image.width * 0.85), Math.round(image.height / 2)), edge: at(Math.round(image.width / 2), 0) } + }, buffer.toString("base64")) +} +const searchField = d.locator(".app-sw-search") +await page.mouse.move(1, 1) +const before = await samplePixels(searchField) +await searchField.hover() +const ring = await searchField.evaluate(node => getComputedStyle(node, "::after").opacity) +const after = await samplePixels(searchField) +const near = (p, q, tolerance = 12) => p.every((value, index) => Math.abs(value - q[index]) <= tolerance) +const yellow = rgb => rgb[0] > 150 && rgb[1] > 100 && rgb[2] < 90 +const layerRing = async () => { await d.locator(".hm-sw-header__field--layer").hover(); return d.locator(".hm-sw-header__field--layer").evaluate(node => getComputedStyle(node, "::after").opacity) } +check("5 D hover ring like existing fields (edge turns yellow, inside unchanged)", ring === "1" && near(before.inside, after.inside) && yellow(after.edge) && !yellow(before.edge) && (await layerRing()) === "1", { ring, before, after }) +await d.locator(".app-sw-search").hover() +await page.screenshot({ path: path.join(out, "D-search-hover.png"), clip: { x: 0, y: (await rect(d)).y, width: 760, height: 60 } }) +const input = d.getByRole("textbox", { name: "검색어" }) +await input.click() +await input.fill("WALL-01") +await page.keyboard.press("Enter") +check("5 D Enter commits through SWHeaderInput → search callback", (await lastEvent()) === "search:WALL-01", await lastEvent()) +await d.getByRole("button", { name: "검색", exact: true }).click() +check("5 D search button callback uses committed value", (await lastEvent()) === "search:WALL-01", await lastEvent()) +await input.click() +await input.fill("TMP") +await page.keyboard.press("Escape") +check("5 D Escape restores the committed value", await input.inputValue() === "WALL-01", await input.inputValue()) +await page.keyboard.press("Tab") +await d.locator(".hm-sw-header__field--color").click() +await d.getByRole("button", { name: "파랑" }).click() +check("5 D existing color dropdown in the same bar", (await lastEvent()) === "color:blue", await lastEvent()) +await page.mouse.click(1800, 900) +await page.mouse.move(1, 1) +await d.locator(".hm-sw-theme").screenshot({ path: path.join(out, "D-search-1920.png") }) + +// 6. Keyboard order follows DOM order in B +await b.locator(".hm-sw-header__home").focus() +const tabs = [] +for (let index = 0; index < 4; index++) { await page.keyboard.press("Tab"); tabs.push(await page.evaluate(() => document.activeElement?.getAttribute("aria-label") ?? document.activeElement?.textContent?.trim().slice(0, 12))) } +check("6 B Tab order = display order", tabs.includes("레이어") && tabs.indexOf("레이어") < tabs.indexOf("색상") && tabs.indexOf("색상") < tabs.indexOf("팝업 가이드"), tabs) + +check("7 no page/console errors", report.errors.length === 0, report.errors) +await writeFile(path.join(out, "report.json"), JSON.stringify(report, null, 2)) +await browser.close() +server.close() +const failed = report.checks.filter(item => item.status === "FAIL").length +console.log(`${report.checks.length - failed}/${report.checks.length} PASS`) +process.exitCode = failed ? 1 : 0 diff --git a/packages/sw/tests/ai-template-consumer.mjs b/packages/sw/tests/ai-template-consumer.mjs new file mode 100644 index 0000000..38a1652 --- /dev/null +++ b/packages/sw/tests/ai-template-consumer.mjs @@ -0,0 +1,70 @@ +// Independent consumer check for @hm-design/sw (AI template, 2026-10-19). +// Usage: node packages/sw/tests/ai-template-consumer.mjs +// Packs the built package (npm pack), creates a React 19 + TypeScript + Vite project in , installs the +// tarball, copies the shipped ai/examples from node_modules (not from the repo) and runs tsc + vite build. +// Build the package first: npm run build -w @hm-design/sw +import { execFileSync } from "node:child_process" +import { cp, mkdir, readdir, writeFile } from "node:fs/promises" +import path from "node:path" +import { fileURLToPath } from "node:url" + +const packageRoot = fileURLToPath(new URL("../", import.meta.url)) +const out = path.resolve(process.argv[2] ?? "") +if (!process.argv[2] || out.startsWith(path.resolve(packageRoot, "../.."))) throw new Error("Pass an empty directory outside the repository") +await mkdir(out, { recursive: true }) +if ((await readdir(out)).length) throw new Error(`${out} is not empty`) + +const npm = (args, cwd) => execFileSync(process.platform === "win32" ? "npm.cmd" : "npm", args, { cwd, stdio: "inherit", shell: process.platform === "win32" }) +npm(["pack", "--ignore-scripts", "--pack-destination", out], packageRoot) +const tarball = (await readdir(out)).find(name => name.endsWith(".tgz")) + +const files = { + "package.json": JSON.stringify({ + name: "sw-ai-template-consumer", private: true, type: "module", + scripts: { typecheck: "tsc -p tsconfig.json", build: "vite build" }, + }, null, 2), + "tsconfig.json": JSON.stringify({ + compilerOptions: { + target: "ES2022", lib: ["ES2022", "DOM", "DOM.Iterable"], module: "ESNext", moduleResolution: "Bundler", + jsx: "react-jsx", strict: true, noEmit: true, skipLibCheck: false, isolatedModules: true, + noUnusedLocals: true, noUnusedParameters: true, types: ["vite/client"], + }, + include: ["src"], + }, null, 2), + "vite.config.ts": `import { defineConfig } from "vite"\nimport react from "@vitejs/plugin-react"\nexport default defineConfig({ plugins: [react()] })\n`, + "index.html": `SW consumer
\n`, + "src/main.tsx": `import { StrictMode, useState } from "react" +import { createRoot } from "react-dom/client" +import "@hm-design/sw/styles.css" +import { ExampleADefaultHeader } from "./examples/ExampleA-DefaultHeader" +import { ExampleBViewerHeader } from "./examples/ExampleB-ViewerHeader" +import { ExampleCFeatureHeader } from "./examples/ExampleC-FeatureHeader" +import { ExampleDSearchExtension } from "./examples/ExampleD-SearchExtension" + +const examples = { a: ExampleADefaultHeader, b: ExampleBViewerHeader, c: ExampleCFeatureHeader, d: ExampleDSearchExtension } +function App() { + const [events, setEvents] = useState([]) + const onEvent = (name: string) => setEvents(list => [...list, name]) + return ( + <> + {Object.entries(examples).map(([id, Example]) => ( +
+ ))} +
{events.join("\\n")}
+ + ) +} +createRoot(document.getElementById("root")!).render() +`, +} +for (const [name, text] of Object.entries(files)) { + await mkdir(path.dirname(path.join(out, name)), { recursive: true }) + await writeFile(path.join(out, name), text) +} +npm(["install", "--no-audit", "--no-fund", `./${tarball}`, "react@19.3.0", "react-dom@19.3.0"], out) +npm(["install", "--no-audit", "--no-fund", "-D", "typescript@7.0.2", "vite@8.3.0", "@vitejs/plugin-react@6.1.1", "@types/react@19.3.0", "@types/react-dom@19.3.0"], out) +// The examples are taken from the installed package: what an AI tool in another project would read. +await cp(path.join(out, "node_modules/@hm-design/sw/ai/examples"), path.join(out, "src/examples"), { recursive: true }) +npm(["run", "typecheck"], out) +npm(["run", "build"], out) +console.log(`Consumer ready: ${out} (dist/ built). Next: node packages/sw/tests/ai-template-consumer.browser.mjs ${out} `)