Files
HMDesign/packages/sw/ai/AI_USAGE.md
T

24 KiB

@hm-design/sw — AI 코딩 도구 사용 안내

이 폴더(node_modules/@hm-design/sw/ai/)는 다른 React 프로젝트에서 AI 코딩 도구가 SW 패키지를 재사용·조합·확장할 때 먼저 읽는 안내서입니다. 패키지 자체에는 AI 기능이 없습니다. 아래 문서는 실제 공개 API와 CSS에서 확인한 값만 적습니다.

먼저 AI_GUIDE.md(HMDesign 공통: 사용 유형 Web / SW 일반·뷰어 / OrgChart / 혼합 확인, 작업 1~7단계, 패키지 분리, 결과 보고)를 읽고 사용 유형이 SW 또는 SW가 포함된 혼합일 때 이 폴더를 씁니다.

문서 내용
AI_GUIDE.md HMDesign 공통 진입점(모든 HMDesign 패키지에 같은 사본)
COMPONENT_CATALOG.md 공식 공개 컴포넌트(일반 모드: Header·개별 컨트롤·Popup·도구 막대·로고 클릭 메뉴 / 뷰어 모드 §9: SWViewer* 전체 Export)·Props·Callback·크기·CSS 의존성
DESIGN_RULES.md SW 전용 토큰·Typography·간격·Hover/Focus/Selected·Overlay·Motion·반응형·Popup 외형·도구 버튼·로고 클릭 메뉴(일반 모드 §1~10·§12), 뷰어 토큰·상태값 요약(§11)
COMPOSITION_PATTERNS.md 완성형·간소화·기능 중심·확장 Header, Popup(자유 콘텐츠), 일반 모드 Header + 도구 막대(1~6), 뷰어 모드 기본 조합(7)
examples/ 공개 API만 쓰는 예제 AJ(10개). 일반 모드 AG·I: A 완성형 Header(ExampleA-DefaultHeader.tsx), B 간소화 Header(ExampleB-ViewerHeader.tsx), C 기능 중심 Header(ExampleC-FeatureHeader.tsx), D 신규 컨트롤 확장(ExampleD-SearchExtension.tsx), E 사용자 정의 Popup(ExampleE-CustomPopup.tsx), F 파일 열기 + 도구 막대(ExampleF-ViewerToolbar.tsx), G 로고 클릭 메뉴(ExampleG-HomeMenu.tsx), I Footer(ExampleI-Footer.tsx). A~F는 독립 소비 프로젝트에서 Typecheck·Build·브라우저 검증. B·F 파일명의 "Viewer"는 과거 이름이며 일반 모드 SWHeader 구성. 뷰어 모드 H(ExampleH-ViewerMode.tsx, SWViewer*). 두 모드 공통 J 테마 토큰 설정(ExampleJ-Theme.tsx, §3.1)
FOOTER.md 일반 모드 하단 막대: SWFooter(보조기능·바 안 명령창·명령 칸·분류 탭·명령어 전체보기), SWFooterLayoutTabs(Model/Layout 탭), SWFooterCommandLine(명령창). AI 작업 순서 1~6
VIEWER.md 뷰어 모드 전용: SWViewerHeader(데이터 메뉴·More·외곽선·로고 규칙), SWViewerMenu(Dropdown·서브메뉴·우클릭), SWViewerPanel(팝업 프레임 + 자유 콘텐츠). 일반 SW 모드는 SWHeader·SWPopup을 그대로 씁니다

0. SW 모드 선택 — SW 일반 모드 / SW 뷰어 모드 (코드 작성 전에 결정)

SW 패키지에는 Header·Popup 계열이 두 벌 있습니다. 화면마다 하나의 모드를 고르고 그 모드의 컴포넌트만 씁니다. 공통 사용 유형 확인(Web / SW / OrgChart / 혼합)은 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, 레이어·색상 행 SWPopupPropertyRow(Header 필드 Dropdown은 Header 전용), 게이지바 SWSlider(appearance), 선택 목록 SWSelect, 속성창 SWHeaderPropertyPanel, 속성Bar SWHeaderPropertyBar SWViewerPanel(이동·크기 조절·접기·modal, headerActions, footer) + SWViewerSection / SWViewerField / SWViewerSwitch / SWViewerInput / SWViewerButton / SWViewerBadge / SWViewerHint, 옵션 패널 게이지는 SWSlider appearance="property"(스타일 B, SWViewerSlider 아님), 선택 목록 SWSelect(뷰어 패널 토큰으로 표시)
로고(홈) 버튼 메뉴 SWHeader의 homeMenu(SWHomeMenu 데이터, 최근파일 SWRecentFiles, Figma 26:10591). 기본 숨김 → 로고 클릭 열기 → 다시 클릭 닫기 사용하지 않음. SWViewerHeader에는 홈 메뉴 Props가 없고 로고 클릭은 onHomeClick만 호출합니다. 파일 열기는 로고 오른쪽 버튼(onDocumentOpen·documentOpenLabel), 샘플 목록은 파일명 클릭 목록(documents·activeDocumentId·onDocumentSelect)이며 groups 항목으로 만들지 않습니다(VIEWER.md §2)
하단 Footer SWFooter(+ 바 안 명령창 command={<SWFooterCommandLine />}, 좌표 status, SWFooterLayoutTabs, 부품 SWFooter*), FOOTER.md 사용하지 않음. 뷰어 화면에는 하단 명령 막대가 없습니다. 도면 공간 탭은 SWViewerHeader의 tabs 항목
버튼·탭·토글 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 §18·§10, DESIGN_RULES.md §110·§12·§13, COMPOSITION_PATTERNS.md 16·8·10, FOOTER.md, 예제 AG·I VIEWER.md, COMPONENT_CATALOG.md §9, DESIGN_RULES.md §11, COMPOSITION_PATTERNS.md 7, 예제 H
  • 하단 명령 막대(Footer) 요청은 일반 모드입니다: FOOTER.md §1 순서로 SWFooter가 있는지 확인하고, 명령·분류·보조기능·문구·아이콘만 Props로 바꿉니다. Footer 외형을 새로 그리지 않습니다.
  • 일반 모드 Header에 도구 막대를 더한 구성(로고 옆 파일 열기 + Model/Layout·Fit·2.5D 버튼을 SWHeader에 추가)은 일반 모드입니다: SWHeader의 documentOpenPlacement·leading·tools + SWToolButton / SWToolGroup(PATTERNS 6, 예제 F). "뷰어"·"도면 보기" 화면을 요청받았다면 이 구성이 아니라 뷰어 모드(SWViewer*)를 씁니다.
  • 모드 진입·종료, 파일 처리, 도면 렌더링, 메뉴 명령 실행은 어느 모드든 프로그램 담당입니다.

0.3 모드 혼합 금지

  • 한 화면에 Header 하나. SWHeader와 SWViewerHeader를 같은 화면에 함께 두지 않습니다. 두 모드를 오가는 프로그램은 상태를 유지한 채 Header 컴포넌트만 바꿉니다(VIEWER.md §1).
  • 뷰어 화면: SWHeader에 뷰어 메뉴를 넣거나 SWHeader·SWPopup을 뷰어처럼 재스타일하지 않습니다. 뷰어 팝업은 SWViewerPanel입니다. 예외: 창 최소화·닫기 버전은 SWViewerHeader의 trailing 맨 끝에 SWHeaderWindowControls(showWindowMove={false})를 그대로 둡니다(VIEWER.md §2.1, 2026-10-21).
  • 일반 화면: SWViewerHeader·SWViewerMenu·SWViewerPanel과 패널 컨트롤(SWViewerSection …)을 쓰지 않습니다.
  • 로고(홈) 메뉴는 SW 일반 모드 전용: SWHomeMenu·SWHomeMenuSection·SWHomeMenuItem·SWRecentFiles·useSWHomeMenuClose와 SWHeader의 homeMenu·homeMenuOpen·defaultHomeMenuOpen·onHomeMenuOpenChange는 일반 모드 SWHeader 화면에서만 씁니다. 뷰어 화면에는 홈 메뉴를 만들지 않고(SWViewerHeader 옆·custom 항목·SWViewerPanel 안에 넣거나 비슷하게 다시 만들지 않음), 뷰어 Header와 기능은 그대로 둡니다.
  • 토큰: --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를 따르고, 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 §4(테두리형 gradient 링, 텍스트형 글자만 #FFC600). 안쪽 입력은 SWHeaderInput 재사용(예제 D) 토큰 --hm-sw-viewer-* + 공유 --hm-sw-header-*(면·외곽선). 상태 표현은 DESIGN_RULES.md §11 / VIEWER.md §2(Hover·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 SWViewerPanel 절).
  • 어느 단계에서도 패키지 원본(node_modules/@hm-design/sw) 수정, hm-sw-* class 재사용·재정의, dist 코드·CSS 복사를 하지 않습니다. 새 class는 소비 프로젝트 접두사(예: app-)를 씁니다.

1. 작업 순서 (필수)

  1. 먼저 검색한다. §0에서 모드를 정하고, 요청 기능을 COMPONENT_CATALOG.md의 공개 컴포넌트(뷰어 모드는 §9와 VIEWER.md)에서 찾는다.
  2. 있으면 재사용한다(1순위). 뷰어 모드는 SWViewerHeader·SWViewerMenu·SWViewerPanel이다(VIEWER.md). 일반 모드에서 완성형 Header가 필요하면 SWHeader 하나만 쓴다. 기존 Props(hiddenControls, menuOrder, controls, documentOpenPlacement, leading, tools, 각 데이터 배열·Callback)로 해결되는지 먼저 본다. 팝업·설정창은 SWPopup, 버튼·탭·토글은 SWToolButton / SWToolGroup, 일반 모드 로고 클릭 2단 메뉴는 SWHeader의 homeMenu(SWHomeMenu 데이터, 최근파일은 SWRecentFiles)이다. SWToolButton과 SWHomeMenuItem은 역할이 다르다(도구 막대 버튼 / 메뉴 타일). 서로 대신 쓰지 않는다.
    • Popup 요청은 이렇게 판단한다: ① SWPopup이 프레임(외형·닫기·Escape·스크롤)을 제공한다 → ② 내용은 children으로 자유 구성(구조 제한 없음) → ③ 행 모양은 SWPopupSection / SWPopupRow + SWHeaderInput, 레이어·색상·선스타일 선택 행은 SWPopupPropertyRow(SWHeader 필드 Dropdown은 Header 전용), 게이지바는 SWSlider, 선택 목록은 SWSelect → ④ 그래도 SW에 없는 컨트롤(Switch, 하단 Button 등)만 @hm-design/ui를 children에 → ⑤ 프레임을 다시 만들거나 없는 Props(content, renderContent 등)를 추측하지 않는다.
  3. 없으면 조합한다(2순위). 개별 공개 컴포넌트(SWHeaderHome, SWHeaderDocumentTitle, SWHeaderLayerMenu …)를 <SWTheme> 안에 배치한다. 배치용 CSS만 소비 프로젝트에 작성한다(COMPOSITION_PATTERNS.md).
  4. 조합으로도 안 될 때만 새로 만든다(3순위). 새 컴포넌트는 소비 프로젝트에 작성하고, 공개 컴포넌트(예: SWHeaderInput)를 내부에 재사용하며, 외형은 공개 토큰 --hm-sw-header-*만 읽는다(DESIGN_RULES.md, 예제 D). 뷰어 모드의 새 UI는 --hm-sw-viewer-*(+ 공유 --hm-sw-header-* 면·외곽선, 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로 적지 않는다.

2. 설치·Import 규칙

import { SWHeader, SWTheme, SWHeaderLayerMenu } from "@hm-design/sw"
import "@hm-design/sw/styles.css" // 앱 진입점에서 한 번
  • 공식 진입점은 @hm-design/sw(JS·타입)와 @hm-design/sw/styles.css 두 개뿐이다. package.json의 exports가 다른 경로를 막는다.
  • 금지: @hm-design/sw/src/..., @hm-design/sw/dist/components/... 같은 내부 경로 Import. dist에 내부 모듈의 .d.ts가 보여도 공개 API가 아니다.
  • Peer: react, react-dom ^19.0.0. 런타임 dependency 없음. @hm-design/ui·조직도 패키지와 무관하다.
  • SVG·PNG 자산은 JS에 data URI로 포함되어 별도 설정이 없다.
  • SW 기본 글꼴은 Noto Sans KR이다(--hm-sw-header-font-family: "Noto Sans KR", "Malgun Gothic", "Apple SD Gothic Neo", sans-serif, 2026-10-20 확정 — 같은 날의 Dotum 기본값은 철회, Figma의 Dotum은 의도적으로 대체). 패키지는 글꼴 파일을 포함하지 않으며 앱이 Noto Sans KR(400/500/700)을 로드한다. 없으면 Malgun Gothic → Apple SD Gothic Neo로 대체된다. Dotum을 기본값으로 다시 넣지 않는다.
  • SW 화면은 SWTheme(또는 SW 컴포넌트 루트)와 SW 토큰의 글꼴을 그대로 쓴다. Web UI도 Noto Sans KR이지만 Web 토큰(--hm-font-family-base)이나 Web theme.css의 글꼴 설정을 SW 화면에 복사하지 않고, SW 컴포넌트에 font-family를 개별 지정하지 않는다. 프로그램(사용자)이 다른 글꼴을 정한 경우에만 §3.1 방법으로 --hm-sw-header-font-family를 바꾸고 결과 보고에 "글꼴 변경"으로 적는다.
  • Weight 범위(2026-10-20 사용자 확정): SWHeader 안의 필드 값은 400, Composed Controls(SWHeader 밖에 단독 배치한 SWHeaderLayerMenu 등)의 필드 값은 700. 파일명·Footer 보조기능/명령어 제목·Footer 분류 탭·Viewer Header 파일명/버튼 라벨/Model·Layout·최근파일 이름/경로/미리보기 제목, Footer Model/Layout 탭 라벨(모든 상태, 2026-10-22 사용자 확정, 이름 편집 입력은 400)은 700, Footer 전체보기·명령·보조기능 라벨은 400. 임의로 일괄 변경하지 않는다. Figma 고정 폭 칸(예: 가중치·스케일 38px)에 그보다 긴 값(예: ByLayer)이 들어가면 말줄임 + title이 된다. Figma 레이어 이름의 Dotum/bold/14를 보고 700으로 바꾸거나 겹침·외곽선을 따로 만들지 않는다.
  • CSS는 전역(html, body, *)을 건드리지 않는다. body margin 등 페이지 기본값은 소비 앱이 정한다.
  • 스크롤바: SW 전용 스크롤바 디자인은 없다. 기존 SW 컴포넌트는 브라우저 기본 스크롤바를 쓰며(속성Bar만 scrollbar-width: thin), Popup 본문 스크롤은 SWPopup이 처리한다. 새 스크롤 영역에 임의 스크롤바 색·두께를 만들지 않는다.
  • TypeScript에서 CSS side-effect import 오류가 나면 Vite의 vite/client 타입을 포함한다.

3. 스타일 규칙

  • SWHeader 밖에서 하위 컴포넌트를 쓰면 반드시 <SWTheme>로 감싼다. 토큰·글꼴·버튼 초기화가 이 범위에서만 적용된다.
  • 소비 코드는 hm-sw-* class를 붙이거나 재정의하지 않는다. 배치는 자기 class(className)와 style로 한다.
  • 뷰어 모드 컴포넌트(SWViewerHeader·SWViewerMenu·SWViewerPanel)는 자체 hm-sw-theme 범위를 가지므로 <SWTheme>로 감싸지 않아도 된다. 소비 코드는 hm-sw-viewer-* class도 붙이거나 재정의하지 않는다.
  • 외형 변경은 §3.1의 방법만 쓴다. 사용자 확정 면(파일명·객체 수정·속성 입력)은 기본값 유지를 권장한다.
  • Light/Dark 분기는 없다. SW 디자인은 하나다.

3.1 테마(토큰) 설정 — 공식 방법 (2026-10-20)

SW 토큰(--hm-sw-header-*, --hm-sw-property-*, --hm-sw-viewer-*, --hm-sw-footer-*)의 기본값은 가장 바깥 SW 범위(<SWTheme>, 또는 단독으로 쓴 SWHeader·SWViewerHeader·SWViewerPanel·SWViewerMenu·SWFooter의 루트)에서 한 번만 선언됩니다. 그 안의 SW 요소 — Header의 Dropdown·More, SWViewerMenu, SWViewerPanel과 안쪽 컨트롤, SWFooterCommandLine, Tooltip·안내 — 는 자기 루트에 hm-sw-theme이 있어도 값을 다시 정하지 않고 상속합니다.

  1. 화면 전체(Header·Panel·Menu가 같은 값)를 바꾸려면 화면을 <SWTheme style={theme}> 하나로 감싸고 거기서만 토큰을 정합니다. 프로그램 class(<SWTheme className="app-sw-theme"> + .app-sw-theme { --hm-sw-header-font-family: … })도 됩니다.
    const appSWTheme = { "--hm-sw-header-font-family": '"Malgun Gothic", sans-serif' } as CSSProperties // 프로그램이 정한 값만
    <SWTheme style={appSWTheme}>
      <SWViewerHeader … />        {/* Dropdown·More 포함 */}
      <SWViewerPanel …>…</SWViewerPanel>
    </SWTheme>
    
  2. 컴포넌트 하나만 쓰면 그 컴포넌트의 style로 정해도 됩니다(그 루트가 가장 바깥 범위). 안쪽 Dropdown·More·명령창에도 적용됩니다.
  3. Portal: 상속은 DOM 위치를 따릅니다. 프로그램이 createPortal로 SW 요소를 범위 밖(document.body 등)에 렌더링하면 값이 전달되지 않으므로, Portal 내용을 같은 theme 객체의 <SWTheme style={appSWTheme}>으로 감쌉니다(예제 ExampleJ-Theme.tsx). SW 패키지 컴포넌트 자체는 Portal을 쓰지 않습니다(Dropdown·More·Panel 모두 범위 안에 렌더링).
  4. 영역마다 다른 값이 필요하면 영역별 <SWTheme>을 둡니다. 옆 영역끼리 섞이지 않고, 안쪽 <SWTheme style>은 그 안에서만 적용됩니다.
  5. 하지 않음: hm-sw-* class를 선택자로 쓴 CSS(.hm-sw-header, .hm-sw-theme { --… } 등), !important, 안쪽 컴포넌트마다 같은 값을 반복 지정, SW 범위가 아닌 조상(body, 앱 루트 div)에만 토큰 지정(SW 범위가 기본값을 다시 선언하므로 적용되지 않음).
  • 다른 토큰을 참조하는 토큰(예: --hm-sw-viewer-panel-background = var(--hm-sw-property-surface))은 가장 바깥 범위에서 계산됩니다. 참조되는 토큰을 바꿀 때도 가장 바깥 범위에서 바꿉니다.

4. 판단 기록 남기기

새 UI를 만들 때 결과 보고에 다음을 남긴다.

요청 항목 판단 근거
예: SW 모드 뷰어 모드 설정 HMDesign 사용 유형: SW 뷰어 / 요청 "DWG 뷰어" / 사용자 답변 중 실제 근거
예: 레이어 재사용 SWHeaderLayerMenu
예: 검색 신규(소비 프로젝트) 카탈로그 MISSING. SWHeaderInput 재사용 + 토큰 기반 표면
예: 뷰어 측정 패널 신규 콘텐츠(소비 프로젝트) SWViewerPanel children에 SWViewerField + SWViewerInput. 토큰에 없는 값은 "AI 구성 값 — 디자인 확인 필요"

새 컴포넌트를 SW 패키지 공식 컴포넌트로 승격할지는 별도 검토 대상이다. 임의로 패키지에 추가하지 않는다.