Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Select] Button is being clicked beneath on responsive #439

Open
llezhava opened this issue Apr 5, 2024 · 4 comments
Open

[Select] Button is being clicked beneath on responsive #439

llezhava opened this issue Apr 5, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@llezhava
Copy link

llezhava commented Apr 5, 2024

Hello everyone!

On my website, I have Select inputs, and below them is the Button component. When I click on the item, the button beneath is being clicked (if the button is below the given item).

  1. Go to reproduction
  2. Open responsive view in chrome console (mobile device must be selected)
  3. Open the select & Click on "Green" option
  4. Check console log, "Button clicked" will be logged.

I observed, that when I click on it from mobile device, two clicks are being registered, and the next click is landing on button.

Right now my fix is to make all the dropdowns above this Button controlled & disable pointer events on a button, while they are open. (And reenable via setTimeout)

  const isSelectOpen = select1Open || select2Open || select3Open;
  const [disableBtnClick, setDisableBtnClick] = useState(false);

  useEffect(() => {
    let timeout: any;
    if (isSelectOpen) {
      setDisableBtnClick(true);
    } else {
      timeout = setTimeout(() => {
        setDisableBtnClick(false);
      }, 10);

      return () => {
        clearTimeout(timeout);
      };
    }
  }, [isSelectOpen]);

@vladmoroz
Copy link
Contributor

vladmoroz commented Apr 5, 2024

Huh this is unexpected
Do you see the issue on an actual mobile device too?

@llezhava
Copy link
Author

llezhava commented Apr 5, 2024

Huh this is unexpected Do you see the issue on an actual mobile device too?

Yeah, I noticed it on my Android device (Chrome) first.

@vladmoroz
Copy link
Contributor

@benoitgrelard is this a primitives bug?

@vladmoroz vladmoroz added the bug Something isn't working label Apr 8, 2024
@llezhava
Copy link
Author

llezhava commented May 19, 2024

I worked on this issue more, because in my case selects were not usable. (I have around 100 items) in the select and items beneath are getting clicked.

I found this issue is because that we're using onPointerDown / onPointerUp events to trigger select open/close.

On mobile devices, the event is not being stopped, and "click" event is getting activated on what's below.

I tried to fix it by "prevenDefault" or "stopPropagation", but this didn't help.

I did patch @radix-ui/react-select to use "onClick" events instead. Now it's working fine, and this issue: #454 also got fixed.

Issue is, that the the component feels slower now (and it actually is). It's better to be fixed with onPointerUp/Down, but it'll require more work.

diff --git a/dist/index.mjs b/dist/index.mjs
index 53fb4dec7748aa9c3f1184402c1bb517f6abe951..f1a832673e3e12ce69bd12b413a3bedf78ba81c9 100644
--- a/dist/index.mjs
+++ b/dist/index.mjs
@@ -194,23 +194,24 @@ const $cc7e05a45900e73f$export$3ac1e88a1c0b9f1 = /*#__PURE__*/ $01b9c$forwardRef
             // because we are preventing default in `onPointerDown` so effectively
             // this only runs for a label "click"
             event.currentTarget.focus();
+            handleOpen();
         }),
-        onPointerDown: $01b9c$composeEventHandlers(triggerProps.onPointerDown, (event)=>{
-            // prevent implicit pointer capture
-            // https://www.w3.org/TR/pointerevents3/#implicit-pointer-capture
-            const target = event.target;
-            if (target.hasPointerCapture(event.pointerId)) target.releasePointerCapture(event.pointerId);
-             // only call handler if it's the left button (mousedown gets triggered by all mouse buttons)
-            // but not when the control key is pressed (avoiding MacOS right click)
-            if (event.button === 0 && event.ctrlKey === false) {
-                handleOpen();
-                context.triggerPointerDownPosRef.current = {
-                    x: Math.round(event.pageX),
-                    y: Math.round(event.pageY)
-                }; // prevent trigger from stealing focus from the active item after opening.
-                event.preventDefault();
-            }
-        }),
+        // onPointerDown: $01b9c$composeEventHandlers(triggerProps.onPointerDown, (event)=>{
+        //     // prevent implicit pointer capture
+        //     // https://www.w3.org/TR/pointerevents3/#implicit-pointer-capture
+        //     const target = event.target;
+        //     if (target.hasPointerCapture(event.pointerId)) target.releasePointerCapture(event.pointerId);
+        //      // only call handler if it's the left button (mousedown gets triggered by all mouse buttons)
+        //     // but not when the control key is pressed (avoiding MacOS right click)
+        //     if (event.button === 0 && event.ctrlKey === false) {
+        //         handleOpen();
+        //         context.triggerPointerDownPosRef.current = {
+        //             x: Math.round(event.pageX),
+        //             y: Math.round(event.pageY)
+        //         }; // prevent trigger from stealing focus from the active item after opening.
+        //         event.preventDefault();
+        //     }
+        // }),
         onKeyDown: $01b9c$composeEventHandlers(triggerProps.onKeyDown, (event)=>{
             const isTypingAhead = searchRef.current !== '';
             const isModifierKey = event.ctrlKey || event.altKey || event.metaKey;
@@ -896,7 +897,8 @@ const $cc7e05a45900e73f$export$13ef48a934230896 = /*#__PURE__*/ $01b9c$forwardRe
         ),
         onBlur: $01b9c$composeEventHandlers(itemProps.onBlur, ()=>setIsFocused(false)
         ),
-        onPointerUp: $01b9c$composeEventHandlers(itemProps.onPointerUp, handleSelect),
+        onPointerUp: $01b9c$composeEventHandlers(itemProps.onPointerUp),
+        onClick: $01b9c$composeEventHandlers(itemProps.onClick, handleSelect),
         onPointerMove: $01b9c$composeEventHandlers(itemProps.onPointerMove, (event)=>{
             if (disabled) {
                 var _contentContext$onIte;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants