From 1d0a4c720d0810080bdfcca73e72e050b7a8f0c0 Mon Sep 17 00:00:00 2001 From: Felipe Cadavid Date: Thu, 2 Jan 2025 12:40:28 -0500 Subject: [PATCH 1/3] feat: add virtualization for datagrid --- .pnp.cjs | 95 +++++++++++++ packages/ui-kit/package.json | 1 + .../components/DataGrid/DataGrid.module.scss | 2 - .../components/DataGrid/DataGrid.stories.tsx | 14 ++ .../src/components/DataGrid/DataGrid.tsx | 133 +++++++++++------- yarn.lock | 20 +++ 6 files changed, 214 insertions(+), 51 deletions(-) diff --git a/.pnp.cjs b/.pnp.cjs index a81f044d..9aa34740 100644 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -11094,6 +11094,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@swc/jest", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:0.2.29::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40swc%2Fjest%2F-%2Fjest-0.2.29.tgz"],\ ["@tanstack/react-query", "virtual:6dd0ee4544359587d64ff328fe311b923a3c1ee8914df11782918738abbc6520285dc1ca059877f86375600584583e7d6592895c5c96572203f7b48dc4661862#npm:4.36.1::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-query%2F-%2Freact-query-4.36.1.tgz"],\ ["@tanstack/react-table", "virtual:6dd0ee4544359587d64ff328fe311b923a3c1ee8914df11782918738abbc6520285dc1ca059877f86375600584583e7d6592895c5c96572203f7b48dc4661862#npm:8.15.3::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-table%2F-%2Freact-table-8.15.3.tgz"],\ + ["@tanstack/react-virtual", "virtual:6dd0ee4544359587d64ff328fe311b923a3c1ee8914df11782918738abbc6520285dc1ca059877f86375600584583e7d6592895c5c96572203f7b48dc4661862#npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-virtual%2F-%2Freact-virtual-3.11.2.tgz"],\ ["@testing-library/jest-dom", "npm:5.17.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40testing-library%2Fjest-dom%2F-%2Fjest-dom-5.17.0.tgz"],\ ["@testing-library/react", "virtual:6dd0ee4544359587d64ff328fe311b923a3c1ee8914df11782918738abbc6520285dc1ca059877f86375600584583e7d6592895c5c96572203f7b48dc4661862#npm:14.1.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40testing-library%2Freact%2F-%2Freact-14.1.2.tgz"],\ ["@testing-library/user-event", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:14.5.1::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40testing-library%2Fuser-event%2F-%2Fuser-event-14.5.1.tgz"],\ @@ -11171,6 +11172,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@swc/jest", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:0.2.29::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40swc%2Fjest%2F-%2Fjest-0.2.29.tgz"],\ ["@tanstack/react-query", "virtual:a84eb495e555084f80c201f07630d1efc544260e49e6a723e5d25c3ed5c3b4ea77b8628678069a7b15d87cb9e6086898e971564f07f3bf23d436e7ee19347a66#npm:4.36.1::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-query%2F-%2Freact-query-4.36.1.tgz"],\ ["@tanstack/react-table", "virtual:a84eb495e555084f80c201f07630d1efc544260e49e6a723e5d25c3ed5c3b4ea77b8628678069a7b15d87cb9e6086898e971564f07f3bf23d436e7ee19347a66#npm:8.15.3::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-table%2F-%2Freact-table-8.15.3.tgz"],\ + ["@tanstack/react-virtual", "virtual:a84eb495e555084f80c201f07630d1efc544260e49e6a723e5d25c3ed5c3b4ea77b8628678069a7b15d87cb9e6086898e971564f07f3bf23d436e7ee19347a66#npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-virtual%2F-%2Freact-virtual-3.11.2.tgz"],\ ["@testing-library/jest-dom", "npm:5.17.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40testing-library%2Fjest-dom%2F-%2Fjest-dom-5.17.0.tgz"],\ ["@testing-library/react", "virtual:a84eb495e555084f80c201f07630d1efc544260e49e6a723e5d25c3ed5c3b4ea77b8628678069a7b15d87cb9e6086898e971564f07f3bf23d436e7ee19347a66#npm:14.1.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40testing-library%2Freact%2F-%2Freact-14.1.2.tgz"],\ ["@testing-library/user-event", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:14.5.1::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40testing-library%2Fuser-event%2F-%2Fuser-event-14.5.1.tgz"],\ @@ -11248,6 +11250,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@swc/jest", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:0.2.29::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40swc%2Fjest%2F-%2Fjest-0.2.29.tgz"],\ ["@tanstack/react-query", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:4.36.1::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-query%2F-%2Freact-query-4.36.1.tgz"],\ ["@tanstack/react-table", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:8.15.3::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-table%2F-%2Freact-table-8.15.3.tgz"],\ + ["@tanstack/react-virtual", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-virtual%2F-%2Freact-virtual-3.11.2.tgz"],\ ["@testing-library/jest-dom", "npm:5.17.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40testing-library%2Fjest-dom%2F-%2Fjest-dom-5.17.0.tgz"],\ ["@testing-library/react", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:14.1.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40testing-library%2Freact%2F-%2Freact-14.1.2.tgz"],\ ["@testing-library/user-event", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:14.5.1::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40testing-library%2Fuser-event%2F-%2Fuser-event-14.5.1.tgz"],\ @@ -11323,6 +11326,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@swc/jest", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:0.2.29::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40swc%2Fjest%2F-%2Fjest-0.2.29.tgz"],\ ["@tanstack/react-query", "virtual:40f8e5d9470dadd0060c7b0d5ccbc7394cb2631c4c32ded046c14477c91f332b2a7e811fb9423edb388a602730fec4c2d722550b1609515756ea1cf3021c1e93#npm:4.36.1::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-query%2F-%2Freact-query-4.36.1.tgz"],\ ["@tanstack/react-table", "virtual:40f8e5d9470dadd0060c7b0d5ccbc7394cb2631c4c32ded046c14477c91f332b2a7e811fb9423edb388a602730fec4c2d722550b1609515756ea1cf3021c1e93#npm:8.15.3::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-table%2F-%2Freact-table-8.15.3.tgz"],\ + ["@tanstack/react-virtual", "virtual:40f8e5d9470dadd0060c7b0d5ccbc7394cb2631c4c32ded046c14477c91f332b2a7e811fb9423edb388a602730fec4c2d722550b1609515756ea1cf3021c1e93#npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-virtual%2F-%2Freact-virtual-3.11.2.tgz"],\ ["@testing-library/jest-dom", "npm:5.17.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40testing-library%2Fjest-dom%2F-%2Fjest-dom-5.17.0.tgz"],\ ["@testing-library/react", "virtual:40f8e5d9470dadd0060c7b0d5ccbc7394cb2631c4c32ded046c14477c91f332b2a7e811fb9423edb388a602730fec4c2d722550b1609515756ea1cf3021c1e93#npm:14.1.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40testing-library%2Freact%2F-%2Freact-14.1.2.tgz"],\ ["@testing-library/user-event", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:14.5.1::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40testing-library%2Fuser-event%2F-%2Fuser-event-14.5.1.tgz"],\ @@ -11398,6 +11402,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@swc/jest", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:0.2.29::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40swc%2Fjest%2F-%2Fjest-0.2.29.tgz"],\ ["@tanstack/react-query", "virtual:a84eb495e555084f80c201f07630d1efc544260e49e6a723e5d25c3ed5c3b4ea77b8628678069a7b15d87cb9e6086898e971564f07f3bf23d436e7ee19347a66#npm:4.36.1::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-query%2F-%2Freact-query-4.36.1.tgz"],\ ["@tanstack/react-table", "virtual:a84eb495e555084f80c201f07630d1efc544260e49e6a723e5d25c3ed5c3b4ea77b8628678069a7b15d87cb9e6086898e971564f07f3bf23d436e7ee19347a66#npm:8.15.3::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-table%2F-%2Freact-table-8.15.3.tgz"],\ + ["@tanstack/react-virtual", "virtual:a84eb495e555084f80c201f07630d1efc544260e49e6a723e5d25c3ed5c3b4ea77b8628678069a7b15d87cb9e6086898e971564f07f3bf23d436e7ee19347a66#npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-virtual%2F-%2Freact-virtual-3.11.2.tgz"],\ ["@testing-library/jest-dom", "npm:5.17.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40testing-library%2Fjest-dom%2F-%2Fjest-dom-5.17.0.tgz"],\ ["@testing-library/react", "virtual:a84eb495e555084f80c201f07630d1efc544260e49e6a723e5d25c3ed5c3b4ea77b8628678069a7b15d87cb9e6086898e971564f07f3bf23d436e7ee19347a66#npm:14.1.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40testing-library%2Freact%2F-%2Freact-14.1.2.tgz"],\ ["@testing-library/user-event", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:14.5.1::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40testing-library%2Fuser-event%2F-%2Fuser-event-14.5.1.tgz"],\ @@ -22000,6 +22005,87 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD"\ }]\ ]],\ + ["@tanstack/react-virtual", [\ + ["npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-virtual%2F-%2Freact-virtual-3.11.2.tgz", {\ + "packageLocation": "./.yarn/cache/@tanstack-react-virtual-npm-3.11.2-c7367d8d06-a1136da0ec.zip/node_modules/@tanstack/react-virtual/",\ + "packageDependencies": [\ + ["@tanstack/react-virtual", "npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-virtual%2F-%2Freact-virtual-3.11.2.tgz"]\ + ],\ + "linkType": "SOFT"\ + }],\ + ["virtual:40f8e5d9470dadd0060c7b0d5ccbc7394cb2631c4c32ded046c14477c91f332b2a7e811fb9423edb388a602730fec4c2d722550b1609515756ea1cf3021c1e93#npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-virtual%2F-%2Freact-virtual-3.11.2.tgz", {\ + "packageLocation": "./.yarn/__virtual__/@tanstack-react-virtual-virtual-236f833641/0/cache/@tanstack-react-virtual-npm-3.11.2-c7367d8d06-a1136da0ec.zip/node_modules/@tanstack/react-virtual/",\ + "packageDependencies": [\ + ["@tanstack/react-virtual", "virtual:40f8e5d9470dadd0060c7b0d5ccbc7394cb2631c4c32ded046c14477c91f332b2a7e811fb9423edb388a602730fec4c2d722550b1609515756ea1cf3021c1e93#npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-virtual%2F-%2Freact-virtual-3.11.2.tgz"],\ + ["@tanstack/virtual-core", "npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Fvirtual-core%2F-%2Fvirtual-core-3.11.2.tgz"],\ + ["@types/react", "npm:18.2.43::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40types%2Freact%2F-%2Freact-18.2.43.tgz"],\ + ["@types/react-dom", "npm:18.2.17::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40types%2Freact-dom%2F-%2Freact-dom-18.2.17.tgz"],\ + ["react", "npm:18.2.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2Freact%2F-%2Freact-18.2.0.tgz"],\ + ["react-dom", "virtual:b6fae5393a385f4f1bbe5a18f6e1eb116e43df87482141188b0ea2783134c1c43b4542d4d2bc120bac7fb6e4d07c5a98dceeaef7ca716c462765afdea8bc7675#npm:18.2.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2Freact-dom%2F-%2Freact-dom-18.2.0.tgz"]\ + ],\ + "packagePeers": [\ + "@types/react-dom",\ + "@types/react",\ + "react-dom",\ + "react"\ + ],\ + "linkType": "HARD"\ + }],\ + ["virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-virtual%2F-%2Freact-virtual-3.11.2.tgz", {\ + "packageLocation": "./.yarn/__virtual__/@tanstack-react-virtual-virtual-710fa4b6dc/0/cache/@tanstack-react-virtual-npm-3.11.2-c7367d8d06-a1136da0ec.zip/node_modules/@tanstack/react-virtual/",\ + "packageDependencies": [\ + ["@tanstack/react-virtual", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-virtual%2F-%2Freact-virtual-3.11.2.tgz"],\ + ["@tanstack/virtual-core", "npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Fvirtual-core%2F-%2Fvirtual-core-3.11.2.tgz"],\ + ["@types/react", "npm:18.2.43::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40types%2Freact%2F-%2Freact-18.2.43.tgz"],\ + ["@types/react-dom", "npm:18.2.17::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40types%2Freact-dom%2F-%2Freact-dom-18.2.17.tgz"],\ + ["react", "npm:16.14.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2Freact%2F-%2Freact-16.14.0.tgz"],\ + ["react-dom", "virtual:ac97dc161a7119c9069046e42490ca00bf6883b0c120a420828f620346e5a616f38063c37c4d30577588c8b903e63efd6999cff91af9cad2663faf104588286f#npm:16.14.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2Freact-dom%2F-%2Freact-dom-16.14.0.tgz"]\ + ],\ + "packagePeers": [\ + "@types/react-dom",\ + "@types/react",\ + "react-dom",\ + "react"\ + ],\ + "linkType": "HARD"\ + }],\ + ["virtual:6dd0ee4544359587d64ff328fe311b923a3c1ee8914df11782918738abbc6520285dc1ca059877f86375600584583e7d6592895c5c96572203f7b48dc4661862#npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-virtual%2F-%2Freact-virtual-3.11.2.tgz", {\ + "packageLocation": "./.yarn/__virtual__/@tanstack-react-virtual-virtual-241766b31f/0/cache/@tanstack-react-virtual-npm-3.11.2-c7367d8d06-a1136da0ec.zip/node_modules/@tanstack/react-virtual/",\ + "packageDependencies": [\ + ["@tanstack/react-virtual", "virtual:6dd0ee4544359587d64ff328fe311b923a3c1ee8914df11782918738abbc6520285dc1ca059877f86375600584583e7d6592895c5c96572203f7b48dc4661862#npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-virtual%2F-%2Freact-virtual-3.11.2.tgz"],\ + ["@tanstack/virtual-core", "npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Fvirtual-core%2F-%2Fvirtual-core-3.11.2.tgz"],\ + ["@types/react", "npm:18.2.43::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40types%2Freact%2F-%2Freact-18.2.43.tgz"],\ + ["@types/react-dom", "npm:18.2.17::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40types%2Freact-dom%2F-%2Freact-dom-18.2.17.tgz"],\ + ["react", "npm:17.0.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2Freact%2F-%2Freact-17.0.2.tgz"],\ + ["react-dom", "virtual:5a5654a74dd0c04c5098a6f512068feec2c8e29bf2d7f2f4f51fc2ab6bc3c25e312c721937dac9a06feea26b637c0eedc3cdde0a175e4193238da9736337ebd8#npm:17.0.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2Freact-dom%2F-%2Freact-dom-17.0.2.tgz"]\ + ],\ + "packagePeers": [\ + "@types/react-dom",\ + "@types/react",\ + "react-dom",\ + "react"\ + ],\ + "linkType": "HARD"\ + }],\ + ["virtual:a84eb495e555084f80c201f07630d1efc544260e49e6a723e5d25c3ed5c3b4ea77b8628678069a7b15d87cb9e6086898e971564f07f3bf23d436e7ee19347a66#npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-virtual%2F-%2Freact-virtual-3.11.2.tgz", {\ + "packageLocation": "./.yarn/__virtual__/@tanstack-react-virtual-virtual-3f7310d27a/0/cache/@tanstack-react-virtual-npm-3.11.2-c7367d8d06-a1136da0ec.zip/node_modules/@tanstack/react-virtual/",\ + "packageDependencies": [\ + ["@tanstack/react-virtual", "virtual:a84eb495e555084f80c201f07630d1efc544260e49e6a723e5d25c3ed5c3b4ea77b8628678069a7b15d87cb9e6086898e971564f07f3bf23d436e7ee19347a66#npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-virtual%2F-%2Freact-virtual-3.11.2.tgz"],\ + ["@tanstack/virtual-core", "npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Fvirtual-core%2F-%2Fvirtual-core-3.11.2.tgz"],\ + ["@types/react", "npm:18.2.43::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40types%2Freact%2F-%2Freact-18.2.43.tgz"],\ + ["@types/react-dom", "npm:18.2.17::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40types%2Freact-dom%2F-%2Freact-dom-18.2.17.tgz"],\ + ["react", "npm:18.2.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2Freact%2F-%2Freact-18.2.0.tgz"],\ + ["react-dom", "virtual:4e943709711c7f1808d16b6e7402826f520934863f82f7eafe744d9fd7069a89c68dec5dc0c69b3849cdbb88a3aca62802ed72bb2f50d28e5d89a57532ec36c3#npm:18.2.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2Freact-dom%2F-%2Freact-dom-18.2.0.tgz"]\ + ],\ + "packagePeers": [\ + "@types/react-dom",\ + "@types/react",\ + "react-dom",\ + "react"\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["@tanstack/table-core", [\ ["npm:8.15.3::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Ftable-core%2F-%2Ftable-core-8.15.3.tgz", {\ "packageLocation": "./.yarn/cache/@tanstack-table-core-npm-8.15.3-9bfd07342a-eab528dcbb.zip/node_modules/@tanstack/table-core/",\ @@ -22009,6 +22095,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD"\ }]\ ]],\ + ["@tanstack/virtual-core", [\ + ["npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Fvirtual-core%2F-%2Fvirtual-core-3.11.2.tgz", {\ + "packageLocation": "./.yarn/cache/@tanstack-virtual-core-npm-3.11.2-30f07cfe06-b5c9166246.zip/node_modules/@tanstack/virtual-core/",\ + "packageDependencies": [\ + ["@tanstack/virtual-core", "npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Fvirtual-core%2F-%2Fvirtual-core-3.11.2.tgz"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["@testing-library/dom", [\ ["npm:9.3.3::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40testing-library%2Fdom%2F-%2Fdom-9.3.3.tgz", {\ "packageLocation": "./.yarn/cache/@testing-library-dom-npm-9.3.3-6ec9ba8b9a-34e0a564da.zip/node_modules/@testing-library/dom/",\ diff --git a/packages/ui-kit/package.json b/packages/ui-kit/package.json index e0abb6e8..99acfbb7 100644 --- a/packages/ui-kit/package.json +++ b/packages/ui-kit/package.json @@ -27,6 +27,7 @@ "@radix-ui/themes": "^3.1.3", "@tanstack/react-query": "^4.29.17", "@tanstack/react-table": "^8.15.3", + "@tanstack/react-virtual": "^3.11.2", "chart.js": "^4.1.2", "chartjs-adapter-luxon": "1.2.1", "classnames": "^2.5.1", diff --git a/packages/ui-kit/src/components/DataGrid/DataGrid.module.scss b/packages/ui-kit/src/components/DataGrid/DataGrid.module.scss index 0e325ed2..23ff8db6 100644 --- a/packages/ui-kit/src/components/DataGrid/DataGrid.module.scss +++ b/packages/ui-kit/src/components/DataGrid/DataGrid.module.scss @@ -240,13 +240,11 @@ .tableIndexCell { text-align: center; width: var(--propel-space-7); - min-width: var(--propel-space-7); max-width: var(--propel-space-7); left: 0; height: var(--propel-space-7); - min-height: var(--propel-space-7); max-height: var(--propel-space-7); background-color: var(--propel-color-background); diff --git a/packages/ui-kit/src/components/DataGrid/DataGrid.stories.tsx b/packages/ui-kit/src/components/DataGrid/DataGrid.stories.tsx index 3aa78981..16da6b7b 100644 --- a/packages/ui-kit/src/components/DataGrid/DataGrid.stories.tsx +++ b/packages/ui-kit/src/components/DataGrid/DataGrid.stories.tsx @@ -316,3 +316,17 @@ export const Custom: Story = { }, render: (args) => } + +export const Virtualization: Story = { + args: { + ...Basic.args, + query: { + ...Basic.args?.query + }, + paginationProps: { + defaultPageSize: 20000, + pageSizeOptions: [20000] + } + }, + render: (args) => +} diff --git a/packages/ui-kit/src/components/DataGrid/DataGrid.tsx b/packages/ui-kit/src/components/DataGrid/DataGrid.tsx index a86ed8fa..33e7d254 100644 --- a/packages/ui-kit/src/components/DataGrid/DataGrid.tsx +++ b/packages/ui-kit/src/components/DataGrid/DataGrid.tsx @@ -13,6 +13,7 @@ import { } from '@tanstack/react-table' import { Tooltip } from '@radix-ui/themes' import '@radix-ui/themes/styles.css' +import { useVirtualizer } from '@tanstack/react-virtual' import { withContainer } from '../withContainer' import { ErrorFallback, ErrorFallbackProps } from '../ErrorFallback' @@ -257,6 +258,21 @@ export const DataGridComponent = React.forwardRef ...reactTablePagination }) + const headerGroups = table.getHeaderGroups() + const rowGroup = table.getRowModel().rows + + const rowVirtualizer = useVirtualizer({ + count: rowGroup?.length ?? 0, + estimateSize: () => 40, //estimate row height for accurate scrollbar dragging + getScrollElement: () => containerRef.current, + //measure dynamic row height, except in firefox because it measures table border height incorrectly + measureElement: + typeof window !== 'undefined' && navigator.userAgent.indexOf('Firefox') === -1 + ? (element) => element?.getBoundingClientRect().height + : undefined, + overscan: 5 + }) + useEffect(() => { function setDefaultSizing() { const INDEX_COLUMN_WIDTH = 40 @@ -440,9 +456,6 @@ export const DataGridComponent = React.forwardRef const linesStyle = getLinesStyle(tableLinesLayout) - const headerGroups = table.getHeaderGroups() - const rowGroup = table.getRowModel().rows - return (
>
-
+
{headerGroups.map((headerGroup) => (
))}
- {rowGroup.map((row, index) => ( -
- {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/click-events-have-key-events */} + {rowVirtualizer.getVirtualItems().map((virtualRow) => { + const row = rowGroup?.[virtualRow.index] + + return (
handleRowIndexClick(row)} - className={classNames( - componentStyles.tableCell, - componentStyles.tableIndexCell, - { - [componentStyles.selectedRow]: row.id === selectedRow?.id - }, - linesStyle, - { - [componentStyles.hideBorder]: hideBorder - }, - slotProps?.cell?.className - )} + role="row" + data-index={virtualRow.index} + ref={(node) => rowVirtualizer.measureElement(node)} //measure dynamic row height + className={classNames(componentStyles.tableRow, { + [componentStyles.preventGap]: isTableOverflowingY + })} + style={{ + display: 'flex', + position: 'absolute', + transform: `translateY(${virtualRow.start}px)`, //this should always be a `style` as it changes on scroll + width: isResizable ? 'fit-content' : '100%' + }} + key={row.id} > -
{index + 1 + pageIndex * (isStatic ? clientPagination.pageSize : pageSize)}
-
- {row.getVisibleCells().map((cell, index) => ( - // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/click-events-have-key-events + {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/click-events-have-key-events */}
handleRowCellClick(cell)} - style={{ - ...slotProps?.cell?.style, - width: isResizable ? cell.column.getSize() : cell.column.getSize() - }} + onClick={() => handleRowIndexClick(row)} className={classNames( componentStyles.tableCell, + componentStyles.tableIndexCell, { - [componentStyles.selectedRow]: - cell.id === selectedRow?.cells[index].id || cell.id === selectedCell?.id + [componentStyles.selectedRow]: row.id === selectedRow?.id }, linesStyle, - slotProps?.cell?.className, { - [componentStyles.hideBorder]: hideBorder, - [componentStyles.numeric]: !isNaN(Number(cell.getValue())) - } + [componentStyles.hideBorder]: hideBorder + }, + slotProps?.cell?.className )} - key={cell.id} + style={slotProps?.cell?.style} > - {flexRender(cell.column.columnDef.cell, cell.getContext())} +
{row.index + 1 + pageIndex * (isStatic ? clientPagination.pageSize : pageSize)}
- ))} -
- ))} + {row.getVisibleCells().map((cell, index) => ( + // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/click-events-have-key-events +
handleRowCellClick(cell)} + style={{ + ...slotProps?.cell?.style, + width: isResizable ? cell.column.getSize() : cell.column.getSize() + }} + className={classNames( + componentStyles.tableCell, + { + [componentStyles.selectedRow]: + cell.id === selectedRow?.cells[index].id || cell.id === selectedCell?.id + }, + linesStyle, + slotProps?.cell?.className, + { + [componentStyles.hideBorder]: hideBorder, + [componentStyles.numeric]: !isNaN(Number(cell.getValue())) + } + )} + key={cell.id} + > + {flexRender(cell.column.columnDef.cell, cell.getContext())} +
+ ))} +
+ ) + })}
diff --git a/yarn.lock b/yarn.lock index e7fcefc2..bb814e32 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5750,6 +5750,7 @@ __metadata: "@swc/jest": ^0.2.26 "@tanstack/react-query": ^4.29.17 "@tanstack/react-table": ^8.15.3 + "@tanstack/react-virtual": ^3.11.2 "@testing-library/jest-dom": ^5.16.5 "@testing-library/react": ^14.0.0 "@testing-library/user-event": ^14.4.3 @@ -9587,6 +9588,18 @@ __metadata: languageName: node linkType: hard +"@tanstack/react-virtual@npm:^3.11.2": + version: 3.11.2 + resolution: "@tanstack/react-virtual@npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Freact-virtual%2F-%2Freact-virtual-3.11.2.tgz" + dependencies: + "@tanstack/virtual-core": 3.11.2 + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: a1136da0ec4c2ecbd4f996d8b84f228f0b8d851b15806e01049a160ad1d9b2eef0e0a491035fe017c6f84a0e125334f69ea23b32c180df23614ea4a8eeb7490c + languageName: node + linkType: hard + "@tanstack/table-core@npm:8.15.3": version: 8.15.3 resolution: "@tanstack/table-core@npm:8.15.3::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Ftable-core%2F-%2Ftable-core-8.15.3.tgz" @@ -9594,6 +9607,13 @@ __metadata: languageName: node linkType: hard +"@tanstack/virtual-core@npm:3.11.2": + version: 3.11.2 + resolution: "@tanstack/virtual-core@npm:3.11.2::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40tanstack%2Fvirtual-core%2F-%2Fvirtual-core-3.11.2.tgz" + checksum: b5c91662461e3edd1cba0efbaa89e1d061c8bb605bb78d1e87e2a687335c740a731c96a81798b05491df4882ff2fbd27b312f5e7440e4f9d553a81fb2283156a + languageName: node + linkType: hard + "@testing-library/dom@npm:^9.0.0": version: 9.3.3 resolution: "@testing-library/dom@npm:9.3.3::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40testing-library%2Fdom%2F-%2Fdom-9.3.3.tgz" From 5d351193a7f127110b88cd4eed5bcaeefd77bba5 Mon Sep 17 00:00:00 2001 From: Felipe Cadavid Date: Thu, 2 Jan 2025 12:42:32 -0500 Subject: [PATCH 2/3] chore: add changeset --- .changeset/wise-trees-drive.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/wise-trees-drive.md diff --git a/.changeset/wise-trees-drive.md b/.changeset/wise-trees-drive.md new file mode 100644 index 00000000..2c1cde50 --- /dev/null +++ b/.changeset/wise-trees-drive.md @@ -0,0 +1,5 @@ +--- +'@propeldata/ui-kit': minor +--- + +Added virtualization to DataGrid component From 5986ba18de5116be6658fee5797f04334e92ee17 Mon Sep 17 00:00:00 2001 From: Felipe Cadavid Date: Fri, 10 Jan 2025 12:34:47 -0500 Subject: [PATCH 3/3] feat: add virtualize prop --- .../components/DataGrid/DataGrid.module.scss | 2 +- .../components/DataGrid/DataGrid.stories.tsx | 5 ++-- .../src/components/DataGrid/DataGrid.test.tsx | 12 +++++--- .../src/components/DataGrid/DataGrid.tsx | 28 +++++++++++++------ .../src/components/DataGrid/DataGrid.types.ts | 2 ++ 5 files changed, 33 insertions(+), 16 deletions(-) diff --git a/packages/ui-kit/src/components/DataGrid/DataGrid.module.scss b/packages/ui-kit/src/components/DataGrid/DataGrid.module.scss index 23ff8db6..2e862c9b 100644 --- a/packages/ui-kit/src/components/DataGrid/DataGrid.module.scss +++ b/packages/ui-kit/src/components/DataGrid/DataGrid.module.scss @@ -58,7 +58,7 @@ position: relative; position: sticky; - top: 0px; + top: 0; box-sizing: border-box; diff --git a/packages/ui-kit/src/components/DataGrid/DataGrid.stories.tsx b/packages/ui-kit/src/components/DataGrid/DataGrid.stories.tsx index 16da6b7b..3ee5f3b5 100644 --- a/packages/ui-kit/src/components/DataGrid/DataGrid.stories.tsx +++ b/packages/ui-kit/src/components/DataGrid/DataGrid.stories.tsx @@ -325,8 +325,9 @@ export const Virtualization: Story = { }, paginationProps: { defaultPageSize: 20000, - pageSizeOptions: [20000] - } + pageSizeOptions: [1, 20000] + }, + virtualize: true }, render: (args) => } diff --git a/packages/ui-kit/src/components/DataGrid/DataGrid.test.tsx b/packages/ui-kit/src/components/DataGrid/DataGrid.test.tsx index 80179525..7a1dd8a1 100644 --- a/packages/ui-kit/src/components/DataGrid/DataGrid.test.tsx +++ b/packages/ui-kit/src/components/DataGrid/DataGrid.test.tsx @@ -16,7 +16,7 @@ const handlers = [ ctx.data({ dataGrid: { headers: ['name'], - rows: [['page 2']], + rows: [['page 2'], ['page 2.2']], pageInfo: { hasNextPage: false, hasPreviousPage: true, @@ -32,7 +32,7 @@ const handlers = [ ctx.data({ dataGrid: { headers: ['name'], - rows: [['page 1']], + rows: [['page 1'], ['page 1.1']], pageInfo: { hasNextPage: true, hasPreviousPage: false, @@ -138,7 +138,11 @@ describe('DataGrid', () => { }, 10000) it('paginates forward and backwards', async () => { - dom = render() + dom = render( +
+ +
+ ) await dom.findByText('page 1') @@ -151,7 +155,7 @@ describe('DataGrid', () => { fireEvent.click(await dom.findByTestId('propel-datagrid-paginate-back')) await dom.findByText('page 1') - }, 30000) + }, 40000) it('changes page size', async () => { dom = render() diff --git a/packages/ui-kit/src/components/DataGrid/DataGrid.tsx b/packages/ui-kit/src/components/DataGrid/DataGrid.tsx index 33e7d254..5fc3e2a9 100644 --- a/packages/ui-kit/src/components/DataGrid/DataGrid.tsx +++ b/packages/ui-kit/src/components/DataGrid/DataGrid.tsx @@ -13,7 +13,7 @@ import { } from '@tanstack/react-table' import { Tooltip } from '@radix-ui/themes' import '@radix-ui/themes/styles.css' -import { useVirtualizer } from '@tanstack/react-virtual' +import { useVirtualizer, VirtualItem } from '@tanstack/react-virtual' import { withContainer } from '../withContainer' import { ErrorFallback, ErrorFallbackProps } from '../ErrorFallback' @@ -69,6 +69,7 @@ export const DataGridComponent = React.forwardRef hideBorder, accentColor, showRowCount = false, + virtualize = false, ...rest }, forwardedRef @@ -270,9 +271,12 @@ export const DataGridComponent = React.forwardRef typeof window !== 'undefined' && navigator.userAgent.indexOf('Firefox') === -1 ? (element) => element?.getBoundingClientRect().height : undefined, - overscan: 5 + overscan: 5, + enabled: virtualize }) + const visibleRowGroup = virtualize ? rowVirtualizer.getVirtualItems() : rowGroup + useEffect(() => { function setDefaultSizing() { const INDEX_COLUMN_WIDTH = 40 @@ -469,8 +473,8 @@ export const DataGridComponent = React.forwardRef ref={tableRef} className={componentStyles.table} style={{ - height: rowVirtualizer.getTotalSize() + 'px', - position: 'relative', + height: virtualize ? rowVirtualizer.getTotalSize() + 'px' : undefined, + position: virtualize ? 'relative' : undefined, width: '100%', maxHeight: 'unset' }} @@ -549,21 +553,27 @@ export const DataGridComponent = React.forwardRef ))}
- {rowVirtualizer.getVirtualItems().map((virtualRow) => { - const row = rowGroup?.[virtualRow.index] + {visibleRowGroup.map((groupRow) => { + const virtualRow = { ...groupRow } as VirtualItem + let row: Row + if (virtualRow.start != null) { + row = rowGroup[virtualRow.index] + } else { + row = groupRow as Row + } return (
rowVirtualizer.measureElement(node)} //measure dynamic row height className={classNames(componentStyles.tableRow, { [componentStyles.preventGap]: isTableOverflowingY })} style={{ display: 'flex', - position: 'absolute', - transform: `translateY(${virtualRow.start}px)`, //this should always be a `style` as it changes on scroll + position: virtualize ? 'absolute' : undefined, + transform: virtualize ? `translateY(${virtualRow.start}px)` : undefined, //this should always be a `style` as it changes on scroll width: isResizable ? 'fit-content' : '100%' }} key={row.id} diff --git a/packages/ui-kit/src/components/DataGrid/DataGrid.types.ts b/packages/ui-kit/src/components/DataGrid/DataGrid.types.ts index f4f4b34b..358515ab 100644 --- a/packages/ui-kit/src/components/DataGrid/DataGrid.types.ts +++ b/packages/ui-kit/src/components/DataGrid/DataGrid.types.ts @@ -84,6 +84,8 @@ export interface DataGridProps extends ThemeSettingProps, DataComponentProps<'di prettifyHeaders?: boolean /** If true, row count will be shown in the footer */ showRowCount?: boolean + /** If true, the table will be virtualized */ + virtualize?: boolean } interface DataGridPaginationProps {