From b79333393b3de45a56ecbb60b2db63027d326f1b Mon Sep 17 00:00:00 2001 From: Alejandro Celaya <alejandro@alejandrocelaya.com> Date: Sun, 5 Apr 2020 16:16:55 +0200 Subject: [PATCH] Converted SearchField component into funcitonal component --- src/utils/SearchField.js | 106 ++++++++++++++++-------------------- src/utils/SearchField.scss | 4 ++ src/visits/VisitsTable.scss | 1 + 3 files changed, 53 insertions(+), 58 deletions(-) diff --git a/src/utils/SearchField.js b/src/utils/SearchField.js index bb3f6026..2b460fa8 100644 --- a/src/utils/SearchField.js +++ b/src/utils/SearchField.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faSearch as searchIcon } from '@fortawesome/free-solid-svg-icons'; import PropTypes from 'prop-types'; @@ -6,69 +6,59 @@ import classNames from 'classnames'; import './SearchField.scss'; const DEFAULT_SEARCH_INTERVAL = 500; +let timer; -export default class SearchField extends React.Component { - static propTypes = { - onChange: PropTypes.func.isRequired, - className: PropTypes.string, - placeholder: PropTypes.string, - large: PropTypes.bool, - noBorder: PropTypes.bool, +const propTypes = { + onChange: PropTypes.func.isRequired, + className: PropTypes.string, + placeholder: PropTypes.string, + large: 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 = { - className: '', - 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; - }; + const searchTermChanged = (newSearchTerm, timeout = DEFAULT_SEARCH_INTERVAL) => { + setSearchTerm(newSearchTerm); resetTimer(); - this.timer = setTimeout(() => { - this.props.onChange(searchTerm); + timer = setTimeout(() => { + onChange(newSearchTerm); resetTimer(); }, timeout); - } + }; - render() { - const { className, placeholder, large, noBorder } = this.props; - - 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={placeholder} - value={this.state.searchTerm} - onChange={(e) => this.searchTermChanged(e.target.value)} - /> - <FontAwesomeIcon icon={searchIcon} className="search-field__icon" /> - <div - className="close search-field__close" - hidden={!this.state.showClearBtn} - id="search-field__close" - onClick={() => this.searchTermChanged('', 0)} - > - × - </div> + 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={placeholder} + 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)} + > + × </div> - ); - } -} + </div> + ); +}; + +SearchField.propTypes = propTypes; + +export default SearchField; diff --git a/src/utils/SearchField.scss b/src/utils/SearchField.scss index 7ba46422..5877b9ce 100644 --- a/src/utils/SearchField.scss +++ b/src/utils/SearchField.scss @@ -2,6 +2,10 @@ .search-field { position: relative; + + &:focus-within { + z-index: 1; + } } .search-field__input.search-field__input { diff --git a/src/visits/VisitsTable.scss b/src/visits/VisitsTable.scss index 42b2e550..b1365b98 100644 --- a/src/visits/VisitsTable.scss +++ b/src/visits/VisitsTable.scss @@ -31,6 +31,7 @@ bottom: 0; margin-top: 34px; padding: .5rem; + @include sticky-cell(); }