diff --git a/components/IconPicker.tsx b/components/IconPicker.tsx
new file mode 100644
index 0000000..994a5af
--- /dev/null
+++ b/components/IconPicker.tsx
@@ -0,0 +1,46 @@
+import { icons } from "@/lib/client/icons";
+import React, { useMemo, useState } from "react";
+import Fuse from "fuse.js";
+import TextInput from "./TextInput";
+
+const fuse = new Fuse(icons, {
+ keys: [{ name: "name", weight: 4 }, "tags", "categories"],
+ threshold: 0.2,
+ useExtendedSearch: true,
+});
+
+type Props = {};
+
+const IconPicker = (props: Props) => {
+ const [query, setQuery] = useState("");
+
+ const filteredQueryResultsSelector = useMemo(() => {
+ if (!query) {
+ return icons;
+ }
+ return fuse.search(query).map((result) => result.item);
+ }, [query]);
+
+ return (
+
+
setQuery(e.target.value)}
+ />
+
+ {filteredQueryResultsSelector.map((icon) => {
+ const IconComponent = icon.Icon;
+ return (
+
console.log(icon.name)}>
+
+
+ );
+ })}
+
+
+ );
+};
+
+export default IconPicker;
diff --git a/lib/client/icons.ts b/lib/client/icons.ts
new file mode 100644
index 0000000..2083bd0
--- /dev/null
+++ b/lib/client/icons.ts
@@ -0,0 +1,18 @@
+import * as Icons from "@phosphor-icons/react";
+import { icons as iconData } from "@phosphor-icons/core";
+import { IconEntry as CoreEntry } from "@phosphor-icons/core";
+
+interface IconEntry extends CoreEntry {
+ Icon: Icons.Icon;
+}
+
+export const icons: ReadonlyArray = iconData.map((entry) => ({
+ ...entry,
+ Icon: Icons[entry.pascal_name as keyof typeof Icons] as Icons.Icon,
+}));
+
+if (process.env.NODE_ENV === "development") {
+ console.log(`${icons.length} icons`);
+}
+
+export const iconCount = Intl.NumberFormat("en-US").format(icons.length * 6);
diff --git a/package.json b/package.json
index 0850217..7f090d9 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "linkwarden",
- "version": "v2.7.1",
+ "version": "v2.8.0",
"main": "index.js",
"repository": "https://github.com/linkwarden/linkwarden.git",
"author": "Daniel31X13 ",
@@ -25,6 +25,8 @@
"@aws-sdk/client-s3": "^3.379.1",
"@headlessui/react": "^1.7.15",
"@mozilla/readability": "^0.4.4",
+ "@phosphor-icons/core": "^2.1.1",
+ "@phosphor-icons/react": "^2.1.7",
"@prisma/client": "^4.16.2",
"@stripe/stripe-js": "^1.54.1",
"@tanstack/react-query": "^5.51.15",
@@ -50,6 +52,7 @@
"eslint-config-next": "13.4.9",
"formidable": "^3.5.1",
"framer-motion": "^10.16.4",
+ "fuse.js": "^7.0.0",
"handlebars": "^4.7.8",
"himalaya": "^1.1.0",
"i18next": "^23.11.5",
diff --git a/yarn.lock b/yarn.lock
index edf5040..85783ea 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1281,6 +1281,16 @@
resolved "https://registry.yarnpkg.com/@panva/hkdf/-/hkdf-1.1.1.tgz#ab9cd8755d1976e72fc77a00f7655a64efe6cd5d"
integrity sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==
+"@phosphor-icons/core@^2.1.1":
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/@phosphor-icons/core/-/core-2.1.1.tgz#62a4cfbec9772f1a613a647da214fbb96f3ad39d"
+ integrity sha512-v4ARvrip4qBCImOE5rmPUylOEK4iiED9ZyKjcvzuezqMaiRASCHKcRIuvvxL/twvLpkfnEODCOJp5dM4eZilxQ==
+
+"@phosphor-icons/react@^2.1.7":
+ version "2.1.7"
+ resolved "https://registry.yarnpkg.com/@phosphor-icons/react/-/react-2.1.7.tgz#b11a4b25849b7e3849970b688d9fe91e5d4fd8d7"
+ integrity sha512-g2e2eVAn1XG2a+LI09QU3IORLhnFNAFkNbo2iwbX6NOKSLOwvEMmTa7CgOzEbgNWR47z8i8kwjdvYZ5fkGx1mQ==
+
"@pkgr/utils@^2.3.1":
version "2.3.1"
resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.3.1.tgz#0a9b06ffddee364d6642b3cd562ca76f55b34a03"
@@ -3553,6 +3563,11 @@ functions-have-names@^1.2.2:
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
+fuse.js@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-7.0.0.tgz#6573c9fcd4c8268e403b4fc7d7131ffcf99a9eb2"
+ integrity sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==
+
gauge@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395"