Unable to delete a link clearly in Slate.js editor using the official example

2.5k Views Asked by At

enter image description here

CodeSandbox Example:

https://codesandbox.io/s/slate-2-images-and-links-forked-s09wi

This is basically the withLink() example from the official document.

When you press backspace or cut out to remove the link, the JSON output still contains the link data with empty text. I don't understand why it still remains in the output. Can anyone provide a solution for this?

The withLink example:

const withLinks = editor => {
  const { insertData, insertText, isInline } = editor

  editor.isInline = element => {
    return element.type === 'link' ? true : isInline(element)
  }

  editor.insertText = text => {
    if (text && isUrl(text)) {
      wrapLink(editor, text)
    } else {
      insertText(text)
    }
  }

  editor.insertData = data => {
    const text = data.getData('text/plain')

    if (text && isUrl(text)) {
      wrapLink(editor, text)
    } else {
      insertData(data)
    }
  }

  return editor
}

const unwrapLink = editor => {
  Transforms.unwrapNodes(editor, {
    match: n =>
      !Editor.isEditor(n) && SlateElement.isElement(n) && n.type === 'link',
  })
}

const wrapLink = (editor, url) => {
  if (isLinkActive(editor)) {
    unwrapLink(editor)
  }

  const { selection } = editor
  const isCollapsed = selection && Range.isCollapsed(selection)
  const link: LinkElement = {
    type: 'link',
    url,
    children: isCollapsed ? [{ text: url }] : [],
  }

  if (isCollapsed) {
    Transforms.insertNodes(editor, link)
  } else {
    Transforms.wrapNodes(editor, link, { split: true })
    Transforms.collapse(editor, { edge: 'end' })
  }
}
1

There are 1 best solutions below

0
On BEST ANSWER

I fixed this issue by adding normalizeNode in withLinks plugin.

const { normalizeNode } = editor
editor.normalizeNode = entry => {
const [node, path] = entry
if (Element.isElement(node) && node.type === 'paragraph') {
  const children = Array.from(Node.children(editor, path))
  for (const [child, childPath] of children) {
    // remove link nodes whose text value is empty string.
    // empty text links happen when you move from link to next line or delete link line.
    if (Element.isElement(child) && child.type === 'link' && child.children[0].text === '') {
      if (children.length === 1) {
        Transforms.removeNodes(editor, { at: path })
        Transforms.insertNodes(editor,
          {
            type: 'paragraph',
            children: [{ text: '' }],
          })
      } else {
        Transforms.removeNodes(editor, { at: childPath })
      }
      return
    }
  }
}
normalizeNode(entry)

}