From 0f061da64bba7fe5c48ac43b75c8c4877d67c25e Mon Sep 17 00:00:00 2001 From: Jason Date: Wed, 5 Jun 2024 09:02:41 -0500 Subject: [PATCH] fix(Combobox): fix issue where autocomplete automatic does not fire selection event (#1493) --- .../src/components/Combobox/Combobox.test.tsx | 30 +++++++++++++++++++ .../src/components/Combobox/Combobox.tsx | 5 ++++ 2 files changed, 35 insertions(+) diff --git a/packages/react/src/components/Combobox/Combobox.test.tsx b/packages/react/src/components/Combobox/Combobox.test.tsx index 84b04f392..291a2b881 100644 --- a/packages/react/src/components/Combobox/Combobox.test.tsx +++ b/packages/react/src/components/Combobox/Combobox.test.tsx @@ -767,6 +767,36 @@ test('should handle selection with "enter" keydown event', () => { fireEnterKeyPress(); }); +test('should handle selection when autocomplete="automatic" and combobox input is blurred', () => { + const onSelectionChange = spy(); + render( + + Apple + Banana + Cantaloupe + + ); + const combobox = screen.getByRole('combobox'); + + // Note: Combobox forwards events to Listbox via dispatchEvent, but this doesn't + // work correctly within jsdom/enzyme so we fire the events directly on listbox + const fireArrowDownKeyPress = () => + fireEvent.keyDown(screen.getByRole('listbox'), { key: 'ArrowDown' }); + + fireEvent.focus(combobox); + assertListboxIsOpen(true); + expect(onSelectionChange.notCalled).toBeTruthy(); + fireArrowDownKeyPress(); + fireEvent.blur(combobox); + expect(onSelectionChange.calledOnce).toBeTruthy(); + expect(onSelectionChange.firstCall.firstArg.value).toEqual('Banana'); +}); + test('should always render all options when autocomplete="none"', () => { render( diff --git a/packages/react/src/components/Combobox/Combobox.tsx b/packages/react/src/components/Combobox/Combobox.tsx index e3cf0920e..9262854a0 100644 --- a/packages/react/src/components/Combobox/Combobox.tsx +++ b/packages/react/src/components/Combobox/Combobox.tsx @@ -240,6 +240,11 @@ const Combobox = forwardRef( /* istanbul ignore next: default value */ ''; setValue(stringValue); setSelectedValue(stringValue); + onSelectionChange?.({ + target: activeDescendant.element, + value: stringValue, + previousValue: value + }); } }, [autocomplete, activeDescendant, onBlur]