-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Description
Custom Menu components that contain elements outside of the MenuList can't be interacted with on touch devices. A valid use case for this is building menus with buttons/tooltips/links/checkboxes as a header/footer elements above/below the list of options.
This occurs because the touch handlers check whether the event target is a child of the MenuList ref, and if not, blurs the input (thereby closing the menu). For this to work as expected, the handler should also check whether the element is a child of the Menu ref.
For example:
const CustomMenu = (props) => {
return (
<components.Menu {...props}>
<div>Header</div> // <- Can't click anything inside on touch
{props.children}
<div>Footer</div> // <- Can't click anything inside on touch
</components.Menu>
);
};
<Select
...
components={{ Menu: CustomMenu }}
/>
A Codesandbox demonstrating this issue can be found here: https://codesandbox.io/p/sandbox/modest-cdn-xz7kls. There is a workaround for this issue, which is to add a touchEnd
listener on the element that prevents propagation of the event, i.e:
const CustomMenu = (props) => {
return (
<components.Menu {...props}>
<div onTouchEnd={e => e.stopPropagation()}>Header</div>
{props.children}
<div onTouchEnd={e => e.stopPropagation()}>Footer</div>
</components.Menu>
);
};