# shadcn/ui 적용 상태 분석 보고서 > 작성일: 2025-01-27 > 기준: shadcn/ui 공식 문서 (https://ui.shadcn.com) ## 📋 목차 1. [개요](#개요) 2. [적용 상태 요약](#적용-상태-요약) 3. [양호한 부분](#양호한-부분) 4. [개선이 필요한 부분](#개선이-필요한-부분) 5. [우선순위별 개선 사항](#우선순위별-개선-사항) 6. [구체적인 수정 필요 파일](#구체적인-수정-필요-파일) --- ## 개요 이 보고서는 프로젝트 전반에 걸쳐 shadcn/ui 공식 문서 기준을 얼마나 잘 준수하고 있는지 분석한 결과입니다. **분석 범위:** - 설정 파일 (components.json, globals.css, tailwind.config) - UI 컴포넌트 (`frontend/components/ui/`) - 비즈니스 컴포넌트 (`frontend/components/`, `frontend/lib/registry/`) - 스타일 가이드 준수 여부 --- ## 적용 상태 요약 ### ✅ 잘 적용된 부분 (70%) 1. **기본 설정** - `components.json` 설정 올바름 - CSS 변수 시스템 정상 작동 - `cn()` 유틸리티 함수 사용 2. **기본 UI 컴포넌트** - Button, Card, Input 등 기본 컴포넌트는 shadcn 표준 따름 - 다크모드 지원 구조 정상 ### ⚠️ 개선이 필요한 부분 (30%) 1. **하드코딩된 색상 사용** (약 2,000+ 건) - `bg-blue-500`, `bg-gray-50`, `text-red-500` 등 직접 색상 사용 - `#ffffff`, `#f9fafb` 등 인라인 스타일 색상 2. **비표준 스타일 패턴** - `border-blue-500`, `ring-blue-100` 등 직접 색상 사용 - `focus:border-orange-500` 등 커스텀 포커스 색상 3. **중첩 박스 문제** - 일부 컴포넌트에서 불필요한 중첩 구조 발견 --- ## 양호한 부분 ### 1. 기본 설정 ✅ **components.json** ```json { "$schema": "https://ui.shadcn.com/schema.json", "style": "new-york", "rsc": true, "tsx": true, "tailwind": { "baseColor": "neutral", "cssVariables": true } } ``` ✅ shadcn 공식 설정과 일치 **globals.css** ```css :root { --background: 0 0% 100%; --foreground: 222.2 84% 4.9%; --primary: 222.2 47.4% 11.2%; /* ... */ } ``` ✅ HSL 형식, 공식 기본값 사용 ### 2. 기본 UI 컴포넌트 ✅ **Button 컴포넌트** (`frontend/components/ui/button.tsx`) ```tsx const buttonVariants = cva("inline-flex items-center justify-center ...", { variants: { variant: { default: "bg-primary text-primary-foreground hover:bg-primary/90", destructive: "bg-destructive text-white ...", // ... }, }, }); ``` ✅ shadcn 공식 패턴 준수 **Card 컴포넌트** (`frontend/components/ui/card.tsx`) ```tsx function Card({ className, ...props }) { return (
); } ``` ✅ CSS 변수 사용, 표준 구조 **Input 컴포넌트** (`frontend/components/ui/input.tsx`) ```tsx className={cn( "border-input bg-transparent ...", "focus-visible:border-ring focus-visible:ring-ring/50 ...", className )} ``` ✅ 시맨틱 색상 사용 ### 3. 유틸리티 함수 ✅ **lib/utils.ts** ```typescript export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } ``` ✅ 공식 구현과 동일 --- ## 개선이 필요한 부분 ### 1. 하드코딩된 색상 사용 ❌ #### 문제점 **직접 색상 클래스 사용** (약 1,600+ 건) ```tsx // ❌ 잘못된 예시
버튼
카드
에러 ``` **인라인 스타일 색상** (약 354건) ```tsx // ❌ 잘못된 예시
``` #### 올바른 패턴 ```tsx // ✅ 올바른 예시
버튼
카드
에러 ``` ### 2. 비표준 포커스 스타일 ❌ #### 문제점 **직접 색상 사용** ```tsx // ❌ 잘못된 예시 (TextInputComponent.tsx) className={` ${isSelected ? "border-blue-500 ring-2 ring-blue-100" : "border-gray-300"} focus:border-orange-500 focus:ring-2 focus:ring-orange-100 `} ``` #### 올바른 패턴 ```tsx // ✅ 올바른 예시 className={cn( "border-input", isSelected && "border-ring ring-2 ring-ring/50", "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-2" )} ``` ### 3. 불필요한 인라인 스타일 ❌ #### 문제점 **하드코딩된 색상 값** ```tsx // ❌ 잘못된 예시 (TableListComponent.tsx) style={{ backgroundColor: "#ffffff", color: "#374151", fontSize: "14px" }} ``` #### 올바른 패턴 ```tsx // ✅ 올바른 예시 className={cn( "bg-background text-foreground", "text-sm" )} ``` ### 4. 중첩 박스 문제 ⚠️ **일부 컴포넌트에서 발견** ```tsx // ⚠️ 중첩된 구조 (CardLayoutRenderer.tsx)
{" "} {/* 중첩된 박스 */} 내용
``` **권장 구조** ```tsx // ✅ 단일 레벨 내용 ``` --- ## 우선순위별 개선 사항 ### 🔴 Priority 1: 핵심 컴포넌트 수정 (즉시) **대상 파일:** 1. `frontend/lib/registry/components/text-input/TextInputComponent.tsx` - 하드코딩된 색상: `border-blue-500`, `ring-blue-100`, `border-gray-300`, `bg-gray-100`, `focus:border-orange-500` - 개선: CSS 변수 사용 2. `frontend/lib/registry/components/date-input/DateInputComponent.tsx` - 동일한 문제 패턴 3. `frontend/lib/registry/components/table-list/TableListComponent.tsx` - 인라인 스타일 색상: `#ffffff`, `#374151`, `#64748b` ### 🟡 Priority 2: 페이지 레벨 수정 (단기) **대상 파일:** 1. `frontend/app/(main)/dashboard/page.tsx` - `bg-blue-500`, `text-white`, `bg-gray-50`, `text-gray-900` 등 2. `frontend/app/(main)/dashboard/[dashboardId]/page.tsx` - 동일한 패턴 3. `frontend/components/screen/InteractiveScreenViewer.tsx` - `bg-gray-50`, `text-gray-700` 등 ### 🟢 Priority 3: 위젯/차트 컴포넌트 (중기) **대상 파일:** 1. `frontend/components/dashboard/widgets/*.tsx` - 위젯별 커스텀 색상이 필요할 수 있으나, 가능한 한 CSS 변수 사용 2. `frontend/components/admin/dashboard/widgets/*.tsx` - 동일 ### ⚪ Priority 4: 기타 (장기) **대상 파일:** - 나머지 모든 파일에서 하드코딩된 색상 점진적 교체 --- ## 구체적인 수정 필요 파일 ### 📁 핵심 컴포넌트 (즉시 수정 필요) #### 1. TextInputComponent.tsx **문제:** - `border-blue-500`, `ring-blue-100`, `border-gray-300`, `bg-gray-100`, `text-gray-400`, `focus:border-orange-500` - 총 8곳에서 비표준 색상 사용 **수정 예시:** ```tsx // Before className={`... ${isSelected ? "border-blue-500 ring-2 ring-blue-100" : "border-gray-300"} ...`} // After className={cn( "border-input", isSelected && "border-ring ring-2 ring-ring/50", "focus-visible:border-ring focus-visible:ring-ring/50" )} ``` #### 2. DateInputComponent.tsx **문제:** - TextInputComponent와 동일한 패턴 #### 3. TableListComponent.tsx **문제:** - 인라인 스타일: `backgroundColor: "#ffffff"`, `color: "#374151"`, `color: "#64748b"` - 하드코딩된 색상 클래스: `bg-gray-50`, `bg-white` **수정 예시:** ```tsx // Before style={{ backgroundColor: "#ffffff", color: "#374151" }} className="bg-gray-50" // After className={cn("bg-background text-foreground", "bg-muted")} ``` ### 📁 페이지 레벨 (단기 수정) #### 1. dashboard/page.tsx **문제:** - `bg-blue-500`, `text-white`, `hover:bg-blue-600` - `bg-gray-50`, `text-gray-900`, `text-gray-600` **수정 예시:** ```tsx // Before

제목

``` #### 2. screen/InteractiveScreenViewer.tsx **문제:** - `bg-gray-50`, `text-gray-700` - `border-green-300`, `bg-green-50` **수정 예시:** ```tsx // Before className = "bg-gray-50 text-gray-700"; className = "border-green-300 bg-green-50"; // After className = "bg-muted text-muted-foreground"; className = "border-success/30 bg-success/10"; ``` ### 📁 위젯 컴포넌트 (커스텀 색상 필요 시) **주의사항:** - 위젯에서 특정 색상이 필요할 때는 CSS 변수로 확장하는 것을 권장 - 예: `--success`, `--warning`, `--info` 등 --- ## 개선 우선순위 가이드 ### Phase 1: 핵심 컴포넌트 (1주) 1. ✅ TextInputComponent.tsx 2. ✅ DateInputComponent.tsx 3. ✅ TableListComponent.tsx ### Phase 2: 주요 페이지 (2주) 1. ✅ Dashboard 페이지들 2. ✅ Screen 페이지들 3. ✅ Admin 페이지들 ### Phase 3: 위젯/차트 (3주) 1. ✅ Dashboard 위젯들 2. ✅ 차트 컴포넌트들 3. ✅ 3D 위젯들 ### Phase 4: 전체 정리 (장기) 1. ✅ 나머지 모든 파일 점진적 교체 2. ✅ 린터 규칙 추가 (하드코딩 색상 금지) 3. ✅ 코드 리뷰 가이드라인 업데이트 --- ## 개선 효과 ### 예상 효과 1. **일관성 향상** - 모든 컴포넌트가 동일한 색상 시스템 사용 - 다크모드 전환 시 자동 대응 2. **유지보수성 향상** - 색상 변경 시 CSS 변수만 수정하면 전체 반영 - 테마 커스터마이징 용이 3. **접근성 향상** - 시맨틱 색상 사용으로 의미 전달 명확 - 다크모드 지원 자동화 4. **코드 품질 향상** - 하드코딩 제거로 코드 간결화 - shadcn 공식 문서 준수 --- ## 체크리스트 ### 기본 설정 - [x] components.json 설정 올바름 - [x] globals.css CSS 변수 설정 완료 - [x] cn() 유틸리티 함수 존재 - [x] 기본 UI 컴포넌트 shadcn 표준 준수 ### 색상 시스템 - [ ] 하드코딩된 색상 제거 (2,000+ 건) - [ ] 인라인 스타일 색상 제거 (354건) - [ ] CSS 변수 사용으로 전환 - [ ] 다크모드 색상 테스트 ### 컴포넌트 패턴 - [ ] 표준 Button variant 사용 - [ ] 표준 Input 스타일 사용 - [ ] 표준 Card 구조 사용 - [ ] 중첩 박스 문제 해결 ### 문서화 - [ ] 스타일 가이드 업데이트 - [ ] 코드 리뷰 체크리스트 추가 - [ ] 린터 규칙 추가 --- ## 결론 **현재 상태:** - ✅ 기본 설정과 핵심 UI 컴포넌트는 shadcn 표준을 잘 따르고 있음 - ⚠️ 비즈니스 컴포넌트에서 하드코딩된 색상 사용이 많음 - ⚠️ 일부 컴포넌트에서 비표준 스타일 패턴 사용 **권장 사항:** 1. **즉시 조치**: 핵심 컴포넌트 (TextInput, DateInput, TableList) 색상 통일 2. **단기 조치**: 주요 페이지 레벨 색상 교체 3. **중기 조치**: 위젯/차트 컴포넌트 점진적 개선 4. **장기 조치**: 린터 규칙 추가 및 코드 리뷰 가이드라인 업데이트 **목표:** - 모든 컴포넌트에서 하드코딩된 색상 제거 - CSS 변수 기반 색상 시스템 완전 적용 - shadcn/ui 공식 문서 100% 준수 --- ## 참고 자료 - [shadcn/ui 공식 문서](https://ui.shadcn.com) - [프로젝트 shadcn 가이드](./shadcn-ui-완전가이드.md) - [프로젝트 스타일 가이드](../.cursor/rules/admin-page-style-guide.mdc)