diff --git a/cypress/components/select/filterable-select/filterable-select.cy.tsx b/cypress/components/select/filterable-select/filterable-select.cy.tsx index 4b8e8ebd81..64d987651f 100644 --- a/cypress/components/select/filterable-select/filterable-select.cy.tsx +++ b/cypress/components/select/filterable-select/filterable-select.cy.tsx @@ -576,6 +576,18 @@ context("Tests for FilterableSelect component", () => { selectListWrapper().should("be.visible"); }); + it("should not reopen list when openOnFocus set and user selects an option via click", () => { + CypressMountWithProviders( + + ); + + commonDataElementInputPreview().focus(); + selectInput().should("have.attr", "aria-expanded", "true"); + selectListWrapper().should("be.visible"); + selectOption(positionOfElement("first")).click(); + selectListWrapper().should("not.be.visible"); + }); + it("should check list is open when input is clicked and openOnFocus is set", () => { CypressMountWithProviders( diff --git a/src/components/select/filterable-select/filterable-select.component.tsx b/src/components/select/filterable-select/filterable-select.component.tsx index d3ffb9dbd2..311c78c8ce 100644 --- a/src/components/select/filterable-select/filterable-select.component.tsx +++ b/src/components/select/filterable-select/filterable-select.component.tsx @@ -153,6 +153,7 @@ export const FilterableSelect = React.forwardRef( label, }); const focusTimer = useRef>(null); + const openOnFocusFlagBlock = useRef(false); if (!deprecateInputRefWarnTriggered && inputRef) { deprecateInputRefWarnTriggered = true; @@ -478,12 +479,13 @@ export const FilterableSelect = React.forwardRef( setActiveDescendantId(selectedOptionId); if (selectionType !== "navigationKey") { + openOnFocusFlagBlock.current = !!openOnFocus; setOpen(false); textboxRef?.focus(); textboxRef?.select(); } }, - [textboxRef, triggerChange] + [textboxRef, triggerChange, openOnFocus] ); const onSelectListClose = useCallback(() => { @@ -521,6 +523,11 @@ export const FilterableSelect = React.forwardRef( clearTimeout(focusTimer.current); } + if (openOnFocusFlagBlock.current) { + openOnFocusFlagBlock.current = false; + return; + } + // we need to use a timeout here as there is a race condition when rendered in a modal // whereby the select list isn't visible when the select is auto focused straight away focusTimer.current = setTimeout(() => { diff --git a/src/components/select/filterable-select/filterable-select.spec.tsx b/src/components/select/filterable-select/filterable-select.spec.tsx index 49e71fa5d1..fd90b11754 100644 --- a/src/components/select/filterable-select/filterable-select.spec.tsx +++ b/src/components/select/filterable-select/filterable-select.spec.tsx @@ -1097,7 +1097,19 @@ describe("FilterableSelect", () => { describe('when the "openOnFocus" prop is set', () => { describe("and the Textbox Input is focused", () => { - it("the SelectList should be rendered", () => { + it("should render the SelectList", () => { + const wrapper = renderSelect({ openOnFocus: true }); + + act(() => { + wrapper.find("input").simulate("focus"); + jest.runOnlyPendingTimers(); + }); + wrapper + .find(Option) + .forEach((option) => expect(option.getDOMNode()).toBeVisible()); + }); + + it("should not reopen the SelectList when a user selects and Option by clicking", () => { const wrapper = renderSelect({ openOnFocus: true }); act(() => { @@ -1107,6 +1119,23 @@ describe("FilterableSelect", () => { wrapper .find(Option) .forEach((option) => expect(option.getDOMNode()).toBeVisible()); + act(() => { + wrapper.find(SelectList).prop("onSelect")({ + value: "opt1", + text: "red", + selectionType: "click", + selectionConfirmed: true, + }); + }); + act(() => { + // need to programatically focus again here to hit coverage + wrapper.find("input").simulate("focus"); + jest.runOnlyPendingTimers(); + }); + wrapper + .update() + .find(Option) + .forEach((option) => expect(option.getDOMNode()).not.toBeVisible()); }); describe.each(["readOnly", "disabled"])(