Skip to content

Commit 5be0c79

Browse files
committed
feat: enhance DataTable with row click navigation and keyboard accessibility
1 parent a4d81f4 commit 5be0c79

File tree

1 file changed

+55
-16
lines changed

1 file changed

+55
-16
lines changed

src/components/DataTable.tsx

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useNavigate, useParams } from '@tanstack/react-router';
12
import {
23
ColumnDef,
34
flexRender,
@@ -12,7 +13,6 @@ import {
1213
TableHeader,
1314
TableRow,
1415
} from '@/components/ui/table';
15-
import { ChainLink } from './ChainLink';
1616

1717
interface DataTableProps<TData, TValue> {
1818
columns: ColumnDef<TData, TValue>[];
@@ -27,12 +27,46 @@ export function DataTable<TData, TValue>({
2727
tableLength = 10,
2828
isLoading,
2929
}: DataTableProps<TData, TValue>) {
30+
const { chainSlug } = useParams({ from: '/$chainSlug' });
31+
const navigate = useNavigate();
32+
3033
const table = useReactTable({
3134
data,
3235
columns,
3336
getCoreRowModel: getCoreRowModel(),
3437
});
3538

39+
const handleRowClick = (
40+
destination: string,
41+
event: React.MouseEvent | React.KeyboardEvent
42+
) => {
43+
// Don't navigate if clicking on buttons, links, or other interactive elements
44+
const target = event.target as HTMLElement;
45+
if (
46+
target.tagName === 'BUTTON' ||
47+
target.tagName === 'A' ||
48+
target.closest('button, a')
49+
) {
50+
return;
51+
}
52+
53+
const path =
54+
destination === '/'
55+
? `/${chainSlug}`
56+
: `/${chainSlug}${destination.startsWith('/') ? destination : `/${destination}`}`;
57+
navigate({ to: path });
58+
};
59+
60+
const handleRowKeyDown = (
61+
destination: string,
62+
event: React.KeyboardEvent
63+
) => {
64+
if (event.key === 'Enter' || event.key === ' ') {
65+
event.preventDefault();
66+
handleRowClick(destination, event);
67+
}
68+
};
69+
3670
return (
3771
<Table>
3872
<TableHeader>
@@ -54,22 +88,27 @@ export function DataTable<TData, TValue>({
5488
))}
5589
</TableHeader>
5690
<TableBody>
57-
{table.getRowModel().rows.map((row) => (
58-
<TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>
59-
{row.getVisibleCells().map((cell) => (
60-
<TableCell key={cell.id}>
61-
<ChainLink
62-
to={
63-
(cell.row.original as { destination: string }).destination
64-
}
65-
className="w-full"
66-
>
91+
{table.getRowModel().rows.map((row) => {
92+
const destination = (row.original as { destination: string })
93+
.destination;
94+
95+
return (
96+
<TableRow
97+
key={row.id}
98+
data-state={row.getIsSelected() && 'selected'}
99+
className="cursor-pointer"
100+
tabIndex={0}
101+
onClick={(e) => handleRowClick(destination, e)}
102+
onKeyDown={(e) => handleRowKeyDown(destination, e)}
103+
>
104+
{row.getVisibleCells().map((cell) => (
105+
<TableCell key={cell.id}>
67106
{flexRender(cell.column.columnDef.cell, cell.getContext())}
68-
</ChainLink>
69-
</TableCell>
70-
))}
71-
</TableRow>
72-
))}
107+
</TableCell>
108+
))}
109+
</TableRow>
110+
);
111+
})}
73112
{data.length === 0 && !isLoading && (
74113
<TableRow>
75114
<TableCell colSpan={columns.length} className="text-center">

0 commit comments

Comments
 (0)