import React, { useState, useEffect, useRef } from 'react' import PropTypes from 'prop-types' import Fuse from 'fuse.js' import InputAdornment from '@material-ui/core/InputAdornment' import TextField from '../../../../components/ui/text-field' import { usePrevious } from '../../../../hooks/usePrevious' const renderAdornment = () => ( ) export default function ListItemSearch ({ onSearch, error, listToSearch = [], fuseSearchKeys, searchPlaceholderText, defaultToAll, }) { const fuseRef = useRef() const [searchQuery, setSearchQuery] = useState('') const handleSearch = (newSearchQuery) => { setSearchQuery(newSearchQuery) const fuseSearchResult = fuseRef.current.search(newSearchQuery) onSearch({ searchQuery: newSearchQuery, results: defaultToAll && newSearchQuery === '' ? listToSearch : fuseSearchResult, }) } useEffect(() => { if (!fuseRef.current) { fuseRef.current = new Fuse(listToSearch, { shouldSort: true, threshold: 0.45, location: 0, distance: 100, maxPatternLength: 32, minMatchCharLength: 1, keys: fuseSearchKeys, }) } }, [fuseSearchKeys, listToSearch]) const previousListToSearch = usePrevious(listToSearch) || [] useEffect(() => { if (fuseRef.current && searchQuery && previousListToSearch !== listToSearch) { fuseRef.current.setCollection(listToSearch) const fuseSearchResult = fuseRef.current.search(searchQuery) onSearch({ searchQuery, results: fuseSearchResult }) } }, [listToSearch, searchQuery, onSearch, previousListToSearch]) return ( handleSearch(e.target.value)} error={error} fullWidth startAdornment={renderAdornment()} autoComplete="off" autoFocus /> ) } ListItemSearch.propTypes = { onSearch: PropTypes.func, error: PropTypes.string, listToSearch: PropTypes.array.isRequired, fuseSearchKeys: PropTypes.arrayOf(PropTypes.object).isRequired, searchPlaceholderText: PropTypes.string, defaultToAll: PropTypes.bool, }