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,