From 8c49669bb669aaf025e591de4a3c333d5cad0e7c Mon Sep 17 00:00:00 2001 From: Brian Hung Date: Fri, 27 Sep 2024 01:26:05 -0700 Subject: [PATCH 1/2] setState and useEditorStateWithDispatch --- src/contexts/EditorContext.ts | 3 ++- src/hooks/useEditorState.ts | 11 +++++++++-- src/hooks/useEditorView.ts | 7 +++++-- 3 files changed, 16 insertions(+), 5 deletions(-) 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..a88dd94b 100644 --- a/src/hooks/useEditorState.ts +++ b/src/hooks/useEditorState.ts @@ -1,13 +1,20 @@ import type { EditorState } from "prosemirror-state"; import { useContext } from "react"; -import { EditorContext } from "../contexts/EditorContext.js"; +import { EditorContext, type EditorContextValue } from "../contexts/EditorContext.js"; /** * Provides access to the current EditorState value. */ export function useEditorState(): EditorState { const { editorState } = useContext(EditorContext); - return editorState; } + +/** + * Provides access to the current EditorState value and method to update it. + */ +export function useEditorStateWithDispatch(): [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..5b03690c 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] ); } From 1829f19ea47b1f81f659d2e4c8c6ad993830d8a0 Mon Sep 17 00:00:00 2001 From: BrianHung Date: Thu, 3 Oct 2024 23:07:00 -0700 Subject: [PATCH 2/2] update useEditorState to have setState --- README.md | 7 +++++-- demo/Menu.tsx | 2 +- src/hooks/useEditorState.ts | 18 +++++++----------- src/hooks/useEditorView.ts | 2 +- src/hooks/useNodePos.tsx | 2 +- 5 files changed, 15 insertions(+), 16 deletions(-) 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/hooks/useEditorState.ts b/src/hooks/useEditorState.ts index a88dd94b..ef1ed133 100644 --- a/src/hooks/useEditorState.ts +++ b/src/hooks/useEditorState.ts @@ -1,20 +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, type EditorContextValue } from "../contexts/EditorContext.js"; - -/** - * Provides access to the current EditorState value. - */ -export function useEditorState(): EditorState { - const { editorState } = useContext(EditorContext); - return editorState; -} - /** * Provides access to the current EditorState value and method to update it. */ -export function useEditorStateWithDispatch(): [EditorState, EditorContextValue['setEditorState']] { +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 5b03690c..460ea59e 100644 --- a/src/hooks/useEditorView.ts +++ b/src/hooks/useEditorView.ts @@ -26,7 +26,7 @@ let didWarnValueDefaultValue = false; export interface UseEditorViewOptions extends EditorProps { defaultState?: EditorState; state?: EditorState; - setState?: EditorContextValue['setEditorState']; + setState?: EditorContextValue["setEditorState"]; plugins?: Plugin[]; dispatchTransaction?(this: EditorView, tr: Transaction): void; } 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 (