diff --git a/packages/react/src/components/ComboBox/ComboBox-test.js b/packages/react/src/components/ComboBox/ComboBox-test.js index f862f4484c1c..1b447b66d597 100644 --- a/packages/react/src/components/ComboBox/ComboBox-test.js +++ b/packages/react/src/components/ComboBox/ComboBox-test.js @@ -621,6 +621,40 @@ describe('ComboBox', () => { 'cds--list-box__menu-item--highlighted' ); }); + + it('should pass defined selectedItem to onChange when item is selected', async () => { + render(); + + expect(mockProps.onChange).not.toHaveBeenCalled(); + + await openMenu(); + await userEvent.click(screen.getAllByRole('option')[0]); + + expect(mockProps.onChange).toHaveBeenCalledTimes(1); + expect(mockProps.onChange).toHaveBeenCalledWith( + expect.objectContaining({ + selectedItem: expect.anything(), + }) + ); + + const call = mockProps.onChange.mock.calls[0][0]; + expect(call.selectedItem).toBeDefined(); + expect(call.selectedItem).toEqual(mockProps.items[0]); + }); + + it('should never pass undefined as selectedItem to onChange', async () => { + render(); + + for (let i = 0; i < mockProps.items.length; i++) { + await openMenu(); + await userEvent.click(screen.getAllByRole('option')[i]); + + const call = mockProps.onChange.mock.calls[i][0]; + expect(call.selectedItem).toBeDefined(); + expect(call.selectedItem).not.toBeUndefined(); + expect(call.selectedItem).toEqual(mockProps.items[i]); + } + }); }); describe('ComboBox autocomplete', () => { diff --git a/packages/react/src/components/ComboBox/ComboBox.tsx b/packages/react/src/components/ComboBox/ComboBox.tsx index a009f001a5bf..fe9413f3fc95 100644 --- a/packages/react/src/components/ComboBox/ComboBox.tsx +++ b/packages/react/src/components/ComboBox/ComboBox.tsx @@ -783,8 +783,9 @@ const ComboBox = forwardRef( onChange({ selectedItem: newSelectedItem }); } if ( - type === useCombobox.stateChangeTypes.FunctionSelectItem || - type === useCombobox.stateChangeTypes.InputKeyDownEnter + (type === useCombobox.stateChangeTypes.FunctionSelectItem || + type === useCombobox.stateChangeTypes.InputKeyDownEnter) && + !isEqual(selectedItemProp, newSelectedItem) // Only fire if there's an actual change ) { onChange({ selectedItem: newSelectedItem }); }