From 8440ac29c7dcbef992039678ecc0fabff2fd04ec Mon Sep 17 00:00:00 2001 From: dujinkim Date: Mon, 1 Dec 2025 00:58:23 +0000 Subject: (대표님) S-EDP 관련 대표님 작업사항 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/client-data-table/data-table.tsx | 300 ++++++++++++++-------------- 1 file changed, 154 insertions(+), 146 deletions(-) (limited to 'components/client-data-table/data-table.tsx') diff --git a/components/client-data-table/data-table.tsx b/components/client-data-table/data-table.tsx index 3e009302..371a1dab 100644 --- a/components/client-data-table/data-table.tsx +++ b/components/client-data-table/data-table.tsx @@ -49,8 +49,9 @@ interface DataTableProps { children?: React.ReactNode /** 선택 상태 초기화 트리거 */ clearSelection?: boolean - initialColumnPinning?: ColumnPinningState // 추가 - + initialColumnPinning?: ColumnPinningState + /** Table 인스턴스를 상위 컴포넌트에 전달하는 콜백 */ + onTableReady?: (table: Table) => void } export function ClientDataTable({ @@ -63,7 +64,8 @@ export function ClientDataTable({ maxHeight, onSelectedRowsChange, clearSelection, - initialColumnPinning + initialColumnPinning, + onTableReady }: DataTableProps) { // (1) React Table 상태 @@ -118,6 +120,13 @@ export function ClientDataTable({ useAutoSizeColumns(table, autoSizeColumns) + // 🆕 Table 인스턴스를 상위 컴포넌트에 전달 + React.useEffect(() => { + if (onTableReady) { + onTableReady(table) + } + }, [table, onTableReady]) + React.useEffect(() => { if (!onSelectedRowsChange) return const selectedRows = table @@ -164,6 +173,7 @@ export function ClientDataTable({ }), } } + // 🎯 테이블 총 너비 계산 const getTableWidth = React.useCallback(() => { const totalSize = table.getCenterTotalSize() + table.getLeftTotalSize() + table.getRightTotalSize() @@ -206,174 +216,172 @@ export function ClientDataTable({ {children} - -
- + thead]:sticky [&>thead]:top-0 [&>thead]:z-10", !hasNestedHeader && "table-fixed" // nested header가 없으면 table-fixed 적용 )} style={{ minWidth: hasNestedHeader ? getTableWidth() : undefined }}> - {/* nested header가 있으면 table-fixed 제거, 없으면 적용 */} - - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => { - // 만약 이 컬럼이 현재 "그룹핑" 상태라면 헤더도 표시하지 않음 - if (header.column.getIsGrouped()) { - return null - } + {/* nested header가 있으면 table-fixed 제거, 없으면 적용 */} + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + // 만약 이 컬럼이 현재 "그룹핑" 상태라면 헤더도 표시하지 않음 + if (header.column.getIsGrouped()) { + return null + } - return ( - -
- {header.isPlaceholder - ? null - : flexRender( - header.column.columnDef.header, - header.getContext() - )} - - {/* 부모 그룹 헤더는 리사이즈 불가, 자식 헤더만 리사이즈 가능 */} - {header.column.getCanResize() && !('columns' in header.column.columnDef) && ( - + return ( + +
+ {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext() )} -
-
- ) - })} - - ))} - - - {table.getRowModel().rows?.length ? ( - table.getRowModel().rows.map((row) => { - // --------------------------------------------------- - // 1) "그룹핑 헤더" Row인지 확인 - // --------------------------------------------------- - if (row.getIsGrouped()) { - // row.groupingColumnId로 어떤 컬럼을 기준으로 그룹화 되었는지 알 수 있음 - const groupingColumnId = row.groupingColumnId ?? "" - const groupingColumn = table.getColumn(groupingColumnId) // 해당 column 객체 + + {/* 부모 그룹 헤더는 리사이즈 불가, 자식 헤더만 리사이즈 가능 */} + {header.column.getCanResize() && !('columns' in header.column.columnDef) && ( + + )} +
+
+ ) + })} +
+ ))} +
+ + {table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => { + // --------------------------------------------------- + // 1) "그룹핑 헤더" Row인지 확인 + // --------------------------------------------------- + if (row.getIsGrouped()) { + // row.groupingColumnId로 어떤 컬럼을 기준으로 그룹화 되었는지 알 수 있음 + const groupingColumnId = row.groupingColumnId ?? "" + const groupingColumn = table.getColumn(groupingColumnId) // 해당 column 객체 - // 컬럼 라벨 가져오기 - let columnLabel = groupingColumnId - if (groupingColumn) { - const headerDef = groupingColumn.columnDef.meta?.excelHeader - if (typeof headerDef === "string") { - columnLabel = headerDef - } + // 컬럼 라벨 가져오기 + let columnLabel = groupingColumnId + if (groupingColumn) { + const headerDef = groupingColumn.columnDef.meta?.excelHeader + if (typeof headerDef === "string") { + columnLabel = headerDef } - - return ( - - {/* 그룹 헤더는 한 줄에 합쳐서 보여주고, 토글 버튼 + 그룹 라벨 + 값 표기 */} - - {/* 확장/축소 버튼 (아이콘 중앙 정렬 + Indent) */} - {row.getCanExpand() && ( - - )} - - {/* Group Label + 값 */} - - {columnLabel}: {row.getValue(groupingColumnId)} - - - ({row.subRows.length} rows) - - - - ) } - // --------------------------------------------------- - // 2) 일반 Row - // → "그룹핑된 컬럼"은 숨긴다 - // --------------------------------------------------- return ( - {row.getVisibleCells().map((cell) => { - // 이 셀의 컬럼이 grouped라면 숨긴다 - if (cell.column.getIsGrouped()) { - return null - } - - return ( - + {/* 확장/축소 버튼 (아이콘 중앙 정렬 + Indent) */} + {row.getCanExpand() && ( + + )} + + {/* Group Label + 값 */} + + {columnLabel}: {row.getValue(groupingColumnId)} + + + ({row.subRows.length} rows) + + ) - }) - ) : ( + } + // --------------------------------------------------- - // 3) 데이터가 없을 때 + // 2) 일반 Row + // → "그룹핑된 컬럼"은 숨긴다 // --------------------------------------------------- - - - No results. - - - )} - -
-
+ {row.getVisibleCells().map((cell) => { + // 이 셀의 컬럼이 grouped라면 숨긴다 + if (cell.column.getIsGrouped()) { + return null + } + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext() + )} + + ) + })} + + ) + }) + ) : ( + // --------------------------------------------------- + // 3) 데이터가 없을 때 + // --------------------------------------------------- + + + No results. + + + )} + + + -- cgit v1.2.3