Skip to content

Commit a8ac37a

Browse files
fix: added condition to handle selection clearing (#18584)
Co-authored-by: Riddhi Bansal <41935566+riddhybansal@users.noreply.github.com>
1 parent 920c60e commit a8ac37a

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

packages/react/src/components/ComboBox/ComboBox-test.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,67 @@ describe('ComboBox', () => {
675675
expect(call.selectedItem).toEqual(mockProps.items[i]);
676676
}
677677
});
678+
it('should clear selection if input does not match any item and there is already a selected item', async () => {
679+
const user = userEvent.setup();
680+
render(<ComboBox {...mockProps} />);
681+
682+
// First select an item
683+
await openMenu();
684+
await user.click(screen.getAllByRole('option')[0]);
685+
686+
expect(findInputNode()).toHaveDisplayValue('Item 0');
687+
expect(mockProps.onChange).toHaveBeenCalledWith({
688+
selectedItem: mockProps.items[0],
689+
});
690+
691+
// Clear input and type something that doesn't match
692+
await user.clear(findInputNode());
693+
await user.type(findInputNode(), 'xyz');
694+
await user.keyboard('[Enter]');
695+
// Selection should be cleared
696+
697+
expect(mockProps.onChange).toHaveBeenLastCalledWith({
698+
selectedItem: null,
699+
});
700+
701+
expect(findInputNode()).toHaveDisplayValue('xyz');
702+
});
703+
704+
it('should not clear selection if no item was previously selected', async () => {
705+
const user = userEvent.setup();
706+
render(<ComboBox {...mockProps} />);
707+
708+
// Type something that doesn't match any item
709+
await user.type(findInputNode(), 'xyz');
710+
await user.keyboard('[Enter]');
711+
712+
// No onChange should be called since there was no selection to clear
713+
expect(mockProps.onChange).not.toHaveBeenCalled();
714+
expect(findInputNode()).toHaveDisplayValue('xyz');
715+
});
716+
717+
it('should keep selection when allowCustomValue is true even if input does not match', async () => {
718+
const user = userEvent.setup();
719+
render(<ComboBox {...mockProps} allowCustomValue />);
720+
721+
// First select an item
722+
await openMenu();
723+
await user.click(screen.getAllByRole('option')[0]);
724+
expect(findInputNode()).toHaveDisplayValue('Item 0');
725+
726+
// Type something that doesn't match
727+
await user.clear(findInputNode());
728+
await user.type(findInputNode(), 'xyz');
729+
await user.keyboard('[Enter]');
730+
731+
// Selection should not be cleared with allowCustomValue
732+
expect(mockProps.onChange).toHaveBeenLastCalledWith({
733+
selectedItem: null,
734+
inputValue: 'xyz',
735+
});
736+
737+
expect(findInputNode()).toHaveDisplayValue('xyz');
738+
});
678739
});
679740

680741
describe('ComboBox autocomplete', () => {

packages/react/src/components/ComboBox/ComboBox.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,17 @@ const ComboBox = forwardRef(
611611
}
612612

613613
case InputKeyDownEnter:
614+
if (
615+
highlightedIndex === -1 &&
616+
!allowCustomValue &&
617+
state.selectedItem
618+
) {
619+
return {
620+
...changes,
621+
selectedItem: null,
622+
inputValue: state.inputValue,
623+
};
624+
}
614625
if (allowCustomValue) {
615626
setInputValue(inputValue);
616627
setHighlightedIndex(changes.selectedItem);

0 commit comments

Comments
 (0)