React-beautiful-dnd: Blur event gets swallowed

Created on 18 Jun 2020  路  3Comments  路  Source: atlassian/react-beautiful-dnd

Steps:

  1. Open the nested-interative-elements--stress-test storybook
  2. Click inside a text input so it has focus (and the caret inside blinks)
  3. Click on any of the other draggable components

Expected:

  1. Text input blurs and loses focus

Actual:

  1. Text input retains focus
unconfirmed-bug untriaged

Most helpful comment

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.

All 3 comments

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.

Was this page helpful?
0 / 5 - 0 ratings