@prosekit/react 0.4.14 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -115,11 +115,35 @@ declare function useEditor<E extends Extension = any>(options?: {
115
115
  * Whether to update the component when the editor is mounted or editor state
116
116
  * is updated.
117
117
  *
118
+ * Note this this option doesn't work with [React
119
+ * compiler](https://react.dev/learn/react-compiler) because the returned
120
+ * editor will be the same instance after state updates. If you're using React
121
+ * compiler, you should use {@link useEditorDerivedValue} instead.
122
+ *
118
123
  * @default false
119
124
  */
120
125
  update?: boolean;
121
126
  }): Editor<E>;
122
127
  //#endregion
128
+ //#region src/hooks/use-editor-derived-value.d.ts
129
+ interface UseEditorDerivedOptions<E extends Extension = any> {
130
+ /**
131
+ * The editor to add the extension to. If not provided, it will use the
132
+ * editor from the nearest `ProseKit` component.
133
+ */
134
+ editor?: Editor<E>;
135
+ }
136
+ /**
137
+ * A hook that runs a function to derive a value from the editor instance after
138
+ * editor state changes.
139
+ *
140
+ * This is useful when you need to render something based on the editor state,
141
+ * for example, whether the selected text is wrapped in an italic mark.
142
+ *
143
+ * @public
144
+ */
145
+ declare function useEditorDerivedValue<E extends Extension, Derived>(derive: (editor: Editor<E>) => Derived, options?: UseEditorDerivedOptions<E>): Derived;
146
+ //#endregion
123
147
  //#region src/hooks/use-keymap.d.ts
124
148
  declare function useKeymap(keymap: Keymap, options?: UseExtensionOptions): void;
125
149
  //#endregion
@@ -139,4 +163,4 @@ type PropsWithClassName<P = unknown> = P & {
139
163
  className?: string | undefined;
140
164
  };
141
165
  //#endregion
142
- export { PropsWithClassName, ProseKit, ProseKitProps, ReactMarkViewComponent, ReactMarkViewOptions, ReactMarkViewProps, ReactNodeViewComponent, ReactNodeViewOptions, ReactNodeViewProps, UseExtensionOptions, defineReactMarkView, defineReactNodeView, useDocChange, useEditor, useExtension, useKeymap, useStateUpdate };
166
+ export { PropsWithClassName, ProseKit, ProseKitProps, ReactMarkViewComponent, ReactMarkViewOptions, ReactMarkViewProps, ReactNodeViewComponent, ReactNodeViewOptions, ReactNodeViewProps, UseEditorDerivedOptions, UseExtensionOptions, defineReactMarkView, defineReactNodeView, useDocChange, useEditor, useEditorDerivedValue, useExtension, useKeymap, useStateUpdate };
@@ -1,6 +1,6 @@
1
1
  import { EditorContextProvider, useEditorContext } from "./editor-context-Cci4uqN_.js";
2
2
  import { ProsemirrorAdapterProvider, useMarkViewContext, useMarkViewFactory, useNodeViewContext, useNodeViewFactory } from "@prosemirror-adapter/react";
3
- import { createElement, useEffect, useMemo, useReducer } from "react";
3
+ import { createElement, useEffect, useMemo, useReducer, useSyncExternalStore } from "react";
4
4
  import { EditorNotFoundError, ProseKitError, defineDocChangeHandler, defineKeymap, defineMarkViewComponent, defineMarkViewFactory, defineMountHandler, defineNodeViewComponent, defineNodeViewFactory, defineUpdateHandler, union, withPriority } from "@prosekit/core";
5
5
 
6
6
  //#region src/hooks/use-editor-extension.ts
@@ -170,6 +170,47 @@ function useForceUpdate() {
170
170
  return dispatch;
171
171
  }
172
172
 
173
+ //#endregion
174
+ //#region src/hooks/use-editor-derived-value.ts
175
+ /**
176
+ * A hook that runs a function to derive a value from the editor instance after
177
+ * editor state changes.
178
+ *
179
+ * This is useful when you need to render something based on the editor state,
180
+ * for example, whether the selected text is wrapped in an italic mark.
181
+ *
182
+ * @public
183
+ */
184
+ function useEditorDerivedValue(derive, options) {
185
+ const editorContext = useEditorContext();
186
+ const editor = options?.editor ?? editorContext;
187
+ if (!editor) throw new EditorNotFoundError();
188
+ const [subscribe, getSnapshot] = useMemo(() => {
189
+ return createEditorStore(editor, derive);
190
+ }, [editor, derive]);
191
+ return useSyncExternalStore(subscribe, getSnapshot);
192
+ }
193
+ function createEditorStore(editor, derive) {
194
+ let dirty = true;
195
+ let derived;
196
+ const subscribe = (onChange) => {
197
+ const handleChange = () => {
198
+ dirty = true;
199
+ onChange();
200
+ };
201
+ const extension = union(defineUpdateHandler(handleChange), defineMountHandler(handleChange));
202
+ return editor.use(extension);
203
+ };
204
+ const getSnapshot = () => {
205
+ if (dirty) {
206
+ dirty = false;
207
+ derived = derive(editor);
208
+ }
209
+ return derived;
210
+ };
211
+ return [subscribe, getSnapshot];
212
+ }
213
+
173
214
  //#endregion
174
215
  //#region src/hooks/use-keymap.ts
175
216
  function useKeymap(keymap, options) {
@@ -190,4 +231,4 @@ function useStateUpdate(handler, options) {
190
231
  }
191
232
 
192
233
  //#endregion
193
- export { ProseKit, defineReactMarkView, defineReactNodeView, useDocChange, useEditor, useExtension, useKeymap, useStateUpdate };
234
+ export { ProseKit, defineReactMarkView, defineReactNodeView, useDocChange, useEditor, useEditorDerivedValue, useExtension, useKeymap, useStateUpdate };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prosekit/react",
3
3
  "type": "module",
4
- "version": "0.4.14",
4
+ "version": "0.5.0",
5
5
  "private": false,
6
6
  "description": "React components and utilities for ProseKit",
7
7
  "author": {
@@ -65,9 +65,9 @@
65
65
  "dependencies": {
66
66
  "@prosemirror-adapter/core": "^0.4.0",
67
67
  "@prosemirror-adapter/react": "^0.4.1",
68
+ "@prosekit/core": "^0.8.1",
68
69
  "@prosekit/pm": "^0.1.10",
69
- "@prosekit/web": "^0.5.9",
70
- "@prosekit/core": "^0.8.1"
70
+ "@prosekit/web": "^0.5.9"
71
71
  },
72
72
  "peerDependencies": {
73
73
  "react": ">= 18.2.0",
@@ -86,7 +86,7 @@
86
86
  "@types/react-dom": "^19.1.5",
87
87
  "react": "^19.1.0",
88
88
  "react-dom": "^19.1.0",
89
- "tsdown": "^0.12.4",
89
+ "tsdown": "^0.12.5",
90
90
  "typescript": "~5.8.3",
91
91
  "vitest": "^3.1.4",
92
92
  "@prosekit/config-tsdown": "0.0.0",