Converted SearchField component into funcitonal component

This commit is contained in:
Alejandro Celaya 2020-04-05 16:16:55 +02:00
parent cb7062bb95
commit b79333393b
3 changed files with 53 additions and 58 deletions

View file

@ -1,4 +1,4 @@
import React from 'react'; import React, { useState } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faSearch as searchIcon } from '@fortawesome/free-solid-svg-icons'; import { faSearch as searchIcon } from '@fortawesome/free-solid-svg-icons';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
@ -6,46 +6,33 @@ import classNames from 'classnames';
import './SearchField.scss'; import './SearchField.scss';
const DEFAULT_SEARCH_INTERVAL = 500; const DEFAULT_SEARCH_INTERVAL = 500;
let timer;
export default class SearchField extends React.Component { const propTypes = {
static propTypes = {
onChange: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired,
className: PropTypes.string, className: PropTypes.string,
placeholder: PropTypes.string, placeholder: PropTypes.string,
large: PropTypes.bool, large: PropTypes.bool,
noBorder: PropTypes.bool, noBorder: PropTypes.bool,
}; };
static defaultProps = {
className: '',
placeholder: 'Search...',
large: true,
noBorder: false,
};
state = { showClearBtn: false, searchTerm: '' }; const SearchField = ({ onChange, className, placeholder = 'Search...', large = true, noBorder = false }) => {
timer = null; const [ searchTerm, setSearchTerm ] = useState('');
searchTermChanged(searchTerm, timeout = DEFAULT_SEARCH_INTERVAL) {
this.setState({
showClearBtn: searchTerm !== '',
searchTerm,
});
const resetTimer = () => { const resetTimer = () => {
clearTimeout(this.timer); clearTimeout(timer);
this.timer = null; timer = null;
}; };
const searchTermChanged = (newSearchTerm, timeout = DEFAULT_SEARCH_INTERVAL) => {
setSearchTerm(newSearchTerm);
resetTimer(); resetTimer();
this.timer = setTimeout(() => { timer = setTimeout(() => {
this.props.onChange(searchTerm); onChange(newSearchTerm);
resetTimer(); resetTimer();
}, timeout); }, timeout);
} };
render() {
const { className, placeholder, large, noBorder } = this.props;
return ( return (
<div className={classNames('search-field', className)}> <div className={classNames('search-field', className)}>
@ -56,19 +43,22 @@ export default class SearchField extends React.Component {
'search-field__input--no-border': noBorder, 'search-field__input--no-border': noBorder,
})} })}
placeholder={placeholder} placeholder={placeholder}
value={this.state.searchTerm} value={searchTerm}
onChange={(e) => this.searchTermChanged(e.target.value)} onChange={(e) => searchTermChanged(e.target.value)}
/> />
<FontAwesomeIcon icon={searchIcon} className="search-field__icon" /> <FontAwesomeIcon icon={searchIcon} className="search-field__icon" />
<div <div
className="close search-field__close" className="close search-field__close"
hidden={!this.state.showClearBtn} hidden={searchTerm === ''}
id="search-field__close" id="search-field__close"
onClick={() => this.searchTermChanged('', 0)} onClick={() => searchTermChanged('', 0)}
> >
&times; &times;
</div> </div>
</div> </div>
); );
} };
}
SearchField.propTypes = propTypes;
export default SearchField;

View file

@ -2,6 +2,10 @@
.search-field { .search-field {
position: relative; position: relative;
&:focus-within {
z-index: 1;
}
} }
.search-field__input.search-field__input { .search-field__input.search-field__input {

View file

@ -31,6 +31,7 @@
bottom: 0; bottom: 0;
margin-top: 34px; margin-top: 34px;
padding: .5rem; padding: .5rem;
@include sticky-cell(); @include sticky-cell();
} }