mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-26 00:05:45 +00:00
feat(FE-326): Support custom header rows and cell render hook
This commit is contained in:
@@ -14,6 +14,8 @@ import {
|
|||||||
SortingState,
|
SortingState,
|
||||||
OnChangeFn,
|
OnChangeFn,
|
||||||
Row,
|
Row,
|
||||||
|
HeaderGroup,
|
||||||
|
Column,
|
||||||
} from '@tanstack/react-table';
|
} from '@tanstack/react-table';
|
||||||
import { rankItem } from '@tanstack/match-sorter-utils';
|
import { rankItem } from '@tanstack/match-sorter-utils';
|
||||||
import { Icon } from '@iconify/react';
|
import { Icon } from '@iconify/react';
|
||||||
@@ -32,6 +34,20 @@ interface TableClassNames {
|
|||||||
bodyRowClassName?: string;
|
bodyRowClassName?: string;
|
||||||
bodyColumnClassName?: string;
|
bodyColumnClassName?: string;
|
||||||
paginationClassName?: string;
|
paginationClassName?: string;
|
||||||
|
customHeaderRowClassName?: string;
|
||||||
|
customHeaderCellClassName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CustomHeaderRow {
|
||||||
|
id: string;
|
||||||
|
cells: Array<{
|
||||||
|
id: string;
|
||||||
|
content: ReactNode;
|
||||||
|
colSpan?: number;
|
||||||
|
rowSpan?: number;
|
||||||
|
className?: string;
|
||||||
|
}>;
|
||||||
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TableProps<TData extends object> {
|
export interface TableProps<TData extends object> {
|
||||||
@@ -52,6 +68,13 @@ export interface TableProps<TData extends object> {
|
|||||||
rowSelection?: Record<string, boolean>;
|
rowSelection?: Record<string, boolean>;
|
||||||
setRowSelection?: OnChangeFn<Record<string, boolean>>;
|
setRowSelection?: OnChangeFn<Record<string, boolean>>;
|
||||||
enableRowSelection?: boolean | ((row: Row<TData>) => 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DUMMY_SKELETON_DATA = [{}, {}, {}, {}, {}];
|
const DUMMY_SKELETON_DATA = [{}, {}, {}, {}, {}];
|
||||||
@@ -85,6 +108,8 @@ const Table = <TData extends object>({
|
|||||||
bodyRowClassName: '',
|
bodyRowClassName: '',
|
||||||
bodyColumnClassName: '',
|
bodyColumnClassName: '',
|
||||||
paginationClassName: '',
|
paginationClassName: '',
|
||||||
|
customHeaderRowClassName: '',
|
||||||
|
customHeaderCellClassName: '',
|
||||||
},
|
},
|
||||||
emptyContent = emptyContentDefaultValue,
|
emptyContent = emptyContentDefaultValue,
|
||||||
sorting,
|
sorting,
|
||||||
@@ -93,6 +118,9 @@ const Table = <TData extends object>({
|
|||||||
rowSelection,
|
rowSelection,
|
||||||
setRowSelection,
|
setRowSelection,
|
||||||
enableRowSelection,
|
enableRowSelection,
|
||||||
|
customHeaderRows = [],
|
||||||
|
renderCustomHeaders = false,
|
||||||
|
onCustomHeaderCellRender,
|
||||||
}: TableProps<TData>) => {
|
}: TableProps<TData>) => {
|
||||||
const isServerSideTable =
|
const isServerSideTable =
|
||||||
totalItems !== undefined &&
|
totalItems !== undefined &&
|
||||||
@@ -195,12 +223,51 @@ const Table = <TData extends object>({
|
|||||||
<div className={className.tableWrapperClassName}>
|
<div className={className.tableWrapperClassName}>
|
||||||
<table className={className.tableClassName}>
|
<table className={className.tableClassName}>
|
||||||
<thead className={className.tableHeaderClassName}>
|
<thead className={className.tableHeaderClassName}>
|
||||||
|
{renderCustomHeaders &&
|
||||||
|
customHeaderRows.length > 0 &&
|
||||||
|
customHeaderRows.map((headerRow) => (
|
||||||
|
<tr
|
||||||
|
key={headerRow.id}
|
||||||
|
className={
|
||||||
|
headerRow.className || className.customHeaderRowClassName
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{headerRow.cells.map((cell) => (
|
||||||
|
<th
|
||||||
|
key={cell.id}
|
||||||
|
colSpan={cell.colSpan}
|
||||||
|
rowSpan={cell.rowSpan}
|
||||||
|
className={
|
||||||
|
cell.className || className.customHeaderCellClassName
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{cell.content}
|
||||||
|
</th>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
|
||||||
{table.getHeaderGroups().map((headerGroup) => (
|
{table.getHeaderGroups().map((headerGroup) => (
|
||||||
<tr key={headerGroup.id} className={className.headerRowClassName}>
|
<tr key={headerGroup.id} className={className.headerRowClassName}>
|
||||||
{headerGroup.headers.map((header) => (
|
{headerGroup.headers.map((header) => {
|
||||||
|
let cellContent = flexRender(
|
||||||
|
header.column.columnDef.header,
|
||||||
|
header.getContext()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (onCustomHeaderCellRender) {
|
||||||
|
cellContent = onCustomHeaderCellRender(
|
||||||
|
cellContent,
|
||||||
|
header.column,
|
||||||
|
headerGroup
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
<th
|
<th
|
||||||
key={header.id}
|
key={header.id}
|
||||||
colSpan={header.colSpan}
|
colSpan={header.colSpan}
|
||||||
|
rowSpan={header.rowSpan}
|
||||||
onClick={header.column.getToggleSortingHandler()}
|
onClick={header.column.getToggleSortingHandler()}
|
||||||
className={cn(
|
className={cn(
|
||||||
header.column.getCanSort()
|
header.column.getCanSort()
|
||||||
@@ -210,10 +277,7 @@ const Table = <TData extends object>({
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className='flex items-center gap-1'>
|
<div className='flex items-center gap-1'>
|
||||||
{flexRender(
|
{cellContent}
|
||||||
header.column.columnDef.header,
|
|
||||||
header.getContext()
|
|
||||||
)}
|
|
||||||
|
|
||||||
{header.column.getCanSort() && (
|
{header.column.getCanSort() && (
|
||||||
<div className='flex items-center'>
|
<div className='flex items-center'>
|
||||||
@@ -243,7 +307,8 @@ const Table = <TData extends object>({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
))}
|
);
|
||||||
|
})}
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</thead>
|
</thead>
|
||||||
|
|||||||
Reference in New Issue
Block a user