From 59b5715ebb3e1fd7bd4eb02ce50399715734f865 Mon Sep 17 00:00:00 2001 From: 0-Zz-ang Date: Mon, 4 Aug 2025 14:59:15 +0900 Subject: (박서영) docu-list-rule detail sheet 컴포넌트 추가 및 검색 필터 기능 오류 수정 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/data-table/data-table-detail.tsx | 226 ++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 components/data-table/data-table-detail.tsx (limited to 'components/data-table/data-table-detail.tsx') diff --git a/components/data-table/data-table-detail.tsx b/components/data-table/data-table-detail.tsx new file mode 100644 index 00000000..c34f9e73 --- /dev/null +++ b/components/data-table/data-table-detail.tsx @@ -0,0 +1,226 @@ +"use client" + +import * as React from "react" +import { flexRender, type Table as TanstackTable } from "@tanstack/react-table" +import { ChevronRight, ChevronUp } from "lucide-react" + +import { cn } from "@/lib/utils" +import { getCommonPinningStylesWithBorder } from "@/lib/data-table" +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table" +import { DataTablePagination } from "@/components/data-table/data-table-pagination" +import { DataTableResizer } from "@/components/data-table/data-table-resizer" +import { useAutoSizeColumns } from "@/hooks/useAutoSizeColumns" + +interface DataTableDetailProps extends React.HTMLAttributes { + table: TanstackTable + floatingBar?: React.ReactNode | null + autoSizeColumns?: boolean + compact?: boolean +} + +// ✅ compactStyles를 정적으로 정의 (매번 새로 생성 방지) +const COMPACT_STYLES = { + row: "h-7", // 행 높이 축소 + cell: "py-1 px-2 text-sm", // 셀 패딩 축소 및 폰트 크기 조정 + groupRow: "py-1 bg-muted/20 text-sm", // 그룹 행 패딩 축소 + emptyRow: "h-16", // 데이터 없을 때 행 높이 조정 + header: "py-1 px-2 text-sm", // 헤더 패딩 축소 + headerHeight: "h-8", // 헤더 높이 축소 +}; + +const NORMAL_STYLES = { + row: "", + cell: "", + groupRow: "bg-muted/20", + emptyRow: "h-24", + header: "", + headerHeight: "", +}; + +/** + * 디테일 시트 전용 DataTable - URL 상태와 연결되지 않는 독립적인 테이블 + */ +export function DataTableDetail({ + table, + floatingBar = null, + autoSizeColumns = true, + compact = false, + children, + className, + maxHeight, + ...props +}: DataTableDetailProps & { maxHeight?: string | number }) { + + useAutoSizeColumns(table, autoSizeColumns) + + // ✅ compactStyles를 useMemo로 메모이제이션 + const compactStyles = React.useMemo(() => + compact ? COMPACT_STYLES : NORMAL_STYLES, + [compact] + ); + + return ( +
+ {children} +
+ + {/* 테이블 헤더 */} + + {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() && ( + + )} +
+
+ ) + })} +
+ ))} +
+ + {/* 테이블 바디 */} + + {table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => { + // 그룹핑 헤더 Row + if (row.getIsGrouped()) { + const groupingColumnId = row.groupingColumnId ?? "" + const groupingColumn = table.getColumn(groupingColumnId) + + let columnLabel = groupingColumnId + if (groupingColumn) { + const headerDef = groupingColumn.columnDef.meta?.excelHeader + if (typeof headerDef === "string") { + columnLabel = headerDef + } + } + + return ( + + + {row.getCanExpand() && ( + + )} + + + {columnLabel}: {row.getValue(groupingColumnId)} + + + ({row.subRows.length} rows) + + + + ) + } + + // 일반 Row + return ( + + {row.getVisibleCells().map((cell) => { + if (cell.column.getIsGrouped()) { + return null + } + + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext() + )} + + ) + })} + + ) + }) + ) : ( + // 데이터가 없을 때 + + + No results. + + + )} + +
+
+ +
+ {/* Pagination */} + + + {/* Floating Bar (선택된 행 있을 때) */} + {table.getFilteredSelectedRowModel().rows.length > 0 && floatingBar} +
+
+ ) +} \ No newline at end of file -- cgit v1.2.3