Skip to content

Commit

Permalink
[Autocomplete] Warn when using wrong getOptionSelected (#19699)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmad-reza619 authored Feb 20, 2020
1 parent 5ed8d0a commit a5a3785
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
30 changes: 30 additions & 0 deletions packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,36 @@ describe('<Autocomplete />', () => {
'For the input option: "a", `getOptionLabel` returns: undefined',
);
});

it('warn if getOptionSelected match multiple values for a given option', () => {
const value = [{ id: '10', text: 'One' }, { id: '20', text: 'Two' }];
const options = [
{ id: '10', text: 'One' },
{ id: '20', text: 'Two' },
{ id: '30', text: 'Three' },
];

render(
<Autocomplete
{...defaultProps}
multiple
options={options}
value={value}
getOptionLabel={option => option.text}
getOptionSelected={option => value.find(v => v.id === option.id)}
renderInput={params => <TextField {...params} autoFocus />}
/>,
);

fireEvent.keyDown(document.activeElement, { key: 'ArrowDown' });
fireEvent.keyDown(document.activeElement, { key: 'ArrowDown' });
fireEvent.keyDown(document.activeElement, { key: 'Enter' });

expect(consoleErrorMock.callCount()).to.equal(1); // strict mode renders twice
expect(consoleErrorMock.args()[0][0]).to.include(
'The component expects a single value to match a given option but found 2 matches.',
);
});
});

describe('prop: options', () => {
Expand Down
15 changes: 15 additions & 0 deletions packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,21 @@ export default function useAutocomplete(props) {
const item = newValue;
newValue = Array.isArray(value) ? [...value] : [];

if (process.env.NODE_ENV !== 'production') {
const matches = newValue.filter(val => getOptionSelected(item, val));

if (matches.length > 1) {
console.error(
[
'Material-UI: the `getOptionSelected` method of useAutocomplete do not handle the arguments correctly.',
`The component expects a single value to match a given option but found ${
matches.length
} matches.`,
].join('\n'),
);
}
}

const itemIndex = findIndex(newValue, valueItem => getOptionSelected(item, valueItem));

if (itemIndex === -1) {
Expand Down

0 comments on commit a5a3785

Please sign in to comment.