summaryrefslogtreecommitdiff
path: root/components/data-table
diff options
context:
space:
mode:
Diffstat (limited to 'components/data-table')
-rw-r--r--components/data-table/data-table-detail.tsx28
-rw-r--r--components/data-table/data-table.tsx17
-rw-r--r--components/data-table/expandable-data-table.tsx15
-rw-r--r--components/data-table/infinite-data-table.tsx15
4 files changed, 62 insertions, 13 deletions
diff --git a/components/data-table/data-table-detail.tsx b/components/data-table/data-table-detail.tsx
index f3f09fe2..016b9f42 100644
--- a/components/data-table/data-table-detail.tsx
+++ b/components/data-table/data-table-detail.tsx
@@ -60,6 +60,19 @@ export function DataTableDetail<TData>({
useAutoSizeColumns(table, autoSizeColumns)
+ // nested header 감지: columns 속성을 가진 헤더가 있는지 확인
+ const hasNestedHeader = React.useMemo(() => {
+ return table.getHeaderGroups().some(headerGroup =>
+ headerGroup.headers.some(header => 'columns' in header.column.columnDef)
+ )
+ }, [table])
+
+ // 🎯 테이블 총 너비 계산 (nested header가 있을 때만 사용)
+ const getTableWidth = React.useCallback(() => {
+ const totalSize = table.getCenterTotalSize() + table.getLeftTotalSize() + table.getRightTotalSize()
+ return Math.max(totalSize, 800) // 최소 800px 보장
+ }, [table])
+
// ✅ compactStyles를 useMemo로 메모이제이션
const compactStyles = React.useMemo(() =>
compact ? COMPACT_STYLES : NORMAL_STYLES,
@@ -70,7 +83,12 @@ export function DataTableDetail<TData>({
<div className={cn("w-full space-y-2.5 overflow-auto", className)} {...props}>
{children}
<div className="max-w-[100vw] overflow-auto" style={{ maxHeight: maxHeight || '35rem' }} >
- <Table className="[&>thead]:sticky [&>thead]:top-0 [&>thead]:z-10 table-fixed">
+ <Table
+ className={cn(
+ "[&>thead]:sticky [&>thead]:top-0 [&>thead]:z-10",
+ !hasNestedHeader && "table-fixed"
+ )}
+ style={{ minWidth: hasNestedHeader ? getTableWidth() : undefined }}>
{/* 테이블 헤더 */}
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
@@ -93,7 +111,11 @@ export function DataTableDetail<TData>({
}),
// 부모 그룹 헤더는 colSpan으로 너비가 결정되므로 width 설정하지 않음
// 자식 헤더만 개별 width 설정
- ...(!('columns' in header.column.columnDef) && { width: header.getSize() }),
+ ...(!('columns' in header.column.columnDef) && {
+ width: header.getSize(),
+ minWidth: header.getSize(),
+ maxWidth: header.column.columnDef.maxSize,
+ }),
}}
>
<div style={{ position: "relative" }}>
@@ -190,6 +212,8 @@ export function DataTableDetail<TData>({
style={{
...getCommonPinningStylesWithBorder({ column: cell.column }),
width: cell.column.getSize(),
+ minWidth: cell.column.getSize(),
+ maxWidth: cell.column.columnDef.maxSize,
}}
>
{flexRender(
diff --git a/components/data-table/data-table.tsx b/components/data-table/data-table.tsx
index 44cbd47b..f6d3af73 100644
--- a/components/data-table/data-table.tsx
+++ b/components/data-table/data-table.tsx
@@ -78,6 +78,12 @@ export function DataTable<TData>({
return children;
}, [children]);
+ // 🎯 테이블 총 너비 계산 (nested header가 있을 때만 사용)
+ const getTableWidth = React.useCallback(() => {
+ const totalSize = table.getCenterTotalSize() + table.getLeftTotalSize() + table.getRightTotalSize()
+ return Math.max(totalSize, 800) // 최소 800px 보장
+ }, [table])
+
return (
<div className={cn("w-full space-y-2.5 overflow-auto", className)} {...props}>
{stableChildren}
@@ -86,8 +92,9 @@ export function DataTable<TData>({
className={cn(
"[&>thead]:sticky [&>thead]:top-0 [&>thead]:z-10",
!hasNestedHeader && "table-fixed" // nested header가 없으면 table-fixed 적용
- )}>
- {/* nested header가 있으면 table-fixed 제거, 없으면 적용 */}
+ )}
+ style={{ minWidth: hasNestedHeader ? getTableWidth() : undefined }}>
+ {/* nested header가 있으면 table-fixed 제거하고 minWidth로 너비 강제, 없으면 table-fixed 적용 */}
{/* 테이블 헤더 */}
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
@@ -116,7 +123,9 @@ export function DataTable<TData>({
// 부모 그룹 헤더는 colSpan으로 너비가 결정되므로 width 설정하지 않음
// 자식 헤더만 개별 width 설정
...(!('columns' in header.column.columnDef) && {
- width: header.getSize()
+ width: header.getSize(),
+ minWidth: header.getSize(),
+ maxWidth: header.column.columnDef.maxSize,
}),
}}
>
@@ -214,6 +223,8 @@ export function DataTable<TData>({
style={{
...getCommonPinningStylesWithBorder({ column: cell.column }),
width: cell.column.getSize(),
+ minWidth: cell.column.getSize(),
+ maxWidth: cell.column.columnDef.maxSize,
}}
>
{flexRender(
diff --git a/components/data-table/expandable-data-table.tsx b/components/data-table/expandable-data-table.tsx
index 165ebd34..bc0833a6 100644
--- a/components/data-table/expandable-data-table.tsx
+++ b/components/data-table/expandable-data-table.tsx
@@ -510,8 +510,9 @@ export function ExpandableDataTable<TData>({
className={cn(
"[&>thead]:sticky [&>thead]:top-0 [&>thead]:z-10",
!hasNestedHeader && "table-fixed" // nested header가 없으면 table-fixed 적용
- )}>
- {/* nested header가 있으면 table-fixed 제거, 없으면 적용 */}
+ )}
+ style={{ minWidth: hasNestedHeader ? getTableWidth() : undefined }}>
+ {/* nested header가 있으면 table-fixed 제거하고 minWidth로 너비 강제, 없으면 table-fixed 적용 */}
<TableHeader className="bg-background">
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id} className={compactStyles.headerRow}>
@@ -540,7 +541,11 @@ export function ExpandableDataTable<TData>({
...getPinnedStyle(header.column, true),
// 부모 그룹 헤더는 colSpan으로 너비가 결정되므로 width 설정하지 않음
// 자식 헤더만 개별 width 설정
- ...(!('columns' in header.column.columnDef) && { width: header.getSize() }),
+ ...(!('columns' in header.column.columnDef) && {
+ width: header.getSize(),
+ minWidth: header.getSize(),
+ maxWidth: header.column.columnDef.maxSize,
+ }),
}}
>
<div style={{ position: "relative" }}>
@@ -655,7 +660,9 @@ export function ExpandableDataTable<TData>({
)}
style={{
...getPinnedStyle(cell.column, false),
- width: cell.column.getSize()
+ width: cell.column.getSize(),
+ minWidth: cell.column.getSize(),
+ maxWidth: cell.column.columnDef.maxSize,
}}
// ✅ 클릭 이벤트 추가
onClick={isClickable ? (e) => handleCellClick(row.id, cell.column.id, e) : undefined}
diff --git a/components/data-table/infinite-data-table.tsx b/components/data-table/infinite-data-table.tsx
index 0242e052..a17a9b55 100644
--- a/components/data-table/infinite-data-table.tsx
+++ b/components/data-table/infinite-data-table.tsx
@@ -154,8 +154,9 @@ export function InfiniteDataTable<TData>({
className={cn(
"[&>thead]:sticky [&>thead]:top-0 [&>thead]:z-10",
!hasNestedHeader && "table-fixed" // nested header가 없으면 table-fixed 적용
- )}>
- {/* nested header가 있으면 table-fixed 제거, 없으면 적용 */}
+ )}
+ style={{ minWidth: hasNestedHeader ? getTableWidth() : undefined }}>
+ {/* nested header가 있으면 table-fixed 제거하고 minWidth로 너비 강제, 없으면 table-fixed 적용 */}
{/* 테이블 헤더 */}
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
@@ -175,7 +176,11 @@ export function InfiniteDataTable<TData>({
...getPinnedStyle(header.column, true), // 🎯 헤더임을 명시
// 부모 그룹 헤더는 colSpan으로 너비가 결정되므로 width 설정하지 않음
// 자식 헤더만 개별 width 설정
- ...(!('columns' in header.column.columnDef) && { width: header.getSize() }),
+ ...(!('columns' in header.column.columnDef) && {
+ width: header.getSize(),
+ minWidth: header.getSize(),
+ maxWidth: header.column.columnDef.maxSize,
+ }),
}}
>
<div style={{ position: "relative" }}>
@@ -272,7 +277,9 @@ export function InfiniteDataTable<TData>({
className={compactStyles.cell}
style={{
...getPinnedStyle(cell.column, false), // 🎯 바디 셀임을 명시
- width: cell.column.getSize(), // 🎯 width 별도 설정
+ width: cell.column.getSize(),
+ minWidth: cell.column.getSize(),
+ maxWidth: cell.column.columnDef.maxSize,
}}
>
{flexRender(