From e81ef12aead45de788b750e0f370c99183de8871 Mon Sep 17 00:00:00 2001 From: Yifei Date: Wed, 10 Jul 2024 22:33:54 +0800 Subject: [PATCH 1/6] feat: expose onValueChange and onSelectionChange from Slate component --- packages/core/src/client/components/Plate.tsx | 14 +++++++++----- .../core/src/client/hooks/useSlateProps.ts | 18 ++++++++++++++++-- packages/core/src/shared/types/PlateStore.ts | 8 +++++++- packages/slate-react/src/types/SlateProps.ts | 6 ++++-- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/packages/core/src/client/components/Plate.tsx b/packages/core/src/client/components/Plate.tsx index 9145c61206..98822c855c 100644 --- a/packages/core/src/client/components/Plate.tsx +++ b/packages/core/src/client/components/Plate.tsx @@ -21,7 +21,14 @@ export interface PlateProps< > extends Partial< Pick< PlateStoreState, - 'editor' | 'id' | 'primary' | 'readOnly' | 'value' + | 'editor' + | 'id' + | 'onChange' + | 'onSelectionChange' + | 'onValueChange' + | 'primary' + | 'readOnly' + | 'value' > > { children: React.ReactNode; @@ -69,9 +76,6 @@ export interface PlateProps< */ normalizeInitialValue?: boolean; - /** Controlled callback called when the editor state changes. */ - onChange?: (value: V) => void; - plugins?: PlatePlugin[]; renderElement?: TEditableProps['renderElement']; renderLeaf?: TEditableProps['renderLeaf']; @@ -110,7 +114,7 @@ function PlateInner< plugins: pluginsProp as any, }), // eslint-disable-next-line react-hooks/exhaustive-deps - [] + [editorProp] ); const value = React.useMemo( diff --git a/packages/core/src/client/hooks/useSlateProps.ts b/packages/core/src/client/hooks/useSlateProps.ts index 7290305c2a..41ce63c4ef 100644 --- a/packages/core/src/client/hooks/useSlateProps.ts +++ b/packages/core/src/client/hooks/useSlateProps.ts @@ -1,6 +1,6 @@ import React from 'react'; -import type { Value } from '@udecode/slate'; +import type { TSelection, Value } from '@udecode/slate'; import type { SlateProps } from '@udecode/slate-react'; import { pipeOnChange } from '../../shared/utils/pipeOnChange'; @@ -21,6 +21,8 @@ export const useSlateProps = ({ const value = usePlateSelectors(id).value(); const setValue = usePlateActions(id).value(); const onChangeProp = usePlateSelectors(id).onChange(); + const onValueChangeProp = usePlateSelectors(id).onValueChange(); + const onSelectionChangeProp = usePlateSelectors(id).onSelectionChange(); const onChange = React.useCallback( (newValue: V) => { @@ -35,13 +37,25 @@ export const useSlateProps = ({ [editor, setValue, onChangeProp] ); + const onValueChange = React.useMemo( + () => onValueChangeProp, + [onValueChangeProp] + ); + + const onSelectionChange = React.useMemo( + () => onSelectionChangeProp, + [onSelectionChangeProp] + ); + return React.useMemo(() => { return { editor, initialValue: value, key: editor.key, onChange, + onSelectionChange, + onValueChange, value, }; - }, [editor, onChange, value]); + }, [editor, onChange, onSelectionChange, onValueChange, value]); }; diff --git a/packages/core/src/shared/types/PlateStore.ts b/packages/core/src/shared/types/PlateStore.ts index 7d531a28f6..22edc36c9d 100644 --- a/packages/core/src/shared/types/PlateStore.ts +++ b/packages/core/src/shared/types/PlateStore.ts @@ -1,6 +1,6 @@ import type React from 'react'; -import type { Value } from '@udecode/slate'; +import type { TSelection, Value } from '@udecode/slate'; import type { PlateId } from '../../client'; import type { PlateEditor } from './PlateEditor'; @@ -60,6 +60,12 @@ export type PlateStoreState< /** Controlled callback called when the editor state changes. */ onChange: (value: V) => void; + /** Controlled callback called when the editor.selection changes. */ + onSelectionChange: (selection: TSelection) => void; + + /** Controlled callback called when the editor.children changes. */ + onValueChange: (value: V) => void; + /** * Whether the editor is primary. If no editor is active, then PlateController * will use the first-mounted primary editor. diff --git a/packages/slate-react/src/types/SlateProps.ts b/packages/slate-react/src/types/SlateProps.ts index 32974b6f94..b281fe0414 100644 --- a/packages/slate-react/src/types/SlateProps.ts +++ b/packages/slate-react/src/types/SlateProps.ts @@ -7,6 +7,8 @@ import type { ReactEditor } from 'slate-react'; export interface SlateProps extends UnknownObject { children: React.ReactNode; editor: ReactEditor; - onChange: (value: SlateProps['value']) => void; - value: TDescendant[]; + initialValue: TDescendant[]; + onChange?: (value: TDescendant[]) => void; + onSelectionChange?: (selection: Selection) => void; + onValueChange?: (value: TDescendant[]) => void; } From f12958d797302ccb302a82a7c98e90ce8ed21a3e Mon Sep 17 00:00:00 2001 From: yf-yang <36890796+yf-yang@users.noreply.github.com> Date: Wed, 10 Jul 2024 22:38:38 +0800 Subject: [PATCH 2/6] Create rich-clouds-attack.md --- .changeset/rich-clouds-attack.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/rich-clouds-attack.md diff --git a/.changeset/rich-clouds-attack.md b/.changeset/rich-clouds-attack.md new file mode 100644 index 0000000000..6e185efccf --- /dev/null +++ b/.changeset/rich-clouds-attack.md @@ -0,0 +1,6 @@ +--- +"@udecode/plate-core": patch +"@udecode/slate-react": patch +--- + +feat: expose onValueChange and onSelectionChange from Slate component, following https://github.com/ianstormtaylor/slate/pull/5526 From c5014249e1ab3ad1fda87c4190d30855b54ece8b Mon Sep 17 00:00:00 2001 From: Yifei Date: Wed, 10 Jul 2024 22:50:27 +0800 Subject: [PATCH 3/6] fix: add missing props --- packages/core/src/client/components/Plate.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/core/src/client/components/Plate.tsx b/packages/core/src/client/components/Plate.tsx index 98822c855c..1f6dccdc33 100644 --- a/packages/core/src/client/components/Plate.tsx +++ b/packages/core/src/client/components/Plate.tsx @@ -95,6 +95,8 @@ function PlateInner< maxLength, normalizeInitialValue: shouldNormalizeInitialValue, onChange, + onSelectionChange, + onValueChange, plugins: pluginsProp, primary, readOnly, @@ -153,6 +155,10 @@ function PlateInner< editorRef={editorRef as PlateStoreState['editorRef']} id={id} onChange={onChange as PlateStoreState['onChange']} + onSelectionChange={ + onSelectionChange as PlateStoreState['onSelectionChange'] + } + onValueChange={onValueChange as PlateStoreState['onValueChange']} plugins={editor.plugins as any} primary={primary} rawPlugins={pluginsProp} From 01213c8d270ca7bde7a2a5799fb2682a5e697481 Mon Sep 17 00:00:00 2001 From: Yifei Date: Wed, 10 Jul 2024 23:20:10 +0800 Subject: [PATCH 4/6] style: remove unused type --- packages/core/src/client/hooks/useSlateProps.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/client/hooks/useSlateProps.ts b/packages/core/src/client/hooks/useSlateProps.ts index 41ce63c4ef..cd990488fb 100644 --- a/packages/core/src/client/hooks/useSlateProps.ts +++ b/packages/core/src/client/hooks/useSlateProps.ts @@ -1,6 +1,6 @@ import React from 'react'; -import type { TSelection, Value } from '@udecode/slate'; +import type { Value } from '@udecode/slate'; import type { SlateProps } from '@udecode/slate-react'; import { pipeOnChange } from '../../shared/utils/pipeOnChange'; From 5f85b08f373c81dd187786382c1e27839e8345d4 Mon Sep 17 00:00:00 2001 From: Yifei Date: Wed, 10 Jul 2024 23:30:53 +0800 Subject: [PATCH 5/6] fix: fix missing prop in plate store --- packages/core/src/client/stores/plate/createPlateStore.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/core/src/client/stores/plate/createPlateStore.ts b/packages/core/src/client/stores/plate/createPlateStore.ts index e90e8d7ee6..b2f2b672b8 100644 --- a/packages/core/src/client/stores/plate/createPlateStore.ts +++ b/packages/core/src/client/stores/plate/createPlateStore.ts @@ -36,6 +36,8 @@ export const createPlateStore = < id, isMounted = false, onChange = null, + onSelectionChange = null, + onValueChange = null, plugins = [], primary = true, rawPlugins = [], @@ -56,6 +58,8 @@ export const createPlateStore = < id, isMounted, onChange, + onSelectionChange, + onValueChange, plugins, primary, rawPlugins, From 7d36a04538f127a35d2229afaeb9ac13eb3b70ae Mon Sep 17 00:00:00 2001 From: Yifei Date: Thu, 11 Jul 2024 10:40:40 +0800 Subject: [PATCH 6/6] fix: remove unexpected useMemo dep --- packages/core/src/client/components/Plate.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/client/components/Plate.tsx b/packages/core/src/client/components/Plate.tsx index 1f6dccdc33..42f3921361 100644 --- a/packages/core/src/client/components/Plate.tsx +++ b/packages/core/src/client/components/Plate.tsx @@ -116,7 +116,7 @@ function PlateInner< plugins: pluginsProp as any, }), // eslint-disable-next-line react-hooks/exhaustive-deps - [editorProp] + [] ); const value = React.useMemo(