Skip to content

Commit

Permalink
polish
Browse files Browse the repository at this point in the history
  • Loading branch information
oliviertassinari committed Oct 9, 2020
1 parent 5954f90 commit f6048ad
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 96 deletions.
99 changes: 28 additions & 71 deletions packages/material-ui/src/Autocomplete/Autocomplete.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2050,77 +2050,34 @@ describe('<Autocomplete />', () => {
});
});

describe('when option is selected', () => {
it('should show all options when popup is opened by focusing on textbox', () => {
const { getAllByRole, getByRole } = render(
<Autocomplete
openOnFocus
options={['one', 'two']}
renderInput={(params) => <TextField {...params} />}
value='one'
/>,
);
const input = getByRole('textbox');
act(() => {
input.blur();
input.focus(); // opens the listbox
});

const options = getAllByRole('option');
expect(options).to.have.length(2);

const listbox = getByRole('listbox');
options.forEach((option) => {
expect(listbox).to.contain(option);
});
});

it('should show all options when popup button is clicked', () => {
const { getAllByRole, getByRole, queryByTitle } = render(
<Autocomplete
options={['one', 'two']}
renderInput={(params) => <TextField {...params} />}
value='one'
/>,
);
fireEvent.click(queryByTitle('Open'));

const options = getAllByRole('option');
expect(options).to.have.length(2);

const listbox = getByRole('listbox');
options.forEach((option) => {
expect(listbox).to.contain(option);
});
});

it('should filter options when new input value matches option', () => {
const handleKeyDown = spy();
const { getAllByRole, getByRole } = render(
<Autocomplete
inputValue="on"
onKeyDown={handleKeyDown}
openOnFocus
options={['one', 'two']}
renderInput={(params) => <TextField {...params} />}
value='one'
/>,
);
const input = getByRole('textbox');
act(() => {
input.blur();
input.focus(); // opens the listbox
});

fireEvent.keyDown(input, { key: 'e' });
expect(handleKeyDown.callCount).to.equal(1);
expect(input.value).to.equal('one');
it('should filter options when new input value matches option', () => {
const handleChange = spy();
const { getAllByRole, getByRole } = render(
<Autocomplete
openOnFocus
options={['one', 'two']}
onChange={handleChange}
renderInput={(params) => <TextField autoFocus {...params} />}
/>,
);
const textbox = getByRole('textbox');
const combobox = getByRole('combobox');

const options = getAllByRole('option');
expect(options).to.have.length(1);

const listbox = getByRole('listbox');
expect(listbox).to.contain(options[0]);
});
fireEvent.change(textbox, { target: { value: 'one' } });
fireEvent.keyDown(textbox, { key: 'ArrowDown' });
fireEvent.keyDown(textbox, { key: 'Enter' });
expect(handleChange.callCount).to.equal(1);
expect(handleChange.args[0][1]).to.deep.equal('one');
expect(combobox).to.have.attribute('aria-expanded', 'false');

fireEvent.keyDown(textbox, { key: 'ArrowDown' });
expect(combobox).to.have.attribute('aria-expanded', 'true');

expect(getAllByRole('option')).to.have.length(2);

fireEvent.change(textbox, { target: { value: 'on' } });
fireEvent.change(textbox, { target: { value: 'one' } });

expect(getAllByRole('option')).to.have.length(1);
});
});
49 changes: 24 additions & 25 deletions packages/material-ui/src/useAutocomplete/useAutocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,30 +177,32 @@ export default function useAutocomplete(props) {
state: 'open',
});

const [inputChange, setInputChange] = React.useState(false);
const [inputPristine, setInputPristine] = React.useState(false);

const inputValueIsSelectedValue =
!multiple && value != null && inputValue === getOptionLabel(value) && inputChange != null && !inputChange;
!multiple &&
value != null &&
inputValue === getOptionLabel(value)

const popupOpen = open;

const filteredOptions = popupOpen
? filterOptions(
options.filter((option) => {
if (
filterSelectedOptions &&
(multiple ? value : [value]).some(
(value2) => value2 !== null && getOptionSelected(option, value2),
)
) {
return false;
}
return true;
}),
// we use the empty string to manipulate `filterOptions` to not filter any options
// i.e. the filter predicate always returns true
{ inputValue: inputValueIsSelectedValue ? '' : inputValue, getOptionLabel },
)
options.filter((option) => {
if (
filterSelectedOptions &&
(multiple ? value : [value]).some(
(value2) => value2 !== null && getOptionSelected(option, value2),
)
) {
return false;
}
return true;
}),
// we use the empty string to manipulate `filterOptions` to not filter any options
// i.e. the filter predicate always returns true
{ inputValue: inputValueIsSelectedValue && inputPristine ? '' : inputValue, getOptionLabel },
)
: [];

const listboxAvailable = open && filteredOptions.length > 0;
Expand All @@ -215,10 +217,9 @@ export default function useAutocomplete(props) {
console.warn(
[
`Material-UI: The value provided to ${componentName} is invalid.`,
`None of the options match with \`${
missingValue.length > 1
? JSON.stringify(missingValue)
: JSON.stringify(missingValue[0])
`None of the options match with \`${missingValue.length > 1
? JSON.stringify(missingValue)
: JSON.stringify(missingValue[0])
}\`.`,
'You can use the `getOptionSelected` prop to customize the equality test.',
].join('\n'),
Expand Down Expand Up @@ -497,7 +498,7 @@ export default function useAutocomplete(props) {
}

setOpenState(true);
setInputChange(false);
setInputPristine(true);

if (onOpen) {
onOpen(event);
Expand Down Expand Up @@ -814,13 +815,11 @@ export default function useAutocomplete(props) {

if (inputValue !== newValue) {
setInputValueState(newValue);
setInputChange(true);
setInputPristine(false);

if (onInputChange) {
onInputChange(event, newValue, 'input');
}
} else {
setInputChange(false);
}

if (newValue === '') {
Expand Down

0 comments on commit f6048ad

Please sign in to comment.