diff --git a/src/components/selectable/selectable.spec.tsx b/src/components/selectable/selectable.spec.tsx index 1560402c9b4..34b875c13fe 100644 --- a/src/components/selectable/selectable.spec.tsx +++ b/src/components/selectable/selectable.spec.tsx @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +/// /// import React, { useState } from 'react'; diff --git a/src/components/selectable/selectable.test.tsx b/src/components/selectable/selectable.test.tsx index f675445b89e..57af21b7847 100644 --- a/src/components/selectable/selectable.test.tsx +++ b/src/components/selectable/selectable.test.tsx @@ -204,6 +204,41 @@ describe('EuiSelectable', () => { ).toEqual('second value'); }); + it('updates options list when searchValue state is controlled by searchProps.value', () => { + const searchProps = { + value: 'Enceladus', + 'data-test-subj': 'searchInput', + }; + const component = mount( + + {(list, search) => ( + <> + {list} + {search} + + )} + + ); + + expect( + (component.find('EuiSelectableList').props() as any).visibleOptions + ).toHaveLength(1); + + component.setProps({ + searchProps: { ...searchProps, value: 'value not in list' }, + }); + + expect(component.find('EuiSelectableList').exists()).toBeFalsy(); + + component.setProps({ + searchProps: { ...searchProps, value: '' }, + }); + + expect( + (component.find('EuiSelectableList').props() as any).visibleOptions + ).toEqual(options); + }); + it('calls the searchProps.onChange callback on mount', () => { const onChange = jest.fn(); mount( diff --git a/src/components/selectable/selectable.tsx b/src/components/selectable/selectable.tsx index a2e226f48e5..b3ac542fb10 100644 --- a/src/components/selectable/selectable.tsx +++ b/src/components/selectable/selectable.tsx @@ -240,28 +240,28 @@ export class EuiSelectable extends Component< const { options, isPreFiltered, searchProps } = nextProps; const { activeOptionIndex, searchValue } = prevState; - const matchingOptions = getMatchingOptions( - options, - searchValue, - isPreFiltered - ); - const stateUpdate: Partial> = { - visibleOptions: matchingOptions, + searchValue, activeOptionIndex, }; + if (searchProps?.value != null && searchProps.value !== searchValue) { + stateUpdate.searchValue = searchProps.value; + } + + stateUpdate.visibleOptions = getMatchingOptions( + options, + stateUpdate.searchValue ?? '', + isPreFiltered + ); + if ( activeOptionIndex != null && - activeOptionIndex >= matchingOptions.length + activeOptionIndex >= stateUpdate.visibleOptions.length ) { stateUpdate.activeOptionIndex = -1; } - if (searchProps?.value != null && searchProps.value !== searchValue) { - stateUpdate.searchValue = searchProps.value; - } - return stateUpdate; } diff --git a/upcoming_changelogs/6317.md b/upcoming_changelogs/6317.md new file mode 100644 index 00000000000..081f4044714 --- /dev/null +++ b/upcoming_changelogs/6317.md @@ -0,0 +1,3 @@ +**Bug fixes** + +- Fixed `EuiSelectable` to ensure the full options list is re-displayed when the search bar is controlled and cleared using `searchProps.value` \ No newline at end of file