JedWatson / JedWatson/react-select
Touch events do not work when `<Select />` is mounted in a shadow root
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 28k
- Forks
- 4.1k
- PR merge metrics
- No merged PRs in 30d
Description
Hi,
the current approach to touch event handling does not work well when <Select /> is used with a shadow root.
Reproduction
- Open Stackblitz: https://stackblitz.com/edit/stackblitz-starters-pandyv?file=src%2FApp.tsx
- The Select component works well using clicks (the Menu opens when clicking into the input)
- Open your browser's mobile device emulation (or use a touch device) and touch into the input field
- The menu does not open
Notes
- The menu actually opens internally, but it is hidden immediately because the
onTouchEndevent handler categorizes the touch event as outside the select control (this results in ablurInput()call) - When inside a shadow root, the event handler registered on the document will not observe the original
.target, but the entire shadow dom. This is obviously not contained in the original node, which causes the behavior in this case. - A more stable alternative to
.contains(...)is to useevent.composedPath()instead. See also this blog post.
I've had trouble creating a unit test for this bug (I could not get touch events inside shadow DOM to work with jest). I hope that the sample above will be sufficient.
I think a fix would look as simple as replacing node.contains(event.target) with event.composedPath().includes(node). I'll gladly create a PR for this.
Kind regards
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in packages/react-select/src/Select.tsx at the onTouchEnd handler around line 1461, then reproduce the issue with the linked StackBlitz example using a Select mounted in a shadow root. Check the touch event's target handling and add or update coverage if feasible; done means touching the input opens the menu instead of immediately hiding it.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100