react-dnd icon indicating copy to clipboard operation
react-dnd copied to clipboard

IMPORTANT: draggable DOM attribute blocks text selection

Open ffjanhoeck opened this issue 5 years ago • 6 comments

Describe the bug If you pass down the drag property to the ref attribute of your DOM element, then a draggable native html attribute will be set to true. It doesn't matter if canDrag is set to false. The draggable HTML attribute is always true and because of this, the user cannot select a text in this component.

Reproduction https://codesandbox.io/s/quirky-chaplygin-89xqe

Steps to reproduce the behavior: Just try to select the text "My Draggable component". You will see that this doesn't work. Afterwards you can take a look into the MyDraggableComponent.tsx. As you can see, the canDrag option is set to false.

Expected behavior If canDrag is set to false, I expected that the HTML attribute draggable is set to false.

Screenshots image

Desktop (please complete the following information):

  • OS: Windows 10
  • Browser: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36
  • Version react-dnd: latest

ffjanhoeck avatar Jul 24 '20 16:07 ffjanhoeck

Edit: I saw that the draggable attribute comes from HTML5BackendImpl class. image

As you can see, the 'true' parameter is hardcoded and not variable. Are there any workarounds for this?

ffjanhoeck avatar Jul 25 '20 09:07 ffjanhoeck

Edit 2: If anyone have the same problem: I have found a workaround for this. It does fix the issue, but isn't a recommended way.

useLayoutEffect(() => {
    if (rootRef.current) {
        if (disabled) {
            rootRef.current.setAttribute('draggable', 'false');
        } else {
            rootRef.current.setAttribute('draggable', 'true');
        }
    }
}, [disabled, rootRef.current]);

ffjanhoeck avatar Jul 25 '20 13:07 ffjanhoeck

Related https://github.com/react-dnd/react-dnd/issues/2565 I also tested that this prevents text selection in both chrome and safari as well.

~Another workaround that's slightly more declarative is to set draggable={false} on a container element lower down then the drag element.~

EDIT: my workaround does not work. ended up just conditionally attaching drag ref depending on if it wanted something to be draggable.

maclockard avatar Sep 21 '20 23:09 maclockard

+1

adlerfaulkner avatar Sep 02 '21 06:09 adlerfaulkner

still seeing this with most recent release, I wonder if it would just be possible to make react dnd conditionally set draggable based on the canDrag option it's passed

maclockard avatar Feb 28 '22 18:02 maclockard

我用了相似的一种解决方法,思路是相似的。在鼠标onMouseEnter进入input框时,解绑drag元素上的ref,将标签中的ref赋值为null。在鼠标onMouseLeave时再恢复。但不推荐这样做,而且需要写注释,否则后来者无法看懂。需要注意的是,chrome上用此方法无问题,但 safari and FF 上也需要测试一下,如果无缺陷即可行,如果有缺陷则需另寻他法。

编辑2: 如果有人遇到同样的问题: 我已经找到了解决方法。它确实解决了问题,但不是推荐的方法。

useLayoutEffect(() => {
    if (rootRef.current) {
        if (disabled) {
            rootRef.current.setAttribute('draggable', 'false');
        } else {
            rootRef.current.setAttribute('draggable', 'true');
        }
    }
}, [disabled, rootRef.current]);

XiaoBieThree avatar Jul 19 '23 11:07 XiaoBieThree