ianstormtaylor / slate

A completely customizable framework for building rich text editors. (Currently in beta.)
http://slatejs.org
MIT License
29.79k stars 3.24k forks source link

ReactEditor.focus does not work after inserting a new node #4961

Open sodenn opened 2 years ago

sodenn commented 2 years ago

Description When using ReactEditor.focus after inserting a new Node via Transforms.insertNodes, the mouse cursor is not placed at the expected location.

Recording Focusing works in slate@0.77.0 and before: 2022-04-22 23 10 42

Focusing no longer works in slate@0.77.2 2022-04-22 23 11 08

Sandbox slate@0.77.0 and before: https://codesandbox.io/s/elastic-nova-2nw62t?file=/src/App.js slate@0.77.2: https://codesandbox.io/s/suspicious-mestorf-e9306h?file=/src/App.js The sandboxes are based on the Mentions example: https://github.com/ianstormtaylor/slate/blob/main/site/examples/mentions.tsx

Steps To reproduce the behavior:

  1. Type "@a" to open the menu
  2. Select a menu item with a mouse click

Expectation The cursor should be placed at the end of the text in the editor.

Environment

ryanmitts commented 2 years ago

Change Transforms.move(editor)

to

Transforms.move(editor, {
    distance: 1,
    unit: "offset"
});
Nikhil22 commented 1 year ago

@ryanmitts That doesn't work for me. My issue is related, and what I want to do is even simpler -- Move the cursor the end of the document.

jacksteves commented 1 year ago

@Nikhil22 How about Transforms.select(editor, Editor.end(editor, []))?

TheSohaibAhmed commented 1 year ago

I seem to have maybe potentially found the fix for this.

Here's what I understood the problem to be: essentially, if the place that I clicked on was not directly the editor, then it lost focus (i.e. ReactEditor.isFocused() was false), but if you try to refocus it, it gave me error "Cannot resolve a DOM node from Slate node: undefined" -- which meant, yeah: if the v0.77 isn't adding the slate node after the Transforms.insertNodes then this'd be a problem.

How I created a slate node

  1. I changed selection to the newly added node (which didn't show the cursor -- as seen in the video OP posted above)
  2. Using the suggestion above, i did "Transform.move(...unit: "offset", edge:"focus") <-- this, i think creates the slade node.
  3. At this point, select the newly added node again (don't focus the editor; somehow that still doesn't work).

You'll get your selection.

Here's the code, when I was adding a new paragraph after the one I was on (i.e. if I was on [0, 0, 16]--in the middle of a para), I wanted to create [0,1] and jump to [0,1,0]):

 1. Insert node
 Transforms.insertNodes(...)

 2. Select the new location's first index (for you this might be diff)
**Transforms.select(editor, {
      anchor: { offset: 0, path: [currentElIndex + 1, 0] },
      focus: { offset: 0, path: [currentElIndex + 1, 0] },
    });**

3. Move to next offset (which shouldn't exist technically);
    **Transforms.move(editor, {
      distance: 1,
      unit: "offset",
      edge: "focus",
    });**

  4. Select the originally intended location
    **Transforms.select(editor, {
      anchor: { offset: 0, path: [currentElIndex + 1, 0] },
      focus: { offset: 0, path: [currentElIndex + 1, 0] },
    });**
jmilus commented 1 year ago

How is this still an unresolved issue? if there's a function for ".focus" it shouldn't require workarounds. Seems like a pretty crucial function, considering people are constantly clicking on format buttons and thus blurring the editor.

AlexeyShaykov commented 5 months ago

Hello everyone, I have same problem with focus after insert new node

` const fn = () => { Transforms.insertNodes(editor, [{ type: 'paragraph', children: [{ text: 'here text' }] }]);

setTimeout(() => { console.log(editor.selection) // anchor: // offset: 0 // path: [1, 0] // focus: // offset: 0 // path: [1, 0] ReactEditor.focus(editor); }, 10); } ` image

As u see, after insert new node my editor.selection show that now selection on second paragraph (path: [1, 0]), but when I call ReactEditor.focus(editor); cursor move to first paragraph. Why so?

tommydangerous commented 2 months ago

@Nikhil22 How about Transforms.select(editor, Editor.end(editor, []))?

this!

gaoqs commented 3 weeks ago

ReactEditor.focus

const end = Editor.end(editor, []); ReactEditor.deselect(editor as ReactEditor); Transforms.select(editor, { anchor: end, focus: end }); ReactEditor.focus(editor as ReactEditor);

deselect first and then select, works for me