import type { IconName } from "@fortawesome/fontawesome-svg-core" import { fas } from "@fortawesome/free-solid-svg-icons" import { FontAwesomeIcon } from "@fortawesome/react-native-fontawesome" import { memo, useCallback, useEffect, useState, useTransition } from "react" import { Modal, ScrollView, View } from "react-native" import { Button, List, Text, TextInput } from "react-native-paper" import Fuse from "fuse.js" import { IconsList } from "./IconsList" export interface IconSelectorModalProps { isVisible?: boolean selectedIcon?: string onIconSelect: (icon: string) => void handleCloseModal?: () => void } interface SearchInputProps { searchText: string handleSearch: (text: string) => void } const SearchInputWithoutMemo: React.FC = (props) => { const { searchText, handleSearch } = props return ( ) } const SearchInput = memo(SearchInputWithoutMemo) const iconNames = Object.keys(fas).map((key) => { return fas[key]?.iconName ?? key }) const fuseOptions = { keys: ["iconName"], threshold: 0.4, } const fuse = new Fuse(iconNames, fuseOptions) const findIconsInLibrary = (icon: string): string[] => { const results = fuse.search(icon).map((result) => { return result.item }) const uniqueResults = Array.from(new Set(results)) return uniqueResults.slice(0, 50) } export const IconSelectorModal: React.FC = ({ isVisible = false, selectedIcon, onIconSelect, handleCloseModal, }) => { const [possibleIcons, setPossibleIcons] = useState([]) const [isLoading, setIsLoading] = useState(true) const [searchText, setSearchText] = useState("") const [_isPending, startTransition] = useTransition() const handleSearch = useCallback((text: string): void => { setSearchText(text) }, []) useEffect(() => { const handlePossibleIcons = (): void => { startTransition(() => { setPossibleIcons(findIconsInLibrary(searchText)) setIsLoading(false) }) } const debounceHandleSearch = setTimeout(handlePossibleIcons, 400) return () => { return clearTimeout(debounceHandleSearch) } }, [searchText]) const handleIconSelect = useCallback( (icon: string): void => { onIconSelect(icon) }, [onIconSelect], ) return ( Selected Icon: ) }