radix-ui / primitives

Radix Primitives is an open-source UI component library for building high-quality, accessible design systems and web apps. Maintained by @workos.
https://radix-ui.com/primitives
MIT License
15.38k stars 768 forks source link

[Dialog] Unable to pinch zoom using trackpad #1554

Open chesterhow opened 2 years ago

chesterhow commented 2 years ago

Bug report

Congrats on the 1.0 release! I see that the allowPinchZoom prop has been removed and now defaults to true. However, there is still an issue with pinch zooming: it is not supported on trackpads.

I understand that allowPinchZoom is a prop for the underlying react-remove-scroll library, and I filed an issue with them a couple of weeks back (https://github.com/theKashey/react-remove-scroll/issues/75). The maintainer has acknowledged the issue but it doesn't seem like there will be a fix anytime soon.

Current Behavior

When a dialog is open (or any primitive that uses react-remove-scroll), I am unable to pinch-and-zoom the webpage using the trackpad.

Expected behavior

I should still be able to pinch-and-zoom using the webpage when the dialog is open.

Reproducible example

This is reproducible in the dialog example in the Radix docs: https://www.radix-ui.com/docs/primitives/components/dialog

Additional context

I am using Dialog to render a full-screen modal of sorts which displays an image. An expected common behavior here would be that I am able to pinch-and-zoom on the image.

alii commented 1 year ago

Able to reproduce this using the Context Menu component in @radix-ui/react-context-menu@2.1.0🙂

JasperAlexander commented 1 year ago

Is there already a solution to this problem?

benoitgrelard commented 1 year ago

Hi @chesterhow,

Yeah this is strange, we specifically enabled pinchZooming on react-remove-scroll:

https://github.com/radix-ui/primitives/blob/6ad72cb90e7820182de778028d4acd1f006999c6/packages/react/dialog/src/Dialog.tsx#L200

We made this change in this PR: #1514 for exactly the reasons you are talking about.

Unfortunately, if the fix is not made upstream, there isn't much we can do at the moment. We did experiment with ditching react-remove-scroll but haven't had the bandwidth to pursue this further.

I would suggest you all continue working with the upstream library to push for a fix which we can then integrate.

:pray:

origamisage commented 11 months ago

I just ran into this today, the way I got it working is a bit hacky: Idea is to set body's overflow to hidden when dialog is opened to prevent scrolling behavior of content behind the dialog and then set it back to initial once closed.

tangye1234 commented 6 months ago

I use pnpm, so I can use overrides and pnpm patch to resolve the issue by patch react-remove-scroll.

It is a neat resolution that everyone can take without breaking structures of dependencies.

  1. Make sure you use pnpm.
  2. In your root package.json, override react-remove-scroll package to the latest version 2.5.7:
    {
    ...
    "resolutions": {
    "react-remove-scroll": "2.5.7"
    }
    }
  3. execute pnpm install to make use of only one version of react-remove-scroll. If you didn't install react-remove-scroll at any place, nor any workspaces yet, just install this package to the workspace that depends on radixui dialog / shadcn before you override package.
  4. execute pnpm patch react-remove-scroll@2.5.7, it will tell you to move on to a tmp directory to fix this lib.
  5. find the code at dist/esXXX/SideEffect.js(XXX means multiple directories es5 / es2015/es2019): https://github.com/theKashey/react-remove-scroll/blob/bd8d6433319b67eabf350d7ec2fa4f17627af417/src/SideEffect.tsx#L57

and change this condition to

if (('touches' in event && event.touches.length === 2) || (event.type === 'wheel' && event.ctrlKey)) {
...
}

This is because it dose not support pinch zoom action on magic track pad, which event is wheel + ctrlKey

  1. just do as it tells you, execute pnpm patch-commit XXXXX

now you can pinch and zoom on the dialog.

dzucconi commented 1 month ago

A related problem is that this disables other gestures like swipe back, so if you, for instance, have a route that is opened in a dialog, that breaks the gesture for back.