react-beautiful-dnd
react-beautiful-dnd copied to clipboard
Blur event gets swallowed
Steps:
- Open the nested-interative-elements--stress-test storybook
- Click inside a text input so it has focus (and the caret inside blinks)
- Click on any of the other draggable components
Expected:
- Text input blurs and loses focus
Actual:
- Text input retains focus
I wrote a massive workaround for this and basically now set state that re-renders any components that might be waiting for a blur event in the onBeforeCapture stage. This is a horrific hack, but I couldn't find a better way. Anything with a drag handle will not propagate events.
I found it easier to move to SortableJS actually: https://github.com/SortableJS/react-sortablejs
This happens because of event.preventDefault()
in useMouseSensor() -> startCaptureBinding
.
I hadn't time to dig deeper, but I just made a tiny workaround and it works.
All you have to do is to focus your drag handler on mousedown:
<Draggable ...>
{provided => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
onMouseDown={e => e.currentTarget.focus()}
>
...
</div>
)}
</Draggable>
You should probably create a helper for this, and use it for all your Draggable handlers. So you can change the behavior any time.
Also as I can see (in use-touch-sensor.js
) we don't have to add the same hack for touchstart
event, since react-beautiful-dnd doesn't prevent this event. Only mousedown
.
I used @olegcherr solution, but in my case I have a MUI select component and it seems that the click event is not propagated to the Select causing me to not be able to select any option, only by keyboard
@leonardopn same here, also drag doest work with that fix, did u fix it
+1
@shamseer-ahammed
It's been a while since I made this request. A lot of things were modified in that code and the solution became minimally complex. My tip today is that if possible, use another more current library to try to solve your drag and drop problems.
Basically I did the following:
- I changed the library to use
@hello-pangea/dnd
; - In the photo component, I passed the controller directly to the highest parent component, that is, I could drag and drop it from anywhere the component was touched. So I created a context that can provide the controller through this component and now, the one who really controls the dnd is the central icon there in the corner;
In other words, this entire area in red could be used to move.
Now only this small field is used for dragging and dropping
Final result:
As i said, for me, the code was very complex, it's even difficult to explain here, as there is no example code for this functionality in the repository. But the idea is to actually pass the controller to another component and not pass the provided.dragHandleProps
to each item to avoid them being controlled too.
If you want, I can put together a codesandbox trying to explain it better