diff --git a/packages/material-ui/src/Select/Select.test.js b/packages/material-ui/src/Select/Select.test.js
index 9db1aa24b77415..81c3c8cd98735d 100644
--- a/packages/material-ui/src/Select/Select.test.js
+++ b/packages/material-ui/src/Select/Select.test.js
@@ -116,6 +116,7 @@ describe('', () => {
const trigger = getByRole('button');
fireEvent.mouseDown(trigger);
+ fireEvent.click(trigger);
expect(handleBlur.callCount).to.equal(0);
expect(getByRole('listbox')).not.to.equal(null);
@@ -246,7 +247,9 @@ describe('', () => {
,
);
- fireEvent.mouseDown(getByRole('button'));
+ const button = getByRole('button');
+ fireEvent.mouseDown(button);
+ fireEvent.click(button);
getAllByRole('option')[1].click();
expect(onChangeHandler.calledOnce).to.equal(true);
@@ -265,7 +268,9 @@ describe('', () => {
,
);
- fireEvent.mouseDown(getByRole('button'));
+ const button = getByRole('button');
+ fireEvent.mouseDown(button);
+ fireEvent.click(button);
getAllByRole('option')[1].click();
expect(eventLog).to.deep.equal(['CHANGE_EVENT', 'CLOSE_EVENT']);
@@ -724,7 +729,9 @@ describe('', () => {
}
const { getByRole, queryByRole } = render();
- fireEvent.mouseDown(getByRole('button'));
+ const button = getByRole('button');
+ fireEvent.mouseDown(button);
+ fireEvent.click(button);
expect(getByRole('listbox')).not.to.equal(null);
act(() => {
@@ -921,7 +928,9 @@ describe('', () => {
});
const { getByRole, getAllByRole } = render();
- fireEvent.mouseDown(getByRole('button'));
+ const button = getByRole('button');
+ fireEvent.mouseDown(button);
+ fireEvent.click(button);
const options = getAllByRole('option');
fireEvent.click(options[2]);
diff --git a/packages/material-ui/src/Select/SelectInput.js b/packages/material-ui/src/Select/SelectInput.js
index 9923a9b2a508f3..08a53e468fd972 100644
--- a/packages/material-ui/src/Select/SelectInput.js
+++ b/packages/material-ui/src/Select/SelectInput.js
@@ -74,6 +74,9 @@ const SelectInput = React.forwardRef(function SelectInput(props, ref) {
const [menuMinWidthState, setMenuMinWidthState] = React.useState();
const [openState, setOpenState] = React.useState(false);
const handleRef = useForkRef(ref, inputRefProp);
+ const handleClick = React.useRef(null);
+ const menuRef = React.useRef(null);
+ const disablePointerEvents = React.useRef(false);
const handleDisplayRef = React.useCallback((node) => {
displayRef.current = node;
@@ -83,6 +86,14 @@ const SelectInput = React.forwardRef(function SelectInput(props, ref) {
}
}, []);
+ const handleMenuRef = React.useCallback((node) => {
+ menuRef.current = node;
+
+ if (node && disablePointerEvents.current) {
+ node.style.pointerEvents = 'none';
+ }
+ }, []);
+
React.useImperativeHandle(
handleRef,
() => ({
@@ -95,6 +106,15 @@ const SelectInput = React.forwardRef(function SelectInput(props, ref) {
[value],
);
+ React.useEffect(() => {
+ const doc = ownerDocument(inputRef.current);
+ return () => {
+ if (handleClick.current) {
+ doc.removeEventListener('click', handleClick.current);
+ }
+ };
+ }, []);
+
React.useEffect(() => {
if (autoFocus) {
displayRef.current.focus();
@@ -141,6 +161,21 @@ const SelectInput = React.forwardRef(function SelectInput(props, ref) {
event.preventDefault();
displayRef.current.focus();
+ const doc = ownerDocument(inputRef.current);
+ if (handleClick.current) {
+ doc.removeEventListener('click', handleClick.current);
+ }
+
+ // Disable menu pointer events between `mousedown` and `click`.
+ disablePointerEvents.current = true;
+ handleClick.current = () => {
+ disablePointerEvents.current = false;
+ menuRef.current.style.pointerEvents = 'auto';
+ doc.removeEventListener('click', handleClick.current);
+ handleClick.current = null;
+ };
+ doc.addEventListener('click', handleClick.current);
+
update(true, event);
};
@@ -426,6 +461,7 @@ const SelectInput = React.forwardRef(function SelectInput(props, ref) {
})}
/>