Spaces:
Running
Running
File size: 5,475 Bytes
9cd6ddb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
import { useEffect, useRef, useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { Icons } from "@/components/svg/icons";
import { IconItem } from "@/types/editor";
import { Input } from "@/components/input";
import {
useResults,
useSingleSearch,
} from "@/components/search/hooks/useSearch";
import { ListItem } from "@/components/editor-icons/comps/list/list-item";
import { Empty } from "@/components/empty";
import { ArrowLeftIcon } from "@heroicons/react/solid";
import { ArrowRightIcon } from "@heroicons/react/solid";
import { useClickAway } from "react-use";
import classNames from "classnames";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faTrash } from "@fortawesome/free-solid-svg-icons";
export const IconPicker = ({
icon,
onSelect,
children,
}: {
onSelect: (i?: string) => void;
icon?: string;
children?: React.ReactNode;
}) => {
const [open, setOpen] = useState(false);
const svgRef = useRef<any>(null);
const container = useRef<HTMLDivElement>(null);
const intl = useIntl();
const [viewBox, setViewBox] = useState<string>("0 0 24 24");
const [search, setSearch] = useState<any>("");
useSingleSearch(search);
const { results, page, maxPage, totalItems, setPage } = useResults(21);
const findIcon = Icons?.find((i: IconItem) => icon === i.name);
const IconComponent = findIcon?.component as any;
useEffect(() => {
return setViewBox(
svgRef?.current?.getAttribute("viewBox") ?? "0 0 200 200"
);
}, [icon]);
useClickAway(container, () => setOpen(false));
return (
<div ref={container} className="relative">
<div
className="border border-dark-300 rounded-lg w-10 h-10 flex items-center justify-center hover:bg-green hover:bg-opacity-40 hover:border-green cursor-pointer"
onClick={() => setOpen(!open)}
>
<svg
width={16}
height={16}
fill="white"
viewBox={viewBox}
style={{ minWidth: 16, minHeight: 16 }}
>
<IconComponent ref={svgRef as any} />
</svg>
</div>
<div
className={classNames(
"w-full fixed lg:absolute lg:w-[420px] p-6 min-h-[350px] rounded-lg bg-dark-default left-0 bottom-0 lg:left-12 lg:top-0 transform lg:-translate-y-1/2 shadow-xl border-2 border-dark-200 border-opacity-20 z-[11]",
{
"opacity-0 pointer-events-none": !open,
}
)}
>
<Input
value={search}
type="text"
placeholder="Search for an icon"
className="bg-dark-600 rounded p-3 text-sm text-white placeholder-dark-200"
onChange={setSearch as any}
/>
<div className="flex jlg:items-start flex-wrap justify-start mt-3 gap-2 lg:gap-3">
{results?.map((result: any, key: number) => (
<ListItem
key={key}
icon={result}
fill={result?.defaultColor}
onSelect={(icon) => {
// if (icon?.isPremium && !user?.id) return setOpen(true);
// onSelect(icon);
onSelect(icon.name);
}}
/>
))}
{results?.length === 0 && (
<Empty
title="Clyde is disappointed..."
description="...there is no icon that matches your search :("
action={() => {
// if (!user?.id) return login();
// send to api a request;
}}
button="Ask for a new Icon"
/>
)}
</div>
{results?.length > 0 && (
<div className="flex items-center justify-between gap-4 mt-10">
<button
disabled={page <= 1}
className="w-full lg:w-auto group border-2 border-darkGreen bg-darkGreen text-white font-medium tracking-wide px-3.5 py-2 text-sm flex items-center justify-center gap-2 rounded-lg hover:bg-opacity-90 hover:border-opacity-0 disabled:bg-dark-100 disabled:bg-opacity-20 disabled:border-dark-100 disabled:border-opacity-0 disabled:text-dark-200 disabled:cursor-not-allowed"
onClick={() => setPage(page - 1)}
>
<ArrowLeftIcon className="w-4 text-white group-disabled:text-dark-200" />
</button>
<div className="hidden items-center justify-center gap-2 lg:flex">
<p className="text-dark-100 font-medium text-sm">
<FormattedMessage
id="iconsEditor.editor.listIcons.pagination.total"
values={{
page: () => page,
maxPage: () => maxPage,
}}
/>
</p>
</div>
<button
disabled={page === maxPage}
className="w-full lg:w-auto group border-2 border-darkGreen bg-darkGreen text-white font-medium tracking-wide px-3.5 py-2 text-sm flex items-center justify-center gap-2 rounded-lg hover:bg-opacity-90 hover:border-opacity-0 disabled:bg-dark-100 disabled:bg-opacity-20 disabled:border-dark-100 disabled:border-opacity-0 disabled:text-dark-200 disabled:cursor-not-allowed"
onClick={page >= maxPage ? () => {} : () => setPage(page + 1)}
>
<ArrowRightIcon className="w-4 text-white group-disabled:text-dark-200" />
</button>
</div>
)}
</div>
</div>
);
};
|