diff --git a/packages/eui/changelogs/upcoming/7806.md b/packages/eui/changelogs/upcoming/7806.md new file mode 100644 index 000000000000..208631e50e65 --- /dev/null +++ b/packages/eui/changelogs/upcoming/7806.md @@ -0,0 +1,3 @@ +**Bug fixes** + +- Fixed `EuiSearchBar`'s filter configs to always respect `autoClose: false` diff --git a/packages/eui/src-docs/src/views/search_bar/props_info.js b/packages/eui/src-docs/src/views/search_bar/props_info.js index 900b7d372240..6616f9270f0e 100644 --- a/packages/eui/src-docs/src/views/search_bar/props_info.js +++ b/packages/eui/src-docs/src/views/search_bar/props_info.js @@ -279,7 +279,7 @@ export const propsInfo = { }, autoClose: { description: - 'Should the dropdown close after the user selects a value. Ignored if multiSelect is true.', + 'Should the dropdown close after the user selects a value. If not explicitly passed, will auto-close for single selection and remain open for multi-selection.', required: false, defaultValue: { value: 'true' }, type: { name: 'boolean' }, diff --git a/packages/eui/src/components/search_bar/filters/field_value_selection_filter.spec.tsx b/packages/eui/src/components/search_bar/filters/field_value_selection_filter.spec.tsx index 112d68ce8465..0189dd6e18c6 100644 --- a/packages/eui/src/components/search_bar/filters/field_value_selection_filter.spec.tsx +++ b/packages/eui/src/components/search_bar/filters/field_value_selection_filter.spec.tsx @@ -225,6 +225,119 @@ describe('FieldValueSelectionFilter', () => { }); }); + describe('auto-close testing', () => { + const FieldValueSelectionFilterWithState = ({ + autoClose, + multiSelect, + }: { + autoClose: undefined | boolean; + multiSelect: 'or' | boolean; + }) => { + const [query, setQuery] = useState(Query.parse('')); + const onChange = (newQuery: Query) => setQuery(newQuery); + + const props: FieldValueSelectionFilterProps = { + ...requiredProps, + index: 0, + onChange, + query, + config: { + type: 'field_value_selection', + field: 'tag', + name: 'Tag', + multiSelect, + autoClose, + options: staticOptions, + }, + }; + + return ; + }; + const selectFilter = () => { + // Open popover + cy.get('button').click(); + cy.get('.euiPopover__panel').should('exist'); + + // Select filter option + cy.get('li[role="option"][title="feature"]') + .should('have.attr', 'aria-checked', 'false') + .click(); + }; + + describe('undefined', () => { + it('multi select: does not close popover', () => { + cy.mount( + + ); + selectFilter(); + cy.get('.euiPopover__panel').should('exist'); + }); + + it('single select: closes popover', () => { + cy.mount( + + ); + selectFilter(); + cy.get('.euiPopover__panel').should('not.exist'); + }); + }); + + describe('false', () => { + it('multi select: never closes popover', () => { + cy.mount( + + ); + selectFilter(); + cy.get('.euiPopover__panel').should('exist'); + }); + + it('single select: never closes popover', () => { + cy.mount( + + ); + selectFilter(); + cy.get('.euiPopover__panel').should('exist'); + }); + }); + + describe('true', () => { + it('multi select: always closes popover', () => { + cy.mount( + + ); + selectFilter(); + cy.get('.euiPopover__panel').should('not.exist'); + }); + + it('single select: always closes popover', () => { + cy.mount( + + ); + + selectFilter(); + cy.get('.euiPopover__panel').should('not.exist'); + }); + }); + }); + it('has inactive filters, field is global', () => { const props: FieldValueSelectionFilterProps = { ...requiredProps, diff --git a/packages/eui/src/components/search_bar/filters/field_value_selection_filter.tsx b/packages/eui/src/components/search_bar/filters/field_value_selection_filter.tsx index af27e8b02256..9ceef0f9a6b5 100644 --- a/packages/eui/src/components/search_bar/filters/field_value_selection_filter.tsx +++ b/packages/eui/src/components/search_bar/filters/field_value_selection_filter.tsx @@ -252,35 +252,37 @@ export class FieldValueSelectionFilter extends Component< ) { const multiSelect = this.resolveMultiSelect(); const { - config: { autoClose = true, operator = Operator.EQ }, + config: { autoClose, operator = Operator.EQ }, } = this.props; - // we're closing popover only if the user can only select one item... if the - // user can select more, we'll leave it open so she can continue selecting - - if (!multiSelect && autoClose) { + // If the consumer explicitly sets `autoClose`, always defer to that. + // Otherwise, default to auto-closing for single selections and leaving the + // popover open for multi-select (so users can continue selecting options) + const shouldClosePopover = autoClose ?? !multiSelect; + if (shouldClosePopover) { this.closePopover(); + } + + if (!multiSelect) { const query = checked ? this.props.query .removeSimpleFieldClauses(field) .addSimpleFieldValue(field, value, true, operator) : this.props.query.removeSimpleFieldClauses(field); + this.props.onChange(query); + } else if (multiSelect === 'or') { + const query = checked + ? this.props.query.addOrFieldValue(field, value, true, operator) + : this.props.query.removeOrFieldValue(field, value); + this.props.onChange(query); } else { - if (multiSelect === 'or') { - const query = checked - ? this.props.query.addOrFieldValue(field, value, true, operator) - : this.props.query.removeOrFieldValue(field, value); - - this.props.onChange(query); - } else { - const query = checked - ? this.props.query.addSimpleFieldValue(field, value, true, operator) - : this.props.query.removeSimpleFieldValue(field, value); - - this.props.onChange(query); - } + const query = checked + ? this.props.query.addSimpleFieldValue(field, value, true, operator) + : this.props.query.removeSimpleFieldValue(field, value); + + this.props.onChange(query); } }