shlink-web-client/src/utils/SearchField.tsx
2021-11-07 11:03:31 +01:00

61 lines
1.7 KiB
TypeScript

import { useState } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faSearch as searchIcon } from '@fortawesome/free-solid-svg-icons';
import classNames from 'classnames';
import './SearchField.scss';
const DEFAULT_SEARCH_INTERVAL = 500;
let timer: NodeJS.Timeout | null;
interface SearchFieldProps {
onChange: (value: string) => void;
className?: string;
large?: boolean;
noBorder?: boolean;
initialValue?: string;
}
const SearchField = ({ onChange, className, large = true, noBorder = false, initialValue = '' }: SearchFieldProps) => {
const [ searchTerm, setSearchTerm ] = useState(initialValue);
const resetTimer = () => {
timer && clearTimeout(timer);
timer = null;
};
const searchTermChanged = (newSearchTerm: string, timeout = DEFAULT_SEARCH_INTERVAL) => {
setSearchTerm(newSearchTerm);
resetTimer();
timer = setTimeout(() => {
onChange(newSearchTerm);
resetTimer();
}, timeout);
};
return (
<div className={classNames('search-field', className)}>
<input
type="text"
className={classNames('form-control search-field__input', {
'form-control-lg': large,
'search-field__input--no-border': noBorder,
})}
placeholder="Search..."
value={searchTerm}
onChange={(e) => searchTermChanged(e.target.value)}
/>
<FontAwesomeIcon icon={searchIcon} className="search-field__icon" />
<div
className="close search-field__close"
hidden={searchTerm === ''}
id="search-field__close"
onClick={() => searchTermChanged('', 0)}
>
&times;
</div>
</div>
);
};
export default SearchField;