From 3099ac7603f5d0f95ae280fdd25b1ff6bbdab5a5 Mon Sep 17 00:00:00 2001 From: Richard Dinh Date: Fri, 31 May 2024 13:09:30 -0400 Subject: [PATCH] updated craco config so less file builds. fixing search bar text area fixing z-index of spyglass icon getting typeahead to work correctly with styling. move button around, fix date filter async typeahead text fix update some stuff update filter and snapshot hide cancel button if no value update more deps, fixing cypress tests fix warnings and nags fix error styles, remove clear button, fixing styles in mobile view. --- craco.config.js | 3 + cypress/e2e/common/filters.cy.js | 8 +- package.json | 28 +- .../Filters/CompanyReceivedFilter.js | 101 +++---- src/components/Filters/DateFilter.js | 101 +++---- src/components/Filters/DateFilter.less | 10 +- .../CompanyReceivedFilter.spec.js.snap | 189 ++++++-------- .../__snapshots__/DateFilter.spec.js.snap | 246 +++++++----------- src/components/Search/PillPanel.less | 2 +- src/components/Search/SearchBar.js | 22 +- src/components/Search/SearchPanel.less | 1 + .../AsyncTypeahead/AsyncTypeahead.js | 135 +++++----- .../Typeahead/ClearButton/ClearButton.js | 5 +- .../HighlightingOption/HighlightingOption.js | 4 +- .../HighlightingOption.spec.js | 10 +- src/components/Typeahead/Input/Input.js | 37 ++- src/components/Typeahead/Input/Input.spec.js | 12 +- src/components/Typeahead/Typeahead.less | 20 +- .../Typeahead/Typeahead/Typeahead.js | 85 +++--- 19 files changed, 443 insertions(+), 576 deletions(-) diff --git a/craco.config.js b/craco.config.js index 60d0905f8..0b1fd60b1 100644 --- a/craco.config.js +++ b/craco.config.js @@ -94,6 +94,9 @@ module.exports = { }, javascriptEnabled: true, math: 'always', + paths: [ + path.resolve(__dirname, 'node_modules/@cfpb/cfpb-core/src'), + ], }, }, }, diff --git a/cypress/e2e/common/filters.cy.js b/cypress/e2e/common/filters.cy.js index b23a0cbdb..0b7e99c99 100644 --- a/cypress/e2e/common/filters.cy.js +++ b/cypress/e2e/common/filters.cy.js @@ -39,12 +39,16 @@ describe('Filter Panel', () => { cy.get('#date_received-from').should('be.visible'); cy.log('collapse it'); - cy.get('.date-filter button.a-btn--link:first').click({ force: true }); + cy.get('.date-filter > button.o-expandable__header:first').click({ + force: true, + }); cy.get('#date-received-agg #start_date').should('not.exist'); cy.log('open it'); - cy.get('.date-filter button.a-btn--link:first').click({ force: true }); + cy.get('.date-filter > button.o-expandable__header:first').click({ + force: true, + }); cy.log('apply dates'); cy.get('#date_received-from').clear(); diff --git a/package.json b/package.json index 3026fe234..79cc33f49 100644 --- a/package.json +++ b/package.json @@ -32,25 +32,25 @@ }, "browserslist": "> 0.2% in @cfpb/browserslist-config stats", "devDependencies": { - "@babel/cli": "^7.24.5", - "@babel/core": "^7.24.5", - "@babel/eslint-parser": "^7.24.5", - "@babel/preset-react": "^7.24.1", - "@babel/runtime": "^7.24.5", + "@babel/cli": "^7.24.7", + "@babel/core": "^7.24.7", + "@babel/eslint-parser": "^7.24.7", + "@babel/preset-react": "^7.24.7", + "@babel/runtime": "^7.24.7", "@cfpb/browserslist-config": "0.0.2", "@cfpb/cfpb-atomic-component": "1.2.0", - "@cfpb/cfpb-buttons": "1.2.0", + "@cfpb/cfpb-buttons": "1.3.0", "@cfpb/cfpb-core": "1.2.0", - "@cfpb/cfpb-design-system": "^1.2.0", + "@cfpb/cfpb-design-system": "^1.3.2", "@cfpb/cfpb-expandables": "^1.2.0", - "@cfpb/cfpb-forms": "1.2.0", + "@cfpb/cfpb-forms": "1.3.0", "@cfpb/cfpb-grid": "1.2.0", "@cfpb/cfpb-icons": "^1.2.0", - "@cfpb/cfpb-layout": "1.2.0", - "@cfpb/cfpb-notifications": "1.2.0", - "@cfpb/cfpb-pagination": "1.2.0", + "@cfpb/cfpb-layout": "1.3.0", + "@cfpb/cfpb-notifications": "1.3.0", + "@cfpb/cfpb-pagination": "1.3.0", "@cfpb/cfpb-tables": "1.2.0", - "@cfpb/cfpb-typography": "1.2.0", + "@cfpb/cfpb-typography": "1.3.2", "@craco/craco": "^7.1.0", "@reduxjs/toolkit": "^2.2.5", "@testing-library/cypress": "^10.0.1", @@ -61,7 +61,7 @@ "coveralls": "^3.0.9", "craco-esbuild": "^0.6.1", "craco-less": "^3.0.1", - "cypress": "^13.9.0", + "cypress": "^13.11.0", "d3": "^7.9.0", "d3-selection": "^3.0.0", "dayjs": "^1.11.10", @@ -91,7 +91,7 @@ "postcss-less": "^6.0.0", "postcss-preset-env": "^9.5.13", "postcss-safe-parser": "^7.0.0", - "prettier": "^3.2.4", + "prettier": "^3.3.1", "prop-types": "^15.5.10", "query-string": "^9.0.0", "react": "^18.2.0", diff --git a/src/components/Filters/CompanyReceivedFilter.js b/src/components/Filters/CompanyReceivedFilter.js index eeb108538..317661f98 100644 --- a/src/components/Filters/CompanyReceivedFilter.js +++ b/src/components/Filters/CompanyReceivedFilter.js @@ -49,15 +49,6 @@ export const CompanyReceivedFilter = () => { setThroughDate(validThroughDate); }, [dateThrough]); - const handleClear = (period) => { - if (period === 'from') { - dispatch(changeDates(fieldName, '', throughDate)); - } - if (period === 'through') { - dispatch(changeDates(fieldName, fromDate, '')); - } - }; - const handleKeyDownFromDate = (event) => { if (event.key === 'Enter') { fromRef.current.blur(); @@ -115,7 +106,7 @@ export const CompanyReceivedFilter = () => { dayjs(fromDate).isBefore(minDate) || dayjs(fromDate).isAfter(throughDate) ) { - style.push('a-text-input__error'); + style.push('a-text-input--error'); } return style.join(' '); }, [fromDate, throughDate]); @@ -126,7 +117,7 @@ export const CompanyReceivedFilter = () => { dayjs(throughDate).isAfter(maxDate) || dayjs(throughDate).isBefore(fromDate) ) { - style.push('a-text-input__error'); + style.push('a-text-input--error'); } return style.join(' '); }, [fromDate, throughDate]); @@ -142,29 +133,22 @@ export const CompanyReceivedFilter = () => { > From -
- setFromDate(evt.target.value)} - onKeyDown={handleKeyDownFromDate} - min={minDate} - max={maxDate} - ref={fromRef} - placeholder={DATE_VALIDATION_FORMAT} - type="date" - value={fromDate} - /> - +
+
+ setFromDate(evt.target.value)} + onKeyDown={handleKeyDownFromDate} + min={minDate} + max={maxDate} + ref={fromRef} + placeholder={DATE_VALIDATION_FORMAT} + type="date" + value={fromDate} + /> +
  • @@ -174,43 +158,38 @@ export const CompanyReceivedFilter = () => { > Through -
    - setThroughDate(evt.target.value)} - onKeyDown={handleKeyDownThroughDate} - min={minDate} - max={maxDate} - placeholder={DATE_VALIDATION_FORMAT} - ref={throughRef} - type="date" - value={throughDate} - /> - +
    +
    + setThroughDate(evt.target.value)} + onKeyDown={handleKeyDownThroughDate} + min={minDate} + max={maxDate} + placeholder={DATE_VALIDATION_FORMAT} + ref={throughRef} + type="date" + value={throughDate} + /> +
  • - {errors.length - ? errors.map((message, key) => ( + {errors.length ? ( +
    + {errors.map((message, key) => (
    {message}
    - )) - : null} + ))} +
    + ) : null}
    ); diff --git a/src/components/Filters/DateFilter.js b/src/components/Filters/DateFilter.js index ccb9ea111..89be28754 100644 --- a/src/components/Filters/DateFilter.js +++ b/src/components/Filters/DateFilter.js @@ -49,24 +49,15 @@ export const DateFilter = () => { useEffect(() => { // put it in YYYY-MM-DD format // validate to make sure it's not invalid - const validFromDate = dateFrom ? formatDate(dateFrom) : ''; + const validFromDate = dateFrom ? formatDate(dateFrom) : minDate; setFromDate(validFromDate); }, [dateFrom]); useEffect(() => { - const validThroughDate = dateThrough ? formatDate(dateThrough) : ''; + const validThroughDate = dateThrough ? formatDate(dateThrough) : maxDate; setThroughDate(validThroughDate); }, [dateThrough]); - const handleClear = (period) => { - if (period === 'from') { - dispatch(changeDates(fieldName, minDate, throughDate)); - } - if (period === 'through') { - dispatch(changeDates(fieldName, fromDate, maxDate)); - } - }; - const handleKeyDownFromDate = (event) => { if (event.key === 'Enter') { fromRef.current.blur(); @@ -118,7 +109,7 @@ export const DateFilter = () => { dayjs(fromDate).isAfter(throughDate) || dayjs(fromDate).isSame(throughDate) ) { - style.push('a-text-input__error'); + style.push('a-text-input--error'); } return style.join(' '); }, [fromDate, throughDate]); @@ -130,7 +121,7 @@ export const DateFilter = () => { dayjs(throughDate).isBefore(fromDate) || dayjs(throughDate).isSame(fromDate) ) { - style.push('a-text-input__error'); + style.push('a-text-input--error'); } return style.join(' '); }, [fromDate, throughDate]); @@ -159,29 +150,25 @@ export const DateFilter = () => { > From -
    - setFromDate(evt.target.value)} - onKeyDown={handleKeyDownFromDate} - min={minDate} - max={maxDate} - ref={fromRef} - placeholder={DATE_VALIDATION_FORMAT} - type="date" - value={fromDate} - /> - +
    +
    + { + const value = evt.target.value || minDate; + setFromDate(value); + }} + onKeyDown={handleKeyDownFromDate} + min={minDate} + max={maxDate} + ref={fromRef} + placeholder={DATE_VALIDATION_FORMAT} + type="date" + value={fromDate} + /> +
  • @@ -191,29 +178,25 @@ export const DateFilter = () => { > Through -
    - setThroughDate(evt.target.value)} - onKeyDown={handleKeyDownThroughDate} - min={minDate} - max={maxDate} - placeholder={DATE_VALIDATION_FORMAT} - ref={throughRef} - type="date" - value={throughDate} - /> - +
    +
    + { + const value = evt.target.value || minDate; + setThroughDate(value); + }} + onKeyDown={handleKeyDownThroughDate} + min={minDate} + max={maxDate} + placeholder={DATE_VALIDATION_FORMAT} + ref={throughRef} + type="date" + value={throughDate} + /> +
  • diff --git a/src/components/Filters/DateFilter.less b/src/components/Filters/DateFilter.less index bf573e28a..d0e3bd1f9 100644 --- a/src/components/Filters/DateFilter.less +++ b/src/components/Filters/DateFilter.less @@ -15,14 +15,8 @@ &:first-of-type { margin-right: @gutter-normal; } - - .m-btn-inside-input { - .a-text-input { - padding-right: @grid_gutter-width; - } - .a-btn { - color: var(--gray); - } + input { + width: 100%; } } } diff --git a/src/components/Filters/__tests__/__snapshots__/CompanyReceivedFilter.spec.js.snap b/src/components/Filters/__tests__/__snapshots__/CompanyReceivedFilter.spec.js.snap index 82ceb7b03..34f3a97eb 100644 --- a/src/components/Filters/__tests__/__snapshots__/CompanyReceivedFilter.spec.js.snap +++ b/src/components/Filters/__tests__/__snapshots__/CompanyReceivedFilter.spec.js.snap @@ -45,33 +45,24 @@ exports[`component::CompanyReceivedFilter snapshot shows errors 1`] = ` From
    - - + +
  • @@ -82,47 +73,43 @@ exports[`component::CompanyReceivedFilter snapshot shows errors 1`] = ` Through
    - - + +
  • -
    - 'From' date must be less than 'through' date -
    @@ -174,33 +161,24 @@ exports[`component::CompanyReceivedFilter snapshot supports no dates in the Redu From
    - - + +
  • @@ -211,33 +189,24 @@ exports[`component::CompanyReceivedFilter snapshot supports no dates in the Redu Through
    - - + +
  • diff --git a/src/components/Filters/__tests__/__snapshots__/DateFilter.spec.js.snap b/src/components/Filters/__tests__/__snapshots__/DateFilter.spec.js.snap index 709fb948f..39c2d983a 100644 --- a/src/components/Filters/__tests__/__snapshots__/DateFilter.spec.js.snap +++ b/src/components/Filters/__tests__/__snapshots__/DateFilter.spec.js.snap @@ -60,33 +60,24 @@ exports[`component::DateFilter snapshot shows a warning for April 2017 1`] = ` From
    - - + +
  • @@ -97,33 +88,24 @@ exports[`component::DateFilter snapshot shows a warning for April 2017 1`] = ` Through
    - - + +
  • @@ -229,33 +211,24 @@ exports[`component::DateFilter snapshot shows errors 1`] = ` From
    - - + +
  • @@ -266,33 +239,24 @@ exports[`component::DateFilter snapshot shows errors 1`] = ` Through
    - - + +
  • @@ -417,33 +381,24 @@ exports[`component::DateFilter snapshot supports no dates in the Redux Store 1`] From
    - - + +
  • @@ -454,33 +409,24 @@ exports[`component::DateFilter snapshot supports no dates in the Redux Store 1`] Through
    - - + +
  • diff --git a/src/components/Search/PillPanel.less b/src/components/Search/PillPanel.less index 05b3ec534..58f944d72 100644 --- a/src/components/Search/PillPanel.less +++ b/src/components/Search/PillPanel.less @@ -34,7 +34,7 @@ @media @phone { flex-direction: column; - margin-top: 10px; + margin-top: 70px; .layout-row { padding-left: 0; } diff --git a/src/components/Search/SearchBar.js b/src/components/Search/SearchBar.js index ae1beb533..81199f96c 100644 --- a/src/components/Search/SearchBar.js +++ b/src/components/Search/SearchBar.js @@ -31,7 +31,6 @@ export const SearchBar = ({ debounceWait }) => { // handleClear is called whenever the user submits by pressing enter // shouldCallClear prevents handleClear from firing a reset after the search is set const [shouldCallClear, setShouldCallClear] = useState(true); - const isVisible = Boolean(searchText || inputValue); useEffect(() => { setInputValue(searchText); @@ -113,7 +112,7 @@ export const SearchBar = ({ debounceWait }) => {
    {searchField === 'company' ? ( { handleClear={onTypeaheadClear} handleSearch={onSearchChange} hasClearButton={true} + hasSearchButton={true} options={dropdownOptions} placeholder="Enter your search term(s)" /> ) : ( setInputValue(event.target.value)} - placeholder="Enter your search term(s)" - value={inputValue} handleClear={onClearInput} handlePressEnter={onPressEnter} - isClearVisible={isVisible} + htmlId="searchText" + value={inputValue} + ariaLabel="Enter the term you want to search for" + placeholder="Enter your search term(s)" /> )}
    - - Skip to Results
    diff --git a/src/components/Search/SearchPanel.less b/src/components/Search/SearchPanel.less index 479f5694c..92e52521f 100644 --- a/src/components/Search/SearchPanel.less +++ b/src/components/Search/SearchPanel.less @@ -8,6 +8,7 @@ @media @phone { padding: @gutter-narrow; + min-height: 150px; } background-color: var(--gray-5); } diff --git a/src/components/Typeahead/AsyncTypeahead/AsyncTypeahead.js b/src/components/Typeahead/AsyncTypeahead/AsyncTypeahead.js index 5ae369b3b..7dbda6ce7 100644 --- a/src/components/Typeahead/AsyncTypeahead/AsyncTypeahead.js +++ b/src/components/Typeahead/AsyncTypeahead/AsyncTypeahead.js @@ -8,19 +8,19 @@ import { ClearButton } from '../ClearButton/ClearButton'; export const AsyncTypeahead = ({ ariaLabel, - className, - defaultValue, - delayWait, + defaultValue = '', + delayWait = 0, htmlId, - isDisabled, + isDisabled = false, handleChange, handleClear, handleSearch, - hasClearButton, - maxResults, - minLength, + hasClearButton = false, + hasSearchButton = false, + maxResults = 5, + minLength = 2, options, - placeholder, + placeholder = 'Enter your search text', }) => { const ref = useRef(); const [searchValue, setSearchValue] = useState(defaultValue); @@ -43,55 +43,65 @@ export const AsyncTypeahead = ({ }; return ( -
    -
    -
    - {getIcon('search')} -
    - - { - if (input === '') setIsVisible(false); - else setIsVisible(true); - }} - onSearch={(input) => { - setSearchValue(input); - handleSearch(input); - }} - onChange={(selected) => { - handleChange(selected); - ref.current.clear(); - setSearchValue(''); - }} - options={options} - maxResults={maxResults} - placeholder={placeholder} - renderMenuItemChildren={(option) => ( -
  • - -
  • - )} - /> - {!!isVisible && ( - { - handleTypeaheadClear(); - setIsVisible(false); +
    +
    +
    + + { + if (input === '') setIsVisible(false); + else setIsVisible(true); + }} + onSearch={(input) => { + setSearchValue(input); + handleSearch(input); + }} + onChange={(selected) => { + handleChange(selected); + ref.current.clear(); + setSearchValue(''); }} + options={options} + maxResults={maxResults} + placeholder={placeholder} + renderMenuItemChildren={(option) => ( +
  • + +
  • + )} /> + + {!!isVisible && ( + { + handleTypeaheadClear(); + setIsVisible(false); + }} + /> + )} +
    + {!!hasSearchButton && ( + )}
    @@ -100,28 +110,17 @@ export const AsyncTypeahead = ({ AsyncTypeahead.propTypes = { ariaLabel: PropTypes.string.isRequired, - className: PropTypes.string, defaultValue: PropTypes.string, delayWait: PropTypes.number.isRequired, - isDisabled: PropTypes.bool.isRequired, + isDisabled: PropTypes.bool, handleChange: PropTypes.func.isRequired, handleClear: PropTypes.func, handleSearch: PropTypes.func.isRequired, hasClearButton: PropTypes.bool, + hasSearchButton: PropTypes.bool, htmlId: PropTypes.string.isRequired, maxResults: PropTypes.number, minLength: PropTypes.number, options: PropTypes.array, placeholder: PropTypes.string, }; - -AsyncTypeahead.defaultProps = { - className: '', - defaultValue: '', - delayWait: 0, - hasClearButton: false, - isDisabled: false, - maxResults: 5, - minLength: 2, - placeholder: 'Enter your search text', -}; diff --git a/src/components/Typeahead/ClearButton/ClearButton.js b/src/components/Typeahead/ClearButton/ClearButton.js index cc1727528..2afacce87 100644 --- a/src/components/Typeahead/ClearButton/ClearButton.js +++ b/src/components/Typeahead/ClearButton/ClearButton.js @@ -4,11 +4,12 @@ import getIcon from '../../iconMap'; export const ClearButton = ({ onClear }) => { return ( ); }; diff --git a/src/components/Typeahead/HighlightingOption/HighlightingOption.js b/src/components/Typeahead/HighlightingOption/HighlightingOption.js index 9d4f42014..d6f0c68c2 100644 --- a/src/components/Typeahead/HighlightingOption/HighlightingOption.js +++ b/src/components/Typeahead/HighlightingOption/HighlightingOption.js @@ -7,13 +7,11 @@ export const HighlightingOption = ({ label, position, value }) => { } const start = label.substring(0, position); - const match = label.substring(position, value.length); const end = label.substring(position + value.length); - return ( {start} - {match} + {value} {end} ); diff --git a/src/components/Typeahead/HighlightingOption/HighlightingOption.spec.js b/src/components/Typeahead/HighlightingOption/HighlightingOption.spec.js index 384dd6840..979a56e09 100644 --- a/src/components/Typeahead/HighlightingOption/HighlightingOption.spec.js +++ b/src/components/Typeahead/HighlightingOption/HighlightingOption.spec.js @@ -8,7 +8,7 @@ describe('HighlightingOption', () => { , ); - expect(container.innerHTML).toEqual(`Maryland (MD)`); + expect(container.innerHTML).toEqual(`maryland (MD)`); }); test('Handles position < 0', () => { @@ -18,4 +18,12 @@ describe('HighlightingOption', () => { expect(container.innerHTML).toEqual(`Maryland (MD)`); }); + + test('Renders partially bolded text in the middle', () => { + const { container } = render( + , + ); + + expect(container.innerHTML).toEqual(`Maryland (MD)`); + }); }); diff --git a/src/components/Typeahead/Input/Input.js b/src/components/Typeahead/Input/Input.js index 3fd1e8490..4a0a32f34 100644 --- a/src/components/Typeahead/Input/Input.js +++ b/src/components/Typeahead/Input/Input.js @@ -1,5 +1,3 @@ -import '../Typeahead.less'; -import React from 'react'; import PropTypes from 'prop-types'; import getIcon from '../../iconMap'; import { ClearButton } from '../ClearButton/ClearButton'; @@ -12,35 +10,38 @@ export const Input = ({ handleChange, handleClear, handlePressEnter, - isClearVisible, placeholder, value, }) => { return ( -
    -
    -
    +
    +
    - - {!!isClearVisible && } +
    -
    + +
    ); }; Input.propTypes = { @@ -51,13 +52,11 @@ Input.propTypes = { handleClear: PropTypes.func, handlePressEnter: PropTypes.func, htmlId: PropTypes.string.isRequired, - isClearVisible: PropTypes.bool, placeholder: PropTypes.string, value: PropTypes.string.isRequired, }; Input.defaultProps = { - isClearVisible: false, isDisabled: false, placeholder: 'Enter your search text', }; diff --git a/src/components/Typeahead/Input/Input.spec.js b/src/components/Typeahead/Input/Input.spec.js index 8bc4241e3..46b9ddbdc 100644 --- a/src/components/Typeahead/Input/Input.spec.js +++ b/src/components/Typeahead/Input/Input.spec.js @@ -26,7 +26,7 @@ describe('Input', () => { test('Handle when change and enter are called', () => { renderComponent(); - const input = screen.getByRole('textbox'); + const input = screen.getByRole('searchbox'); fireEvent.change(input, { target: { value: 'text' } }); expect(handleChangeMock).toBeCalled(); fireEvent.click(input); @@ -34,16 +34,10 @@ describe('Input', () => { expect(handleEnterMock).toBeCalled(); }); - test('When handleClear is not given then clear button is not present', () => { - renderComponent(); - expect(screen.queryByRole('button')).not.toBeInTheDocument(); - }); - - test('When handleClear is given then clear button is present', () => { + test('When handleClear is given then clear button is present', () => { const handleClearMock = jest.fn(); renderComponent(handleClearMock, true); - expect(screen.getByRole('button')).toBeDefined(); - fireEvent.click(screen.getByRole('button')); + fireEvent.click(screen.getByRole('button', { name: 'clear search' })); expect(handleClearMock).toBeCalled(); }); }); diff --git a/src/components/Typeahead/Typeahead.less b/src/components/Typeahead/Typeahead.less index c5e404ab9..93104ee6d 100644 --- a/src/components/Typeahead/Typeahead.less +++ b/src/components/Typeahead/Typeahead.less @@ -6,21 +6,10 @@ border: solid 2px var(--pacific); } } - .m-btn-inside-input { - .a-btn { - position: absolute; - right: 1em; - top: ~'calc(50% - 8px)'; - } - .cf-icon-svg { - padding-right: @gutter-minimum * 0.8; - } - } &-selector { + width: 100%; position: relative; - // z-index: 99; - ul { padding-left: 0; border: solid 2px var(--pacific); @@ -100,6 +89,13 @@ background-color: var(--gray-10); } } + + .o-search-input__input { + //display: block; + &-label { + z-index: 1; + } + } } .input-contains-label__before { diff --git a/src/components/Typeahead/Typeahead/Typeahead.js b/src/components/Typeahead/Typeahead/Typeahead.js index aee44d62a..401cd1393 100644 --- a/src/components/Typeahead/Typeahead/Typeahead.js +++ b/src/components/Typeahead/Typeahead/Typeahead.js @@ -1,19 +1,17 @@ import '../Typeahead.less'; -import React, { useRef, useState } from 'react'; +import { ClearButton } from '../ClearButton/ClearButton'; +import { useRef, useState } from 'react'; import PropTypes from 'prop-types'; import { Typeahead as DropdownTypeahead } from 'react-bootstrap-typeahead'; import getIcon from '../../iconMap'; import HighlightingOption from '../HighlightingOption/HighlightingOption'; -import { ClearButton } from '../ClearButton/ClearButton'; export const Typeahead = ({ ariaLabel, - className, htmlId, isDisabled, handleChange, handleInputChange, - hasClearButton, maxResults, minLength, options, @@ -21,7 +19,6 @@ export const Typeahead = ({ }) => { const ref = useRef(); const [input, setInput] = useState(''); - const isVisible = hasClearButton && input; const handleClear = () => { ref.current.clear(); @@ -29,53 +26,55 @@ export const Typeahead = ({ }; return ( -
    -
    -
    - {getIcon('search')} +
    +
    +
    + + { + handleChange(selection); + handleClear(); + }} + onInputChange={(value) => { + handleInputChange(value); + setInput(value); + }} + options={options} + maxResults={maxResults} + placeholder={placeholder} + renderMenuItemChildren={(option) => ( +
  • + +
  • + )} + inputProps={{ + id: htmlId, + className: 'a-text-input a-text-input__full', + }} + /> + {!!input && }
    - - { - handleChange(selection); - handleClear(); - }} - onInputChange={(value) => { - handleInputChange(value); - setInput(value); - }} - options={options} - maxResults={maxResults} - placeholder={placeholder} - renderMenuItemChildren={(option) => ( -
  • - -
  • - )} - /> - {!!isVisible && }
    ); }; Typeahead.propTypes = { ariaLabel: PropTypes.string.isRequired, - className: PropTypes.string, isDisabled: PropTypes.bool.isRequired, handleChange: PropTypes.func.isRequired, handleInputChange: PropTypes.func.isRequired, - hasClearButton: PropTypes.bool, htmlId: PropTypes.string.isRequired, maxResults: PropTypes.number, minLength: PropTypes.number, @@ -84,8 +83,6 @@ Typeahead.propTypes = { }; Typeahead.defaultProps = { - className: '', - hasClearButton: false, isDisabled: false, maxResults: 5, minLength: 2,