Material-ui: [Slider] Improve touch passive event handling

Created on 17 Nov 2018  路  11Comments  路  Source: mui-org/material-ui

https://material-ui.com/lab/slider/
You can just open chrome developer console and drag the slider, you will see all the warnings.

bug 馃悰 Slider good first issue

Most helpful comment

@csellis could you PLEASE let me know where/how to add that .sortable-handler { touch-action: none; } ?

All 11 comments

Well I don't. What is your browser/os version?

I'm using Chrome Version 70.0.3538.102 (Official Build) (64-bit) on Ubuntu 18.04.1 LTS

@eps1lon I have recorded the video https://youtu.be/tVmOlY-7UaE

You forgot to mention that this is happening when the device toolbar is enabled.

This is caused by https://www.chromestatus.com/features/5093566007214080 and https://github.com/mui-org/material-ui/blob/master/packages/material-ui-lab/src/Slider/Slider.js#L326

Not sure how to resolve this yet. I guess we can remove this since we're have another non-passive listener that calls preventDefault to prevent scrolling.

@csellis could you PLEASE let me know where/how to add that .sortable-handler { touch-action: none; } ?

The issue was solved, upgrade to the latest version, it should be free from this problem.

@oliviertassinari the issue still exists.
Open sandbox with slider demos (https://5r8pi.csb.app/) and run audit in google chrome.
You will get this:
image

@oliviertassinari so we must wait for Safari support? maybe leave passive only for Safari (is that possible?)
As a workaround, I switched to rc-slider but I'd like to get back to MUI

As a workaround, I switched to rc-slider but I'd like to get back to MUI

@Misiu If you don't need to support iOS, sure, it's great 馃憣

rc-slider

In this context, I would propose that we take a step toward "touch-action: none":

diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js
index 3d3473c83..9d92ead64 100644
--- a/packages/material-ui/src/Slider/Slider.js
+++ b/packages/material-ui/src/Slider/Slider.js
@@ -125,6 +125,8 @@ const axisProps = {

 const Identity = x => x;

+const iOS = typeof navigator !== 'undefined' && /iPad|iPhone|iPod/.test(navigator.userAgent);
+
 export const styles = theme => ({
   /* Styles applied to the root element. */
   root: {
@@ -138,6 +140,8 @@ export const styles = theme => ({
     touchAction: 'none',
     color: theme.palette.primary.main,
     WebkitTapHighlightColor: 'transparent',
+    // Disable scroll capabilities.
+    touchAction: 'none',
     '&$disabled': {
       pointerEvents: 'none',
       cursor: 'default',
@@ -603,8 +607,11 @@ const Slider = React.forwardRef(function Slider(props, ref) {
   });

   const handleTouchStart = useEventCallback(event => {
-    // Workaround as Safari has partial support for touchAction: 'none'.
-    event.preventDefault();
+    if (event.cancelable) {
+      // Workaround as Safari has partial support for touchAction: 'none'.
+      event.preventDefault();
+    }
+
     const touch = event.changedTouches[0];
     if (touch != null) {
       // A number that uniquely identifies the current finger in the touch session.
@@ -627,7 +634,11 @@ const Slider = React.forwardRef(function Slider(props, ref) {

   React.useEffect(() => {
     const { current: slider } = sliderRef;
-    slider.addEventListener('touchstart', handleTouchStart);
+    // TODO: replace with a synthetic event, like onMouseDown.
+    // https://caniuse.com/#search=touch-action
+    slider.addEventListener('touchstart', handleTouchStart, {
+      // Workaround as Safari has partial support for touchAction: 'none'.
+      passive: !iOS,
+    });
     const doc = ownerDocument(slider);

     return () => {
diff --git a/packages/material-ui/src/SwipeableDrawer/SwipeableDrawer.js b/packages/material-ui/src/SwipeableDrawer/SwipeableDrawer.js
index ddd794460..3645c2372 100644
--- a/packages/material-ui/src/SwipeableDrawer/SwipeableDrawer.js
+++ b/packages/material-ui/src/SwipeableDrawer/SwipeableDrawer.js
@@ -115,8 +115,7 @@ function findNativeHandler({ domTreeShapes, start, current, anchor }) {
   });
 }

-const disableSwipeToOpenDefault =
-  typeof navigator !== 'undefined' && /iPad|iPhone|iPod/.test(navigator.userAgent);
+const iOS = typeof navigator !== 'undefined' && /iPad|iPhone|iPod/.test(navigator.userAgent);
 const transitionDurationDefault = { enter: duration.enteringScreen, exit: duration.leavingScreen };

 const useEnhancedEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
@@ -126,7 +125,7 @@ const SwipeableDrawer = React.forwardRef(function SwipeableDrawer(props, ref) {
     anchor = 'left',
     disableBackdropTransition = false,
     disableDiscovery = false,
-    disableSwipeToOpen = disableSwipeToOpenDefault,
+    disableSwipeToOpen = iOS,
     hideBackdrop,
     hysteresis = 0.52,
     minFlingVelocity = 450,

@Misiu feel free to work on it :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

amcasey picture amcasey  路  70Comments

darkowic picture darkowic  路  62Comments

NonameSLdev picture NonameSLdev  路  56Comments

cfilipov picture cfilipov  路  55Comments

iceafish picture iceafish  路  62Comments