Skip to content

Commit

Permalink
[EuiComboBox] Clean duplicated values before adding them (#8335)
Browse files Browse the repository at this point in the history
Co-authored-by: Tomasz Kajtoch <[email protected]>
  • Loading branch information
dfvalero and tkajtoch authored Mar 5, 2025
1 parent 035255d commit ed97224
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 1 deletion.
3 changes: 3 additions & 0 deletions packages/eui/changelogs/upcoming/8335.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**Bug fixes**

- Fixed `EuiComboBox` by cleaning duplicated values when having a delimiter prop.
42 changes: 42 additions & 0 deletions packages/eui/src/components/combo_box/combo_box.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ describe('EuiComboBox', () => {
const onChange = (selectedOptions: typeof options) => {
setSelected(selectedOptions);
};

return (
<EuiComboBox
options={options}
Expand All @@ -46,6 +47,28 @@ describe('EuiComboBox', () => {
);
};

const CreateComboBox = () => {
const [options, setOptions] = useState([]);
const [selectedOptions, setSelected] = useState([]);

const onCreateOption = (searchValue: string) => {
const newOption = { label: searchValue };

setOptions([...options, newOption]);

setSelected((prevSelected) => [...prevSelected, newOption]);
};

return (
<EuiComboBox
options={options}
selectedOptions={selectedOptions}
onCreateOption={onCreateOption}
delimiter=","
/>
);
};

describe('focus management', () => {
it('keeps focus on the input box when clicking a disabled item', () => {
cy.realMount(
Expand Down Expand Up @@ -410,6 +433,25 @@ describe('EuiComboBox', () => {
'Item 1'
);
});

it('adds only one item when pasting duplicated elements', () => {
cy.realMount(<CreateComboBox />);
cy.get('[data-test-subj="euiComboBoxPill"]').should('not.exist');

cy.get('[data-test-subj="comboBoxSearchInput"]').click();

// Simulate pasting text
cy.get('[data-test-subj="comboBoxSearchInput"]')
.clear()
.invoke('val', 'a, a, a, a')
.trigger('input');
cy.get('[data-test-subj="comboBoxSearchInput"]').type(' {backspace}');

cy.realPress('Enter');

cy.get('[data-test-subj="euiComboBoxPill"]').should('have.length', 1);
cy.get('[data-test-subj="euiComboBoxPill"]').should('have.text', 'a');
});
});

describe('single selection', () => {
Expand Down
20 changes: 20 additions & 0 deletions packages/eui/src/components/combo_box/combo_box.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,26 @@ describe('EuiComboBox', () => {

expect(onCreateOptionHandler).not.toHaveBeenCalled();
});

it('fires the callback only once when adding duplicated values', () => {
const onCreateOptionHandler = jest.fn();

const { getByTestSubject } = render(
<EuiComboBox
delimiter=","
options={options}
selectedOptions={[options[2]]}
onCreateOption={onCreateOptionHandler}
/>
);
const input = getByTestSubject('comboBoxSearchInput');

fireEvent.change(input, { target: { value: 'a, a, a, a' } });
fireEvent.keyDown(input, { key: 'Enter' });

expect(onCreateOptionHandler).toHaveBeenCalledTimes(1);
expect(onCreateOptionHandler).toHaveBeenCalledWith('a', options);
});
});
});

Expand Down
5 changes: 4 additions & 1 deletion packages/eui/src/components/combo_box/combo_box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,10 @@ export class EuiComboBox<T> extends Component<
const { searchValue } = this.state;
const { delimiter } = this.props;
if (delimiter) {
searchValue.split(delimiter).forEach((option: string) => {
const trimmed = searchValue.split(delimiter).map((value) => value.trim());
const values = [...new Set([...trimmed])];

values.forEach((option: string) => {
if (option.length > 0) this.addCustomOption(isContainerBlur, option);
});
} else {
Expand Down

0 comments on commit ed97224

Please sign in to comment.