diff --git a/.changeset/curly-ligers-lay.md b/.changeset/curly-ligers-lay.md new file mode 100644 index 0000000000..6ffa5f9ea9 --- /dev/null +++ b/.changeset/curly-ligers-lay.md @@ -0,0 +1,6 @@ +--- +'slate': minor +'slate-react': minor +--- + +Add `onValueChange` to watch value changes and `onSelectorChange` to watch selector changes diff --git a/packages/slate-react/src/components/slate.tsx b/packages/slate-react/src/components/slate.tsx index 2e1d69d730..eddc8e6e75 100644 --- a/packages/slate-react/src/components/slate.tsx +++ b/packages/slate-react/src/components/slate.tsx @@ -23,6 +23,7 @@ export const Slate = (props: { children: React.ReactNode onChange?: (value: Descendant[]) => void }) => { + // do we need to add onValueChange and onSelectorChange here? const { editor, children, onChange, initialValue, ...rest } = props const [context, setContext] = React.useState(() => { diff --git a/packages/slate-react/src/plugin/with-react.ts b/packages/slate-react/src/plugin/with-react.ts index 21d0ff10b7..9d1258eeb5 100644 --- a/packages/slate-react/src/plugin/with-react.ts +++ b/packages/slate-react/src/plugin/with-react.ts @@ -53,7 +53,15 @@ export const withReact = ( clipboardFormatKey = 'x-slate-fragment' ): T & ReactEditor => { const e = editor as T & ReactEditor - const { apply, onChange, deleteBackward, addMark, removeMark } = e + const { + apply, + onChange, + onValueChange, + onSelectionChange, + deleteBackward, + addMark, + removeMark, + } = e // The WeakMap which maps a key to a specific HTMLElement must be scoped to the editor instance to // avoid collisions between editors in the DOM that share the same value. @@ -366,6 +374,14 @@ export const withReact = ( onContextChange() } + switch (options?.operation?.type) { + case 'set_selection': + onSelectionChange(options) + break + default: + onValueChange(options) + } + onChange(options) }) } diff --git a/packages/slate/src/interfaces/editor.ts b/packages/slate/src/interfaces/editor.ts index 3907e89526..f0e01c6309 100644 --- a/packages/slate/src/interfaces/editor.ts +++ b/packages/slate/src/interfaces/editor.ts @@ -56,6 +56,8 @@ export interface BaseEditor { markableVoid: (element: Element) => boolean normalizeNode: (entry: NodeEntry, options?: { operation?: Operation }) => void onChange: (options?: { operation?: Operation }) => void + onSelectionChange: (options?: { operation?: Operation }) => void + onValueChange: (options?: { operation?: Operation }) => void shouldNormalize: ({ iteration, dirtyPaths,