How to ignore empty lines while wrapping nodes with SlateJS?

654 Views Asked by At

I'm using Slate.js to build a rich text editor. I set up an inline formatting that I can toggle with the following function:

toggleInline: function (editor, format) {
  const isActive = this.isFormatActive(editor, format, TYPES.FORMATS.INLINE);

  if (isActive) {
    Transforms.unwrapNodes(editor, {
      match: node => !this.isEditor(node) && Element.isElement(node) && node.type === format
    });

  } else {
    const inline = { type: format, children: noChildren };
    Transforms.wrapNodes(editor, inline, { split: true });
  }
}

It works fine, but if I select multiple lines I would like to ignore the empty lines so no empty block is inserted. Here for example I only want to wrap A and B but not the empty line:

enter image description here

The corresponding children look like this:

[
  { type: "p", children: [{ text: "A" }]},
  { type: "p", children: [{ text: "" }]},
  { type: "p", children: [{ text: "B" }]}
]

I tried to add a match option on wrapNodes but it erases the empty lines instead of skipping them:

Transforms.wrapNodes(editor, inline, {
  match: node => node.text !== emptyString
  split: true
});

How can I do?

1

There are 1 best solutions below

0
Arkellys On BEST ANSWER

It turns out the match option is the way to go, I just needed to use a proper function to check if an element is empty:

Transforms.wrapNodes(editor, inline, {
  match: (node) => !Element.isEmpty(node),
  split: true
});

My custom isEmpty function:

isEmpty: function (element) {
  if ("text" in element) return element.text === emptyString;
  if (element.children.length > 1) return false;

  return this.isEmpty(head(element.children));
}