1
0
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:
mjadobson
2017-07-12 16:44:59 +01:00
committed by Ian Storm Taylor
parent 31c75590ae
commit 37ba8e9e6d
3 changed files with 75 additions and 5 deletions

View File

@@ -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

View File

@@ -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>

View File

@@ -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) => {