mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-30 18:39:51 +02:00
Allow drop events on void nodes (#921)
* Allow drop events on void nodes Text will be inserted in next non-void text node * Fix linting errors * Fixed formatting
This commit is contained in:
committed by
Ian Storm Taylor
parent
31c75590ae
commit
37ba8e9e6d
@@ -521,9 +521,6 @@ class Content extends React.Component {
|
||||
isFocused: true
|
||||
})
|
||||
|
||||
// If the target is inside a void node, abort.
|
||||
if (state.document.hasVoidParent(point.key)) return
|
||||
|
||||
// Add drop-specific information to the data.
|
||||
data.target = target
|
||||
|
||||
|
@@ -41,6 +41,17 @@ class Void extends React.Component {
|
||||
state: Types.object.isRequired,
|
||||
}
|
||||
|
||||
/**
|
||||
* State
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
state = {
|
||||
dragCounter: 0,
|
||||
editable: false
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug.
|
||||
*
|
||||
@@ -81,6 +92,45 @@ class Void extends React.Component {
|
||||
editor.onChange(next)
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment counter, and temporarily switch node to editable to allow drop events
|
||||
* Counter required as onDragLeave fires when hovering over child elements
|
||||
*
|
||||
* @param {Event} event
|
||||
*/
|
||||
|
||||
onDragEnter = () => {
|
||||
this.setState((prevState) => {
|
||||
const dragCounter = prevState.dragCounter + 1
|
||||
return { dragCounter, editable: undefined }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement counter, and if counter 0, then no longer dragging over node
|
||||
* and thus switch back to non-editable
|
||||
*
|
||||
* @param {Event} event
|
||||
*/
|
||||
|
||||
onDragLeave = () => {
|
||||
this.setState((prevState) => {
|
||||
const dragCounter = prevState.dragCounter + 1
|
||||
const editable = dragCounter === 0 ? false : undefined
|
||||
return { dragCounter, editable }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* If dropped item onto node, then reset state
|
||||
*
|
||||
* @param {Event} event
|
||||
*/
|
||||
|
||||
onDrop = () => {
|
||||
this.setState({ dragCounter: 0, editable: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* Render.
|
||||
*
|
||||
@@ -103,9 +153,16 @@ class Void extends React.Component {
|
||||
this.debug('render', { props })
|
||||
|
||||
return (
|
||||
<Tag data-slate-void style={style} onClick={this.onClick}>
|
||||
<Tag
|
||||
data-slate-void
|
||||
style={style}
|
||||
onClick={this.onClick}
|
||||
onDragEnter={this.onDragEnter}
|
||||
onDragLeave={this.onDragLeave}
|
||||
onDrop={this.onDrop}
|
||||
>
|
||||
{this.renderSpacer()}
|
||||
<Tag contentEditable={false}>
|
||||
<Tag contentEditable={this.state.editable}>
|
||||
{children}
|
||||
</Tag>
|
||||
</Tag>
|
||||
|
@@ -434,10 +434,26 @@ function Plugin(options = {}) {
|
||||
debug('onDropText', { data })
|
||||
|
||||
const { text, target } = data
|
||||
const { document } = state
|
||||
const transform = state
|
||||
.transform()
|
||||
.select(target)
|
||||
|
||||
let hasVoidParent = document.hasVoidParent(target.anchorKey)
|
||||
|
||||
// Insert text into nearest text node
|
||||
if (hasVoidParent) {
|
||||
let node = document.getNode(target.anchorKey)
|
||||
|
||||
while (hasVoidParent) {
|
||||
node = document.getNextText(node.key)
|
||||
if (!node) break
|
||||
hasVoidParent = document.hasVoidParent(node.key)
|
||||
}
|
||||
|
||||
if (node) transform.collapseToStartOf(node)
|
||||
}
|
||||
|
||||
text
|
||||
.split('\n')
|
||||
.forEach((line, i) => {
|
||||
|
Reference in New Issue
Block a user