Material-ui: [Slider] Component doesn't allow for preventing event propagation for drag-related event handlers.

Created on 17 Feb 2020  路  8Comments  路  Source: mui-org/material-ui

Summary

Using <Slider> as a child of a React component that also listens for drag events, when I drag the Slider, the parent component event handlers are triggered. (I think - actually I'm a little out of my depth in terms of how these libraries are handling events and which events are being handled)

  • [x] The issue is present in the latest release.
  • [x] I have searched the issues of this repository and believe that this is not a duplicate. To my knowledge this issue hasn't been raised yet (although it could be related to an issue that I wouldn't have known to search for - in which case I apologize!)

Example code

This is the most basic usage example of react-beautiful-dnd, with a list of 10 items that can be reordered. Each of these items contains a slider that shows the problem I am experiencing (that the slider's can't be dragged without triggering the dnd drag): https://codesandbox.io/s/recursing-nightingale-issyt?fontsize=14&hidenavigation=1&theme=dark (in the Demo.js file)

Current Behavior 馃槸

When trying to update the slider value by drag, the parent component event handlers are fired (see the demo). Updating the slider value by clicking works fine.

Expected Behavior 馃

I expected that any event explicitly handled by <Slider> would not then bubble up to parent components. Or, I would like to be able to 'manually' prevent this by using ev.stopPropagation. However, having tried this in the onChange event handler I know that this doesn't work. I assume that the onChange handler is an abstraction over other event handlers that I DON'T have access to?

Steps to Reproduce 馃暪

The bug/behaviour (technically I'm not sure that this can be considered a bug per say) is reproduced in the codesanbox example linked to above.

Steps:

  1. Try adjusting a slider (it doesn't work)
  2. Change isDragDisabled to true (line 83 of Demo.js), then refresh the page
  3. Dragging the slider now works

Context 馃敠

I have found that disabling the ability to drag on the parent element allows me to then using the Slider. So, my current workaround is registering onMouseEnter and onMouseLeave handlers that sets a property on the parent component to disable / enable drag. But I think this is probably inefficient.. since I imagine that I am rerendering the Draggable component more than I have to (I'm not 100% clear on this).

Slider

Most helpful comment

@zachsa The Slider has a touch-action CSS property, hence the behavior you are seeing on mobile. The issue is on desktop.

All 8 comments

Just out of interest, I see that there is the same problem when using a slider from react-md library: https://codesandbox.io/s/upbeat-mahavira-87ikz?fontsize=14&hidenavigation=1&theme=dark

Interesting. We had almost the same discussion in #16565. I think that we can move forward with: https://github.com/mui-org/material-ui/issues/16565#issuecomment-510426544

Hi, is anyone still working on this?
I was looking at the discussion in #16565 and the comment you suggested above, do you want to add the event.stopPropagation() or something more inline with the last suggestion there (https://github.com/mui-org/material-ui/issues/16565#issuecomment-544137595)?

@brorlarsnicklas You are free to go. It's interesting to compare the behavior with a native slider. If you could figure out what makes it work correctly in https://codesandbox.io/s/boring-platform-tkel2. It would be awesome.

Capture d鈥檈虂cran 2020-09-15 a虁 22 01 21

@oliviertassinari I have been looking at the sandbox example and I'm not sure if this is any new information but, I think that there is some diff between how the slider component handles touch events and mouse events. Changing the slider in the sandbox with a touchscreen makes the slider behave correctly (works with both a computer with touchscreen and a phone). Is there a way to adapt the behavior of the touch event to the mouse event?

Since I'm quite new to this I'm not really sure where to look in the slider code though. Any suggestions?

Here is an example using my phone:
touch

@zachsa The Slider has a touch-action CSS property, hence the behavior you are seeing on mobile. The issue is on desktop.

@zachsa react-beautiful-dnd has a custom logic to handle <input type="range" />. They also describe how they behave in https://github.com/atlassian/react-beautiful-dnd/blob/24a8e6021600920c0b2a28f89d5ffb17538fe96c/docs/guides/how-we-use-dom-events.md. I don't think that there is anything we should change. I'm closing.

Any ugly workaround would be to set <div contentEditable> for react-beautiful-dnd. However, I'm not sure what would be the best workaround. Maybe @alexreardon has some tips.

Was this page helpful?
0 / 5 - 0 ratings