Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add suppressThrow to ReactEditors toDOMRange and toDOMPoint #5571

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

markacola
Copy link

Description
When the editor content is set externally, the DOM may not have the focus points the editor attempts to resolve. This is already handled for when the current selection is null.

This is an implementation of the first suggestion noted here

Issue
Fixes: Various issues that result from the DOM content changing under the editor and I believe 3309

Example
Here is an example of the external value being reset to "Text" programmatically, with the cursor at the end of the input. Previously, this would have errored.
Screencast from 30-11-23 14:29:54.webm

Context
I have replicated the suppressThrow pattern on other methods and enabled it when reprocessing focus via the useLayoutEffect in the Editable component.

Checks

  • The new code matches the existing patterns and styles.
  • The tests pass with yarn test.
  • The linter passes with yarn lint. (Fix errors with yarn fix.)
  • The relevant examples still work. (Run examples with yarn start.)
  • You've added a changeset if changing functionality. (Add one with yarn changeset add.)

Copy link

changeset-bot bot commented Nov 30, 2023

🦋 Changeset detected

Latest commit: 1eda475

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
slate-react Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@nemanja-tosic
Copy link
Contributor

Can you post a reproduction of the issue somewhere?

@markacola
Copy link
Author

Here you go: https://replit.com/@MarkCola/Slate-js-5571#src/App.tsx

Run this, type some extra content beyond the existing and you will see this error when the user focus is outside the updated/reset content:
image

@dylans
Copy link
Collaborator

dylans commented Dec 6, 2023

@markacola still thinking through this one. I'm a bit conflicted on this. I understand what the documentation says and your use case. I know that in our app we manage to avoid this scenario by instead mostly working with operations rather than the approach you are following (which isn't a bad thing, just why I've not really had this issue).

@markacola
Copy link
Author

markacola commented Dec 13, 2023

@dylans Thank you for considering the changes - I implemented the PR under the assumption that the desired behaviour is to avoid throwing an error.

The only functional difference with these changes would be the focus blurring instead of throwing an error; I haven't considered the implementation details, but perhaps an alternative to this behaviour is attempting to recover an approximate selection.

Would that be preferable? Or would it be better to:

  1. update the docs outlining the risks of implementing the naive editor.children = externalValue approach, and
  2. document a way to consume external values via operations.

Alternatively, I am happy to close this PR if the advice is to work around the issue using operations.

@azvoncov-smartling
Copy link

The same problem occurs when changing the editor structure synchronously (like wrapNodes), and setSelection is set asynchronously - sometimes the same problem occurs

Only decision:

const isPointExist = (editor, point) => {...};
// ...
editor.apply = (operation) => {
         if (operation.type === "set_selection" && operation.newProperties) {
             if (operation.newProperties.anchor && !isPointExist(editor, operation.newProperties.anchor)) return;
             if (operation.newProperties.focus && !isPointExist(editor, operation.newProperties.focus)) return;
         }

         apply(operation);
     };
};

@bryanph
Copy link
Contributor

bryanph commented Mar 27, 2024

instead of suppressing the error everywhere I think it would make more sense to introduce a specific editor.reset method that also resets the selection appropriately. Alternatively you can just reset the selection to [0,0] before setting editor.children.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants