Slate: Cannot resolve a DOM node from Slate node: {"text":""}

Created on 23 Oct 2020  路  2Comments  路  Source: ianstormtaylor/slate

Do you want to request a _feature_ or report a _bug_?

Bug

What's the current behavior?

Transforms.insertNodes(props.editor, [{
      type: 'image',
      src: url,
      children: [{text: ''}]
    }])

After inserting an image as a void node, and then clicking the image, the editor throws the error

Cannot resolve a DOM node from Slate node: {"text":""}

The resulting editor state when inserting an image:

[{type: 'image', src: 'http://imageurl.com/image.jpg', children: [{text: ''}]}]

The resulting DOM:

<img data-slate-node="element" data-slate-void="true" src="http://imageurl.com/image.jpg">

The area of the code responsible for determining focus is where the error is thrown:
https://github.com/ianstormtaylor/slate/blob/master/packages/slate-react/src/plugin/react-editor.ts#L211

Unless I am missing something, this bug doesn't make a whole lot of sense. I will keep poking around, but unfortunately the documentation seems very sparse after the latest update, so I am not sure what's up or down any more. Lots of outdated information floating around.

Slate: 0.59.0
Browser: Chrome
OS: Mac

What's the expected behavior?

Either nothing happens, or the cursor just rests on either side of the image.

Most helpful comment

Thanks for chiming in @AlfonzAlfonz !

I discovered this as well by digging into one of the hosted example projects. The documentation is just not very clear about how to handle void elements

const ImageElement = ({ attributes, children, element }) => {
    const selected = useSelected()
    const focused = useFocused()
    return (
        <div {...attributes}>
            <div contentEditable={false}>
                <img
                  src={element.url}
                  style={{
                      display: 'block',
                      maxWidth: '550px',
                      maxHeight: '20em',
                      boxShadow: `${selected && focused ? '0 0 0 3px #B4D5FF' : 'none'}`
                  }}
                />
            </div>
            {children}
        </div>
    )
}

As you mentioned, {children} must be passed. The outermost div must have the attributes rendered, followed by a div with contentEditable={false}, followed finally by an image tag. The children being rendered in the within the outermost div.

All 2 comments

I've run into the same problem, but I've managed to fix it by rendering {children} somewhere in my void element.

Thanks for chiming in @AlfonzAlfonz !

I discovered this as well by digging into one of the hosted example projects. The documentation is just not very clear about how to handle void elements

const ImageElement = ({ attributes, children, element }) => {
    const selected = useSelected()
    const focused = useFocused()
    return (
        <div {...attributes}>
            <div contentEditable={false}>
                <img
                  src={element.url}
                  style={{
                      display: 'block',
                      maxWidth: '550px',
                      maxHeight: '20em',
                      boxShadow: `${selected && focused ? '0 0 0 3px #B4D5FF' : 'none'}`
                  }}
                />
            </div>
            {children}
        </div>
    )
}

As you mentioned, {children} must be passed. The outermost div must have the attributes rendered, followed by a div with contentEditable={false}, followed finally by an image tag. The children being rendered in the within the outermost div.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

chriserickson picture chriserickson  路  3Comments

ianstormtaylor picture ianstormtaylor  路  3Comments

AlexeiAndreev picture AlexeiAndreev  路  3Comments

markolofsen picture markolofsen  路  3Comments

JSH3R0 picture JSH3R0  路  3Comments