From ae2324ecd352acfc215a6222727bacc34c80f444 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Tue, 20 Aug 2024 16:59:01 -0400 Subject: [PATCH] progressed icon picker component --- components/IconPicker.tsx | 168 ++++++++++-------- .../ModalContent/EditCollectionModal.tsx | 73 +++----- pages/_app.tsx | 7 +- styles/globals.css | 9 +- 4 files changed, 130 insertions(+), 127 deletions(-) diff --git a/components/IconPicker.tsx b/components/IconPicker.tsx index f90dc1f..513da2c 100644 --- a/components/IconPicker.tsx +++ b/components/IconPicker.tsx @@ -1,31 +1,26 @@ import { icons } from "@/lib/client/icons"; -import React, { useMemo, useState } from "react"; +import React, { useMemo, useState, lazy, Suspense } from "react"; import Fuse from "fuse.js"; import TextInput from "./TextInput"; import Popover from "./Popover"; import { HexColorPicker } from "react-colorful"; +import { useTranslation } from "next-i18next"; import Icon from "./Icon"; - -const fuse = new Fuse(icons, { - keys: [{ name: "name", weight: 4 }, "tags", "categories"], - threshold: 0.2, - useExtendedSearch: true, -}); +import { IconWeight } from "@phosphor-icons/react"; type Props = { - onClose: Function; - alignment?: "left" | "right" | "bottom" | "top"; + alignment?: "left" | "right"; color: string; setColor: Function; - iconName: string; + iconName?: string; setIconName: Function; - weight: "light" | "regular" | "bold" | "fill" | "duotone"; + weight: "light" | "regular" | "bold" | "fill" | "duotone" | "thin"; setWeight: Function; + reset: Function; className?: string; }; const IconPicker = ({ - onClose, alignment, color, setColor, @@ -34,8 +29,17 @@ const IconPicker = ({ weight, setWeight, className, + reset, }: Props) => { + const fuse = new Fuse(icons, { + keys: [{ name: "name", weight: 4 }, "tags", "categories"], + threshold: 0.2, + useExtendedSearch: true, + }); + + const { t } = useTranslation(); const [query, setQuery] = useState(""); + const [iconPicker, setIconPicker] = useState(false); const filteredQueryResultsSelector = useMemo(() => { if (!query) { @@ -45,67 +49,87 @@ const IconPicker = ({ }, [query]); return ( - -
-
-
- - - -
- setColor(e)} /> -
- - setQuery(e.target.value)} - /> - -
- {filteredQueryResultsSelector.map((icon) => { - const IconComponent = icon.Icon; - return ( -
setIconName(icon.pascal_name)} - className={`cursor-pointer btn p-1 box-border ${ - icon.pascal_name === iconName - ? "outline outline-1 outline-primary" - : "" - }`} - > - -
- ); - })} -
+
+
setIconPicker(!iconPicker)} + className="btn btn-square w-20 h-20" + > + {iconName ? ( + + ) : ( + + )}
- + {iconPicker && ( + setIconPicker(false)} + className={ + className + + " fade-in bg-base-200 border border-neutral-content p-2 h-44 w-[22.5rem] rounded-lg backdrop-blur-sm bg-opacity-90 top-20 left-0 lg:-translate-x-1/3" + } + > +
+
+
} + > + {t("reset")} +
+ + setColor(e)} /> +
+ +
+ setQuery(e.target.value)} + /> + +
+ {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 aspect-square ${ + icon.pascal_name === iconName + ? "outline outline-1 outline-primary" + : "" + }`} + > + +
+ ); + })} +
+
+
+
+ )} +
); }; diff --git a/components/ModalContent/EditCollectionModal.tsx b/components/ModalContent/EditCollectionModal.tsx index 76833e7..20a6cdd 100644 --- a/components/ModalContent/EditCollectionModal.tsx +++ b/components/ModalContent/EditCollectionModal.tsx @@ -1,6 +1,5 @@ import React, { useState } from "react"; import TextInput from "@/components/TextInput"; -import { HexColorPicker } from "react-colorful"; import { CollectionIncludingMembersAndLinkCount } from "@/types/global"; import Modal from "../Modal"; import { useTranslation } from "next-i18next"; @@ -8,6 +7,7 @@ import { useUpdateCollection } from "@/hooks/store/collections"; import toast from "react-hot-toast"; import IconPicker from "../IconPicker"; import Icon from "../Icon"; +import { IconWeight } from "@phosphor-icons/react"; type Props = { onClose: Function; @@ -22,7 +22,6 @@ export default function EditCollectionModal({ const [collection, setCollection] = useState(activeCollection); - const [iconPicker, setIconPicker] = useState(false); const [submitLoader, setSubmitLoader] = useState(false); const updateCollection = useUpdateCollection(); @@ -59,10 +58,32 @@ export default function EditCollectionModal({
-
-
-

{t("name")}

-
+
+
+ + setCollection({ ...collection, color }) + } + weight={(collection.iconWeight || "regular") as IconWeight} + setWeight={(iconWeight: string) => + setCollection({ ...collection, iconWeight }) + } + iconName={collection.icon as string} + setIconName={(icon: string) => + setCollection({ ...collection, icon }) + } + reset={() => + setCollection({ + ...collection, + color: "#0ea5e9", + icon: "", + iconWeight: "", + }) + } + /> +
+

{t("name")}

-
-

{t("color")}

-
-
- setIconPicker(true)} - /> - {iconPicker && ( - setIconPicker(false)} - className="top-20" - color={collection.color as string} - setColor={(color: string) => - setCollection({ ...collection, color }) - } - weight={collection.iconWeight as any} - setWeight={(iconWeight: string) => - setCollection({ ...collection, iconWeight }) - } - iconName={collection.icon as string} - setIconName={(icon: string) => - setCollection({ ...collection, icon }) - } - /> - )} -
- setCollection({ ...collection, color: "#0ea5e9" }) - } - > - {t("reset")} -
-
-
-
diff --git a/pages/_app.tsx b/pages/_app.tsx index dc6603a..c99d26a 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -88,13 +88,10 @@ function App({ {icon} {message} {t.type !== "loading" && ( - + >
)}
)} diff --git a/styles/globals.css b/styles/globals.css index 022c160..28a0105 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -144,15 +144,16 @@ /* For react-colorful */ .color-picker .react-colorful { - width: 100%; - height: 7.5rem; + height: 7rem; + width: 7rem; } .color-picker .react-colorful__hue { height: 1rem; } .color-picker .react-colorful__pointer { - width: 1.3rem; - height: 1.3rem; + width: 1rem; + height: 1rem; + border-width: 1px; } /* For the Link banner */