Skip to content

Commit

Permalink
[material-ui][Autocomplete] Fix bug with child chip button events pro…
Browse files Browse the repository at this point in the history
…pagating to parent (#43982)
  • Loading branch information
snapwich authored Oct 16, 2024
1 parent 1b40ca5 commit 064fa67
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 36 deletions.
6 changes: 5 additions & 1 deletion packages/mui-material/src/Autocomplete/Autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,11 @@ const Autocomplete = React.forwardRef(function Autocomplete(inProps, ref) {
ref: setAnchorEl,
className: classes.inputRoot,
startAdornment,
onMouseDown: (event) => handleInputMouseDown(event),
onMouseDown: (event) => {
if (event.target === event.currentTarget) {
handleInputMouseDown(event);
}
},
...((hasClearIcon || hasPopupIcon) && {
endAdornment: (
<AutocompleteEndAdornment className={classes.endAdornment} ownerState={ownerState}>
Expand Down
76 changes: 43 additions & 33 deletions packages/mui-material/src/Autocomplete/Autocomplete.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -442,39 +442,6 @@ describe('<Autocomplete />', () => {
expect(getAllByRole('button', { hidden: false })).to.have.lengthOf(5);
}
});

// Test for https://github.com/mui/material-ui/issues/42432
it('when the input box needs to expand downward, the listbox should remain open.', () => {
const options = [
'The Lord of the Rings: The Return of the King',
'The Good, the Bad and the Ugly',
'The Shawshank Redemption',
'Star Wars: Episode V - The Empire Strikes Back',
];
const defaultValue = [
'The Lord of the Rings: The Return of the King',
'The Good, the Bad and the Ugly',
'The Shawshank Redemption',
];

render(
<Autocomplete
multiple
limitTags={2}
options={options}
defaultValue={defaultValue}
renderInput={(params) => <TextField {...params} />}
sx={{ width: 500 }}
/>,
);

const textbox = screen.getByRole('combobox');

fireEvent.mouseDown(textbox);

const listbox = screen.getByRole('listbox');
expect(listbox).toBeVisible();
});
});

describe('prop: filterSelectedOptions', () => {
Expand Down Expand Up @@ -892,6 +859,49 @@ describe('<Autocomplete />', () => {
expect(handleSubmit.callCount).to.equal(4);
});

it('should not open the autocomplete popup when deleting chips', async () => {
const { queryByRole, queryByText, user } = render(
<Autocomplete
multiple
options={['one', 'two', 'three']}
defaultValue={['one']}
renderInput={(params) => <TextField {...params} autoFocus />}
/>,
);

expect(queryByRole('listbox')).to.equal(null);

const chip = queryByText('one').parentElement;
expect(chip).not.to.equal(null);

// Delete the chip
await user.click(chip.getElementsByClassName(chipClasses.deleteIcon)[0]);

expect(queryByText('one')).to.equal(null);
expect(queryByRole('listbox')).to.equal(null);
});

it('should toggle the autocomplete popup when clicking the popup indicator', async () => {
const { queryByRole, getByRole, user } = render(
<Autocomplete
multiple
options={['One', 'Two', 'Three']}
renderInput={(params) => <TextField {...params} autoFocus />}
/>,
);

expect(queryByRole('listbox')).to.equal(null);

const popupIndicator = getByRole('button', { name: 'Open' });
await user.click(popupIndicator);

expect(queryByRole('listbox')).not.to.equal(null);

await user.click(popupIndicator);

expect(queryByRole('listbox')).to.equal(null);
});

describe('prop: getOptionDisabled', () => {
it('should prevent the disabled option to trigger actions but allow focus with disabledItemsFocusable', () => {
const handleSubmit = spy();
Expand Down
2 changes: 0 additions & 2 deletions packages/mui-material/src/useAutocomplete/useAutocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -1020,7 +1020,6 @@ function useAutocomplete(props) {
const handleInputMouseDown = (event) => {
if (!disabledProp && (inputValue === '' || !open)) {
handlePopupIndicator(event);
event.stopPropagation();
}
};

Expand Down Expand Up @@ -1109,7 +1108,6 @@ function useAutocomplete(props) {
tabIndex: -1,
type: 'button',
onClick: handlePopupIndicator,
onMouseDown: (event) => event.stopPropagation(),
}),
getTagProps: ({ index }) => ({
key: index,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as React from 'react';
import TextField from '@mui/material/TextField';
import Autocomplete from '@mui/material/Autocomplete';

export default function StandardAutocomplete() {
return (
<div style={{ height: 220 }}>
<Autocomplete
multiple
limitTags={2}
options={['One', 'Two', 'Three']}
defaultValue={['One', 'Two', 'Three']}
renderInput={(params) => <TextField {...params} />}
sx={{ width: 300 }}
/>
</div>
);
}
14 changes: 14 additions & 0 deletions test/regressions/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,20 @@ async function main() {
await takeScreenshot({ testcase, route: '/regression-Rating/PreciseFocusVisibleRating3' });
});
});

describe('Autocomplete', () => {
it('should not close immediately when textbox expands', async () => {
const testcase = await renderFixture(
'/regression-Autocomplete/TextboxExpandsOnListboxOpen',
);
await page.getByRole('combobox').click();
await page.waitForTimeout(10);
await takeScreenshot({
testcase,
route: '/regression-Autocomplete/TextboxExpandsOnListboxOpen2',
});
});
});
});

run();
Expand Down

0 comments on commit 064fa67

Please sign in to comment.