import emojis from './emojiList.json' import emojiTagsData from 'emojilib' import { Stack, SimpleGrid, GridItem, Button, Input as ClassicInput, Text, } from '@chakra-ui/react' import { useState, ChangeEvent, useEffect, useRef } from 'react' const emojiTags = emojiTagsData as Record const people = emojis['Smileys & Emotion'].concat(emojis['People & Body']) const nature = emojis['Animals & Nature'] const food = emojis['Food & Drink'] const activities = emojis['Activities'] const travel = emojis['Travel & Places'] const objects = emojis['Objects'] const symbols = emojis['Symbols'] const flags = emojis['Flags'] export const EmojiSearchableList = ({ onEmojiSelected, }: { onEmojiSelected: (emoji: string) => void }) => { const scrollContainer = useRef(null) const bottomElement = useRef(null) const [isSearching, setIsSearching] = useState(false) const [filteredPeople, setFilteredPeople] = useState(people) const [filteredAnimals, setFilteredAnimals] = useState(nature) const [filteredFood, setFilteredFood] = useState(food) const [filteredTravel, setFilteredTravel] = useState(travel) const [filteredActivities, setFilteredActivities] = useState(activities) const [filteredObjects, setFilteredObjects] = useState(objects) const [filteredSymbols, setFilteredSymbols] = useState(symbols) const [filteredFlags, setFilteredFlags] = useState(flags) const [totalDisplayedCategories, setTotalDisplayedCategories] = useState(1) useEffect(() => { if (!bottomElement.current) return const observer = new IntersectionObserver(handleObserver, { root: scrollContainer.current, }) if (bottomElement.current) observer.observe(bottomElement.current) return () => { observer.disconnect() } // eslint-disable-next-line react-hooks/exhaustive-deps }, [bottomElement.current]) const handleObserver = (entities: IntersectionObserverEntry[]) => { const target = entities[0] if (target.isIntersecting) setTotalDisplayedCategories((c) => c + 1) } const handleSearchChange = async (e: ChangeEvent) => { const searchValue = e.target.value if (searchValue.length <= 2 && isSearching) return resetEmojiList() setIsSearching(true) setTotalDisplayedCategories(8) const byTag = (emoji: string) => emojiTags[emoji].find((tag) => tag.includes(searchValue)) setFilteredPeople(people.filter(byTag)) setFilteredAnimals(nature.filter(byTag)) setFilteredFood(food.filter(byTag)) setFilteredTravel(travel.filter(byTag)) setFilteredActivities(activities.filter(byTag)) setFilteredObjects(objects.filter(byTag)) setFilteredSymbols(symbols.filter(byTag)) setFilteredFlags(flags.filter(byTag)) } const resetEmojiList = () => { setTotalDisplayedCategories(1) setIsSearching(false) setFilteredPeople(people) setFilteredAnimals(nature) setFilteredFood(food) setFilteredTravel(travel) setFilteredActivities(activities) setFilteredObjects(objects) setFilteredSymbols(symbols) setFilteredFlags(flags) } return ( {filteredPeople.length > 0 && ( People )} {filteredAnimals.length > 0 && totalDisplayedCategories >= 2 && ( Animals & Nature )} {filteredFood.length > 0 && totalDisplayedCategories >= 3 && ( Food & Drink )} {filteredTravel.length > 0 && totalDisplayedCategories >= 4 && ( Travel & Places )} {filteredActivities.length > 0 && totalDisplayedCategories >= 5 && ( Activities )} {filteredObjects.length > 0 && totalDisplayedCategories >= 6 && ( Objects )} {filteredSymbols.length > 0 && totalDisplayedCategories >= 7 && ( Symbols )} {filteredFlags.length > 0 && totalDisplayedCategories >= 8 && ( Flags )}
) } const EmojiGrid = ({ emojis, onEmojiClick, }: { emojis: string[] onEmojiClick: (emoji: string) => void }) => { const handleClick = (emoji: string) => () => onEmojiClick(emoji) return ( {emojis.map((emoji) => ( {emoji} ))} ) }