diff --git a/README.md b/README.md index bcda570d..b402b117 100644 --- a/README.md +++ b/README.md @@ -420,10 +420,13 @@ function MyProseMirrorField() { ### `useEditorState` ```tsx -type useEditorState = () => EditorState; +type useEditorState = () => [ + EditorState, + React.Dispatch> +]; ``` -Provides access to the current EditorState value. +Provides access to the current EditorState value and a method to update it. ### `useEditorEventCallback` diff --git a/demo/Menu.tsx b/demo/Menu.tsx index 3d611e84..040a5252 100644 --- a/demo/Menu.tsx +++ b/demo/Menu.tsx @@ -37,7 +37,7 @@ export function Button(props: { } export default function Menu() { - const state = useEditorState(); + const [state] = useEditorState(); const toggleBold = useEditorEventCallback((view) => { const toggleBoldMark = toggleMark(view.state.schema.marks["strong"]); diff --git a/src/contexts/EditorContext.ts b/src/contexts/EditorContext.ts index ad1248e3..c8cb88b1 100644 --- a/src/contexts/EditorContext.ts +++ b/src/contexts/EditorContext.ts @@ -1,12 +1,13 @@ import type { EditorState } from "prosemirror-state"; import type { DOMEventMap, EditorView } from "prosemirror-view"; -import { createContext } from "react"; +import React, { createContext } from "react"; import type { EventHandler } from "../plugins/componentEventListeners"; export interface EditorContextValue { editorView: EditorView | null; editorState: EditorState; + setEditorState: React.Dispatch>; registerEventListener( eventType: EventType, handler: EventHandler diff --git a/src/hooks/useEditorState.ts b/src/hooks/useEditorState.ts index b4d10c66..ef1ed133 100644 --- a/src/hooks/useEditorState.ts +++ b/src/hooks/useEditorState.ts @@ -1,13 +1,16 @@ +import { EditorContext } from "../contexts/EditorContext.js"; +import type { EditorContextValue } from "../contexts/EditorContext.js"; + import type { EditorState } from "prosemirror-state"; import { useContext } from "react"; -import { EditorContext } from "../contexts/EditorContext.js"; - /** - * Provides access to the current EditorState value. + * Provides access to the current EditorState value and method to update it. */ -export function useEditorState(): EditorState { - const { editorState } = useContext(EditorContext); - - return editorState; +export function useEditorState(): [ + EditorState, + EditorContextValue["setEditorState"], +] { + const { editorState, setEditorState } = useContext(EditorContext); + return [editorState, setEditorState]; } diff --git a/src/hooks/useEditorView.ts b/src/hooks/useEditorView.ts index e996d5be..460ea59e 100644 --- a/src/hooks/useEditorView.ts +++ b/src/hooks/useEditorView.ts @@ -26,6 +26,7 @@ let didWarnValueDefaultValue = false; export interface UseEditorViewOptions extends EditorProps { defaultState?: EditorState; state?: EditorState; + setState?: EditorContextValue["setEditorState"]; plugins?: Plugin[]; dispatchTransaction?(this: EditorView, tr: Transaction): void; } @@ -61,8 +62,9 @@ export function useEditorView( } const defaultState = options.defaultState ?? EMPTY_STATE; - const [_state, setState] = useState(defaultState); + const [_state, _setState] = useState(defaultState); const state = options.state ?? _state; + const setState = options.setState ?? _setState; const { componentEventListenersPlugin, @@ -121,10 +123,11 @@ export function useEditorView( return useMemo( () => ({ editorState: state, + setEditorState: setState, editorView: view, registerEventListener, unregisterEventListener, }), - [state, view, registerEventListener, unregisterEventListener] + [state, setState, view, registerEventListener, unregisterEventListener] ); } diff --git a/src/hooks/useNodePos.tsx b/src/hooks/useNodePos.tsx index 3576370f..27e80934 100644 --- a/src/hooks/useNodePos.tsx +++ b/src/hooks/useNodePos.tsx @@ -14,7 +14,7 @@ type Props = { const NodePosContext = createContext(null as unknown as number); export function NodePosProvider({ nodeKey, children }: Props) { - const editorState = useEditorState(); + const [editorState] = useEditorState(); const pluginState = reactPluginKey.getState(editorState); if (!pluginState) return <>{children}; return (