@blocknote/core 0.7.1-alpha.0 → 0.8.1
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/blocknote.js +1711 -1469
- package/dist/blocknote.js.map +1 -1
- package/dist/blocknote.umd.cjs +6 -2
- package/dist/blocknote.umd.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +3 -3
- package/src/BlockNoteEditor.ts +104 -53
- package/src/BlockNoteExtensions.ts +24 -14
- package/src/api/blockManipulation/blockManipulation.test.ts +6 -3
- package/src/api/blockManipulation/blockManipulation.ts +7 -6
- package/src/api/formatConversions/formatConversions.test.ts +13 -8
- package/src/api/formatConversions/formatConversions.ts +15 -12
- package/src/api/nodeConversions/__snapshots__/nodeConversions.test.ts.snap +292 -0
- package/src/api/nodeConversions/nodeConversions.test.ts +265 -10
- package/src/api/nodeConversions/nodeConversions.ts +199 -47
- package/src/api/nodeConversions/testUtil.ts +8 -4
- package/src/editor.module.css +5 -6
- package/src/extensions/Blocks/api/block.ts +229 -0
- package/src/extensions/Blocks/api/blockTypes.ts +158 -71
- package/src/extensions/Blocks/api/cursorPositionTypes.ts +5 -5
- package/src/extensions/Blocks/api/defaultBlocks.ts +44 -0
- package/src/extensions/Blocks/api/selectionTypes.ts +3 -3
- package/src/extensions/Blocks/api/serialization.ts +29 -0
- package/src/extensions/Blocks/index.ts +0 -8
- package/src/extensions/Blocks/nodes/Block.module.css +28 -16
- package/src/extensions/Blocks/nodes/BlockContainer.ts +8 -4
- package/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.ts +4 -4
- package/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +5 -5
- package/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +100 -97
- package/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.ts +4 -4
- package/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.ts +11 -9
- package/src/extensions/DraggableBlocks/DraggableBlocksExtension.ts +6 -5
- package/src/extensions/DraggableBlocks/DraggableBlocksPlugin.ts +57 -14
- package/src/extensions/FormattingToolbar/FormattingToolbarExtension.ts +21 -16
- package/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.ts +9 -5
- package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +38 -58
- package/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts +19 -0
- package/src/extensions/Placeholder/PlaceholderExtension.ts +1 -0
- package/src/extensions/SlashMenu/BaseSlashMenuItem.ts +5 -2
- package/src/extensions/SlashMenu/SlashMenuExtension.ts +37 -33
- package/src/extensions/SlashMenu/defaultSlashMenuItems.tsx +14 -10
- package/src/extensions/SlashMenu/index.ts +2 -2
- package/src/index.ts +4 -0
- package/src/shared/plugins/suggestion/SuggestionPlugin.ts +29 -13
- package/types/src/BlockNoteEditor.d.ts +38 -23
- package/types/src/BlockNoteExtensions.d.ts +15 -8
- package/types/src/api/blockManipulation/blockManipulation.d.ts +4 -4
- package/types/src/api/formatConversions/formatConversions.d.ts +5 -5
- package/types/src/api/nodeConversions/nodeConversions.d.ts +3 -3
- package/types/src/api/nodeConversions/testUtil.d.ts +2 -2
- package/types/src/extensions/Blocks/api/block.d.ts +2 -4
- package/types/src/extensions/Blocks/api/blockTypes.d.ts +77 -33
- package/types/src/extensions/Blocks/api/cursorPositionTypes.d.ts +5 -5
- package/types/src/extensions/Blocks/api/defaultBlocks.d.ts +4 -4
- package/types/src/extensions/Blocks/api/selectionTypes.d.ts +3 -3
- package/types/src/extensions/Blocks/api/serialization.d.ts +2 -0
- package/types/src/extensions/Blocks/nodes/BlockContainer.d.ts +3 -3
- package/types/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.d.ts +1 -2
- package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.d.ts +1 -2
- package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.d.ts +1 -2
- package/types/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.d.ts +1 -2
- package/types/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.d.ts +7 -7
- package/types/src/extensions/DraggableBlocks/DraggableBlocksExtension.d.ts +5 -4
- package/types/src/extensions/DraggableBlocks/DraggableBlocksPlugin.d.ts +12 -11
- package/types/src/extensions/FormattingToolbar/FormattingToolbarExtension.d.ts +6 -5
- package/types/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.d.ts +4 -3
- package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +16 -19
- package/types/src/extensions/Placeholder/localisation/index.d.ts +2 -0
- package/types/src/extensions/Placeholder/localisation/translation.d.ts +51 -0
- package/types/src/extensions/SlashMenu/BaseSlashMenuItem.d.ts +4 -3
- package/types/src/extensions/SlashMenu/SlashMenuExtension.d.ts +5 -4
- package/types/src/extensions/SlashMenu/defaultSlashMenuItems.d.ts +66 -1
- package/types/src/extensions/SlashMenu/index.d.ts +2 -2
- package/types/src/index.d.ts +4 -0
- package/types/src/shared/plugins/suggestion/SuggestionPlugin.d.ts +5 -4
- package/types/src/extensions/Blocks/api/alertBlock.d.ts +0 -13
- package/types/src/extensions/Blocks/api/alertBlock2.d.ts +0 -13
|
@@ -1,117 +1,120 @@
|
|
|
1
|
-
import { InputRule, mergeAttributes
|
|
2
|
-
import
|
|
1
|
+
import { InputRule, mergeAttributes } from "@tiptap/core";
|
|
2
|
+
import { createTipTapBlock } from "../../../../api/block";
|
|
3
3
|
import { handleEnter } from "../ListItemKeyboardShortcuts";
|
|
4
4
|
import { NumberedListIndexingPlugin } from "./NumberedListIndexingPlugin";
|
|
5
|
+
import styles from "../../../Block.module.css";
|
|
5
6
|
|
|
6
|
-
export const NumberedListItemBlockContent =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
export const NumberedListItemBlockContent =
|
|
8
|
+
createTipTapBlock<"numberedListItem">({
|
|
9
|
+
name: "numberedListItem",
|
|
10
|
+
content: "inline*",
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
addAttributes() {
|
|
13
|
+
return {
|
|
14
|
+
index: {
|
|
15
|
+
default: null,
|
|
16
|
+
parseHTML: (element) => element.getAttribute("data-index"),
|
|
17
|
+
renderHTML: (attributes) => {
|
|
18
|
+
return {
|
|
19
|
+
"data-index": attributes.index,
|
|
20
|
+
};
|
|
21
|
+
},
|
|
20
22
|
},
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
},
|
|
23
|
+
};
|
|
24
|
+
},
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
26
|
+
addInputRules() {
|
|
27
|
+
return [
|
|
28
|
+
// Creates an ordered list when starting with "1.".
|
|
29
|
+
new InputRule({
|
|
30
|
+
find: new RegExp(`^1\\.\\s$`),
|
|
31
|
+
handler: ({ state, chain, range }) => {
|
|
32
|
+
chain()
|
|
33
|
+
.BNUpdateBlock(state.selection.from, {
|
|
34
|
+
type: "numberedListItem",
|
|
35
|
+
props: {},
|
|
36
|
+
})
|
|
37
|
+
// Removes the "1." characters used to set the list.
|
|
38
|
+
.deleteRange({ from: range.from, to: range.to });
|
|
39
|
+
},
|
|
40
|
+
}),
|
|
41
|
+
];
|
|
42
|
+
},
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
addKeyboardShortcuts() {
|
|
45
|
+
return {
|
|
46
|
+
Enter: () => handleEnter(this.editor),
|
|
47
|
+
};
|
|
48
|
+
},
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
addProseMirrorPlugins() {
|
|
51
|
+
return [NumberedListIndexingPlugin()];
|
|
52
|
+
},
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
54
|
+
parseHTML() {
|
|
55
|
+
return [
|
|
56
|
+
// Case for regular HTML list structure.
|
|
57
|
+
// (e.g.: when pasting from other apps)
|
|
58
|
+
{
|
|
59
|
+
tag: "li",
|
|
60
|
+
getAttrs: (element) => {
|
|
61
|
+
if (typeof element === "string") {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
63
64
|
|
|
64
|
-
|
|
65
|
+
const parent = element.parentElement;
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
if (parent === null) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
69
70
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
if (parent.tagName === "OL") {
|
|
72
|
+
return {};
|
|
73
|
+
}
|
|
73
74
|
|
|
74
|
-
return false;
|
|
75
|
-
},
|
|
76
|
-
node: "numberedListItem",
|
|
77
|
-
},
|
|
78
|
-
// Case for BlockNote list structure.
|
|
79
|
-
// (e.g.: when pasting from blocknote)
|
|
80
|
-
{
|
|
81
|
-
tag: "p",
|
|
82
|
-
getAttrs: (element) => {
|
|
83
|
-
if (typeof element === "string") {
|
|
84
75
|
return false;
|
|
85
|
-
}
|
|
76
|
+
},
|
|
77
|
+
node: "numberedListItem",
|
|
78
|
+
},
|
|
79
|
+
// Case for BlockNote list structure.
|
|
80
|
+
// (e.g.: when pasting from blocknote)
|
|
81
|
+
{
|
|
82
|
+
tag: "p",
|
|
83
|
+
getAttrs: (element) => {
|
|
84
|
+
if (typeof element === "string") {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
86
87
|
|
|
87
|
-
|
|
88
|
+
const parent = element.parentElement;
|
|
88
89
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
if (parent === null) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
92
93
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
if (
|
|
95
|
+
parent.getAttribute("data-content-type") === "numberedListItem"
|
|
96
|
+
) {
|
|
97
|
+
return {};
|
|
98
|
+
}
|
|
96
99
|
|
|
97
|
-
|
|
100
|
+
return false;
|
|
101
|
+
},
|
|
102
|
+
priority: 300,
|
|
103
|
+
node: "numberedListItem",
|
|
98
104
|
},
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
},
|
|
102
|
-
];
|
|
103
|
-
},
|
|
105
|
+
];
|
|
106
|
+
},
|
|
104
107
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
});
|
|
108
|
+
renderHTML({ HTMLAttributes }) {
|
|
109
|
+
return [
|
|
110
|
+
"div",
|
|
111
|
+
mergeAttributes(HTMLAttributes, {
|
|
112
|
+
class: styles.blockContent,
|
|
113
|
+
"data-content-type": this.name,
|
|
114
|
+
}),
|
|
115
|
+
// we use a <p> tag, because for <li> tags we'd need to add a <ul> parent for around siblings to be semantically correct,
|
|
116
|
+
// which would be quite cumbersome
|
|
117
|
+
["p", { class: styles.inlineContent }, 0],
|
|
118
|
+
];
|
|
119
|
+
},
|
|
120
|
+
});
|
package/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { mergeAttributes
|
|
1
|
+
import { mergeAttributes } from "@tiptap/core";
|
|
2
|
+
import { createTipTapBlock } from "../../../api/block";
|
|
2
3
|
import styles from "../../Block.module.css";
|
|
3
4
|
|
|
4
|
-
export const ParagraphBlockContent =
|
|
5
|
+
export const ParagraphBlockContent = createTipTapBlock<"paragraph">({
|
|
5
6
|
name: "paragraph",
|
|
6
|
-
group: "blockContent",
|
|
7
7
|
content: "inline*",
|
|
8
8
|
|
|
9
9
|
parseHTML() {
|
|
@@ -23,7 +23,7 @@ export const ParagraphBlockContent = Node.create({
|
|
|
23
23
|
class: styles.blockContent,
|
|
24
24
|
"data-content-type": this.name,
|
|
25
25
|
}),
|
|
26
|
-
["p", 0],
|
|
26
|
+
["p", { class: styles.inlineContent }, 0],
|
|
27
27
|
];
|
|
28
28
|
},
|
|
29
29
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { EditorElement, ElementFactory } from "../../shared/EditorElement";
|
|
2
2
|
import { BlockNoteEditor } from "../../BlockNoteEditor";
|
|
3
|
-
import { Block } from "../Blocks/api/blockTypes";
|
|
3
|
+
import { Block, BlockSchema } from "../Blocks/api/blockTypes";
|
|
4
4
|
|
|
5
|
-
export type BlockSideMenuStaticParams = {
|
|
6
|
-
editor: BlockNoteEditor
|
|
5
|
+
export type BlockSideMenuStaticParams<BSchema extends BlockSchema> = {
|
|
6
|
+
editor: BlockNoteEditor<BSchema>;
|
|
7
7
|
|
|
8
8
|
addBlock: () => void;
|
|
9
9
|
|
|
@@ -14,14 +14,16 @@ export type BlockSideMenuStaticParams = {
|
|
|
14
14
|
unfreezeMenu: () => void;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
export type BlockSideMenuDynamicParams = {
|
|
18
|
-
block: Block
|
|
17
|
+
export type BlockSideMenuDynamicParams<BSchema extends BlockSchema> = {
|
|
18
|
+
block: Block<BSchema>;
|
|
19
19
|
|
|
20
20
|
referenceRect: DOMRect;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
export type BlockSideMenu = EditorElement<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
export type BlockSideMenu<BSchema extends BlockSchema> = EditorElement<
|
|
24
|
+
BlockSideMenuDynamicParams<BSchema>
|
|
25
|
+
>;
|
|
26
|
+
export type BlockSideMenuFactory<BSchema extends BlockSchema> = ElementFactory<
|
|
27
|
+
BlockSideMenuStaticParams<BSchema>,
|
|
28
|
+
BlockSideMenuDynamicParams<BSchema>
|
|
27
29
|
>;
|
|
@@ -2,11 +2,12 @@ import { Editor, Extension } from "@tiptap/core";
|
|
|
2
2
|
import { BlockSideMenuFactory } from "./BlockSideMenuFactoryTypes";
|
|
3
3
|
import { createDraggableBlocksPlugin } from "./DraggableBlocksPlugin";
|
|
4
4
|
import { BlockNoteEditor } from "../../BlockNoteEditor";
|
|
5
|
+
import { BlockSchema } from "../Blocks/api/blockTypes";
|
|
5
6
|
|
|
6
|
-
export type DraggableBlocksOptions = {
|
|
7
|
+
export type DraggableBlocksOptions<BSchema extends BlockSchema> = {
|
|
7
8
|
tiptapEditor: Editor;
|
|
8
|
-
editor: BlockNoteEditor
|
|
9
|
-
blockSideMenuFactory: BlockSideMenuFactory
|
|
9
|
+
editor: BlockNoteEditor<BSchema>;
|
|
10
|
+
blockSideMenuFactory: BlockSideMenuFactory<BSchema>;
|
|
10
11
|
};
|
|
11
12
|
|
|
12
13
|
/**
|
|
@@ -15,8 +16,8 @@ export type DraggableBlocksOptions = {
|
|
|
15
16
|
*
|
|
16
17
|
* code based on https://github.com/ueberdosis/tiptap/issues/323#issuecomment-506637799
|
|
17
18
|
*/
|
|
18
|
-
export const
|
|
19
|
-
Extension.create<DraggableBlocksOptions
|
|
19
|
+
export const createDraggableBlocksExtension = <BSchema extends BlockSchema>() =>
|
|
20
|
+
Extension.create<DraggableBlocksOptions<BSchema>>({
|
|
20
21
|
name: "DraggableBlocksExtension",
|
|
21
22
|
priority: 1000, // Need to be high, in order to hide menu when typing slash
|
|
22
23
|
addProseMirrorPlugins() {
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
import { DraggableBlocksOptions } from "./DraggableBlocksExtension";
|
|
16
16
|
import { MultipleNodeSelection } from "./MultipleNodeSelection";
|
|
17
17
|
import { BlockNoteEditor } from "../../BlockNoteEditor";
|
|
18
|
+
import { BlockSchema } from "../Blocks/api/blockTypes";
|
|
18
19
|
|
|
19
20
|
const serializeForClipboard = (pv as any).__serializeForClipboard;
|
|
20
21
|
// code based on https://github.com/ueberdosis/tiptap/issues/323#issuecomment-506637799
|
|
@@ -223,15 +224,15 @@ function dragStart(e: DragEvent, view: EditorView) {
|
|
|
223
224
|
}
|
|
224
225
|
}
|
|
225
226
|
|
|
226
|
-
export type BlockMenuViewProps = {
|
|
227
|
+
export type BlockMenuViewProps<BSchema extends BlockSchema> = {
|
|
227
228
|
tiptapEditor: Editor;
|
|
228
|
-
editor: BlockNoteEditor
|
|
229
|
-
blockMenuFactory: BlockSideMenuFactory
|
|
229
|
+
editor: BlockNoteEditor<BSchema>;
|
|
230
|
+
blockMenuFactory: BlockSideMenuFactory<BSchema>;
|
|
230
231
|
horizontalPosAnchoredAtRoot: boolean;
|
|
231
232
|
};
|
|
232
233
|
|
|
233
|
-
export class BlockMenuView {
|
|
234
|
-
editor: BlockNoteEditor
|
|
234
|
+
export class BlockMenuView<BSchema extends BlockSchema> {
|
|
235
|
+
editor: BlockNoteEditor<BSchema>;
|
|
235
236
|
private ttEditor: Editor;
|
|
236
237
|
|
|
237
238
|
// When true, the drag handle with be anchored at the same level as root elements
|
|
@@ -240,7 +241,7 @@ export class BlockMenuView {
|
|
|
240
241
|
|
|
241
242
|
horizontalPosAnchor: number;
|
|
242
243
|
|
|
243
|
-
blockMenu: BlockSideMenu
|
|
244
|
+
blockMenu: BlockSideMenu<BSchema>;
|
|
244
245
|
|
|
245
246
|
hoveredBlock: HTMLElement | undefined;
|
|
246
247
|
|
|
@@ -254,7 +255,7 @@ export class BlockMenuView {
|
|
|
254
255
|
editor,
|
|
255
256
|
blockMenuFactory,
|
|
256
257
|
horizontalPosAnchoredAtRoot,
|
|
257
|
-
}: BlockMenuViewProps) {
|
|
258
|
+
}: BlockMenuViewProps<BSchema>) {
|
|
258
259
|
this.editor = editor;
|
|
259
260
|
this.ttEditor = tiptapEditor;
|
|
260
261
|
this.horizontalPosAnchoredAtRoot = horizontalPosAnchoredAtRoot;
|
|
@@ -319,7 +320,7 @@ export class BlockMenuView {
|
|
|
319
320
|
};
|
|
320
321
|
|
|
321
322
|
/**
|
|
322
|
-
* If the event is outside
|
|
323
|
+
* If the event is outside the editor contents,
|
|
323
324
|
* we dispatch a fake event, so that we can still drop the content
|
|
324
325
|
* when dragging / dropping to the side of the editor
|
|
325
326
|
*/
|
|
@@ -374,11 +375,45 @@ export class BlockMenuView {
|
|
|
374
375
|
return;
|
|
375
376
|
}
|
|
376
377
|
|
|
377
|
-
// Editor itself may have padding or other styling which affects
|
|
378
|
-
// the first child (i.e. the
|
|
378
|
+
// Editor itself may have padding or other styling which affects
|
|
379
|
+
// size/position, so we get the boundingRect of the first child (i.e. the
|
|
380
|
+
// blockGroup that wraps all blocks in the editor) for more accurate side
|
|
381
|
+
// menu placement.
|
|
379
382
|
const editorBoundingBox = (
|
|
380
383
|
this.ttEditor.view.dom.firstChild! as HTMLElement
|
|
381
384
|
).getBoundingClientRect();
|
|
385
|
+
// We want the full area of the editor to check if the cursor is hovering
|
|
386
|
+
// above it though.
|
|
387
|
+
const editorOuterBoundingBox =
|
|
388
|
+
this.ttEditor.view.dom.getBoundingClientRect();
|
|
389
|
+
const cursorWithinEditor =
|
|
390
|
+
event.clientX >= editorOuterBoundingBox.left &&
|
|
391
|
+
event.clientX <= editorOuterBoundingBox.right &&
|
|
392
|
+
event.clientY >= editorOuterBoundingBox.top &&
|
|
393
|
+
event.clientY <= editorOuterBoundingBox.bottom;
|
|
394
|
+
|
|
395
|
+
// Doesn't update if the mouse hovers an element that's over the editor but
|
|
396
|
+
// isn't a part of it or the side menu.
|
|
397
|
+
if (
|
|
398
|
+
// Cursor is within the editor area
|
|
399
|
+
cursorWithinEditor &&
|
|
400
|
+
// An element is hovered
|
|
401
|
+
event &&
|
|
402
|
+
event.target &&
|
|
403
|
+
// Element is outside the editor
|
|
404
|
+
this.ttEditor.view.dom !== event.target &&
|
|
405
|
+
!this.ttEditor.view.dom.contains(event.target as HTMLElement) &&
|
|
406
|
+
// Element is outside the side menu
|
|
407
|
+
this.blockMenu.element !== event.target &&
|
|
408
|
+
!this.blockMenu.element?.contains(event.target as HTMLElement)
|
|
409
|
+
) {
|
|
410
|
+
if (this.menuOpen) {
|
|
411
|
+
this.menuOpen = false;
|
|
412
|
+
this.blockMenu.hide();
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
382
417
|
|
|
383
418
|
this.horizontalPosAnchor = editorBoundingBox.x;
|
|
384
419
|
|
|
@@ -429,6 +464,14 @@ export class BlockMenuView {
|
|
|
429
464
|
};
|
|
430
465
|
|
|
431
466
|
onScroll = () => {
|
|
467
|
+
// Editor itself may have padding or other styling which affects size/position, so we get the boundingRect of
|
|
468
|
+
// the first child (i.e. the blockGroup that wraps all blocks in the editor) for a more accurate bounding box.
|
|
469
|
+
const editorBoundingBox = (
|
|
470
|
+
this.ttEditor.view.dom.firstChild! as HTMLElement
|
|
471
|
+
).getBoundingClientRect();
|
|
472
|
+
|
|
473
|
+
this.horizontalPosAnchor = editorBoundingBox.x;
|
|
474
|
+
|
|
432
475
|
if (this.menuOpen) {
|
|
433
476
|
this.blockMenu.render(this.getDynamicParams(), false);
|
|
434
477
|
}
|
|
@@ -497,7 +540,7 @@ export class BlockMenuView {
|
|
|
497
540
|
);
|
|
498
541
|
}
|
|
499
542
|
|
|
500
|
-
getStaticParams(): BlockSideMenuStaticParams {
|
|
543
|
+
getStaticParams(): BlockSideMenuStaticParams<BSchema> {
|
|
501
544
|
return {
|
|
502
545
|
editor: this.editor,
|
|
503
546
|
addBlock: () => this.addBlock(),
|
|
@@ -516,7 +559,7 @@ export class BlockMenuView {
|
|
|
516
559
|
};
|
|
517
560
|
}
|
|
518
561
|
|
|
519
|
-
getDynamicParams(): BlockSideMenuDynamicParams {
|
|
562
|
+
getDynamicParams(): BlockSideMenuDynamicParams<BSchema> {
|
|
520
563
|
const blockContent = this.hoveredBlock!.firstChild! as HTMLElement;
|
|
521
564
|
const blockContentBoundingBox = blockContent.getBoundingClientRect();
|
|
522
565
|
|
|
@@ -534,8 +577,8 @@ export class BlockMenuView {
|
|
|
534
577
|
}
|
|
535
578
|
}
|
|
536
579
|
|
|
537
|
-
export const createDraggableBlocksPlugin = (
|
|
538
|
-
options: DraggableBlocksOptions
|
|
580
|
+
export const createDraggableBlocksPlugin = <BSchema extends BlockSchema>(
|
|
581
|
+
options: DraggableBlocksOptions<BSchema>
|
|
539
582
|
) => {
|
|
540
583
|
return new Plugin({
|
|
541
584
|
key: new PluginKey("DraggableBlocksPlugin"),
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import { Extension } from "@tiptap/core";
|
|
2
2
|
import { PluginKey } from "prosemirror-state";
|
|
3
|
-
import { BlockNoteEditor } from "../..";
|
|
3
|
+
import { BlockNoteEditor, BlockSchema } from "../..";
|
|
4
4
|
import { FormattingToolbarFactory } from "./FormattingToolbarFactoryTypes";
|
|
5
5
|
import { createFormattingToolbarPlugin } from "./FormattingToolbarPlugin";
|
|
6
6
|
|
|
7
|
+
export type FormattingToolbarOptions<BSchema extends BlockSchema> = {
|
|
8
|
+
formattingToolbarFactory: FormattingToolbarFactory<BSchema>;
|
|
9
|
+
editor: BlockNoteEditor<BSchema>;
|
|
10
|
+
};
|
|
11
|
+
|
|
7
12
|
/**
|
|
8
13
|
* The menu that is displayed when selecting a piece of text.
|
|
9
14
|
*/
|
|
10
|
-
export const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
export const createFormattingToolbarExtension = <
|
|
16
|
+
BSchema extends BlockSchema
|
|
17
|
+
>() =>
|
|
18
|
+
Extension.create<FormattingToolbarOptions<BSchema>>({
|
|
19
|
+
name: "FormattingToolbarExtension",
|
|
15
20
|
|
|
16
21
|
addProseMirrorPlugins() {
|
|
17
22
|
if (!this.options.formattingToolbarFactory || !this.options.editor) {
|
|
@@ -20,13 +25,13 @@ export const FormattingToolbarExtension = Extension.create<{
|
|
|
20
25
|
);
|
|
21
26
|
}
|
|
22
27
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
});
|
|
28
|
+
return [
|
|
29
|
+
createFormattingToolbarPlugin({
|
|
30
|
+
tiptapEditor: this.editor,
|
|
31
|
+
editor: this.options.editor,
|
|
32
|
+
formattingToolbarFactory: this.options.formattingToolbarFactory,
|
|
33
|
+
pluginKey: new PluginKey("FormattingToolbarPlugin"),
|
|
34
|
+
}),
|
|
35
|
+
];
|
|
36
|
+
},
|
|
37
|
+
});
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import { EditorElement, ElementFactory } from "../../shared/EditorElement";
|
|
2
2
|
import { BlockNoteEditor } from "../../BlockNoteEditor";
|
|
3
|
+
import { BlockSchema } from "../Blocks/api/blockTypes";
|
|
3
4
|
|
|
4
|
-
export type FormattingToolbarStaticParams = {
|
|
5
|
-
editor: BlockNoteEditor
|
|
5
|
+
export type FormattingToolbarStaticParams<BSchema extends BlockSchema> = {
|
|
6
|
+
editor: BlockNoteEditor<BSchema>;
|
|
6
7
|
};
|
|
7
8
|
|
|
8
9
|
export type FormattingToolbarDynamicParams = {
|
|
9
10
|
referenceRect: DOMRect;
|
|
10
11
|
};
|
|
11
12
|
|
|
12
|
-
export type FormattingToolbar = EditorElement<
|
|
13
|
-
export type FormattingToolbarFactory = ElementFactory<
|
|
14
|
-
FormattingToolbarStaticParams,
|
|
13
|
+
export type FormattingToolbar = EditorElement<
|
|
15
14
|
FormattingToolbarDynamicParams
|
|
16
15
|
>;
|
|
16
|
+
export type FormattingToolbarFactory<BSchema extends BlockSchema> =
|
|
17
|
+
ElementFactory<
|
|
18
|
+
FormattingToolbarStaticParams<BSchema>,
|
|
19
|
+
FormattingToolbarDynamicParams
|
|
20
|
+
>;
|