From fe6bb18ab72e6add4685aea938a30f99efeb57af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Gu=CC=88ell=20Segarra?= Date: Tue, 5 Sep 2023 14:53:30 +0200 Subject: [PATCH] Allow to pass selection row keys in Table component --- package-lock.json | 49 ++++++++++++++++++++++++++++++++------ package.json | 3 ++- src/Table.tsx | 8 +++++-- src/hooks/useSelectable.ts | 29 +++++++++++++++------- src/types/index.tsx | 1 + vite.config.ts | 2 +- 6 files changed, 73 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index a420054..3b8119d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,8 @@ "dependencies": { "react": "^16.8.0 || 17.x", "react-dom": "^16.8.0 || 17.x", - "styled-components": "^5.0.0" + "styled-components": "^5.0.0", + "use-deep-compare-effect": "^1.8.1" }, "devDependencies": { "@babel/core": "^7.17.8", @@ -1987,7 +1988,6 @@ "version": "7.22.6", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", - "dev": true, "dependencies": { "regenerator-runtime": "^0.13.11" }, @@ -13353,6 +13353,14 @@ "node": ">= 0.8" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, "node_modules/des.js": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", @@ -24015,8 +24023,7 @@ "node_modules/regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "node_modules/regenerator-transform": { "version": "0.15.0", @@ -27470,6 +27477,22 @@ "node": ">=0.10.0" } }, + "node_modules/use-deep-compare-effect": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/use-deep-compare-effect/-/use-deep-compare-effect-1.8.1.tgz", + "integrity": "sha512-kbeNVZ9Zkc0RFGpfMN3MNfaKNvcLNyxOAAd9O4CBZ+kCBXXscn9s/4I+8ytUER4RDpEYs5+O6Rs4PqiZ+rHr5Q==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "dequal": "^2.0.2" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + }, + "peerDependencies": { + "react": ">=16.13" + } + }, "node_modules/util": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", @@ -30568,7 +30591,6 @@ "version": "7.22.6", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", - "dev": true, "requires": { "regenerator-runtime": "^0.13.11" } @@ -39315,6 +39337,11 @@ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true }, + "dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==" + }, "des.js": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", @@ -47497,8 +47524,7 @@ "regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "regenerator-transform": { "version": "0.15.0", @@ -50212,6 +50238,15 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, + "use-deep-compare-effect": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/use-deep-compare-effect/-/use-deep-compare-effect-1.8.1.tgz", + "integrity": "sha512-kbeNVZ9Zkc0RFGpfMN3MNfaKNvcLNyxOAAd9O4CBZ+kCBXXscn9s/4I+8ytUER4RDpEYs5+O6Rs4PqiZ+rHr5Q==", + "requires": { + "@babel/runtime": "^7.12.5", + "dequal": "^2.0.2" + } + }, "util": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", diff --git a/package.json b/package.json index 2b118a1..ef9d9f5 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "dependencies": { "react": "^16.8.0 || 17.x", "react-dom": "^16.8.0 || 17.x", - "styled-components": "^5.0.0" + "styled-components": "^5.0.0", + "use-deep-compare-effect": "^1.8.1" }, "devDependencies": { "@babel/core": "^7.17.8", diff --git a/src/Table.tsx b/src/Table.tsx index 55e7a98..a663ad4 100644 --- a/src/Table.tsx +++ b/src/Table.tsx @@ -23,7 +23,8 @@ export const Table = (props: TableProps) => { sorter, expandableOpts, onCellRender, - readonly + readonly, + selectionRowKeys: selectionRowKeysProps, } = props; if (loading) { @@ -35,7 +36,10 @@ export const Table = (props: TableProps) => { toggleAllRowsSelected, isRowSelected, changeSelected, - } = useSelectable(); + } = useSelectable({ + selectionRowKeysProps + }); + const onChange = useShiftSelected(dataSource.map(el => el.id), changeSelected); const { localSorter, getColumnSorter, handleColumnClick } = useSortable(sorter); diff --git a/src/hooks/useSelectable.ts b/src/hooks/useSelectable.ts index b559219..ea28a71 100644 --- a/src/hooks/useSelectable.ts +++ b/src/hooks/useSelectable.ts @@ -1,7 +1,18 @@ -import { useState, useCallback } from "react"; +import { useState, useCallback, useEffect } from "react"; +import useDeepCompareEffect from "use-deep-compare-effect"; -export const useSelectable = () => { - const [selectedRowKeys, setSelectedRowKeys] = useState([]); +export const useSelectable = ({ + selectionRowKeysProps = [], +}: { + selectionRowKeysProps?: number[]; +}) => { + const [selectedRowKeys, setSelectedRowKeys] = useState( + selectionRowKeysProps + ); + + useDeepCompareEffect(() => { + setSelectedRowKeys(selectionRowKeysProps); + }, [selectionRowKeysProps]); const toggleAllRowsSelected = useCallback( (allVisibleKeys: number[]) => { @@ -24,11 +35,14 @@ export const useSelectable = () => { return; } if (check) { - setSelectedRowKeys([...new Set([...selectedRowKeys, ...items])]) + setSelectedRowKeys([...new Set([...selectedRowKeys, ...items])]); } else { - setSelectedRowKeys(selectedRowKeys.filter((id: number) => !items.includes(id))) + setSelectedRowKeys( + selectedRowKeys.filter((id: number) => !items.includes(id)) + ); } - }, [selectedRowKeys, setSelectedRowKeys] + }, + [selectedRowKeys, setSelectedRowKeys] ); const toggleRowSelected = useCallback( @@ -49,7 +63,6 @@ export const useSelectable = () => { const isRowSelected = useCallback( (row: any) => { - const selectedFoundRow = selectedRowKeys.find( (id: number) => row.id === id ); @@ -66,4 +79,4 @@ export const useSelectable = () => { toggleRowSelected, changeSelected, }; -}; +}; \ No newline at end of file diff --git a/src/types/index.tsx b/src/types/index.tsx index 334d2c1..e6c8171 100644 --- a/src/types/index.tsx +++ b/src/types/index.tsx @@ -44,4 +44,5 @@ export type TableProps = { height?: number; onCellRender?: (opts: OnCellRenderOpts) => React.ReactNode; readonly?: boolean; + selectionRowKeys?: number[]; }; diff --git a/vite.config.ts b/vite.config.ts index d12c27a..039b871 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -19,7 +19,7 @@ export default defineConfig({ fileName: (format) => `react-formiga-table.${format}.js`, }, rollupOptions: { - external: ["react", "react-dom", "styled-components"], + external: ["react", "react-dom", "styled-components", "use-deep-compare-effect"], output: { globals: { react: "React",