diff --git a/components/IconGrid.tsx b/components/IconGrid.tsx
index b6333a7..494337e 100644
--- a/components/IconGrid.tsx
+++ b/components/IconGrid.tsx
@@ -1,6 +1,7 @@
import { icons } from "@/lib/client/icons";
import Fuse from "fuse.js";
-import { useMemo } from "react";
+import { forwardRef, useMemo } from "react";
+import { FixedSizeGrid as Grid } from "react-window";
const fuse = new Fuse(icons, {
keys: [{ name: "name", weight: 4 }, "tags", "categories"],
@@ -17,32 +18,74 @@ type Props = {
};
const IconGrid = ({ query, color, weight, iconName, setIconName }: Props) => {
- const filteredQueryResultsSelector = useMemo(() => {
+ // Memoize the filtered results to avoid recalculations on each render
+ const filteredIcons = useMemo(() => {
if (!query) {
return icons;
}
return fuse.search(query).map((result) => result.item);
}, [query]);
+ // Grid configuration
+ const columnCount = 6;
+ const rowCount = Math.ceil(filteredIcons.length / columnCount);
+ const GUTTER_SIZE = 5;
+
+ // Render a single cell (icon) in the grid
+ const Cell = ({ columnIndex, rowIndex, style }: any) => {
+ const index = rowIndex * columnCount + columnIndex;
+ if (index >= filteredIcons.length) return null; // Prevent overflow
+
+ const icon = filteredIcons[index];
+ const IconComponent = icon.Icon;
+
+ return (
+
setIconName(icon.pascal_name)}
+ className={`cursor-pointer p-[6px] rounded-lg bg-base-100 w-full ${
+ icon.pascal_name === iconName
+ ? "outline outline-1 outline-primary"
+ : ""
+ }`}
+ >
+
+
+ );
+ };
+
+ const innerElementType = forwardRef(({ style, ...rest }: any, ref) => (
+
+ ));
+
return (
- <>
- {filteredQueryResultsSelector.map((icon) => {
- const IconComponent = icon.Icon;
- return (
- setIconName(icon.pascal_name)}
- className={`cursor-pointer btn p-1 box-border bg-base-100 border-none w-full ${
- icon.pascal_name === iconName
- ? "outline outline-1 outline-primary"
- : ""
- }`}
- >
-
-
- );
- })}
- >
+
+ {Cell}
+
);
};
diff --git a/package.json b/package.json
index dc19969..b07bbb2 100644
--- a/package.json
+++ b/package.json
@@ -76,6 +76,7 @@
"react-masonry-css": "^1.0.16",
"react-select": "^5.7.4",
"react-spinners": "^0.14.1",
+ "react-window": "^1.8.10",
"socks-proxy-agent": "^8.0.2",
"stripe": "^12.13.0",
"tailwind-merge": "^2.3.0",
@@ -89,6 +90,7 @@
"@types/dompurify": "^3.0.4",
"@types/jsdom": "^21.1.3",
"@types/node-fetch": "^2.6.10",
+ "@types/react-window": "^1.8.8",
"@types/shelljs": "^0.8.15",
"autoprefixer": "^10.4.14",
"daisyui": "^4.4.2",
diff --git a/yarn.lock b/yarn.lock
index e06adb4..fdf66a1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2118,6 +2118,13 @@
dependencies:
"@types/react" "*"
+"@types/react-window@^1.8.8":
+ version "1.8.8"
+ resolved "https://registry.yarnpkg.com/@types/react-window/-/react-window-1.8.8.tgz#c20645414d142364fbe735818e1c1e0a145696e3"
+ integrity sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==
+ dependencies:
+ "@types/react" "*"
+
"@types/react@*", "@types/react@18.2.14":
version "18.2.14"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.14.tgz#fa7a6fecf1ce35ca94e74874f70c56ce88f7a127"
@@ -4516,7 +4523,7 @@ make-error@^1.1.1:
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
-memoize-one@^5.0.4:
+"memoize-one@>=3.1.1 <6", memoize-one@^5.0.4:
version "5.2.1"
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e"
integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==
@@ -5421,6 +5428,14 @@ react-transition-group@^4.3.0:
loose-envify "^1.4.0"
prop-types "^15.6.2"
+react-window@^1.8.10:
+ version "1.8.10"
+ resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.10.tgz#9e6b08548316814b443f7002b1cf8fd3a1bdde03"
+ integrity sha512-Y0Cx+dnU6NLa5/EvoHukUD0BklJ8qITCtVEPY1C/nL8wwoZ0b5aEw8Ff1dOVHw7fCzMt55XfJDd8S8W8LCaUCg==
+ dependencies:
+ "@babel/runtime" "^7.0.0"
+ memoize-one ">=3.1.1 <6"
+
react@18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"