# 04. 공통 컴포넌트 사용법 > **대상**: 프론트엔드 개발자 > **버전**: 1.0.0 > **최종 수정**: 2026-03-09 --- ## 1. UniversalListPage 59+ 리스트 페이지에서 사용하는 통합 템플릿. config 객체 하나로 전체 동작 제어. ### 기본 사용법 ```typescript import { UniversalListPage, type UniversalListConfig, type StatCard, } from '@/components/templates/UniversalListPage'; const config: UniversalListConfig = { // 필수 title: '페이지 제목', icon: FileText, basePath: '/accounting/my-page', idField: 'id', columns: [ { key: 'name', label: '이름', className: 'w-[200px]' }, { key: 'amount', label: '금액', className: 'text-right w-[120px]' }, { key: 'status', label: '상태', className: 'text-center w-[80px]' }, ], actions: { getList: getMyList, // Server Action deleteItems: deleteMyItems, // 선택사항 }, // 선택 itemsPerPage: 20, showCheckbox: true, clientSideFiltering: false, // 서버 페이지네이션 시 false }; return ; ``` ### 주요 config 옵션 | 옵션 | 타입 | 설명 | |------|------|------| | `columns` | Column[] | 테이블 컬럼 정의 | | `actions.getList` | Function | 목록 조회 Server Action | | `showCheckbox` | boolean | 체크박스 표시 | | `hideSearch` | boolean | 검색창 숨김 | | `computeStats` | () => StatCard[] | 통계 카드 | | `headerActions` | () => ReactNode | 헤더 버튼 영역 | | `renderTableRow` | Function | 커스텀 행 렌더링 | | `renderMobileCard` | Function | 모바일 카드 렌더링 | | `tableFooter` | ReactNode | 테이블 하단 (합계 행 등) | | `dateRangeSelector` | Object | 날짜 범위 선택기 | | `tabs` | Tab[] | 탭 필터 | | `excelExport` | Object | Excel 내보내기 설정 | ### 서버 페이지네이션 연동 ```typescript const [currentPage, setCurrentPage] = useState(1); const [pagination, setPagination] = useState({ ... }); ``` --- ## 2. SearchableSelectionModal\ 검색 + 선택 기능이 필요한 모달. 직접 Dialog 조합 금지. ### 사용법 ```typescript import { SearchableSelectionModal } from '@/components/organisms'; open={isOpen} onOpenChange={setIsOpen} title="거래처 선택" searchPlaceholder="거래처명 검색" fetchItems={async (search) => { const result = await searchClients({ search }); return result.success ? result.data : []; }} columns={[ { key: 'name', label: '거래처명' }, { key: 'code', label: '코드' }, ]} onSelect={(item) => { setSelectedClient(item); setIsOpen(false); }} getItemId={(item) => item.id} /> ``` --- ## 3. IntegratedDetailTemplate 상세/등록/수정 페이지 통합 템플릿. ### 기본 사용법 ```typescript import { IntegratedDetailTemplate } from '@/components/templates/IntegratedDetailTemplate'; ``` ### forwardRef API 프로그래밍 방식으로 폼 제어: ```typescript const templateRef = useRef(null); // 폼 데이터 읽기/쓰기 templateRef.current?.getFormData(); templateRef.current?.setFormData(newData); templateRef.current?.setFieldValue('name', '새 이름'); templateRef.current?.validate(); ``` --- ## 4. PageHeader / PageLayout ### PageLayout — 페이지 콘텐츠 래퍼 ```typescript import { PageLayout } from '@/components/organisms/PageLayout'; {/* 콘텐츠 */} ``` - 자동으로 `p-0 md:space-y-6` 패딩 적용 - **page.tsx에서 추가 패딩 금지** (이중 패딩 방지) ### PageHeader — 페이지 제목 ```typescript import { PageHeader } from '@/components/organisms/PageHeader'; 등록 } /> ``` --- ## 5. StatCards — 통계 카드 ```typescript import { StatCards } from '@/components/organisms'; ``` --- ## 6. DataTable — 데이터 테이블 organisms 레벨 범용 테이블. UniversalListPage 내부에서도 사용. ```typescript import { DataTable } from '@/components/organisms'; handleDetail(item.id)} /> ``` --- ## 7. 테이블 필수 구조 모든 테이블은 다음 컬럼 순서를 준수: ``` [체크박스] → [번호(1부터)] → [데이터 컬럼들] → [작업 컬럼] ``` - **번호**: `(currentPage - 1) * pageSize + index + 1` - **작업 버튼**: 체크박스 선택 시만 표시 (또는 행별 버튼)