diff options
Diffstat (limited to 'components/data-table/data-table.tsx')
| -rw-r--r-- | components/data-table/data-table.tsx | 75 |
1 files changed, 37 insertions, 38 deletions
diff --git a/components/data-table/data-table.tsx b/components/data-table/data-table.tsx index b1027cc0..5aeefe21 100644 --- a/components/data-table/data-table.tsx +++ b/components/data-table/data-table.tsx @@ -22,15 +22,17 @@ interface DataTableProps<TData> extends React.HTMLAttributes<HTMLDivElement> { table: TanstackTable<TData> floatingBar?: React.ReactNode | null autoSizeColumns?: boolean + compact?: boolean // 컴팩트 모드 옵션 추가 } /** - * 멀티 그룹핑 + 그룹 토글 + 그룹 컬럼/헤더 숨김 + Indent + 리사이징 + * 멀티 그룹핑 + 그룹 토글 + 그룹 컬럼/헤더 숨김 + Indent + 리사이징 + 컴팩트 모드 */ export function DataTable<TData>({ table, floatingBar = null, autoSizeColumns = true, + compact = false, // 기본값은 false로 설정 children, className, ...props @@ -38,20 +40,29 @@ export function DataTable<TData>({ useAutoSizeColumns(table, autoSizeColumns) + // 컴팩트 모드를 위한 클래스 정의 + const compactStyles = compact ? { + row: "h-7", // 행 높이 축소 + cell: "py-1 px-2 text-sm", // 셀 패딩 축소 및 폰트 크기 조정 + groupRow: "py-1 bg-muted/20 text-sm", // 그룹 행 패딩 축소 + emptyRow: "h-16", // 데이터 없을 때 행 높이 조정 + } : { + row: "", + cell: "", + groupRow: "bg-muted/20", + emptyRow: "h-24", + } + return ( <div className={cn("w-full space-y-2.5 overflow-auto", className)} {...props}> {children} - <div className="max-w-[100vw] overflow-auto" style={{ maxHeight: '36.1rem' }}> + <div className="max-w-[100vw] overflow-auto" style={{ maxHeight: '35rem' }}> <Table className="[&>thead]:sticky [&>thead]:top-0 [&>thead]:z-10 table-fixed"> - {/* ------------------------------- - Table Header - → 그룹핑된 컬럼의 헤더는 숨김 처리 - ------------------------------- */} + {/* 테이블 헤더 */} <TableHeader> {table.getHeaderGroups().map((headerGroup) => ( - <TableRow key={headerGroup.id}> + <TableRow key={headerGroup.id} className={compact ? "h-8" : ""}> {headerGroup.headers.map((header) => { - // 만약 이 컬럼이 현재 "그룹핑" 상태라면 헤더도 표시하지 않음 if (header.column.getIsGrouped()) { return null } @@ -61,10 +72,10 @@ export function DataTable<TData>({ key={header.id} colSpan={header.colSpan} data-column-id={header.column.id} + className={compact ? "py-1 px-2 text-sm" : ""} style={{ ...getCommonPinningStyles({ column: header.column }), - width: header.getSize(), // 리사이징을 위한 너비 설정 - // position: "relative" // 리사이저를 위한 포지셔닝 + width: header.getSize(), }} > <div style={{ position: "relative" }}> @@ -75,7 +86,6 @@ export function DataTable<TData>({ header.getContext() )} - {/* 리사이즈 핸들 - 별도의 컴포넌트로 분리 */} {header.column.getCanResize() && ( <DataTableResizer header={header} /> )} @@ -87,21 +97,15 @@ export function DataTable<TData>({ ))} </TableHeader> - {/* ------------------------------- - Table Body - ------------------------------- */} + {/* 테이블 바디 */} <TableBody> {table.getRowModel().rows?.length ? ( table.getRowModel().rows.map((row) => { - // --------------------------------------------------- - // 1) "그룹핑 헤더" Row인지 확인 - // --------------------------------------------------- + // 그룹핑 헤더 Row if (row.getIsGrouped()) { - // row.groupingColumnId로 어떤 컬럼을 기준으로 그룹화 되었는지 알 수 있음 const groupingColumnId = row.groupingColumnId ?? "" - const groupingColumn = table.getColumn(groupingColumnId) // 해당 column 객체 + const groupingColumn = table.getColumn(groupingColumnId) - // 컬럼 라벨 가져오기 let columnLabel = groupingColumnId if (groupingColumn) { const headerDef = groupingColumn.columnDef.meta?.excelHeader @@ -113,30 +117,29 @@ export function DataTable<TData>({ return ( <TableRow key={row.id} - className="bg-muted/20" + className={compactStyles.groupRow} data-state={row.getIsExpanded() && "expanded"} > - {/* 그룹 헤더는 한 줄에 합쳐서 보여주고, 토글 버튼 + 그룹 라벨 + 값 표기 */} - <TableCell colSpan={table.getVisibleFlatColumns().length}> - {/* 확장/축소 버튼 (아이콘 중앙 정렬 + Indent) */} + <TableCell + colSpan={table.getVisibleFlatColumns().length} + className={compact ? "py-1 px-2" : ""} + > {row.getCanExpand() && ( <button onClick={row.getToggleExpandedHandler()} className="inline-flex items-center justify-center mr-2 w-5 h-5" style={{ - // row.depth: 0이면 top-level, 1이면 그 하위 등 marginLeft: `${row.depth * 1.5}rem`, }} > {row.getIsExpanded() ? ( - <ChevronUp size={16} /> + <ChevronUp size={compact ? 14 : 16} /> ) : ( - <ChevronRight size={16} /> + <ChevronRight size={compact ? 14 : 16} /> )} </button> )} - {/* Group Label + 값 */} <span className="font-semibold"> {columnLabel}: {row.getValue(groupingColumnId)} </span> @@ -148,17 +151,14 @@ export function DataTable<TData>({ ) } - // --------------------------------------------------- - // 2) 일반 Row - // → "그룹핑된 컬럼"은 숨긴다 - // --------------------------------------------------- + // 일반 Row return ( <TableRow key={row.id} + className={compactStyles.row} data-state={row.getIsSelected() && "selected"} > {row.getVisibleCells().map((cell) => { - // 이 셀의 컬럼이 grouped라면 숨긴다 if (cell.column.getIsGrouped()) { return null } @@ -167,9 +167,10 @@ export function DataTable<TData>({ <TableCell key={cell.id} data-column-id={cell.column.id} + className={compactStyles.cell} style={{ ...getCommonPinningStyles({ column: cell.column }), - width: cell.column.getSize(), // 리사이징을 위한 너비 설정 + width: cell.column.getSize(), }} > {flexRender( @@ -183,13 +184,11 @@ export function DataTable<TData>({ ) }) ) : ( - // --------------------------------------------------- - // 3) 데이터가 없을 때 - // --------------------------------------------------- + // 데이터가 없을 때 <TableRow> <TableCell colSpan={table.getAllColumns().length} - className="h-24 text-center" + className={compactStyles.emptyRow + " text-center"} > No results. </TableCell> |
