Skip to content

Commit

Permalink
Merge pull request #3346 from yf-yang/expose-slate-onchange
Browse files Browse the repository at this point in the history
feat: expose onValueChange and onSelectionChange from Slate component
  • Loading branch information
zbeyens authored Jul 11, 2024
2 parents 65cfe84 + 7d36a04 commit 30a2e69
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 8 deletions.
6 changes: 6 additions & 0 deletions .changeset/rich-clouds-attack.md
Original file line number Diff line number Diff line change
@@ -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
18 changes: 14 additions & 4 deletions packages/core/src/client/components/Plate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@ export interface PlateProps<
> extends Partial<
Pick<
PlateStoreState<V, E>,
'editor' | 'id' | 'primary' | 'readOnly' | 'value'
| 'editor'
| 'id'
| 'onChange'
| 'onSelectionChange'
| 'onValueChange'
| 'primary'
| 'readOnly'
| 'value'
>
> {
children: React.ReactNode;
Expand Down Expand Up @@ -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'];
Expand All @@ -91,6 +95,8 @@ function PlateInner<
maxLength,
normalizeInitialValue: shouldNormalizeInitialValue,
onChange,
onSelectionChange,
onValueChange,
plugins: pluginsProp,
primary,
readOnly,
Expand Down Expand Up @@ -149,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}
Expand Down
16 changes: 15 additions & 1 deletion packages/core/src/client/hooks/useSlateProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export const useSlateProps = <V extends Value>({
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) => {
Expand All @@ -35,13 +37,25 @@ export const useSlateProps = <V extends Value>({
[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]);
};
4 changes: 4 additions & 0 deletions packages/core/src/client/stores/plate/createPlateStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export const createPlateStore = <
id,
isMounted = false,
onChange = null,
onSelectionChange = null,
onValueChange = null,
plugins = [],
primary = true,
rawPlugins = [],
Expand All @@ -56,6 +58,8 @@ export const createPlateStore = <
id,
isMounted,
onChange,
onSelectionChange,
onValueChange,
plugins,
primary,
rawPlugins,
Expand Down
8 changes: 7 additions & 1 deletion packages/core/src/shared/types/PlateStore.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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.
Expand Down
6 changes: 4 additions & 2 deletions packages/slate-react/src/types/SlateProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

0 comments on commit 30a2e69

Please sign in to comment.