import { library } from "@fortawesome/fontawesome-svg-core" import { fas } from "@fortawesome/free-solid-svg-icons" import React, { memo, useCallback, useEffect, useState, useTransition, } from "react" import { ScrollView, StyleSheet, View } from "react-native" import { Button, List, Modal, Portal, TextInput } from "react-native-paper" import { HabitIconList } from "./HabitIconList" export interface HabitIconSelectorModalProps { visible?: boolean value: string onDismiss: () => void onSelect: (icon: string) => void onPress: () => void } interface SearchInputProps { searchText: string handleSearch: (text: string) => void } library.add(fas) const iconNames = Object.keys(fas).map((key) => { return fas[key]?.iconName ?? "" }) const findIconsInLibrary = (icon: string): string[] => { return iconNames .filter((name, index, self) => { return name.includes(icon) && self.indexOf(name) === index }) .slice(0, 20) } const SearchInputWithoutMemo: React.FC = (props) => { const { searchText, handleSearch } = props return ( ) } const SearchInput = memo(SearchInputWithoutMemo) export const HabitIconSelectorModal: React.FC = ({ visible = false, value, onDismiss, onSelect, onPress, }) => { const [selectedIcon, setSelectedIcon] = useState() const [possibleIcons, setPossibleIcons] = useState([]) const [searchText, setSearchText] = useState(value) const [isPending, startTransition] = useTransition() const handleSearch = useCallback((text: string): void => { setSearchText(text) }, []) useEffect(() => { const delay = setTimeout(() => { startTransition(() => { setPossibleIcons(findIconsInLibrary(searchText)) }) }, 500) return () => { return clearTimeout(delay) } }, [searchText, isPending]) const handleIconSelect = useCallback( (icon: string): void => { setSelectedIcon(icon) onSelect(icon) }, [onSelect], ) return ( <> ) } const styles = StyleSheet.create({ modalContent: { backgroundColor: "white", padding: 20, margin: 20, borderRadius: 10, }, iconContainer: { flexDirection: "row", flexWrap: "wrap", justifyContent: "space-between", }, scrollView: { maxHeight: 10000, maxWidth: 5000, }, noResults: { marginTop: 20, alignItems: "center", }, })