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 });
}