diff --git a/libs/ui/src/organisms/datatable/datatable.tsx b/libs/ui/src/organisms/datatable/datatable.tsx index f0517bb..61dba12 100644 --- a/libs/ui/src/organisms/datatable/datatable.tsx +++ b/libs/ui/src/organisms/datatable/datatable.tsx @@ -1,84 +1,96 @@ import { ReactElement, ReactNode } from 'react'; +import { + useReactTable, + getCoreRowModel, + getPaginationRowModel, + getFilteredRowModel, +} from '@tanstack/react-table'; interface DataTableProps { data: T[]; headers: { - label: string; - key?: keyof T; - render?: (item: T, index: number) => ReactNode; - className?: string; + accessorKey?: keyof T; + header: string; + cell?: (info: any) => ReactNode; }[]; - showCheckbox?: boolean; onRowClick?: (item: T) => void; } export const DataTable = >({ data, headers, - showCheckbox = true, onRowClick, }: DataTableProps): ReactElement => { + const table = useReactTable({ + data, + columns: headers.map((header) => ({ + accessorKey: header.accessorKey, + header: header.header, + cell: header.cell, + })), + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), + getFilteredRowModel: getFilteredRowModel(), + }); return (
- - {showCheckbox && ( - - )} - {headers.map((header, index) => { - const isFirst = index === 0 && !showCheckbox; - const isLast = index === headers.length - 1; - return ( - + {headerGroup.headers.map((header) => ( + - ); - })} - + ))} + + ))} - {data.map((item, rowIndex) => ( + {table.getRowModel().rows.map((row) => ( onRowClick && onRowClick(item)} + key={row.id} + onClick={() => onRowClick && onRowClick(row.original)} > - {showCheckbox && ( - - )} - {headers.map((header, colIndex) => { - const isFirst = colIndex === 0 && !showCheckbox; - const isLast = colIndex === headers.length - 1; - - return ( - - ); - })} + {row.getVisibleCells().map((cell) => ( + + ))} ))}
- - - {header.label} + {table.getHeaderGroups().map((headerGroup) => ( +
+ {header.isPlaceholder ? null : ( +
+ {typeof header.column.columnDef.header === 'function' + ? header.column.columnDef.header(header.getContext()) + : header.column.columnDef.header} +
+ )}
- - - {header.render - ? header.render(item, rowIndex) - : header.key - ? item[header.key] - : null} - {cell.getValue() as ReactNode}
+
+ + + + +
); }; diff --git a/package-lock.json b/package-lock.json index 0379858..c4d353c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "@ant-design/icons": "^5.6.1", "@tanstack/react-query": "^5.67.3", + "@tanstack/react-table": "^8.21.2", "axios": "^1.8.3", "clsx": "^2.1.1", "react": "^19.0.0", @@ -8817,6 +8818,39 @@ "react": "^18 || ^19" } }, + "node_modules/@tanstack/react-table": { + "version": "8.21.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.21.2.tgz", + "integrity": "sha512-11tNlEDTdIhMJba2RBH+ecJ9l1zgS2kjmexDPAraulc8jeNA4xocSNeyzextT0XJyASil4XsCYlJmf5jEWAtYg==", + "license": "MIT", + "dependencies": { + "@tanstack/table-core": "8.21.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/@tanstack/table-core": { + "version": "8.21.2", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.21.2.tgz", + "integrity": "sha512-uvXk/U4cBiFMxt+p9/G7yUWI/UbHYbyghLCjlpWZ3mLeIZiUBSKcUnw9UnKkdRz7Z/N4UBuFLWQdJCjUe7HjvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@testing-library/dom": { "version": "10.4.0", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", diff --git a/package.json b/package.json index 4c65385..4a3cf8a 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "dependencies": { "@ant-design/icons": "^5.6.1", "@tanstack/react-query": "^5.67.3", + "@tanstack/react-table": "^8.21.2", "axios": "^1.8.3", "clsx": "^2.1.1", "react": "^19.0.0",