Skip to content

Elements within custom Menu components are not interactable on touch devices #6071

@iranana

Description

@iranana

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>
  );
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    issue/bug-unconfirmedIssues that describe a bug that hasn't been confirmed by a maintainer yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions