Skip to content

Commit

Permalink
fix(slate): slate loses some updates / keystrokes (#1275)
Browse files Browse the repository at this point in the history
this does not solve it entirly, but mitigatates the problem a lot

the issue stems from the fact that slate became an uncontrolled input which makes it hard to use with outside values
  • Loading branch information
macrozone committed Feb 2, 2023
1 parent 69f54fb commit b593744
Showing 1 changed file with 18 additions and 23 deletions.
41 changes: 18 additions & 23 deletions packages/plugins/content/slate/src/components/SlateProvider.tsx
@@ -1,5 +1,6 @@
import { deepEquals } from '@react-page/editor';
import type { FC, PropsWithChildren } from 'react';

import React, { useCallback, useEffect, useMemo } from 'react';
import { createEditor, Transforms } from 'slate';
import { ReactEditor, Slate, withReact } from 'slate-react';
Expand All @@ -18,9 +19,11 @@ const SlateProvider: FC<PropsWithChildren<SlateProps>> = (props) => {
)(withReact(withInline(plugins)(createEditor()))),
[]
);

useEffect(() => {
// unfortunatly, slate broke the controlled input pattern. So we have to hack our way around it, see https://github.com/ianstormtaylor/slate/issues/4992
// We abuse useMemo for a side effect
// don't try this at home!
// unfortunatly, slate broke the controlled input pattern. So we have to hack our way around it, see https://github.com/ianstormtaylor/slate/issues/4992
// doing it in a `useEffect` works, but there are still timing issues where updates are lost and inconsistency arise
useMemo(() => {
editor.children = data?.slate;
try {
// focus
Expand All @@ -37,27 +40,19 @@ const SlateProvider: FC<PropsWithChildren<SlateProps>> = (props) => {
}
}, [data?.slate, data?.selection]);

const onChange = useCallback(
(v: any) => {
if (
!deepEquals(editor.children, data?.slate) ||
!deepEquals(editor.selection, data?.selection)
) {
props.onChange(
{
slate: editor.children,
selection: editor.selection,
},
{
// mark as not undoable when state is same
// that happens if only selection was changed
notUndoable: deepEquals(editor.children, data?.slate),
}
);
const onChange = useCallback(() => {
props.onChange(
{
slate: editor.children,
selection: editor.selection,
},
{
// mark as not undoable when state is same
// that happens if only selection was changed
notUndoable: deepEquals(editor.children, data?.slate),
}
},
[data?.slate, props.onChange]
);
);
}, [data?.slate, props.onChange]);

const initialValue = data?.slate;

Expand Down

0 comments on commit b593744

Please sign in to comment.