Skip to content

Commit 2d57d8f

Browse files
committed
don't use editor passed in, just for types
1 parent 0b40bdd commit 2d57d8f

File tree

3 files changed

+56
-34
lines changed

3 files changed

+56
-34
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ import { api } from "../convex/_generated/api";
140140
import { BlockNoteEditor } from "@blocknote/core";
141141

142142
export function MyComponent() {
143-
const sync = useBlockNoteSync(api.example, "some-id", { BlockNoteEditor });
143+
const sync = useBlockNoteSync<BlockNoteEditor>(api.example, "some-id");
144144
return sync.isLoading ? (
145145
<p>Loading...</p>
146146
) : sync.editor ? (

example/src/BlockNoteExample.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ import { api } from "../convex/_generated/api";
66
import { BlockNoteEditor } from "@blocknote/core";
77

88
export function BlockNoteExample(props: { id: string }) {
9-
const sync = useBlockNoteSync(api.example, props.id, {
10-
BlockNoteEditor,
9+
const sync = useBlockNoteSync<BlockNoteEditor>(api.example, props.id, {
1110
debug: true,
1211
});
1312
if (!sync.isLoading && sync.editor === null) {

src/blocknote/index.ts

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,9 @@ import {
77
type BlockNoteEditorOptions,
88
nodeToBlock,
99
} from "@blocknote/core";
10-
import { Schema } from "prosemirror-model";
10+
import { JSONContent } from "@tiptap/core";
1111

12-
interface BlockNoteEditorInterface {
13-
readonly pmSchema: Schema;
14-
}
15-
16-
interface BlockNoteEditorCreator<Editor extends BlockNoteEditorInterface> {
17-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
18-
create: (options: any) => Editor;
19-
}
20-
21-
export type BlockNoteSyncOptions<
22-
Editor extends BlockNoteEditorInterface = BlockNoteEditor,
23-
> = UseSyncOptions & {
12+
export type BlockNoteSyncOptions<Editor = BlockNoteEditor> = UseSyncOptions & {
2413
/**
2514
* If you pass options into the editor, you should pass them here, to ensure
2615
* the initialContent is parsed with the correct schema.
@@ -30,28 +19,62 @@ export type BlockNoteSyncOptions<
3019
Omit<BlockNoteEditorOptions<any, any, any>, "initialContent">
3120
>;
3221
/**
33-
* The BlockNoteEditor from your installed version of BlockNote.
34-
* If you see an error like:
35-
* ```
36-
* Property 'options' is protected but type 'BlockNoteEditor<BSchema, ISchema, SSchema>' is not a class derived from 'BlockNoteEditor<BSchema, ISchema, SSchema>'.
37-
* ```
38-
* You can pass your own BlockNoteEditor version here.
39-
* This is a workaround for the types of your editor not matching the editor
40-
* version used by prosemirror-sync.
22+
* @deprecated Do `useBlockNoteSync<BlockNoteEditor>` instead.
23+
*
4124
*/
42-
BlockNoteEditor?: BlockNoteEditorCreator<Editor>;
25+
BlockNoteEditor?: Editor;
4326
};
4427

45-
export function useBlockNoteSync<
46-
Editor extends BlockNoteEditorInterface = BlockNoteEditor,
47-
>(syncApi: SyncApi, id: string, opts?: BlockNoteSyncOptions<Editor>) {
28+
/**
29+
* A hook to sync a BlockNote editor with a Convex document.
30+
*
31+
* Usually used like:
32+
*
33+
* ```tsx
34+
* const sync = useBlockNoteSync(api.example, "some-id");
35+
* ```
36+
*
37+
* If you see an error like:
38+
* ```
39+
* Property 'options' is protected but type 'BlockNoteEditor<BSchema, ISchema, SSchema>' is not a class derived from 'BlockNoteEditor<BSchema, ISchema, SSchema>'.
40+
* ```
41+
* You can pass your own BlockNoteEditor like:
42+
* ```tsx
43+
* import { BlockNoteEditor } from "@blocknote/core";
44+
* //...
45+
* const sync = useBlockNoteSync<BlockNoteEditor>(api.example, "some-id");
46+
* ```
47+
* This is a workaround for the types of your editor not matching the editor
48+
* version used by prosemirror-sync.
49+
*
50+
* @param syncApi Wherever you exposed the sync api, e.g. `api.example`.
51+
* @param id The document ID.
52+
* @param opts Options to pass to the underlying BlockNoteEditor and sync opts.
53+
* @returns The editor, loading state, and fn to create the initial document.
54+
*/
55+
export function useBlockNoteSync<Editor = BlockNoteEditor>(
56+
syncApi: SyncApi,
57+
id: string,
58+
opts?: BlockNoteSyncOptions<Editor>
59+
):
60+
| {
61+
editor: null;
62+
isLoading: true;
63+
create?: (content: JSONContent) => Promise<void>;
64+
}
65+
| {
66+
editor: null;
67+
isLoading: false;
68+
create: (content: JSONContent) => Promise<void>;
69+
}
70+
| {
71+
editor: Editor;
72+
isLoading: false;
73+
} {
4874
const sync = useTiptapSync(syncApi, id, opts);
49-
const Editor =
50-
opts?.BlockNoteEditor ??
51-
(BlockNoteEditor as unknown as BlockNoteEditorCreator<Editor>);
5275
const editor = useMemo(() => {
5376
if (sync.initialContent === null) return null;
54-
const editor = Editor.create({
77+
const editor = BlockNoteEditor.create({
5578
...opts?.editorOptions,
5679
_headless: true,
5780
});
@@ -67,7 +90,7 @@ export function useBlockNoteSync<
6790
return false;
6891
});
6992
}
70-
return Editor.create({
93+
return BlockNoteEditor.create({
7194
...opts?.editorOptions,
7295
_tiptapOptions: {
7396
...opts?.editorOptions?._tiptapOptions,
@@ -104,7 +127,7 @@ export function useBlockNoteSync<
104127
} as const;
105128
}
106129
return {
107-
editor,
130+
editor: editor as unknown as Editor,
108131
isLoading: false,
109132
} as const;
110133
}

0 commit comments

Comments
 (0)