- Deleted the following files as they are no longer relevant to the current project structure: - 결재 시스템 구현 현황 - 결재 시스템 v2 사용 가이드 - WACE 시스템 문제점 분석 및 개선 계획 - Agent Pipeline 한계점 분석 - AI 기반 화면 자동 생성 시스템 설계서 - WACE ERP Backend - 분석 문서 인덱스 These deletions help streamline the documentation and remove obsolete information, ensuring that only current and relevant resources are maintained.
5.8 KiB
5.8 KiB
WACE 반응형 컴포넌트 전략
개요
WACE 프로젝트의 모든 반응형 UI는 3개의 레이아웃 프리미티브 + 1개의 훅으로 통일한다. 컴포넌트마다 새로 타입을 정의하거나 리사이저를 구현하지 않는다.
아키텍처
┌─────────────────────────────────────────────────┐
│ useResponsive() 훅 │
│ isMobile | isTablet | isDesktop | width │
└──────────┬──────────┬──────────┬────────────────┘
│ │ │
┌───────▼──┐ ┌────▼─────┐ ┌─▼──────────────┐
│ 데이터 │ │ 좌우분할 │ │ 캔버스(디자이너)│
│ 목록 │ │ 패널 │ │ 화면 │
└──────────┘ └──────────┘ └────────────────┘
ResponsiveDataView ResponsiveSplitPanel ResponsiveGridRenderer
1. useResponsive (훅)
위치: frontend/lib/hooks/useResponsive.ts
모든 반응형 판단의 기반. 직접 breakpoint 분기가 필요할 때만 사용. 가능하면 아래 레이아웃 컴포넌트를 쓰고, 훅 직접 사용은 최소화.
| 반환값 | 브레이크포인트 | 해상도 |
|---|---|---|
| isMobile | xs, sm | < 768px |
| isTablet | md | 768 ~ 1023px |
| isDesktop | lg, xl, 2xl | >= 1024px |
2. ResponsiveDataView (데이터 목록)
위치: frontend/components/common/ResponsiveDataView.tsx
패턴: 데스크톱 = 테이블, 모바일 = 카드 리스트
적용 대상: 모든 목록/리스트 화면
<ResponsiveDataView<User>
data={users}
columns={columns}
keyExtractor={(u) => u.id}
cardTitle={(u) => u.name}
cardFields={[
{ label: "이메일", render: (u) => u.email },
{ label: "부서", render: (u) => u.dept },
]}
renderActions={(u) => <Button>편집</Button>}
/>
적용 완료 (12개 화면):
- UserTable, CompanyTable, UserAuthTable
- DataFlowList, ScreenList
- system-notices, approvalTemplate, standards
- batch-management, mail/receive, flowMgmtList
- exconList, exCallConfList
3. ResponsiveSplitPanel (좌우 분할)
위치: frontend/components/common/ResponsiveSplitPanel.tsx
패턴: 데스크톱 = 좌우 분할(리사이저 포함), 모바일 = 세로 스택(접기/펼치기)
적용 대상: 카테고리관리, 메뉴관리, 부서관리, BOM 등 좌우 분할 레이아웃
<ResponsiveSplitPanel
left={<TreeView />}
right={<DetailPanel />}
leftTitle="카테고리"
leftWidth={25}
minLeftWidth={10}
maxLeftWidth={40}
height="calc(100vh - 120px)"
/>
Props:
| Prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| left | ReactNode | 필수 | 좌측 패널 콘텐츠 |
| right | ReactNode | 필수 | 우측 패널 콘텐츠 |
| leftTitle | string | "목록" | 모바일 접기 헤더 |
| leftWidth | number | 25 | 초기 좌측 너비(%) |
| minLeftWidth | number | 10 | 최소 좌측 너비(%) |
| maxLeftWidth | number | 50 | 최대 좌측 너비(%) |
| showResizer | boolean | true | 리사이저 표시 |
| collapsedOnMobile | boolean | true | 모바일 기본 접힘 |
| height | string | "100%" | 컨테이너 높이 |
동작:
- 데스크톱(>= 1024px): 좌우 분할 + 드래그 리사이저 + 좌측 접기 버튼
- 모바일(< 1024px): 세로 스택, 좌측 패널 40vh 제한, 접기/펼치기
마이그레이션 후보:
V2CategoryManagerComponent(완료)SplitPanelLayoutComponent(v1, v2)BomTreeComponentScreenSplitPanel- menu/page.tsx (메뉴 관리)
- departments/page.tsx (부서 관리)
4. ResponsiveGridRenderer (디자이너 캔버스)
위치: frontend/components/screen/ResponsiveGridRenderer.tsx
패턴: 데스크톱(비전폭 컴포넌트) = 캔버스 스케일링, 그 외 = Flex 그리드
적용 대상: 화면 디자이너로 만든 동적 화면
이 컴포넌트는 화면 디자이너 시스템 전용. 일반 개발에서 직접 사용하지 않음.
사용 가이드
새 화면 만들 때
| 화면 유형 | 사용 컴포넌트 |
|---|---|
| 데이터 목록 (테이블) | ResponsiveDataView |
| 좌우 분할 (트리+상세) | ResponsiveSplitPanel |
| 디자이너 화면 | ResponsiveGridRenderer (자동) |
| 단순 레이아웃 | Tailwind 반응형 (flex-col lg:flex-row) |
금지 사항
- 컴포넌트 내부에
isDraggingRef,handleMouseDown/Move/Up직접 구현 금지 ->ResponsiveSplitPanel사용 hidden lg:block/lg:hidden패턴으로 테이블/카드 이중 렌더링 금지 ->ResponsiveDataView사용window.innerWidth직접 체크 금지 ->useResponsive()훅 사용- 반응형 분기를 위한 새로운 타입/인터페이스 정의 금지 -> 기존 프리미티브의 Props 사용
폐기 예정 컴포넌트
| 컴포넌트 | 대체 | 상태 |
|---|---|---|
ResponsiveContainer |
Tailwind 또는 useResponsive |
미사용, 삭제 예정 |
ResponsiveGrid |
Tailwind grid-cols-* |
미사용, 삭제 예정 |
ResponsiveText |
Tailwind text-sm lg:text-lg |
미사용, 삭제 예정 |
파일 구조
frontend/
├── lib/hooks/
│ └── useResponsive.ts # 브레이크포인트 훅 (기반)
├── components/common/
│ ├── ResponsiveDataView.tsx # 테이블/카드 전환
│ └── ResponsiveSplitPanel.tsx # 좌우 분할 반응형
└── components/screen/
└── ResponsiveGridRenderer.tsx # 디자이너 캔버스 렌더러