@tiptap/react 3.0.0-next.1 → 3.0.0-next.2
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.
- package/dist/index.cjs +255 -130
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +155 -42
- package/dist/index.d.ts +155 -42
- package/dist/index.js +244 -113
- package/dist/index.js.map +1 -1
- package/package.json +9 -8
- package/src/BubbleMenu.tsx +70 -50
- package/src/Context.tsx +14 -6
- package/src/FloatingMenu.tsx +51 -45
- package/src/ReactNodeViewRenderer.tsx +152 -41
- package/src/ReactRenderer.tsx +26 -19
- package/src/useEditor.ts +17 -9
- package/src/useEditorState.ts +49 -10
package/src/useEditorState.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import type { Editor } from '@tiptap/core'
|
|
2
|
-
import
|
|
2
|
+
import deepEqual from 'fast-deep-equal/es6/react'
|
|
3
|
+
import {
|
|
4
|
+
useDebugValue, useEffect, useLayoutEffect, useState,
|
|
5
|
+
} from 'react'
|
|
3
6
|
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector'
|
|
4
7
|
|
|
8
|
+
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect
|
|
9
|
+
|
|
5
10
|
export type EditorStateSnapshot<TEditor extends Editor | null = Editor | null> = {
|
|
6
11
|
editor: TEditor;
|
|
7
12
|
transactionNumber: number;
|
|
8
13
|
};
|
|
14
|
+
|
|
9
15
|
export type UseEditorStateOptions<
|
|
10
16
|
TSelectorResult,
|
|
11
17
|
TEditor extends Editor | null = Editor | null,
|
|
@@ -20,7 +26,7 @@ export type UseEditorStateOptions<
|
|
|
20
26
|
selector: (context: EditorStateSnapshot<TEditor>) => TSelectorResult;
|
|
21
27
|
/**
|
|
22
28
|
* A custom equality function to determine if the editor should re-render.
|
|
23
|
-
* @default `
|
|
29
|
+
* @default `deepEqual` from `fast-deep-equal`
|
|
24
30
|
*/
|
|
25
31
|
equalityFn?: (a: TSelectorResult, b: TSelectorResult | null) => boolean;
|
|
26
32
|
};
|
|
@@ -108,30 +114,63 @@ class EditorStateManager<TEditor extends Editor | null = Editor | null> {
|
|
|
108
114
|
}
|
|
109
115
|
}
|
|
110
116
|
|
|
117
|
+
/**
|
|
118
|
+
* This hook allows you to watch for changes on the editor instance.
|
|
119
|
+
* It will allow you to select a part of the editor state and re-render the component when it changes.
|
|
120
|
+
* @example
|
|
121
|
+
* ```tsx
|
|
122
|
+
* const editor = useEditor({...options})
|
|
123
|
+
* const { currentSelection } = useEditorState({
|
|
124
|
+
* editor,
|
|
125
|
+
* selector: snapshot => ({ currentSelection: snapshot.editor.state.selection }),
|
|
126
|
+
* })
|
|
127
|
+
*/
|
|
111
128
|
export function useEditorState<TSelectorResult>(
|
|
112
129
|
options: UseEditorStateOptions<TSelectorResult, Editor>
|
|
113
130
|
): TSelectorResult;
|
|
131
|
+
/**
|
|
132
|
+
* This hook allows you to watch for changes on the editor instance.
|
|
133
|
+
* It will allow you to select a part of the editor state and re-render the component when it changes.
|
|
134
|
+
* @example
|
|
135
|
+
* ```tsx
|
|
136
|
+
* const editor = useEditor({...options})
|
|
137
|
+
* const { currentSelection } = useEditorState({
|
|
138
|
+
* editor,
|
|
139
|
+
* selector: snapshot => ({ currentSelection: snapshot.editor.state.selection }),
|
|
140
|
+
* })
|
|
141
|
+
*/
|
|
114
142
|
export function useEditorState<TSelectorResult>(
|
|
115
143
|
options: UseEditorStateOptions<TSelectorResult, Editor | null>
|
|
116
144
|
): TSelectorResult | null;
|
|
117
145
|
|
|
146
|
+
/**
|
|
147
|
+
* This hook allows you to watch for changes on the editor instance.
|
|
148
|
+
* It will allow you to select a part of the editor state and re-render the component when it changes.
|
|
149
|
+
* @example
|
|
150
|
+
* ```tsx
|
|
151
|
+
* const editor = useEditor({...options})
|
|
152
|
+
* const { currentSelection } = useEditorState({
|
|
153
|
+
* editor,
|
|
154
|
+
* selector: snapshot => ({ currentSelection: snapshot.editor.state.selection }),
|
|
155
|
+
* })
|
|
156
|
+
*/
|
|
118
157
|
export function useEditorState<TSelectorResult>(
|
|
119
158
|
options: UseEditorStateOptions<TSelectorResult, Editor> | UseEditorStateOptions<TSelectorResult, Editor | null>,
|
|
120
159
|
): TSelectorResult | null {
|
|
121
|
-
const [
|
|
160
|
+
const [editorStateManager] = useState(() => new EditorStateManager(options.editor))
|
|
122
161
|
|
|
123
162
|
// Using the `useSyncExternalStore` hook to sync the editor instance with the component state
|
|
124
163
|
const selectedState = useSyncExternalStoreWithSelector(
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
164
|
+
editorStateManager.subscribe,
|
|
165
|
+
editorStateManager.getSnapshot,
|
|
166
|
+
editorStateManager.getServerSnapshot,
|
|
128
167
|
options.selector as UseEditorStateOptions<TSelectorResult, Editor | null>['selector'],
|
|
129
|
-
options.equalityFn,
|
|
168
|
+
options.equalityFn ?? deepEqual,
|
|
130
169
|
)
|
|
131
170
|
|
|
132
|
-
|
|
133
|
-
return
|
|
134
|
-
}, [options.editor,
|
|
171
|
+
useIsomorphicLayoutEffect(() => {
|
|
172
|
+
return editorStateManager.watch(options.editor)
|
|
173
|
+
}, [options.editor, editorStateManager])
|
|
135
174
|
|
|
136
175
|
useDebugValue(selectedState)
|
|
137
176
|
|