fix(Select): Touch scroll triggers the select content #807
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR aims to improve the behavior of the
Select
component on touch devices.Fixes: #804
The Problem
On the latest version of Radix UI (v1.6.1) if you try to scroll on a touch screen device and the initial tap to begin the scroll gesture fell on the
SelectTrigger
, it prevents scrolling and immediately opens theSelectContent
.This behavior feels wrong to the end user because they expect to be able to scroll by tapping anywhere on the screen. But if they tap on any
SelectTrigger
, not only does it lock scrolling, it also opens theSelectContent
and feels like a bug.See #804 for more details.
The Cause
The issue was caused by the
SelectTrigger
opening theSelectContent
via the@pointerdown
event, which feels normal with a mouse, but on touch devices it gets triggered immediately after touching the screen, even if it's for a gesture.This was done because if we triggered the open event on
@click
, restoring the focus on theSelectTrigger
after the content closes caused it to get triggered again, so theSelectContent
did not get closed onEnter
.The Solution
This proposal replaces the
@pointerdown
with@pointerup
and follows the same behavior as theDropdownMenuTrigger
to prevent focus competition.It also removes the
watchEffect
fromSelectContentImpl.vue
that prevented the@pointerdown
event from selecting an option accidentally. Since we now use@pointerup
, the pointer is no longer interacting and cannot trigger an item. (This was also the behavior that prevented an option from being selected until a secondpointerup
event was triggered)I updated the tests to use
@pointerup
as well. I also tested on Safari, Chrome and Firefox on both iOS, MacOS, Windows and Android and the behavior seems to work as expected.