在 slate-react 文本编辑器中添加图像后的段落

Add paragraph after image within a slate-react text editor

我目前正在研究基于slatejs的富文本编辑器。当图像聚焦时,我需要实现在图像之后插入段落的可能性。现在,当图像具有焦点并且我按下 Enter 按钮时 - 没有任何反应。它应该在图像之后插入新的空段落。

示例中的相同行为 https://www.slatejs.org/examples/images

感谢任何帮助

编辑 SlateJS 给出的 source,我只是在 insertImage() 函数中添加了一个段落节点。

SlateJS 来源:

const insertImage = (editor, url) => {
  const text = { text: '' }
  const image = { type: 'image', url, children: [text] }
  Transforms.insertNodes(editor, image)
}

编辑为:

const insertImage = (editor, url) => {
  const text = { text: '' }
  const image = [
    { 
      type: 'image', 
      url, 
      children: [text] 
    }, 
    {
      type: 'paragraph',
      children: [text],
    }
  ];

  Transforms.insertNodes(editor, image);
};

如果您 select 创建一个空节点(图像节点),默认情况下按 enter 不会添加新行。投票最多的答案仅在图像插入时添加了一个新行,这没有解决问题。

这是一个关于如何为编辑器提供您想要的行为的插件。

import { Editor, Node, Path, Range, Transforms } from 'slate'

export const withCorrectVoidBehavior = editor => {
  const { deleteBackward, insertBreak } = editor

  // if current selection is void node, insert a default node below
  editor.insertBreak = () => {
    if (!editor.selection || !Range.isCollapsed(editor.selection)) {
      return insertBreak()
    }

    const selectedNodePath = Path.parent(editor.selection.anchor.path)
    const selectedNode = Node.get(editor, selectedNodePath)
    if (Editor.isVoid(editor, selectedNode)) {
      Editor.insertNode(editor, {
        type: 'paragraph',
        children: [{ text: '' }],
      })
      return
    }

    insertBreak()
  }
    
  // if prev node is a void node, remove the current node and select the void node
  editor.deleteBackward = unit => {
    if (
      !editor.selection ||
      !Range.isCollapsed(editor.selection) ||
      editor.selection.anchor.offset !== 0
    ) {
      return deleteBackward(unit)
    }

    const parentPath = Path.parent(editor.selection.anchor.path)
    const parentNode = Node.get(editor, parentPath)
    const parentIsEmpty = Node.string(parentNode).length === 0

    if (parentIsEmpty && Path.hasPrevious(parentPath)) {
      const prevNodePath = Path.previous(parentPath)
      const prevNode = Node.get(editor, prevNodePath)
      if (Editor.isVoid(editor, prevNode)) {
        return Transforms.removeNodes(editor)
      }
    }

    deleteBackward(unit)
  }

  return editor
}

我们覆盖 insertBreak 行为(它在 carrige return 上被调用)并且如果 selected 节点为空则通过调用 Editor.insertNode(editor, blankNode) 插入一个空行.

我们还覆盖了 deleteBackward 行为。如果没有插件,删除空节点后的空行也会删除该节点!现在,我们不删除之前的节点,而是删除空白行和 select 之前的节点。

要使用此插件,您需要执行以下操作:

const editor = useMemo(() => withCorrectVoidBehavior(withReact(createEditor())), []);

我从以下位置窃取了插件代码:https://github.com/ianstormtaylor/slate/issues/3991