Skip to content

Commit

Permalink
[Autocomplete] Fix unexpected clearing (#19511)
Browse files Browse the repository at this point in the history
  • Loading branch information
captain-yossarian authored Feb 4, 2020
1 parent 4f07472 commit 6a61ec8
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 8 deletions.
44 changes: 44 additions & 0 deletions packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,51 @@ describe('<Autocomplete />', () => {
});
});

describe('prop: autoHighlight', () => {
it('should set the focus on the first item', () => {
const options = ['one', 'two'];
const { getByRole } = render(
<Autocomplete
freeSolo
autoHighlight
options={options}
renderInput={params => <TextField autoFocus {...params} />}
/>,
);

function checkHighlightIs(expected) {
expect(getByRole('listbox').querySelector('li[data-focus]')).to.have.text(expected);
}

checkHighlightIs('one');
fireEvent.change(document.activeElement, { target: { value: 'oo' } });
fireEvent.change(document.activeElement, { target: { value: 'o' } });
checkHighlightIs('one');
});
});

describe('prop: autoSelect', () => {
it('should not clear on blur when value does not match any option', () => {
const handleChange = spy();
const options = ['one', 'two'];

render(
<Autocomplete
freeSolo
autoSelect
options={options}
onChange={handleChange}
renderInput={params => <TextField autoFocus {...params} />}
/>,
);
fireEvent.change(document.activeElement, { target: { value: 'o' } });
fireEvent.keyDown(document.activeElement, { key: 'ArrowDown' });
fireEvent.change(document.activeElement, { target: { value: 'oo' } });
document.activeElement.blur();
expect(handleChange.callCount).to.equal(1);
expect(handleChange.args[0][1]).to.deep.equal('oo');
});

it('should add new value when autoSelect & multiple on blur', () => {
const handleChange = spy();
const options = ['one', 'two'];
Expand Down
17 changes: 9 additions & 8 deletions packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ export default function useAutocomplete(props) {
const [focusedTag, setFocusedTag] = React.useState(-1);
const defaultHighlighted = autoHighlight ? 0 : -1;
const highlightedIndexRef = React.useRef(defaultHighlighted);
const selectedIndexRef = React.useRef(-1);

function setHighlightedIndex(index, mouse = false) {
highlightedIndexRef.current = index;
Expand Down Expand Up @@ -373,7 +372,6 @@ export default function useAutocomplete(props) {

const nextIndex = validOptionIndex(getNextIndex(), direction);
setHighlightedIndex(nextIndex);
selectedIndexRef.current = nextIndex;

if (autoComplete && diff !== 'reset') {
if (nextIndex === -1) {
Expand Down Expand Up @@ -454,8 +452,6 @@ export default function useAutocomplete(props) {
if (!disableCloseOnSelect) {
handleClose(event);
}

selectedIndexRef.current = -1;
};

function validTagIndex(index, direction) {
Expand Down Expand Up @@ -656,8 +652,8 @@ export default function useAutocomplete(props) {
return;
}

if (autoSelect && selectedIndexRef.current !== -1) {
selectNewValue(event, filteredOptions[selectedIndexRef.current]);
if (autoSelect && highlightedIndexRef.current !== -1 && popupOpen) {
selectNewValue(event, filteredOptions[highlightedIndexRef.current]);
} else if (autoSelect && freeSolo && inputValue !== '') {
selectNewValue(event, inputValue, 'freeSolo');
} else if (!freeSolo) {
Expand Down Expand Up @@ -730,8 +726,13 @@ export default function useAutocomplete(props) {
return;
}

// Restore the focus to the correct option.
setHighlightedIndex(highlightedIndexRef.current);
// Automatically select the first option as the listbox become visible.
if (highlightedIndexRef.current === -1 && autoHighlight) {
changeHighlightedIndex('reset', 'next');
} else {
// Restore the focus to the correct option.
setHighlightedIndex(highlightedIndexRef.current);
}
});

const handlePopupIndicator = event => {
Expand Down

0 comments on commit 6a61ec8

Please sign in to comment.