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,69 +6,59 @@ 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, };
const SearchField = ({ onChange, className, placeholder = 'Search...', large = true, noBorder = false }) => {
const [ searchTerm, setSearchTerm ] = useState('');
const resetTimer = () => {
clearTimeout(timer);
timer = null;
}; };
static defaultProps = { const searchTermChanged = (newSearchTerm, timeout = DEFAULT_SEARCH_INTERVAL) => {
className: '', setSearchTerm(newSearchTerm);
placeholder: 'Search...',
large: true,
noBorder: false,
};
state = { showClearBtn: false, searchTerm: '' };
timer = null;
searchTermChanged(searchTerm, timeout = DEFAULT_SEARCH_INTERVAL) {
this.setState({
showClearBtn: searchTerm !== '',
searchTerm,
});
const resetTimer = () => {
clearTimeout(this.timer);
this.timer = null;
};
resetTimer(); resetTimer();
this.timer = setTimeout(() => { timer = setTimeout(() => {
this.props.onChange(searchTerm); onChange(newSearchTerm);
resetTimer(); resetTimer();
}, timeout); }, timeout);
} };
render() { return (
const { className, placeholder, large, noBorder } = this.props; <div className={classNames('search-field', className)}>
<input
return ( type="text"
<div className={classNames('search-field', className)}> className={classNames('form-control search-field__input', {
<input 'form-control-lg': large,
type="text" 'search-field__input--no-border': noBorder,
className={classNames('form-control search-field__input', { })}
'form-control-lg': large, placeholder={placeholder}
'search-field__input--no-border': noBorder, value={searchTerm}
})} onChange={(e) => searchTermChanged(e.target.value)}
placeholder={placeholder} />
value={this.state.searchTerm} <FontAwesomeIcon icon={searchIcon} className="search-field__icon" />
onChange={(e) => this.searchTermChanged(e.target.value)} <div
/> className="close search-field__close"
<FontAwesomeIcon icon={searchIcon} className="search-field__icon" /> hidden={searchTerm === ''}
<div id="search-field__close"
className="close search-field__close" onClick={() => searchTermChanged('', 0)}
hidden={!this.state.showClearBtn} >
id="search-field__close" &times;
onClick={() => this.searchTermChanged('', 0)}
>
&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();
} }