Skip to content

Commit b59311b

Browse files
committed
refactor: migrate react-table to @tanstack/react-table
- replace react-table with @tanstack/react-table - remove @types/react-table - refactor shared Table to use useReactTable and flexRender - manage row expansion with ExpandedState - update table utility types to TanStack v8 - migrate enrolment and occurrence table columns from v7 to v8 Refs: PT-2015
1 parent 27f4921 commit b59311b

9 files changed

Lines changed: 215 additions & 440 deletions

File tree

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"@playwright/test": "^1.60.0",
2222
"@sentry/browser": "^10.25.0",
2323
"@stylistic/eslint-plugin": "^5.10.0",
24+
"@tanstack/react-table": "^8.20.0",
2425
"@types/apollo-upload-client": "^18.0.0",
2526
"@types/draft-js": "^0.11.20",
2627
"@types/draftjs-to-html": "^0.8.4",
@@ -33,7 +34,6 @@
3334
"@types/react-dom": "^19.2.3",
3435
"@types/react-draft-wysiwyg": "^1.13.9",
3536
"@types/react-helmet": "^6.1.11",
36-
"@types/react-table": "^7.7.20",
3737
"@typescript-eslint/eslint-plugin": "^8.57.2",
3838
"@typescript-eslint/parser": "^8.57.2",
3939
"@vitejs/plugin-react-swc": "^4.3.0",
@@ -78,7 +78,6 @@
7878
"react-i18next": "^15.5.1",
7979
"react-idle-timer": "^5.7.2",
8080
"react-router": "^7.15.0",
81-
"react-table": "^7.8.0",
8281
"react-toastify": "^11.0.5",
8382
"sass": "^1.87.0",
8483
"typescript": "^5.8.3",

pnpm-lock.yaml

Lines changed: 22 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/common/components/table/Table.tsx

Lines changed: 68 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
1+
import {
2+
ColumnDef,
3+
ExpandedState,
4+
flexRender,
5+
getCoreRowModel,
6+
getExpandedRowModel,
7+
useReactTable,
8+
} from '@tanstack/react-table';
19
import classNames from 'classnames';
2-
import React, { ReactElement } from 'react';
3-
import { Column, Row, useExpanded, useTable } from 'react-table';
10+
import React, { ReactElement, useState } from 'react';
411

512
import styles from './table.module.scss';
6-
import { ExtendedCell, ExtendedHeaderGroup, ExtendedRow } from './types';
13+
import { ExtendedColumnDef, ExtendedRow } from './types';
714

815
type Props<D extends Record<string, unknown>> = {
9-
columns: Array<Column<D>>;
16+
columns: Array<ColumnDef<D>>;
1017
data: Array<D>;
1118
expandedAreaOffset?: number;
12-
onRowClick?: (row: Row<D>) => void;
19+
onRowClick?: (row: ExtendedRow<D>) => void;
1320
renderExpandedArea?: (row: D) => React.ReactElement;
1421
tableHeaderRowClassName?: string;
1522
};
@@ -22,48 +29,47 @@ export default function Table<D extends Record<string, unknown>>({
2229
renderExpandedArea,
2330
tableHeaderRowClassName,
2431
}: Props<D>): ReactElement {
25-
const { getTableBodyProps, getTableProps, headerGroups, prepareRow, rows } =
26-
useTable(
27-
{
28-
columns,
29-
data,
30-
},
31-
useExpanded
32-
);
32+
const [expanded, setExpanded] = useState<ExpandedState>({});
33+
34+
const table = useReactTable({
35+
data,
36+
columns,
37+
state: {
38+
expanded,
39+
},
40+
onExpandedChange: setExpanded,
41+
getCoreRowModel: getCoreRowModel(),
42+
getExpandedRowModel: getExpandedRowModel(),
43+
});
44+
45+
const { getHeaderGroups, getRowModel } = table;
3346

3447
// Render the UI for your table
3548
return (
3649
<div className={styles.tableWrapper}>
37-
<table {...getTableProps({ className: styles.table })}>
50+
<table className={styles.table}>
3851
<thead>
39-
{headerGroups.map((headerGroup) => {
40-
const headerGroupProps = headerGroup.getHeaderGroupProps({
41-
className: tableHeaderRowClassName,
42-
});
43-
const { key, ...restHeaderGroupProps } = headerGroupProps;
44-
return (
45-
<tr {...restHeaderGroupProps} key={key}>
46-
{headerGroup.headers.map((column: ExtendedHeaderGroup<D>) => {
47-
const { style, className } = column;
48-
const { key, ...restHeaderProps } = column.getHeaderProps();
49-
return (
50-
<th
51-
{...restHeaderProps}
52-
{...{ style, className }}
53-
key={key}
54-
>
55-
{column.render('Header')}
56-
</th>
57-
);
58-
})}
59-
</tr>
60-
);
61-
})}
52+
{getHeaderGroups().map((headerGroup) => (
53+
<tr key={headerGroup.id} className={tableHeaderRowClassName}>
54+
{headerGroup.headers.map((header) => {
55+
const { className, style } =
56+
(header.column.columnDef as ExtendedColumnDef<D>) || {};
57+
return (
58+
<th key={header.id} style={style} className={className}>
59+
{header.isPlaceholder
60+
? null
61+
: flexRender(
62+
header.column.columnDef.header,
63+
header.getContext()
64+
)}
65+
</th>
66+
);
67+
})}
68+
</tr>
69+
))}
6270
</thead>
63-
<tbody {...getTableBodyProps()}>
64-
{rows.map((row: ExtendedRow<D>) => {
65-
prepareRow(row);
66-
71+
<tbody>
72+
{getRowModel().rows.map((row) => {
6773
const handleClick = (event: React.MouseEvent) => {
6874
const element = event.target as HTMLElement;
6975
if (
@@ -87,40 +93,42 @@ export default function Table<D extends Record<string, unknown>>({
8793
}
8894
};
8995

90-
const { key, ...restRowProps } = row.getRowProps();
91-
9296
return (
93-
<React.Fragment key={key}>
97+
<React.Fragment key={row.id}>
9498
<tr
95-
{...restRowProps}
9699
className={classNames({
97100
[styles.clickableRow]: onRowClick,
98-
[styles.expandedRow]: row.isExpanded,
101+
[styles.expandedRow]: row.getIsExpanded(),
99102
})}
100103
onClick={handleClick}
101104
onKeyDown={handleKeyDown}
102105
tabIndex={onRowClick ? 0 : -1}
103106
>
104-
{row.cells.map((cell: ExtendedCell<D>) => {
105-
const { className, style } = cell.column;
106-
const { key, ...restCellProps } = cell.getCellProps();
107+
{row.getVisibleCells().map((cell) => {
108+
const { className, style } =
109+
(cell.column.columnDef as ExtendedColumnDef<D>) || {};
107110
return (
108-
<td
109-
{...restCellProps}
110-
{...{ className, style }}
111-
key={key}
112-
>
113-
{cell.render('Cell')}
111+
<td key={cell.id} style={style} className={className}>
112+
{flexRender(
113+
cell.column.columnDef.cell,
114+
cell.getContext()
115+
)}
114116
</td>
115117
);
116118
})}
117119
</tr>
118-
{row.isExpanded && (
120+
{row.getIsExpanded() && (
119121
<tr className={styles.expandedArea}>
120-
{expandedAreaOffset > 0 && (
121-
<td colSpan={expandedAreaOffset}></td>
122-
)}
123-
<td colSpan={row.cells.length - expandedAreaOffset}>
122+
{expandedAreaOffset > 0 &&
123+
expandedAreaOffset < row.getVisibleCells().length && (
124+
<td colSpan={expandedAreaOffset}></td>
125+
)}
126+
<td
127+
colSpan={Math.max(
128+
1,
129+
row.getVisibleCells().length - expandedAreaOffset
130+
)}
131+
>
124132
{renderExpandedArea && renderExpandedArea(row.original)}
125133
</td>
126134
</tr>
Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,22 @@
1-
import {
2-
Cell,
3-
ColumnInstance,
4-
HeaderGroup,
5-
Row,
6-
UseExpandedRowProps,
7-
} from 'react-table';
1+
import { Cell, ColumnDef, Header, Row, Table } from '@tanstack/react-table';
82

93
type StyleProps = {
104
className?: string;
115
style?: React.CSSProperties;
126
};
137

14-
type ExtendedColumnInstance<D extends Record<string, unknown>> =
15-
ColumnInstance<D> & StyleProps;
8+
export type ExtendedColumnDef<D extends Record<string, unknown>> =
9+
ColumnDef<D> & StyleProps;
1610

17-
export type ExtendedCell<D extends Record<string, unknown>> = Cell<
11+
export type ExtendedCell<D extends Record<string, unknown>> = Cell<D, unknown> &
12+
StyleProps;
13+
14+
export type ExtendedHeader<D extends Record<string, unknown>> = Header<
1815
D,
1916
unknown
20-
> & {
21-
column: ExtendedColumnInstance<D>;
22-
};
17+
> &
18+
StyleProps;
2319

24-
export type ExtendedHeaderGroup<D extends Record<string, unknown>> =
25-
HeaderGroup<D> & StyleProps;
20+
export type ExtendedRow<D extends Record<string, unknown>> = Row<D>;
2621

27-
export type ExtendedRow<D extends Record<string, unknown>> = Row<D> & {
28-
isExpanded?: boolean;
29-
};
30-
31-
export type UseExpandedColumnCell<D extends Record<string, unknown>> = {
32-
value: D;
33-
row: UseExpandedRowProps<D>;
34-
};
22+
export type ExtendedTable<D extends Record<string, unknown>> = Table<D>;

0 commit comments

Comments
 (0)