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)}
-        >
-          &times;
-        </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)}
+      >
+        &times;
       </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();
 }