mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-09 16:56:36 +02:00
Make drop and dragend event handlers global (#5664)
This commit is contained in:
5
.changeset/grumpy-icons-refuse.md
Normal file
5
.changeset/grumpy-icons-refuse.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'slate-react': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix: `state.isDraggingInternally` is stale if a drop handler outside the editor causes the dragged DOM element to unmount
|
@@ -822,26 +822,37 @@ export const Editable = (props: EditableProps) => {
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
// Attach a native DOM event handler for `selectionchange`, because React's
|
|
||||||
// built-in `onSelect` handler doesn't fire for all selection changes. It's a
|
|
||||||
// leaky polyfill that only fires on keypresses or clicks. Instead, we want to
|
|
||||||
// fire for any change to the selection inside the editor. (2019/11/04)
|
|
||||||
// https://github.com/facebook/react/issues/5785
|
|
||||||
useIsomorphicLayoutEffect(() => {
|
useIsomorphicLayoutEffect(() => {
|
||||||
const window = ReactEditor.getWindow(editor)
|
const window = ReactEditor.getWindow(editor)
|
||||||
|
|
||||||
|
// Attach a native DOM event handler for `selectionchange`, because React's
|
||||||
|
// built-in `onSelect` handler doesn't fire for all selection changes. It's
|
||||||
|
// a leaky polyfill that only fires on keypresses or clicks. Instead, we
|
||||||
|
// want to fire for any change to the selection inside the editor.
|
||||||
|
// (2019/11/04) https://github.com/facebook/react/issues/5785
|
||||||
window.document.addEventListener(
|
window.document.addEventListener(
|
||||||
'selectionchange',
|
'selectionchange',
|
||||||
scheduleOnDOMSelectionChange
|
scheduleOnDOMSelectionChange
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Listen for dragend and drop globally. In Firefox, if a drop handler
|
||||||
|
// initiates an operation that causes the originally dragged element to
|
||||||
|
// unmount, that element will not emit a dragend event. (2024/06/21)
|
||||||
|
const stoppedDragging = () => {
|
||||||
|
state.isDraggingInternally = false
|
||||||
|
}
|
||||||
|
window.document.addEventListener('dragend', stoppedDragging)
|
||||||
|
window.document.addEventListener('drop', stoppedDragging)
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.document.removeEventListener(
|
window.document.removeEventListener(
|
||||||
'selectionchange',
|
'selectionchange',
|
||||||
scheduleOnDOMSelectionChange
|
scheduleOnDOMSelectionChange
|
||||||
)
|
)
|
||||||
|
window.document.removeEventListener('dragend', stoppedDragging)
|
||||||
|
window.document.removeEventListener('drop', stoppedDragging)
|
||||||
}
|
}
|
||||||
}, [scheduleOnDOMSelectionChange])
|
}, [scheduleOnDOMSelectionChange, state])
|
||||||
|
|
||||||
const decorations = decorate([editor, []])
|
const decorations = decorate([editor, []])
|
||||||
|
|
||||||
@@ -1378,8 +1389,6 @@ export const Editable = (props: EditableProps) => {
|
|||||||
ReactEditor.focus(editor)
|
ReactEditor.focus(editor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state.isDraggingInternally = false
|
|
||||||
},
|
},
|
||||||
[readOnly, editor, attributes.onDrop, state]
|
[readOnly, editor, attributes.onDrop, state]
|
||||||
)}
|
)}
|
||||||
@@ -1393,11 +1402,6 @@ export const Editable = (props: EditableProps) => {
|
|||||||
) {
|
) {
|
||||||
attributes.onDragEnd(event)
|
attributes.onDragEnd(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
// When dropping on a different droppable element than the current editor,
|
|
||||||
// `onDrop` is not called. So we need to clean up in `onDragEnd` instead.
|
|
||||||
// Note: `onDragEnd` is only called when `onDrop` is not called
|
|
||||||
state.isDraggingInternally = false
|
|
||||||
},
|
},
|
||||||
[readOnly, state, attributes, editor]
|
[readOnly, state, attributes, editor]
|
||||||
)}
|
)}
|
||||||
|
@@ -26,4 +26,4 @@ export { ReactEditor } from './plugin/react-editor'
|
|||||||
export { withReact } from './plugin/with-react'
|
export { withReact } from './plugin/with-react'
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
export { NODE_TO_INDEX, NODE_TO_PARENT } from "./utils/weak-maps"
|
export { NODE_TO_INDEX, NODE_TO_PARENT } from './utils/weak-maps'
|
||||||
|
Reference in New Issue
Block a user