diff --git a/.changeset/light-gorillas-train.md b/.changeset/light-gorillas-train.md new file mode 100644 index 000000000..07f75d49e --- /dev/null +++ b/.changeset/light-gorillas-train.md @@ -0,0 +1,5 @@ +--- +'slate-react': patch +--- + +Fix erroneous text after native insert diff --git a/packages/slate-react/src/components/editable.tsx b/packages/slate-react/src/components/editable.tsx index e1f685ea8..8a5848172 100644 --- a/packages/slate-react/src/components/editable.tsx +++ b/packages/slate-react/src/components/editable.tsx @@ -310,10 +310,6 @@ export const Editable = (props: EditableProps) => { } } - if (!native) { - event.preventDefault() - } - // COMPAT: For the deleting forward/backward input types we don't want // to change the selection because it is the range that will be deleted, // and those commands determine that for themselves. @@ -427,7 +423,9 @@ export const Editable = (props: EditableProps) => { // Only insertText operations use the native functionality, for now. // Potentially expand to single character deletes, as well. if (native) { - asNative(editor, () => Editor.insertText(editor, data)) + asNative(editor, () => Editor.insertText(editor, data), { + onFlushed: () => (native = false), + }) } else { Editor.insertText(editor, data) } @@ -436,6 +434,10 @@ export const Editable = (props: EditableProps) => { break } } + + if (!native) { + event.preventDefault() + } } }, [readOnly, propsOnDOMBeforeInput] diff --git a/packages/slate-react/src/utils/native.ts b/packages/slate-react/src/utils/native.ts index 9411d61ea..12a2857d6 100644 --- a/packages/slate-react/src/utils/native.ts +++ b/packages/slate-react/src/utils/native.ts @@ -10,10 +10,25 @@ export const NATIVE_OPERATIONS: WeakMap = new WeakMap() * @param {Editor} editor - Editor on which the operations are being applied * @param {callback} fn - Function containing .exec calls which will be queued as native */ -export const asNative = (editor: Editor, fn: () => void) => { +export const asNative = ( + editor: Editor, + fn: () => void, + { onFlushed }: { onFlushed?: () => void } = {} +) => { + const isNative = AS_NATIVE.get(editor) + AS_NATIVE.set(editor, true) - fn() - AS_NATIVE.set(editor, false) + try { + fn() + } finally { + if (isNative !== undefined) { + AS_NATIVE.set(editor, isNative) + } + } + + if (!NATIVE_OPERATIONS.get(editor)) { + onFlushed?.() + } } /** @@ -25,7 +40,7 @@ export const flushNativeEvents = (editor: Editor) => { // Clear list _before_ applying, as we might flush // events in each op, as well. - NATIVE_OPERATIONS.set(editor, []) + NATIVE_OPERATIONS.delete(editor) if (nativeOps) { Editor.withoutNormalizing(editor, () => {