From 2ad58471ca80fd7d9f35694e01480ba1a0e63737 Mon Sep 17 00:00:00 2001 From: Bruno Henriques Date: Wed, 4 Dec 2024 00:11:49 +0000 Subject: [PATCH 1/2] docs(Table): example docs refactor --- .../stories/TableHooks/TableHooks.stories.tsx | 2 +- .../stories/TableHooks/UseHvPagination.tsx | 75 ++++++++++++++++--- 2 files changed, 64 insertions(+), 13 deletions(-) diff --git a/packages/core/src/Table/stories/TableHooks/TableHooks.stories.tsx b/packages/core/src/Table/stories/TableHooks/TableHooks.stories.tsx index 179e0768ee..ff9f5e6155 100644 --- a/packages/core/src/Table/stories/TableHooks/TableHooks.stories.tsx +++ b/packages/core/src/Table/stories/TableHooks/TableHooks.stories.tsx @@ -30,7 +30,7 @@ import { UseHvHeaderGroups } from "./UseHvHeaderGroups"; import UseHvHeaderGroupsRaw from "./UseHvHeaderGroups?raw"; import { UseHvHooks } from "./UseHvHooks"; import UseHvHooksRaw from "./UseHvHooks?raw"; -import { UseHvPagination } from "./UseHvPagination"; +import { Demo as UseHvPagination } from "./UseHvPagination"; import UseHvPaginationRaw from "./UseHvPagination?raw"; import { UseHvRowExpand } from "./UseHvRowExpand"; import UseHvRowExpandRaw from "./UseHvRowExpand?raw"; diff --git a/packages/core/src/Table/stories/TableHooks/UseHvPagination.tsx b/packages/core/src/Table/stories/TableHooks/UseHvPagination.tsx index 2f21d56eca..934c775e74 100644 --- a/packages/core/src/Table/stories/TableHooks/UseHvPagination.tsx +++ b/packages/core/src/Table/stories/TableHooks/UseHvPagination.tsx @@ -4,15 +4,21 @@ import { HvTable, HvTableBody, HvTableCell, + HvTableColumnConfig, HvTableContainer, HvTableHead, HvTableHeader, HvTableRow, - useHvData, useHvPagination, + useHvTable, } from "@hitachivantara/uikit-react-core"; -import { AssetEvent, getColumns, makeData } from "../storiesUtils"; +export function Demo() { + const columns = useMemo(() => getColumns(), []); + const data = useMemo(() => makeData(32), []); + + return ; +} const EmptyRow = () => ( @@ -20,19 +26,23 @@ const EmptyRow = () => ( ); -export const UseHvPagination = () => { - const columns = useMemo(() => getColumns(), []); - const data = useMemo(() => makeData(32), []); - +export function MyTable>({ + data, + columns, +}: { + data: T[]; + columns: HvTableColumnConfig[]; +}) { const { getTableProps, + getTableHeadProps, getTableBodyProps, prepareRow, headerGroups, page, state: { pageSize }, getHvPaginationProps, - } = useHvData({ columns, data }, useHvPagination); + } = useHvTable({ columns, data }, useHvPagination); const renderTableRow = (i: number) => { const row = page[i]; @@ -56,7 +66,7 @@ export const UseHvPagination = () => { <> - + {headerGroups.map((headerGroup) => ( { - {page?.length ? ( - - ) : undefined} + {page?.length > 0 && } ); -}; +} + +interface AssetEvent { + id: string; + name: string; + createdDate: string; + eventType: string; + riskScore: number; + status: string | null; + severity: string; + priority: string; + link?: string; + selected?: boolean; +} + +const getColumns = (): HvTableColumnConfig[] => [ + { Header: "Title", accessor: "name", style: { minWidth: 120 } }, + { Header: "Time", accessor: "createdDate", style: { minWidth: 100 } }, + { Header: "Event Type", accessor: "eventType", style: { minWidth: 100 } }, + { Header: "Status", accessor: "status", style: { minWidth: 100 } }, + { + Header: "Probability", + accessor: "riskScore", + align: "right", // numeric values should be right-aligned + Cell: ({ value }) => `${value}%`, + }, + { Header: "Severity", accessor: "severity" }, + { Header: "Priority", accessor: "priority" }, +]; + +const getOption = (opts: string[], i: number) => opts[i % opts.length]; + +const makeEvent = (i: number): AssetEvent => ({ + id: `${i + 1}`, + name: `Event ${i + 1}`, + createdDate: new Date("2020-03-20").toISOString().slice(0, 10), + eventType: "Anomaly detection", + status: getOption(["Closed", "Open"], i), + riskScore: (i % 100) + 1, + severity: getOption(["Critical", "Major", "Average", "Minor"], i), + priority: getOption(["High", "Medium", "Low"], i), +}); + +const makeData = (len = 10) => [...Array(len).keys()].map(makeEvent); From 4d2014d891551474b7fade990cdee55186a99f43 Mon Sep 17 00:00:00 2001 From: Bruno Henriques Date: Wed, 4 Dec 2024 09:34:35 +0000 Subject: [PATCH 2/2] docs(Table): migrate sample to react-table@8 --- package-lock.json | 36 ++++++ package.json | 1 + .../stories/TableHooks/UseHvPagination.tsx | 115 ++++++++++-------- 3 files changed, 104 insertions(+), 48 deletions(-) diff --git a/package-lock.json b/package-lock.json index 08570c1168..0849464bc9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,6 +42,7 @@ "@storybook/test": "^8.4.1", "@storybook/test-runner": "^0.19.1", "@storybook/types": "^8.4.1", + "@tanstack/react-table": "^8.20.5", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.4.2", "@testing-library/react": "^16.0.0", @@ -8308,6 +8309,27 @@ "@swc/counter": "^0.1.3" } }, + "node_modules/@tanstack/react-table": { + "version": "8.20.5", + "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.20.5.tgz", + "integrity": "sha512-WEHopKw3znbUZ61s9i0+i9g8drmDo6asTWbrQh8Us63DAk/M0FkmIqERew6P71HI75ksZ2Pxyuf4vvKh9rAkiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tanstack/table-core": "8.20.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/@tanstack/react-virtual": { "version": "3.10.8", "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.10.8.tgz", @@ -8325,6 +8347,20 @@ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/@tanstack/table-core": { + "version": "8.20.5", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.20.5.tgz", + "integrity": "sha512-P9dF7XbibHph2PFRz8gfBKEXEY/HJPOhym8CHmjF8y3q5mWpKx9xtZapXQUWCgkqvsK0R46Azuz+VaxD4Xl+Tg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@tanstack/virtual-core": { "version": "3.10.8", "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.10.8.tgz", diff --git a/package.json b/package.json index 77bb4b92c8..166232db4e 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "@storybook/test": "^8.4.1", "@storybook/test-runner": "^0.19.1", "@storybook/types": "^8.4.1", + "@tanstack/react-table": "^8.20.5", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.4.2", "@testing-library/react": "^16.0.0", diff --git a/packages/core/src/Table/stories/TableHooks/UseHvPagination.tsx b/packages/core/src/Table/stories/TableHooks/UseHvPagination.tsx index 934c775e74..5c8ded6bba 100644 --- a/packages/core/src/Table/stories/TableHooks/UseHvPagination.tsx +++ b/packages/core/src/Table/stories/TableHooks/UseHvPagination.tsx @@ -1,16 +1,25 @@ import { useMemo } from "react"; +import { + ColumnDef, + createColumnHelper, + flexRender, + getCoreRowModel, + getFilteredRowModel, + getPaginationRowModel, + getSortedRowModel, + Table, + useReactTable, +} from "@tanstack/react-table"; import { HvPagination, + HvPaginationProps, HvTable, HvTableBody, HvTableCell, - HvTableColumnConfig, HvTableContainer, HvTableHead, HvTableHeader, HvTableRow, - useHvPagination, - useHvTable, } from "@hitachivantara/uikit-react-core"; export function Demo() { @@ -22,7 +31,7 @@ export function Demo() { const EmptyRow = () => ( - + ); @@ -31,31 +40,27 @@ export function MyTable>({ columns, }: { data: T[]; - columns: HvTableColumnConfig[]; + columns: ColumnDef[]; }) { - const { - getTableProps, - getTableHeadProps, - getTableBodyProps, - prepareRow, - headerGroups, - page, - state: { pageSize }, - getHvPaginationProps, - } = useHvTable({ columns, data }, useHvPagination); + const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getSortedRowModel: getSortedRowModel(), + getFilteredRowModel: getFilteredRowModel(), + getPaginationRowModel: getPaginationRowModel(), + }); const renderTableRow = (i: number) => { - const row = page[i]; + const row = table.getRowModel().rows[i]; if (!row) return ; - prepareRow(row); - return ( - - {row.cells.map((cell) => ( - - {cell.render("Cell")} + + {row.getVisibleCells().map((cell) => ( + + {flexRender(cell.column.columnDef.cell, cell.getContext())} ))} @@ -65,30 +70,30 @@ export function MyTable>({ return ( <> - - - {headerGroups.map((headerGroup) => ( - + + + {...table.getHeaderGroups().map((headerGroup) => ( + {headerGroup.headers.map((col) => ( - {col.render("Header")} + {flexRender(col.column.columnDef.header, col.getContext())} ))} ))} - - {pageSize && [...Array(pageSize).keys()].map(renderTableRow)} + + {[...Array(table.getState().pagination.pageSize).keys()].map( + renderTableRow, + )} - {page?.length > 0 && } + ); } @@ -106,19 +111,20 @@ interface AssetEvent { selected?: boolean; } -const getColumns = (): HvTableColumnConfig[] => [ - { Header: "Title", accessor: "name", style: { minWidth: 120 } }, - { Header: "Time", accessor: "createdDate", style: { minWidth: 100 } }, - { Header: "Event Type", accessor: "eventType", style: { minWidth: 100 } }, - { Header: "Status", accessor: "status", style: { minWidth: 100 } }, - { - Header: "Probability", - accessor: "riskScore", - align: "right", // numeric values should be right-aligned - Cell: ({ value }) => `${value}%`, - }, - { Header: "Severity", accessor: "severity" }, - { Header: "Priority", accessor: "priority" }, +const columnHelper = createColumnHelper(); + +const getColumns = (): ColumnDef[] => [ + { header: "Title", accessorKey: "name", minSize: 120 }, + { header: "Time", accessorKey: "createdDate", minSize: 100 }, + { header: "Event Type", accessorKey: "eventType", minSize: 100 }, + { header: "Status", accessorKey: "status", minSize: 100 }, + columnHelper.accessor("riskScore", { + header: "Probability", + cell: ({ getValue }) => `${getValue()}%`, + }), + + { header: "Severity", accessorKey: "severity" }, + { header: "Priority", accessorKey: "priority" }, ]; const getOption = (opts: string[], i: number) => opts[i % opts.length]; @@ -135,3 +141,16 @@ const makeEvent = (i: number): AssetEvent => ({ }); const makeData = (len = 10) => [...Array(len).keys()].map(makeEvent); + +function getHvPaginationProps(table: Table): HvPaginationProps { + const { pageIndex, pageSize } = table.getState().pagination; + return { + canPrevious: table.getCanPreviousPage(), + canNext: table.getCanNextPage(), + pageSize: pageSize, + page: pageIndex, + pages: table.getPageCount(), + onPageChange: (newPage) => table.setPageIndex(newPage), + onPageSizeChange: (newPageSize) => table.setPageSize(newPageSize), + }; +}