summaryrefslogtreecommitdiff
path: root/components/data-table/data-table.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'components/data-table/data-table.tsx')
-rw-r--r--components/data-table/data-table.tsx75
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>