bokuweb/react-rnd

Scrollbar is not Clickable

GabrielFerrarini opened this issue · 6 comments

Overview of the problem

I'm using react-rnd version [10.1.10]

My browser is: Chrome (83.0.4103.116)

I am sure this issue is not a duplicate?

Reproduced project

https://codesandbox.io/s/confident-hill-oee4i

Description

The scrollbar is not clickable when overflow is auto

Although it's visible

image

and its style change when we hover over it

image

we can't click on it

Steps to Reproduce

  1. Go to https://codesandbox.io/s/confident-hill-oee4i
  2. Try to scroll by clicking on the scrollbar
  3. Moving the style into the <Rnd /> component doesn't fix it

Expected behavior

For the content to scroll when the scrollbar buttons and bar are clicked

Actual behavior

Nothing happens, although the DOM indicates that the dragging starts by adding the react-draggable-dragging class to the draggable component

miqh commented

@GabrielFerrarini, I just stumbled across a similar problem myself.

I found this behaviour is exacerbated by the specification of the bounds prop. If you get rid of the latter, you should be able to use the scrollbar.

I had a look at the source to see if there's an easy fix. Couldn't find one, but I believe the problem is in the onDragStart handler.

onDragStart(e: RndDragEvent, data: DraggableData) {

I think what's missing is that this handler needs to check whether the clicked point falls within the scrollbar area. A check could be made by using the click target, then checking whether the X is greater than clientX + clientWidth (because clientWidth < offsetWidth if a scrollbar exists). If there's an intersection, it needs to use this information somehow before immediately updating bounds via setState().

Still unsure though. 🤷

bind mousedown event on the scrollable div can fix this, like:

<Rnd>
 <div onMouseDown={e => e.stopPropagation()} style={{marginTop: 20}}></div>
</Rnd>

To whomever is still struggling with this in 2022:) As mentioned above, listen to the mousedown event in the container that has scrollbars. Check if the click happened in the scrollbar space and stop it from propagating.

const isScrollbarClicked = (e: MouseEvent<HTMLElement>): boolean => {
  const target = e.target as Element
  return (
    e.nativeEvent.offsetX > target.clientWidth ||
    e.nativeEvent.offsetY > target.clientHeight
  )
}

...
if (isScrollbarClicked(ev)) ev.stopPropagation()

To whomever is still struggling with this in 2022:) As mentioned above, listen to the mousedown event in the container that has scrollbars. Check if the click happened in the scrollbar space and stop it from propagating.

const isScrollbarClicked = (e: MouseEvent<HTMLElement>): boolean => {
  const target = e.target as Element
  return (
    e.nativeEvent.offsetX > target.clientWidth ||
    e.nativeEvent.offsetY > target.clientHeight
  )
}

...
if (isScrollbarClicked(ev)) ev.stopPropagation()

This fix won't work on Mac, since there's no reserved space for scrollbars there.

Cancel prop resolves the drag conflicts.

cancel="button, svg, textarea, .targetClass etc..."

In my case, the issue was that the resize handlers appear inside the scrollbar and not outside.
For those having issues with scrollbars in this library, my recommendation after some frustration is:
Put a div inside the react-rnd, put the height of that component to be like 100% of the parent, set the overflow of the react-rnd to hidden, and then you will have a scrollbar working without issues in a normal div, and the full functionality of the react-rnd not affected.
Also, using the dragHandleClassName and allowing drag only with an sub sub div prevents the scrollbars from performing dragging operations.