Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
1import { MagnifyingGlassIcon, XMarkIcon } from "@heroicons/react/24/outline";
2import { ERRORS } from "@hey/data/errors";
3import type { Emoji } from "@hey/types/misc";
4import type { ChangeEvent, MouseEvent } from "react";
5import { useEffect, useRef, useState } from "react";
6import Loader from "@/components/Shared/Loader";
7import { ErrorMessage, Input } from "@/components/Shared/UI";
8import cn from "@/helpers/cn";
9import stopEventPropagation from "@/helpers/stopEventPropagation";
10import useEmojis from "@/hooks/prosekit/useEmojis";
11
12interface ListProps {
13 setEmoji: (emoji: string) => void;
14}
15
16const List = ({ setEmoji }: ListProps) => {
17 const inputRef = useRef<HTMLInputElement>(null);
18 const [searchText, setSearchText] = useState("");
19 const { emojis, error, isLoading } = useEmojis({
20 limit: 100, // Show more emojis in the picker
21 minQueryLength: 2,
22 query: searchText
23 });
24
25 const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
26 setSearchText(event.target.value);
27 };
28
29 const handleClearSearch = (e: MouseEvent) => {
30 e.preventDefault();
31 stopEventPropagation(e);
32 setSearchText("");
33 };
34
35 useEffect(() => {
36 inputRef.current?.focus();
37 }, []);
38
39 if (error) {
40 return (
41 <ErrorMessage
42 className="m-5"
43 error={{ message: "Error while loading emojis" }}
44 title={ERRORS.SomethingWentWrong}
45 />
46 );
47 }
48
49 if (isLoading) {
50 return <Loader className="my-5" message="Loading emojis" />;
51 }
52
53 return (
54 <div>
55 <div className="w-full p-2 pt-4 pb-0">
56 <Input
57 autoFocus
58 className="px-3 py-2 text-sm"
59 iconLeft={<MagnifyingGlassIcon />}
60 iconRight={
61 <XMarkIcon
62 className={cn(
63 "cursor-pointer",
64 searchText ? "visible" : "invisible"
65 )}
66 onClick={handleClearSearch}
67 />
68 }
69 onChange={handleChange}
70 onClick={(e) => {
71 e.preventDefault();
72 stopEventPropagation(e);
73 }}
74 placeholder="Search..."
75 ref={inputRef}
76 type="text"
77 value={searchText}
78 />
79 </div>
80 <div className="grid max-h-[10rem] grid-cols-8 overflow-y-auto p-2 pt-2">
81 {emojis.map((emoji: Emoji) => (
82 <button
83 className="rounded-lg py-1 hover:bg-gray-100 dark:hover:bg-gray-800"
84 key={emoji.emoji}
85 onClick={() => setEmoji(emoji.emoji)}
86 type="button"
87 >
88 {emoji.emoji}
89 </button>
90 ))}
91 </div>
92 </div>
93 );
94};
95
96export default List;