14 KiB
shadcn 기반 구현 원칙
적용 범위: HMDesignSystem의 새로운 Component / Pattern / Story 구현과 기존 테스트 디자인 재현
이 문서는
docs/guidelines/프로젝트-지침.md의 컴포넌트 구현 규칙을 보완하는 공통 지침이다. 두 문서가 충돌하면 더 구체적인 컴포넌트 문서(docs/components/,docs/patterns/)의 사용자 확정 결정과 이 문서의 재사용·구조 원칙을 함께 적용한다.
2026-10-07 사용자 확정 — AI 기본 구현 정책의 상세 Source of Truth. 사용자가 별도로 기존 컴포넌트/디자인 시스템 사용, Theme 적용, Semantic Token 사용, Navigation 정책 준수를 요청하지 않아도 AI는 모든 신규·수정 UI에 자동 적용한다. 기본 전제는 Existing Component First / Theme Applied By Default / Single Navigation Mode / Minimum Custom이다. 과거 문서·예제와 충돌하면 이 정책과 Navigation Single Mode Policy를 우선한다.
1. 구현 전 필수 판단
작업을 시작하기 전에 반드시 다음 질문에 답한다.
먼저 변경 범위를 STORYBOOK_ONLY | PRODUCTION_UI | BOTH 중 하나로 정하고, 아래 기존 구현과 사용례를 검색한다. 디렉터리 존재 여부와 관련 후보를 확인한 뒤 필요한 파일만 읽는다. CENTER 규격은 CENTER 작업에만 적용하며 일반 UI의 근거로 섞지 않는다.
| 탐색 대상 | 확인 내용 |
|---|---|
packages/ui |
공개 exports, src/components/ui, src/patterns, Theme / Component Mapping |
src/components |
대표 Component Story, 기존 Variant / Prop, story-board.tsx 등 shared helpers |
src/patterns |
Layout / Pattern Story, dashboard-work-status.ts 등 공통 상태 mapping |
src/center |
CENTER 관련 Story 및 center-stories.css의 Common Card 구현 |
| 기존 Storybook stories / shared helpers | 유사 대표/PRIMARY Story, composition, 상태·선택·Card mapping과 공통 helper |
docs/components/, docs/patterns/ |
후보의 현재 API, 적용 Token, 사용자 확정 결정 |
Storybook은 QA 도구이자 구현 Reference Catalog다. Button은 Button 대표 Story, Dashboard는 Dashboard 대표 Story, CENTER 카드는 CENTER Common Card Story부터 확인한다. 현재 Story의 시각 언어를 무시해 새 패턴을 만들지 않는다. verification Story는 계약/상태 검증용이며 운영 화면의 기본 Reference가 아니다. 특히 혼합 Navigation의 VERIFICATION ONLY Story는 신규 구현 근거로 사용하지 않는다. 일반 업무 화면은 Storybook Story·사이드바에 등록하지 않고 별도 React 화면과 독립 미리보기로 제공한다.
Component와 Theme은 함께 설계한다. Component 탐색과 동시에 기존 Theme / Token을 확인하고, 조합과 Semantic 연결을 포함해 화면을 구현한다. 구현 후 Theme을 별도 후처리로 추가하는 흐름은 사용하지 않는다. Theme 우선순위와 Source 수정 조건은 테마 토큰 가이드의 AI 기본 적용 정책을 따른다.
이 화면을 현재
@hm-design/ui+ shadcn 조합으로 만들 수 있는가?
답이 YES이면 그 구조와 동작을 유지하고 HM 디자인 값만 CSS와 Token으로 적용한다. 기본 방향은 shadcn을 HM 디자인으로 스타일링하는 것이며, HM 디자인을 이유로 shadcn을 대체하는 별도 시스템을 만들지 않는다.
2. 구현 우선순위
다음 순서를 건너뛰지 않는다.
- 기존
@hm-design/uiComponent / Pattern 재사용 - 기존 Variant / Prop으로 요구사항 표현
- 기존 Composition으로 해결
- shadcn 기본 Component / Composition 활용
- Radix 등 shadcn이 사용하는 Primitive 활용
- 위 방법으로 해결할 수 없을 때만 최소 Custom 구현
기반 기술의 운영 우선순위는 @hm-design/ui existing → shadcn → Radix Primitive → Composition → CSS / Token Visual → Minimum Custom이다. 이는 새 기반 기능이 필요한 경우의 선택 기준이며, 이미 있는 HM Variant / Composition을 먼저 확인하는 위 재사용 순서를 건너뛰는 이유가 아니다. 모든 단계에서 Visual은 HM Theme / Token으로 연결하며 직접 primitive 동작을 만드는 것은 마지막 수단이다.
판단 예시는 다음과 같다.
| 필요 | 우선 선택 |
|---|---|
| Button | 기존 HM Button |
| Popup | Popover / Dropdown Menu |
| Disclosure | Collapsible / Accordion |
| Mobile navigation | Sheet |
| 검색 조합 | Input / Select / Command / Combobox |
| Empty / Result 화면 | 기존 Pattern / Component composition |
| Search Form | Input + Select + Button |
| Dashboard Empty | Dashboard Layout + 기존 Empty / Data Table composition |
| Filter 화면 | Filter Bar |
| GNB User Menu | Avatar + Dropdown Menu |
3. 구조·동작과 시각의 소유권
shadcn 기반으로 구현 가능한 형태라면 shadcn/Radix의 구조, API, 상태 모델, 접근성, keyboard interaction을 최대한 유지한다.
shadcn/Radix 구조를 유지하는 영역
- DOM / Component 구조
- Public API
- controlled / uncontrolled 방식
data-state- ARIA
- keyboard navigation
- focus management
- Portal
- Dismiss / Escape 동작
asChild- composition 방식
HM이 소유하고 조정할 수 있는 영역
- CSS와 CSS Custom Properties
- Component Token과 Semantic Token mapping
- height, padding, gap
- border, radius, color, shadow
- typography
- responsive layout
즉, Behavior / Structure는 shadcn/Radix를 유지하고 Visual은 HM Theme로 조정한다.
시각 차이는 HM CSS / Token으로, spacing·radius·color 차이는 Component Token으로 해결한다. CSS로 해결 가능한 차이를 위해 새 prop이나 별도 Component API를 추가하지 않는다.
4. Component와 Pattern
이미 @hm-design/ui에 구현된 Component가 있으면 shadcn Component를 다시 복사하거나 비슷한 별도 버전을 만들지 않는다.
Pattern도 새로운 primitive를 만들기 전에 기존 Component composition을 우선한다. 반복 사용성과 고유한 계약이 실제 제품 사용에서 확인될 때만 별도 Pattern으로 승격한다. 시각 결과가 기존 Component 조합으로 표현 가능하다면 Pattern은 조합과 상태 연결만 소유하고 primitive의 동작이나 스타일을 복제하지 않는다.
shadcn/Radix에 이미 존재하는 interaction은 새로 구현하지 않는다. 기존 Component 여러 개로 표현할 수 있는 화면은 composition으로 해결한다.
Status / Badge / Card / Navigation에 공통 mapping이 있으면 함께 재사용한다. 상태 Badge는 기존 Badge → status mapping → 기존 variant → 필요한 최소 확장 순으로 판단한다. Dashboard 상태는 src/patterns/dashboard-work-status.ts, CENTER 카드는 src/center/center-stories.css를 확인한다. 이 파일들은 현재 Story 범위의 구현이므로 재사용 시 Production export 여부와 파일 책임을 확인하고 Story helper를 Production에 직접 import하지 않는다. 색상 값·Card CSS를 복사하거나 Dashboard 전용 Badge를 중복 생성하지 않는다.
package exports, public props, public types, package entry, Story ID, meta.title을 불필요하게 변경하지 않는다. 요구사항상 변경이 필요하면 소비처, 호환성 및 Story 링크 영향을 먼저 확인하고 사유를 기록한다.
5. Storybook과 Production 구현 분리
5.1 Storybook Reference와 신규 화면 생성의 분리
일반적인 "화면 만들어줘", 대시보드 또는 업무 페이지 제작 요청에서 Storybook은 기존 디자인 시스템을 확인하는 Reference로만 사용한다. 신규 업무 화면을 Story로 등록하거나 Storybook 사이드바에 추가하지 않으며, 기존 대표 Story를 생성 화면으로 교체하지 않는다. 화면 확인을 위해 Storybook 실행을 필수로 요구하지 않고, 별도의 React 화면을 빌드한 뒤 독립적인 미리보기를 제공한다. H-2 또는 유사 자동화가 사용 가능한 경우 preview.html·desktop/mobile 이미지 등 독립 미리보기 산출을 지원할 수 있지만, 이는 Storybook Story 등록과 별개의 역할이다. Storybook 전용 helper/CSS는 운영 화면에 사용하지 않는다.
다음처럼 사용자가 Storybook 수정을 명시한 경우에는 예외로 처리한다: 새로운 Component 또는 Pattern 추가/수정, 대표 또는 Verification Story 작성, Storybook Reference 자체 개선. 이 예외에서도 화면 생성 결과와 Storybook Reference 변경을 서로 다른 범위로 기록한다.
Storybook에서 디자인 상태를 비교하기 위한 표현 때문에 Production API를 추가하지 않는다.
STORYBOOK_ONLY의 배치·specimen 표현 문제는 Story 범위에서 해결한다. 이를 이유로 Production Component를 불필요하게 수정하지 않는다. 실제 Production 동작 문제가 있으면 필요한 Production 변경과 관련 Story를 함께 다루며 Story CSS override로만 숨기지 않는다.
다음은 Story 전용 표현으로 처리할 수 있다.
- Hover 고정 specimen
- Selected + Hover 비교
- Spacing guide
- Token reference
Story 안의 실제 화면과 상호작용에는 가능한 한 production @hm-design/ui Component를 그대로 사용한다. 특정 상태를 보여줄 때도 production Component의 실제 API와 shadcn/Radix 상태 모델을 우선한다. Story 전용 helper나 selector는 검수 표현에만 한정하며 production bundle이나 Public API에 포함하지 않는다.
6. Custom 구현 허용 조건
별도 Custom 구현은 다음을 모두 확인한 뒤에만 허용한다.
- 기존 HM Component로 해결할 수 없다.
- 기존 Component composition으로 해결할 수 없다.
- 기존 Variant / Prop 확장이 요구사항·API 의미에 부적절하다.
- shadcn 기본 Component 및 Radix Primitive 조합으로 해결하기 어렵다.
- CSS / Token 조정만으로 해결할 수 없다.
- 실제 제품에서 반복적으로 필요한 독립적인 동작 또는 API가 있다.
Custom 구현은 필요한 동작과 API에 한해 최소 범위로 제한한다. 결과 보고와 관련 컴포넌트 또는 패턴 문서에는 다음을 기록한다.
- 왜 shadcn으로 해결할 수 없었는지
- 왜 기존 HM 조합으로 해결할 수 없었는지
- 왜 기존 Variant 확장이 부적절하고 Radix 조합도 어려운지
- 추가한 Custom 범위
- Public API 영향
7. 금지 사항
- 디자인을 맞추기 위해 shadcn을 통째로 다시 작성한다.
- Radix state logic을 재구현한다.
- 기존 HM Component와 유사한 Custom Component를 추가한다.
- Storybook 검증만을 위한 Production prop을 추가한다.
- CSS로 해결 가능한 차이에 새 API를 추가한다.
- 이전 ui-viz JSX, DOM, class 또는 상태 로직을 그대로 복사한다.
- 기존 Component와 Story를 확인하지 않고 Button / Input / Badge / Card / Dialog / Select / Table / Navigation 등을 생성한다.
- 기존 Badge가 있는데 Dashboard 전용 Badge를 새로 만들거나 기존 Common Card CSS를 복사한다.
- 기존 Theme Token이 있는데 색상·spacing·값을 하드코딩하거나 같은 Token을 여러 파일에 중복 정의한다.
- UI 구현 후 Theme을 선택적 후처리로 적용한다.
- Storybook 표현 문제만을 위해 Production 코드를 바꾸거나 Production 동작 문제를 Story CSS override로 숨긴다.
- GNB / LNB / Dashboard 혼합은 운영 페이지에 사용하지 않는다. 혼합 Navigation은 현재 단일 모드 정책의 조건을 충족하는 기술 검증 Story에만 둔다.
8. 구현·검토 체크리스트
- 현재
@hm-design/ui에 재사용할 Component 또는 Pattern이 있는가? - 기존 Variant / Prop / Composition과 유사 대표 Story, 공통 mapping을 먼저 확인했는가?
- shadcn 기본 Component / Composition으로 해결할 수 있는가?
- Radix 또는 기존 기반 라이브러리가 동작과 접근성을 이미 제공하는가?
- Component composition으로 별도 primitive 없이 표현할 수 있는가?
- 남은 차이는 HM CSS / Token만으로 맞출 수 있는가?
- Story 전용 요구가 Production API로 유입되지 않았는가?
- Custom이 필요하다면 모든 허용 조건과 기록 요건을 충족했는가?
- Theme / Semantic 연결, 독립 fallback, 변경 범위와 public API 보호를 지켰는가?
- 단일 Navigation Mode와 같은 모드의 반응형 표현을 지켰는가?
9. AI 신규 화면 구현 순서
AI 화면 구현의 단일 실행 순서는 저장소 루트의 AGENTS.md 필수 규칙을 따른다. 후보 Component·Pattern의 실제 export, 사용 문서, 대표 Story는 통합 Reference Index에서 찾는다. 일반 업무 화면은 Storybook에 등록하지 않고 별도 React 화면으로 생성하며, 화면별 빌드·필요한 검증·독립 미리보기를 결과로 제공한다. 상세 재사용·Theme·Navigation 조건은 이 문서와 연결된 Source of Truth를 유지한다.
구현 중에는 다음 단계에 필요한 최소 확인만 하고, 완료 후 diff / 요구사항 / 관련 Story / 필요한 프로젝트 검증을 한 번에 수행한다. 같은 조건으로 성공한 검증을 형식적으로 반복하지 않는다.
10. 명시적 예외
사용자가 새로운 Component 실험, Theme 미적용 prototype, 외부 디자인 완전 재현, 기존 디자인 시스템과 독립된 POC를 명시적으로 요청한 경우에만 기본 정책의 예외를 검토한다. 예외의 목적·범위·사유와 Theme 미적용 여부를 기록하고 기존 시스템에 영향을 주지 않는 별도 Story / 실험 범위로 격리한다. Production exports / Theme Source / 공통 mapping을 임의로 변경하지 않는다.
이 예외는 혼합 Navigation 운영을 자동 허용하지 않는다. Navigation 조합을 명시적으로 요청받아도 정책 변경인지 기술 검증인지 구분하며 Navigation Single Mode Policy의 verification 태그와 VERIFICATION ONLY 조건을 유지한다.