| import { useEffect, useRef } from "react"; | |
| interface StickerPickerProps { | |
| onSelect: (url: string) => void; | |
| onClose: () => void; | |
| } | |
| // Placeholder stickers – replace with your own hosted GIF/PNG files | |
| const STICKER_SET = [ | |
| { src: "/stickers/hello.gif", name: "hello" }, | |
| { src: "/stickers/like.gif", name: "like" }, | |
| { src: "/stickers/fire.gif", name: "fire" }, | |
| { src: "/stickers/clap.gif", name: "clap" }, | |
| { src: "/stickers/party.gif", name: "party" }, | |
| { src: "/stickers/wow.gif", name: "wow" }, | |
| ]; | |
| export function StickerPicker({ onSelect, onClose }: StickerPickerProps) { | |
| const panelRef = useRef<HTMLDivElement>(null); | |
| useEffect(() => { | |
| const handleClick = (e: MouseEvent) => { | |
| if (panelRef.current && !panelRef.current.contains(e.target as Node)) { | |
| onClose(); | |
| } | |
| }; | |
| document.addEventListener("mousedown", handleClick); | |
| return () => document.removeEventListener("mousedown", handleClick); | |
| }, [onClose]); | |
| return ( | |
| <div | |
| ref={panelRef} | |
| className="absolute bottom-full mb-2 left-0 w-72 bg-white dark:bg-gray-800 rounded-2xl shadow-2xl border border-gray-200 dark:border-gray-700 p-3 z-50" | |
| > | |
| <div className="flex justify-between items-center mb-2"> | |
| <span className="text-sm font-semibold text-gray-700 dark:text-gray-300"> | |
| Stickers | |
| </span> | |
| <button | |
| onClick={onClose} | |
| className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300" | |
| > | |
| ✕ | |
| </button> | |
| </div> | |
| <div className="grid grid-cols-4 gap-2"> | |
| {STICKER_SET.map((sticker) => ( | |
| <button | |
| key={sticker.name} | |
| onClick={() => onSelect(sticker.src)} | |
| className="aspect-square bg-gray-100 dark:bg-gray-700 rounded-xl hover:bg-gray-200 dark:hover:bg-gray-600 transition p-2" | |
| title={sticker.name} | |
| > | |
| <img | |
| src={sticker.src} | |
| alt={sticker.name} | |
| className="w-full h-full object-contain" | |
| loading="lazy" | |
| /> | |
| </button> | |
| ))} | |
| </div> | |
| </div> | |
| ); | |
| } |
Xet Storage Details
- Size:
- 2.14 kB
- Xet hash:
- 52fbeb976bd5c43e9c4c432b5c5dc1d0a6f74da8083818ee4534dde5c44a46a7
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.