1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-31 02:49:56 +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 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. // Add drop-specific information to the data.
data.target = target data.target = target

View File

@@ -41,6 +41,17 @@ class Void extends React.Component {
state: Types.object.isRequired, state: Types.object.isRequired,
} }
/**
* State
*
* @type {Object}
*/
state = {
dragCounter: 0,
editable: false
}
/** /**
* Debug. * Debug.
* *
@@ -81,6 +92,45 @@ class Void extends React.Component {
editor.onChange(next) 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. * Render.
* *
@@ -103,9 +153,16 @@ class Void extends React.Component {
this.debug('render', { props }) this.debug('render', { props })
return ( 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()} {this.renderSpacer()}
<Tag contentEditable={false}> <Tag contentEditable={this.state.editable}>
{children} {children}
</Tag> </Tag>
</Tag> </Tag>

View File

@@ -434,10 +434,26 @@ function Plugin(options = {}) {
debug('onDropText', { data }) debug('onDropText', { data })
const { text, target } = data const { text, target } = data
const { document } = state
const transform = state const transform = state
.transform() .transform()
.select(target) .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 text
.split('\n') .split('\n')
.forEach((line, i) => { .forEach((line, i) => {