ianstormtaylor / slate

A completely customizable framework for building rich text editors. (Currently in beta.)

Home Page:http://slatejs.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Different behaviour for text added with insertText() resulting in error

martinhonza opened this issue · comments

Description
Hi,
we are adding soft break \n on keyDown enter with a code

 if (event.key === 'Enter') {
        event.preventDefault();
        event.stopPropagation();
        Transforms.insertText(editor, '\n');
      }

We also need to calculate a position of absolutly positioned element that will be on the same line as cursor, so in onChange event we do bunch of checks and then call ReactEditor.toDOMRange(editor, editor.selection) and here is a problem.
In ReactEditor.toDOMRange there is call to ReactEditor.toDOMPoint. After logging it out it seems that if text is added by slate and not Transforms.insertText(editor,...) then the call toDOMPoint return slate node with old text which corresponds with the DOM. But if I use Transforms.insertText() toDOMPoint uses node with already updated text which doesn't correspond with what is selected from DOM and then there is mismatch of offsets.

Recording
A GIF or video showing the issue happening. (If you don't include this, there's a very good chance your issue will be closed, because it's much too hard to figure out exactly what is going wrong, and it makes maintenance much harder.)

Sandbox
https://codesandbox.io/p/sandbox/slate-reproductions-forked-6k27z9?file=%2Findex.tsx%3A19%2C1

Steps
To reproduce the behavior:

  1. Open console and go to end of line
  2. Press enter
  3. Error in console
  4. For further debugging you can log out editor in ReactEditor.toDOMPoint and see the text value of node that is being updated

Expectation
Same behaviour for insertText() and how slate behaves by default.

Environment

  • Slate Version: [e.g. 0.59]
  • Operating System: [e.g. iOS]
  • Browser: [e.g. Chrome, Safari]
  • TypeScript Version: [e.g. 3.9.7 - required only if it's a TypeScript issue]

Context
Add any other context about the problem here. (The fastest way to have an issue fixed is to create a pull request with working, tested code and we'll help merge it. Slate is solving a pretty complex problem, and we can't do it without active contributors, so thank you so much for your help!)

And I have solved it by not calling the ReactEditor.toDOMRange() in onChange but rather setState in onChange and then in useEffect when state is set call ReactEditor.toDOMRange() which works.