- 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 <noreply@anthropic.com>
117 lines
11 KiB
Markdown
117 lines
11 KiB
Markdown
# 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와 속성창 단독 사용까지 확장.
|