From e2df5968422fa5036d7a16f10072a7778c278744 Mon Sep 17 00:00:00 2001 From: Mena Hassan Date: Wed, 9 Aug 2023 09:51:35 -0400 Subject: [PATCH] fix: disable browser autocomplete and edit dropdown items elements Add attributes to `input` element to disable browser autocomplete on autosuggest component and change the div that houses the dropdown items to be a `ul`, change the button elements that render the list to be `li`. add new `role` to each element --- src/Form/FormAutosuggest.jsx | 19 ++++++++++--------- src/Form/FormAutosuggestOption.jsx | 3 +++ src/Form/_index.scss | 1 + src/Form/form-autosuggest.mdx | 2 +- src/Form/tests/FormAutosuggest.test.jsx | 22 +++++++++++----------- 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/Form/FormAutosuggest.jsx b/src/Form/FormAutosuggest.jsx index f9435391728..c6a5281f785 100644 --- a/src/Form/FormAutosuggest.jsx +++ b/src/Form/FormAutosuggest.jsx @@ -39,7 +39,7 @@ function FormAutosuggest({ }); const handleItemClick = (e, onClick) => { - const clickedValue = e.currentTarget.value; + const clickedValue = e.currentTarget.getAttribute('data-value'); if (onSelected && clickedValue !== value) { onSelected(clickedValue); @@ -66,7 +66,7 @@ function FormAutosuggest({ return React.cloneElement(child, { ...rest, children, - value: children, + 'data-value': children, onClick: (e) => handleItemClick(e, onClick), }); }); @@ -219,6 +219,9 @@ function FormAutosuggest({ 0).toString()} aria-owns="pgn__form-autosuggest__dropdown-box" + role="combobox" + aria-autocomplete="list" + autoComplete="off" value={state.displayValue} aria-invalid={state.errorMessage} onChange={handleOnChange} @@ -240,25 +243,25 @@ function FormAutosuggest({ )} -
{isLoading ? (
- ) : state.dropDownItems.length > 0 && state.dropDownItems} -
+ ) : state.dropDownItems.length > 0 && state.dropDownItems} + ); } FormAutosuggest.defaultProps = { - arrowKeyNavigationSelector: 'a:not(:disabled),button:not(:disabled, .btn-icon),input:not(:disabled)', + arrowKeyNavigationSelector: 'a:not(:disabled),li:not(:disabled, .btn-icon),input:not(:disabled)', ignoredArrowKeysNames: ['ArrowRight', 'ArrowLeft'], isLoading: false, - role: 'list', className: null, floatingLabel: null, onChange: null, @@ -283,8 +286,6 @@ FormAutosuggest.propTypes = { ignoredArrowKeysNames: PropTypes.arrayOf(PropTypes.string), /** Specifies loading state. */ isLoading: PropTypes.bool, - /** An ARIA role describing the form autosuggest. */ - role: PropTypes.string, /** Specifies class name to append to the base element. */ className: PropTypes.string, /** Specifies floating label to display for the input component. */ diff --git a/src/Form/FormAutosuggestOption.jsx b/src/Form/FormAutosuggestOption.jsx index a313d2381e4..c8792acc041 100644 --- a/src/Form/FormAutosuggestOption.jsx +++ b/src/Form/FormAutosuggestOption.jsx @@ -11,6 +11,9 @@ function FormAutosuggestOption({ }) { return ( JavaScript Python Rube - alert(e.currentTarget.value)}> + alert(e.currentTarget.getAttribute('data-value'))}> Option with custom onClick diff --git a/src/Form/tests/FormAutosuggest.test.jsx b/src/Form/tests/FormAutosuggest.test.jsx index 1eef6e3fbc6..b6aa0708f83 100644 --- a/src/Form/tests/FormAutosuggest.test.jsx +++ b/src/Form/tests/FormAutosuggest.test.jsx @@ -73,7 +73,7 @@ describe('FormAutosuggest', () => { it('renders component with options', () => { container.find('input').simulate('click'); - const optionsList = container.find('.pgn__form-autosuggest__dropdown').find('button'); + const optionsList = container.find('.pgn__form-autosuggest__dropdown').find('li'); expect(optionsList.length).toEqual(3); }); @@ -94,7 +94,7 @@ describe('FormAutosuggest', () => { describe('controlled behavior', () => { it('selects option', () => { container.find('input').simulate('click'); - container.find('.pgn__form-autosuggest__dropdown').find('button') + container.find('.pgn__form-autosuggest__dropdown').find('li') .at(0).simulate('click'); expect(container.find('input').instance().value).toEqual('Option 1'); @@ -104,7 +104,7 @@ describe('FormAutosuggest', () => { it('when a function is passed to onClick, it is called', () => { container.find('input').simulate('change', { target: { value: 'Option 2' } }); - container.find('.pgn__form-autosuggest__dropdown').find('button') + container.find('.pgn__form-autosuggest__dropdown').find('li') .at(0).simulate('click'); expect(onClick).toHaveBeenCalledTimes(1); @@ -112,7 +112,7 @@ describe('FormAutosuggest', () => { it('when a function is not passed to onClick, it is not called', () => { container.find('input').simulate('change', { target: { value: 'Option 1' } }); - container.find('.pgn__form-autosuggest__dropdown').find('button') + container.find('.pgn__form-autosuggest__dropdown').find('li') .at(0).simulate('click'); expect(onClick).toHaveBeenCalledTimes(0); @@ -127,26 +127,26 @@ describe('FormAutosuggest', () => { it('options list depends on filled field value', () => { container.find('input').simulate('change', { target: { value: 'option 1' } }); - expect(container.find('.pgn__form-autosuggest__dropdown').find('button').length).toEqual(1); + expect(container.find('.pgn__form-autosuggest__dropdown').find('li').length).toEqual(1); expect(onSelected).toHaveBeenCalledTimes(0); }); it('toggles options list', () => { const dropdownContainer = '.pgn__form-autosuggest__dropdown'; - expect(container.find(dropdownContainer).find('button').length).toEqual(1); + expect(container.find(dropdownContainer).find('li').length).toEqual(1); container.find('button.pgn__form-autosuggest__icon-button').simulate('click'); - expect(container.find(dropdownContainer).find('button').length).toEqual(0); + expect(container.find(dropdownContainer).find('li').length).toEqual(0); container.find('button.pgn__form-autosuggest__icon-button').simulate('click'); - expect(container.find(dropdownContainer).find('button').length).toEqual(3); + expect(container.find(dropdownContainer).find('li').length).toEqual(3); }); it('shows options list depends on field value', () => { container.find('input').simulate('change', { target: { value: '1' } }); - expect(container.find('.pgn__form-autosuggest__dropdown').find('button').length).toEqual(2); + expect(container.find('.pgn__form-autosuggest__dropdown').find('li').length).toEqual(2); }); it('closes options list on click outside', () => { @@ -154,12 +154,12 @@ describe('FormAutosuggest', () => { const dropdownContainer = '.pgn__form-autosuggest__dropdown'; container.find('input').simulate('click'); - expect(container.find(dropdownContainer).find('button').length).toEqual(2); + expect(container.find(dropdownContainer).find('li').length).toEqual(2); act(() => { fireEvent.click(document.body); }); container.update(); - expect(container.find(dropdownContainer).find('button').length).toEqual(0); + expect(container.find(dropdownContainer).find('li').length).toEqual(0); }); }); });