@tiptap/react 2.1.0-rc.11 → 2.1.0-rc.13
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 +160 -124
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +158 -126
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +163 -127
- package/dist/index.umd.js.map +1 -1
- package/dist/packages/react/src/BubbleMenu.d.ts +2 -2
- package/dist/packages/react/src/Context.d.ts +15 -0
- package/dist/packages/react/src/EditorContent.d.ts +1 -1
- package/dist/packages/react/src/FloatingMenu.d.ts +2 -2
- package/dist/packages/react/src/index.d.ts +1 -0
- package/package.json +7 -7
- package/src/BubbleMenu.tsx +16 -6
- package/src/Context.tsx +47 -0
- package/src/FloatingMenu.tsx +16 -5
- package/src/index.ts +1 -0
package/src/BubbleMenu.tsx
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { BubbleMenuPlugin, BubbleMenuPluginProps } from '@tiptap/extension-bubble-menu'
|
|
2
2
|
import React, { useEffect, useState } from 'react'
|
|
3
3
|
|
|
4
|
+
import { useCurrentEditor } from './Context.js'
|
|
5
|
+
|
|
4
6
|
type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
|
|
5
7
|
|
|
6
|
-
export type BubbleMenuProps = Omit<Optional<BubbleMenuPluginProps, 'pluginKey'>, 'element'> & {
|
|
8
|
+
export type BubbleMenuProps = Omit<Optional<BubbleMenuPluginProps, 'pluginKey' | 'editor'>, 'element'> & {
|
|
7
9
|
className?: string;
|
|
8
10
|
children: React.ReactNode;
|
|
9
11
|
updateDelay?: number;
|
|
@@ -11,13 +13,14 @@ export type BubbleMenuProps = Omit<Optional<BubbleMenuPluginProps, 'pluginKey'>,
|
|
|
11
13
|
|
|
12
14
|
export const BubbleMenu = (props: BubbleMenuProps) => {
|
|
13
15
|
const [element, setElement] = useState<HTMLDivElement | null>(null)
|
|
16
|
+
const { editor: currentEditor } = useCurrentEditor()
|
|
14
17
|
|
|
15
18
|
useEffect(() => {
|
|
16
19
|
if (!element) {
|
|
17
20
|
return
|
|
18
21
|
}
|
|
19
22
|
|
|
20
|
-
if (props.editor
|
|
23
|
+
if (props.editor?.isDestroyed || currentEditor?.isDestroyed) {
|
|
21
24
|
return
|
|
22
25
|
}
|
|
23
26
|
|
|
@@ -25,18 +28,25 @@ export const BubbleMenu = (props: BubbleMenuProps) => {
|
|
|
25
28
|
pluginKey = 'bubbleMenu', editor, tippyOptions = {}, updateDelay, shouldShow = null,
|
|
26
29
|
} = props
|
|
27
30
|
|
|
31
|
+
const menuEditor = editor || currentEditor
|
|
32
|
+
|
|
33
|
+
if (!menuEditor) {
|
|
34
|
+
console.warn('BubbleMenu component is not rendered inside of an editor component or does not have editor prop.')
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
|
|
28
38
|
const plugin = BubbleMenuPlugin({
|
|
29
39
|
updateDelay,
|
|
30
|
-
editor,
|
|
40
|
+
editor: menuEditor,
|
|
31
41
|
element,
|
|
32
42
|
pluginKey,
|
|
33
43
|
shouldShow,
|
|
34
44
|
tippyOptions,
|
|
35
45
|
})
|
|
36
46
|
|
|
37
|
-
|
|
38
|
-
return () =>
|
|
39
|
-
}, [props.editor, element])
|
|
47
|
+
menuEditor.registerPlugin(plugin)
|
|
48
|
+
return () => menuEditor.unregisterPlugin(pluginKey)
|
|
49
|
+
}, [props.editor, currentEditor, element])
|
|
40
50
|
|
|
41
51
|
return (
|
|
42
52
|
<div ref={setElement} className={props.className} style={{ visibility: 'hidden' }}>
|
package/src/Context.tsx
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { EditorOptions } from '@tiptap/core'
|
|
2
|
+
import React, { createContext, ReactNode, useContext } from 'react'
|
|
3
|
+
|
|
4
|
+
import { Editor } from './Editor.js'
|
|
5
|
+
import { EditorContent } from './EditorContent.js'
|
|
6
|
+
import { useEditor } from './useEditor.js'
|
|
7
|
+
|
|
8
|
+
export type EditorContextValue = {
|
|
9
|
+
editor: Editor | null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const EditorContext = createContext<EditorContextValue>({
|
|
13
|
+
editor: null,
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
export const EditorConsumer = EditorContext.Consumer
|
|
17
|
+
|
|
18
|
+
export const useCurrentEditor = () => useContext(EditorContext)
|
|
19
|
+
|
|
20
|
+
export type EditorProviderProps = {
|
|
21
|
+
children: ReactNode;
|
|
22
|
+
slotBefore?: ReactNode;
|
|
23
|
+
slotAfter?: ReactNode;
|
|
24
|
+
} & Partial<EditorOptions>
|
|
25
|
+
|
|
26
|
+
export const EditorProvider = ({
|
|
27
|
+
children, slotAfter, slotBefore, ...editorOptions
|
|
28
|
+
}: EditorProviderProps) => {
|
|
29
|
+
const editor = useEditor(editorOptions)
|
|
30
|
+
|
|
31
|
+
if (!editor) {
|
|
32
|
+
return null
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<EditorContext.Provider value={{ editor }}>
|
|
37
|
+
{slotBefore}
|
|
38
|
+
<EditorConsumer>
|
|
39
|
+
{({ editor: currentEditor }) => (
|
|
40
|
+
<EditorContent editor={currentEditor} />
|
|
41
|
+
)}
|
|
42
|
+
</EditorConsumer>
|
|
43
|
+
{children}
|
|
44
|
+
{slotAfter}
|
|
45
|
+
</EditorContext.Provider>
|
|
46
|
+
)
|
|
47
|
+
}
|
package/src/FloatingMenu.tsx
CHANGED
|
@@ -3,22 +3,25 @@ import React, {
|
|
|
3
3
|
useEffect, useState,
|
|
4
4
|
} from 'react'
|
|
5
5
|
|
|
6
|
+
import { useCurrentEditor } from './Context.js'
|
|
7
|
+
|
|
6
8
|
type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>
|
|
7
9
|
|
|
8
|
-
export type FloatingMenuProps = Omit<Optional<FloatingMenuPluginProps, 'pluginKey'>, 'element'> & {
|
|
10
|
+
export type FloatingMenuProps = Omit<Optional<FloatingMenuPluginProps, 'pluginKey' | 'editor'>, 'element'> & {
|
|
9
11
|
className?: string,
|
|
10
12
|
children: React.ReactNode
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
export const FloatingMenu = (props: FloatingMenuProps) => {
|
|
14
16
|
const [element, setElement] = useState<HTMLDivElement | null>(null)
|
|
17
|
+
const { editor: currentEditor } = useCurrentEditor()
|
|
15
18
|
|
|
16
19
|
useEffect(() => {
|
|
17
20
|
if (!element) {
|
|
18
21
|
return
|
|
19
22
|
}
|
|
20
23
|
|
|
21
|
-
if (props.editor
|
|
24
|
+
if (props.editor?.isDestroyed || currentEditor?.isDestroyed) {
|
|
22
25
|
return
|
|
23
26
|
}
|
|
24
27
|
|
|
@@ -29,18 +32,26 @@ export const FloatingMenu = (props: FloatingMenuProps) => {
|
|
|
29
32
|
shouldShow = null,
|
|
30
33
|
} = props
|
|
31
34
|
|
|
35
|
+
const menuEditor = editor || currentEditor
|
|
36
|
+
|
|
37
|
+
if (!menuEditor) {
|
|
38
|
+
console.warn('FloatingMenu component is not rendered inside of an editor component or does not have editor prop.')
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
|
|
32
42
|
const plugin = FloatingMenuPlugin({
|
|
33
43
|
pluginKey,
|
|
34
|
-
editor,
|
|
44
|
+
editor: menuEditor,
|
|
35
45
|
element,
|
|
36
46
|
tippyOptions,
|
|
37
47
|
shouldShow,
|
|
38
48
|
})
|
|
39
49
|
|
|
40
|
-
|
|
41
|
-
return () =>
|
|
50
|
+
menuEditor.registerPlugin(plugin)
|
|
51
|
+
return () => menuEditor.unregisterPlugin(pluginKey)
|
|
42
52
|
}, [
|
|
43
53
|
props.editor,
|
|
54
|
+
currentEditor,
|
|
44
55
|
element,
|
|
45
56
|
])
|
|
46
57
|
|