# POP 컴포넌트 로드맵 ## 큰 그림: 3단계 접근 ``` ┌─────────────────────────────────────────────────────────────────┐ │ │ │ 1단계: 기초 블록 2단계: 조합 블록 3단계: 완성 화면 │ │ ─────────────── ─────────────── ─────────────── │ │ │ │ [버튼] [입력창] [폼 그룹] [작업지시 화면] │ │ [아이콘] [라벨] → [카드] → [실적입력 화면] │ │ [뱃지] [로딩] [리스트] [모니터링 대시보드] │ │ [테이블] │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` --- ## 1단계: 기초 블록 (Primitive) 가장 작은 단위. 다른 곳에서 재사용됩니다. ### 필수 기초 블록 | 컴포넌트 | 역할 | 우선순위 | |---------|------|---------| | `PopButton` | 모든 버튼 | 1 | | `PopInput` | 텍스트 입력 | 1 | | `PopLabel` | 라벨/제목 | 1 | | `PopIcon` | 아이콘 표시 | 1 | | `PopBadge` | 상태 뱃지 | 2 | | `PopLoading` | 로딩 스피너 | 2 | | `PopDivider` | 구분선 | 3 | ### PopButton 예시 ```typescript interface PopButtonProps { children: React.ReactNode; variant: "primary" | "secondary" | "danger" | "success"; size: "sm" | "md" | "lg" | "xl"; disabled?: boolean; loading?: boolean; icon?: string; fullWidth?: boolean; onClick?: () => void; } // 사용 작업 완료 ``` ### PopInput 예시 ```typescript interface PopInputProps { type: "text" | "number" | "date" | "time"; value: string | number; onChange: (value: string | number) => void; label?: string; placeholder?: string; required?: boolean; error?: string; size: "md" | "lg"; // POP은 lg 기본 } // 사용 ``` --- ## 2단계: 조합 블록 (Compound) 기초 블록을 조합한 중간 단위. ### 조합 블록 목록 | 컴포넌트 | 구성 | 용도 | |---------|------|-----| | `PopFormField` | Label + Input + Error | 폼 입력 그룹 | | `PopCard` | Container + Header + Body | 정보 카드 | | `PopListItem` | Container + Content + Action | 리스트 항목 | | `PopNumberPad` | Grid + Buttons | 숫자 입력 | | `PopStatusBox` | Icon + Label + Value | 상태 표시 | ### PopFormField 예시 ```typescript // 기초 블록 조합 function PopFormField({ label, required, error, children }) { return (
{label} {children} {error && {error}}
); } // 사용 ``` ### PopCard 예시 ```typescript function PopCard({ title, badge, children, onClick }) { return (
{title} {badge && {badge}}
{children}
); } // 사용

목표 수량: 100개

완료 수량: 45개

``` --- ## 3단계: 복합 컴포넌트 (Complex) 비즈니스 로직이 포함된 완성형. ### 복합 컴포넌트 목록 | 컴포넌트 | 기능 | 데이터 | |---------|------|-------| | `PopDataTable` | 대량 데이터 표시/편집 | API 연동 | | `PopCardList` | 카드 형태 리스트 | API 연동 | | `PopBarcodeScanner` | 바코드/QR 스캔 | 카메라/외부장치 | | `PopKpiGauge` | KPI 게이지 | 실시간 데이터 | | `PopAlarmList` | 알람 목록 | 웹소켓 | | `PopProcessFlow` | 공정 흐름도 | 공정 데이터 | ### PopDataTable 예시 ```typescript interface PopDataTableProps { // 데이터 data: any[]; columns: Column[]; // 기능 selectable?: boolean; editable?: boolean; sortable?: boolean; // 반응형 (자동) responsiveColumns?: { tablet: string[]; mobile: string[]; }; // 이벤트 onRowClick?: (row: any) => void; onSelectionChange?: (selected: any[]) => void; } // 사용 openDetail(row.id)} /> ``` --- ## 개발 순서 제안 ### Phase 1: 기초 (1-2주) ``` Week 1: - PopButton (모든 버튼의 기반) - PopInput (모든 입력의 기반) - PopLabel - PopIcon Week 2: - PopBadge - PopLoading - PopDivider ``` ### Phase 2: 조합 (2-3주) ``` Week 3: - PopFormField (폼의 기본 단위) - PopCard (카드의 기본 단위) Week 4: - PopListItem - PopStatusBox - PopNumberPad Week 5: - PopModal - PopToast ``` ### Phase 3: 복합 (3-4주) ``` Week 6-7: - PopDataTable (가장 복잡) - PopCardList Week 8-9: - PopBarcodeScanner - PopKpiGauge - PopAlarmList - PopProcessFlow ``` --- ## 컴포넌트 설계 원칙 ### 1. 크기는 외부에서 제어 ```typescript // 좋음: 크기를 props로 받음 확인 // 나쁨: 내부에서 크기 고정 ``` ### 2. 최소 크기는 내부에서 보장 ```typescript // 컴포넌트 내부 const styles = { minHeight: 48, // 터치 최소 크기 보장 minWidth: 80, }; ``` ### 3. 반응형은 자동 ```typescript // 좋음: 화면 크기에 따라 자동 조절 // 나쁨: 모드별로 다른 컴포넌트 {isMobile ? : } ``` ### 4. 데이터와 UI 분리 ```typescript // 좋음: 데이터 로직은 훅으로 const { data, loading, error } = useWorkOrders(); // 나쁨: 컴포넌트 안에서 fetch function PopDataTable() { useEffect(() => { fetch('/api/work-orders')... }, []); } ``` --- ## 폴더 구조 제안 ``` frontend/components/pop/ ├── primitives/ # 1단계: 기초 블록 │ ├── PopButton.tsx │ ├── PopInput.tsx │ ├── PopLabel.tsx │ ├── PopIcon.tsx │ ├── PopBadge.tsx │ ├── PopLoading.tsx │ └── index.ts │ ├── compounds/ # 2단계: 조합 블록 │ ├── PopFormField.tsx │ ├── PopCard.tsx │ ├── PopListItem.tsx │ ├── PopNumberPad.tsx │ ├── PopStatusBox.tsx │ └── index.ts │ ├── complex/ # 3단계: 복합 컴포넌트 │ ├── PopDataTable/ │ │ ├── PopDataTable.tsx │ │ ├── PopTableHeader.tsx │ │ ├── PopTableRow.tsx │ │ └── index.ts │ ├── PopCardList/ │ ├── PopBarcodeScanner/ │ └── index.ts │ ├── hooks/ # 공용 훅 │ ├── usePopTheme.ts │ ├── useResponsiveSize.ts │ └── useTouchFeedback.ts │ └── styles/ # 공용 스타일 ├── pop-variables.css └── pop-base.css ``` --- ## 스타일 변수 ```css /* pop-variables.css */ :root { /* 터치 크기 */ --pop-touch-min: 48px; --pop-touch-industrial: 60px; /* 폰트 크기 */ --pop-font-body: clamp(14px, 1.5vw, 18px); --pop-font-heading: clamp(18px, 2.5vw, 28px); --pop-font-caption: clamp(12px, 1vw, 14px); /* 간격 */ --pop-gap-sm: 8px; --pop-gap-md: 16px; --pop-gap-lg: 24px; /* 색상 */ --pop-primary: #2563eb; --pop-success: #16a34a; --pop-warning: #f59e0b; --pop-danger: #dc2626; /* 고대비 (야외용) */ --pop-high-contrast-bg: #000000; --pop-high-contrast-fg: #ffffff; } ``` --- ## 다음 단계 1. **기초 블록부터 시작**: PopButton, PopInput 먼저 만들기 2. **스토리북 설정**: 컴포넌트별 문서화 3. **테스트**: 터치 크기, 반응형 확인 4. **디자이너 연동**: v4 레이아웃 시스템과 통합 --- *최종 업데이트: 2026-02-03*