Repository: gregnb/mui-datatables
Pull request #1053 (2019-11-06 17:45:28)

Reset `activeIcon` to `null` when Search button is clicked while search is already open
Currently, clicking the Search button while search is already open will close the search bar, but will not revert the `activeIcon` state to `null`.

This PR will toggle the click method of the Search button based on the `showSearch` state property so that clicking the button while search is open will close the search bar and revert the icon **as long as there is no search query entered**.

When there is a search query, the icon will remain in its active state until the query is cleared.

## Testing
### Without Search Query
1. Click Search Icon
    * Query area appears
    * Search Icon gains active state
2. Click Search Icon Again
    * Query area closes
    * Search Icon looses active state
### With Search Query
1. Click Search Icon
    * Query area appears
    * Search Icon gains active state
2. Enter search query
3. Click Search Icon Again
    * Query area remains open
    * Search Icon retains active state
4. Click Filter Icon
    * Query area remains open
    * Search Icon retains active state
    * Filter Icon gains active state
5. Click outside Filter Icon, closing popover
    * Query area remains open
    * Search Icon retains active state
    * Filter Icon looses active state

coveralls: 
[![Coverage Status](https://coveralls.io/builds/26811488/badge)](https://coveralls.io/builds/26811488)

Coverage increased (+0.4%) to 77.742% when pulling **82677ffcf00efbfda469c1a65fc36d8792d63552 on pgoforth:bugfix/activeIcon-for-search-not-reset-on-toggle** into **2d37c383beeebb039fae2b6e0b531ddb7959e2ce on gregnb:master**.


Patch:
diff --git a/package-lock.json b/package-lock.json
index 498d1cc..b94945f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "mui-datatables",
-  "version": "2.13.2",
+  "version": "2.13.3",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
diff --git a/package.json b/package.json
index 9fda7df..ece96d9 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "mui-datatables",
-  "version": "2.13.2",
+  "version": "2.13.3",
   "description": "Datatables for React using Material-UI",
   "main": "dist/index.js",
   "files": [
diff --git a/src/MUIDataTable.js b/src/MUIDataTable.js
index 38a5d34..60af68f 100644
--- a/src/MUIDataTable.js
+++ b/src/MUIDataTable.js
@@ -16,7 +16,7 @@ import TableHead from './components/TableHead';
 import TableResize from './components/TableResize';
 import TableToolbar from './components/TableToolbar';
 import TableToolbarSelect from './components/TableToolbarSelect';
-import textLabels from './textLabels';
+import getTextLabels from './textLabels';
 import { buildMap, getCollatorComparator, sortCompare, getPageValue } from './utils';
 
 const defaultTableStyles = theme => ({
@@ -138,7 +138,7 @@ class MUIDataTable extends React.Component {
     options: PropTypes.shape({
       responsive: PropTypes.oneOf(['stacked', 'scrollMaxHeight', 'scrollFullHeight']),
       filterType: PropTypes.oneOf(['dropdown', 'checkbox', 'multiselect', 'textField', 'custom']),
-      textLabels: PropTypes.object,
+      getTextLabels: PropTypes.func,
       pagination: PropTypes.bool,
       expandableRows: PropTypes.bool,
       expandableRowsOnClick: PropTypes.bool,
@@ -297,7 +297,7 @@ class MUIDataTable extends React.Component {
     responsive: 'stacked',
     filterType: 'dropdown',
     pagination: true,
-    textLabels,
+    textLabels: getTextLabels(),
     serverSideFilterList: [],
     expandableRows: false,
     expandableRowsOnClick: false,
diff --git a/src/components/TableHeadCell.js b/src/components/TableHeadCell.js
index fe99cb0..75e79fb 100644
--- a/src/components/TableHeadCell.js
+++ b/src/components/TableHeadCell.js
@@ -83,11 +83,6 @@ class TableHeadCell extends React.Component {
     column: PropTypes.object,
   };
 
-  state = {
-    isSortTooltipOpen: false,
-    isHintTooltipOpen: false,
-  };
-
   handleKeyboardSortinput = e => {
     if (e.key === 'Enter') {
       this.props.toggleSort(this.props.index);
@@ -101,8 +96,6 @@ class TableHeadCell extends React.Component {
   };
 
   render() {
-    const { isSortTooltipOpen, isHintTooltipOpen } = this.state;
-
     const { children, classes, options, sortDirection, sort, hint, print, column, cellHeaderProps = {} } = this.props;
     const { className, ...otherProps } = cellHeaderProps;
 
@@ -136,61 +129,45 @@ class TableHeadCell extends React.Component {
     return (
       <TableCell className={cellClass} scope={'col'} sortDirection={ariaSortDirection} {...otherProps}>
         {options.sort && sort ? (
-          <Tooltip
-            title={
-              options.textLabels.body.columnHeaderTooltip
-                ? options.textLabels.body.columnHeaderTooltip(column)
-                : options.textLabels.body.toolTip
-            }
-            placement={'bottom-start'}
-            classes={{
-              tooltip: classes.tooltip,
-            }}
-            enterDelay={300}
-            classes={{ popper: classes.mypopper }}
-            open={isSortTooltipOpen}
-            onOpen={() =>
-              isHintTooltipOpen
-                ? this.setState({ isSortTooltipOpen: false })
-                : this.setState({ isSortTooltipOpen: true })
-            }
-            onClose={() => this.setState({ isSortTooltipOpen: false })}>
-            <span
-              role="button"
-              onKeyUp={this.handleKeyboardSortinput}
-              onClick={this.handleSortClick}
-              className={classes.toolButton}
-              tabIndex={0}>
-              <div
-                className={classNames({
-                  [classes.data]: true,
-                  [classes.sortActive]: sortActive,
-                })}>
-                {children}
-              </div>
+          <span
+            role="button"
+            onKeyUp={this.handleKeyboardSortinput}
+            onClick={this.handleSortClick}
+            className={classes.toolButton}
+            tabIndex={0}>
+            <Tooltip
+              title={
+                options.textLabels.body.columnHeaderTooltip
+                  ? options.textLabels.body.columnHeaderTooltip(column)
+                  : options.textLabels.body.toolTip
+              }
+              placement={'bottom-start'}
+              classes={{
+                tooltip: classes.tooltip,
+              }}
+              classes={{ popper: classes.mypopper }}>
               <div className={classes.sortAction}>
-                <TableSortLabel {...sortLabelProps} />
-                {hint && (
-                  <Tooltip
-                    title={hint}
-                    placement={'bottom-end'}
-                    classes={{
-                      tooltip: classes.tooltip,
-                    }}
-                    enterDelay={300}
-                    classes={{ popper: classes.mypopper }}
-                    open={isHintTooltipOpen}
-                    onOpen={() => this.setState({ isSortTooltipOpen: false, isHintTooltipOpen: true })}
-                    onClose={() => this.setState({ isHintTooltipOpen: false })}>
-                    <HelpIcon
-                      className={!sortActive ? classes.hintIconAlone : classes.hintIconWithSortIcon}
-                      fontSize="small"
-                    />
-                  </Tooltip>
-                )}
+                <div
+                  className={classNames({
+                    [classes.data]: true,
+                    [classes.sortActive]: sortActive,
+                  })}>
+                  {children}
+                </div>
+                <div className={classes.sortAction}>
+                  <TableSortLabel {...sortLabelProps} />
+                </div>
               </div>
-            </span>
-          </Tooltip>
+            </Tooltip>
+            {hint && (
+              <Tooltip title={hint}>
+                <HelpIcon
+                  className={!sortActive ? classes.hintIconAlone : classes.hintIconWithSortIcon}
+                  fontSize="small"
+                />
+              </Tooltip>
+            )}
+          </span>
         ) : (
           <div className={hint ? classes.sortAction : null}>
             {children}
diff --git a/src/components/TableToolbar.js b/src/components/TableToolbar.js
index c26be05..99ccbfc 100644
--- a/src/components/TableToolbar.js
+++ b/src/components/TableToolbar.js
@@ -178,7 +178,12 @@ class TableToolbar extends React.Component {
   };
 
   getActiveIcon = (styles, iconName) => {
-    return this.state.iconActive !== iconName ? styles.icon : styles.iconActive;
+    let isActive = this.state.iconActive === iconName;
+    if (iconName === 'search') {
+      const { showSearch, searchText } = this.state;
+      isActive = isActive || showSearch || searchText;
+    }
+    return isActive ? styles.iconActive : styles.icon;
   };
 
   showSearch = () => {
@@ -208,6 +213,15 @@ class TableToolbar extends React.Component {
     this.props.searchTextUpdate(value);
   };
 
+  handleSearchIconClick = () => {
+    const { showSearch, searchText } = this.state;
+    if (showSearch && !searchText) {
+      this.hideSearch();
+    } else {
+      this.setActiveIcon('search');
+    }
+  }
+
   render() {
     const {
       data,
@@ -258,7 +272,7 @@ class TableToolbar extends React.Component {
                 data-testid={search + '-iconButton'}
                 buttonRef={el => (this.searchButton = el)}
                 classes={{ root: this.getActiveIcon(classes, 'search') }}
-                onClick={this.setActiveIcon.bind(null, 'search')}>
+                onClick={this.handleSearchIconClick}>
                 <SearchIcon />
               </IconButton>
             </Tooltip>
diff --git a/src/textLabels.js b/src/textLabels.js
index a2df615..54f9ca1 100644
--- a/src/textLabels.js
+++ b/src/textLabels.js
@@ -1,7 +1,7 @@
 /*
  * Default text labels.
  */
-const textLabels = {
+const getTextLabels = () => ({
   body: {
     noMatch: 'Sorry, no matching records found',
     toolTip: 'Sort',
@@ -33,6 +33,6 @@ const textLabels = {
     delete: 'Delete',
     deleteAria: 'Delete Selected Rows',
   },
-};
+});
 
-export default textLabels;
+export default getTextLabels;


Test patch:
diff --git a/test/MUIDataTable.test.js b/test/MUIDataTable.test.js
index 53fc065..4a3f927 100644
--- a/test/MUIDataTable.test.js
+++ b/test/MUIDataTable.test.js
@@ -8,7 +8,7 @@ import TableFilterList from '../src/components/TableFilterList';
 import TablePagination from '../src/components/TablePagination';
 import TableToolbar from '../src/components/TableToolbar';
 import TableToolbarSelect from '../src/components/TableToolbarSelect';
-import textLabels from '../src/textLabels';
+import getTextLabels from '../src/textLabels';
 import Chip from '@material-ui/core/Chip';
 import Cities from '../examples/component/cities';
 import { getCollatorComparator } from '../src/utils';
@@ -512,7 +512,7 @@ describe('<MUIDataTable />', function() {
   it('should correctly build internal rowsPerPage when provided in options', () => {
     const options = {
       rowsPerPage: 20,
-      textLabels,
+      textLabels: getTextLabels(),
     };
 
     const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} options={options} />);
@@ -875,7 +875,7 @@ describe('<MUIDataTable />', function() {
   it('should properly set searchText when hiding the search bar', () => {
     const options = {
       rowsPerPage: 1,
-      textLabels,
+      textLabels: getTextLabels(),
     };
     const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} />);
     const table = shallowWrapper.dive();
@@ -905,7 +905,7 @@ describe('<MUIDataTable />', function() {
   it('should not change page when hiding the search bar', () => {
     const options = {
       rowsPerPage: 1,
-      textLabels,
+      textLabels: getTextLabels(),
     };
     const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} options={options} />);
     const table = shallowWrapper.dive();
diff --git a/test/MUIDataTableBody.test.js b/test/MUIDataTableBody.test.js
index 6afeb23..054bca2 100644
--- a/test/MUIDataTableBody.test.js
+++ b/test/MUIDataTableBody.test.js
@@ -2,7 +2,7 @@ import React from 'react';
 import { spy, stub } from 'sinon';
 import { mount, shallow } from 'enzyme';
 import { assert, expect, should } from 'chai';
-import textLabels from '../src/textLabels';
+import getTextLabels from '../src/textLabels';
 import TableBody from '../src/components/TableBody';
 import TableSelectCell from '../src/components/TableSelectCell';
 import Checkbox from '@material-ui/core/Checkbox';
@@ -67,7 +67,7 @@ describe('<TableBody />', function() {
   });
 
   it('should render a table body with no records if no data provided', () => {
-    const options = { selectableRows: false, textLabels };
+    const options = { selectableRows: false, textLabels: getTextLabels() };
     const selectRowUpdate = () => {};
     const toggleExpandRow = () => {};
 
diff --git a/test/MUIDataTableFilter.test.js b/test/MUIDataTableFilter.test.js
index c5b3cb6..5104738 100644
--- a/test/MUIDataTableFilter.test.js
+++ b/test/MUIDataTableFilter.test.js
@@ -7,7 +7,7 @@ import { mount, shallow } from 'enzyme';
 import React from 'react';
 import { spy } from 'sinon';
 import TableFilter from '../src/components/TableFilter';
-import textLabels from '../src/textLabels';
+import getTextLabels from '../src/textLabels';
 
 describe('<TableFilter />', function() {
   let data;
@@ -38,7 +38,7 @@ describe('<TableFilter />', function() {
   });
 
   it('should render label as filter name', () => {
-    const options = { filterType: 'checkbox', textLabels };
+    const options = { filterType: 'checkbox', textLabels: getTextLabels() };
     const filterList = [[], [], [], []];
     const shallowWrapper = mount(
       <TableFilter columns={columns} filterData={filterData} filterList={filterList} options={options} />,
@@ -51,7 +51,7 @@ describe('<TableFilter />', function() {
   });
 
   it("should render data table filter view with checkboxes if filterType = 'checkbox'", () => {
-    const options = { filterType: 'checkbox', textLabels };
+    const options = { filterType: 'checkbox', textLabels: getTextLabels() };
     const filterList = [[], [], [], []];
     const shallowWrapper = mount(
       <TableFilter columns={columns} filterData={filterData} filterList={filterList} options={options} />,
@@ -62,7 +62,7 @@ describe('<TableFilter />', function() {
   });
 
   it('should render data table filter view with no checkboxes if filter=false for each column', () => {
-    const options = { filterType: 'checkbox', textLabels };
+    const options = { filterType: 'checkbox', textLabels: getTextLabels() };
     const filterList = [[], [], [], []];
     columns = columns.map(item => (item.filter = false));
 
@@ -75,7 +75,7 @@ describe('<TableFilter />', function() {
   });
 
   it("should render data table filter view with selects if filterType = 'select'", () => {
-    const options = { filterType: 'select', textLabels };
+    const options = { filterType: 'select', textLabels: getTextLabels() };
     const filterList = [['Joe James'], [], [], []];
 
     const mountWrapper = mount(
@@ -87,7 +87,7 @@ describe('<TableFilter />', function() {
   });
 
   it('should render data table filter view no selects if filter=false for each column', () => {
-    const options = { filterType: 'select', textLabels };
+    const options = { filterType: 'select', textLabels: getTextLabels() };
     const filterList = [['Joe James'], [], [], []];
     columns = columns.map(item => (item.filter = false));
 
@@ -100,7 +100,7 @@ describe('<TableFilter />', function() {
   });
 
   it("should render data table filter view with checkbox selects if filterType = 'multiselect'", () => {
-    const options = { filterType: 'multiselect', textLabels };
+    const options = { filterType: 'multiselect', textLabels: getTextLabels() };
     const filterList = [['Joe James', 'John Walsh'], [], [], []];
 
     const mountWrapper = mount(
@@ -114,7 +114,7 @@ describe('<TableFilter />', function() {
   it("should data table custom filter view with if filterType = 'custom' and a valid display filterOption is provided", () => {
     const options = {
       filterType: 'custom',
-      textLabels,
+      textLabels: getTextLabels(),
       filterOptions: {
         names: [],
         logic(city, filters) {
@@ -137,7 +137,7 @@ describe('<TableFilter />', function() {
   });
 
   it("should render column.label as filter label if filterType = 'textField'", () => {
-    const options = { filterType: 'textField', textLabels };
+    const options = { filterType: 'textField', textLabels: getTextLabels() };
     const filterList = [[], [], [], []];
     const shallowWrapper = mount(
       <TableFilter columns={columns} filterData={filterData} filterList={filterList} options={options} />,
@@ -150,7 +150,7 @@ describe('<TableFilter />', function() {
   });
 
   it("should data table filter view with TextFields if filterType = 'textfield'", () => {
-    const options = { filterType: 'textField', textLabels };
+    const options = { filterType: 'textField', textLabels: getTextLabels() };
     const filterList = [[], [], [], []];
     const shallowWrapper = mount(
       <TableFilter columns={columns} filterData={filterData} filterList={filterList} options={options} />,
@@ -161,7 +161,7 @@ describe('<TableFilter />', function() {
   });
 
   it("should data table filter view with no TextFields if filter=false when filterType = 'textField'", () => {
-    const options = { filterType: 'textField', textLabels };
+    const options = { filterType: 'textField', textLabels: getTextLabels() };
     const filterList = [[], [], [], []];
     columns = columns.map(item => (item.filter = false));
 
@@ -174,7 +174,7 @@ describe('<TableFilter />', function() {
   });
 
   it("should data table filter view with checkboxes if column.filterType = 'checkbox' irrespective of global filterType value", () => {
-    const options = { filterType: 'textField', textLabels };
+    const options = { filterType: 'textField', textLabels: getTextLabels() };
     const filterList = [[], [], [], []];
     columns.forEach(item => (item.filterType = 'checkbox'));
 
@@ -188,7 +188,7 @@ describe('<TableFilter />', function() {
 
   it('should render a filter dialog with custom footer when customFooter is provided', () => {
     const CustomFooter = () => <div id="custom-footer">customFooter</div>;
-    const options = { textLabels };
+    const options = { textLabels: getTextLabels() };
     const filterList = [[], [], [], []];
     const onFilterUpdate = spy();
 
@@ -208,7 +208,7 @@ describe('<TableFilter />', function() {
   });
 
   it('should trigger onFilterUpdate prop callback when calling method handleCheckboxChange', () => {
-    const options = { filterType: 'checkbox', textLabels };
+    const options = { filterType: 'checkbox', textLabels: getTextLabels() };
     const filterList = [[], [], [], []];
     const onFilterUpdate = spy();
 
@@ -229,7 +229,7 @@ describe('<TableFilter />', function() {
   });
 
   it('should trigger onFilterUpdate prop callback when calling method handleDropdownChange', () => {
-    const options = { filterType: 'select', textLabels };
+    const options = { filterType: 'select', textLabels: getTextLabels() };
     const filterList = [[], [], [], []];
     const onFilterUpdate = spy();
 
@@ -260,7 +260,7 @@ describe('<TableFilter />', function() {
   });
 
   it('should trigger onFilterUpdate prop callback when calling method handleMultiselectChange', () => {
-    const options = { filterType: 'multiselect', textLabels };
+    const options = { filterType: 'multiselect', textLabels: getTextLabels() };
     const filterList = [[], [], [], []];
     const onFilterUpdate = spy();
 
@@ -292,7 +292,7 @@ describe('<TableFilter />', function() {
   });
 
   it('should trigger onFilterUpdate prop callback when calling method handleTextFieldChange', () => {
-    const options = { filterType: 'textField', textLabels };
+    const options = { filterType: 'textField', textLabels: getTextLabels() };
     const filterList = [[], [], [], []];
     const onFilterUpdate = spy();
 
diff --git a/test/MUIDataTableHeadCell.test.js b/test/MUIDataTableHeadCell.test.js
index 2924ebc..340f7de 100644
--- a/test/MUIDataTableHeadCell.test.js
+++ b/test/MUIDataTableHeadCell.test.js
@@ -2,7 +2,7 @@ import React from 'react';
 import { spy, stub } from 'sinon';
 import { mount, shallow } from 'enzyme';
 import { assert, expect, should } from 'chai';
-import textLabels from '../src/textLabels';
+import getTextLabels from '../src/textLabels';
 import TableHeadCell from '../src/components/TableHeadCell';
 import TableCell from '@material-ui/core/TableCell';
 import TableSortLabel from '@material-ui/core/TableSortLabel';
@@ -18,7 +18,7 @@ describe('<TableHeadCell />', function() {
   });
 
   it('should add custom props to header cell if "setCellHeaderProps" provided', () => {
-    const options = { sort: true, textLabels };
+    const options = { sort: true, textLabels: getTextLabels() };
     const toggleSort = () => {};
     const setCellHeaderProps = { myProp: 'test', className: 'testClass' };
     const selectRowUpdate = stub();
@@ -45,7 +45,7 @@ describe('<TableHeadCell />', function() {
   });
 
   it('should render a table head cell with sort label when options.sort = true provided', () => {
-    const options = { sort: true, textLabels };
+    const options = { sort: true, textLabels: getTextLabels() };
     const toggleSort = () => {};
 
     const shallowWrapper = shallow(
@@ -59,7 +59,7 @@ describe('<TableHeadCell />', function() {
   });
 
   it('should render a table head cell without sort label when options.sort = false provided', () => {
-    const options = { sort: false, textLabels };
+    const options = { sort: false, textLabels: getTextLabels() };
     const toggleSort = () => {};
 
     const shallowWrapper = shallow(
@@ -73,7 +73,7 @@ describe('<TableHeadCell />', function() {
   });
 
   it('should render a table help icon when hint provided', () => {
-    const options = { sort: true, textLabels };
+    const options = { sort: true, textLabels: getTextLabels() };
 
     const shallowWrapper = shallow(
       <TableHeadCell options={options} hint={'hint text'} classes={classes}>
@@ -86,7 +86,7 @@ describe('<TableHeadCell />', function() {
   });
 
   it('should render a table head cell without custom tooltip when hint provided', () => {
-    const options = { sort: true, textLabels };
+    const options = { sort: true, textLabels: getTextLabels() };
 
     const shallowWrapper = shallow(
       <TableHeadCell options={options} classes={classes}>
@@ -99,7 +99,7 @@ describe('<TableHeadCell />', function() {
   });
 
   it('should trigger toggleSort prop callback when calling method handleSortClick', () => {
-    const options = { sort: true, textLabels };
+    const options = { sort: true, textLabels: getTextLabels() };
     const toggleSort = spy();
 
     const shallowWrapper = shallow(
diff --git a/test/MUIDataTablePagination.test.js b/test/MUIDataTablePagination.test.js
index 71719c1..5e434a3 100644
--- a/test/MUIDataTablePagination.test.js
+++ b/test/MUIDataTablePagination.test.js
@@ -5,7 +5,7 @@ import { assert, expect, should } from 'chai';
 import TableRow from '@material-ui/core/TableRow';
 import TableFooter from '@material-ui/core/TableFooter';
 import MuiTablePagination from '@material-ui/core/TablePagination';
-import textLabels from '../src/textLabels';
+import getTextLabels from '../src/textLabels';
 import TablePagination from '../src/components/TablePagination';
 
 describe('<TablePagination />', function() {
@@ -14,7 +14,7 @@ describe('<TablePagination />', function() {
   before(() => {
     options = {
       rowsPerPageOptions: [5, 10, 15],
-      textLabels,
+      textLabels: getTextLabels(),
     };
   });
 
diff --git a/test/MUIDataTableSearch.test.js b/test/MUIDataTableSearch.test.js
index e974bec..e16e968 100644
--- a/test/MUIDataTableSearch.test.js
+++ b/test/MUIDataTableSearch.test.js
@@ -5,11 +5,11 @@ import { mount, shallow } from 'enzyme';
 import { assert, expect, should } from 'chai';
 import TextField from '@material-ui/core/TextField';
 import TableSearch from '../src/components/TableSearch';
-import textLabels from '../src/textLabels';
+import getTextLabels from '../src/textLabels';
 
 describe('<TableSearch />', function() {
   it('should render a search bar', () => {
-    const options = { textLabels };
+    const options = { textLabels: getTextLabels() };
     const onSearch = () => {};
     const onHide = () => {};
 
@@ -20,7 +20,7 @@ describe('<TableSearch />', function() {
   });
 
   it('should render a search bar with text initialized', () => {
-    const options = { textLabels };
+    const options = { textLabels: getTextLabels() };
     const onSearch = () => {};
     const onHide = () => {};
 
@@ -33,7 +33,7 @@ describe('<TableSearch />', function() {
   });
 
   it('should change search bar text when searchText changes', () => {
-    const options = { textLabels };
+    const options = { textLabels: getTextLabels() };
     const onSearch = () => {};
     const onHide = () => {};
 
@@ -46,7 +46,7 @@ describe('<TableSearch />', function() {
   });
 
   it('should render a search bar with placeholder when searchPlaceholder is set', () => {
-    const options = { textLabels, searchPlaceholder: 'TestingPlaceholder' };
+    const options = { textLabels: getTextLabels(), searchPlaceholder: 'TestingPlaceholder' };
     const onSearch = () => {};
     const onHide = () => {};
 
@@ -57,7 +57,7 @@ describe('<TableSearch />', function() {
   });
 
   it('should trigger handleTextChange prop callback when calling method handleTextChange', () => {
-    const options = { onSearchChange: () => true, textLabels };
+    const options = { onSearchChange: () => true, textLabels: getTextLabels() };
     const onSearch = spy();
     const onHide = () => {};
 
@@ -70,7 +70,7 @@ describe('<TableSearch />', function() {
   });
 
   it('should hide the search bar when hitting the ESCAPE key', () => {
-    const options = { textLabels };
+    const options = { textLabels: getTextLabels() };
     const onHide = spy();
 
     const mountWrapper = mount(<TableSearch onHide={onHide} options={options} />, { attachTo: document.body });
@@ -80,7 +80,7 @@ describe('<TableSearch />', function() {
   });
 
   it('should hide not hide search bar when entering anything but the ESCAPE key', () => {
-    const options = { textLabels };
+    const options = { textLabels: getTextLabels() };
     const onHide = spy();
 
     const mountWrapper = mount(<TableSearch onHide={onHide} options={options} />, { attachTo: document.body });
diff --git a/test/MUIDataTableToolbar.test.js b/test/MUIDataTableToolbar.test.js
index 301dff1..9cdaf62 100644
--- a/test/MUIDataTableToolbar.test.js
+++ b/test/MUIDataTableToolbar.test.js
@@ -10,7 +10,7 @@ import React from 'react';
 import { spy } from 'sinon';
 import TableSearch from '../src/components/TableSearch';
 import TableToolbar from '../src/components/TableToolbar';
-import textLabels from '../src/textLabels';
+import getTextLabels from '../src/textLabels';
 
 describe('<TableToolbar />', function() {
   let data;
@@ -25,7 +25,7 @@ describe('<TableToolbar />', function() {
       search: true,
       filter: true,
       viewColumns: true,
-      textLabels,
+      textLabels: getTextLabels(),
       downloadOptions: {
         separator: ',',
         filename: 'tableDownload.csv',
@@ -193,6 +193,75 @@ describe('<TableToolbar />', function() {
     assert.strictEqual(actualResult.length, 0);
   });
 
+  it('should hide search when search icon is clicked while search is open without content', () => {
+    const searchTextUpdate = () => {};
+    const shallowWrapper = shallow(
+      <TableToolbar
+        searchClose={() => {}}
+        searchTextUpdate={searchTextUpdate}
+        columns={columns}
+        data={data}
+        options={options}
+        setTableAction={setTableAction}
+      />,
+    ).dive();
+    const instance = shallowWrapper.instance();
+    instance.searchButton = {
+      focus: () => {},
+    };
+
+    // click search button to display search
+    shallowWrapper.find('[data-testid="Search-iconButton"]').simulate('click');
+    shallowWrapper.update();
+
+    assert.strictEqual(shallowWrapper.state('iconActive'), 'search');
+    let actualResult = shallowWrapper.find(TableSearch);
+    assert.strictEqual(actualResult.length, 1);
+
+    // now click search button again and test
+    shallowWrapper.find('[data-testid="Search-iconButton"]').simulate('click');
+    shallowWrapper.update();
+
+    assert.strictEqual(shallowWrapper.state('iconActive'), null);
+    actualResult = shallowWrapper.find(TableSearch);
+    assert.strictEqual(actualResult.length, 0);
+  });
+
+  it('should not hide search when search icon is clicked while search is open with content', () => {
+    const searchTextUpdate = () => {};
+    const shallowWrapper = shallow(
+      <TableToolbar
+        searchClose={() => {}}
+        searchTextUpdate={searchTextUpdate}
+        columns={columns}
+        data={data}
+        options={options}
+        setTableAction={setTableAction}
+      />,
+    ).dive();
+    const instance = shallowWrapper.instance();
+    instance.searchButton = {
+      focus: () => {},
+    };
+
+    // click search button to display search
+    shallowWrapper.find('[data-testid="Search-iconButton"]').simulate('click');
+    shallowWrapper.update();
+
+    assert.strictEqual(shallowWrapper.state('iconActive'), 'search');
+    let actualResult = shallowWrapper.find(TableSearch);
+    assert.strictEqual(actualResult.length, 1);
+
+    // now set searchText and click search button again and test
+    shallowWrapper.setState({ searchText: 'fakeSearchText'});
+    shallowWrapper.find('[data-testid="Search-iconButton"]').simulate('click');
+    shallowWrapper.update();
+
+    assert.strictEqual(shallowWrapper.state('iconActive'), 'search');
+    actualResult = shallowWrapper.find(TableSearch);
+    assert.strictEqual(actualResult.length, 1);
+  });
+
   it('should call onFilterDialogOpen when opening filters via toolbar', () => {
     const onFilterDialogOpen = spy();
     const newOptions = { ...options, onFilterDialogOpen };
@@ -236,6 +305,26 @@ describe('<TableToolbar />', function() {
     assert.strictEqual(state.iconActive, 'filter');
   });
 
+  it('should render search icon as active if option.searchOpen = true', () => {
+    const newOptions = { ...options, search: true, searchOpen: true };
+    const shallowWrapper = shallow(
+      <TableToolbar columns={columns} data={data} options={newOptions} setTableAction={setTableAction} />,
+    ).dive();
+    const actualResult = shallowWrapper.find('[data-testid="Search-iconButton"]');
+    assert.strictEqual(actualResult.prop('classes').root.indexOf('MUIDataTableToolbar-iconActive-'), 0);
+
+  });
+
+  it('should render search icon as active if option.searchText = some_text', () => {
+    const newOptions = { ...options, search: true, searchText: 'searchText' };
+    const shallowWrapper = shallow(
+      <TableToolbar columns={columns} data={data} options={newOptions} setTableAction={setTableAction} />,
+    ).dive();
+    const actualResult = shallowWrapper.find('[data-testid="Search-iconButton"]');
+    assert.strictEqual(actualResult.prop('classes').root.indexOf('MUIDataTableToolbar-iconActive-'), 0);
+
+  });
+
   it('should download CSV when calling method handleCSVDownload', () => {
     const shallowWrapper = shallow(
       <TableToolbar
diff --git a/test/MUIDataTableToolbarSelect.test.js b/test/MUIDataTableToolbarSelect.test.js
index cafccb4..fc15c15 100644
--- a/test/MUIDataTableToolbarSelect.test.js
+++ b/test/MUIDataTableToolbarSelect.test.js
@@ -4,7 +4,7 @@ import { mount, shallow } from 'enzyme';
 import { assert, expect, should } from 'chai';
 import DeleteIcon from '@material-ui/icons/Delete';
 import TableToolbarSelect from '../src/components/TableToolbarSelect';
-import textLabels from '../src/textLabels';
+import getTextLabels from '../src/textLabels';
 
 describe('<TableToolbarSelect />', function() {
   before(() => {});
@@ -12,7 +12,11 @@ describe('<TableToolbarSelect />', function() {
   it('should render table toolbar select', () => {
     const onRowsDelete = () => {};
     const mountWrapper = mount(
-      <TableToolbarSelect options={{ textLabels }} selectedRows={{ data: [1] }} onRowsDelete={onRowsDelete} />,
+      <TableToolbarSelect
+        options={{ textLabels: getTextLabels() }}
+        selectedRows={{ data: [1] }}
+        onRowsDelete={onRowsDelete}
+      />,
     );
 
     const actualResult = mountWrapper.find(DeleteIcon);
@@ -27,7 +31,7 @@ describe('<TableToolbarSelect />', function() {
 
     const mountWrapper = mount(
       <TableToolbarSelect
-        options={{ textLabels, customToolbarSelect }}
+        options={{ textLabels: getTextLabels(), customToolbarSelect }}
         selectedRows={selectedRows}
         onRowsDelete={onRowsDelete}
         displayData={displayData}
@@ -62,7 +66,7 @@ describe('<TableToolbarSelect />', function() {
 
     const mountWrapper = mount(
       <TableToolbarSelect
-        options={{ textLabels, customToolbarSelect }}
+        options={{ textLabels: getTextLabels(), customToolbarSelect }}
         selectedRows={selectedRows}
         onRowsDelete={onRowsDelete}
         displayData={displayData}
@@ -82,7 +86,7 @@ describe('<TableToolbarSelect />', function() {
 
     const mountWrapper = mount(
       <TableToolbarSelect
-        options={{ textLabels, customToolbarSelect }}
+        options={{ textLabels: getTextLabels(), customToolbarSelect }}
         selectedRows={selectedRows}
         onRowsDelete={onRowsDelete}
         displayData={displayData}
diff --git a/test/MUIDataTableViewCol.test.js b/test/MUIDataTableViewCol.test.js
index 8eaf50d..70b775d 100644
--- a/test/MUIDataTableViewCol.test.js
+++ b/test/MUIDataTableViewCol.test.js
@@ -4,7 +4,7 @@ import { mount, shallow } from 'enzyme';
 import { assert, expect, should } from 'chai';
 import Checkbox from '@material-ui/core/Checkbox';
 import TableViewCol from '../src/components/TableViewCol';
-import textLabels from '../src/textLabels';
+import getTextLabels from '../src/textLabels';
 import { FormControlLabel } from '@material-ui/core';
 
 describe('<TableViewCol />', function() {
@@ -19,7 +19,7 @@ describe('<TableViewCol />', function() {
       { name: 'd', label: 'D' },
     ];
     options = {
-      textLabels,
+      textLabels: getTextLabels(),
     };
   });