0

I am using Slate JS.

I have some code, which should focus a given block (move the cursor there).

The use case here is: press / to open a modal, then when the modal closes, we want to refocus to the block we were at before.

To do this, we use Transforms.select().

Something like this:

getCurrentBlock(editor: Editor) {
  const { selection } = editor;

  if (!selection) {
    return { block: null, anchor: null, focus: null };
  }

  const { anchor, focus } = selection;
  const { path } = anchor
  const block = editor.children[path[0]] as Block;
  return { block, anchor, focus };
}

const focusBlock = (editor, path) => {
  ReactEditor.focus(editor);
  
  Transforms.select(editor, {
    anchor: { path: [path[0], 0], offset: 0 },
    focus: { path: [path[0], 0], offset: 0 },
  });
}

It generally works in all cases like this:

const { block, anchor, focus} = getCurrentBlock(editor)
const { path } = anchor
focusBlock(editor, path)

However, it does not work when the position of the cursor is at the start of a line.

i.e. when offset = 0.

In this case, the focus moves the cursor to the very top of the page.

Why might this be happening, and how can I make it focus the block in question, even when the cursor is at the start of the line?

Colin Ricardo
  • 16,488
  • 11
  • 47
  • 80

1 Answers1

0

Solved this by doing:

refocusEditor({ editor }: { editor: Editor }) {
   const block = Editor.above(editor, {
    match: (n) => Editor.isBlock(editor, n),
  });

  const path = block ? block[1] : [];
  ReactEditor.focus(editor);
  // @ts-ignore
  Transforms.setSelection(editor, path);
}

Colin Ricardo
  • 16,488
  • 11
  • 47
  • 80