Slate.js prevent block deletion

962 Views Asked by At

Which way I can prevent user to remove specific block from slate.js editor (or inform user that block will be deleted) my goal is protect information from accidental removal. Thanks in advance.

3

There are 3 best solutions below

0
On

In slate, all the delete / remove node seems to be happening the endpoint of

editor.apply('remove-node', options);

Therefore, adding plugins worked for me as shown below:

const withPreventBlockDeletion = editor => {
  const { apply } = editor
    
  editor.apply = operation => {
    if (operation.type === 'remove_node') {
      const { node } = operation;
      if (node.type === 'your block type') {
        // Prevent certain element/node to be deleted
        return;
      }
    }
    
    // Other cases
    apply(operation)
  }
    
  return editor
 }
0
On

I was looking for something similar.

One way that I found was - by preventing default deleteForward and deleteBackward invocation when inside that node.

For example I have a front-matter node that contains meta-information about the document and I'd like the user to edit it but never remove from the tree.

text node is editable and this is the schema

{
    type: 'front-matter',
    children: [{ text: 'Welcome to the document' }],
}

And this is the plugin

export const withFrontmatter = (editor: Editor) => {
    const { deleteForward } = editor;

    editor.deleteForward = (unit: TextUnit) => {
        const [frontmatter] = Editor.nodes(editor, {
            match: (node) =>
                !Editor.isEditor(node) && Element.isElement(node) &&
                node.type === 'front-matter'
        });

        if (
            !!frontmatter &&
            Element.isElement(frontmatter[0]) &&
            Editor.isEmpty(editor, frontmatter[0])
        ) {
            return;
        }

        deleteForward(unit);
    };

    return editor;
};

Identical logic for deleteBackward and you have an un-deletable node.

Editor.isEmpty(editor, frontmatter[0]) checks if the inner text fragment is empty.

0
On

Add the property: contentEditable={false} to the element renderer, this will prevent this element (node) from being changed in the editor