refactor(FE-326): Remove custom header rows and simplify Table

This commit is contained in:
rstubryan
2025-12-06 09:47:38 +07:00
parent aad24c3c58
commit c9552dec2d
2 changed files with 53 additions and 293 deletions
+45 -163
View File
@@ -14,8 +14,6 @@ import {
SortingState,
OnChangeFn,
Row,
HeaderGroup,
Column,
} from '@tanstack/react-table';
import { rankItem } from '@tanstack/match-sorter-utils';
import { Icon } from '@iconify/react';
@@ -34,21 +32,6 @@ interface TableClassNames {
bodyRowClassName?: string;
bodyColumnClassName?: string;
paginationClassName?: string;
customHeaderRowClassName?: string;
customHeaderCellClassName?: string;
}
export interface CustomHeaderRow {
id: string;
cells: Array<{
id: string;
content: ReactNode;
colSpan?: number;
rowSpan?: number;
className?: string;
field?: string;
}>;
className?: string;
}
export interface TableProps<TData extends object> {
@@ -69,13 +52,6 @@ export interface TableProps<TData extends object> {
rowSelection?: Record<string, boolean>;
setRowSelection?: OnChangeFn<Record<string, boolean>>;
enableRowSelection?: boolean | ((row: Row<TData>) => boolean);
customHeaderRows?: CustomHeaderRow[];
renderCustomHeaders?: boolean;
onCustomHeaderCellRender?: <TData extends object>(
cell: ReactNode,
column: Column<TData, unknown>,
headerGroup: HeaderGroup<TData>
) => ReactNode;
renderFooter?: boolean;
footerContent?: ReactNode;
}
@@ -111,8 +87,6 @@ const Table = <TData extends object>({
bodyRowClassName: '',
bodyColumnClassName: '',
paginationClassName: '',
customHeaderRowClassName: '',
customHeaderCellClassName: '',
},
emptyContent = emptyContentDefaultValue,
sorting,
@@ -121,9 +95,6 @@ const Table = <TData extends object>({
rowSelection,
setRowSelection,
enableRowSelection,
customHeaderRows = [],
renderCustomHeaders = false,
onCustomHeaderCellRender,
renderFooter = false,
footerContent,
}: TableProps<TData>) => {
@@ -228,143 +199,55 @@ const Table = <TData extends object>({
<div className={className.tableWrapperClassName}>
<table className={className.tableClassName}>
<thead className={className.tableHeaderClassName}>
{renderCustomHeaders &&
customHeaderRows.length > 0 &&
customHeaderRows.map((headerRow) => (
<tr
key={headerRow.id}
className={
headerRow.className || className.customHeaderRowClassName
}
>
{headerRow.cells.map((cell) => {
const column = table
.getAllColumns()
.find((col) => col.id === cell.field);
const canSort = column?.getCanSort();
const sortingState = column?.getIsSorted();
return (
<th
key={cell.id}
colSpan={cell.colSpan}
rowSpan={cell.rowSpan}
onClick={
canSort
? column?.getToggleSortingHandler()
: undefined
}
className={cn(
cell.className || className.customHeaderCellClassName,
canSort ? 'cursor-pointer select-none' : ''
)}
>
<div
className={cn(
'flex items-center gap-1',
cell.className?.includes('text-center')
? 'justify-center'
: ''
)}
>
{cell.content}
{canSort && (
<div className='flex items-center'>
<Icon
icon='lucide:arrow-up'
width={12}
height={12}
className={cn(
'transition-all ease-in-out duration-200',
sortingState === 'asc'
? 'text-black'
: 'text-black/30'
)}
/>
<Icon
icon='lucide:arrow-down'
width={12}
height={12}
className={cn(
'transition-all ease-in-out duration-200',
sortingState === 'desc'
? 'text-black'
: 'text-black/30'
)}
/>
</div>
)}
</div>
</th>
);
})}
</tr>
))}
{table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id} className={className.headerRowClassName}>
{headerGroup.headers.map((header) => {
let cellContent = flexRender(
header.column.columnDef.header,
header.getContext()
);
if (onCustomHeaderCellRender) {
cellContent = onCustomHeaderCellRender(
cellContent,
header.column,
headerGroup
);
}
return (
<th
key={header.id}
colSpan={header.colSpan}
rowSpan={header.rowSpan}
onClick={header.column.getToggleSortingHandler()}
className={cn(
header.column.getCanSort()
? 'cursor-pointer select-none'
: '',
className.headerColumnClassName
{headerGroup.headers.map((header) => (
<th
key={header.id}
colSpan={header.colSpan}
onClick={header.column.getToggleSortingHandler()}
className={cn(
header.column.getCanSort()
? 'cursor-pointer select-none'
: '',
className.headerColumnClassName
)}
>
<div className='flex items-center gap-1'>
{flexRender(
header.column.columnDef.header,
header.getContext()
)}
>
<div className='flex items-center gap-1'>
{cellContent}
{header.column.getCanSort() && (
<div className='flex items-center'>
<Icon
icon='lucide:arrow-up'
width={12}
height={12}
className={cn(
'transition-all ease-in-out duration-200',
header.column.getIsSorted() === 'asc'
? 'text-black'
: 'text-black/30'
)}
/>
<Icon
icon='lucide:arrow-down'
width={12}
height={12}
className={cn(
'transition-all ease-in-out duration-200',
header.column.getIsSorted() === 'desc'
? 'text-black'
: 'text-black/30'
)}
/>
</div>
)}
</div>
</th>
);
})}
{header.column.getCanSort() && (
<div className='flex items-center'>
<Icon
icon='lucide:arrow-up'
width={12}
height={12}
className={cn(
'transition-all ease-in-out duration-200',
header.column.getIsSorted() === 'asc'
? 'text-black'
: 'text-black/30'
)}
/>
<Icon
icon='lucide:arrow-down'
width={12}
height={12}
className={cn(
'transition-all ease-in-out duration-200',
header.column.getIsSorted() === 'desc'
? 'text-black'
: 'text-black/30'
)}
/>
</div>
)}
</div>
</th>
))}
</tr>
))}
</thead>
@@ -383,7 +266,6 @@ const Table = <TData extends object>({
</tr>
))}
</tbody>
{renderFooter && footerContent}
</table>
</div>