docs(ai): split SW usage into general / viewer mode in packaged AI guides
- Usage types are now Web / SW (general mode, viewer mode) / OrgChart / mixed. Shared AI_GUIDE step 1 asks for the SW mode only when the request or the project setting (HMDesign 사용 유형: SW 일반 | SW 뷰어) leaves it open; examples B0/B1/B2 cover "HMDesign SW로 화면을 만들어 주세요", general and viewer. - Missing-component handling in three steps (reuse in the chosen type/mode -> build with that mode's tokens -> HMDesign-consistent style, reported as "AI 구성 값 — 디자인 확인 필요"), plus SW general/viewer separation rules. - sw/ai: AI_USAGE §0 mode selection, catalog §8 lists all 33 SWViewer* exports, DESIGN_RULES §11 viewer tokens, PATTERNS 7 viewer composition; examples B/F marked as general mode. ui/ai and org-chart/ai aligned with the new types. - AGENTS_SNIPPET, AGENTS.md and MAINTAINING updated; copies synced. - scripts/ai-docs.mjs: shared-copy check ignores CRLF/LF (core.autocrlf=true checks out packages/sw as LF and the rest as CRLF). - Verification record updated (code samples typechecked, built and rendered).
This commit is contained in:
1 parent
be7a04a847
commit
7621934f69
25 files changed
+779
-235
No files matched your search
@@ -7,6 +7,7 @@
|
||||
## 패키지 소비용 AI 지침 — 2026-10-19
|
||||
|
||||
- 이 파일은 HMDesign 저장소를 개발하는 AI용이다. 패키지를 설치한 **다른 프로젝트**의 AI가 읽는 지침은 각 패키지의 `ai/`(`packages/ui/ai`, `packages/sw/ai`, `packages/org-chart/ai`, `packages/org-chart-react/ai`)에 있고 공통 진입점 원본은 [docs/ai/AI_GUIDE.md](docs/ai/AI_GUIDE.md)다.
|
||||
- 사용 유형은 Web / SW(**SW 일반 모드**·**SW 뷰어 모드**) / OrgChart / 혼합이다. SW 작업은 모드를 먼저 정하고(불명확하면 질문, 요청·설정으로 명확하면 묻지 않음) 선택 모드의 컴포넌트·토큰만 쓴다 — 일반 `SWHeader`·`SWPopup`, 뷰어 `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`. 기준은 [packages/sw/ai/AI_USAGE.md](packages/sw/ai/AI_USAGE.md) §0과 공통 가이드 1·4·5단계이며 이 파일에 본문을 복사하지 않는다.
|
||||
- 공개 Export·Props·토큰을 바꾸면 같은 변경에서 해당 `ai/` 문서를 갱신하고 `npm run check:ai-docs`를 실행한다. 공통 가이드는 원본만 고친 뒤 `npm run sync:ai-docs`로 사본을 갱신한다. 절차는 [docs/ai/MAINTAINING.md](docs/ai/MAINTAINING.md).
|
||||
|
||||
## Typography — 공통 정책
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
## HMDesign 디자인 시스템
|
||||
|
||||
<!-- HMDesign 패키지의 ai/AGENTS_SNIPPET.md에서 복사. 아래 "사용 유형"을 프로젝트에 맞게 고치거나, 정하지 않았으면 그 줄을 지운다. -->
|
||||
<!-- HMDesign 패키지의 ai/AGENTS_SNIPPET.md에서 복사. 아래 "사용 유형"을 하나로 고치거나(SW는 모드까지: SW 일반 / SW 뷰어), 정하지 않았으면 그 줄을 지운다. -->
|
||||
|
||||
HMDesign 사용 유형: Web | SW | OrgChart | 혼합(영역별로 적기)
|
||||
HMDesign 사용 유형: Web | SW 일반 | SW 뷰어 | OrgChart | 혼합(영역별로 적기, SW 영역은 모드까지)
|
||||
|
||||
화면·컴포넌트를 구현하거나 수정하기 전에 다음을 지킨다.
|
||||
|
||||
1. 설치된 HMDesign 패키지의 공통 가이드를 먼저 읽는다: `node_modules/@hm-design/<설치된 패키지>/ai/AI_GUIDE.md` (`ui`, `sw`, `org-chart`, `org-chart-react` 중 아무 사본이나 내용이 같다).
|
||||
2. 위 "사용 유형"이 없고 요청으로도 정할 수 없으면 코드 작성 전에 "어떤 HMDesign 디자인 시스템을 사용하시겠습니까? 1. Web 2. SW 3. OrgChart 4. 혼합 사용"을 묻는다. 정해져 있으면 다시 묻지 않는다.
|
||||
2. 위 "사용 유형"이 없고 요청으로도 정할 수 없으면 코드 작성 전에 "어떤 HMDesign 디자인 시스템을 사용하시겠습니까? 1. Web 2. SW (일반 모드 / 뷰어 모드) 3. OrgChart 4. 혼합 사용"을 묻는다. SW인데 모드(일반/뷰어)가 불명확하면 "SW 화면을 어떤 모드로 만들까요? 1. SW 일반 모드 2. SW 뷰어 모드"를 묻는다(근거는 `@hm-design/sw/ai/AI_USAGE.md` §0). 정해져 있으면 다시 묻지 않는다.
|
||||
3. 선택한 패키지의 `ai/AI_USAGE.md` → `COMPONENT_CATALOG.md` → `DESIGN_RULES.md` → `COMPOSITION_PATTERNS.md` 순으로 필요한 절을 읽는다.
|
||||
- Web: `node_modules/@hm-design/ui/ai/`
|
||||
- SW: `node_modules/@hm-design/sw/ai/`
|
||||
- SW: `node_modules/@hm-design/sw/ai/` (뷰어 모드는 `AI_USAGE.md` §0 다음 `VIEWER.md`)
|
||||
- OrgChart: `node_modules/@hm-design/org-chart/ai/` (React는 `node_modules/@hm-design/org-chart-react/ai/AI_USAGE.md`도)
|
||||
4. 기존 컴포넌트 → Props → 조합 → (없는 부분만) 패키지 토큰으로 신규 구현 순서를 지킨다. 패키지 파일 수정·내부 경로 import·구현 복사·새 디자인 값 생성은 하지 않는다.
|
||||
5. Web / SW / OrgChart 스타일을 영역별로 분리하고, 완료 후 AI_GUIDE의 결과 보고 형식으로 재사용·신규·토큰·검증·NOT VERIFIED를 보고한다.
|
||||
4. 선택한 유형·모드 안에서 기존 컴포넌트 → Props → 조합 → (없는 부분만) 그 모드의 토큰·스타일로 신규 → (참고 값도 없으면) HMDesign 공통 규칙과 조화되게 구성하고 "AI 구성 값"으로 보고하는 순서를 지킨다. 패키지 파일 수정·내부 경로 import·구현 복사는 하지 않는다.
|
||||
5. Web / SW 일반 / SW 뷰어 / OrgChart 스타일을 영역별로 분리하고(한 SW 화면에 일반·뷰어 컴포넌트를 섞지 않음), 완료 후 AI_GUIDE의 결과 보고 형식으로 유형·모드, 재사용·신규·토큰·AI 구성 값·검증·NOT VERIFIED를 보고한다.
|
||||
+92
-32
@@ -2,18 +2,19 @@
|
||||
|
||||
> 이 파일은 HMDesign 패키지(`@hm-design/ui`, `@hm-design/sw`, `@hm-design/org-chart`, `@hm-design/org-chart-react`)의 `ai/AI_GUIDE.md`에 **같은 내용으로** 들어 있습니다. 원본은 HMDesign 저장소 `docs/ai/AI_GUIDE.md`이며 패키지 사본은 `npm run sync:ai-docs`로 갱신합니다. 사본을 직접 고치지 않습니다.
|
||||
|
||||
사용자가 "HMDesign 패키지를 기준으로 화면을 구현해 주세요"처럼 요청하면 AI 코딩 도구는 이 파일의 1~6단계를 순서대로 따릅니다. 이 문서와 각 패키지의 `ai/` 문서는 실제 공개 API·CSS에서 확인한 내용만 적습니다. 여기에 없는 컴포넌트·Props·토큰은 없는 것으로 취급합니다.
|
||||
사용자가 "HMDesign 패키지를 기준으로 화면을 구현해 주세요", "HMDesign SW로 화면을 만들어 주세요"처럼 요청하면 AI 코딩 도구는 이 파일의 1~7단계를 순서대로 따릅니다. 이 문서와 각 패키지의 `ai/` 문서는 실제 공개 API·CSS에서 확인한 내용만 적습니다. 여기에 없는 컴포넌트·Props·토큰은 없는 것으로 취급합니다.
|
||||
|
||||
## 0. 읽는 순서
|
||||
|
||||
1. **이 파일**(어느 패키지의 사본이든 같음)
|
||||
2. 선택한 패키지의 `ai/AI_USAGE.md` → `ai/COMPONENT_CATALOG.md` → `ai/DESIGN_RULES.md` → `ai/COMPOSITION_PATTERNS.md`
|
||||
2. 선택한 패키지의 `ai/AI_USAGE.md` → `ai/COMPONENT_CATALOG.md` → `ai/DESIGN_RULES.md` → `ai/COMPOSITION_PATTERNS.md` (SW 뷰어 모드는 `AI_USAGE.md` §0 다음에 `ai/VIEWER.md`를 먼저 읽고 카탈로그의 뷰어 절을 봅니다)
|
||||
3. API가 의심스러우면 그 패키지의 `dist/*.d.ts`(공개 진입점에서 export되는 것만)
|
||||
|
||||
| 유형 | 패키지 | 지침 위치(설치 후) | JS 진입점 | CSS |
|
||||
|---|---|---|---|---|
|
||||
| ① Web UI | `@hm-design/ui` | `node_modules/@hm-design/ui/ai/` | `@hm-design/ui`, `@hm-design/ui/theme` | `@hm-design/ui/tailwind.css` + `@hm-design/ui/theme.css`(Tailwind CSS 4 필요), 선택 `@hm-design/ui/dashboard-status.css` |
|
||||
| ② SW UI | `@hm-design/sw` | `node_modules/@hm-design/sw/ai/` | `@hm-design/sw` | `@hm-design/sw/styles.css` |
|
||||
| ② SW UI — 일반 모드 | `@hm-design/sw` | `node_modules/@hm-design/sw/ai/` (`AI_USAGE.md` §0 모드 선택 → 일반 모드 문서) | `@hm-design/sw` | `@hm-design/sw/styles.css` |
|
||||
| ② SW UI — 뷰어 모드 | `@hm-design/sw`(같은 패키지) | `node_modules/@hm-design/sw/ai/` (`AI_USAGE.md` §0 → `VIEWER.md`) | `@hm-design/sw` | `@hm-design/sw/styles.css`(같은 파일) |
|
||||
| ③ OrgChart | `@hm-design/org-chart`(Core) + React면 `@hm-design/org-chart-react` | `node_modules/@hm-design/org-chart/ai/` (React 어댑터 안내는 `node_modules/@hm-design/org-chart-react/ai/AI_USAGE.md`) | `@hm-design/org-chart`, `@hm-design/org-chart-react`, 선택 `@hm-design/org-chart-react/hm-dialog` | `@hm-design/org-chart/engine.css`, `@hm-design/org-chart/style.css`(URL로 전달 — Shadow DOM 안에 로드) |
|
||||
| 기타 | `@hm-design/center-graphic` | AI 지침 없음. 패키지 `README.md`만 | `@hm-design/center-graphic` | 자동 import |
|
||||
|
||||
@@ -21,12 +22,19 @@
|
||||
|
||||
## 1단계. 사용 목적 확인
|
||||
|
||||
화면 구현 요청을 받으면 코드 작성 전에 **사용 유형**을 정합니다. 유형은 다음 넷이고, SW는 다시 두 모드로 나뉩니다.
|
||||
|
||||
1. Web
|
||||
2. SW — **SW 일반 모드**(편집용: `SWHeader`, `SWPopup` …) / **SW 뷰어 모드**(보기 전용: `SWViewerHeader`, `SWViewerMenu`, `SWViewerPanel` …)
|
||||
3. OrgChart
|
||||
4. 혼합 사용(영역마다 위 유형 하나)
|
||||
|
||||
다음 순서로 판단하고, **판단되면 다시 묻지 않습니다.**
|
||||
|
||||
1. 소비 프로젝트의 `AGENTS.md`·`CLAUDE.md` 등에 `HMDesign 사용 유형:` 설정이 있으면 그대로 따릅니다(§9).
|
||||
1. 소비 프로젝트의 `AGENTS.md`·`CLAUDE.md` 등에 `HMDesign 사용 유형:` 설정이 있으면 그대로 따릅니다(§9). 값은 `Web` / `SW 일반` / `SW 뷰어` / `OrgChart` / `혼합(영역별: …)`입니다. 값이 `SW`뿐이면 유형은 정해진 것이고 모드만 아래 4번으로 정합니다.
|
||||
2. 사용자 요청이 유형을 분명히 말하면 그대로 따릅니다.
|
||||
- Web: 웹 화면, 관리자·업무 화면, 목록·검색·Form, 대시보드, GNB/LNB, Dialog, Table …
|
||||
- SW: 데스크톱 SW, 뷰어, 도면·CAD, SW Header, 툴바, 레이어/색상/선스타일, 속성창·SW Popup …
|
||||
- SW: 데스크톱 SW, 도면·CAD, SW Header, 툴바, 레이어/색상/선스타일, 속성창·SW Popup, 뷰어 …
|
||||
- OrgChart: 조직도, 조직 계층·직원 카드, 조직 JSON/CSV/Excel 시각화 …
|
||||
- 둘 이상이 함께 나오면 ④ 혼합(예: "업무 화면 안에 조직도" = Web + OrgChart).
|
||||
3. 위로 정할 수 없으면 코드 작성 전에 **그대로** 묻습니다.
|
||||
@@ -34,12 +42,21 @@
|
||||
> 어떤 HMDesign 디자인 시스템을 사용하시겠습니까?
|
||||
>
|
||||
> 1. Web
|
||||
> 2. SW
|
||||
> 2. SW (일반 모드 / 뷰어 모드)
|
||||
> 3. OrgChart
|
||||
> 4. 혼합 사용
|
||||
|
||||
- `package.json`에 설치된 패키지가 하나뿐이어도 그것만으로 유형을 확정하지 않습니다(설치가 덜 된 상태일 수 있음). 요청 내용과 맞을 때만 근거로 씁니다.
|
||||
- 혼합을 고르면 영역별 패키지(예: "페이지 = Web, 가운데 영역 = OrgChart")를 확인합니다.
|
||||
4. **SW가 정해졌거나 포함됐는데 모드가 불명확하면** 코드 작성 전에 묻습니다. 설정 값(`SW 일반`/`SW 뷰어`)이나 요청이 모드를 분명히 말하면 묻지 않습니다. 판단 근거와 질문 문구는 `@hm-design/sw/ai/AI_USAGE.md` §0을 따릅니다. 유형 질문이 필요한 경우에는 같은 메시지에서 2번 선택 시의 모드도 함께 묻습니다(한 번에 끝냄).
|
||||
|
||||
> SW 화면을 어떤 모드로 만들까요?
|
||||
>
|
||||
> 1. SW 일반 모드 — 편집용 Header(`SWHeader`)·속성창·SW Popup
|
||||
> 2. SW 뷰어 모드 — 보기 전용 Header(`SWViewerHeader`)·뷰어 메뉴·뷰어 패널
|
||||
|
||||
- "HMDesign SW로 화면을 만들어 주세요"처럼 SW만 말하고 모드 근거가 없으면 유형은 SW로 확정하고 4번의 모드 질문만 합니다.
|
||||
- `package.json`에 설치된 패키지가 하나뿐이어도 그것만으로 유형을 확정하지 않습니다(설치가 덜 된 상태일 수 있음). 요청 내용과 맞을 때만 근거로 씁니다. SW 모드도 같은 패키지이므로 설치 상태로는 판단하지 않습니다.
|
||||
- 정해진 유형·모드는 결과 보고(7단계)에 적고, 작업 중에 다른 유형·모드의 컴포넌트·스타일을 임의로 섞지 않습니다(5단계).
|
||||
- 혼합을 고르면 영역별 패키지(예: "페이지 = Web, 가운데 영역 = OrgChart")를 확인합니다. SW 영역이 있으면 그 영역의 모드(일반/뷰어)까지 정합니다.
|
||||
- **OrgChart가 포함되고 생성 방식이 없으면** 같은 메시지에서 다음도 묻습니다(이미 말했으면 묻지 않음): "조직도만 기존 페이지에 삽입할까요(Chart Only), 아니면 레이아웃까지 구성한 새 페이지 전체를 생성할까요(Full Page)?" 상세는 `@hm-design/org-chart/ai/AI_USAGE.md` §1.
|
||||
- 선택한 패키지가 설치되어 있지 않으면 설치가 필요하다고 보고합니다. 다른 HMDesign 패키지나 임의 라이브러리로 대신하지 않습니다.
|
||||
|
||||
@@ -57,8 +74,9 @@
|
||||
| 요청 항목 | 판단 | 근거(카탈로그의 실제 이름) |
|
||||
|---|---|---|
|
||||
| 예: 상단 메뉴 | 재사용 | Web `GNB` + `GNBMobileMenu` |
|
||||
| 예: 레이어 선택 | 재사용 | SW `SWHeaderLayerMenu` |
|
||||
| 예: 검색 상자(SW) | 신규 | SW 카탈로그에 없음 → `SWHeaderInput` 재사용 + SW 토큰 |
|
||||
| 예: 레이어 선택(SW 일반) | 재사용 | SW `SWHeaderLayerMenu` |
|
||||
| 예: 상단 메뉴(SW 뷰어) | Props 설정 | SW `SWViewerHeader`의 `groups` |
|
||||
| 예: 검색 상자(SW 일반) | 신규 | SW 카탈로그에 없음 → `SWHeaderInput` 재사용 + 일반 모드 토큰 |
|
||||
|
||||
판단 값은 **재사용**(그대로) / **Props 설정**(기존 Variant·Props) / **조합**(기존 컴포넌트 배치) / **신규**(소비 프로젝트에 최소 구현) 중 하나입니다.
|
||||
|
||||
@@ -69,31 +87,44 @@
|
||||
1. 선택 패키지의 기존 컴포넌트·Pattern을 그대로 사용
|
||||
2. 기존 Variant / Props / Callback으로 해결
|
||||
3. 기존 컴포넌트 조합(배치용 CSS만 소비 프로젝트에 작성)
|
||||
4. 조합으로 안 되는 부분만 **소비 프로젝트에** 새로 구현 — 패키지 토큰만 읽고, 안쪽에 기존 컴포넌트를 재사용
|
||||
4. 조합으로 안 되는 부분만 **소비 프로젝트에** 새로 구현 — 아래 "없는 컴포넌트 처리 3단계"
|
||||
|
||||
모든 단계는 **1단계에서 정한 유형·모드 안에서만** 찾습니다. SW 뷰어 모드는 뷰어 컴포넌트(`SWViewer*`)를, SW 일반 모드는 일반 컴포넌트(`SWHeader`·`SWPopup` …)를 먼저 씁니다. 다른 모드에 같은 역할의 컴포넌트가 있어도 가져오지 않습니다.
|
||||
|
||||
### 없는 컴포넌트 처리 3단계
|
||||
|
||||
| 단계 | 조건 | 할 일 | 결과 보고 |
|
||||
|---|---|---|---|
|
||||
| ① 재사용 | 선택 유형·모드에 컴포넌트·Variant·Props·조합이 있음 | 그대로 사용(위 1~3) | 재사용 / Props 설정 / 조합 |
|
||||
| ② 같은 모드 스타일로 신규 | 컴포넌트는 없지만 그 모드의 토큰·확인값·상태 표현이 있음 | 소비 프로젝트에 최소 구현. 그 유형·모드의 토큰과 `DESIGN_RULES.md`(SW 뷰어는 `VIEWER.md`도)의 크기·색·상태 표현만 읽고, 안쪽에는 그 모드의 공개 컴포넌트를 재사용 | 신규 · 읽은 토큰 목록 |
|
||||
| ③ HMDesign과 조화되는 새 스타일 | ②로 참고할 토큰·확인값이 없음 | HMDesign 공통 규칙(아래)과 선택 유형·모드의 가장 가까운 토큰을 기준으로 새 스타일을 구성 | 신규 · **"AI 구성 값 — 디자인 확인 필요"** 목록(속성·값·이유) |
|
||||
|
||||
- 토큰·확인값이 있으면 ②에서 반드시 그것을 씁니다. ③은 참고할 값이 정말 없을 때만이며, ③에서 만든 값은 확정 디자인이 아니라 확인 대상입니다. 화면 인상을 크게 바꾸는 값(주요 색·Header 높이 등)이 필요하면 구현 전에 사용자에게 먼저 확인합니다.
|
||||
- 유형·모드별 구체 토큰과 예는 각 패키지 `ai/AI_USAGE.md`에 있습니다.
|
||||
|
||||
규칙:
|
||||
|
||||
- `node_modules` 안 패키지 파일을 수정하지 않습니다. 패키지 `dist` 구현이나 내부 CSS 블록을 복사해 같은 컴포넌트를 다시 만들지 않습니다.
|
||||
- 이미 있는 컴포넌트와 같은 역할의 컴포넌트를 새로 만들지 않습니다(예: Web에 `Dialog`가 있는데 자체 Modal 작성 금지).
|
||||
- 새 디자인 값을 만들지 않습니다. 색·크기·간격·radius·그림자는 각 패키지 `DESIGN_RULES.md`의 토큰·확인값만 씁니다. 값이 없으면 추측하지 말고 사용자에게 확인합니다.
|
||||
- 토큰·확인값이 있는 속성에 새 값을 만들지 않습니다. 색·크기·간격·radius·그림자는 각 패키지 `DESIGN_RULES.md`(SW 뷰어는 `VIEWER.md`도)의 토큰·확인값을 씁니다. 값이 없을 때만 위 ③으로 구성하고 "AI 구성 값"으로 보고합니다(추측한 값을 확정값처럼 쓰지 않음).
|
||||
- 공통: Font Weight는 400 / 500 / 700만 씁니다(600 없음). Light/Dark 분기를 만들지 않습니다. 새 컴포넌트 CSS에 `html`·`body`·`*` 전역 규칙을 넣지 않습니다. 새 class는 소비 프로젝트 접두사(예: `app-`)를 씁니다.
|
||||
- 요청에 없는 메뉴·통계·설명·다운로드·외부 API·AI 입력 UI를 추가하지 않습니다. 필요해 보이면 제안으로만 보고합니다.
|
||||
|
||||
### 없는 UI를 같은 스타일로 만들 때 확인할 항목
|
||||
|
||||
신규 항목마다 아래를 선택 패키지 `DESIGN_RULES.md`에서 찾아 그대로 적용합니다. 찾을 수 없는 항목은 "값 없음 — 사용자 확인 필요"로 보고합니다.
|
||||
신규 항목마다 아래를 선택 유형·모드의 문서에서 찾아 그대로 적용합니다(②). 찾을 수 없는 항목은 ③으로 구성하고 "AI 구성 값 — 디자인 확인 필요"로 보고합니다.
|
||||
|
||||
| 항목 | Web(`@hm-design/ui`) | SW(`@hm-design/sw`) | OrgChart |
|
||||
|---|---|---|---|
|
||||
| 토큰·CSS 변수 | `--hm-sem-*`, `--hm-color-*`, `--hm-radius-*`(`:root`) | `--hm-sw-header-*`, `--hm-sw-property-*`(`SWTheme` 범위) | `--hm-orgchart-*` 공개 입력(Shadow DOM 상속) |
|
||||
| 색·Typography | DESIGN_RULES §2·§3 | DESIGN_RULES §2·§3 | DESIGN_RULES §2·§3 |
|
||||
| 크기·여백 | DESIGN_RULES §4 | DESIGN_RULES §1 | 카드·간격 변경 금지(승인 디자인) |
|
||||
| Border·Radius·배경·그림자 | DESIGN_RULES §2·§4 | DESIGN_RULES §2·§8 | 공개 입력만 |
|
||||
| 아이콘 | `lucide-react`(패키지 의존성) | 패키지 내장 SVG만, 새 아이콘은 사용자 제공 | Core 내장 |
|
||||
| 스크롤바 | `ScrollArea`(Radix), DESIGN_RULES §6 | 전용 디자인 없음 — 브라우저 기본(AI_USAGE §2) | Core 내부 Zoom/Pan |
|
||||
| Hover / Active / Focus / Disabled | DESIGN_RULES §5 | DESIGN_RULES §4 | Core 내장 |
|
||||
| Popup·Panel | `Dialog`·`AlertDialog`·`Sheet`·`Drawer`·`Popover` | `SWPopup` + `SWPopupSection`/`SWPopupRow` | Core 팝업 / HM Dialog / 어댑터 |
|
||||
| 동작·키보드 | Radix 동작 유지 | 카탈로그 "공통 키보드" | Core 키보드(Pan, Alt+M 이동 등) |
|
||||
| 항목 | Web(`@hm-design/ui`) | SW 일반 모드(`@hm-design/sw`) | SW 뷰어 모드(`@hm-design/sw`) | OrgChart |
|
||||
|---|---|---|---|---|
|
||||
| 토큰·CSS 변수 | `--hm-sem-*`, `--hm-color-*`, `--hm-radius-*`(`:root`) | `--hm-sw-header-*`, `--hm-sw-property-*`(`SWTheme` 범위) | `--hm-sw-viewer-*` + 두 Header가 공유하는 `--hm-sw-header-document-*`·`object-*`·`property-*`(SW 범위) | `--hm-orgchart-*` 공개 입력(Shadow DOM 상속) |
|
||||
| 색·Typography | DESIGN_RULES §2·§3 | DESIGN_RULES §2·§3 | VIEWER.md `SWViewerHeader`·디자인 변경 절 | DESIGN_RULES §2·§3 |
|
||||
| 크기·여백 | DESIGN_RULES §4 | DESIGN_RULES §1 | VIEWER.md 디자인 변경 절(52px Header 등 실측값) | 카드·간격 변경 금지(승인 디자인) |
|
||||
| Border·Radius·배경·그림자 | DESIGN_RULES §2·§4 | DESIGN_RULES §2·§8 | VIEWER.md `SWViewerPanel` 절(프레임은 SWPopup과 같음) | 공개 입력만 |
|
||||
| 아이콘 | `lucide-react`(패키지 의존성) | 패키지 내장 SVG만, 새 아이콘은 사용자 제공 | 프로그램 제공 16px `currentColor` 아이콘, 외곽선은 `SWViewerIcon` | Core 내장 |
|
||||
| 스크롤바 | `ScrollArea`(Radix), DESIGN_RULES §6 | 전용 디자인 없음 — 브라우저 기본(AI_USAGE §2) | 전용 디자인 없음 — 패널 본문 스크롤은 `SWViewerPanel` | Core 내부 Zoom/Pan |
|
||||
| Hover / Active / Focus / Disabled | DESIGN_RULES §5 | DESIGN_RULES §4 | VIEWER.md `SWViewerHeader` 절 상태 표현 | Core 내장 |
|
||||
| Popup·Panel | `Dialog`·`AlertDialog`·`Sheet`·`Drawer`·`Popover` | `SWPopup` + `SWPopupSection`/`SWPopupRow` | `SWViewerPanel`(+ `modal`) + `SWViewerSection`/`SWViewerField` | Core 팝업 / HM Dialog / 어댑터 |
|
||||
| 동작·키보드 | Radix 동작 유지 | 카탈로그 "공통 키보드" | VIEWER.md `SWViewerMenu`·`SWViewerPanel` 키보드 | Core 키보드(Pan, Alt+M 이동 등) |
|
||||
|
||||
## 5단계. 패키지별 디자인 분리 (혼합 사용 포함)
|
||||
|
||||
@@ -102,20 +133,30 @@
|
||||
| 패키지 | 스타일이 적용되는 범위 | 주의 |
|
||||
|---|---|---|
|
||||
| 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`(`<SWTheme>`)에만 정의. 전역 선택자 없음 | Header 밖 SW 부품은 반드시 `<SWTheme>` 안 |
|
||||
| SW(일반·뷰어 공통) | 토큰은 `.hm-sw-header`와 `.hm-sw-theme`에만 정의(뷰어 토큰 `--hm-sw-viewer-*`도 같은 범위). 전역 선택자 없음. `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`은 자기 root에 `hm-sw-theme`를 가짐 | 일반 모드의 Header 밖 SW 부품은 반드시 `<SWTheme>` 안 |
|
||||
| OrgChart | Core가 자기 open Shadow DOM에만 CSS 로드. 호스트 CSS selector는 안쪽에 닿지 않고 **Custom Property 상속만** 통과 | 호스트 class로 카드 모양을 바꾸려 하지 않음 |
|
||||
|
||||
혼합 규칙:
|
||||
|
||||
1. 영역마다 하나의 패키지를 정하고 그 영역의 신규 UI는 그 패키지의 토큰만 읽습니다. Web 토큰(`--hm-sem-*`)을 SW 영역에, SW 토큰(`--hm-sw-*`)을 Web 영역에 쓰지 않습니다. OrgChart 내부는 `--hm-orgchart-*`만 씁니다.
|
||||
2. 다른 패키지 컴포넌트는 **문서에 허용된 지점에서만** 씁니다.
|
||||
- SW `SWPopup`의 `children` 안 Web 컨트롤(SW 카탈로그가 허용, 예: Popup 하단 `Button`)
|
||||
- SW 일반 모드 `SWPopup`의 `children` 안 Web 컨트롤(SW 카탈로그가 허용, 예: Popup 하단 `Button`)
|
||||
- SW 뷰어 모드 `SWViewerPanel`의 `children` 안 Web 컨트롤 — `SWViewer*` 컨트롤로 안 될 때만(SW `AI_USAGE.md` §0.4)
|
||||
- OrgChart Full Page의 바깥 레이아웃 = Web(또는 요청된 패키지)
|
||||
- OrgChart React의 직원 팝업 = 선택 `@hm-design/org-chart-react/hm-dialog`(Web `Dialog`, Web Theme CSS 필요)
|
||||
3. 패키지 class(`hm-sw-*`, `hm-orgchart-*`, Web `data-slot`)를 소비 코드에서 덮어쓰지 않습니다. 배치는 `className`·`style`과 소비 프로젝트 class로 합니다.
|
||||
4. **Web + SW를 한 문서에 함께 쓰면** Web의 전역 base(위 표)가 SW 화면에도 적용됩니다. SW는 자기 범위에서 버튼 등을 초기화하지만 이 조합의 시각 결과는 패키지에서 검증된 적이 없습니다(NOT VERIFIED). 이 조합이면 브라우저에서 SW 부품의 글꼴·테두리·배경을 직접 확인하고 차이를 보고합니다. 가능하면 Web CSS가 없는 SW 전용 화면(별도 entry)으로 분리합니다.
|
||||
5. Web Scoped Theme(`[data-hm-theme]`)는 body Portal(Select·Popover·DatePicker 팝업)에 전달되지 않습니다. Web 영역만 다른 테마로 바꾸려면 Global Theme를 쓰거나 차이를 보고합니다.
|
||||
|
||||
### SW 일반 모드 ↔ 뷰어 모드 분리
|
||||
|
||||
SW 일반 모드와 뷰어 모드는 같은 패키지·같은 CSS 파일이지만 **서로 다른 디자인**입니다. 한 화면(한 Header 영역)에는 한 모드만 씁니다.
|
||||
|
||||
1. 일반 모드 화면: `SWHeader`·개별 컨트롤·`SWPopup`·`SWHeaderPropertyPanel`·`SWToolButton`/`SWToolGroup`. `SWViewer*` 컴포넌트와 `--hm-sw-viewer-*` 토큰을 쓰지 않습니다.
|
||||
2. 뷰어 모드 화면: `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`과 뷰어 패널 컨트롤(`SWViewerSection`·`SWViewerField` …). `SWHeader`에 뷰어 메뉴를 억지로 넣거나 `SWPopup`을 뷰어처럼 재스타일하지 않습니다.
|
||||
3. 패키지가 실제로 공유하는 부분은 혼합이 아닙니다: `SWViewerPanel`은 `SWPopup` 프레임을 그대로 렌더링하고, 두 Header는 파일명·객체 수정·속성 면 토큰(`--hm-sw-header-document-*`·`object-*`·`property-*`)을 공유합니다. 소비 코드가 이 공유를 흉내 내 다른 모드 부품을 섞어도 된다는 뜻은 아닙니다.
|
||||
4. 프로그램이 두 모드를 모두 가지면 모드 전환 시 Header 컴포넌트를 바꿔 끼웁니다(파일·패널 상태는 프로그램 상태로 유지). 세부는 `@hm-design/sw/ai/AI_USAGE.md` §0과 `VIEWER.md`.
|
||||
|
||||
## 6단계. 디자인 검증
|
||||
|
||||
소비 프로젝트에서 실제로 실행한 것만 PASS로 적습니다.
|
||||
@@ -123,20 +164,22 @@
|
||||
1. Typecheck(`tsc --noEmit` 등)와 Production Build
|
||||
2. 브라우저 렌더링: 재사용한 컴포넌트가 HM 외형으로 보이는지(CSS 진입점 누락 확인), 신규 UI가 같은 토큰을 쓰는지
|
||||
3. 상태·동작: Hover / Focus(키보드) / Disabled, Popup 열기·닫기·Escape·Focus 복귀, 선택 패키지의 핵심 동작
|
||||
4. 폭: Web 390 / 768 / 1280 / 1440px, SW는 대상 창 폭(Header는 반응형 More 포함), OrgChart는 캔버스 크기·초기 Fit
|
||||
5. 혼합이면 영역 경계에서 스타일 침범이 없는지(§5)
|
||||
4. 폭: Web 390 / 768 / 1280 / 1440px, SW 일반 모드는 대상 창 폭(Header는 반응형 More 포함), SW 뷰어 모드는 대상 창 폭과 항목 `collapseBelow`·`iconOnlyBelow` 경계 전후(More 이동·아이콘만 표시), OrgChart는 캔버스 크기·초기 Fit
|
||||
5. 혼합이면 영역 경계에서 스타일 침범이 없는지, SW면 선택하지 않은 모드의 컴포넌트·토큰이 섞이지 않았는지(§5)
|
||||
6. 실행하지 못한 항목은 `NOT VERIFIED`로 남깁니다.
|
||||
|
||||
## 7단계. 결과 보고 형식
|
||||
|
||||
```md
|
||||
## HMDesign 적용 결과
|
||||
- 사용 유형: Web | SW | OrgChart(Chart Only|Full Page) | 혼합(영역별: …)
|
||||
- 사용 유형: Web | SW 일반 | SW 뷰어 | OrgChart(Chart Only|Full Page) | 혼합(영역별: …)
|
||||
- 유형·모드 판단 근거: 프로젝트 설정 | 요청 문구 "…" | 사용자 답변
|
||||
- 패키지·버전: @hm-design/ui 0.1.0, …
|
||||
- 재사용한 컴포넌트: …(Props 설정 포함)
|
||||
- 조합한 부분: …
|
||||
- AI가 새로 구현한 부분: 파일 경로 · 이유(카탈로그에 없음) · 안쪽에서 재사용한 컴포넌트
|
||||
- 적용한 디자인 토큰: --hm-… (신규 UI가 읽은 것)
|
||||
- AI 구성 값 — 디자인 확인 필요: 없음 | 속성 · 값 · 이유(4단계 ③)
|
||||
- 카탈로그와 .d.ts 차이: 없음 | …
|
||||
- 검증: Typecheck PASS · Build PASS · 브라우저(폭/상태) … · NOT VERIFIED: …
|
||||
- 제안(구현하지 않음): …
|
||||
@@ -161,9 +204,14 @@
|
||||
import { Button, Card, CardContent, FilterBar, FilterBarActions, FilterBarSearch, PageHeader, PageHeaderContent, PageHeaderTitle } from "@hm-design/ui"
|
||||
```
|
||||
|
||||
### 예시 B — SW 뷰어
|
||||
### 예시 B0 — "HMDesign SW로 화면을 만들어 주세요" (모드 미지정)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/sw/ai/` → COMPOSITION_PATTERNS "6. 파일 열기 + 도구 막대", 예제 `ai/examples/ExampleF-ViewerToolbar.tsx`
|
||||
- 유형은 SW로 확정, 모드 근거가 없으므로 코드 작성 전에 1단계 4번의 모드 질문만 합니다. 답에 따라 B1 또는 B2로 진행합니다.
|
||||
- 소비 프로젝트 설정이 `HMDesign 사용 유형: SW 일반` 또는 `SW 뷰어`이면 묻지 않고 바로 B1/B2입니다.
|
||||
|
||||
### 예시 B1 — SW 일반 모드 (편집 Header + 도구 막대 + 설정 Popup)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/sw/ai/` → AI_USAGE §0(일반 모드) → COMPOSITION_PATTERNS "6. 파일 열기 + 도구 막대", 예제 `ai/examples/ExampleF-ViewerToolbar.tsx`(파일 이름의 Viewer는 과거 명칭이며 일반 모드 `SWHeader` 예제)
|
||||
- 재사용: `SWHeader`(`documentOpenPlacement="header"`, `controls`, `tools`), `SWToolGroup` + `SWToolButton`(Model/Layout 탭, Fit 등), `SWPopup` + `SWPopupSection` + `SWPopupRow` + `SWHeaderInput`(설정 Popup)
|
||||
- 신규: SW에 없는 기능(예: 검색) → 소비 프로젝트 컴포넌트, `<SWTheme>` 안, `--hm-sw-header-*` 토큰, 안쪽 입력은 `SWHeaderInput`(예제 `ExampleD-SearchExtension.tsx`)
|
||||
|
||||
@@ -172,6 +220,18 @@ import { SWHeader, SWPopup, SWTheme, SWToolButton, SWToolGroup } from "@hm-desig
|
||||
import "@hm-design/sw/styles.css"
|
||||
```
|
||||
|
||||
### 예시 B2 — SW 뷰어 모드 (뷰어 Header + 메뉴 + 패널)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/sw/ai/` → AI_USAGE §0(뷰어 모드) → `VIEWER.md`, 예제 `ai/examples/ExampleH-ViewerMode.tsx`
|
||||
- 재사용: `SWViewerHeader`(`groups` 데이터: `button`·`toggle`·`menu`·`tabs`·`switch`·`custom` 항목, `onCommand`, `trailing`에 `SWViewerStatus`·`SWViewerHeaderButton`), Dropdown은 `type: "menu"` 항목의 `entries`(단독·우클릭은 `SWViewerMenu`), 팝업은 `SWViewerPanel` + `SWViewerSection`·`SWViewerField`·`SWViewerSwitch`·`SWViewerSlider`·`SWViewerInput`·`SWViewerButton`
|
||||
- 신규: 뷰어에 없는 패널 콘텐츠 → 소비 프로젝트 컴포넌트를 `SWViewerPanel`의 `children`에, 안쪽은 `SWViewerField` + `SWViewerInput` 등, 외형은 `--hm-sw-viewer-*` 토큰
|
||||
- 하지 않음: `SWHeader`·`SWPopup`을 뷰어 화면에 섞기, 로고가 없다고 임의 문자·아이콘 넣기, 연결할 명령이 없는 메뉴를 가짜 동작으로 만들기(제외 또는 `disabled` + 미연결 보고)
|
||||
|
||||
```tsx
|
||||
import { SWViewerHeader, SWViewerPanel, SWViewerSection, SWViewerField, SWViewerSwitch, type SWViewerHeaderGroup } from "@hm-design/sw"
|
||||
import "@hm-design/sw/styles.css"
|
||||
```
|
||||
|
||||
### 예시 C — 조직도만 (Chart Only)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/org-chart/ai/` → COMPOSITION_PATTERNS "1. Chart Only"
|
||||
@@ -198,7 +258,7 @@ import coreUrl from "@hm-design/org-chart/style.css?url"
|
||||
|
||||
AI 코딩 도구는 보통 **프로젝트 루트의** `AGENTS.md`(Codex 등)·`CLAUDE.md`(Claude Code)·도구별 규칙 파일만 자동으로 읽고 `node_modules`는 읽지 않습니다. 패키지 설치만으로 지침이 자동 적용되지는 않으므로 소비 프로젝트에서 한 번 연결합니다.
|
||||
|
||||
1. 패키지에 들어 있는 `ai/AGENTS_SNIPPET.md`를 루트 `AGENTS.md`(없으면 새로 만듦)에 붙여 넣고 `HMDesign 사용 유형:` 줄을 프로젝트에 맞게 고칩니다. 정하지 않았으면 그 줄을 지워 AI가 1단계에서 묻게 합니다.
|
||||
1. 패키지에 들어 있는 `ai/AGENTS_SNIPPET.md`를 루트 `AGENTS.md`(없으면 새로 만듦)에 붙여 넣고 `HMDesign 사용 유형:` 줄을 프로젝트에 맞게 고칩니다. 값은 `Web` / `SW 일반` / `SW 뷰어` / `OrgChart` / `혼합(영역별: 예 "페이지 = Web, 중앙 = OrgChart")` 중 하나입니다. SW 프로젝트면 모드까지 적어야 AI가 모드를 다시 묻지 않습니다(`SW`만 적으면 모드를 묻습니다). 정하지 않았으면 그 줄을 지워 AI가 1단계에서 묻게 합니다.
|
||||
```bash
|
||||
cat node_modules/@hm-design/ui/ai/AGENTS_SNIPPET.md >> AGENTS.md
|
||||
```
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
|
||||
| 위치 | 역할 | 패키지 포함 |
|
||||
|---|---|---|
|
||||
| `docs/ai/AI_GUIDE.md` | 공통 진입점 원본(사용 유형 선택, 1~7단계, 패키지 분리, 예시 A~D, 소비 프로젝트 설정) | 사본으로 포함 |
|
||||
| `docs/ai/AI_GUIDE.md` | 공통 진입점 원본(사용 유형 Web / SW 일반·뷰어 / OrgChart / 혼합 선택, 없는 컴포넌트 처리 3단계, 1~7단계, 패키지·SW 모드 분리, 예시 A~D, 소비 프로젝트 설정) | 사본으로 포함 |
|
||||
| `docs/ai/AGENTS_SNIPPET.md` | 소비 프로젝트 루트 `AGENTS.md`에 붙일 연결 문구 원본 | 사본으로 포함 |
|
||||
| `docs/ai/MAINTAINING.md` | 이 문서 | 미포함 |
|
||||
| `packages/ui/ai/` | Web: `AI_USAGE`, `COMPONENT_CATALOG`, `DESIGN_RULES`, `COMPOSITION_PATTERNS` | 포함(`files`) |
|
||||
| `packages/sw/ai/` | SW: 위 4종 + `examples/` | 포함 |
|
||||
| `packages/sw/ai/` | SW: 위 4종(`AI_USAGE.md` §0 = SW 일반/뷰어 모드 선택) + 뷰어 모드 전용 `VIEWER.md` + `examples/`(A~F 일반 모드, H 뷰어 모드) | 포함 |
|
||||
| `packages/org-chart/ai/` | OrgChart(Core + React 어댑터 API): 위 4종 | 포함 |
|
||||
| `packages/org-chart-react/ai/` | `AI_USAGE`(Core `ai/` 안내) | 포함 |
|
||||
| `scripts/ai-docs.mjs` | 동기화(`--sync`)·검사(`--check`) | — |
|
||||
@@ -26,14 +26,14 @@
|
||||
1. **공개 Export가 바뀌면** 해당 패키지 `ai/COMPONENT_CATALOG.md`에 이름·용도·HM Props(기본값)를 추가·수정·삭제합니다. 내부 전용 이름은 "공개하지 않은 것" 절에만 적습니다.
|
||||
2. **Props·Variant 기본값·허용 조합이 바뀌면** 카탈로그 표와 `COMPOSITION_PATTERNS.md`의 예시 코드를 함께 고칩니다.
|
||||
3. **토큰·CSS 값이 바뀌면** `DESIGN_RULES.md`의 표를 실제 CSS 선언과 맞춥니다(값은 CSS에서 복사, 추측 금지).
|
||||
4. **새 화면 유형·조합 규칙이 생기면** `COMPOSITION_PATTERNS.md` §0 표에 행을 추가합니다.
|
||||
5. 공통 규칙(유형 선택·혼합·보고 형식)이 바뀌면 `docs/ai/AI_GUIDE.md`만 고치고 `npm run sync:ai-docs`로 사본을 갱신합니다. 패키지 사본을 직접 고치지 않습니다.
|
||||
4. **새 화면 유형·조합 규칙이 생기면** `COMPOSITION_PATTERNS.md` §0 표에 행을 추가합니다. SW 뷰어 모드 컴포넌트(`SWViewer*`)를 바꾸면 `VIEWER.md`와 카탈로그의 뷰어 절을 함께 고치고, 일반/뷰어 모드 구분이 바뀌면 `packages/sw/ai/AI_USAGE.md` §0과 공통 `AI_GUIDE.md` 1단계·5단계를 같이 맞춥니다.
|
||||
5. 공통 규칙(유형·SW 모드 선택·혼합·보고 형식)이 바뀌면 `docs/ai/AI_GUIDE.md`만 고치고 `npm run sync:ai-docs`로 사본을 갱신합니다. 패키지 사본을 직접 고치지 않습니다.
|
||||
6. `npm run check:ai-docs`를 실행해 PASS를 확인합니다.
|
||||
7. 버전을 올리면 카탈로그 첫 줄의 기준 버전을 같이 바꿉니다.
|
||||
|
||||
## 3. `npm run check:ai-docs`가 검사하는 것
|
||||
|
||||
1. `docs/ai`의 공유 파일과 각 패키지 사본이 같은지
|
||||
1. `docs/ai`의 공유 파일과 각 패키지 사본이 같은지(줄바꿈 CRLF/LF 차이는 무시 — `core.autocrlf=true`에서 `packages/sw`만 `.gitattributes`로 LF checkout)
|
||||
2. 각 패키지 `package.json`의 `files`에 `ai`가 있는지
|
||||
3. 공개 진입점(`src/index.ts` 등, `export *` 재귀 포함)의 **모든 Export 이름이 카탈로그에 나오는지**
|
||||
4. 카탈로그에 Export처럼 보이지만(기존 Export 이름으로 시작) 실제로는 없는 이름이 없는지 — 예: `DialogFancyPanel`. "공개하지 않은 것"·"없는 것"·"지원하지 않는" 절은 제외
|
||||
|
||||
@@ -26,3 +26,39 @@
|
||||
- Web CSS와 SW를 **한 문서**에서 함께 쓰는 경우의 시각 결과(문서에 NOT VERIFIED로 명시, 별도 entry 권장).
|
||||
- 768px 화면, 실제 터치·스크린리더, Registry publish 후 설치.
|
||||
- 문서의 Props 기본값·토큰 값 전부를 기계적으로 대조하지는 않았다(검사기는 Export 이름·링크·사본만 검사). 이번 작성은 소스를 직접 확인했다.
|
||||
|
||||
## 추가 검증 — SW 일반 / 뷰어 모드 구분 (2026-10-19)
|
||||
|
||||
범위: `feature/sw-viewer-header`(68fbcf6)를 merge(be7a04a)한 뒤, 사용 유형을 Web / SW(일반·뷰어) / OrgChart / 혼합으로 나누고 SW 모드 선택·혼합 금지·없는 컴포넌트 처리 3단계를 공통 가이드와 각 패키지 `ai/` 문서에 반영. 런타임 코드·CSS·Storybook·공개 API 변경 없음. 위 기록의 "SW 뷰어(SWHeader + SWToolGroup + SWPopup)"는 당시 명칭이며, 현재 기준으로는 **일반 모드 Header + 도구 막대** 구성이다(뷰어 모드 = `SWViewer*`).
|
||||
|
||||
| 항목 | 결과 |
|
||||
|---|---|
|
||||
| `npm run sync:ai-docs` → `npm run check:ai-docs` (뷰어 Export 33개 포함 카탈로그 ↔ 공개 Export) | PASS |
|
||||
| `npm run build -w packages/sw` 후 `npm pack --ignore-scripts` 4종을 임시 소비 폴더 `node_modules/@hm-design/*`에 풀어 확인 | sw tarball에 `ai/VIEWER.md`·`examples/ExampleH-ViewerMode.tsx` 포함, `dist/index.d.ts`가 `sw-viewer`를 `export *` |
|
||||
| 뷰어 문서(VIEWER.md, 카탈로그 §8, DESIGN_RULES §11, PATTERNS 7, AI_USAGE §0)의 Props·토큰 이름 ↔ `sw-viewer` 소스·`sw-viewer.css` | 일치(남은 차이는 예제 변수명과 "없는 Props" 목록뿐) |
|
||||
| 설치 위치 기준 시나리오 정적 검사 124건: 공통(사본 동일·상대 링크), Web(설정 → `ui/ai`, 다른 영역 이관, 3단계), SW 미지정("HMDesign SW로 화면을 만들어 주세요" → 유형 확정 + 모드 질문만, 애매하면 추측 금지), SW 일반(설정 → 묻지 않음, `SWViewer*` 금지, 예제 B·F 명칭), SW 뷰어(설정·요청 근거 → `VIEWER.md`, `SWHeader`/`SWPopup` 재스타일 금지, 주요 8개 컴포넌트가 카탈로그와 설치 `.d.ts`에 존재), OrgChart(Chart Only / Full Page 질문 1회, 승인 디자인 유지), 혼합(SW 영역 모드, 보고 형식) | 124 PASS / 0 FAIL |
|
||||
|
||||
### Cold-start 검증(`be7a04a` 기준) 지적 사항 반영
|
||||
|
||||
| 지적 | 현재 작업본 |
|
||||
|---|---|
|
||||
| `check:ai-docs` FAIL — sw 사본 `AI_GUIDE.md`·`AGENTS_SNIPPET.md` 불일치 | 원인은 내용이 아니라 줄바꿈: `core.autocrlf=true`에서 `docs/ai`·ui·org-chart는 CRLF, `packages/sw`(`.gitattributes` `eol=lf`)는 LF로 checkout. `scripts/ai-docs.mjs` 사본 비교를 줄바꿈 무시로 변경. 작업본 스냅샷을 `git archive`(CRLF checkout 재현)로 풀어 검사 PASS, 실제 내용 차이를 넣으면 FAIL 검출 |
|
||||
| `check:ai-docs` FAIL — SW 카탈로그에 `SWViewer*` 33개 누락 | 카탈로그 §8에 33개 모두 등재, 검사 PASS |
|
||||
| 카탈로그 "표에 없는 이름은 공개 API 아님"과 VIEWER.md 충돌 | §8 등재로 해소, 머리말 "무엇을 쓸까"에 일반/뷰어 분기 |
|
||||
| "도면 뷰어" 요청 시 예시 B(`SWHeader`+`SWPopup`)와 VIEWER.md가 다른 답 | 공통 1단계 4번·예시 B0/B1/B2, SW `AI_USAGE.md` §0(판단 순서·질문 문구·혼합 금지), 예제 B·F는 일반 모드로 명시 |
|
||||
| `SWPopup` `anchorRef` 사용 시 열릴 때 Focus 미이동 | **이번 AI 지침 작업 범위 밖 — 별도 수정 대상.** 코드 수정하지 않음 |
|
||||
|
||||
### 추가 검증 — 코드 예제 (변경분만, 기존 PASS 재사용)
|
||||
|
||||
| 항목 | 결과 |
|
||||
|---|---|
|
||||
| 임시 소비 프로젝트(설치 tarball, React 19.3.0, TypeScript 7.0.2, Vite 8.3.0)에서 `COMPOSITION_PATTERNS.md` 7 코드 조각과 `VIEWER.md` §5 코드 조각을 **본문 그대로** 감싸고 자유 변수만 선언, 예제 H 포함 | `tsc --noEmit`(strict, skipLibCheck false) PASS, `vite build` PASS |
|
||||
| 브라우저 1440px — PATTERNS 7 | 샘플 메뉴 열림·선택 → 파일명 표시, 도면 공간 탭 전환(`space=layout`), 설정 패널 열림 시 패널 안 Focus·Escape 닫힘·토글로 Focus 복귀, 정보 `modal` Focus·확인 닫힘, 가로 넘침 없음, 글꼴 Noto Sans KR, 콘솔 오류 0 |
|
||||
| 브라우저 1440px — VIEWER.md §5 | 파일명 표시, 전체 보기 명령, 설정 패널 Focus, Switch 토글·Label 연결 |
|
||||
| 800px 폭 | 항목이 More(⋯)로 이동(반응형 동작 확인, 세부 경계값 미측정) |
|
||||
|
||||
### NOT VERIFIED
|
||||
|
||||
- 독립 AI가 Cold-start로 이 문서를 읽고 실제로 모드를 묻거나 고르는지(행동 검증). 위 검사는 문서에 필요한 판단 문구가 읽는 경로에 있는지만 확인한다.
|
||||
- 확정 Commit 기준 독립 Cold-start 재검증(별도 1회 예정).
|
||||
- SW 일반/뷰어 모드 전환을 소비 프로젝트에서 실제로 구성한 화면, SW 화면 + 조직도 조합.
|
||||
@@ -1,16 +1,16 @@
|
||||
## HMDesign 디자인 시스템
|
||||
|
||||
<!-- HMDesign 패키지의 ai/AGENTS_SNIPPET.md에서 복사. 아래 "사용 유형"을 프로젝트에 맞게 고치거나, 정하지 않았으면 그 줄을 지운다. -->
|
||||
<!-- HMDesign 패키지의 ai/AGENTS_SNIPPET.md에서 복사. 아래 "사용 유형"을 하나로 고치거나(SW는 모드까지: SW 일반 / SW 뷰어), 정하지 않았으면 그 줄을 지운다. -->
|
||||
|
||||
HMDesign 사용 유형: Web | SW | OrgChart | 혼합(영역별로 적기)
|
||||
HMDesign 사용 유형: Web | SW 일반 | SW 뷰어 | OrgChart | 혼합(영역별로 적기, SW 영역은 모드까지)
|
||||
|
||||
화면·컴포넌트를 구현하거나 수정하기 전에 다음을 지킨다.
|
||||
|
||||
1. 설치된 HMDesign 패키지의 공통 가이드를 먼저 읽는다: `node_modules/@hm-design/<설치된 패키지>/ai/AI_GUIDE.md` (`ui`, `sw`, `org-chart`, `org-chart-react` 중 아무 사본이나 내용이 같다).
|
||||
2. 위 "사용 유형"이 없고 요청으로도 정할 수 없으면 코드 작성 전에 "어떤 HMDesign 디자인 시스템을 사용하시겠습니까? 1. Web 2. SW 3. OrgChart 4. 혼합 사용"을 묻는다. 정해져 있으면 다시 묻지 않는다.
|
||||
2. 위 "사용 유형"이 없고 요청으로도 정할 수 없으면 코드 작성 전에 "어떤 HMDesign 디자인 시스템을 사용하시겠습니까? 1. Web 2. SW (일반 모드 / 뷰어 모드) 3. OrgChart 4. 혼합 사용"을 묻는다. SW인데 모드(일반/뷰어)가 불명확하면 "SW 화면을 어떤 모드로 만들까요? 1. SW 일반 모드 2. SW 뷰어 모드"를 묻는다(근거는 `@hm-design/sw/ai/AI_USAGE.md` §0). 정해져 있으면 다시 묻지 않는다.
|
||||
3. 선택한 패키지의 `ai/AI_USAGE.md` → `COMPONENT_CATALOG.md` → `DESIGN_RULES.md` → `COMPOSITION_PATTERNS.md` 순으로 필요한 절을 읽는다.
|
||||
- Web: `node_modules/@hm-design/ui/ai/`
|
||||
- SW: `node_modules/@hm-design/sw/ai/`
|
||||
- SW: `node_modules/@hm-design/sw/ai/` (뷰어 모드는 `AI_USAGE.md` §0 다음 `VIEWER.md`)
|
||||
- OrgChart: `node_modules/@hm-design/org-chart/ai/` (React는 `node_modules/@hm-design/org-chart-react/ai/AI_USAGE.md`도)
|
||||
4. 기존 컴포넌트 → Props → 조합 → (없는 부분만) 패키지 토큰으로 신규 구현 순서를 지킨다. 패키지 파일 수정·내부 경로 import·구현 복사·새 디자인 값 생성은 하지 않는다.
|
||||
5. Web / SW / OrgChart 스타일을 영역별로 분리하고, 완료 후 AI_GUIDE의 결과 보고 형식으로 재사용·신규·토큰·검증·NOT VERIFIED를 보고한다.
|
||||
4. 선택한 유형·모드 안에서 기존 컴포넌트 → Props → 조합 → (없는 부분만) 그 모드의 토큰·스타일로 신규 → (참고 값도 없으면) HMDesign 공통 규칙과 조화되게 구성하고 "AI 구성 값"으로 보고하는 순서를 지킨다. 패키지 파일 수정·내부 경로 import·구현 복사는 하지 않는다.
|
||||
5. Web / SW 일반 / SW 뷰어 / OrgChart 스타일을 영역별로 분리하고(한 SW 화면에 일반·뷰어 컴포넌트를 섞지 않음), 완료 후 AI_GUIDE의 결과 보고 형식으로 유형·모드, 재사용·신규·토큰·AI 구성 값·검증·NOT VERIFIED를 보고한다.
|
||||
@@ -2,18 +2,19 @@
|
||||
|
||||
> 이 파일은 HMDesign 패키지(`@hm-design/ui`, `@hm-design/sw`, `@hm-design/org-chart`, `@hm-design/org-chart-react`)의 `ai/AI_GUIDE.md`에 **같은 내용으로** 들어 있습니다. 원본은 HMDesign 저장소 `docs/ai/AI_GUIDE.md`이며 패키지 사본은 `npm run sync:ai-docs`로 갱신합니다. 사본을 직접 고치지 않습니다.
|
||||
|
||||
사용자가 "HMDesign 패키지를 기준으로 화면을 구현해 주세요"처럼 요청하면 AI 코딩 도구는 이 파일의 1~6단계를 순서대로 따릅니다. 이 문서와 각 패키지의 `ai/` 문서는 실제 공개 API·CSS에서 확인한 내용만 적습니다. 여기에 없는 컴포넌트·Props·토큰은 없는 것으로 취급합니다.
|
||||
사용자가 "HMDesign 패키지를 기준으로 화면을 구현해 주세요", "HMDesign SW로 화면을 만들어 주세요"처럼 요청하면 AI 코딩 도구는 이 파일의 1~7단계를 순서대로 따릅니다. 이 문서와 각 패키지의 `ai/` 문서는 실제 공개 API·CSS에서 확인한 내용만 적습니다. 여기에 없는 컴포넌트·Props·토큰은 없는 것으로 취급합니다.
|
||||
|
||||
## 0. 읽는 순서
|
||||
|
||||
1. **이 파일**(어느 패키지의 사본이든 같음)
|
||||
2. 선택한 패키지의 `ai/AI_USAGE.md` → `ai/COMPONENT_CATALOG.md` → `ai/DESIGN_RULES.md` → `ai/COMPOSITION_PATTERNS.md`
|
||||
2. 선택한 패키지의 `ai/AI_USAGE.md` → `ai/COMPONENT_CATALOG.md` → `ai/DESIGN_RULES.md` → `ai/COMPOSITION_PATTERNS.md` (SW 뷰어 모드는 `AI_USAGE.md` §0 다음에 `ai/VIEWER.md`를 먼저 읽고 카탈로그의 뷰어 절을 봅니다)
|
||||
3. API가 의심스러우면 그 패키지의 `dist/*.d.ts`(공개 진입점에서 export되는 것만)
|
||||
|
||||
| 유형 | 패키지 | 지침 위치(설치 후) | JS 진입점 | CSS |
|
||||
|---|---|---|---|---|
|
||||
| ① Web UI | `@hm-design/ui` | `node_modules/@hm-design/ui/ai/` | `@hm-design/ui`, `@hm-design/ui/theme` | `@hm-design/ui/tailwind.css` + `@hm-design/ui/theme.css`(Tailwind CSS 4 필요), 선택 `@hm-design/ui/dashboard-status.css` |
|
||||
| ② SW UI | `@hm-design/sw` | `node_modules/@hm-design/sw/ai/` | `@hm-design/sw` | `@hm-design/sw/styles.css` |
|
||||
| ② SW UI — 일반 모드 | `@hm-design/sw` | `node_modules/@hm-design/sw/ai/` (`AI_USAGE.md` §0 모드 선택 → 일반 모드 문서) | `@hm-design/sw` | `@hm-design/sw/styles.css` |
|
||||
| ② SW UI — 뷰어 모드 | `@hm-design/sw`(같은 패키지) | `node_modules/@hm-design/sw/ai/` (`AI_USAGE.md` §0 → `VIEWER.md`) | `@hm-design/sw` | `@hm-design/sw/styles.css`(같은 파일) |
|
||||
| ③ OrgChart | `@hm-design/org-chart`(Core) + React면 `@hm-design/org-chart-react` | `node_modules/@hm-design/org-chart/ai/` (React 어댑터 안내는 `node_modules/@hm-design/org-chart-react/ai/AI_USAGE.md`) | `@hm-design/org-chart`, `@hm-design/org-chart-react`, 선택 `@hm-design/org-chart-react/hm-dialog` | `@hm-design/org-chart/engine.css`, `@hm-design/org-chart/style.css`(URL로 전달 — Shadow DOM 안에 로드) |
|
||||
| 기타 | `@hm-design/center-graphic` | AI 지침 없음. 패키지 `README.md`만 | `@hm-design/center-graphic` | 자동 import |
|
||||
|
||||
@@ -21,12 +22,19 @@
|
||||
|
||||
## 1단계. 사용 목적 확인
|
||||
|
||||
화면 구현 요청을 받으면 코드 작성 전에 **사용 유형**을 정합니다. 유형은 다음 넷이고, SW는 다시 두 모드로 나뉩니다.
|
||||
|
||||
1. Web
|
||||
2. SW — **SW 일반 모드**(편집용: `SWHeader`, `SWPopup` …) / **SW 뷰어 모드**(보기 전용: `SWViewerHeader`, `SWViewerMenu`, `SWViewerPanel` …)
|
||||
3. OrgChart
|
||||
4. 혼합 사용(영역마다 위 유형 하나)
|
||||
|
||||
다음 순서로 판단하고, **판단되면 다시 묻지 않습니다.**
|
||||
|
||||
1. 소비 프로젝트의 `AGENTS.md`·`CLAUDE.md` 등에 `HMDesign 사용 유형:` 설정이 있으면 그대로 따릅니다(§9).
|
||||
1. 소비 프로젝트의 `AGENTS.md`·`CLAUDE.md` 등에 `HMDesign 사용 유형:` 설정이 있으면 그대로 따릅니다(§9). 값은 `Web` / `SW 일반` / `SW 뷰어` / `OrgChart` / `혼합(영역별: …)`입니다. 값이 `SW`뿐이면 유형은 정해진 것이고 모드만 아래 4번으로 정합니다.
|
||||
2. 사용자 요청이 유형을 분명히 말하면 그대로 따릅니다.
|
||||
- Web: 웹 화면, 관리자·업무 화면, 목록·검색·Form, 대시보드, GNB/LNB, Dialog, Table …
|
||||
- SW: 데스크톱 SW, 뷰어, 도면·CAD, SW Header, 툴바, 레이어/색상/선스타일, 속성창·SW Popup …
|
||||
- SW: 데스크톱 SW, 도면·CAD, SW Header, 툴바, 레이어/색상/선스타일, 속성창·SW Popup, 뷰어 …
|
||||
- OrgChart: 조직도, 조직 계층·직원 카드, 조직 JSON/CSV/Excel 시각화 …
|
||||
- 둘 이상이 함께 나오면 ④ 혼합(예: "업무 화면 안에 조직도" = Web + OrgChart).
|
||||
3. 위로 정할 수 없으면 코드 작성 전에 **그대로** 묻습니다.
|
||||
@@ -34,12 +42,21 @@
|
||||
> 어떤 HMDesign 디자인 시스템을 사용하시겠습니까?
|
||||
>
|
||||
> 1. Web
|
||||
> 2. SW
|
||||
> 2. SW (일반 모드 / 뷰어 모드)
|
||||
> 3. OrgChart
|
||||
> 4. 혼합 사용
|
||||
|
||||
- `package.json`에 설치된 패키지가 하나뿐이어도 그것만으로 유형을 확정하지 않습니다(설치가 덜 된 상태일 수 있음). 요청 내용과 맞을 때만 근거로 씁니다.
|
||||
- 혼합을 고르면 영역별 패키지(예: "페이지 = Web, 가운데 영역 = OrgChart")를 확인합니다.
|
||||
4. **SW가 정해졌거나 포함됐는데 모드가 불명확하면** 코드 작성 전에 묻습니다. 설정 값(`SW 일반`/`SW 뷰어`)이나 요청이 모드를 분명히 말하면 묻지 않습니다. 판단 근거와 질문 문구는 `@hm-design/sw/ai/AI_USAGE.md` §0을 따릅니다. 유형 질문이 필요한 경우에는 같은 메시지에서 2번 선택 시의 모드도 함께 묻습니다(한 번에 끝냄).
|
||||
|
||||
> SW 화면을 어떤 모드로 만들까요?
|
||||
>
|
||||
> 1. SW 일반 모드 — 편집용 Header(`SWHeader`)·속성창·SW Popup
|
||||
> 2. SW 뷰어 모드 — 보기 전용 Header(`SWViewerHeader`)·뷰어 메뉴·뷰어 패널
|
||||
|
||||
- "HMDesign SW로 화면을 만들어 주세요"처럼 SW만 말하고 모드 근거가 없으면 유형은 SW로 확정하고 4번의 모드 질문만 합니다.
|
||||
- `package.json`에 설치된 패키지가 하나뿐이어도 그것만으로 유형을 확정하지 않습니다(설치가 덜 된 상태일 수 있음). 요청 내용과 맞을 때만 근거로 씁니다. SW 모드도 같은 패키지이므로 설치 상태로는 판단하지 않습니다.
|
||||
- 정해진 유형·모드는 결과 보고(7단계)에 적고, 작업 중에 다른 유형·모드의 컴포넌트·스타일을 임의로 섞지 않습니다(5단계).
|
||||
- 혼합을 고르면 영역별 패키지(예: "페이지 = Web, 가운데 영역 = OrgChart")를 확인합니다. SW 영역이 있으면 그 영역의 모드(일반/뷰어)까지 정합니다.
|
||||
- **OrgChart가 포함되고 생성 방식이 없으면** 같은 메시지에서 다음도 묻습니다(이미 말했으면 묻지 않음): "조직도만 기존 페이지에 삽입할까요(Chart Only), 아니면 레이아웃까지 구성한 새 페이지 전체를 생성할까요(Full Page)?" 상세는 `@hm-design/org-chart/ai/AI_USAGE.md` §1.
|
||||
- 선택한 패키지가 설치되어 있지 않으면 설치가 필요하다고 보고합니다. 다른 HMDesign 패키지나 임의 라이브러리로 대신하지 않습니다.
|
||||
|
||||
@@ -57,8 +74,9 @@
|
||||
| 요청 항목 | 판단 | 근거(카탈로그의 실제 이름) |
|
||||
|---|---|---|
|
||||
| 예: 상단 메뉴 | 재사용 | Web `GNB` + `GNBMobileMenu` |
|
||||
| 예: 레이어 선택 | 재사용 | SW `SWHeaderLayerMenu` |
|
||||
| 예: 검색 상자(SW) | 신규 | SW 카탈로그에 없음 → `SWHeaderInput` 재사용 + SW 토큰 |
|
||||
| 예: 레이어 선택(SW 일반) | 재사용 | SW `SWHeaderLayerMenu` |
|
||||
| 예: 상단 메뉴(SW 뷰어) | Props 설정 | SW `SWViewerHeader`의 `groups` |
|
||||
| 예: 검색 상자(SW 일반) | 신규 | SW 카탈로그에 없음 → `SWHeaderInput` 재사용 + 일반 모드 토큰 |
|
||||
|
||||
판단 값은 **재사용**(그대로) / **Props 설정**(기존 Variant·Props) / **조합**(기존 컴포넌트 배치) / **신규**(소비 프로젝트에 최소 구현) 중 하나입니다.
|
||||
|
||||
@@ -69,31 +87,44 @@
|
||||
1. 선택 패키지의 기존 컴포넌트·Pattern을 그대로 사용
|
||||
2. 기존 Variant / Props / Callback으로 해결
|
||||
3. 기존 컴포넌트 조합(배치용 CSS만 소비 프로젝트에 작성)
|
||||
4. 조합으로 안 되는 부분만 **소비 프로젝트에** 새로 구현 — 패키지 토큰만 읽고, 안쪽에 기존 컴포넌트를 재사용
|
||||
4. 조합으로 안 되는 부분만 **소비 프로젝트에** 새로 구현 — 아래 "없는 컴포넌트 처리 3단계"
|
||||
|
||||
모든 단계는 **1단계에서 정한 유형·모드 안에서만** 찾습니다. SW 뷰어 모드는 뷰어 컴포넌트(`SWViewer*`)를, SW 일반 모드는 일반 컴포넌트(`SWHeader`·`SWPopup` …)를 먼저 씁니다. 다른 모드에 같은 역할의 컴포넌트가 있어도 가져오지 않습니다.
|
||||
|
||||
### 없는 컴포넌트 처리 3단계
|
||||
|
||||
| 단계 | 조건 | 할 일 | 결과 보고 |
|
||||
|---|---|---|---|
|
||||
| ① 재사용 | 선택 유형·모드에 컴포넌트·Variant·Props·조합이 있음 | 그대로 사용(위 1~3) | 재사용 / Props 설정 / 조합 |
|
||||
| ② 같은 모드 스타일로 신규 | 컴포넌트는 없지만 그 모드의 토큰·확인값·상태 표현이 있음 | 소비 프로젝트에 최소 구현. 그 유형·모드의 토큰과 `DESIGN_RULES.md`(SW 뷰어는 `VIEWER.md`도)의 크기·색·상태 표현만 읽고, 안쪽에는 그 모드의 공개 컴포넌트를 재사용 | 신규 · 읽은 토큰 목록 |
|
||||
| ③ HMDesign과 조화되는 새 스타일 | ②로 참고할 토큰·확인값이 없음 | HMDesign 공통 규칙(아래)과 선택 유형·모드의 가장 가까운 토큰을 기준으로 새 스타일을 구성 | 신규 · **"AI 구성 값 — 디자인 확인 필요"** 목록(속성·값·이유) |
|
||||
|
||||
- 토큰·확인값이 있으면 ②에서 반드시 그것을 씁니다. ③은 참고할 값이 정말 없을 때만이며, ③에서 만든 값은 확정 디자인이 아니라 확인 대상입니다. 화면 인상을 크게 바꾸는 값(주요 색·Header 높이 등)이 필요하면 구현 전에 사용자에게 먼저 확인합니다.
|
||||
- 유형·모드별 구체 토큰과 예는 각 패키지 `ai/AI_USAGE.md`에 있습니다.
|
||||
|
||||
규칙:
|
||||
|
||||
- `node_modules` 안 패키지 파일을 수정하지 않습니다. 패키지 `dist` 구현이나 내부 CSS 블록을 복사해 같은 컴포넌트를 다시 만들지 않습니다.
|
||||
- 이미 있는 컴포넌트와 같은 역할의 컴포넌트를 새로 만들지 않습니다(예: Web에 `Dialog`가 있는데 자체 Modal 작성 금지).
|
||||
- 새 디자인 값을 만들지 않습니다. 색·크기·간격·radius·그림자는 각 패키지 `DESIGN_RULES.md`의 토큰·확인값만 씁니다. 값이 없으면 추측하지 말고 사용자에게 확인합니다.
|
||||
- 토큰·확인값이 있는 속성에 새 값을 만들지 않습니다. 색·크기·간격·radius·그림자는 각 패키지 `DESIGN_RULES.md`(SW 뷰어는 `VIEWER.md`도)의 토큰·확인값을 씁니다. 값이 없을 때만 위 ③으로 구성하고 "AI 구성 값"으로 보고합니다(추측한 값을 확정값처럼 쓰지 않음).
|
||||
- 공통: Font Weight는 400 / 500 / 700만 씁니다(600 없음). Light/Dark 분기를 만들지 않습니다. 새 컴포넌트 CSS에 `html`·`body`·`*` 전역 규칙을 넣지 않습니다. 새 class는 소비 프로젝트 접두사(예: `app-`)를 씁니다.
|
||||
- 요청에 없는 메뉴·통계·설명·다운로드·외부 API·AI 입력 UI를 추가하지 않습니다. 필요해 보이면 제안으로만 보고합니다.
|
||||
|
||||
### 없는 UI를 같은 스타일로 만들 때 확인할 항목
|
||||
|
||||
신규 항목마다 아래를 선택 패키지 `DESIGN_RULES.md`에서 찾아 그대로 적용합니다. 찾을 수 없는 항목은 "값 없음 — 사용자 확인 필요"로 보고합니다.
|
||||
신규 항목마다 아래를 선택 유형·모드의 문서에서 찾아 그대로 적용합니다(②). 찾을 수 없는 항목은 ③으로 구성하고 "AI 구성 값 — 디자인 확인 필요"로 보고합니다.
|
||||
|
||||
| 항목 | Web(`@hm-design/ui`) | SW(`@hm-design/sw`) | OrgChart |
|
||||
|---|---|---|---|
|
||||
| 토큰·CSS 변수 | `--hm-sem-*`, `--hm-color-*`, `--hm-radius-*`(`:root`) | `--hm-sw-header-*`, `--hm-sw-property-*`(`SWTheme` 범위) | `--hm-orgchart-*` 공개 입력(Shadow DOM 상속) |
|
||||
| 색·Typography | DESIGN_RULES §2·§3 | DESIGN_RULES §2·§3 | DESIGN_RULES §2·§3 |
|
||||
| 크기·여백 | DESIGN_RULES §4 | DESIGN_RULES §1 | 카드·간격 변경 금지(승인 디자인) |
|
||||
| Border·Radius·배경·그림자 | DESIGN_RULES §2·§4 | DESIGN_RULES §2·§8 | 공개 입력만 |
|
||||
| 아이콘 | `lucide-react`(패키지 의존성) | 패키지 내장 SVG만, 새 아이콘은 사용자 제공 | Core 내장 |
|
||||
| 스크롤바 | `ScrollArea`(Radix), DESIGN_RULES §6 | 전용 디자인 없음 — 브라우저 기본(AI_USAGE §2) | Core 내부 Zoom/Pan |
|
||||
| Hover / Active / Focus / Disabled | DESIGN_RULES §5 | DESIGN_RULES §4 | Core 내장 |
|
||||
| Popup·Panel | `Dialog`·`AlertDialog`·`Sheet`·`Drawer`·`Popover` | `SWPopup` + `SWPopupSection`/`SWPopupRow` | Core 팝업 / HM Dialog / 어댑터 |
|
||||
| 동작·키보드 | Radix 동작 유지 | 카탈로그 "공통 키보드" | Core 키보드(Pan, Alt+M 이동 등) |
|
||||
| 항목 | Web(`@hm-design/ui`) | SW 일반 모드(`@hm-design/sw`) | SW 뷰어 모드(`@hm-design/sw`) | OrgChart |
|
||||
|---|---|---|---|---|
|
||||
| 토큰·CSS 변수 | `--hm-sem-*`, `--hm-color-*`, `--hm-radius-*`(`:root`) | `--hm-sw-header-*`, `--hm-sw-property-*`(`SWTheme` 범위) | `--hm-sw-viewer-*` + 두 Header가 공유하는 `--hm-sw-header-document-*`·`object-*`·`property-*`(SW 범위) | `--hm-orgchart-*` 공개 입력(Shadow DOM 상속) |
|
||||
| 색·Typography | DESIGN_RULES §2·§3 | DESIGN_RULES §2·§3 | VIEWER.md `SWViewerHeader`·디자인 변경 절 | DESIGN_RULES §2·§3 |
|
||||
| 크기·여백 | DESIGN_RULES §4 | DESIGN_RULES §1 | VIEWER.md 디자인 변경 절(52px Header 등 실측값) | 카드·간격 변경 금지(승인 디자인) |
|
||||
| Border·Radius·배경·그림자 | DESIGN_RULES §2·§4 | DESIGN_RULES §2·§8 | VIEWER.md `SWViewerPanel` 절(프레임은 SWPopup과 같음) | 공개 입력만 |
|
||||
| 아이콘 | `lucide-react`(패키지 의존성) | 패키지 내장 SVG만, 새 아이콘은 사용자 제공 | 프로그램 제공 16px `currentColor` 아이콘, 외곽선은 `SWViewerIcon` | Core 내장 |
|
||||
| 스크롤바 | `ScrollArea`(Radix), DESIGN_RULES §6 | 전용 디자인 없음 — 브라우저 기본(AI_USAGE §2) | 전용 디자인 없음 — 패널 본문 스크롤은 `SWViewerPanel` | Core 내부 Zoom/Pan |
|
||||
| Hover / Active / Focus / Disabled | DESIGN_RULES §5 | DESIGN_RULES §4 | VIEWER.md `SWViewerHeader` 절 상태 표현 | Core 내장 |
|
||||
| Popup·Panel | `Dialog`·`AlertDialog`·`Sheet`·`Drawer`·`Popover` | `SWPopup` + `SWPopupSection`/`SWPopupRow` | `SWViewerPanel`(+ `modal`) + `SWViewerSection`/`SWViewerField` | Core 팝업 / HM Dialog / 어댑터 |
|
||||
| 동작·키보드 | Radix 동작 유지 | 카탈로그 "공통 키보드" | VIEWER.md `SWViewerMenu`·`SWViewerPanel` 키보드 | Core 키보드(Pan, Alt+M 이동 등) |
|
||||
|
||||
## 5단계. 패키지별 디자인 분리 (혼합 사용 포함)
|
||||
|
||||
@@ -102,20 +133,30 @@
|
||||
| 패키지 | 스타일이 적용되는 범위 | 주의 |
|
||||
|---|---|---|
|
||||
| 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`(`<SWTheme>`)에만 정의. 전역 선택자 없음 | Header 밖 SW 부품은 반드시 `<SWTheme>` 안 |
|
||||
| SW(일반·뷰어 공통) | 토큰은 `.hm-sw-header`와 `.hm-sw-theme`에만 정의(뷰어 토큰 `--hm-sw-viewer-*`도 같은 범위). 전역 선택자 없음. `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`은 자기 root에 `hm-sw-theme`를 가짐 | 일반 모드의 Header 밖 SW 부품은 반드시 `<SWTheme>` 안 |
|
||||
| OrgChart | Core가 자기 open Shadow DOM에만 CSS 로드. 호스트 CSS selector는 안쪽에 닿지 않고 **Custom Property 상속만** 통과 | 호스트 class로 카드 모양을 바꾸려 하지 않음 |
|
||||
|
||||
혼합 규칙:
|
||||
|
||||
1. 영역마다 하나의 패키지를 정하고 그 영역의 신규 UI는 그 패키지의 토큰만 읽습니다. Web 토큰(`--hm-sem-*`)을 SW 영역에, SW 토큰(`--hm-sw-*`)을 Web 영역에 쓰지 않습니다. OrgChart 내부는 `--hm-orgchart-*`만 씁니다.
|
||||
2. 다른 패키지 컴포넌트는 **문서에 허용된 지점에서만** 씁니다.
|
||||
- SW `SWPopup`의 `children` 안 Web 컨트롤(SW 카탈로그가 허용, 예: Popup 하단 `Button`)
|
||||
- SW 일반 모드 `SWPopup`의 `children` 안 Web 컨트롤(SW 카탈로그가 허용, 예: Popup 하단 `Button`)
|
||||
- SW 뷰어 모드 `SWViewerPanel`의 `children` 안 Web 컨트롤 — `SWViewer*` 컨트롤로 안 될 때만(SW `AI_USAGE.md` §0.4)
|
||||
- OrgChart Full Page의 바깥 레이아웃 = Web(또는 요청된 패키지)
|
||||
- OrgChart React의 직원 팝업 = 선택 `@hm-design/org-chart-react/hm-dialog`(Web `Dialog`, Web Theme CSS 필요)
|
||||
3. 패키지 class(`hm-sw-*`, `hm-orgchart-*`, Web `data-slot`)를 소비 코드에서 덮어쓰지 않습니다. 배치는 `className`·`style`과 소비 프로젝트 class로 합니다.
|
||||
4. **Web + SW를 한 문서에 함께 쓰면** Web의 전역 base(위 표)가 SW 화면에도 적용됩니다. SW는 자기 범위에서 버튼 등을 초기화하지만 이 조합의 시각 결과는 패키지에서 검증된 적이 없습니다(NOT VERIFIED). 이 조합이면 브라우저에서 SW 부품의 글꼴·테두리·배경을 직접 확인하고 차이를 보고합니다. 가능하면 Web CSS가 없는 SW 전용 화면(별도 entry)으로 분리합니다.
|
||||
5. Web Scoped Theme(`[data-hm-theme]`)는 body Portal(Select·Popover·DatePicker 팝업)에 전달되지 않습니다. Web 영역만 다른 테마로 바꾸려면 Global Theme를 쓰거나 차이를 보고합니다.
|
||||
|
||||
### SW 일반 모드 ↔ 뷰어 모드 분리
|
||||
|
||||
SW 일반 모드와 뷰어 모드는 같은 패키지·같은 CSS 파일이지만 **서로 다른 디자인**입니다. 한 화면(한 Header 영역)에는 한 모드만 씁니다.
|
||||
|
||||
1. 일반 모드 화면: `SWHeader`·개별 컨트롤·`SWPopup`·`SWHeaderPropertyPanel`·`SWToolButton`/`SWToolGroup`. `SWViewer*` 컴포넌트와 `--hm-sw-viewer-*` 토큰을 쓰지 않습니다.
|
||||
2. 뷰어 모드 화면: `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`과 뷰어 패널 컨트롤(`SWViewerSection`·`SWViewerField` …). `SWHeader`에 뷰어 메뉴를 억지로 넣거나 `SWPopup`을 뷰어처럼 재스타일하지 않습니다.
|
||||
3. 패키지가 실제로 공유하는 부분은 혼합이 아닙니다: `SWViewerPanel`은 `SWPopup` 프레임을 그대로 렌더링하고, 두 Header는 파일명·객체 수정·속성 면 토큰(`--hm-sw-header-document-*`·`object-*`·`property-*`)을 공유합니다. 소비 코드가 이 공유를 흉내 내 다른 모드 부품을 섞어도 된다는 뜻은 아닙니다.
|
||||
4. 프로그램이 두 모드를 모두 가지면 모드 전환 시 Header 컴포넌트를 바꿔 끼웁니다(파일·패널 상태는 프로그램 상태로 유지). 세부는 `@hm-design/sw/ai/AI_USAGE.md` §0과 `VIEWER.md`.
|
||||
|
||||
## 6단계. 디자인 검증
|
||||
|
||||
소비 프로젝트에서 실제로 실행한 것만 PASS로 적습니다.
|
||||
@@ -123,20 +164,22 @@
|
||||
1. Typecheck(`tsc --noEmit` 등)와 Production Build
|
||||
2. 브라우저 렌더링: 재사용한 컴포넌트가 HM 외형으로 보이는지(CSS 진입점 누락 확인), 신규 UI가 같은 토큰을 쓰는지
|
||||
3. 상태·동작: Hover / Focus(키보드) / Disabled, Popup 열기·닫기·Escape·Focus 복귀, 선택 패키지의 핵심 동작
|
||||
4. 폭: Web 390 / 768 / 1280 / 1440px, SW는 대상 창 폭(Header는 반응형 More 포함), OrgChart는 캔버스 크기·초기 Fit
|
||||
5. 혼합이면 영역 경계에서 스타일 침범이 없는지(§5)
|
||||
4. 폭: Web 390 / 768 / 1280 / 1440px, SW 일반 모드는 대상 창 폭(Header는 반응형 More 포함), SW 뷰어 모드는 대상 창 폭과 항목 `collapseBelow`·`iconOnlyBelow` 경계 전후(More 이동·아이콘만 표시), OrgChart는 캔버스 크기·초기 Fit
|
||||
5. 혼합이면 영역 경계에서 스타일 침범이 없는지, SW면 선택하지 않은 모드의 컴포넌트·토큰이 섞이지 않았는지(§5)
|
||||
6. 실행하지 못한 항목은 `NOT VERIFIED`로 남깁니다.
|
||||
|
||||
## 7단계. 결과 보고 형식
|
||||
|
||||
```md
|
||||
## HMDesign 적용 결과
|
||||
- 사용 유형: Web | SW | OrgChart(Chart Only|Full Page) | 혼합(영역별: …)
|
||||
- 사용 유형: Web | SW 일반 | SW 뷰어 | OrgChart(Chart Only|Full Page) | 혼합(영역별: …)
|
||||
- 유형·모드 판단 근거: 프로젝트 설정 | 요청 문구 "…" | 사용자 답변
|
||||
- 패키지·버전: @hm-design/ui 0.1.0, …
|
||||
- 재사용한 컴포넌트: …(Props 설정 포함)
|
||||
- 조합한 부분: …
|
||||
- AI가 새로 구현한 부분: 파일 경로 · 이유(카탈로그에 없음) · 안쪽에서 재사용한 컴포넌트
|
||||
- 적용한 디자인 토큰: --hm-… (신규 UI가 읽은 것)
|
||||
- AI 구성 값 — 디자인 확인 필요: 없음 | 속성 · 값 · 이유(4단계 ③)
|
||||
- 카탈로그와 .d.ts 차이: 없음 | …
|
||||
- 검증: Typecheck PASS · Build PASS · 브라우저(폭/상태) … · NOT VERIFIED: …
|
||||
- 제안(구현하지 않음): …
|
||||
@@ -161,9 +204,14 @@
|
||||
import { Button, Card, CardContent, FilterBar, FilterBarActions, FilterBarSearch, PageHeader, PageHeaderContent, PageHeaderTitle } from "@hm-design/ui"
|
||||
```
|
||||
|
||||
### 예시 B — SW 뷰어
|
||||
### 예시 B0 — "HMDesign SW로 화면을 만들어 주세요" (모드 미지정)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/sw/ai/` → COMPOSITION_PATTERNS "6. 파일 열기 + 도구 막대", 예제 `ai/examples/ExampleF-ViewerToolbar.tsx`
|
||||
- 유형은 SW로 확정, 모드 근거가 없으므로 코드 작성 전에 1단계 4번의 모드 질문만 합니다. 답에 따라 B1 또는 B2로 진행합니다.
|
||||
- 소비 프로젝트 설정이 `HMDesign 사용 유형: SW 일반` 또는 `SW 뷰어`이면 묻지 않고 바로 B1/B2입니다.
|
||||
|
||||
### 예시 B1 — SW 일반 모드 (편집 Header + 도구 막대 + 설정 Popup)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/sw/ai/` → AI_USAGE §0(일반 모드) → COMPOSITION_PATTERNS "6. 파일 열기 + 도구 막대", 예제 `ai/examples/ExampleF-ViewerToolbar.tsx`(파일 이름의 Viewer는 과거 명칭이며 일반 모드 `SWHeader` 예제)
|
||||
- 재사용: `SWHeader`(`documentOpenPlacement="header"`, `controls`, `tools`), `SWToolGroup` + `SWToolButton`(Model/Layout 탭, Fit 등), `SWPopup` + `SWPopupSection` + `SWPopupRow` + `SWHeaderInput`(설정 Popup)
|
||||
- 신규: SW에 없는 기능(예: 검색) → 소비 프로젝트 컴포넌트, `<SWTheme>` 안, `--hm-sw-header-*` 토큰, 안쪽 입력은 `SWHeaderInput`(예제 `ExampleD-SearchExtension.tsx`)
|
||||
|
||||
@@ -172,6 +220,18 @@ import { SWHeader, SWPopup, SWTheme, SWToolButton, SWToolGroup } from "@hm-desig
|
||||
import "@hm-design/sw/styles.css"
|
||||
```
|
||||
|
||||
### 예시 B2 — SW 뷰어 모드 (뷰어 Header + 메뉴 + 패널)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/sw/ai/` → AI_USAGE §0(뷰어 모드) → `VIEWER.md`, 예제 `ai/examples/ExampleH-ViewerMode.tsx`
|
||||
- 재사용: `SWViewerHeader`(`groups` 데이터: `button`·`toggle`·`menu`·`tabs`·`switch`·`custom` 항목, `onCommand`, `trailing`에 `SWViewerStatus`·`SWViewerHeaderButton`), Dropdown은 `type: "menu"` 항목의 `entries`(단독·우클릭은 `SWViewerMenu`), 팝업은 `SWViewerPanel` + `SWViewerSection`·`SWViewerField`·`SWViewerSwitch`·`SWViewerSlider`·`SWViewerInput`·`SWViewerButton`
|
||||
- 신규: 뷰어에 없는 패널 콘텐츠 → 소비 프로젝트 컴포넌트를 `SWViewerPanel`의 `children`에, 안쪽은 `SWViewerField` + `SWViewerInput` 등, 외형은 `--hm-sw-viewer-*` 토큰
|
||||
- 하지 않음: `SWHeader`·`SWPopup`을 뷰어 화면에 섞기, 로고가 없다고 임의 문자·아이콘 넣기, 연결할 명령이 없는 메뉴를 가짜 동작으로 만들기(제외 또는 `disabled` + 미연결 보고)
|
||||
|
||||
```tsx
|
||||
import { SWViewerHeader, SWViewerPanel, SWViewerSection, SWViewerField, SWViewerSwitch, type SWViewerHeaderGroup } from "@hm-design/sw"
|
||||
import "@hm-design/sw/styles.css"
|
||||
```
|
||||
|
||||
### 예시 C — 조직도만 (Chart Only)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/org-chart/ai/` → COMPOSITION_PATTERNS "1. Chart Only"
|
||||
@@ -198,7 +258,7 @@ import coreUrl from "@hm-design/org-chart/style.css?url"
|
||||
|
||||
AI 코딩 도구는 보통 **프로젝트 루트의** `AGENTS.md`(Codex 등)·`CLAUDE.md`(Claude Code)·도구별 규칙 파일만 자동으로 읽고 `node_modules`는 읽지 않습니다. 패키지 설치만으로 지침이 자동 적용되지는 않으므로 소비 프로젝트에서 한 번 연결합니다.
|
||||
|
||||
1. 패키지에 들어 있는 `ai/AGENTS_SNIPPET.md`를 루트 `AGENTS.md`(없으면 새로 만듦)에 붙여 넣고 `HMDesign 사용 유형:` 줄을 프로젝트에 맞게 고칩니다. 정하지 않았으면 그 줄을 지워 AI가 1단계에서 묻게 합니다.
|
||||
1. 패키지에 들어 있는 `ai/AGENTS_SNIPPET.md`를 루트 `AGENTS.md`(없으면 새로 만듦)에 붙여 넣고 `HMDesign 사용 유형:` 줄을 프로젝트에 맞게 고칩니다. 값은 `Web` / `SW 일반` / `SW 뷰어` / `OrgChart` / `혼합(영역별: 예 "페이지 = Web, 중앙 = OrgChart")` 중 하나입니다. SW 프로젝트면 모드까지 적어야 AI가 모드를 다시 묻지 않습니다(`SW`만 적으면 모드를 묻습니다). 정하지 않았으면 그 줄을 지워 AI가 1단계에서 묻게 합니다.
|
||||
```bash
|
||||
cat node_modules/@hm-design/ui/ai/AGENTS_SNIPPET.md >> AGENTS.md
|
||||
```
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# @hm-design/org-chart-react — AI 코딩 도구 사용 안내
|
||||
|
||||
먼저 [AI_GUIDE.md](./AI_GUIDE.md)(공통 1~7단계)를 읽습니다. 이 패키지는 OrgChart Core의 **React 수명주기 어댑터**일 뿐이며 자체 디자인·레이아웃이 없습니다. OrgChart 작업 규칙·API·디자인은 Core 패키지의 `ai/` 폴더가 기준입니다.
|
||||
먼저 [AI_GUIDE.md](./AI_GUIDE.md)(공통 1~7단계)를 읽습니다. 이 패키지는 OrgChart Core의 **React 수명주기 어댑터**일 뿐이며 자체 디자인·레이아웃이 없습니다. 사용 유형은 공통 체계(1 Web / 2 SW 일반·뷰어 / 3 OrgChart / 4 혼합)를 따르며 이 패키지는 3 OrgChart 또는 혼합의 조직도 영역에서 씁니다. OrgChart 작업 규칙·API·디자인·없는 UI 처리 3단계는 Core 패키지의 `ai/` 폴더가 기준이며 여기에 반복하지 않습니다.
|
||||
|
||||
| 읽을 문서 | 설치 후 위치 |
|
||||
|---|---|
|
||||
| OrgChart 작업 순서·생성 방식(Chart Only / Full Page)·데이터 규칙 | `node_modules/@hm-design/org-chart/ai/AI_USAGE.md` |
|
||||
| 사용 유형·혼합 규칙, 생성 방식(Chart Only / Full Page), 작업 순서, 데이터 규칙 | `node_modules/@hm-design/org-chart/ai/AI_USAGE.md` |
|
||||
| React `OrgChart` Props 전체 + Core API | `node_modules/@hm-design/org-chart/ai/COMPONENT_CATALOG.md` §1 |
|
||||
| 디자인·CSS 입력 | `node_modules/@hm-design/org-chart/ai/DESIGN_RULES.md` |
|
||||
| React·Vanilla 조합 예시 | `node_modules/@hm-design/org-chart/ai/COMPOSITION_PATTERNS.md` |
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
## HMDesign 디자인 시스템
|
||||
|
||||
<!-- HMDesign 패키지의 ai/AGENTS_SNIPPET.md에서 복사. 아래 "사용 유형"을 프로젝트에 맞게 고치거나, 정하지 않았으면 그 줄을 지운다. -->
|
||||
<!-- HMDesign 패키지의 ai/AGENTS_SNIPPET.md에서 복사. 아래 "사용 유형"을 하나로 고치거나(SW는 모드까지: SW 일반 / SW 뷰어), 정하지 않았으면 그 줄을 지운다. -->
|
||||
|
||||
HMDesign 사용 유형: Web | SW | OrgChart | 혼합(영역별로 적기)
|
||||
HMDesign 사용 유형: Web | SW 일반 | SW 뷰어 | OrgChart | 혼합(영역별로 적기, SW 영역은 모드까지)
|
||||
|
||||
화면·컴포넌트를 구현하거나 수정하기 전에 다음을 지킨다.
|
||||
|
||||
1. 설치된 HMDesign 패키지의 공통 가이드를 먼저 읽는다: `node_modules/@hm-design/<설치된 패키지>/ai/AI_GUIDE.md` (`ui`, `sw`, `org-chart`, `org-chart-react` 중 아무 사본이나 내용이 같다).
|
||||
2. 위 "사용 유형"이 없고 요청으로도 정할 수 없으면 코드 작성 전에 "어떤 HMDesign 디자인 시스템을 사용하시겠습니까? 1. Web 2. SW 3. OrgChart 4. 혼합 사용"을 묻는다. 정해져 있으면 다시 묻지 않는다.
|
||||
2. 위 "사용 유형"이 없고 요청으로도 정할 수 없으면 코드 작성 전에 "어떤 HMDesign 디자인 시스템을 사용하시겠습니까? 1. Web 2. SW (일반 모드 / 뷰어 모드) 3. OrgChart 4. 혼합 사용"을 묻는다. SW인데 모드(일반/뷰어)가 불명확하면 "SW 화면을 어떤 모드로 만들까요? 1. SW 일반 모드 2. SW 뷰어 모드"를 묻는다(근거는 `@hm-design/sw/ai/AI_USAGE.md` §0). 정해져 있으면 다시 묻지 않는다.
|
||||
3. 선택한 패키지의 `ai/AI_USAGE.md` → `COMPONENT_CATALOG.md` → `DESIGN_RULES.md` → `COMPOSITION_PATTERNS.md` 순으로 필요한 절을 읽는다.
|
||||
- Web: `node_modules/@hm-design/ui/ai/`
|
||||
- SW: `node_modules/@hm-design/sw/ai/`
|
||||
- SW: `node_modules/@hm-design/sw/ai/` (뷰어 모드는 `AI_USAGE.md` §0 다음 `VIEWER.md`)
|
||||
- OrgChart: `node_modules/@hm-design/org-chart/ai/` (React는 `node_modules/@hm-design/org-chart-react/ai/AI_USAGE.md`도)
|
||||
4. 기존 컴포넌트 → Props → 조합 → (없는 부분만) 패키지 토큰으로 신규 구현 순서를 지킨다. 패키지 파일 수정·내부 경로 import·구현 복사·새 디자인 값 생성은 하지 않는다.
|
||||
5. Web / SW / OrgChart 스타일을 영역별로 분리하고, 완료 후 AI_GUIDE의 결과 보고 형식으로 재사용·신규·토큰·검증·NOT VERIFIED를 보고한다.
|
||||
4. 선택한 유형·모드 안에서 기존 컴포넌트 → Props → 조합 → (없는 부분만) 그 모드의 토큰·스타일로 신규 → (참고 값도 없으면) HMDesign 공통 규칙과 조화되게 구성하고 "AI 구성 값"으로 보고하는 순서를 지킨다. 패키지 파일 수정·내부 경로 import·구현 복사는 하지 않는다.
|
||||
5. Web / SW 일반 / SW 뷰어 / OrgChart 스타일을 영역별로 분리하고(한 SW 화면에 일반·뷰어 컴포넌트를 섞지 않음), 완료 후 AI_GUIDE의 결과 보고 형식으로 유형·모드, 재사용·신규·토큰·AI 구성 값·검증·NOT VERIFIED를 보고한다.
|
||||
@@ -2,18 +2,19 @@
|
||||
|
||||
> 이 파일은 HMDesign 패키지(`@hm-design/ui`, `@hm-design/sw`, `@hm-design/org-chart`, `@hm-design/org-chart-react`)의 `ai/AI_GUIDE.md`에 **같은 내용으로** 들어 있습니다. 원본은 HMDesign 저장소 `docs/ai/AI_GUIDE.md`이며 패키지 사본은 `npm run sync:ai-docs`로 갱신합니다. 사본을 직접 고치지 않습니다.
|
||||
|
||||
사용자가 "HMDesign 패키지를 기준으로 화면을 구현해 주세요"처럼 요청하면 AI 코딩 도구는 이 파일의 1~6단계를 순서대로 따릅니다. 이 문서와 각 패키지의 `ai/` 문서는 실제 공개 API·CSS에서 확인한 내용만 적습니다. 여기에 없는 컴포넌트·Props·토큰은 없는 것으로 취급합니다.
|
||||
사용자가 "HMDesign 패키지를 기준으로 화면을 구현해 주세요", "HMDesign SW로 화면을 만들어 주세요"처럼 요청하면 AI 코딩 도구는 이 파일의 1~7단계를 순서대로 따릅니다. 이 문서와 각 패키지의 `ai/` 문서는 실제 공개 API·CSS에서 확인한 내용만 적습니다. 여기에 없는 컴포넌트·Props·토큰은 없는 것으로 취급합니다.
|
||||
|
||||
## 0. 읽는 순서
|
||||
|
||||
1. **이 파일**(어느 패키지의 사본이든 같음)
|
||||
2. 선택한 패키지의 `ai/AI_USAGE.md` → `ai/COMPONENT_CATALOG.md` → `ai/DESIGN_RULES.md` → `ai/COMPOSITION_PATTERNS.md`
|
||||
2. 선택한 패키지의 `ai/AI_USAGE.md` → `ai/COMPONENT_CATALOG.md` → `ai/DESIGN_RULES.md` → `ai/COMPOSITION_PATTERNS.md` (SW 뷰어 모드는 `AI_USAGE.md` §0 다음에 `ai/VIEWER.md`를 먼저 읽고 카탈로그의 뷰어 절을 봅니다)
|
||||
3. API가 의심스러우면 그 패키지의 `dist/*.d.ts`(공개 진입점에서 export되는 것만)
|
||||
|
||||
| 유형 | 패키지 | 지침 위치(설치 후) | JS 진입점 | CSS |
|
||||
|---|---|---|---|---|
|
||||
| ① Web UI | `@hm-design/ui` | `node_modules/@hm-design/ui/ai/` | `@hm-design/ui`, `@hm-design/ui/theme` | `@hm-design/ui/tailwind.css` + `@hm-design/ui/theme.css`(Tailwind CSS 4 필요), 선택 `@hm-design/ui/dashboard-status.css` |
|
||||
| ② SW UI | `@hm-design/sw` | `node_modules/@hm-design/sw/ai/` | `@hm-design/sw` | `@hm-design/sw/styles.css` |
|
||||
| ② SW UI — 일반 모드 | `@hm-design/sw` | `node_modules/@hm-design/sw/ai/` (`AI_USAGE.md` §0 모드 선택 → 일반 모드 문서) | `@hm-design/sw` | `@hm-design/sw/styles.css` |
|
||||
| ② SW UI — 뷰어 모드 | `@hm-design/sw`(같은 패키지) | `node_modules/@hm-design/sw/ai/` (`AI_USAGE.md` §0 → `VIEWER.md`) | `@hm-design/sw` | `@hm-design/sw/styles.css`(같은 파일) |
|
||||
| ③ OrgChart | `@hm-design/org-chart`(Core) + React면 `@hm-design/org-chart-react` | `node_modules/@hm-design/org-chart/ai/` (React 어댑터 안내는 `node_modules/@hm-design/org-chart-react/ai/AI_USAGE.md`) | `@hm-design/org-chart`, `@hm-design/org-chart-react`, 선택 `@hm-design/org-chart-react/hm-dialog` | `@hm-design/org-chart/engine.css`, `@hm-design/org-chart/style.css`(URL로 전달 — Shadow DOM 안에 로드) |
|
||||
| 기타 | `@hm-design/center-graphic` | AI 지침 없음. 패키지 `README.md`만 | `@hm-design/center-graphic` | 자동 import |
|
||||
|
||||
@@ -21,12 +22,19 @@
|
||||
|
||||
## 1단계. 사용 목적 확인
|
||||
|
||||
화면 구현 요청을 받으면 코드 작성 전에 **사용 유형**을 정합니다. 유형은 다음 넷이고, SW는 다시 두 모드로 나뉩니다.
|
||||
|
||||
1. Web
|
||||
2. SW — **SW 일반 모드**(편집용: `SWHeader`, `SWPopup` …) / **SW 뷰어 모드**(보기 전용: `SWViewerHeader`, `SWViewerMenu`, `SWViewerPanel` …)
|
||||
3. OrgChart
|
||||
4. 혼합 사용(영역마다 위 유형 하나)
|
||||
|
||||
다음 순서로 판단하고, **판단되면 다시 묻지 않습니다.**
|
||||
|
||||
1. 소비 프로젝트의 `AGENTS.md`·`CLAUDE.md` 등에 `HMDesign 사용 유형:` 설정이 있으면 그대로 따릅니다(§9).
|
||||
1. 소비 프로젝트의 `AGENTS.md`·`CLAUDE.md` 등에 `HMDesign 사용 유형:` 설정이 있으면 그대로 따릅니다(§9). 값은 `Web` / `SW 일반` / `SW 뷰어` / `OrgChart` / `혼합(영역별: …)`입니다. 값이 `SW`뿐이면 유형은 정해진 것이고 모드만 아래 4번으로 정합니다.
|
||||
2. 사용자 요청이 유형을 분명히 말하면 그대로 따릅니다.
|
||||
- Web: 웹 화면, 관리자·업무 화면, 목록·검색·Form, 대시보드, GNB/LNB, Dialog, Table …
|
||||
- SW: 데스크톱 SW, 뷰어, 도면·CAD, SW Header, 툴바, 레이어/색상/선스타일, 속성창·SW Popup …
|
||||
- SW: 데스크톱 SW, 도면·CAD, SW Header, 툴바, 레이어/색상/선스타일, 속성창·SW Popup, 뷰어 …
|
||||
- OrgChart: 조직도, 조직 계층·직원 카드, 조직 JSON/CSV/Excel 시각화 …
|
||||
- 둘 이상이 함께 나오면 ④ 혼합(예: "업무 화면 안에 조직도" = Web + OrgChart).
|
||||
3. 위로 정할 수 없으면 코드 작성 전에 **그대로** 묻습니다.
|
||||
@@ -34,12 +42,21 @@
|
||||
> 어떤 HMDesign 디자인 시스템을 사용하시겠습니까?
|
||||
>
|
||||
> 1. Web
|
||||
> 2. SW
|
||||
> 2. SW (일반 모드 / 뷰어 모드)
|
||||
> 3. OrgChart
|
||||
> 4. 혼합 사용
|
||||
|
||||
- `package.json`에 설치된 패키지가 하나뿐이어도 그것만으로 유형을 확정하지 않습니다(설치가 덜 된 상태일 수 있음). 요청 내용과 맞을 때만 근거로 씁니다.
|
||||
- 혼합을 고르면 영역별 패키지(예: "페이지 = Web, 가운데 영역 = OrgChart")를 확인합니다.
|
||||
4. **SW가 정해졌거나 포함됐는데 모드가 불명확하면** 코드 작성 전에 묻습니다. 설정 값(`SW 일반`/`SW 뷰어`)이나 요청이 모드를 분명히 말하면 묻지 않습니다. 판단 근거와 질문 문구는 `@hm-design/sw/ai/AI_USAGE.md` §0을 따릅니다. 유형 질문이 필요한 경우에는 같은 메시지에서 2번 선택 시의 모드도 함께 묻습니다(한 번에 끝냄).
|
||||
|
||||
> SW 화면을 어떤 모드로 만들까요?
|
||||
>
|
||||
> 1. SW 일반 모드 — 편집용 Header(`SWHeader`)·속성창·SW Popup
|
||||
> 2. SW 뷰어 모드 — 보기 전용 Header(`SWViewerHeader`)·뷰어 메뉴·뷰어 패널
|
||||
|
||||
- "HMDesign SW로 화면을 만들어 주세요"처럼 SW만 말하고 모드 근거가 없으면 유형은 SW로 확정하고 4번의 모드 질문만 합니다.
|
||||
- `package.json`에 설치된 패키지가 하나뿐이어도 그것만으로 유형을 확정하지 않습니다(설치가 덜 된 상태일 수 있음). 요청 내용과 맞을 때만 근거로 씁니다. SW 모드도 같은 패키지이므로 설치 상태로는 판단하지 않습니다.
|
||||
- 정해진 유형·모드는 결과 보고(7단계)에 적고, 작업 중에 다른 유형·모드의 컴포넌트·스타일을 임의로 섞지 않습니다(5단계).
|
||||
- 혼합을 고르면 영역별 패키지(예: "페이지 = Web, 가운데 영역 = OrgChart")를 확인합니다. SW 영역이 있으면 그 영역의 모드(일반/뷰어)까지 정합니다.
|
||||
- **OrgChart가 포함되고 생성 방식이 없으면** 같은 메시지에서 다음도 묻습니다(이미 말했으면 묻지 않음): "조직도만 기존 페이지에 삽입할까요(Chart Only), 아니면 레이아웃까지 구성한 새 페이지 전체를 생성할까요(Full Page)?" 상세는 `@hm-design/org-chart/ai/AI_USAGE.md` §1.
|
||||
- 선택한 패키지가 설치되어 있지 않으면 설치가 필요하다고 보고합니다. 다른 HMDesign 패키지나 임의 라이브러리로 대신하지 않습니다.
|
||||
|
||||
@@ -57,8 +74,9 @@
|
||||
| 요청 항목 | 판단 | 근거(카탈로그의 실제 이름) |
|
||||
|---|---|---|
|
||||
| 예: 상단 메뉴 | 재사용 | Web `GNB` + `GNBMobileMenu` |
|
||||
| 예: 레이어 선택 | 재사용 | SW `SWHeaderLayerMenu` |
|
||||
| 예: 검색 상자(SW) | 신규 | SW 카탈로그에 없음 → `SWHeaderInput` 재사용 + SW 토큰 |
|
||||
| 예: 레이어 선택(SW 일반) | 재사용 | SW `SWHeaderLayerMenu` |
|
||||
| 예: 상단 메뉴(SW 뷰어) | Props 설정 | SW `SWViewerHeader`의 `groups` |
|
||||
| 예: 검색 상자(SW 일반) | 신규 | SW 카탈로그에 없음 → `SWHeaderInput` 재사용 + 일반 모드 토큰 |
|
||||
|
||||
판단 값은 **재사용**(그대로) / **Props 설정**(기존 Variant·Props) / **조합**(기존 컴포넌트 배치) / **신규**(소비 프로젝트에 최소 구현) 중 하나입니다.
|
||||
|
||||
@@ -69,31 +87,44 @@
|
||||
1. 선택 패키지의 기존 컴포넌트·Pattern을 그대로 사용
|
||||
2. 기존 Variant / Props / Callback으로 해결
|
||||
3. 기존 컴포넌트 조합(배치용 CSS만 소비 프로젝트에 작성)
|
||||
4. 조합으로 안 되는 부분만 **소비 프로젝트에** 새로 구현 — 패키지 토큰만 읽고, 안쪽에 기존 컴포넌트를 재사용
|
||||
4. 조합으로 안 되는 부분만 **소비 프로젝트에** 새로 구현 — 아래 "없는 컴포넌트 처리 3단계"
|
||||
|
||||
모든 단계는 **1단계에서 정한 유형·모드 안에서만** 찾습니다. SW 뷰어 모드는 뷰어 컴포넌트(`SWViewer*`)를, SW 일반 모드는 일반 컴포넌트(`SWHeader`·`SWPopup` …)를 먼저 씁니다. 다른 모드에 같은 역할의 컴포넌트가 있어도 가져오지 않습니다.
|
||||
|
||||
### 없는 컴포넌트 처리 3단계
|
||||
|
||||
| 단계 | 조건 | 할 일 | 결과 보고 |
|
||||
|---|---|---|---|
|
||||
| ① 재사용 | 선택 유형·모드에 컴포넌트·Variant·Props·조합이 있음 | 그대로 사용(위 1~3) | 재사용 / Props 설정 / 조합 |
|
||||
| ② 같은 모드 스타일로 신규 | 컴포넌트는 없지만 그 모드의 토큰·확인값·상태 표현이 있음 | 소비 프로젝트에 최소 구현. 그 유형·모드의 토큰과 `DESIGN_RULES.md`(SW 뷰어는 `VIEWER.md`도)의 크기·색·상태 표현만 읽고, 안쪽에는 그 모드의 공개 컴포넌트를 재사용 | 신규 · 읽은 토큰 목록 |
|
||||
| ③ HMDesign과 조화되는 새 스타일 | ②로 참고할 토큰·확인값이 없음 | HMDesign 공통 규칙(아래)과 선택 유형·모드의 가장 가까운 토큰을 기준으로 새 스타일을 구성 | 신규 · **"AI 구성 값 — 디자인 확인 필요"** 목록(속성·값·이유) |
|
||||
|
||||
- 토큰·확인값이 있으면 ②에서 반드시 그것을 씁니다. ③은 참고할 값이 정말 없을 때만이며, ③에서 만든 값은 확정 디자인이 아니라 확인 대상입니다. 화면 인상을 크게 바꾸는 값(주요 색·Header 높이 등)이 필요하면 구현 전에 사용자에게 먼저 확인합니다.
|
||||
- 유형·모드별 구체 토큰과 예는 각 패키지 `ai/AI_USAGE.md`에 있습니다.
|
||||
|
||||
규칙:
|
||||
|
||||
- `node_modules` 안 패키지 파일을 수정하지 않습니다. 패키지 `dist` 구현이나 내부 CSS 블록을 복사해 같은 컴포넌트를 다시 만들지 않습니다.
|
||||
- 이미 있는 컴포넌트와 같은 역할의 컴포넌트를 새로 만들지 않습니다(예: Web에 `Dialog`가 있는데 자체 Modal 작성 금지).
|
||||
- 새 디자인 값을 만들지 않습니다. 색·크기·간격·radius·그림자는 각 패키지 `DESIGN_RULES.md`의 토큰·확인값만 씁니다. 값이 없으면 추측하지 말고 사용자에게 확인합니다.
|
||||
- 토큰·확인값이 있는 속성에 새 값을 만들지 않습니다. 색·크기·간격·radius·그림자는 각 패키지 `DESIGN_RULES.md`(SW 뷰어는 `VIEWER.md`도)의 토큰·확인값을 씁니다. 값이 없을 때만 위 ③으로 구성하고 "AI 구성 값"으로 보고합니다(추측한 값을 확정값처럼 쓰지 않음).
|
||||
- 공통: Font Weight는 400 / 500 / 700만 씁니다(600 없음). Light/Dark 분기를 만들지 않습니다. 새 컴포넌트 CSS에 `html`·`body`·`*` 전역 규칙을 넣지 않습니다. 새 class는 소비 프로젝트 접두사(예: `app-`)를 씁니다.
|
||||
- 요청에 없는 메뉴·통계·설명·다운로드·외부 API·AI 입력 UI를 추가하지 않습니다. 필요해 보이면 제안으로만 보고합니다.
|
||||
|
||||
### 없는 UI를 같은 스타일로 만들 때 확인할 항목
|
||||
|
||||
신규 항목마다 아래를 선택 패키지 `DESIGN_RULES.md`에서 찾아 그대로 적용합니다. 찾을 수 없는 항목은 "값 없음 — 사용자 확인 필요"로 보고합니다.
|
||||
신규 항목마다 아래를 선택 유형·모드의 문서에서 찾아 그대로 적용합니다(②). 찾을 수 없는 항목은 ③으로 구성하고 "AI 구성 값 — 디자인 확인 필요"로 보고합니다.
|
||||
|
||||
| 항목 | Web(`@hm-design/ui`) | SW(`@hm-design/sw`) | OrgChart |
|
||||
|---|---|---|---|
|
||||
| 토큰·CSS 변수 | `--hm-sem-*`, `--hm-color-*`, `--hm-radius-*`(`:root`) | `--hm-sw-header-*`, `--hm-sw-property-*`(`SWTheme` 범위) | `--hm-orgchart-*` 공개 입력(Shadow DOM 상속) |
|
||||
| 색·Typography | DESIGN_RULES §2·§3 | DESIGN_RULES §2·§3 | DESIGN_RULES §2·§3 |
|
||||
| 크기·여백 | DESIGN_RULES §4 | DESIGN_RULES §1 | 카드·간격 변경 금지(승인 디자인) |
|
||||
| Border·Radius·배경·그림자 | DESIGN_RULES §2·§4 | DESIGN_RULES §2·§8 | 공개 입력만 |
|
||||
| 아이콘 | `lucide-react`(패키지 의존성) | 패키지 내장 SVG만, 새 아이콘은 사용자 제공 | Core 내장 |
|
||||
| 스크롤바 | `ScrollArea`(Radix), DESIGN_RULES §6 | 전용 디자인 없음 — 브라우저 기본(AI_USAGE §2) | Core 내부 Zoom/Pan |
|
||||
| Hover / Active / Focus / Disabled | DESIGN_RULES §5 | DESIGN_RULES §4 | Core 내장 |
|
||||
| Popup·Panel | `Dialog`·`AlertDialog`·`Sheet`·`Drawer`·`Popover` | `SWPopup` + `SWPopupSection`/`SWPopupRow` | Core 팝업 / HM Dialog / 어댑터 |
|
||||
| 동작·키보드 | Radix 동작 유지 | 카탈로그 "공통 키보드" | Core 키보드(Pan, Alt+M 이동 등) |
|
||||
| 항목 | Web(`@hm-design/ui`) | SW 일반 모드(`@hm-design/sw`) | SW 뷰어 모드(`@hm-design/sw`) | OrgChart |
|
||||
|---|---|---|---|---|
|
||||
| 토큰·CSS 변수 | `--hm-sem-*`, `--hm-color-*`, `--hm-radius-*`(`:root`) | `--hm-sw-header-*`, `--hm-sw-property-*`(`SWTheme` 범위) | `--hm-sw-viewer-*` + 두 Header가 공유하는 `--hm-sw-header-document-*`·`object-*`·`property-*`(SW 범위) | `--hm-orgchart-*` 공개 입력(Shadow DOM 상속) |
|
||||
| 색·Typography | DESIGN_RULES §2·§3 | DESIGN_RULES §2·§3 | VIEWER.md `SWViewerHeader`·디자인 변경 절 | DESIGN_RULES §2·§3 |
|
||||
| 크기·여백 | DESIGN_RULES §4 | DESIGN_RULES §1 | VIEWER.md 디자인 변경 절(52px Header 등 실측값) | 카드·간격 변경 금지(승인 디자인) |
|
||||
| Border·Radius·배경·그림자 | DESIGN_RULES §2·§4 | DESIGN_RULES §2·§8 | VIEWER.md `SWViewerPanel` 절(프레임은 SWPopup과 같음) | 공개 입력만 |
|
||||
| 아이콘 | `lucide-react`(패키지 의존성) | 패키지 내장 SVG만, 새 아이콘은 사용자 제공 | 프로그램 제공 16px `currentColor` 아이콘, 외곽선은 `SWViewerIcon` | Core 내장 |
|
||||
| 스크롤바 | `ScrollArea`(Radix), DESIGN_RULES §6 | 전용 디자인 없음 — 브라우저 기본(AI_USAGE §2) | 전용 디자인 없음 — 패널 본문 스크롤은 `SWViewerPanel` | Core 내부 Zoom/Pan |
|
||||
| Hover / Active / Focus / Disabled | DESIGN_RULES §5 | DESIGN_RULES §4 | VIEWER.md `SWViewerHeader` 절 상태 표현 | Core 내장 |
|
||||
| Popup·Panel | `Dialog`·`AlertDialog`·`Sheet`·`Drawer`·`Popover` | `SWPopup` + `SWPopupSection`/`SWPopupRow` | `SWViewerPanel`(+ `modal`) + `SWViewerSection`/`SWViewerField` | Core 팝업 / HM Dialog / 어댑터 |
|
||||
| 동작·키보드 | Radix 동작 유지 | 카탈로그 "공통 키보드" | VIEWER.md `SWViewerMenu`·`SWViewerPanel` 키보드 | Core 키보드(Pan, Alt+M 이동 등) |
|
||||
|
||||
## 5단계. 패키지별 디자인 분리 (혼합 사용 포함)
|
||||
|
||||
@@ -102,20 +133,30 @@
|
||||
| 패키지 | 스타일이 적용되는 범위 | 주의 |
|
||||
|---|---|---|
|
||||
| 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`(`<SWTheme>`)에만 정의. 전역 선택자 없음 | Header 밖 SW 부품은 반드시 `<SWTheme>` 안 |
|
||||
| SW(일반·뷰어 공통) | 토큰은 `.hm-sw-header`와 `.hm-sw-theme`에만 정의(뷰어 토큰 `--hm-sw-viewer-*`도 같은 범위). 전역 선택자 없음. `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`은 자기 root에 `hm-sw-theme`를 가짐 | 일반 모드의 Header 밖 SW 부품은 반드시 `<SWTheme>` 안 |
|
||||
| OrgChart | Core가 자기 open Shadow DOM에만 CSS 로드. 호스트 CSS selector는 안쪽에 닿지 않고 **Custom Property 상속만** 통과 | 호스트 class로 카드 모양을 바꾸려 하지 않음 |
|
||||
|
||||
혼합 규칙:
|
||||
|
||||
1. 영역마다 하나의 패키지를 정하고 그 영역의 신규 UI는 그 패키지의 토큰만 읽습니다. Web 토큰(`--hm-sem-*`)을 SW 영역에, SW 토큰(`--hm-sw-*`)을 Web 영역에 쓰지 않습니다. OrgChart 내부는 `--hm-orgchart-*`만 씁니다.
|
||||
2. 다른 패키지 컴포넌트는 **문서에 허용된 지점에서만** 씁니다.
|
||||
- SW `SWPopup`의 `children` 안 Web 컨트롤(SW 카탈로그가 허용, 예: Popup 하단 `Button`)
|
||||
- SW 일반 모드 `SWPopup`의 `children` 안 Web 컨트롤(SW 카탈로그가 허용, 예: Popup 하단 `Button`)
|
||||
- SW 뷰어 모드 `SWViewerPanel`의 `children` 안 Web 컨트롤 — `SWViewer*` 컨트롤로 안 될 때만(SW `AI_USAGE.md` §0.4)
|
||||
- OrgChart Full Page의 바깥 레이아웃 = Web(또는 요청된 패키지)
|
||||
- OrgChart React의 직원 팝업 = 선택 `@hm-design/org-chart-react/hm-dialog`(Web `Dialog`, Web Theme CSS 필요)
|
||||
3. 패키지 class(`hm-sw-*`, `hm-orgchart-*`, Web `data-slot`)를 소비 코드에서 덮어쓰지 않습니다. 배치는 `className`·`style`과 소비 프로젝트 class로 합니다.
|
||||
4. **Web + SW를 한 문서에 함께 쓰면** Web의 전역 base(위 표)가 SW 화면에도 적용됩니다. SW는 자기 범위에서 버튼 등을 초기화하지만 이 조합의 시각 결과는 패키지에서 검증된 적이 없습니다(NOT VERIFIED). 이 조합이면 브라우저에서 SW 부품의 글꼴·테두리·배경을 직접 확인하고 차이를 보고합니다. 가능하면 Web CSS가 없는 SW 전용 화면(별도 entry)으로 분리합니다.
|
||||
5. Web Scoped Theme(`[data-hm-theme]`)는 body Portal(Select·Popover·DatePicker 팝업)에 전달되지 않습니다. Web 영역만 다른 테마로 바꾸려면 Global Theme를 쓰거나 차이를 보고합니다.
|
||||
|
||||
### SW 일반 모드 ↔ 뷰어 모드 분리
|
||||
|
||||
SW 일반 모드와 뷰어 모드는 같은 패키지·같은 CSS 파일이지만 **서로 다른 디자인**입니다. 한 화면(한 Header 영역)에는 한 모드만 씁니다.
|
||||
|
||||
1. 일반 모드 화면: `SWHeader`·개별 컨트롤·`SWPopup`·`SWHeaderPropertyPanel`·`SWToolButton`/`SWToolGroup`. `SWViewer*` 컴포넌트와 `--hm-sw-viewer-*` 토큰을 쓰지 않습니다.
|
||||
2. 뷰어 모드 화면: `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`과 뷰어 패널 컨트롤(`SWViewerSection`·`SWViewerField` …). `SWHeader`에 뷰어 메뉴를 억지로 넣거나 `SWPopup`을 뷰어처럼 재스타일하지 않습니다.
|
||||
3. 패키지가 실제로 공유하는 부분은 혼합이 아닙니다: `SWViewerPanel`은 `SWPopup` 프레임을 그대로 렌더링하고, 두 Header는 파일명·객체 수정·속성 면 토큰(`--hm-sw-header-document-*`·`object-*`·`property-*`)을 공유합니다. 소비 코드가 이 공유를 흉내 내 다른 모드 부품을 섞어도 된다는 뜻은 아닙니다.
|
||||
4. 프로그램이 두 모드를 모두 가지면 모드 전환 시 Header 컴포넌트를 바꿔 끼웁니다(파일·패널 상태는 프로그램 상태로 유지). 세부는 `@hm-design/sw/ai/AI_USAGE.md` §0과 `VIEWER.md`.
|
||||
|
||||
## 6단계. 디자인 검증
|
||||
|
||||
소비 프로젝트에서 실제로 실행한 것만 PASS로 적습니다.
|
||||
@@ -123,20 +164,22 @@
|
||||
1. Typecheck(`tsc --noEmit` 등)와 Production Build
|
||||
2. 브라우저 렌더링: 재사용한 컴포넌트가 HM 외형으로 보이는지(CSS 진입점 누락 확인), 신규 UI가 같은 토큰을 쓰는지
|
||||
3. 상태·동작: Hover / Focus(키보드) / Disabled, Popup 열기·닫기·Escape·Focus 복귀, 선택 패키지의 핵심 동작
|
||||
4. 폭: Web 390 / 768 / 1280 / 1440px, SW는 대상 창 폭(Header는 반응형 More 포함), OrgChart는 캔버스 크기·초기 Fit
|
||||
5. 혼합이면 영역 경계에서 스타일 침범이 없는지(§5)
|
||||
4. 폭: Web 390 / 768 / 1280 / 1440px, SW 일반 모드는 대상 창 폭(Header는 반응형 More 포함), SW 뷰어 모드는 대상 창 폭과 항목 `collapseBelow`·`iconOnlyBelow` 경계 전후(More 이동·아이콘만 표시), OrgChart는 캔버스 크기·초기 Fit
|
||||
5. 혼합이면 영역 경계에서 스타일 침범이 없는지, SW면 선택하지 않은 모드의 컴포넌트·토큰이 섞이지 않았는지(§5)
|
||||
6. 실행하지 못한 항목은 `NOT VERIFIED`로 남깁니다.
|
||||
|
||||
## 7단계. 결과 보고 형식
|
||||
|
||||
```md
|
||||
## HMDesign 적용 결과
|
||||
- 사용 유형: Web | SW | OrgChart(Chart Only|Full Page) | 혼합(영역별: …)
|
||||
- 사용 유형: Web | SW 일반 | SW 뷰어 | OrgChart(Chart Only|Full Page) | 혼합(영역별: …)
|
||||
- 유형·모드 판단 근거: 프로젝트 설정 | 요청 문구 "…" | 사용자 답변
|
||||
- 패키지·버전: @hm-design/ui 0.1.0, …
|
||||
- 재사용한 컴포넌트: …(Props 설정 포함)
|
||||
- 조합한 부분: …
|
||||
- AI가 새로 구현한 부분: 파일 경로 · 이유(카탈로그에 없음) · 안쪽에서 재사용한 컴포넌트
|
||||
- 적용한 디자인 토큰: --hm-… (신규 UI가 읽은 것)
|
||||
- AI 구성 값 — 디자인 확인 필요: 없음 | 속성 · 값 · 이유(4단계 ③)
|
||||
- 카탈로그와 .d.ts 차이: 없음 | …
|
||||
- 검증: Typecheck PASS · Build PASS · 브라우저(폭/상태) … · NOT VERIFIED: …
|
||||
- 제안(구현하지 않음): …
|
||||
@@ -161,9 +204,14 @@
|
||||
import { Button, Card, CardContent, FilterBar, FilterBarActions, FilterBarSearch, PageHeader, PageHeaderContent, PageHeaderTitle } from "@hm-design/ui"
|
||||
```
|
||||
|
||||
### 예시 B — SW 뷰어
|
||||
### 예시 B0 — "HMDesign SW로 화면을 만들어 주세요" (모드 미지정)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/sw/ai/` → COMPOSITION_PATTERNS "6. 파일 열기 + 도구 막대", 예제 `ai/examples/ExampleF-ViewerToolbar.tsx`
|
||||
- 유형은 SW로 확정, 모드 근거가 없으므로 코드 작성 전에 1단계 4번의 모드 질문만 합니다. 답에 따라 B1 또는 B2로 진행합니다.
|
||||
- 소비 프로젝트 설정이 `HMDesign 사용 유형: SW 일반` 또는 `SW 뷰어`이면 묻지 않고 바로 B1/B2입니다.
|
||||
|
||||
### 예시 B1 — SW 일반 모드 (편집 Header + 도구 막대 + 설정 Popup)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/sw/ai/` → AI_USAGE §0(일반 모드) → COMPOSITION_PATTERNS "6. 파일 열기 + 도구 막대", 예제 `ai/examples/ExampleF-ViewerToolbar.tsx`(파일 이름의 Viewer는 과거 명칭이며 일반 모드 `SWHeader` 예제)
|
||||
- 재사용: `SWHeader`(`documentOpenPlacement="header"`, `controls`, `tools`), `SWToolGroup` + `SWToolButton`(Model/Layout 탭, Fit 등), `SWPopup` + `SWPopupSection` + `SWPopupRow` + `SWHeaderInput`(설정 Popup)
|
||||
- 신규: SW에 없는 기능(예: 검색) → 소비 프로젝트 컴포넌트, `<SWTheme>` 안, `--hm-sw-header-*` 토큰, 안쪽 입력은 `SWHeaderInput`(예제 `ExampleD-SearchExtension.tsx`)
|
||||
|
||||
@@ -172,6 +220,18 @@ import { SWHeader, SWPopup, SWTheme, SWToolButton, SWToolGroup } from "@hm-desig
|
||||
import "@hm-design/sw/styles.css"
|
||||
```
|
||||
|
||||
### 예시 B2 — SW 뷰어 모드 (뷰어 Header + 메뉴 + 패널)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/sw/ai/` → AI_USAGE §0(뷰어 모드) → `VIEWER.md`, 예제 `ai/examples/ExampleH-ViewerMode.tsx`
|
||||
- 재사용: `SWViewerHeader`(`groups` 데이터: `button`·`toggle`·`menu`·`tabs`·`switch`·`custom` 항목, `onCommand`, `trailing`에 `SWViewerStatus`·`SWViewerHeaderButton`), Dropdown은 `type: "menu"` 항목의 `entries`(단독·우클릭은 `SWViewerMenu`), 팝업은 `SWViewerPanel` + `SWViewerSection`·`SWViewerField`·`SWViewerSwitch`·`SWViewerSlider`·`SWViewerInput`·`SWViewerButton`
|
||||
- 신규: 뷰어에 없는 패널 콘텐츠 → 소비 프로젝트 컴포넌트를 `SWViewerPanel`의 `children`에, 안쪽은 `SWViewerField` + `SWViewerInput` 등, 외형은 `--hm-sw-viewer-*` 토큰
|
||||
- 하지 않음: `SWHeader`·`SWPopup`을 뷰어 화면에 섞기, 로고가 없다고 임의 문자·아이콘 넣기, 연결할 명령이 없는 메뉴를 가짜 동작으로 만들기(제외 또는 `disabled` + 미연결 보고)
|
||||
|
||||
```tsx
|
||||
import { SWViewerHeader, SWViewerPanel, SWViewerSection, SWViewerField, SWViewerSwitch, type SWViewerHeaderGroup } from "@hm-design/sw"
|
||||
import "@hm-design/sw/styles.css"
|
||||
```
|
||||
|
||||
### 예시 C — 조직도만 (Chart Only)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/org-chart/ai/` → COMPOSITION_PATTERNS "1. Chart Only"
|
||||
@@ -198,7 +258,7 @@ import coreUrl from "@hm-design/org-chart/style.css?url"
|
||||
|
||||
AI 코딩 도구는 보통 **프로젝트 루트의** `AGENTS.md`(Codex 등)·`CLAUDE.md`(Claude Code)·도구별 규칙 파일만 자동으로 읽고 `node_modules`는 읽지 않습니다. 패키지 설치만으로 지침이 자동 적용되지는 않으므로 소비 프로젝트에서 한 번 연결합니다.
|
||||
|
||||
1. 패키지에 들어 있는 `ai/AGENTS_SNIPPET.md`를 루트 `AGENTS.md`(없으면 새로 만듦)에 붙여 넣고 `HMDesign 사용 유형:` 줄을 프로젝트에 맞게 고칩니다. 정하지 않았으면 그 줄을 지워 AI가 1단계에서 묻게 합니다.
|
||||
1. 패키지에 들어 있는 `ai/AGENTS_SNIPPET.md`를 루트 `AGENTS.md`(없으면 새로 만듦)에 붙여 넣고 `HMDesign 사용 유형:` 줄을 프로젝트에 맞게 고칩니다. 값은 `Web` / `SW 일반` / `SW 뷰어` / `OrgChart` / `혼합(영역별: 예 "페이지 = Web, 중앙 = OrgChart")` 중 하나입니다. SW 프로젝트면 모드까지 적어야 AI가 모드를 다시 묻지 않습니다(`SW`만 적으면 모드를 묻습니다). 정하지 않았으면 그 줄을 지워 AI가 1단계에서 묻게 합니다.
|
||||
```bash
|
||||
cat node_modules/@hm-design/ui/ai/AGENTS_SNIPPET.md >> AGENTS.md
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# @hm-design/org-chart — AI 코딩 도구 사용 안내 (OrgChart)
|
||||
|
||||
먼저 [AI_GUIDE.md](./AI_GUIDE.md)(공통 1~7단계)를 읽고 사용 유형이 **OrgChart** 또는 OrgChart가 포함된 혼합일 때 이 폴더를 씁니다. 이 폴더(`node_modules/@hm-design/org-chart/ai/`)는 Core `@hm-design/org-chart` 0.1.0과 React 어댑터 `@hm-design/org-chart-react` 0.1.0의 공개 Export·타입에서 확인한 내용만 적습니다.
|
||||
먼저 [AI_GUIDE.md](./AI_GUIDE.md)(공통 1~7단계)를 읽고 사용 유형이 **3 OrgChart** 또는 OrgChart가 포함된 **4 혼합**일 때 이 폴더를 씁니다. 이 폴더(`node_modules/@hm-design/org-chart/ai/`)는 Core `@hm-design/org-chart` 0.1.0과 React 어댑터 `@hm-design/org-chart-react` 0.1.0의 공개 Export·타입에서 확인한 내용만 적습니다.
|
||||
|
||||
| 문서 | 내용 |
|
||||
|---|---|
|
||||
@@ -8,9 +8,22 @@
|
||||
| [DESIGN_RULES.md](./DESIGN_RULES.md) | 승인된 기본 디자인, 회사 컬러, 공개 CSS 입력 `--hm-orgchart-*`, 변경 가능/불가 경계 |
|
||||
| [COMPOSITION_PATTERNS.md](./COMPOSITION_PATTERNS.md) | Chart Only(React·Vanilla), Full Page(Web + OrgChart), 데이터 생성·변환, 팝업 선택 |
|
||||
|
||||
## 0. 사용 유형 (공통 체계)
|
||||
|
||||
사용 유형은 **1 Web / 2 SW(SW 일반 모드 · SW 뷰어 모드) / 3 OrgChart / 4 혼합**이고, 소비 프로젝트 설정 값은 `HMDesign 사용 유형: Web | SW 일반 | SW 뷰어 | OrgChart | 혼합(영역별)`입니다. 확인 순서·질문 문구·설정 방법은 [AI_GUIDE.md](./AI_GUIDE.md)가 정의하며 여기서 반복하지 않습니다. 유형·모드 사이를 임의로 섞지 않고, 이 패키지의 컴포넌트·CSS 원본은 수정하지 않습니다.
|
||||
|
||||
- **OrgChart 선택 시** 아래 §1의 Chart Only / Full Page 질문은 유형 질문과 **같은 메시지에서 한 번만** 묻습니다. 유형·생성 방식이 이미 정해졌으면 묻지 않습니다.
|
||||
- **혼합:** 영역별로 패키지를 나눕니다. Full Page의 바깥(Page·Navigation·제목·필터)은 Web(또는 요청한 패키지), 조직도 영역은 OrgChart입니다. SW 화면 안의 조직도는 SW 영역과 OrgChart 영역을 분리하고, SW 모드 규칙은 `node_modules/@hm-design/sw/ai/` 문서를 따릅니다. 두 패키지는 서로 의존하지 않으며 **SW 화면 + 조직도 조합은 패키지에서 검증된 적이 없어 NOT VERIFIED**입니다(결과 보고에 적습니다).
|
||||
|
||||
### 없는 UI의 처리 (OrgChart 기준 3단계)
|
||||
|
||||
1. **기존 Core/React 우선:** [COMPONENT_CATALOG.md](./COMPONENT_CATALOG.md)의 컴포넌트·옵션·Props로 먼저 해결합니다(예: `presentationMode`, `autoLayout`, `employeePopup`, `companyTopNodes`).
|
||||
2. **없으면 소비 프로젝트에 신규 구현:** 조직도 바깥 UI는 소비 프로젝트에 만들고, 조직도에 맞춘 색·글꼴은 공개 입력 `--hm-orgchart-*`와 [DESIGN_RULES.md](./DESIGN_RULES.md)를 참고합니다. 카드·연결선·배치(승인 디자인)는 바꾸지 않고 패키지 원본·Shadow DOM 내부도 수정하지 않습니다.
|
||||
3. **참고할 값이 없으면:** HMDesign 공통 규칙(Font Weight 400/500/700, Light/Dark 없음, 전역 CSS 금지)과 조화되게 구성합니다. 토큰·승인 기록에 없는 값은 결과 보고에 **"AI 구성 값 — 디자인 확인 필요"**로 적습니다.
|
||||
|
||||
## 1. 생성 방식 사전 선택 (필수)
|
||||
|
||||
새 조직도 컴포넌트나 조직도 페이지를 만들 때 **생성 방식이 요청에 없으면 코드 작성 전에** 대화에서 묻습니다(웹페이지에 선택 UI를 만들지 않음). 이미 말했으면 다시 묻지 않습니다.
|
||||
새 조직도 컴포넌트나 조직도 페이지를 만들 때 **생성 방식이 요청에 없으면 코드 작성 전에** 대화에서 묻습니다(웹페이지에 선택 UI를 만들지 않음). 사용 유형도 정해지지 않았다면 유형 질문과 같은 메시지에서 한 번에 묻고, 이미 말했으면 다시 묻지 않습니다.
|
||||
|
||||
> 조직도만 기존 페이지에 삽입할까요, 아니면 레이아웃까지 구성한 새 페이지 전체를 생성할까요?
|
||||
>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
| 직원 정보 팝업을 Web 디자인으로 | 3. HM Dialog 팝업 |
|
||||
| 다른 디자인 시스템의 팝업 | 4. 팝업 어댑터 |
|
||||
| 자연어·CSV·Excel → 데이터 | 5. 데이터 만들기 |
|
||||
| Web·SW 등 다른 영역과 혼합 | 2. Full Page의 영역 분리 원칙. SW 화면 + 조직도는 NOT VERIFIED([AI_USAGE.md §0](./AI_USAGE.md)) |
|
||||
| 기존 Workdesk(고정) 구성 | `layoutMode="fixed"`(기본), `displayMode="readOnly"` 등 — Chart Only 불가 |
|
||||
|
||||
## 1. Chart Only (Auto) — 조직도 영역만
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
1. **승인된 기본 디자인을 그대로 씁니다.** 카드·회사색·그룹 제목·연결선·Typography·간격·배치를 바꾸지 않습니다. 기본값 자체를 바꾸려면 사용자 확인이 먼저입니다.
|
||||
2. **커스터마이징은 공개 CSS 입력(`--hm-orgchart-*`)만**으로 합니다(외부 테마). 이는 기본값 변경과 구분해 보고합니다.
|
||||
3. 새 카드·연결선·노드 디자인을 만들지 않습니다. Shadow DOM 내부 DOM을 스크립트로 바꾸지 않습니다.
|
||||
4. `resolved-*`, `current-*`, `expanded-primary`, `expanded-card-primary`는 내부 계산 변수입니다. 쓰지 않습니다.
|
||||
4. 조직도 바깥에 새 UI가 필요하고 참고할 `--hm-orgchart-*` 값이 없으면 HMDesign 공통 규칙(Font Weight 400/500/700, Light/Dark 없음, 전역 CSS 금지)과 조화되게 구성하고, 토큰에 없는 값은 보고에 "AI 구성 값 — 디자인 확인 필요"로 적습니다([AI_USAGE.md §0](./AI_USAGE.md)).
|
||||
5. `resolved-*`, `current-*`, `expanded-primary`, `expanded-card-primary`는 내부 계산 변수입니다. 쓰지 않습니다.
|
||||
|
||||
## 2. 승인된 기본값
|
||||
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
## HMDesign 디자인 시스템
|
||||
|
||||
<!-- HMDesign 패키지의 ai/AGENTS_SNIPPET.md에서 복사. 아래 "사용 유형"을 프로젝트에 맞게 고치거나, 정하지 않았으면 그 줄을 지운다. -->
|
||||
<!-- HMDesign 패키지의 ai/AGENTS_SNIPPET.md에서 복사. 아래 "사용 유형"을 하나로 고치거나(SW는 모드까지: SW 일반 / SW 뷰어), 정하지 않았으면 그 줄을 지운다. -->
|
||||
|
||||
HMDesign 사용 유형: Web | SW | OrgChart | 혼합(영역별로 적기)
|
||||
HMDesign 사용 유형: Web | SW 일반 | SW 뷰어 | OrgChart | 혼합(영역별로 적기, SW 영역은 모드까지)
|
||||
|
||||
화면·컴포넌트를 구현하거나 수정하기 전에 다음을 지킨다.
|
||||
|
||||
1. 설치된 HMDesign 패키지의 공통 가이드를 먼저 읽는다: `node_modules/@hm-design/<설치된 패키지>/ai/AI_GUIDE.md` (`ui`, `sw`, `org-chart`, `org-chart-react` 중 아무 사본이나 내용이 같다).
|
||||
2. 위 "사용 유형"이 없고 요청으로도 정할 수 없으면 코드 작성 전에 "어떤 HMDesign 디자인 시스템을 사용하시겠습니까? 1. Web 2. SW 3. OrgChart 4. 혼합 사용"을 묻는다. 정해져 있으면 다시 묻지 않는다.
|
||||
2. 위 "사용 유형"이 없고 요청으로도 정할 수 없으면 코드 작성 전에 "어떤 HMDesign 디자인 시스템을 사용하시겠습니까? 1. Web 2. SW (일반 모드 / 뷰어 모드) 3. OrgChart 4. 혼합 사용"을 묻는다. SW인데 모드(일반/뷰어)가 불명확하면 "SW 화면을 어떤 모드로 만들까요? 1. SW 일반 모드 2. SW 뷰어 모드"를 묻는다(근거는 `@hm-design/sw/ai/AI_USAGE.md` §0). 정해져 있으면 다시 묻지 않는다.
|
||||
3. 선택한 패키지의 `ai/AI_USAGE.md` → `COMPONENT_CATALOG.md` → `DESIGN_RULES.md` → `COMPOSITION_PATTERNS.md` 순으로 필요한 절을 읽는다.
|
||||
- Web: `node_modules/@hm-design/ui/ai/`
|
||||
- SW: `node_modules/@hm-design/sw/ai/`
|
||||
- SW: `node_modules/@hm-design/sw/ai/` (뷰어 모드는 `AI_USAGE.md` §0 다음 `VIEWER.md`)
|
||||
- OrgChart: `node_modules/@hm-design/org-chart/ai/` (React는 `node_modules/@hm-design/org-chart-react/ai/AI_USAGE.md`도)
|
||||
4. 기존 컴포넌트 → Props → 조합 → (없는 부분만) 패키지 토큰으로 신규 구현 순서를 지킨다. 패키지 파일 수정·내부 경로 import·구현 복사·새 디자인 값 생성은 하지 않는다.
|
||||
5. Web / SW / OrgChart 스타일을 영역별로 분리하고, 완료 후 AI_GUIDE의 결과 보고 형식으로 재사용·신규·토큰·검증·NOT VERIFIED를 보고한다.
|
||||
4. 선택한 유형·모드 안에서 기존 컴포넌트 → Props → 조합 → (없는 부분만) 그 모드의 토큰·스타일로 신규 → (참고 값도 없으면) HMDesign 공통 규칙과 조화되게 구성하고 "AI 구성 값"으로 보고하는 순서를 지킨다. 패키지 파일 수정·내부 경로 import·구현 복사는 하지 않는다.
|
||||
5. Web / SW 일반 / SW 뷰어 / OrgChart 스타일을 영역별로 분리하고(한 SW 화면에 일반·뷰어 컴포넌트를 섞지 않음), 완료 후 AI_GUIDE의 결과 보고 형식으로 유형·모드, 재사용·신규·토큰·AI 구성 값·검증·NOT VERIFIED를 보고한다.
|
||||
+92
-32
@@ -2,18 +2,19 @@
|
||||
|
||||
> 이 파일은 HMDesign 패키지(`@hm-design/ui`, `@hm-design/sw`, `@hm-design/org-chart`, `@hm-design/org-chart-react`)의 `ai/AI_GUIDE.md`에 **같은 내용으로** 들어 있습니다. 원본은 HMDesign 저장소 `docs/ai/AI_GUIDE.md`이며 패키지 사본은 `npm run sync:ai-docs`로 갱신합니다. 사본을 직접 고치지 않습니다.
|
||||
|
||||
사용자가 "HMDesign 패키지를 기준으로 화면을 구현해 주세요"처럼 요청하면 AI 코딩 도구는 이 파일의 1~6단계를 순서대로 따릅니다. 이 문서와 각 패키지의 `ai/` 문서는 실제 공개 API·CSS에서 확인한 내용만 적습니다. 여기에 없는 컴포넌트·Props·토큰은 없는 것으로 취급합니다.
|
||||
사용자가 "HMDesign 패키지를 기준으로 화면을 구현해 주세요", "HMDesign SW로 화면을 만들어 주세요"처럼 요청하면 AI 코딩 도구는 이 파일의 1~7단계를 순서대로 따릅니다. 이 문서와 각 패키지의 `ai/` 문서는 실제 공개 API·CSS에서 확인한 내용만 적습니다. 여기에 없는 컴포넌트·Props·토큰은 없는 것으로 취급합니다.
|
||||
|
||||
## 0. 읽는 순서
|
||||
|
||||
1. **이 파일**(어느 패키지의 사본이든 같음)
|
||||
2. 선택한 패키지의 `ai/AI_USAGE.md` → `ai/COMPONENT_CATALOG.md` → `ai/DESIGN_RULES.md` → `ai/COMPOSITION_PATTERNS.md`
|
||||
2. 선택한 패키지의 `ai/AI_USAGE.md` → `ai/COMPONENT_CATALOG.md` → `ai/DESIGN_RULES.md` → `ai/COMPOSITION_PATTERNS.md` (SW 뷰어 모드는 `AI_USAGE.md` §0 다음에 `ai/VIEWER.md`를 먼저 읽고 카탈로그의 뷰어 절을 봅니다)
|
||||
3. API가 의심스러우면 그 패키지의 `dist/*.d.ts`(공개 진입점에서 export되는 것만)
|
||||
|
||||
| 유형 | 패키지 | 지침 위치(설치 후) | JS 진입점 | CSS |
|
||||
|---|---|---|---|---|
|
||||
| ① Web UI | `@hm-design/ui` | `node_modules/@hm-design/ui/ai/` | `@hm-design/ui`, `@hm-design/ui/theme` | `@hm-design/ui/tailwind.css` + `@hm-design/ui/theme.css`(Tailwind CSS 4 필요), 선택 `@hm-design/ui/dashboard-status.css` |
|
||||
| ② SW UI | `@hm-design/sw` | `node_modules/@hm-design/sw/ai/` | `@hm-design/sw` | `@hm-design/sw/styles.css` |
|
||||
| ② SW UI — 일반 모드 | `@hm-design/sw` | `node_modules/@hm-design/sw/ai/` (`AI_USAGE.md` §0 모드 선택 → 일반 모드 문서) | `@hm-design/sw` | `@hm-design/sw/styles.css` |
|
||||
| ② SW UI — 뷰어 모드 | `@hm-design/sw`(같은 패키지) | `node_modules/@hm-design/sw/ai/` (`AI_USAGE.md` §0 → `VIEWER.md`) | `@hm-design/sw` | `@hm-design/sw/styles.css`(같은 파일) |
|
||||
| ③ OrgChart | `@hm-design/org-chart`(Core) + React면 `@hm-design/org-chart-react` | `node_modules/@hm-design/org-chart/ai/` (React 어댑터 안내는 `node_modules/@hm-design/org-chart-react/ai/AI_USAGE.md`) | `@hm-design/org-chart`, `@hm-design/org-chart-react`, 선택 `@hm-design/org-chart-react/hm-dialog` | `@hm-design/org-chart/engine.css`, `@hm-design/org-chart/style.css`(URL로 전달 — Shadow DOM 안에 로드) |
|
||||
| 기타 | `@hm-design/center-graphic` | AI 지침 없음. 패키지 `README.md`만 | `@hm-design/center-graphic` | 자동 import |
|
||||
|
||||
@@ -21,12 +22,19 @@
|
||||
|
||||
## 1단계. 사용 목적 확인
|
||||
|
||||
화면 구현 요청을 받으면 코드 작성 전에 **사용 유형**을 정합니다. 유형은 다음 넷이고, SW는 다시 두 모드로 나뉩니다.
|
||||
|
||||
1. Web
|
||||
2. SW — **SW 일반 모드**(편집용: `SWHeader`, `SWPopup` …) / **SW 뷰어 모드**(보기 전용: `SWViewerHeader`, `SWViewerMenu`, `SWViewerPanel` …)
|
||||
3. OrgChart
|
||||
4. 혼합 사용(영역마다 위 유형 하나)
|
||||
|
||||
다음 순서로 판단하고, **판단되면 다시 묻지 않습니다.**
|
||||
|
||||
1. 소비 프로젝트의 `AGENTS.md`·`CLAUDE.md` 등에 `HMDesign 사용 유형:` 설정이 있으면 그대로 따릅니다(§9).
|
||||
1. 소비 프로젝트의 `AGENTS.md`·`CLAUDE.md` 등에 `HMDesign 사용 유형:` 설정이 있으면 그대로 따릅니다(§9). 값은 `Web` / `SW 일반` / `SW 뷰어` / `OrgChart` / `혼합(영역별: …)`입니다. 값이 `SW`뿐이면 유형은 정해진 것이고 모드만 아래 4번으로 정합니다.
|
||||
2. 사용자 요청이 유형을 분명히 말하면 그대로 따릅니다.
|
||||
- Web: 웹 화면, 관리자·업무 화면, 목록·검색·Form, 대시보드, GNB/LNB, Dialog, Table …
|
||||
- SW: 데스크톱 SW, 뷰어, 도면·CAD, SW Header, 툴바, 레이어/색상/선스타일, 속성창·SW Popup …
|
||||
- SW: 데스크톱 SW, 도면·CAD, SW Header, 툴바, 레이어/색상/선스타일, 속성창·SW Popup, 뷰어 …
|
||||
- OrgChart: 조직도, 조직 계층·직원 카드, 조직 JSON/CSV/Excel 시각화 …
|
||||
- 둘 이상이 함께 나오면 ④ 혼합(예: "업무 화면 안에 조직도" = Web + OrgChart).
|
||||
3. 위로 정할 수 없으면 코드 작성 전에 **그대로** 묻습니다.
|
||||
@@ -34,12 +42,21 @@
|
||||
> 어떤 HMDesign 디자인 시스템을 사용하시겠습니까?
|
||||
>
|
||||
> 1. Web
|
||||
> 2. SW
|
||||
> 2. SW (일반 모드 / 뷰어 모드)
|
||||
> 3. OrgChart
|
||||
> 4. 혼합 사용
|
||||
|
||||
- `package.json`에 설치된 패키지가 하나뿐이어도 그것만으로 유형을 확정하지 않습니다(설치가 덜 된 상태일 수 있음). 요청 내용과 맞을 때만 근거로 씁니다.
|
||||
- 혼합을 고르면 영역별 패키지(예: "페이지 = Web, 가운데 영역 = OrgChart")를 확인합니다.
|
||||
4. **SW가 정해졌거나 포함됐는데 모드가 불명확하면** 코드 작성 전에 묻습니다. 설정 값(`SW 일반`/`SW 뷰어`)이나 요청이 모드를 분명히 말하면 묻지 않습니다. 판단 근거와 질문 문구는 `@hm-design/sw/ai/AI_USAGE.md` §0을 따릅니다. 유형 질문이 필요한 경우에는 같은 메시지에서 2번 선택 시의 모드도 함께 묻습니다(한 번에 끝냄).
|
||||
|
||||
> SW 화면을 어떤 모드로 만들까요?
|
||||
>
|
||||
> 1. SW 일반 모드 — 편집용 Header(`SWHeader`)·속성창·SW Popup
|
||||
> 2. SW 뷰어 모드 — 보기 전용 Header(`SWViewerHeader`)·뷰어 메뉴·뷰어 패널
|
||||
|
||||
- "HMDesign SW로 화면을 만들어 주세요"처럼 SW만 말하고 모드 근거가 없으면 유형은 SW로 확정하고 4번의 모드 질문만 합니다.
|
||||
- `package.json`에 설치된 패키지가 하나뿐이어도 그것만으로 유형을 확정하지 않습니다(설치가 덜 된 상태일 수 있음). 요청 내용과 맞을 때만 근거로 씁니다. SW 모드도 같은 패키지이므로 설치 상태로는 판단하지 않습니다.
|
||||
- 정해진 유형·모드는 결과 보고(7단계)에 적고, 작업 중에 다른 유형·모드의 컴포넌트·스타일을 임의로 섞지 않습니다(5단계).
|
||||
- 혼합을 고르면 영역별 패키지(예: "페이지 = Web, 가운데 영역 = OrgChart")를 확인합니다. SW 영역이 있으면 그 영역의 모드(일반/뷰어)까지 정합니다.
|
||||
- **OrgChart가 포함되고 생성 방식이 없으면** 같은 메시지에서 다음도 묻습니다(이미 말했으면 묻지 않음): "조직도만 기존 페이지에 삽입할까요(Chart Only), 아니면 레이아웃까지 구성한 새 페이지 전체를 생성할까요(Full Page)?" 상세는 `@hm-design/org-chart/ai/AI_USAGE.md` §1.
|
||||
- 선택한 패키지가 설치되어 있지 않으면 설치가 필요하다고 보고합니다. 다른 HMDesign 패키지나 임의 라이브러리로 대신하지 않습니다.
|
||||
|
||||
@@ -57,8 +74,9 @@
|
||||
| 요청 항목 | 판단 | 근거(카탈로그의 실제 이름) |
|
||||
|---|---|---|
|
||||
| 예: 상단 메뉴 | 재사용 | Web `GNB` + `GNBMobileMenu` |
|
||||
| 예: 레이어 선택 | 재사용 | SW `SWHeaderLayerMenu` |
|
||||
| 예: 검색 상자(SW) | 신규 | SW 카탈로그에 없음 → `SWHeaderInput` 재사용 + SW 토큰 |
|
||||
| 예: 레이어 선택(SW 일반) | 재사용 | SW `SWHeaderLayerMenu` |
|
||||
| 예: 상단 메뉴(SW 뷰어) | Props 설정 | SW `SWViewerHeader`의 `groups` |
|
||||
| 예: 검색 상자(SW 일반) | 신규 | SW 카탈로그에 없음 → `SWHeaderInput` 재사용 + 일반 모드 토큰 |
|
||||
|
||||
판단 값은 **재사용**(그대로) / **Props 설정**(기존 Variant·Props) / **조합**(기존 컴포넌트 배치) / **신규**(소비 프로젝트에 최소 구현) 중 하나입니다.
|
||||
|
||||
@@ -69,31 +87,44 @@
|
||||
1. 선택 패키지의 기존 컴포넌트·Pattern을 그대로 사용
|
||||
2. 기존 Variant / Props / Callback으로 해결
|
||||
3. 기존 컴포넌트 조합(배치용 CSS만 소비 프로젝트에 작성)
|
||||
4. 조합으로 안 되는 부분만 **소비 프로젝트에** 새로 구현 — 패키지 토큰만 읽고, 안쪽에 기존 컴포넌트를 재사용
|
||||
4. 조합으로 안 되는 부분만 **소비 프로젝트에** 새로 구현 — 아래 "없는 컴포넌트 처리 3단계"
|
||||
|
||||
모든 단계는 **1단계에서 정한 유형·모드 안에서만** 찾습니다. SW 뷰어 모드는 뷰어 컴포넌트(`SWViewer*`)를, SW 일반 모드는 일반 컴포넌트(`SWHeader`·`SWPopup` …)를 먼저 씁니다. 다른 모드에 같은 역할의 컴포넌트가 있어도 가져오지 않습니다.
|
||||
|
||||
### 없는 컴포넌트 처리 3단계
|
||||
|
||||
| 단계 | 조건 | 할 일 | 결과 보고 |
|
||||
|---|---|---|---|
|
||||
| ① 재사용 | 선택 유형·모드에 컴포넌트·Variant·Props·조합이 있음 | 그대로 사용(위 1~3) | 재사용 / Props 설정 / 조합 |
|
||||
| ② 같은 모드 스타일로 신규 | 컴포넌트는 없지만 그 모드의 토큰·확인값·상태 표현이 있음 | 소비 프로젝트에 최소 구현. 그 유형·모드의 토큰과 `DESIGN_RULES.md`(SW 뷰어는 `VIEWER.md`도)의 크기·색·상태 표현만 읽고, 안쪽에는 그 모드의 공개 컴포넌트를 재사용 | 신규 · 읽은 토큰 목록 |
|
||||
| ③ HMDesign과 조화되는 새 스타일 | ②로 참고할 토큰·확인값이 없음 | HMDesign 공통 규칙(아래)과 선택 유형·모드의 가장 가까운 토큰을 기준으로 새 스타일을 구성 | 신규 · **"AI 구성 값 — 디자인 확인 필요"** 목록(속성·값·이유) |
|
||||
|
||||
- 토큰·확인값이 있으면 ②에서 반드시 그것을 씁니다. ③은 참고할 값이 정말 없을 때만이며, ③에서 만든 값은 확정 디자인이 아니라 확인 대상입니다. 화면 인상을 크게 바꾸는 값(주요 색·Header 높이 등)이 필요하면 구현 전에 사용자에게 먼저 확인합니다.
|
||||
- 유형·모드별 구체 토큰과 예는 각 패키지 `ai/AI_USAGE.md`에 있습니다.
|
||||
|
||||
규칙:
|
||||
|
||||
- `node_modules` 안 패키지 파일을 수정하지 않습니다. 패키지 `dist` 구현이나 내부 CSS 블록을 복사해 같은 컴포넌트를 다시 만들지 않습니다.
|
||||
- 이미 있는 컴포넌트와 같은 역할의 컴포넌트를 새로 만들지 않습니다(예: Web에 `Dialog`가 있는데 자체 Modal 작성 금지).
|
||||
- 새 디자인 값을 만들지 않습니다. 색·크기·간격·radius·그림자는 각 패키지 `DESIGN_RULES.md`의 토큰·확인값만 씁니다. 값이 없으면 추측하지 말고 사용자에게 확인합니다.
|
||||
- 토큰·확인값이 있는 속성에 새 값을 만들지 않습니다. 색·크기·간격·radius·그림자는 각 패키지 `DESIGN_RULES.md`(SW 뷰어는 `VIEWER.md`도)의 토큰·확인값을 씁니다. 값이 없을 때만 위 ③으로 구성하고 "AI 구성 값"으로 보고합니다(추측한 값을 확정값처럼 쓰지 않음).
|
||||
- 공통: Font Weight는 400 / 500 / 700만 씁니다(600 없음). Light/Dark 분기를 만들지 않습니다. 새 컴포넌트 CSS에 `html`·`body`·`*` 전역 규칙을 넣지 않습니다. 새 class는 소비 프로젝트 접두사(예: `app-`)를 씁니다.
|
||||
- 요청에 없는 메뉴·통계·설명·다운로드·외부 API·AI 입력 UI를 추가하지 않습니다. 필요해 보이면 제안으로만 보고합니다.
|
||||
|
||||
### 없는 UI를 같은 스타일로 만들 때 확인할 항목
|
||||
|
||||
신규 항목마다 아래를 선택 패키지 `DESIGN_RULES.md`에서 찾아 그대로 적용합니다. 찾을 수 없는 항목은 "값 없음 — 사용자 확인 필요"로 보고합니다.
|
||||
신규 항목마다 아래를 선택 유형·모드의 문서에서 찾아 그대로 적용합니다(②). 찾을 수 없는 항목은 ③으로 구성하고 "AI 구성 값 — 디자인 확인 필요"로 보고합니다.
|
||||
|
||||
| 항목 | Web(`@hm-design/ui`) | SW(`@hm-design/sw`) | OrgChart |
|
||||
|---|---|---|---|
|
||||
| 토큰·CSS 변수 | `--hm-sem-*`, `--hm-color-*`, `--hm-radius-*`(`:root`) | `--hm-sw-header-*`, `--hm-sw-property-*`(`SWTheme` 범위) | `--hm-orgchart-*` 공개 입력(Shadow DOM 상속) |
|
||||
| 색·Typography | DESIGN_RULES §2·§3 | DESIGN_RULES §2·§3 | DESIGN_RULES §2·§3 |
|
||||
| 크기·여백 | DESIGN_RULES §4 | DESIGN_RULES §1 | 카드·간격 변경 금지(승인 디자인) |
|
||||
| Border·Radius·배경·그림자 | DESIGN_RULES §2·§4 | DESIGN_RULES §2·§8 | 공개 입력만 |
|
||||
| 아이콘 | `lucide-react`(패키지 의존성) | 패키지 내장 SVG만, 새 아이콘은 사용자 제공 | Core 내장 |
|
||||
| 스크롤바 | `ScrollArea`(Radix), DESIGN_RULES §6 | 전용 디자인 없음 — 브라우저 기본(AI_USAGE §2) | Core 내부 Zoom/Pan |
|
||||
| Hover / Active / Focus / Disabled | DESIGN_RULES §5 | DESIGN_RULES §4 | Core 내장 |
|
||||
| Popup·Panel | `Dialog`·`AlertDialog`·`Sheet`·`Drawer`·`Popover` | `SWPopup` + `SWPopupSection`/`SWPopupRow` | Core 팝업 / HM Dialog / 어댑터 |
|
||||
| 동작·키보드 | Radix 동작 유지 | 카탈로그 "공통 키보드" | Core 키보드(Pan, Alt+M 이동 등) |
|
||||
| 항목 | Web(`@hm-design/ui`) | SW 일반 모드(`@hm-design/sw`) | SW 뷰어 모드(`@hm-design/sw`) | OrgChart |
|
||||
|---|---|---|---|---|
|
||||
| 토큰·CSS 변수 | `--hm-sem-*`, `--hm-color-*`, `--hm-radius-*`(`:root`) | `--hm-sw-header-*`, `--hm-sw-property-*`(`SWTheme` 범위) | `--hm-sw-viewer-*` + 두 Header가 공유하는 `--hm-sw-header-document-*`·`object-*`·`property-*`(SW 범위) | `--hm-orgchart-*` 공개 입력(Shadow DOM 상속) |
|
||||
| 색·Typography | DESIGN_RULES §2·§3 | DESIGN_RULES §2·§3 | VIEWER.md `SWViewerHeader`·디자인 변경 절 | DESIGN_RULES §2·§3 |
|
||||
| 크기·여백 | DESIGN_RULES §4 | DESIGN_RULES §1 | VIEWER.md 디자인 변경 절(52px Header 등 실측값) | 카드·간격 변경 금지(승인 디자인) |
|
||||
| Border·Radius·배경·그림자 | DESIGN_RULES §2·§4 | DESIGN_RULES §2·§8 | VIEWER.md `SWViewerPanel` 절(프레임은 SWPopup과 같음) | 공개 입력만 |
|
||||
| 아이콘 | `lucide-react`(패키지 의존성) | 패키지 내장 SVG만, 새 아이콘은 사용자 제공 | 프로그램 제공 16px `currentColor` 아이콘, 외곽선은 `SWViewerIcon` | Core 내장 |
|
||||
| 스크롤바 | `ScrollArea`(Radix), DESIGN_RULES §6 | 전용 디자인 없음 — 브라우저 기본(AI_USAGE §2) | 전용 디자인 없음 — 패널 본문 스크롤은 `SWViewerPanel` | Core 내부 Zoom/Pan |
|
||||
| Hover / Active / Focus / Disabled | DESIGN_RULES §5 | DESIGN_RULES §4 | VIEWER.md `SWViewerHeader` 절 상태 표현 | Core 내장 |
|
||||
| Popup·Panel | `Dialog`·`AlertDialog`·`Sheet`·`Drawer`·`Popover` | `SWPopup` + `SWPopupSection`/`SWPopupRow` | `SWViewerPanel`(+ `modal`) + `SWViewerSection`/`SWViewerField` | Core 팝업 / HM Dialog / 어댑터 |
|
||||
| 동작·키보드 | Radix 동작 유지 | 카탈로그 "공통 키보드" | VIEWER.md `SWViewerMenu`·`SWViewerPanel` 키보드 | Core 키보드(Pan, Alt+M 이동 등) |
|
||||
|
||||
## 5단계. 패키지별 디자인 분리 (혼합 사용 포함)
|
||||
|
||||
@@ -102,20 +133,30 @@
|
||||
| 패키지 | 스타일이 적용되는 범위 | 주의 |
|
||||
|---|---|---|
|
||||
| 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`(`<SWTheme>`)에만 정의. 전역 선택자 없음 | Header 밖 SW 부품은 반드시 `<SWTheme>` 안 |
|
||||
| SW(일반·뷰어 공통) | 토큰은 `.hm-sw-header`와 `.hm-sw-theme`에만 정의(뷰어 토큰 `--hm-sw-viewer-*`도 같은 범위). 전역 선택자 없음. `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`은 자기 root에 `hm-sw-theme`를 가짐 | 일반 모드의 Header 밖 SW 부품은 반드시 `<SWTheme>` 안 |
|
||||
| OrgChart | Core가 자기 open Shadow DOM에만 CSS 로드. 호스트 CSS selector는 안쪽에 닿지 않고 **Custom Property 상속만** 통과 | 호스트 class로 카드 모양을 바꾸려 하지 않음 |
|
||||
|
||||
혼합 규칙:
|
||||
|
||||
1. 영역마다 하나의 패키지를 정하고 그 영역의 신규 UI는 그 패키지의 토큰만 읽습니다. Web 토큰(`--hm-sem-*`)을 SW 영역에, SW 토큰(`--hm-sw-*`)을 Web 영역에 쓰지 않습니다. OrgChart 내부는 `--hm-orgchart-*`만 씁니다.
|
||||
2. 다른 패키지 컴포넌트는 **문서에 허용된 지점에서만** 씁니다.
|
||||
- SW `SWPopup`의 `children` 안 Web 컨트롤(SW 카탈로그가 허용, 예: Popup 하단 `Button`)
|
||||
- SW 일반 모드 `SWPopup`의 `children` 안 Web 컨트롤(SW 카탈로그가 허용, 예: Popup 하단 `Button`)
|
||||
- SW 뷰어 모드 `SWViewerPanel`의 `children` 안 Web 컨트롤 — `SWViewer*` 컨트롤로 안 될 때만(SW `AI_USAGE.md` §0.4)
|
||||
- OrgChart Full Page의 바깥 레이아웃 = Web(또는 요청된 패키지)
|
||||
- OrgChart React의 직원 팝업 = 선택 `@hm-design/org-chart-react/hm-dialog`(Web `Dialog`, Web Theme CSS 필요)
|
||||
3. 패키지 class(`hm-sw-*`, `hm-orgchart-*`, Web `data-slot`)를 소비 코드에서 덮어쓰지 않습니다. 배치는 `className`·`style`과 소비 프로젝트 class로 합니다.
|
||||
4. **Web + SW를 한 문서에 함께 쓰면** Web의 전역 base(위 표)가 SW 화면에도 적용됩니다. SW는 자기 범위에서 버튼 등을 초기화하지만 이 조합의 시각 결과는 패키지에서 검증된 적이 없습니다(NOT VERIFIED). 이 조합이면 브라우저에서 SW 부품의 글꼴·테두리·배경을 직접 확인하고 차이를 보고합니다. 가능하면 Web CSS가 없는 SW 전용 화면(별도 entry)으로 분리합니다.
|
||||
5. Web Scoped Theme(`[data-hm-theme]`)는 body Portal(Select·Popover·DatePicker 팝업)에 전달되지 않습니다. Web 영역만 다른 테마로 바꾸려면 Global Theme를 쓰거나 차이를 보고합니다.
|
||||
|
||||
### SW 일반 모드 ↔ 뷰어 모드 분리
|
||||
|
||||
SW 일반 모드와 뷰어 모드는 같은 패키지·같은 CSS 파일이지만 **서로 다른 디자인**입니다. 한 화면(한 Header 영역)에는 한 모드만 씁니다.
|
||||
|
||||
1. 일반 모드 화면: `SWHeader`·개별 컨트롤·`SWPopup`·`SWHeaderPropertyPanel`·`SWToolButton`/`SWToolGroup`. `SWViewer*` 컴포넌트와 `--hm-sw-viewer-*` 토큰을 쓰지 않습니다.
|
||||
2. 뷰어 모드 화면: `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`과 뷰어 패널 컨트롤(`SWViewerSection`·`SWViewerField` …). `SWHeader`에 뷰어 메뉴를 억지로 넣거나 `SWPopup`을 뷰어처럼 재스타일하지 않습니다.
|
||||
3. 패키지가 실제로 공유하는 부분은 혼합이 아닙니다: `SWViewerPanel`은 `SWPopup` 프레임을 그대로 렌더링하고, 두 Header는 파일명·객체 수정·속성 면 토큰(`--hm-sw-header-document-*`·`object-*`·`property-*`)을 공유합니다. 소비 코드가 이 공유를 흉내 내 다른 모드 부품을 섞어도 된다는 뜻은 아닙니다.
|
||||
4. 프로그램이 두 모드를 모두 가지면 모드 전환 시 Header 컴포넌트를 바꿔 끼웁니다(파일·패널 상태는 프로그램 상태로 유지). 세부는 `@hm-design/sw/ai/AI_USAGE.md` §0과 `VIEWER.md`.
|
||||
|
||||
## 6단계. 디자인 검증
|
||||
|
||||
소비 프로젝트에서 실제로 실행한 것만 PASS로 적습니다.
|
||||
@@ -123,20 +164,22 @@
|
||||
1. Typecheck(`tsc --noEmit` 등)와 Production Build
|
||||
2. 브라우저 렌더링: 재사용한 컴포넌트가 HM 외형으로 보이는지(CSS 진입점 누락 확인), 신규 UI가 같은 토큰을 쓰는지
|
||||
3. 상태·동작: Hover / Focus(키보드) / Disabled, Popup 열기·닫기·Escape·Focus 복귀, 선택 패키지의 핵심 동작
|
||||
4. 폭: Web 390 / 768 / 1280 / 1440px, SW는 대상 창 폭(Header는 반응형 More 포함), OrgChart는 캔버스 크기·초기 Fit
|
||||
5. 혼합이면 영역 경계에서 스타일 침범이 없는지(§5)
|
||||
4. 폭: Web 390 / 768 / 1280 / 1440px, SW 일반 모드는 대상 창 폭(Header는 반응형 More 포함), SW 뷰어 모드는 대상 창 폭과 항목 `collapseBelow`·`iconOnlyBelow` 경계 전후(More 이동·아이콘만 표시), OrgChart는 캔버스 크기·초기 Fit
|
||||
5. 혼합이면 영역 경계에서 스타일 침범이 없는지, SW면 선택하지 않은 모드의 컴포넌트·토큰이 섞이지 않았는지(§5)
|
||||
6. 실행하지 못한 항목은 `NOT VERIFIED`로 남깁니다.
|
||||
|
||||
## 7단계. 결과 보고 형식
|
||||
|
||||
```md
|
||||
## HMDesign 적용 결과
|
||||
- 사용 유형: Web | SW | OrgChart(Chart Only|Full Page) | 혼합(영역별: …)
|
||||
- 사용 유형: Web | SW 일반 | SW 뷰어 | OrgChart(Chart Only|Full Page) | 혼합(영역별: …)
|
||||
- 유형·모드 판단 근거: 프로젝트 설정 | 요청 문구 "…" | 사용자 답변
|
||||
- 패키지·버전: @hm-design/ui 0.1.0, …
|
||||
- 재사용한 컴포넌트: …(Props 설정 포함)
|
||||
- 조합한 부분: …
|
||||
- AI가 새로 구현한 부분: 파일 경로 · 이유(카탈로그에 없음) · 안쪽에서 재사용한 컴포넌트
|
||||
- 적용한 디자인 토큰: --hm-… (신규 UI가 읽은 것)
|
||||
- AI 구성 값 — 디자인 확인 필요: 없음 | 속성 · 값 · 이유(4단계 ③)
|
||||
- 카탈로그와 .d.ts 차이: 없음 | …
|
||||
- 검증: Typecheck PASS · Build PASS · 브라우저(폭/상태) … · NOT VERIFIED: …
|
||||
- 제안(구현하지 않음): …
|
||||
@@ -161,9 +204,14 @@
|
||||
import { Button, Card, CardContent, FilterBar, FilterBarActions, FilterBarSearch, PageHeader, PageHeaderContent, PageHeaderTitle } from "@hm-design/ui"
|
||||
```
|
||||
|
||||
### 예시 B — SW 뷰어
|
||||
### 예시 B0 — "HMDesign SW로 화면을 만들어 주세요" (모드 미지정)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/sw/ai/` → COMPOSITION_PATTERNS "6. 파일 열기 + 도구 막대", 예제 `ai/examples/ExampleF-ViewerToolbar.tsx`
|
||||
- 유형은 SW로 확정, 모드 근거가 없으므로 코드 작성 전에 1단계 4번의 모드 질문만 합니다. 답에 따라 B1 또는 B2로 진행합니다.
|
||||
- 소비 프로젝트 설정이 `HMDesign 사용 유형: SW 일반` 또는 `SW 뷰어`이면 묻지 않고 바로 B1/B2입니다.
|
||||
|
||||
### 예시 B1 — SW 일반 모드 (편집 Header + 도구 막대 + 설정 Popup)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/sw/ai/` → AI_USAGE §0(일반 모드) → COMPOSITION_PATTERNS "6. 파일 열기 + 도구 막대", 예제 `ai/examples/ExampleF-ViewerToolbar.tsx`(파일 이름의 Viewer는 과거 명칭이며 일반 모드 `SWHeader` 예제)
|
||||
- 재사용: `SWHeader`(`documentOpenPlacement="header"`, `controls`, `tools`), `SWToolGroup` + `SWToolButton`(Model/Layout 탭, Fit 등), `SWPopup` + `SWPopupSection` + `SWPopupRow` + `SWHeaderInput`(설정 Popup)
|
||||
- 신규: SW에 없는 기능(예: 검색) → 소비 프로젝트 컴포넌트, `<SWTheme>` 안, `--hm-sw-header-*` 토큰, 안쪽 입력은 `SWHeaderInput`(예제 `ExampleD-SearchExtension.tsx`)
|
||||
|
||||
@@ -172,6 +220,18 @@ import { SWHeader, SWPopup, SWTheme, SWToolButton, SWToolGroup } from "@hm-desig
|
||||
import "@hm-design/sw/styles.css"
|
||||
```
|
||||
|
||||
### 예시 B2 — SW 뷰어 모드 (뷰어 Header + 메뉴 + 패널)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/sw/ai/` → AI_USAGE §0(뷰어 모드) → `VIEWER.md`, 예제 `ai/examples/ExampleH-ViewerMode.tsx`
|
||||
- 재사용: `SWViewerHeader`(`groups` 데이터: `button`·`toggle`·`menu`·`tabs`·`switch`·`custom` 항목, `onCommand`, `trailing`에 `SWViewerStatus`·`SWViewerHeaderButton`), Dropdown은 `type: "menu"` 항목의 `entries`(단독·우클릭은 `SWViewerMenu`), 팝업은 `SWViewerPanel` + `SWViewerSection`·`SWViewerField`·`SWViewerSwitch`·`SWViewerSlider`·`SWViewerInput`·`SWViewerButton`
|
||||
- 신규: 뷰어에 없는 패널 콘텐츠 → 소비 프로젝트 컴포넌트를 `SWViewerPanel`의 `children`에, 안쪽은 `SWViewerField` + `SWViewerInput` 등, 외형은 `--hm-sw-viewer-*` 토큰
|
||||
- 하지 않음: `SWHeader`·`SWPopup`을 뷰어 화면에 섞기, 로고가 없다고 임의 문자·아이콘 넣기, 연결할 명령이 없는 메뉴를 가짜 동작으로 만들기(제외 또는 `disabled` + 미연결 보고)
|
||||
|
||||
```tsx
|
||||
import { SWViewerHeader, SWViewerPanel, SWViewerSection, SWViewerField, SWViewerSwitch, type SWViewerHeaderGroup } from "@hm-design/sw"
|
||||
import "@hm-design/sw/styles.css"
|
||||
```
|
||||
|
||||
### 예시 C — 조직도만 (Chart Only)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/org-chart/ai/` → COMPOSITION_PATTERNS "1. Chart Only"
|
||||
@@ -198,7 +258,7 @@ import coreUrl from "@hm-design/org-chart/style.css?url"
|
||||
|
||||
AI 코딩 도구는 보통 **프로젝트 루트의** `AGENTS.md`(Codex 등)·`CLAUDE.md`(Claude Code)·도구별 규칙 파일만 자동으로 읽고 `node_modules`는 읽지 않습니다. 패키지 설치만으로 지침이 자동 적용되지는 않으므로 소비 프로젝트에서 한 번 연결합니다.
|
||||
|
||||
1. 패키지에 들어 있는 `ai/AGENTS_SNIPPET.md`를 루트 `AGENTS.md`(없으면 새로 만듦)에 붙여 넣고 `HMDesign 사용 유형:` 줄을 프로젝트에 맞게 고칩니다. 정하지 않았으면 그 줄을 지워 AI가 1단계에서 묻게 합니다.
|
||||
1. 패키지에 들어 있는 `ai/AGENTS_SNIPPET.md`를 루트 `AGENTS.md`(없으면 새로 만듦)에 붙여 넣고 `HMDesign 사용 유형:` 줄을 프로젝트에 맞게 고칩니다. 값은 `Web` / `SW 일반` / `SW 뷰어` / `OrgChart` / `혼합(영역별: 예 "페이지 = Web, 중앙 = OrgChart")` 중 하나입니다. SW 프로젝트면 모드까지 적어야 AI가 모드를 다시 묻지 않습니다(`SW`만 적으면 모드를 묻습니다). 정하지 않았으면 그 줄을 지워 AI가 1단계에서 묻게 합니다.
|
||||
```bash
|
||||
cat node_modules/@hm-design/ui/ai/AGENTS_SNIPPET.md >> AGENTS.md
|
||||
```
|
||||
|
||||
+74
-10
@@ -2,25 +2,86 @@
|
||||
|
||||
이 폴더(`node_modules/@hm-design/sw/ai/`)는 다른 React 프로젝트에서 AI 코딩 도구가 SW 패키지를 **재사용·조합·확장**할 때 먼저 읽는 안내서입니다. 패키지 자체에는 AI 기능이 없습니다. 아래 문서는 실제 공개 API와 CSS에서 확인한 값만 적습니다.
|
||||
|
||||
먼저 [AI_GUIDE.md](./AI_GUIDE.md)(HMDesign 공통: 사용 유형 Web / SW / OrgChart / 혼합 확인, 작업 1~7단계, 패키지 분리, 결과 보고)를 읽고 사용 유형이 **SW** 또는 SW가 포함된 혼합일 때 이 폴더를 씁니다.
|
||||
먼저 [AI_GUIDE.md](./AI_GUIDE.md)(HMDesign 공통: 사용 유형 Web / SW 일반·뷰어 / OrgChart / 혼합 확인, 작업 1~7단계, 패키지 분리, 결과 보고)를 읽고 사용 유형이 **SW** 또는 SW가 포함된 혼합일 때 이 폴더를 씁니다.
|
||||
|
||||
| 문서 | 내용 |
|
||||
|---|---|
|
||||
| [AI_GUIDE.md](./AI_GUIDE.md) | HMDesign 공통 진입점(모든 HMDesign 패키지에 같은 사본) |
|
||||
| [COMPONENT_CATALOG.md](./COMPONENT_CATALOG.md) | 공식 공개 컴포넌트(Header·개별 컨트롤·Popup·도구 막대)·Props·Callback·크기·CSS 의존성 |
|
||||
| [DESIGN_RULES.md](./DESIGN_RULES.md) | SW 전용 토큰·Typography·간격·Hover/Focus/Selected·Overlay·Motion·반응형·Popup 외형·도구 버튼 |
|
||||
| [COMPOSITION_PATTERNS.md](./COMPOSITION_PATTERNS.md) | 완성형·간소화·기능 중심·확장 Header, Popup(자유 콘텐츠), 파일 열기 + 도구 막대 |
|
||||
| [examples/](./examples) | 공개 API만 쓰는 예제 A~F(E = 사용자 정의 Popup, F = 파일 열기 + 도구 막대. 독립 소비 프로젝트에서 Typecheck·Build·브라우저 검증), H = 뷰어 모드 |
|
||||
| [COMPONENT_CATALOG.md](./COMPONENT_CATALOG.md) | 공식 공개 컴포넌트(일반 모드: Header·개별 컨트롤·Popup·도구 막대 / 뷰어 모드 §8: `SWViewer*` 전체 Export)·Props·Callback·크기·CSS 의존성 |
|
||||
| [DESIGN_RULES.md](./DESIGN_RULES.md) | SW 전용 토큰·Typography·간격·Hover/Focus/Selected·Overlay·Motion·반응형·Popup 외형·도구 버튼(일반 모드 §1~10), 뷰어 토큰·상태값 요약(§11) |
|
||||
| [COMPOSITION_PATTERNS.md](./COMPOSITION_PATTERNS.md) | 완성형·간소화·기능 중심·확장 Header, Popup(자유 콘텐츠), 일반 모드 Header + 도구 막대(1~6), 뷰어 모드 기본 조합(7) |
|
||||
| [examples/](./examples) | 공개 API만 쓰는 예제. **일반 모드** A~F(E = 사용자 정의 Popup, F = 파일 열기 + 도구 막대. 독립 소비 프로젝트에서 Typecheck·Build·브라우저 검증. B·F 파일명의 "Viewer"는 과거 이름이며 일반 모드 `SWHeader` 구성), **뷰어 모드** H(`SWViewer*`) |
|
||||
| [VIEWER.md](./VIEWER.md) | **뷰어 모드 전용**: `SWViewerHeader`(데이터 메뉴·More·외곽선·로고 규칙), `SWViewerMenu`(Dropdown·서브메뉴·우클릭), `SWViewerPanel`(팝업 프레임 + 자유 콘텐츠). 일반 SW 모드는 `SWHeader`·`SWPopup`을 그대로 씁니다 |
|
||||
|
||||
## 0. SW 모드 선택 — SW 일반 모드 / SW 뷰어 모드 (코드 작성 전에 결정)
|
||||
|
||||
SW 패키지에는 Header·Popup 계열이 두 벌 있습니다. 화면마다 **하나의 모드**를 고르고 그 모드의 컴포넌트만 씁니다. 공통 사용 유형 확인(Web / SW / OrgChart / 혼합)은 [AI_GUIDE.md](./AI_GUIDE.md)를 따르고, 사용 유형이 SW로 정해진 뒤 이 절로 모드를 정합니다.
|
||||
|
||||
### 0.1 판단 순서
|
||||
|
||||
1. **소비 프로젝트 설정:** `AGENTS.md`·`CLAUDE.md` 등에 `HMDesign 사용 유형: SW 일반` 또는 `HMDesign 사용 유형: SW 뷰어`가 있으면 그 모드를 씁니다. 혼합(영역별)이면 SW 영역에 적힌 모드를 씁니다.
|
||||
2. **요청 문구:** 설정이 없거나 `SW`만 적혀 있으면 요청을 봅니다.
|
||||
- **뷰어 모드 근거:** "뷰어", "DWG/DXF 보기", "도면 뷰어", "도면 보기·열람", "읽기 전용", 도면 공간(Model/Layout) 탭·전체 보기·레이어/설정 패널 토글·불러오기 상태가 중심.
|
||||
- **일반 모드 근거:** "편집", "그리기"(그리기모드), "객체 수정", 레이어·색상·선스타일·문자/치수스타일 **값 편집**, 속성Bar·"속성창" 편집이 중심.
|
||||
- 근거가 한쪽에만 있고 분명할 때만 그 모드로 정합니다. 양쪽 근거가 섞여 있거나 하나라도 애매하면(예: "도면 화면", "CAD 화면 상단", "레이어 보기") **추측하지 않습니다.**
|
||||
3. **그래도 모르면 코드 작성 전에 그대로 묻습니다.**
|
||||
|
||||
> SW 화면을 어떤 모드로 만들까요?
|
||||
> 1. SW 일반 모드(편집용 `SWHeader`·`SWPopup`)
|
||||
> 2. SW 뷰어 모드(`SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`)
|
||||
|
||||
4. 설정·요청·이전 답변으로 모드가 **이미 명확하면 다시 묻지 않습니다.** 결과 보고에 정한 모드와 근거(설정 값 / 요청 문구 / 사용자 답변)를 적습니다(§4).
|
||||
|
||||
### 0.2 모드별 컴포넌트와 읽을 문서
|
||||
|
||||
| 구분 | SW 일반 모드 | SW 뷰어 모드 |
|
||||
|---|---|---|
|
||||
| 용도 | 설치형·도면 **편집** SW 상단: 그리기모드, 레이어·색상·선/문자/치수스타일 선택, 속성Bar·속성창 | 도면 **보기** 화면 상단: 파일 열기·샘플, 도면 공간(Model/Layout) 탭, 전체 보기, 2.5D·배경 스위치, 레이어·설정·속성 패널 토글, 불러오기 상태 |
|
||||
| 기준 | Figma 이지빔 SW `26:8944`, 49px | 참고 DWG/DXF 뷰어 실측(1440px), 52px |
|
||||
| Header | `SWHeader`, 또는 `<SWTheme>` 안의 개별 컨트롤(`SWHeaderHome`, `SWHeaderDocumentTitle`, `SWHeaderLayerMenu`, `SWHeaderColorMenu`, `SWHeaderLineStyleMenu`, `SWHeaderTextStyleMenu`, `SWHeaderDimensionStyleMenu`, `SWHeaderActions`, `SWHeaderWindowControls`, `SWHeaderProperties` …) | `SWViewerHeader`(`groups` 데이터 + `trailing`), 오른쪽 끝·`custom` 버튼 `SWViewerHeaderButton`, 상태 `SWViewerStatus` |
|
||||
| Dropdown | 각 필드 Dropdown(`SWHeaderLayerMenu` …) | `type: "menu"` 항목, 단독·우클릭은 `SWViewerMenu` |
|
||||
| 팝업·설정창 | `SWPopup`(`titleActions`, `footer`) + `SWPopupSection` / `SWPopupRow` + `SWHeaderInput`, 속성창 `SWHeaderPropertyPanel`, 속성Bar `SWHeaderPropertyBar` | `SWViewerPanel`(이동·크기 조절·접기·`modal`, `headerActions`, `footer`) + `SWViewerSection` / `SWViewerField` / `SWViewerSwitch` / `SWViewerSlider` / `SWViewerInput` / `SWViewerButton` / `SWViewerBadge` / `SWViewerHint` |
|
||||
| 버튼·탭·토글 | `SWToolButton` / `SWToolGroup` | Header 항목 `type: "button" \| "toggle" \| "tabs" \| "switch"`, 패널 안 `SWViewerButton` |
|
||||
| 아이콘 | 패키지 자산(필드 안 아이콘) | 프로그램 아이콘 16px, 직접 그린 아이콘은 `SWViewerIcon`으로 감쌈 |
|
||||
| 범위 | Header 밖 부품은 `<SWTheme>` 안 | `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`은 루트에 `hm-sw-theme`이 있어 `<SWTheme>` 불필요. 패널 컨트롤은 `SWViewerPanel` 안 |
|
||||
| 토큰 | `--hm-sw-header-*`, Popup 콘텐츠 `--hm-sw-property-*` | `--hm-sw-viewer-*` + 공유 `--hm-sw-header-*`(아래 0.3) |
|
||||
| 읽을 문서 | [COMPONENT_CATALOG.md](./COMPONENT_CATALOG.md) §1~7, [DESIGN_RULES.md](./DESIGN_RULES.md) §1~10, [COMPOSITION_PATTERNS.md](./COMPOSITION_PATTERNS.md) 1~6, 예제 A~F | [VIEWER.md](./VIEWER.md), [COMPONENT_CATALOG.md](./COMPONENT_CATALOG.md) §8, [DESIGN_RULES.md](./DESIGN_RULES.md) §11, [COMPOSITION_PATTERNS.md](./COMPOSITION_PATTERNS.md) 7, [예제 H](./examples/ExampleH-ViewerMode.tsx) |
|
||||
|
||||
- **일반 모드 Header에 도구 막대를 더한 구성**(로고 옆 파일 열기 + Model/Layout·Fit·2.5D 버튼을 `SWHeader`에 추가)은 **일반 모드**입니다: `SWHeader`의 `documentOpenPlacement`·`leading`·`tools` + `SWToolButton` / `SWToolGroup`(PATTERNS 6, 예제 F). "뷰어"·"도면 보기" 화면을 요청받았다면 이 구성이 아니라 뷰어 모드(`SWViewer*`)를 씁니다.
|
||||
- 모드 진입·종료, 파일 처리, 도면 렌더링, 메뉴 명령 실행은 어느 모드든 **프로그램 담당**입니다.
|
||||
|
||||
### 0.3 모드 혼합 금지
|
||||
|
||||
- **한 화면에 Header 하나.** `SWHeader`와 `SWViewerHeader`를 같은 화면에 함께 두지 않습니다. 두 모드를 오가는 프로그램은 상태를 유지한 채 Header 컴포넌트만 바꿉니다(VIEWER.md §1).
|
||||
- **뷰어 화면:** `SWHeader`에 뷰어 메뉴를 넣거나 `SWHeader`·`SWPopup`을 뷰어처럼 재스타일하지 않습니다. 뷰어 팝업은 `SWViewerPanel`입니다.
|
||||
- **일반 화면:** `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`과 패널 컨트롤(`SWViewerSection` …)을 쓰지 않습니다.
|
||||
- **토큰:** `--hm-sw-viewer-*` 토큰을 일반 모드 신규 UI에 쓰지 않고, 일반 모드 전용 모양(속성창 행 `SWPopupRow`, `SWToolButton`의 `pill`·`text` 모양, 일반 필드 Dropdown)을 뷰어 신규 UI에 가져오지 않습니다. 두 토큰은 같은 범위(`.hm-sw-header`, `.hm-sw-theme`)에 함께 선언되어 있어 기술적으로 읽히지만, 읽힌다는 것이 허용을 뜻하지 않습니다.
|
||||
- **공유 — 모드 혼합 아님(실제 코드가 공유하는 부분):**
|
||||
- `SWViewerPanel`은 내부에서 `SWPopup` 프레임(제목 막대·제목·닫기·테두리·면)을 렌더링합니다. 뷰어에서 `SWViewerPanel`을 쓰는 것은 일반 모드 혼합이 아닙니다. 단, 뷰어 화면에서 `SWPopup`을 직접 쓰지는 않습니다.
|
||||
- 두 Header는 사용자 확정 면 토큰 `--hm-sw-header-document-*`·`--hm-sw-header-object-*`·`--hm-sw-header-property-*`와 외곽선 토큰 `--hm-sw-header-text-outline*`·`--hm-sw-header-label-outline`을 공유합니다(바꾸면 두 Header가 함께 바뀜).
|
||||
- 뷰어 패널 콘텐츠 토큰 일부(`--hm-sw-viewer-panel-background`·`-field-background`·`-inner-border`·`-text`·`-badge-background`, `--hm-sw-viewer-panel-switch-off`)는 `--hm-sw-property-*` 값을 참조합니다. 뷰어 신규 UI는 `--hm-sw-viewer-panel-*` 이름으로 읽습니다.
|
||||
|
||||
### 0.4 없는 컴포넌트 처리 (모드별 3단계)
|
||||
|
||||
공통 원칙은 [AI_GUIDE.md](./AI_GUIDE.md)를 따르고, SW에서는 아래 값을 씁니다.
|
||||
|
||||
| 단계 | SW 일반 모드 | SW 뷰어 모드 |
|
||||
|---|---|---|
|
||||
| ① 기존 재사용 | `SWHeader` Props(`hiddenControls`·`menuOrder`·`controls`·`documentOpenPlacement`·`leading`·`tools`) → 개별 컨트롤 조합 → `SWPopup` children → `SWToolButton` / `SWToolGroup` | `SWViewerHeader`의 `groups` 항목(`button`·`toggle`·`menu`·`tabs`·`switch`·`custom`)과 `trailing` → `SWViewerMenu` → `SWViewerPanel` children·`footer`·`headerActions` + 패널 컨트롤 |
|
||||
| ② 소비 프로젝트에 신규 | 토큰 `--hm-sw-header-*`, Popup 안은 `--hm-sw-property-*`. 상태 표현은 [DESIGN_RULES.md](./DESIGN_RULES.md) §4(테두리형 gradient 링, 텍스트형 글자만 `#FFC600`). 안쪽 입력은 `SWHeaderInput` 재사용(예제 D) | 토큰 `--hm-sw-viewer-*` + 공유 `--hm-sw-header-*`(면·외곽선). 상태 표현은 [DESIGN_RULES.md](./DESIGN_RULES.md) §11 / VIEWER.md §2(Hover `#266651` 면, Active·Pressed 글자 `#FFC600`, Focus 2px `#FFC600`). 안쪽은 뷰어 공개 컴포넌트 재사용(예: 새 패널 콘텐츠 = `SWViewerField` + `SWViewerInput`, 새 Header 도구 = `custom` 항목 안 `SWViewerHeaderButton`, 아이콘 = `SWViewerIcon`) |
|
||||
| ③ 참고 값 없음 | 기존 HMDesign SW 규칙과 조화: Font Weight 400/500/700만, Light/Dark 없음, 전역 CSS(`html`·`body`·`*`) 금지, SW 공통 토큰 우선. 토큰에 없는 값은 결과 보고에 **"AI 구성 값 — 디자인 확인 필요"**로 표시 | 같음 |
|
||||
|
||||
- 뷰어 패널 안에 `@hm-design/ui` 컨트롤을 넣는 것은 `SWViewerPanel` `children`이 `ReactNode`라 가능하지만, `SWViewer*` 컨트롤로 안 될 때만 씁니다(별도 설치·외형 확인 필요, [VIEWER.md](./VIEWER.md) `SWViewerPanel` 절).
|
||||
- 어느 단계에서도 패키지 원본(`node_modules/@hm-design/sw`) 수정, `hm-sw-*` class 재사용·재정의, `dist` 코드·CSS 복사를 하지 않습니다. 새 class는 소비 프로젝트 접두사(예: `app-`)를 씁니다.
|
||||
|
||||
## 1. 작업 순서 (필수)
|
||||
|
||||
1. **먼저 검색한다.** 요청 기능을 [COMPONENT_CATALOG.md](./COMPONENT_CATALOG.md)의 공개 컴포넌트에서 찾는다.
|
||||
2. **있으면 재사용한다(1순위).** 완성형 Header가 필요하면 `SWHeader` 하나만 쓴다. 기존 Props(`hiddenControls`, `menuOrder`, `controls`, `documentOpenPlacement`, `leading`, `tools`, 각 데이터 배열·Callback)로 해결되는지 먼저 본다. 팝업·설정창은 `SWPopup`, 버튼·탭·토글은 `SWToolButton` / `SWToolGroup`이다.
|
||||
1. **먼저 검색한다.** §0에서 모드를 정하고, 요청 기능을 [COMPONENT_CATALOG.md](./COMPONENT_CATALOG.md)의 공개 컴포넌트(뷰어 모드는 §8과 [VIEWER.md](./VIEWER.md))에서 찾는다.
|
||||
2. **있으면 재사용한다(1순위).** 뷰어 모드는 `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`이다(VIEWER.md). 일반 모드에서 완성형 Header가 필요하면 `SWHeader` 하나만 쓴다. 기존 Props(`hiddenControls`, `menuOrder`, `controls`, `documentOpenPlacement`, `leading`, `tools`, 각 데이터 배열·Callback)로 해결되는지 먼저 본다. 팝업·설정창은 `SWPopup`, 버튼·탭·토글은 `SWToolButton` / `SWToolGroup`이다.
|
||||
- Popup 요청은 이렇게 판단한다: ① `SWPopup`이 프레임(외형·닫기·Escape·스크롤)을 제공한다 → ② 내용은 `children`으로 자유 구성(구조 제한 없음) → ③ 행 모양은 `SWPopupSection` / `SWPopupRow` + `SWHeaderInput` → ④ SW에 없는 컨트롤은 `@hm-design/ui`를 children에 → ⑤ 프레임을 다시 만들거나 없는 Props(`content`, `renderContent` 등)를 추측하지 않는다.
|
||||
3. **없으면 조합한다(2순위).** 개별 공개 컴포넌트(`SWHeaderHome`, `SWHeaderDocumentTitle`, `SWHeaderLayerMenu` …)를 `<SWTheme>` 안에 배치한다. 배치용 CSS만 소비 프로젝트에 작성한다([COMPOSITION_PATTERNS.md](./COMPOSITION_PATTERNS.md)).
|
||||
4. **조합으로도 안 될 때만 새로 만든다(3순위).** 새 컴포넌트는 **소비 프로젝트**에 작성하고, 공개 컴포넌트(예: `SWHeaderInput`)를 내부에 재사용하며, 외형은 공개 토큰 `--hm-sw-header-*`만 읽는다([DESIGN_RULES.md](./DESIGN_RULES.md), 예제 D).
|
||||
5. **새 디자인 값을 만들지 않는다.** 크기·색·간격은 토큰과 DESIGN_RULES의 확인값만 쓴다. 값이 없으면 추측하지 말고 사용자에게 확인한다.
|
||||
4. **조합으로도 안 될 때만 새로 만든다(3순위).** 새 컴포넌트는 **소비 프로젝트**에 작성하고, 공개 컴포넌트(예: `SWHeaderInput`)를 내부에 재사용하며, 외형은 공개 토큰 `--hm-sw-header-*`만 읽는다([DESIGN_RULES.md](./DESIGN_RULES.md), 예제 D). 뷰어 모드의 새 UI는 `--hm-sw-viewer-*`(+ 공유 `--hm-sw-header-*` 면·외곽선, [DESIGN_RULES.md](./DESIGN_RULES.md) §11)를 읽고 Header 버튼·패널 버튼·입력은 `SWViewerHeaderButton`·`SWViewerButton`·`SWViewerField` + `SWViewerInput`을 재사용한다. 모드별 상세는 §0.4. 뷰어 화면에 일반 모드 컨트롤 모양을 섞지 않는다.
|
||||
5. **토큰이 있는 값을 새로 만들지 않는다.** 크기·색·간격은 선택 모드의 토큰과 DESIGN_RULES(뷰어는 VIEWER.md도)의 확인값을 쓴다. 참고 값이 없을 때만 §0.4 ③으로 구성하고 "AI 구성 값 — 디자인 확인 필요"로 보고한다(화면 인상을 크게 바꾸는 값은 구현 전에 사용자에게 확인).
|
||||
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로 적지 않는다.
|
||||
@@ -45,7 +106,8 @@ import "@hm-design/sw/styles.css" // 앱 진입점에서 한 번
|
||||
|
||||
- `SWHeader` 밖에서 하위 컴포넌트를 쓰면 반드시 `<SWTheme>`로 감싼다. 토큰·글꼴·버튼 초기화가 이 범위에서만 적용된다.
|
||||
- 소비 코드는 `hm-sw-*` class를 붙이거나 재정의하지 않는다. 배치는 자기 class(`className`)와 `style`로 한다.
|
||||
- 외형 변경은 `--hm-sw-header-*` 토큰을 `SWTheme`/`SWHeader`의 `style`로 바꾸는 방법만 쓴다. 사용자 확정 면(파일명·객체 수정·속성 입력)은 기본값 유지를 권장한다.
|
||||
- 뷰어 모드 컴포넌트(`SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`)는 자체 `hm-sw-theme` 범위를 가지므로 `<SWTheme>`로 감싸지 않아도 된다. 소비 코드는 `hm-sw-viewer-*` class도 붙이거나 재정의하지 않는다.
|
||||
- 외형 변경은 `--hm-sw-header-*`(뷰어 모드는 `--hm-sw-viewer-*`) 토큰을 `SWTheme`/`SWHeader`(뷰어 모드는 해당 컴포넌트)의 `style`로 바꾸는 방법만 쓴다. 사용자 확정 면(파일명·객체 수정·속성 입력)은 기본값 유지를 권장한다.
|
||||
- Light/Dark 분기는 없다. SW 디자인은 하나다.
|
||||
|
||||
## 4. 판단 기록 남기기
|
||||
@@ -54,7 +116,9 @@ import "@hm-design/sw/styles.css" // 앱 진입점에서 한 번
|
||||
|
||||
| 요청 항목 | 판단 | 근거 |
|
||||
|---|---|---|
|
||||
| 예: SW 모드 | 뷰어 모드 | 설정 `HMDesign 사용 유형: SW 뷰어` / 요청 "DWG 뷰어" / 사용자 답변 중 실제 근거 |
|
||||
| 예: 레이어 | 재사용 | `SWHeaderLayerMenu` |
|
||||
| 예: 검색 | 신규(소비 프로젝트) | 카탈로그 MISSING. `SWHeaderInput` 재사용 + 토큰 기반 표면 |
|
||||
| 예: 뷰어 측정 패널 | 신규 콘텐츠(소비 프로젝트) | `SWViewerPanel` children에 `SWViewerField` + `SWViewerInput`. 토큰에 없는 값은 "AI 구성 값 — 디자인 확인 필요" |
|
||||
|
||||
새 컴포넌트를 SW 패키지 공식 컴포넌트로 승격할지는 별도 검토 대상이다. 임의로 패키지에 추가하지 않는다.
|
||||
@@ -7,7 +7,9 @@
|
||||
- **열림 상태:** Dropdown은 `open` / `onOpenChange`(Controlled)를 주지 않으면 내부 상태로 동작합니다.
|
||||
- **공통 키보드:** Click·Enter·Space 열기/닫기(Hover로는 열리지 않음), ArrowDown 열고 첫(현재) 항목 Focus, Arrow 이동, Escape·바깥 클릭·Tab 이탈 닫기(Escape는 Trigger로 Focus 복귀).
|
||||
- **검증 표시:** ✅ = 2026-10-19 독립 소비 프로젝트(Tarball 설치)에서 브라우저 검증, ◻ = 소비 검증 범위 밖(Storybook 검증 기록만 있음).
|
||||
- **무엇을 쓸까:** Header 전체 → `SWHeader`(1). Header 부품 조합 → 개별 컨트롤(2). 팝업·설정창·정보창 → `SWPopup`(3). 도구 막대·탭·토글 → `SWToolButton` / `SWToolGroup`(4). Slider·Switch·Badge·Progress·Dialog(모달)·Label·FilterBar는 SW에 없습니다 → `@hm-design/ui`를 그대로 씁니다(필요하면 `SWPopup` children 안에).
|
||||
- **먼저 모드:** SW 일반 모드(편집) / SW 뷰어 모드(도면 보기)를 [AI_USAGE.md](./AI_USAGE.md) §0으로 정합니다. **뷰어 모드는 §8(`SWViewer*`)만** 쓰고, 아래 §1~4는 일반 모드용입니다. 두 모드를 한 화면에 섞지 않습니다.
|
||||
- **무엇을 쓸까(일반 모드):** Header 전체 → `SWHeader`(1). Header 부품 조합 → 개별 컨트롤(2). 팝업·설정창·정보창 → `SWPopup`(3). 도구 막대·탭·토글 → `SWToolButton` / `SWToolGroup`(4). Slider·Switch·Badge·Progress·Dialog(모달)·Label·FilterBar는 SW에 없습니다 → `@hm-design/ui`를 그대로 씁니다(필요하면 `SWPopup` children 안에).
|
||||
- **무엇을 쓸까(뷰어 모드):** Header → `SWViewerHeader`(`groups` + `trailing`), Dropdown·우클릭 → `SWViewerMenu`, 팝업·설정창·모달 → `SWViewerPanel` + `SWViewerSection`/`SWViewerField`/`SWViewerSwitch`/`SWViewerSlider`/`SWViewerInput`/`SWViewerButton`, 상태 → `SWViewerStatus`(8).
|
||||
|
||||
## 1. 완성형 템플릿
|
||||
|
||||
@@ -65,18 +67,18 @@ SW 공식 기준 Header(Figma 26:8944, 1920 × 49). 로고 · 파일 · 객체
|
||||
|
||||
| 컴포넌트 | 용도 | 주요 Props | 크기·동작 | 검증 |
|
||||
|---|---|---|---|---|
|
||||
| `SWPopup` | 설정·정보·사용자 정의 Popup 프레임 | `title`(필수), `children`, `onClose`(닫기 버튼·Escape), `closeLabel`(기본 `닫기`), `autoFocus`(열릴 때 Focus, 안에서 닫히면 원래 위치로 복귀), `anchorRef`(기준 요소 아래 고정 Overlay), `style`·`className`·`div` 속성 | 폭 314, 제목줄 30, 높이는 콘텐츠(최대 화면 − 8px, `style.maxHeight`로 더 줄일 수 있음) → 본문 스크롤. Non-modal(Dim·Portal·Focus trap 없음) | ✅ |
|
||||
| `SWPopup` | 설정·정보·사용자 정의 Popup 프레임 | `title`(필수), `children`, `onClose`(닫기 버튼·Escape), `closeLabel`(기본 `닫기`), `titleActions`(제목 막대 닫기 버튼 앞 추가 버튼), `footer`(본문 뒤 고정 영역, 본문이 스크롤해도 보임), `autoFocus`(열릴 때 Focus, 안에서 닫히면 원래 위치로 복귀), `anchorRef`(기준 요소 아래 고정 Overlay), `style`·`className`·`div` 속성 | 폭 314, 제목줄 30, 높이는 콘텐츠(최대 화면 − 8px, `style.maxHeight`로 더 줄일 수 있음) → 본문 스크롤. Non-modal(Dim·Portal·Focus trap 없음) | ✅ |
|
||||
| `SWPopupSection` | 속성창 그룹 면(제목 + 내용) | `title`, `children`, `section` 속성 | 그룹 제목 700·70% 검정, 내용 면 `--hm-sw-property-content` | ✅ |
|
||||
| `SWPopupRow` | 속성창 한 줄(라벨 + 값) | `label`(필수), `htmlFor`, `children`(값 컨트롤, SW 필드는 `SWHeaderInput`), `unit`, `field`(`box` 기본 · `compact` · `none`), `numeric`(숫자 편집 On), `readOnly`, `disabled` | 행 최소 32, 라벨 72, 값 상자 28(Default·Hover 테두리, 숫자 편집 시 #0F0D0A). `compact` = 41px hug 숫자 필드 | ✅ |
|
||||
| `SWHeaderPropertyPanel` | 데이터 기반 속성창(2절). 같은 프레임이며 `children`도 받음 | 2절 | 같은 DOM·class | ✅ |
|
||||
|
||||
- **Escape·Focus:** Popup 안의 Escape는 그 Popup만 닫습니다. 바깥의 Escape는 가장 최근에 열리거나 사용한(Focus·클릭) Popup 하나만 닫습니다. Dropdown·편집 중인 Input처럼 Escape를 이미 처리한 요소(`preventDefault` / 전파 중단)가 있으면 Popup은 닫히지 않습니다.
|
||||
- **Popup 안 SW Dropdown:** 레이어·색상·선·문자·치수 Dropdown은 Popup 안에서 고정 위치 Overlay로 열려 스크롤 본문에 잘리지 않습니다(아래에 자리가 없으면 위로 열림). 단, Header용 어두운 필드 모양 그대로이므로 밝은 Popup 면과 대비가 다릅니다. 속성창 행 모양의 선택 필드가 필요하면 `SWHeaderPropertyPanel`의 `picker` 속성(`properties`)을 씁니다.
|
||||
- **Popup 하단 버튼(적용·취소)의 SW 전용 디자인은 아직 없습니다.** 필요하면 소비 프로젝트 버튼이나 `@hm-design/ui`의 `Button`을 `children`에 둡니다. 어두운 `SWToolButton`을 밝은 Popup에 강제로 쓰지 않습니다.
|
||||
- **Popup 하단 버튼(적용·취소)의 일반 모드 SW 전용 디자인은 아직 없습니다.** 자리는 `footer`(또는 `children`)이고 버튼은 소비 프로젝트 버튼이나 `@hm-design/ui`의 `Button`을 둡니다. 뷰어 전용 `SWViewerButton`을 일반 모드 Popup에 쓰지 않습니다. 어두운 `SWToolButton`을 밝은 Popup에 강제로 쓰지 않습니다.
|
||||
|
||||
## 4. 도구 막대 — 기존 SW 버튼 3종
|
||||
|
||||
새 디자인 값 없이 기존 SW 버튼 모양을 공개 버튼으로 씁니다(뷰어의 Model/Layout, Fit, 2.5D, 파일 열기 등). `SWHeader`의 `tools`·`leading` 안이나 `<SWTheme>` 안에 둡니다.
|
||||
**일반 모드** 도구 막대입니다. 새 디자인 값 없이 기존 SW 버튼 모양을 공개 버튼으로 씁니다(일반 모드 `SWHeader`에 더하는 Model/Layout, Fit, 2.5D, 파일 열기 등). 뷰어 모드 화면은 §8 `SWViewerHeader` 항목을 씁니다. `SWHeader`의 `tools`·`leading` 안이나 `<SWTheme>` 안에 둡니다.
|
||||
|
||||
| 컴포넌트 | 용도 | 주요 Props | 모양(기존 기준) | 검증 |
|
||||
|---|---|---|---|---|
|
||||
@@ -84,11 +86,11 @@ SW 공식 기준 Header(Figma 26:8944, 1920 × 49). 로고 · 파일 · 객체
|
||||
| `SWToolGroup` | 버튼 묶음 | `appearance`(`text` 기본 = 상세보기 묶음, `pill` = 인쇄·K pill), `label`(`text`의 12px 캡션·접근성 이름), `selection`(`single` = radiogroup, 화살표·Home·End로 이동·선택), `div` 속성 | 버튼 사이 1px 구분선(`text`), 내용 폭 pill | ✅ |
|
||||
|
||||
- 탭(Model / Layout)은 별도 컴포넌트 없이 `SWToolGroup selection="single"` + `SWToolButton pressed`입니다.
|
||||
- 상태 표시(로드 상태 등) 전용 SW 디자인은 아직 없습니다(상태 표시 컴포넌트는 디자인 확정 후 검토).
|
||||
- 일반 모드의 상태 표시(로드 상태 등) 전용 SW 디자인은 아직 없습니다(디자인 확정 후 검토). 뷰어 모드는 `SWViewerStatus`(§8)가 있으며 일반 모드 Header에 가져오지 않습니다.
|
||||
|
||||
## 5. 공개 타입
|
||||
|
||||
`SWHeaderProps`, 각 컴포넌트 Props(`SWHeaderHomeProps`, `SWHeaderDocumentTitleProps`, `SWHeaderLayerControlProps`, `SWHeaderLayerMenuProps`, `SWHeaderColorMenuProps`, `SWHeaderLineStyleMenuProps`, `SWHeaderTextStyleMenuProps`, `SWHeaderDimensionStyleMenuProps`, `SWHeaderInputProps`, `SWHeaderPropertiesProps`, `SWHeaderPropertyPanelProps`, `SWHeaderPropertyBarProps`, `SWHeaderActionsProps`, `SWHeaderWindowControlsProps`), `SWThemeProps`, `SWPopupProps`, `SWPopupSectionProps`, `SWPopupRowProps`, `SWToolButtonProps`, `SWToolButtonAppearance`, `SWToolGroupProps`, `SWHeaderMenuId`, `SWHeaderControlId`, `SWHeaderControlConfig`, `SWHeaderFrameControlId`, `SWHeaderSubControlId`, `SWHeaderHideableControlId`, `SWHeaderDocument`, `SWHeaderLayer`, `SWHeaderLayerValue`, `SWHeaderColorValue`, `SWHeaderColorOption`, `SWHeaderColorMode`, `SWHeaderColorInputValue`, `SWHeaderLineStyleValue`, `SWHeaderLineType`, `SWHeaderLineWeight`, `SWHeaderTextStyleValue`, `SWHeaderTextStyleOption`, `SWHeaderDimensionStyleValue`, `SWHeaderDimensionStyleOption`, `SWHeaderInputValueType`, `SWHeaderProperty`, `SWHeaderPropertyType`, `SWHeaderPropertyPicker`, `SWHeaderPropertyMenus`, `SWHeaderPropertyGroup`, `SWHeaderPropertySelection`, `SWHeaderPropertyShapeContent`, `SWHeaderPropertyShapeContext`.
|
||||
`SWHeaderProps`, 각 컴포넌트 Props(`SWHeaderHomeProps`, `SWHeaderDocumentTitleProps`, `SWHeaderLayerControlProps`, `SWHeaderLayerMenuProps`, `SWHeaderColorMenuProps`, `SWHeaderLineStyleMenuProps`, `SWHeaderTextStyleMenuProps`, `SWHeaderDimensionStyleMenuProps`, `SWHeaderInputProps`, `SWHeaderPropertiesProps`, `SWHeaderPropertyPanelProps`, `SWHeaderPropertyBarProps`, `SWHeaderActionsProps`, `SWHeaderWindowControlsProps`), `SWThemeProps`, `SWPopupProps`, `SWPopupSectionProps`, `SWPopupRowProps`, `SWToolButtonProps`, `SWToolButtonAppearance`, `SWToolGroupProps`, `SWHeaderMenuId`, `SWHeaderControlId`, `SWHeaderControlConfig`, `SWHeaderFrameControlId`, `SWHeaderSubControlId`, `SWHeaderHideableControlId`, `SWHeaderDocument`, `SWHeaderLayer`, `SWHeaderLayerValue`, `SWHeaderColorValue`, `SWHeaderColorOption`, `SWHeaderColorMode`, `SWHeaderColorInputValue`, `SWHeaderLineStyleValue`, `SWHeaderLineType`, `SWHeaderLineWeight`, `SWHeaderTextStyleValue`, `SWHeaderTextStyleOption`, `SWHeaderDimensionStyleValue`, `SWHeaderDimensionStyleOption`, `SWHeaderInputValueType`, `SWHeaderProperty`, `SWHeaderPropertyType`, `SWHeaderPropertyPicker`, `SWHeaderPropertyMenus`, `SWHeaderPropertyGroup`, `SWHeaderPropertySelection`, `SWHeaderPropertyShapeContent`, `SWHeaderPropertyShapeContext`. 뷰어 모드 타입은 §8.
|
||||
|
||||
## 6. 공개하지 않은 것 (사용 금지)
|
||||
|
||||
@@ -104,3 +106,28 @@ SW 공식 기준 Header(Figma 26:8944, 1920 × 49). 로고 · 파일 · 객체
|
||||
| 창 영역 배경 | 배경·테두리는 `SWHeader`의 창 영역에 있음 | 소비 레이아웃이 토큰으로 표면 작성(예제 B·C) |
|
||||
| Dropdown 위치 | `SWHeader` 안이면 헤더, 밖이면 뷰포트 안으로 좌우 보정. `SWPopup`·속성창 안이면 고정 위치 Overlay | Popup 밖에서는 부모에 `overflow: hidden`을 두지 않는다 |
|
||||
| 파일 열기 뒤 파일명 여백 | `SWToolButton appearance="document"` 바로 뒤의 파일명은 왼쪽 여백 12px(로고 아래가 아니므로) | 패키지 CSS가 처리. 소비 코드에서 조정하지 않음 |
|
||||
|
||||
## 8. 뷰어 모드 (`SWViewer*`)
|
||||
|
||||
SW **뷰어 모드** 전용 Export입니다(2026-10-19 추가, 참고 DWG/DXF 뷰어 실측 기준). 모드 선택은 [AI_USAGE.md](./AI_USAGE.md) §0, Props 상세·상태·금지 사항은 [VIEWER.md](./VIEWER.md), 토큰은 [DESIGN_RULES.md](./DESIGN_RULES.md) §11, 조합은 [COMPOSITION_PATTERNS.md](./COMPOSITION_PATTERNS.md) 7과 [예제 H](./examples/ExampleH-ViewerMode.tsx)를 봅니다. 일반 모드 화면에서는 쓰지 않습니다. `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`은 루트에 `hm-sw-theme`을 가지므로 `<SWTheme>`가 필요 없습니다.
|
||||
|
||||
| 컴포넌트 | 용도 | 주요 Props | 검증 |
|
||||
|---|---|---|---|
|
||||
| `SWViewerHeader` | 52px 뷰어 Header(로고 면 → 파일명 면 → 메뉴 그룹 → 오른쪽 끝), 반응형 More | `groups: SWViewerHeaderGroup[]`(필수), `onCommand(SWViewerCommand)`, `documentTitle`(`string \| null`), `documentPlaceholder`, `documentTooltip`, `document`, `logo`, `logoSrc`, `logoAlt`, `onHomeClick`, `trailing`, `moreLabel`, `toolbarLabel`, `<header>` 속성·`ref` | ◻ |
|
||||
| `SWViewerHeaderButton` | `trailing`·`custom` 항목용 Header 버튼(정보 버튼 등) | `label`(필수), `icon`, `iconOnly`(`true` = 32 × 40, `"compact"` = 34 × 34), `pressed`(주면 토글), `button` 속성 | ◻ |
|
||||
| `SWViewerMenu` | 단독 Dropdown·우클릭 메뉴(Header `type: "menu"`와 같은 메뉴) | `entries: SWViewerMenuEntry[]`, `open`, `onOpenChange`(필수), `anchorRef` 또는 `anchorPoint`, `align`(`start`/`end`), `width`, `surface`(`light` 기본 / `beige` = More 면), `label`, `onEntrySelect`, `initialFocus`(`first`/`menu`), `id`, `className` | ◻ |
|
||||
| `SWViewerIcon` | 직접 그린 아이콘에 SW 아이콘 외곽선(SVG stroke) 적용 | `children`(필수), `className` | ◻ |
|
||||
| `SWViewerPanel` | 뷰어 팝업·설정창·모달(프레임은 `SWPopup`) | `title`·`open`·`onClose`(필수), `closeLabel`, `headerActions`, `children`, `footer`, `width`(314)·`height`(420 / `"auto"`)·`minWidth`·`minHeight`, `defaultPosition`(`{ left, top }` 또는 `SWViewerPanelPlacement`), `inset`, `strategy`(`fixed`/`absolute`), `draggable`, `resizable`, `collapsible`, `defaultCollapsed`, `collapsed`, `onCollapsedChange`, `modal`, `autoFocus`, `onPositionChange`, `onSizeChange`, `div` 속성 | ◻ |
|
||||
| `SWViewerSection` | 패널 콘텐츠 묶음(12px 700 제목) | `title`, `surface`(`card` 기본 / `plain`), `children`, `section` 속성 | ◻ |
|
||||
| `SWViewerField` | 라벨 + 컨트롤 행 | `label`(필수), `children`(노드 또는 `(id) => 노드`), `htmlFor`, `layout`(`inline` 기본 / `stacked`), `unit`, `below`, `disabled` | ◻ |
|
||||
| `SWViewerSwitch` | 스위치 | `checked`(필수), `onCheckedChange`, `button` 속성 | ◻ |
|
||||
| `SWViewerSlider` | 슬라이더(native range) | `value`·`min`·`max`(필수), `step`, `onValueChange`, `input` 속성 | ◻ |
|
||||
| `SWViewerInput` | 28px 패널 Input(native input) | `input` 속성 전체 | ◻ |
|
||||
| `SWViewerButton` | 패널 버튼 | `variant`(`outline` / `primary` / `ghost`), `tone`(`"green"`), `icon`, `button` 속성 | ◻ |
|
||||
| `SWViewerBadge` | 개수 Badge | `children`(필수), `span` 속성 | ◻ |
|
||||
| `SWViewerHint` | 12px 보조 설명 | `p` 속성 | ◻ |
|
||||
| `SWViewerStatus` | Header 불러오기 상태(`trailing`) | `state: SWViewerStatusState`(`idle`/`loading`/`ready`/`error`, 필수), `label`, `detail`, `div` 속성 | ◻ |
|
||||
|
||||
- **공개 타입:** `SWViewerHeaderProps`, `SWViewerHeaderButtonProps`, `SWViewerMenuProps`, `SWViewerIconProps`, `SWViewerPanelProps`, `SWViewerPanelPlacement`(`"top-end"` / `"top-start"` / `"center"`), `SWViewerSectionProps`, `SWViewerFieldProps`, `SWViewerSwitchProps`, `SWViewerSliderProps`, `SWViewerInputProps`, `SWViewerButtonProps`, `SWViewerBadgeProps`, `SWViewerStatusProps`, `SWViewerStatusState`, `SWViewerHeaderItem`(`button`·`toggle`·`menu`·`tabs`·`switch`·`custom`), `SWViewerHeaderGroup`, `SWViewerMenuEntry`(`item`·`checkbox`·`radio`·`submenu`·`label`·`separator`), `SWViewerCommand`(`id`, `itemId`, `value`).
|
||||
- **검증 표시:** 뷰어 Export는 이 카탈로그 기준의 독립 소비 프로젝트(Tarball) 브라우저 검증 기록이 없어 ◻입니다. 예제 H는 공개 Export만 사용합니다.
|
||||
- 상세 크기·상태는 [VIEWER.md](./VIEWER.md) §2~4가 기준입니다. 이 표에 없는 Props(`items`, `content`, `renderBody` 등)는 없습니다.
|
||||
@@ -1,17 +1,20 @@
|
||||
# SW 조합 패턴
|
||||
|
||||
모든 패턴은 공개 Export만 사용합니다. 전체 코드는 [examples/](./examples)에 있으며, 설치된 패키지에서 꺼낸 그대로 독립 React 19 + TypeScript + Vite 프로젝트의 `tsc`·Production Build·브라우저 검증을 통과했습니다(2026-10-19).
|
||||
모든 패턴은 공개 Export만 사용합니다. 전체 코드는 [examples/](./examples)에 있으며, 설치된 패키지에서 꺼낸 그대로 독립 React 19 + TypeScript + Vite 프로젝트의 `tsc`·Production Build·브라우저 검증을 통과했습니다(2026-10-19, 예제 A~F. 뷰어 모드 예제 H는 공개 Export만 쓰지만 같은 독립 소비 검증 기록은 이 문서에 없습니다).
|
||||
|
||||
## 0. 어떤 패턴을 고를까
|
||||
|
||||
| 요청 | 패턴 |
|
||||
|---|---|
|
||||
| 기존 SW Header 전체(일부 부품 제거·메뉴 순서 변경 포함) | 1. 완성형 |
|
||||
| 기존 컨트롤 일부만, 다른 배치·순서 | 2. 조합 Header |
|
||||
| 기존 Dropdown을 툴바·패널 등 다른 곳에 | 3. 개별 컨트롤 |
|
||||
| 패키지에 없는 기능 | 4. 확장(소비 프로젝트 신규 컴포넌트) |
|
||||
| SW Popup 디자인의 설정창·정보창·사용자 정의 폼 | 5. Popup(외형 고정, 콘텐츠 자유) |
|
||||
| 로고 옆 파일 열기, 뷰어 도구 막대(Model/Layout, Fit, 2.5D) | 6. 파일 열기 + 도구 막대 |
|
||||
먼저 SW 모드를 정합니다([AI_USAGE.md](./AI_USAGE.md) §0). 1~6은 **SW 일반 모드**, 7은 **SW 뷰어 모드**이며 한 화면에서 섞지 않습니다.
|
||||
|
||||
| 요청 | 모드 | 패턴 |
|
||||
|---|---|---|
|
||||
| 기존 SW Header 전체(일부 부품 제거·메뉴 순서 변경 포함) | 일반 | 1. 완성형 |
|
||||
| 기존 컨트롤 일부만, 다른 배치·순서 | 일반 | 2. 조합 Header |
|
||||
| 기존 Dropdown을 툴바·패널 등 다른 곳에 | 일반 | 3. 개별 컨트롤 |
|
||||
| 패키지에 없는 기능 | 일반(뷰어는 7 + AI_USAGE §0.4) | 4. 확장(소비 프로젝트 신규 컴포넌트) |
|
||||
| SW Popup 디자인의 설정창·정보창·사용자 정의 폼 | 일반 | 5. Popup(외형 고정, 콘텐츠 자유) |
|
||||
| 일반 모드 `SWHeader`에 로고 옆 파일 열기·도구 막대(Model/Layout, Fit, 2.5D) 추가 | 일반 | 6. 파일 열기 + 도구 막대 |
|
||||
| 뷰어·DWG/DXF 보기·도면 뷰어·읽기 전용 화면(Header 메뉴, 패널, 모달, 불러오기 상태) | 뷰어 | 7. 뷰어 모드 기본 조합 |
|
||||
|
||||
## 1. 완성형 SW Header — [ExampleA-DefaultHeader.tsx](./examples/ExampleA-DefaultHeader.tsx)
|
||||
|
||||
@@ -43,7 +46,7 @@
|
||||
</SWTheme>
|
||||
```
|
||||
|
||||
- 간소화 Viewer: [ExampleB-ViewerHeader.tsx](./examples/ExampleB-ViewerHeader.tsx) — 로고 → 파일 → 레이어 → 색상 → K.
|
||||
- 간소화 Header(일반 모드): [ExampleB-ViewerHeader.tsx](./examples/ExampleB-ViewerHeader.tsx) — 로고 → 파일 → 레이어 → 색상 → K. 파일명·주석의 "Viewer"는 과거 이름이며 SW 뷰어 모드가 아닙니다(뷰어 모드는 7).
|
||||
- 기능 중심: [ExampleC-FeatureHeader.tsx](./examples/ExampleC-FeatureHeader.tsx) — 파일 → 선 → 문자 → 치수스타일 → 인쇄.
|
||||
- 순서는 JSX 순서입니다(DOM·Tab 순서 동일). CSS `order`로 바꾸지 않습니다.
|
||||
- 로고 없이 파일 면이 처음이면 왼쪽 테두리가 없으므로 wrapper에 1px 테두리를 둡니다(예제 C `app-sw-file-edge`).
|
||||
@@ -102,6 +105,8 @@
|
||||
|
||||
## 6. 파일 열기 + 도구 막대 — [ExampleF-ViewerToolbar.tsx](./examples/ExampleF-ViewerToolbar.tsx)
|
||||
|
||||
**일반 모드 Header에 도구 막대를 더한 구성**입니다. 예제 파일명·주석의 "viewer"는 과거 이름이며 SW 뷰어 모드가 아닙니다. "뷰어"·"도면 보기" 화면은 7(`SWViewer*`)을 씁니다.
|
||||
|
||||
```tsx
|
||||
<SWHeader documentTitle={name} documents={documents} documentOpenPlacement="header" documentOpenLabel="파일 열기" onDocumentOpen={open}
|
||||
controls={[{ id: "document" }, { id: "layer" }, { id: "color" }, { id: "popupGuide" }]}
|
||||
@@ -116,10 +121,64 @@
|
||||
- 지원하지 않는 기능은 `hiddenControls`로 뺀다(`documentNew`, `documentOpen`, `layerFreeze`, `layerLock`). 가짜 버튼을 두지 않는다.
|
||||
- `SWHeader` 없이 같은 순서가 필요하면: `SWHeaderHome` → `SWToolButton appearance="document"` → `SWHeaderDocumentTitle showOpen={false}`(사선 접점·12px 여백은 패키지가 처리). 이 경우 More는 없다.
|
||||
|
||||
## 7. 하지 말 것
|
||||
## 7. 뷰어 모드 기본 조합 — [ExampleH-ViewerMode.tsx](./examples/ExampleH-ViewerMode.tsx)
|
||||
|
||||
SW **뷰어 모드**(도면 보기) 화면입니다. 모드 선택은 [AI_USAGE.md](./AI_USAGE.md) §0, Props·상태는 [VIEWER.md](./VIEWER.md), 토큰은 [DESIGN_RULES.md](./DESIGN_RULES.md) §11. 이 패턴에는 1~6의 일반 모드 컴포넌트(`SWHeader`, `SWPopup`, `SWToolButton` …)를 섞지 않습니다.
|
||||
|
||||
```tsx
|
||||
const groups: SWViewerHeaderGroup[] = [
|
||||
{ id: "file", label: "파일", items: [
|
||||
{ type: "button", id: "open", label: "파일 열기", icon: icons.open, iconOnlyBelow: 560 },
|
||||
{ type: "menu", id: "samples", label: "샘플", moreLabel: "샘플 도면", collapseBelow: 1180, entries: sampleEntries },
|
||||
] },
|
||||
{ id: "space", label: "도면 공간", surface: "field", hidden: !fileName, items: [
|
||||
{ type: "tabs", id: "space", label: "모델과 배치 선택", collapseBelow: 1180, value: space, onValueChange: setSpace, options },
|
||||
] },
|
||||
{ id: "view", label: "화면 보기", surface: "field", items: [
|
||||
{ type: "button", id: "fit", label: "전체 보기", icon: icons.fit, iconOnlyBelow: 560, disabled: !fileName },
|
||||
{ type: "switch", id: "depth", label: "2.5D", checked: depth, collapseBelow: 1180, onCheckedChange: setDepth },
|
||||
] },
|
||||
{ id: "panels", label: "패널", placement: "end", items: [
|
||||
{ type: "toggle", id: "options", label: "설정", icon: icons.options, pressed: optionsOpen, collapseBelow: 900, onPressedChange: setOptionsOpen },
|
||||
] },
|
||||
]
|
||||
|
||||
<SWViewerHeader documentTitle={fileName} groups={groups} onCommand={runCommand}
|
||||
trailing={<>
|
||||
<SWViewerStatus state={fileName ? "ready" : "idle"} />
|
||||
<SWViewerHeaderButton iconOnly icon={icons.info} label="정보" onClick={() => setAbout(true)} />
|
||||
</>} />
|
||||
<SWViewerPanel title="옵션" open={optionsOpen} onClose={() => setOptionsOpen(false)} width={340} height="auto"
|
||||
footer={<SWViewerButton variant="primary" onClick={apply}>적용</SWViewerButton>}>
|
||||
<SWViewerSection title="표시">
|
||||
<SWViewerField label="그리드">{id => <SWViewerSwitch id={id} checked={grid} onCheckedChange={setGrid} />}</SWViewerField>
|
||||
<SWViewerField label="줌 속도" layout="stacked" below={<SWViewerSlider aria-label="줌 속도" value={zoom} min={0.2} max={3} step={0.1} onValueChange={setZoom} />}>
|
||||
{id => <SWViewerInput id={id} type="number" value={zoom} onChange={e => setZoom(Number(e.currentTarget.value))} />}
|
||||
</SWViewerField>
|
||||
</SWViewerSection>
|
||||
</SWViewerPanel>
|
||||
<SWViewerPanel modal title="정보" open={about} onClose={() => setAbout(false)} width={360} height="auto" resizable={false} collapsible={false}
|
||||
footer={<SWViewerButton variant="primary" onClick={() => setAbout(false)}>확인</SWViewerButton>}>…</SWViewerPanel>
|
||||
```
|
||||
|
||||
| 구성 | 사용 |
|
||||
|---|---|
|
||||
| Header 메뉴 | `groups` 데이터: 파일(`button`·`menu`), 도면 공간(`tabs`, `surface: "field"`), 화면 보기(`button`·`switch`, `field`), 패널 토글(`toggle`, `placement: "end"`) |
|
||||
| 오른쪽 끝 | `trailing`: `SWViewerStatus` + `SWViewerHeaderButton iconOnly` |
|
||||
| 도구 창 | 비모달 `SWViewerPanel`(드래그·크기 조절·접기 기본). 여러 개면 `inset`·`defaultPosition`으로 겹치지 않게 |
|
||||
| 확인·정보 | `SWViewerPanel modal` + `footer`의 `SWViewerButton variant="primary"` |
|
||||
| 패널 내용 | `SWViewerSection` > `SWViewerField` > `SWViewerSwitch` / `SWViewerSlider` / `SWViewerInput`, 목록은 `surface="plain"` + 프로그램 목록, 설명 `SWViewerHint` |
|
||||
| 반응형 | 참고값 `collapseBelow` 1180(샘플·도면 공간·2.5D) / 900(패널 토글), `iconOnlyBelow` 560(파일 열기·전체 보기) |
|
||||
| 우클릭 메뉴 | `SWViewerMenu` + `anchorPoint` |
|
||||
|
||||
- 상태(파일명·패널 열림·탭 값)는 프로그램이 가지고, 명령은 각 Callback 또는 `onCommand` 한 곳에서 받는다. 도면 영역 높이·렌더러 크기는 앱 레이아웃 담당(VIEWER.md §7).
|
||||
- 없는 기능은 메뉴를 만들지 않거나 `disabled` + 미연결 보고. 패키지에 없는 UI는 [AI_USAGE.md](./AI_USAGE.md) §0.4 뷰어 열을 따른다.
|
||||
|
||||
## 8. 하지 말 것
|
||||
|
||||
- `hm-sw-*` class를 소비 코드에 쓰거나 CSS로 덮어쓰기
|
||||
- `dist` 구현·`styles.css` 블록 복사로 같은 컴포넌트 재작성
|
||||
- `@hm-design/sw/dist/...`·`src/...` 내부 경로 Import
|
||||
- 문서에 없는 Props 추측, 새 색·크기 값 도입
|
||||
- 같은 화면에 `SWHeader`와 조합 Header를 겹쳐 두 개의 Header 만들기
|
||||
- 같은 화면에 `SWHeader`와 `SWViewerHeader`를 함께 두기, 일반 모드 화면에 `SWViewer*` 사용, 뷰어 화면에서 `SWHeader`·`SWPopup` 재스타일(AI_USAGE §0.3)
|
||||
@@ -1,10 +1,11 @@
|
||||
# SW 디자인 규칙
|
||||
|
||||
출처: `@hm-design/sw` `styles.css`(원본 `src/theme/sw.css`)의 토큰과 규칙, Figma 이지빔 SW `rj6wpsfk24lOWvWiVRAANP` node `26:8944`와 사용자 확정값. 이 문서에 없는 값은 확정값이 아닙니다. 새 컴포넌트에 임의 값을 만들지 말고 아래 토큰을 `var(--…)`로 읽으세요.
|
||||
출처: `@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는 `@hm-design/ui` 토큰을 쓰지 않습니다. UI 패키지 토큰을 복제하거나 섞지 않습니다.
|
||||
- Light/Dark 분기 없음. 전역 선택자(`html`, `body`, `*`) 없음.
|
||||
- **모드:** §1~10은 SW **일반 모드**(`SWHeader`·`SWPopup`·`SWToolButton`) 기준입니다. SW **뷰어 모드**(`SWViewer*`)의 토큰·상태는 §11과 [VIEWER.md](./VIEWER.md)를 봅니다. 모드 선택·혼합 금지는 [AI_USAGE.md](./AI_USAGE.md) §0.
|
||||
|
||||
## 1. 크기·간격
|
||||
|
||||
@@ -120,3 +121,31 @@ Container `hm-sw-header` 기준 Breakpoint: **< 1800** 선/문자/치수스타
|
||||
6. `hm-sw-*` class를 새로 쓰거나 덮어쓰지 않는다(자기 접두사 사용, 예: `app-`).
|
||||
7. 버튼·탭·토글이면 먼저 `SWToolButton`의 세 모양(§9)으로 해결되는지 본다. 팝업·설정창이면 `SWPopup` + `SWPopupSection` / `SWPopupRow`(§8).
|
||||
8. 팝업 안의 새 콘텐츠는 §8의 Popup 토큰(`--hm-sw-property-*`)만 읽는다. Header용 어두운 토큰을 밝은 Popup 면에 섞지 않는다.
|
||||
|
||||
## 11. 뷰어 모드 토큰·상태 요약 (`SWViewer*` 전용)
|
||||
|
||||
출처: `@hm-design/sw` `styles.css`(원본 `src/theme/sw-viewer.css`)에서 그대로 옮긴 값입니다. 사용 규칙·크기 상세는 [VIEWER.md](./VIEWER.md), 모드 선택·혼합 금지는 [AI_USAGE.md](./AI_USAGE.md) §0입니다. §1~10은 일반 모드 기준이며 이 절의 토큰은 **뷰어 모드 신규 UI에서만** 읽습니다(일반 모드 신규 UI에 쓰지 않음). 토큰은 `.hm-sw-header`, `.hm-sw-theme`에 선언됩니다.
|
||||
|
||||
| 영역 | 토큰 = 기본값 |
|
||||
|---|---|
|
||||
| Header | `--hm-sw-viewer-height` 52px, `--hm-sw-viewer-background` `linear-gradient(180deg, #266651 0%, #123328 45%, #0a221d 100%)`, `--hm-sw-viewer-border-color` #071e18, `--hm-sw-viewer-text` #fff, `--hm-sw-viewer-muted` #bddfd4, `--hm-sw-viewer-accent` #ffc600, `--hm-sw-viewer-hover` #266651 |
|
||||
| 로고 면 | `--hm-sw-viewer-brand-width` 72px, `--hm-sw-viewer-brand-empty-width` 24px(로고 없음), `--hm-sw-viewer-brand-top` #123328, `--hm-sw-viewer-brand-middle` #205241, `--hm-sw-viewer-brand-bottom` #071e18 |
|
||||
| 크기·글자 | `--hm-sw-viewer-gap` 4px, `--hm-sw-viewer-radius` 4px, `--hm-sw-viewer-control-height` 40px, `--hm-sw-viewer-button-height` 34px, `--hm-sw-viewer-font-size` 14px, `--hm-sw-viewer-label-size` 11px, `--hm-sw-viewer-icon-size` 16px, `--hm-sw-viewer-disabled-opacity` 0.6 |
|
||||
| Header 스위치·아이콘 | `--hm-sw-viewer-switch-off` #0a221d, `--hm-sw-viewer-switch-bevel` `inset 0 1px 0 rgba(255, 255, 255, 0.1), inset 0 -1px 1px rgba(0, 0, 0, 0.25)`, `--hm-sw-viewer-icon-outline-color` = `var(--hm-sw-header-text-outline-color)`, `--hm-sw-viewer-icon-outline-width` 1px |
|
||||
| Dropdown·More | `--hm-sw-viewer-menu-background` #fff, `--hm-sw-viewer-menu-border-color` #dedbd2, `--hm-sw-viewer-menu-text` #0a221d, `--hm-sw-viewer-menu-muted` #6e6759, `--hm-sw-viewer-menu-highlight` `rgba(189, 223, 212, 0.45)`, `--hm-sw-viewer-menu-highlight-text` #123328, `--hm-sw-viewer-menu-shadow` `0 0 12px rgba(0, 0, 0, 0.2)`, `--hm-sw-viewer-menu-item-height` 36px, `--hm-sw-viewer-more-background` #f5f0e5, `--hm-sw-viewer-more-border-color` #897445 |
|
||||
| 패널 콘텐츠 | `--hm-sw-viewer-panel-background` = `var(--hm-sw-property-surface)`, `--hm-sw-viewer-panel-field-background` = `var(--hm-sw-property-content)`, `--hm-sw-viewer-panel-inner-border` = `var(--hm-sw-property-inner-border)`, `--hm-sw-viewer-panel-text` = `var(--hm-sw-property-label)`, `--hm-sw-viewer-panel-heading` #3e3523, `--hm-sw-viewer-panel-label` #6e6759, `--hm-sw-viewer-panel-primary` #123328, `--hm-sw-viewer-panel-switch-off` = `var(--hm-sw-property-inner-border)`, `--hm-sw-viewer-panel-switch-on` #266651, `--hm-sw-viewer-panel-badge-background` = `var(--hm-sw-property-table)`, `--hm-sw-viewer-panel-overlay` `rgba(0, 0, 0, 0.1)`, `--hm-sw-viewer-panel-spacing` 12px |
|
||||
|
||||
- **공유 토큰(모드 혼합 아님):** 뷰어 Header의 파일명·객체 수정·속성 면은 `--hm-sw-header-document-*`, `--hm-sw-header-object-*`, `--hm-sw-header-property-*`를, 글자 외곽선은 `--hm-sw-header-text-outline`·`--hm-sw-header-label-outline`을 그대로 읽습니다(§2·§3). 패널 제목 막대 추가 버튼(`ghost`)의 Hover·Focus 색은 `--hm-sw-header-selected-color`입니다.
|
||||
|
||||
| 상태 | Header 항목(button·toggle·menu·tabs·switch) | 패널 콘텐츠 |
|
||||
|---|---|---|
|
||||
| Hover | 면 `--hm-sw-viewer-hover`(#266651) | `outline` 버튼: 면 `--hm-sw-viewer-panel-field-background` / `primary`: 면·테두리 `--hm-sw-viewer-hover` / `tone="green"`: 면·테두리 `--hm-sw-viewer-hover`, 글자 #fff / `ghost`: 글자만 `--hm-sw-header-selected-color` |
|
||||
| Active·Pressed·열림·선택 탭 | 글자·아이콘 `--hm-sw-viewer-accent`(#ffc600), 선택 박스 없음 | `tone="green"` 누르는 동안: 면·테두리 `--hm-sw-viewer-panel-primary`, 글자 #fff |
|
||||
| Checked(스위치) | 면 `--hm-sw-viewer-accent`, thumb `--hm-sw-viewer-switch-off` | 면 `--hm-sw-viewer-panel-switch-on` |
|
||||
| Focus | 2px solid `--hm-sw-viewer-accent` 외곽선 | 버튼·Input·Slider: 2px solid `--hm-sw-viewer-panel-switch-on` 외곽선 |
|
||||
| Disabled | `--hm-sw-viewer-disabled-opacity`(0.6) | 버튼·Input·Field 0.5 |
|
||||
| Dropdown 항목 | 면 `--hm-sw-viewer-menu-highlight`, 글자 `--hm-sw-viewer-menu-highlight-text`(Focus·Hover·서브메뉴 열림), Disabled 0.5 | — |
|
||||
| 상태 표시 | `SWViewerStatus`: 글자 `--hm-sw-viewer-muted` 11px 400, `error`는 `--hm-sw-viewer-accent`, `loading` 아이콘 회전 | — |
|
||||
|
||||
- **Typography(뷰어):** Header 항목 14px 500, 캡션·개수·상태 11px 400, 패널 필드 라벨 14px 500, Section 제목 12px 700, 패널 버튼·Badge 12px 500, Input 12px. Font Weight는 400/500/700만 씁니다.
|
||||
- **뷰어 신규 컴포넌트 체크리스트:** ① VIEWER.md·§8 컴포넌트로 해결되는지 먼저 본다 ② 위 토큰을 `var(--…)`로만 읽고 일반 모드 전용 모양(§8 `SWPopupRow`, §9 `SWToolButton`)을 섞지 않는다 ③ 상태는 위 표대로 ④ 토큰에 없는 값은 결과 보고에 "AI 구성 값 — 디자인 확인 필요"로 적는다 ⑤ `hm-sw-viewer-*` class를 쓰거나 덮어쓰지 않는다.
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
기준: 2026-10-19, 참고 DWG/DXF 뷰어(`dwg-dxf-viewer-hm`) 상단 메뉴·팝업을 같은 해상도(1440 × 900)에서 실측해 패키지 컴포넌트로 옮긴 결과입니다. 아래 이름은 모두 `from "@hm-design/sw"` 공개 Export이고 CSS는 `@hm-design/sw/styles.css` 한 개입니다. 예제: [examples/ExampleH-ViewerMode.tsx](./examples/ExampleH-ViewerMode.tsx).
|
||||
|
||||
> **모드 선택 먼저:** 이 문서는 SW **뷰어 모드** 전용입니다. 화면이 뷰어 모드인지는 [AI_USAGE.md](./AI_USAGE.md) §0(설정 `HMDesign 사용 유형: SW 뷰어` → 요청 문구 → 불명확하면 질문)으로 정합니다. 전체 Export 목록은 [COMPONENT_CATALOG.md](./COMPONENT_CATALOG.md) §8, 토큰·상태 요약은 [DESIGN_RULES.md](./DESIGN_RULES.md) §11, 조합은 [COMPOSITION_PATTERNS.md](./COMPOSITION_PATTERNS.md) 7입니다.
|
||||
>
|
||||
> **일반 모드 금지 사항(상호 참조):** 뷰어 화면에 `SWHeader`·`SWPopup`·`SWPopupSection`·`SWPopupRow`·`SWToolButton`·`SWToolGroup`·`SWHeaderPropertyPanel`을 쓰거나 재스타일하지 않고, 일반 모드 화면에 `SWViewer*`와 `--hm-sw-viewer-*` 토큰을 쓰지 않습니다. `SWViewerPanel`이 내부에서 `SWPopup` 프레임을 렌더링하는 것과 두 Header가 `--hm-sw-header-document-*`·`object-*`·`property-*`·외곽선 토큰을 공유하는 것은 패키지 구현이며 모드 혼합이 아닙니다([AI_USAGE.md](./AI_USAGE.md) §0.3). 패키지에 없는 뷰어 UI는 [AI_USAGE.md](./AI_USAGE.md) §0.4 뷰어 열을 따릅니다.
|
||||
|
||||
## 1. 언제 무엇을 쓰나
|
||||
|
||||
| 화면 | 사용 | 쓰지 않음 |
|
||||
@@ -66,6 +70,7 @@
|
||||
| `autoFocus?` | 열 때 패널로 Focus, 닫을 때 원래 위치로 복귀(기본 true) |
|
||||
|
||||
- Escape는 Focus가 패널 안에 있을 때 그 패널만 닫습니다. 비모달 패널은 바깥 클릭으로 닫히지 않습니다(참고 뷰어와 동일, 도구 창). 마지막으로 누른 패널이 맨 앞으로 옵니다.
|
||||
- **콘텐츠 우선순위:** `children`·`footer`는 타입상 `ReactNode`이고 소스 주석도 자유 콘텐츠(“any component”)라고 적습니다. 그래도 기본은 `SWViewerSection`·`SWViewerField`·`SWViewerSwitch`·`SWViewerSlider`·`SWViewerInput`·`SWViewerButton`·`SWViewerBadge`·`SWViewerHint` 우선입니다. 이것으로 안 되는 컨트롤(예: Select·Checkbox·표)만 `@hm-design/ui` 컴포넌트나 소비 프로젝트 요소를 넣을 수 있습니다. `@hm-design/ui`는 SW 패키지 dependency가 아니어서 별도 설치(사용 유형 혼합)가 필요하고, `SWPopup`과 달리 뷰어 패널 안 `@hm-design/ui` 외형 정합성은 문서화·검증 기록이 없으므로 결과 보고에 “디자인 확인 필요”로 적습니다. Header 안에는 `@hm-design/ui` DropdownMenu 등을 직접 두지 않습니다(§1 표).
|
||||
- **콘텐츠 교체:** 같은 프레임에 다른 `children`을 넣습니다(레이어 목록 / 옵션 / 속성 / 입력 폼 — Storybook `Popup Content Variants`). 프레임을 복사하거나 `hm-sw-viewer-*` class로 새 팝업을 만들지 않습니다.
|
||||
|
||||
## 5. 올바른 사용
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
## HMDesign 디자인 시스템
|
||||
|
||||
<!-- HMDesign 패키지의 ai/AGENTS_SNIPPET.md에서 복사. 아래 "사용 유형"을 프로젝트에 맞게 고치거나, 정하지 않았으면 그 줄을 지운다. -->
|
||||
<!-- HMDesign 패키지의 ai/AGENTS_SNIPPET.md에서 복사. 아래 "사용 유형"을 하나로 고치거나(SW는 모드까지: SW 일반 / SW 뷰어), 정하지 않았으면 그 줄을 지운다. -->
|
||||
|
||||
HMDesign 사용 유형: Web | SW | OrgChart | 혼합(영역별로 적기)
|
||||
HMDesign 사용 유형: Web | SW 일반 | SW 뷰어 | OrgChart | 혼합(영역별로 적기, SW 영역은 모드까지)
|
||||
|
||||
화면·컴포넌트를 구현하거나 수정하기 전에 다음을 지킨다.
|
||||
|
||||
1. 설치된 HMDesign 패키지의 공통 가이드를 먼저 읽는다: `node_modules/@hm-design/<설치된 패키지>/ai/AI_GUIDE.md` (`ui`, `sw`, `org-chart`, `org-chart-react` 중 아무 사본이나 내용이 같다).
|
||||
2. 위 "사용 유형"이 없고 요청으로도 정할 수 없으면 코드 작성 전에 "어떤 HMDesign 디자인 시스템을 사용하시겠습니까? 1. Web 2. SW 3. OrgChart 4. 혼합 사용"을 묻는다. 정해져 있으면 다시 묻지 않는다.
|
||||
2. 위 "사용 유형"이 없고 요청으로도 정할 수 없으면 코드 작성 전에 "어떤 HMDesign 디자인 시스템을 사용하시겠습니까? 1. Web 2. SW (일반 모드 / 뷰어 모드) 3. OrgChart 4. 혼합 사용"을 묻는다. SW인데 모드(일반/뷰어)가 불명확하면 "SW 화면을 어떤 모드로 만들까요? 1. SW 일반 모드 2. SW 뷰어 모드"를 묻는다(근거는 `@hm-design/sw/ai/AI_USAGE.md` §0). 정해져 있으면 다시 묻지 않는다.
|
||||
3. 선택한 패키지의 `ai/AI_USAGE.md` → `COMPONENT_CATALOG.md` → `DESIGN_RULES.md` → `COMPOSITION_PATTERNS.md` 순으로 필요한 절을 읽는다.
|
||||
- Web: `node_modules/@hm-design/ui/ai/`
|
||||
- SW: `node_modules/@hm-design/sw/ai/`
|
||||
- SW: `node_modules/@hm-design/sw/ai/` (뷰어 모드는 `AI_USAGE.md` §0 다음 `VIEWER.md`)
|
||||
- OrgChart: `node_modules/@hm-design/org-chart/ai/` (React는 `node_modules/@hm-design/org-chart-react/ai/AI_USAGE.md`도)
|
||||
4. 기존 컴포넌트 → Props → 조합 → (없는 부분만) 패키지 토큰으로 신규 구현 순서를 지킨다. 패키지 파일 수정·내부 경로 import·구현 복사·새 디자인 값 생성은 하지 않는다.
|
||||
5. Web / SW / OrgChart 스타일을 영역별로 분리하고, 완료 후 AI_GUIDE의 결과 보고 형식으로 재사용·신규·토큰·검증·NOT VERIFIED를 보고한다.
|
||||
4. 선택한 유형·모드 안에서 기존 컴포넌트 → Props → 조합 → (없는 부분만) 그 모드의 토큰·스타일로 신규 → (참고 값도 없으면) HMDesign 공통 규칙과 조화되게 구성하고 "AI 구성 값"으로 보고하는 순서를 지킨다. 패키지 파일 수정·내부 경로 import·구현 복사는 하지 않는다.
|
||||
5. Web / SW 일반 / SW 뷰어 / OrgChart 스타일을 영역별로 분리하고(한 SW 화면에 일반·뷰어 컴포넌트를 섞지 않음), 완료 후 AI_GUIDE의 결과 보고 형식으로 유형·모드, 재사용·신규·토큰·AI 구성 값·검증·NOT VERIFIED를 보고한다.
|
||||
+92
-32
@@ -2,18 +2,19 @@
|
||||
|
||||
> 이 파일은 HMDesign 패키지(`@hm-design/ui`, `@hm-design/sw`, `@hm-design/org-chart`, `@hm-design/org-chart-react`)의 `ai/AI_GUIDE.md`에 **같은 내용으로** 들어 있습니다. 원본은 HMDesign 저장소 `docs/ai/AI_GUIDE.md`이며 패키지 사본은 `npm run sync:ai-docs`로 갱신합니다. 사본을 직접 고치지 않습니다.
|
||||
|
||||
사용자가 "HMDesign 패키지를 기준으로 화면을 구현해 주세요"처럼 요청하면 AI 코딩 도구는 이 파일의 1~6단계를 순서대로 따릅니다. 이 문서와 각 패키지의 `ai/` 문서는 실제 공개 API·CSS에서 확인한 내용만 적습니다. 여기에 없는 컴포넌트·Props·토큰은 없는 것으로 취급합니다.
|
||||
사용자가 "HMDesign 패키지를 기준으로 화면을 구현해 주세요", "HMDesign SW로 화면을 만들어 주세요"처럼 요청하면 AI 코딩 도구는 이 파일의 1~7단계를 순서대로 따릅니다. 이 문서와 각 패키지의 `ai/` 문서는 실제 공개 API·CSS에서 확인한 내용만 적습니다. 여기에 없는 컴포넌트·Props·토큰은 없는 것으로 취급합니다.
|
||||
|
||||
## 0. 읽는 순서
|
||||
|
||||
1. **이 파일**(어느 패키지의 사본이든 같음)
|
||||
2. 선택한 패키지의 `ai/AI_USAGE.md` → `ai/COMPONENT_CATALOG.md` → `ai/DESIGN_RULES.md` → `ai/COMPOSITION_PATTERNS.md`
|
||||
2. 선택한 패키지의 `ai/AI_USAGE.md` → `ai/COMPONENT_CATALOG.md` → `ai/DESIGN_RULES.md` → `ai/COMPOSITION_PATTERNS.md` (SW 뷰어 모드는 `AI_USAGE.md` §0 다음에 `ai/VIEWER.md`를 먼저 읽고 카탈로그의 뷰어 절을 봅니다)
|
||||
3. API가 의심스러우면 그 패키지의 `dist/*.d.ts`(공개 진입점에서 export되는 것만)
|
||||
|
||||
| 유형 | 패키지 | 지침 위치(설치 후) | JS 진입점 | CSS |
|
||||
|---|---|---|---|---|
|
||||
| ① Web UI | `@hm-design/ui` | `node_modules/@hm-design/ui/ai/` | `@hm-design/ui`, `@hm-design/ui/theme` | `@hm-design/ui/tailwind.css` + `@hm-design/ui/theme.css`(Tailwind CSS 4 필요), 선택 `@hm-design/ui/dashboard-status.css` |
|
||||
| ② SW UI | `@hm-design/sw` | `node_modules/@hm-design/sw/ai/` | `@hm-design/sw` | `@hm-design/sw/styles.css` |
|
||||
| ② SW UI — 일반 모드 | `@hm-design/sw` | `node_modules/@hm-design/sw/ai/` (`AI_USAGE.md` §0 모드 선택 → 일반 모드 문서) | `@hm-design/sw` | `@hm-design/sw/styles.css` |
|
||||
| ② SW UI — 뷰어 모드 | `@hm-design/sw`(같은 패키지) | `node_modules/@hm-design/sw/ai/` (`AI_USAGE.md` §0 → `VIEWER.md`) | `@hm-design/sw` | `@hm-design/sw/styles.css`(같은 파일) |
|
||||
| ③ OrgChart | `@hm-design/org-chart`(Core) + React면 `@hm-design/org-chart-react` | `node_modules/@hm-design/org-chart/ai/` (React 어댑터 안내는 `node_modules/@hm-design/org-chart-react/ai/AI_USAGE.md`) | `@hm-design/org-chart`, `@hm-design/org-chart-react`, 선택 `@hm-design/org-chart-react/hm-dialog` | `@hm-design/org-chart/engine.css`, `@hm-design/org-chart/style.css`(URL로 전달 — Shadow DOM 안에 로드) |
|
||||
| 기타 | `@hm-design/center-graphic` | AI 지침 없음. 패키지 `README.md`만 | `@hm-design/center-graphic` | 자동 import |
|
||||
|
||||
@@ -21,12 +22,19 @@
|
||||
|
||||
## 1단계. 사용 목적 확인
|
||||
|
||||
화면 구현 요청을 받으면 코드 작성 전에 **사용 유형**을 정합니다. 유형은 다음 넷이고, SW는 다시 두 모드로 나뉩니다.
|
||||
|
||||
1. Web
|
||||
2. SW — **SW 일반 모드**(편집용: `SWHeader`, `SWPopup` …) / **SW 뷰어 모드**(보기 전용: `SWViewerHeader`, `SWViewerMenu`, `SWViewerPanel` …)
|
||||
3. OrgChart
|
||||
4. 혼합 사용(영역마다 위 유형 하나)
|
||||
|
||||
다음 순서로 판단하고, **판단되면 다시 묻지 않습니다.**
|
||||
|
||||
1. 소비 프로젝트의 `AGENTS.md`·`CLAUDE.md` 등에 `HMDesign 사용 유형:` 설정이 있으면 그대로 따릅니다(§9).
|
||||
1. 소비 프로젝트의 `AGENTS.md`·`CLAUDE.md` 등에 `HMDesign 사용 유형:` 설정이 있으면 그대로 따릅니다(§9). 값은 `Web` / `SW 일반` / `SW 뷰어` / `OrgChart` / `혼합(영역별: …)`입니다. 값이 `SW`뿐이면 유형은 정해진 것이고 모드만 아래 4번으로 정합니다.
|
||||
2. 사용자 요청이 유형을 분명히 말하면 그대로 따릅니다.
|
||||
- Web: 웹 화면, 관리자·업무 화면, 목록·검색·Form, 대시보드, GNB/LNB, Dialog, Table …
|
||||
- SW: 데스크톱 SW, 뷰어, 도면·CAD, SW Header, 툴바, 레이어/색상/선스타일, 속성창·SW Popup …
|
||||
- SW: 데스크톱 SW, 도면·CAD, SW Header, 툴바, 레이어/색상/선스타일, 속성창·SW Popup, 뷰어 …
|
||||
- OrgChart: 조직도, 조직 계층·직원 카드, 조직 JSON/CSV/Excel 시각화 …
|
||||
- 둘 이상이 함께 나오면 ④ 혼합(예: "업무 화면 안에 조직도" = Web + OrgChart).
|
||||
3. 위로 정할 수 없으면 코드 작성 전에 **그대로** 묻습니다.
|
||||
@@ -34,12 +42,21 @@
|
||||
> 어떤 HMDesign 디자인 시스템을 사용하시겠습니까?
|
||||
>
|
||||
> 1. Web
|
||||
> 2. SW
|
||||
> 2. SW (일반 모드 / 뷰어 모드)
|
||||
> 3. OrgChart
|
||||
> 4. 혼합 사용
|
||||
|
||||
- `package.json`에 설치된 패키지가 하나뿐이어도 그것만으로 유형을 확정하지 않습니다(설치가 덜 된 상태일 수 있음). 요청 내용과 맞을 때만 근거로 씁니다.
|
||||
- 혼합을 고르면 영역별 패키지(예: "페이지 = Web, 가운데 영역 = OrgChart")를 확인합니다.
|
||||
4. **SW가 정해졌거나 포함됐는데 모드가 불명확하면** 코드 작성 전에 묻습니다. 설정 값(`SW 일반`/`SW 뷰어`)이나 요청이 모드를 분명히 말하면 묻지 않습니다. 판단 근거와 질문 문구는 `@hm-design/sw/ai/AI_USAGE.md` §0을 따릅니다. 유형 질문이 필요한 경우에는 같은 메시지에서 2번 선택 시의 모드도 함께 묻습니다(한 번에 끝냄).
|
||||
|
||||
> SW 화면을 어떤 모드로 만들까요?
|
||||
>
|
||||
> 1. SW 일반 모드 — 편집용 Header(`SWHeader`)·속성창·SW Popup
|
||||
> 2. SW 뷰어 모드 — 보기 전용 Header(`SWViewerHeader`)·뷰어 메뉴·뷰어 패널
|
||||
|
||||
- "HMDesign SW로 화면을 만들어 주세요"처럼 SW만 말하고 모드 근거가 없으면 유형은 SW로 확정하고 4번의 모드 질문만 합니다.
|
||||
- `package.json`에 설치된 패키지가 하나뿐이어도 그것만으로 유형을 확정하지 않습니다(설치가 덜 된 상태일 수 있음). 요청 내용과 맞을 때만 근거로 씁니다. SW 모드도 같은 패키지이므로 설치 상태로는 판단하지 않습니다.
|
||||
- 정해진 유형·모드는 결과 보고(7단계)에 적고, 작업 중에 다른 유형·모드의 컴포넌트·스타일을 임의로 섞지 않습니다(5단계).
|
||||
- 혼합을 고르면 영역별 패키지(예: "페이지 = Web, 가운데 영역 = OrgChart")를 확인합니다. SW 영역이 있으면 그 영역의 모드(일반/뷰어)까지 정합니다.
|
||||
- **OrgChart가 포함되고 생성 방식이 없으면** 같은 메시지에서 다음도 묻습니다(이미 말했으면 묻지 않음): "조직도만 기존 페이지에 삽입할까요(Chart Only), 아니면 레이아웃까지 구성한 새 페이지 전체를 생성할까요(Full Page)?" 상세는 `@hm-design/org-chart/ai/AI_USAGE.md` §1.
|
||||
- 선택한 패키지가 설치되어 있지 않으면 설치가 필요하다고 보고합니다. 다른 HMDesign 패키지나 임의 라이브러리로 대신하지 않습니다.
|
||||
|
||||
@@ -57,8 +74,9 @@
|
||||
| 요청 항목 | 판단 | 근거(카탈로그의 실제 이름) |
|
||||
|---|---|---|
|
||||
| 예: 상단 메뉴 | 재사용 | Web `GNB` + `GNBMobileMenu` |
|
||||
| 예: 레이어 선택 | 재사용 | SW `SWHeaderLayerMenu` |
|
||||
| 예: 검색 상자(SW) | 신규 | SW 카탈로그에 없음 → `SWHeaderInput` 재사용 + SW 토큰 |
|
||||
| 예: 레이어 선택(SW 일반) | 재사용 | SW `SWHeaderLayerMenu` |
|
||||
| 예: 상단 메뉴(SW 뷰어) | Props 설정 | SW `SWViewerHeader`의 `groups` |
|
||||
| 예: 검색 상자(SW 일반) | 신규 | SW 카탈로그에 없음 → `SWHeaderInput` 재사용 + 일반 모드 토큰 |
|
||||
|
||||
판단 값은 **재사용**(그대로) / **Props 설정**(기존 Variant·Props) / **조합**(기존 컴포넌트 배치) / **신규**(소비 프로젝트에 최소 구현) 중 하나입니다.
|
||||
|
||||
@@ -69,31 +87,44 @@
|
||||
1. 선택 패키지의 기존 컴포넌트·Pattern을 그대로 사용
|
||||
2. 기존 Variant / Props / Callback으로 해결
|
||||
3. 기존 컴포넌트 조합(배치용 CSS만 소비 프로젝트에 작성)
|
||||
4. 조합으로 안 되는 부분만 **소비 프로젝트에** 새로 구현 — 패키지 토큰만 읽고, 안쪽에 기존 컴포넌트를 재사용
|
||||
4. 조합으로 안 되는 부분만 **소비 프로젝트에** 새로 구현 — 아래 "없는 컴포넌트 처리 3단계"
|
||||
|
||||
모든 단계는 **1단계에서 정한 유형·모드 안에서만** 찾습니다. SW 뷰어 모드는 뷰어 컴포넌트(`SWViewer*`)를, SW 일반 모드는 일반 컴포넌트(`SWHeader`·`SWPopup` …)를 먼저 씁니다. 다른 모드에 같은 역할의 컴포넌트가 있어도 가져오지 않습니다.
|
||||
|
||||
### 없는 컴포넌트 처리 3단계
|
||||
|
||||
| 단계 | 조건 | 할 일 | 결과 보고 |
|
||||
|---|---|---|---|
|
||||
| ① 재사용 | 선택 유형·모드에 컴포넌트·Variant·Props·조합이 있음 | 그대로 사용(위 1~3) | 재사용 / Props 설정 / 조합 |
|
||||
| ② 같은 모드 스타일로 신규 | 컴포넌트는 없지만 그 모드의 토큰·확인값·상태 표현이 있음 | 소비 프로젝트에 최소 구현. 그 유형·모드의 토큰과 `DESIGN_RULES.md`(SW 뷰어는 `VIEWER.md`도)의 크기·색·상태 표현만 읽고, 안쪽에는 그 모드의 공개 컴포넌트를 재사용 | 신규 · 읽은 토큰 목록 |
|
||||
| ③ HMDesign과 조화되는 새 스타일 | ②로 참고할 토큰·확인값이 없음 | HMDesign 공통 규칙(아래)과 선택 유형·모드의 가장 가까운 토큰을 기준으로 새 스타일을 구성 | 신규 · **"AI 구성 값 — 디자인 확인 필요"** 목록(속성·값·이유) |
|
||||
|
||||
- 토큰·확인값이 있으면 ②에서 반드시 그것을 씁니다. ③은 참고할 값이 정말 없을 때만이며, ③에서 만든 값은 확정 디자인이 아니라 확인 대상입니다. 화면 인상을 크게 바꾸는 값(주요 색·Header 높이 등)이 필요하면 구현 전에 사용자에게 먼저 확인합니다.
|
||||
- 유형·모드별 구체 토큰과 예는 각 패키지 `ai/AI_USAGE.md`에 있습니다.
|
||||
|
||||
규칙:
|
||||
|
||||
- `node_modules` 안 패키지 파일을 수정하지 않습니다. 패키지 `dist` 구현이나 내부 CSS 블록을 복사해 같은 컴포넌트를 다시 만들지 않습니다.
|
||||
- 이미 있는 컴포넌트와 같은 역할의 컴포넌트를 새로 만들지 않습니다(예: Web에 `Dialog`가 있는데 자체 Modal 작성 금지).
|
||||
- 새 디자인 값을 만들지 않습니다. 색·크기·간격·radius·그림자는 각 패키지 `DESIGN_RULES.md`의 토큰·확인값만 씁니다. 값이 없으면 추측하지 말고 사용자에게 확인합니다.
|
||||
- 토큰·확인값이 있는 속성에 새 값을 만들지 않습니다. 색·크기·간격·radius·그림자는 각 패키지 `DESIGN_RULES.md`(SW 뷰어는 `VIEWER.md`도)의 토큰·확인값을 씁니다. 값이 없을 때만 위 ③으로 구성하고 "AI 구성 값"으로 보고합니다(추측한 값을 확정값처럼 쓰지 않음).
|
||||
- 공통: Font Weight는 400 / 500 / 700만 씁니다(600 없음). Light/Dark 분기를 만들지 않습니다. 새 컴포넌트 CSS에 `html`·`body`·`*` 전역 규칙을 넣지 않습니다. 새 class는 소비 프로젝트 접두사(예: `app-`)를 씁니다.
|
||||
- 요청에 없는 메뉴·통계·설명·다운로드·외부 API·AI 입력 UI를 추가하지 않습니다. 필요해 보이면 제안으로만 보고합니다.
|
||||
|
||||
### 없는 UI를 같은 스타일로 만들 때 확인할 항목
|
||||
|
||||
신규 항목마다 아래를 선택 패키지 `DESIGN_RULES.md`에서 찾아 그대로 적용합니다. 찾을 수 없는 항목은 "값 없음 — 사용자 확인 필요"로 보고합니다.
|
||||
신규 항목마다 아래를 선택 유형·모드의 문서에서 찾아 그대로 적용합니다(②). 찾을 수 없는 항목은 ③으로 구성하고 "AI 구성 값 — 디자인 확인 필요"로 보고합니다.
|
||||
|
||||
| 항목 | Web(`@hm-design/ui`) | SW(`@hm-design/sw`) | OrgChart |
|
||||
|---|---|---|---|
|
||||
| 토큰·CSS 변수 | `--hm-sem-*`, `--hm-color-*`, `--hm-radius-*`(`:root`) | `--hm-sw-header-*`, `--hm-sw-property-*`(`SWTheme` 범위) | `--hm-orgchart-*` 공개 입력(Shadow DOM 상속) |
|
||||
| 색·Typography | DESIGN_RULES §2·§3 | DESIGN_RULES §2·§3 | DESIGN_RULES §2·§3 |
|
||||
| 크기·여백 | DESIGN_RULES §4 | DESIGN_RULES §1 | 카드·간격 변경 금지(승인 디자인) |
|
||||
| Border·Radius·배경·그림자 | DESIGN_RULES §2·§4 | DESIGN_RULES §2·§8 | 공개 입력만 |
|
||||
| 아이콘 | `lucide-react`(패키지 의존성) | 패키지 내장 SVG만, 새 아이콘은 사용자 제공 | Core 내장 |
|
||||
| 스크롤바 | `ScrollArea`(Radix), DESIGN_RULES §6 | 전용 디자인 없음 — 브라우저 기본(AI_USAGE §2) | Core 내부 Zoom/Pan |
|
||||
| Hover / Active / Focus / Disabled | DESIGN_RULES §5 | DESIGN_RULES §4 | Core 내장 |
|
||||
| Popup·Panel | `Dialog`·`AlertDialog`·`Sheet`·`Drawer`·`Popover` | `SWPopup` + `SWPopupSection`/`SWPopupRow` | Core 팝업 / HM Dialog / 어댑터 |
|
||||
| 동작·키보드 | Radix 동작 유지 | 카탈로그 "공통 키보드" | Core 키보드(Pan, Alt+M 이동 등) |
|
||||
| 항목 | Web(`@hm-design/ui`) | SW 일반 모드(`@hm-design/sw`) | SW 뷰어 모드(`@hm-design/sw`) | OrgChart |
|
||||
|---|---|---|---|---|
|
||||
| 토큰·CSS 변수 | `--hm-sem-*`, `--hm-color-*`, `--hm-radius-*`(`:root`) | `--hm-sw-header-*`, `--hm-sw-property-*`(`SWTheme` 범위) | `--hm-sw-viewer-*` + 두 Header가 공유하는 `--hm-sw-header-document-*`·`object-*`·`property-*`(SW 범위) | `--hm-orgchart-*` 공개 입력(Shadow DOM 상속) |
|
||||
| 색·Typography | DESIGN_RULES §2·§3 | DESIGN_RULES §2·§3 | VIEWER.md `SWViewerHeader`·디자인 변경 절 | DESIGN_RULES §2·§3 |
|
||||
| 크기·여백 | DESIGN_RULES §4 | DESIGN_RULES §1 | VIEWER.md 디자인 변경 절(52px Header 등 실측값) | 카드·간격 변경 금지(승인 디자인) |
|
||||
| Border·Radius·배경·그림자 | DESIGN_RULES §2·§4 | DESIGN_RULES §2·§8 | VIEWER.md `SWViewerPanel` 절(프레임은 SWPopup과 같음) | 공개 입력만 |
|
||||
| 아이콘 | `lucide-react`(패키지 의존성) | 패키지 내장 SVG만, 새 아이콘은 사용자 제공 | 프로그램 제공 16px `currentColor` 아이콘, 외곽선은 `SWViewerIcon` | Core 내장 |
|
||||
| 스크롤바 | `ScrollArea`(Radix), DESIGN_RULES §6 | 전용 디자인 없음 — 브라우저 기본(AI_USAGE §2) | 전용 디자인 없음 — 패널 본문 스크롤은 `SWViewerPanel` | Core 내부 Zoom/Pan |
|
||||
| Hover / Active / Focus / Disabled | DESIGN_RULES §5 | DESIGN_RULES §4 | VIEWER.md `SWViewerHeader` 절 상태 표현 | Core 내장 |
|
||||
| Popup·Panel | `Dialog`·`AlertDialog`·`Sheet`·`Drawer`·`Popover` | `SWPopup` + `SWPopupSection`/`SWPopupRow` | `SWViewerPanel`(+ `modal`) + `SWViewerSection`/`SWViewerField` | Core 팝업 / HM Dialog / 어댑터 |
|
||||
| 동작·키보드 | Radix 동작 유지 | 카탈로그 "공통 키보드" | VIEWER.md `SWViewerMenu`·`SWViewerPanel` 키보드 | Core 키보드(Pan, Alt+M 이동 등) |
|
||||
|
||||
## 5단계. 패키지별 디자인 분리 (혼합 사용 포함)
|
||||
|
||||
@@ -102,20 +133,30 @@
|
||||
| 패키지 | 스타일이 적용되는 범위 | 주의 |
|
||||
|---|---|---|
|
||||
| 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`(`<SWTheme>`)에만 정의. 전역 선택자 없음 | Header 밖 SW 부품은 반드시 `<SWTheme>` 안 |
|
||||
| SW(일반·뷰어 공통) | 토큰은 `.hm-sw-header`와 `.hm-sw-theme`에만 정의(뷰어 토큰 `--hm-sw-viewer-*`도 같은 범위). 전역 선택자 없음. `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`은 자기 root에 `hm-sw-theme`를 가짐 | 일반 모드의 Header 밖 SW 부품은 반드시 `<SWTheme>` 안 |
|
||||
| OrgChart | Core가 자기 open Shadow DOM에만 CSS 로드. 호스트 CSS selector는 안쪽에 닿지 않고 **Custom Property 상속만** 통과 | 호스트 class로 카드 모양을 바꾸려 하지 않음 |
|
||||
|
||||
혼합 규칙:
|
||||
|
||||
1. 영역마다 하나의 패키지를 정하고 그 영역의 신규 UI는 그 패키지의 토큰만 읽습니다. Web 토큰(`--hm-sem-*`)을 SW 영역에, SW 토큰(`--hm-sw-*`)을 Web 영역에 쓰지 않습니다. OrgChart 내부는 `--hm-orgchart-*`만 씁니다.
|
||||
2. 다른 패키지 컴포넌트는 **문서에 허용된 지점에서만** 씁니다.
|
||||
- SW `SWPopup`의 `children` 안 Web 컨트롤(SW 카탈로그가 허용, 예: Popup 하단 `Button`)
|
||||
- SW 일반 모드 `SWPopup`의 `children` 안 Web 컨트롤(SW 카탈로그가 허용, 예: Popup 하단 `Button`)
|
||||
- SW 뷰어 모드 `SWViewerPanel`의 `children` 안 Web 컨트롤 — `SWViewer*` 컨트롤로 안 될 때만(SW `AI_USAGE.md` §0.4)
|
||||
- OrgChart Full Page의 바깥 레이아웃 = Web(또는 요청된 패키지)
|
||||
- OrgChart React의 직원 팝업 = 선택 `@hm-design/org-chart-react/hm-dialog`(Web `Dialog`, Web Theme CSS 필요)
|
||||
3. 패키지 class(`hm-sw-*`, `hm-orgchart-*`, Web `data-slot`)를 소비 코드에서 덮어쓰지 않습니다. 배치는 `className`·`style`과 소비 프로젝트 class로 합니다.
|
||||
4. **Web + SW를 한 문서에 함께 쓰면** Web의 전역 base(위 표)가 SW 화면에도 적용됩니다. SW는 자기 범위에서 버튼 등을 초기화하지만 이 조합의 시각 결과는 패키지에서 검증된 적이 없습니다(NOT VERIFIED). 이 조합이면 브라우저에서 SW 부품의 글꼴·테두리·배경을 직접 확인하고 차이를 보고합니다. 가능하면 Web CSS가 없는 SW 전용 화면(별도 entry)으로 분리합니다.
|
||||
5. Web Scoped Theme(`[data-hm-theme]`)는 body Portal(Select·Popover·DatePicker 팝업)에 전달되지 않습니다. Web 영역만 다른 테마로 바꾸려면 Global Theme를 쓰거나 차이를 보고합니다.
|
||||
|
||||
### SW 일반 모드 ↔ 뷰어 모드 분리
|
||||
|
||||
SW 일반 모드와 뷰어 모드는 같은 패키지·같은 CSS 파일이지만 **서로 다른 디자인**입니다. 한 화면(한 Header 영역)에는 한 모드만 씁니다.
|
||||
|
||||
1. 일반 모드 화면: `SWHeader`·개별 컨트롤·`SWPopup`·`SWHeaderPropertyPanel`·`SWToolButton`/`SWToolGroup`. `SWViewer*` 컴포넌트와 `--hm-sw-viewer-*` 토큰을 쓰지 않습니다.
|
||||
2. 뷰어 모드 화면: `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`과 뷰어 패널 컨트롤(`SWViewerSection`·`SWViewerField` …). `SWHeader`에 뷰어 메뉴를 억지로 넣거나 `SWPopup`을 뷰어처럼 재스타일하지 않습니다.
|
||||
3. 패키지가 실제로 공유하는 부분은 혼합이 아닙니다: `SWViewerPanel`은 `SWPopup` 프레임을 그대로 렌더링하고, 두 Header는 파일명·객체 수정·속성 면 토큰(`--hm-sw-header-document-*`·`object-*`·`property-*`)을 공유합니다. 소비 코드가 이 공유를 흉내 내 다른 모드 부품을 섞어도 된다는 뜻은 아닙니다.
|
||||
4. 프로그램이 두 모드를 모두 가지면 모드 전환 시 Header 컴포넌트를 바꿔 끼웁니다(파일·패널 상태는 프로그램 상태로 유지). 세부는 `@hm-design/sw/ai/AI_USAGE.md` §0과 `VIEWER.md`.
|
||||
|
||||
## 6단계. 디자인 검증
|
||||
|
||||
소비 프로젝트에서 실제로 실행한 것만 PASS로 적습니다.
|
||||
@@ -123,20 +164,22 @@
|
||||
1. Typecheck(`tsc --noEmit` 등)와 Production Build
|
||||
2. 브라우저 렌더링: 재사용한 컴포넌트가 HM 외형으로 보이는지(CSS 진입점 누락 확인), 신규 UI가 같은 토큰을 쓰는지
|
||||
3. 상태·동작: Hover / Focus(키보드) / Disabled, Popup 열기·닫기·Escape·Focus 복귀, 선택 패키지의 핵심 동작
|
||||
4. 폭: Web 390 / 768 / 1280 / 1440px, SW는 대상 창 폭(Header는 반응형 More 포함), OrgChart는 캔버스 크기·초기 Fit
|
||||
5. 혼합이면 영역 경계에서 스타일 침범이 없는지(§5)
|
||||
4. 폭: Web 390 / 768 / 1280 / 1440px, SW 일반 모드는 대상 창 폭(Header는 반응형 More 포함), SW 뷰어 모드는 대상 창 폭과 항목 `collapseBelow`·`iconOnlyBelow` 경계 전후(More 이동·아이콘만 표시), OrgChart는 캔버스 크기·초기 Fit
|
||||
5. 혼합이면 영역 경계에서 스타일 침범이 없는지, SW면 선택하지 않은 모드의 컴포넌트·토큰이 섞이지 않았는지(§5)
|
||||
6. 실행하지 못한 항목은 `NOT VERIFIED`로 남깁니다.
|
||||
|
||||
## 7단계. 결과 보고 형식
|
||||
|
||||
```md
|
||||
## HMDesign 적용 결과
|
||||
- 사용 유형: Web | SW | OrgChart(Chart Only|Full Page) | 혼합(영역별: …)
|
||||
- 사용 유형: Web | SW 일반 | SW 뷰어 | OrgChart(Chart Only|Full Page) | 혼합(영역별: …)
|
||||
- 유형·모드 판단 근거: 프로젝트 설정 | 요청 문구 "…" | 사용자 답변
|
||||
- 패키지·버전: @hm-design/ui 0.1.0, …
|
||||
- 재사용한 컴포넌트: …(Props 설정 포함)
|
||||
- 조합한 부분: …
|
||||
- AI가 새로 구현한 부분: 파일 경로 · 이유(카탈로그에 없음) · 안쪽에서 재사용한 컴포넌트
|
||||
- 적용한 디자인 토큰: --hm-… (신규 UI가 읽은 것)
|
||||
- AI 구성 값 — 디자인 확인 필요: 없음 | 속성 · 값 · 이유(4단계 ③)
|
||||
- 카탈로그와 .d.ts 차이: 없음 | …
|
||||
- 검증: Typecheck PASS · Build PASS · 브라우저(폭/상태) … · NOT VERIFIED: …
|
||||
- 제안(구현하지 않음): …
|
||||
@@ -161,9 +204,14 @@
|
||||
import { Button, Card, CardContent, FilterBar, FilterBarActions, FilterBarSearch, PageHeader, PageHeaderContent, PageHeaderTitle } from "@hm-design/ui"
|
||||
```
|
||||
|
||||
### 예시 B — SW 뷰어
|
||||
### 예시 B0 — "HMDesign SW로 화면을 만들어 주세요" (모드 미지정)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/sw/ai/` → COMPOSITION_PATTERNS "6. 파일 열기 + 도구 막대", 예제 `ai/examples/ExampleF-ViewerToolbar.tsx`
|
||||
- 유형은 SW로 확정, 모드 근거가 없으므로 코드 작성 전에 1단계 4번의 모드 질문만 합니다. 답에 따라 B1 또는 B2로 진행합니다.
|
||||
- 소비 프로젝트 설정이 `HMDesign 사용 유형: SW 일반` 또는 `SW 뷰어`이면 묻지 않고 바로 B1/B2입니다.
|
||||
|
||||
### 예시 B1 — SW 일반 모드 (편집 Header + 도구 막대 + 설정 Popup)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/sw/ai/` → AI_USAGE §0(일반 모드) → COMPOSITION_PATTERNS "6. 파일 열기 + 도구 막대", 예제 `ai/examples/ExampleF-ViewerToolbar.tsx`(파일 이름의 Viewer는 과거 명칭이며 일반 모드 `SWHeader` 예제)
|
||||
- 재사용: `SWHeader`(`documentOpenPlacement="header"`, `controls`, `tools`), `SWToolGroup` + `SWToolButton`(Model/Layout 탭, Fit 등), `SWPopup` + `SWPopupSection` + `SWPopupRow` + `SWHeaderInput`(설정 Popup)
|
||||
- 신규: SW에 없는 기능(예: 검색) → 소비 프로젝트 컴포넌트, `<SWTheme>` 안, `--hm-sw-header-*` 토큰, 안쪽 입력은 `SWHeaderInput`(예제 `ExampleD-SearchExtension.tsx`)
|
||||
|
||||
@@ -172,6 +220,18 @@ import { SWHeader, SWPopup, SWTheme, SWToolButton, SWToolGroup } from "@hm-desig
|
||||
import "@hm-design/sw/styles.css"
|
||||
```
|
||||
|
||||
### 예시 B2 — SW 뷰어 모드 (뷰어 Header + 메뉴 + 패널)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/sw/ai/` → AI_USAGE §0(뷰어 모드) → `VIEWER.md`, 예제 `ai/examples/ExampleH-ViewerMode.tsx`
|
||||
- 재사용: `SWViewerHeader`(`groups` 데이터: `button`·`toggle`·`menu`·`tabs`·`switch`·`custom` 항목, `onCommand`, `trailing`에 `SWViewerStatus`·`SWViewerHeaderButton`), Dropdown은 `type: "menu"` 항목의 `entries`(단독·우클릭은 `SWViewerMenu`), 팝업은 `SWViewerPanel` + `SWViewerSection`·`SWViewerField`·`SWViewerSwitch`·`SWViewerSlider`·`SWViewerInput`·`SWViewerButton`
|
||||
- 신규: 뷰어에 없는 패널 콘텐츠 → 소비 프로젝트 컴포넌트를 `SWViewerPanel`의 `children`에, 안쪽은 `SWViewerField` + `SWViewerInput` 등, 외형은 `--hm-sw-viewer-*` 토큰
|
||||
- 하지 않음: `SWHeader`·`SWPopup`을 뷰어 화면에 섞기, 로고가 없다고 임의 문자·아이콘 넣기, 연결할 명령이 없는 메뉴를 가짜 동작으로 만들기(제외 또는 `disabled` + 미연결 보고)
|
||||
|
||||
```tsx
|
||||
import { SWViewerHeader, SWViewerPanel, SWViewerSection, SWViewerField, SWViewerSwitch, type SWViewerHeaderGroup } from "@hm-design/sw"
|
||||
import "@hm-design/sw/styles.css"
|
||||
```
|
||||
|
||||
### 예시 C — 조직도만 (Chart Only)
|
||||
|
||||
- 읽기: `node_modules/@hm-design/org-chart/ai/` → COMPOSITION_PATTERNS "1. Chart Only"
|
||||
@@ -198,7 +258,7 @@ import coreUrl from "@hm-design/org-chart/style.css?url"
|
||||
|
||||
AI 코딩 도구는 보통 **프로젝트 루트의** `AGENTS.md`(Codex 등)·`CLAUDE.md`(Claude Code)·도구별 규칙 파일만 자동으로 읽고 `node_modules`는 읽지 않습니다. 패키지 설치만으로 지침이 자동 적용되지는 않으므로 소비 프로젝트에서 한 번 연결합니다.
|
||||
|
||||
1. 패키지에 들어 있는 `ai/AGENTS_SNIPPET.md`를 루트 `AGENTS.md`(없으면 새로 만듦)에 붙여 넣고 `HMDesign 사용 유형:` 줄을 프로젝트에 맞게 고칩니다. 정하지 않았으면 그 줄을 지워 AI가 1단계에서 묻게 합니다.
|
||||
1. 패키지에 들어 있는 `ai/AGENTS_SNIPPET.md`를 루트 `AGENTS.md`(없으면 새로 만듦)에 붙여 넣고 `HMDesign 사용 유형:` 줄을 프로젝트에 맞게 고칩니다. 값은 `Web` / `SW 일반` / `SW 뷰어` / `OrgChart` / `혼합(영역별: 예 "페이지 = Web, 중앙 = OrgChart")` 중 하나입니다. SW 프로젝트면 모드까지 적어야 AI가 모드를 다시 묻지 않습니다(`SW`만 적으면 모드를 묻습니다). 정하지 않았으면 그 줄을 지워 AI가 1단계에서 묻게 합니다.
|
||||
```bash
|
||||
cat node_modules/@hm-design/ui/ai/AGENTS_SNIPPET.md >> AGENTS.md
|
||||
```
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# @hm-design/ui — AI 코딩 도구 사용 안내 (Web UI)
|
||||
|
||||
먼저 [AI_GUIDE.md](./AI_GUIDE.md)(공통 1~7단계)를 읽고 사용 유형이 **Web** 또는 Web이 포함된 혼합일 때 이 폴더를 씁니다. 이 폴더(`node_modules/@hm-design/ui/ai/`)의 내용은 `@hm-design/ui` 0.1.0의 공개 Export(`src/index.ts` → `dist/index.d.ts`)와 `theme.css`에서 확인한 값만 적습니다.
|
||||
먼저 [AI_GUIDE.md](./AI_GUIDE.md)(공통 1~7단계, 사용 유형 정의)를 읽습니다. 사용 유형은 `1 Web / 2 SW(SW 일반 모드 · SW 뷰어 모드) / 3 OrgChart / 4 혼합`이고, 소비 프로젝트 설정 값은 `HMDesign 사용 유형: Web | SW 일반 | SW 뷰어 | OrgChart | 혼합(영역별)`입니다. **이 폴더는 유형이 Web이거나 혼합의 Web 영역일 때만** 씁니다. 이 폴더(`node_modules/@hm-design/ui/ai/`)의 내용은 `@hm-design/ui` 0.1.0의 공개 Export(`src/index.ts` → `dist/index.d.ts`)와 `theme.css`에서 확인한 값만 적습니다.
|
||||
|
||||
- 요청에 SW(일반/뷰어) 화면이 섞이면 그 영역은 [SW 안내](../../sw/ai/AI_USAGE.md), OrgChart가 섞이면 [OrgChart 안내](../../org-chart/ai/AI_USAGE.md)로 넘기고, 영역·모드 사이에 컴포넌트·토큰을 임의로 섞지 않습니다. 유형이 정해지지 않았으면 AI_GUIDE의 확인 질문을 먼저 합니다.
|
||||
- Web 컴포넌트(`Button`, `DropdownMenu`, `Dialog` 등)를 SW 화면의 Header·뷰어 메뉴·툴바 대용으로 쓰지 않습니다. SW 화면 안에서 Web 컴포넌트는 SW 문서가 허용한 지점에만 둡니다: 일반 모드는 `SWPopup`의 `children` 안(예: Popup 하단 `Button`), 뷰어 모드는 `SWViewerPanel`의 `children` 안이며 `SWViewer*` 컨트롤로 안 될 때만입니다.
|
||||
|
||||
| 문서 | 내용 |
|
||||
|---|---|
|
||||
@@ -14,7 +17,10 @@
|
||||
2. **컴포넌트를 찾는다.** [COMPONENT_CATALOG.md](./COMPONENT_CATALOG.md)에서 요청 항목과 같은 역할을 찾는다. 같은 역할이 있으면 새로 만들지 않는다.
|
||||
3. **Variant·Props로 맞춘다.** `Button`의 `variant` × `appearance`, `Input`/`Select`/`DatePicker`/`Combobox`의 `size`, `Card`·`Tabs`의 `surface` 등 기존 Props로 해결한다. `<Button>`처럼 기본 API만으로 HM 외형이 적용된다. `hm-*` class를 붙이거나 Story 전용 class로 외형을 보정하지 않는다.
|
||||
4. **조합한다.** 여러 컴포넌트를 배치하고 배치용 레이아웃(flex/grid, 간격)만 소비 프로젝트에 작성한다.
|
||||
5. **없을 때만 새로 만든다.** 소비 프로젝트에 작성하고, 외형은 [DESIGN_RULES.md](./DESIGN_RULES.md)의 토큰만 `var(--…)`로 읽으며, 안쪽에는 기존 컴포넌트(`Card`, `Button`, `Label` …)를 재사용한다.
|
||||
5. **없을 때만 새로 만든다 (3단계).**
|
||||
- ① 기존 Pattern·컴포넌트·Variant·Props·조합으로 되는지 먼저 확인한다(위 1~4).
|
||||
- ② 없으면 소비 프로젝트에 새로 작성한다. 색·간격·radius·글꼴은 [DESIGN_RULES.md](./DESIGN_RULES.md)의 Web 토큰(`--hm-sem-*`, `--hm-color-*`, `--hm-radius-*`)을 `var(--…)`로 읽고, hover·focus·disabled·invalid 등 상태 표현도 같은 문서를 따른다. 안쪽에는 기존 컴포넌트(`Card`, `Button`, `Label` …)를 재사용한다. **쓸 수 있는 토큰이 있으면 반드시 토큰을 쓴다.**
|
||||
- ③ 참고할 토큰·스타일이 없을 때만 HMDesign 공통 규칙(Font Weight 400/500/700만, Light/Dark 없음, 전역 CSS 금지)과 조화되게 구성한다. 이때 토큰에 없는 값은 결과 보고에 **"AI 구성 값 — 디자인 확인 필요"** 로 적는다.
|
||||
6. **추측하지 않는다.** 카탈로그·`dist/index.d.ts`에 없는 Export·Props·토큰은 없다. 기본 HTML·임의 CSS·`data-slot` 흉내로 HM 컴포넌트를 모방하지 않는다(레이아웃·콘텐츠용 HTML은 허용).
|
||||
7. **실제로 검증한다.** [AI_GUIDE.md](./AI_GUIDE.md) 6단계.
|
||||
|
||||
@@ -58,5 +64,5 @@ import { applyRuntimeTheme, resetRuntimeTheme, loadRuntimeTheme } from "@hm-desi
|
||||
## 5. 이 패키지에 없는 것
|
||||
|
||||
- 공개 Form Pattern, Empty·Error 전용 컴포넌트, Stepper, Tree, Chart(그래프) 컴포넌트는 없다. Form은 `Label` + `Input`/`Textarea`/`Select`/`Checkbox`/`RadioGroup`/`Switch`를 `Card` 안에 조합하고, 빈 목록은 `DataTable`의 `emptyMessage`, 오류 안내는 `Alert`로 만든다.
|
||||
- Badge에 success / warning / information variant는 없다(HM Theme에 상태 팔레트가 아직 없음). 새 상태색을 만들지 않는다.
|
||||
- Badge에 success / warning / information variant는 없다(HM Theme에 상태 팔레트가 아직 없음). 새 상태색을 임의로 만들지 않는다(불가피하면 위 ③ 방식으로 보고).
|
||||
- 상세 컴포넌트 문서·Storybook은 HMDesign 저장소(`docs/components/<name>.md`, `docs/patterns/`)에 있고 패키지에는 포함되지 않는다. 패키지만 있을 때는 이 폴더와 `.d.ts`가 기준이다.
|
||||
@@ -1,6 +1,6 @@
|
||||
# Web(@hm-design/ui) 디자인 규칙
|
||||
|
||||
출처: `@hm-design/ui/theme.css`(원본 `src/theme/primitives.css`·`default.css`·컴포넌트별 `theme/*.css`)에 실제 선언된 값. 이 문서와 그 CSS에 없는 값은 확정값이 아닙니다. 새 UI는 아래 변수를 `var(--…)`로 읽고 HEX·px 값을 새로 만들지 않습니다.
|
||||
출처: `@hm-design/ui/theme.css`(원본 `src/theme/primitives.css`·`default.css`·컴포넌트별 `theme/*.css`)에 실제 선언된 값. 이 문서와 그 CSS에 없는 값은 확정값이 아닙니다. 새 UI는 아래 변수를 `var(--…)`로 읽고 HEX·px 값을 새로 만들지 않습니다. 참고할 변수가 없을 때만 [AI_USAGE.md](./AI_USAGE.md) §1-5 ③으로 구성하고 "AI 구성 값 — 디자인 확인 필요"로 보고합니다.
|
||||
|
||||
- 토큰 범위: `:root, [data-hm-theme]`. Runtime Theme(`@hm-design/ui/theme`)가 같은 변수를 바꿉니다.
|
||||
- Light/Dark 분기 없음. 컴포넌트 CSS에 `html`·`body`·`*` 규칙을 추가하지 않습니다.
|
||||
|
||||
+5
-3
@@ -36,13 +36,15 @@ if (mode === "--sync") {
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
// 1. Shared copies are identical to docs/ai.
|
||||
// 1. Shared copies are identical to docs/ai. Line endings are ignored: with core.autocrlf=true, packages/sw
|
||||
// (.gitattributes eol=lf) checks out LF while docs/ai and the other packages check out CRLF.
|
||||
const normalizeEol = text => text.replace(/\r\n/g, "\n")
|
||||
for (const file of shared) {
|
||||
const source = await readFile(path.join(root, "docs/ai", file), "utf8")
|
||||
const source = normalizeEol(await readFile(path.join(root, "docs/ai", file), "utf8"))
|
||||
for (const name of Object.keys(packages)) {
|
||||
const copy = path.join(packageDir(name), "ai", file)
|
||||
if (!existsSync(copy)) failures.push(`${name}: ai/${file} missing (run npm run sync:ai-docs)`)
|
||||
else if ((await readFile(copy, "utf8")) !== source) failures.push(`${name}: ai/${file} differs from docs/ai/${file} (run npm run sync:ai-docs)`)
|
||||
else if (normalizeEol(await readFile(copy, "utf8")) !== source) failures.push(`${name}: ai/${file} differs from docs/ai/${file} (run npm run sync:ai-docs)`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user