@blocknote/core 0.8.1 → 0.8.3
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/README.md +4 -0
- package/dist/blocknote.js +1787 -1834
- package/dist/blocknote.js.map +1 -1
- package/dist/blocknote.umd.cjs +4 -4
- package/dist/blocknote.umd.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +3 -3
- package/src/BlockNoteEditor.ts +102 -38
- package/src/BlockNoteExtensions.ts +1 -58
- package/src/api/formatConversions/__snapshots__/formatConversions.test.ts.snap +10 -10
- package/src/api/formatConversions/formatConversions.test.ts +587 -605
- package/src/api/nodeConversions/__snapshots__/nodeConversions.test.ts.snap +15 -15
- package/src/api/nodeConversions/nodeConversions.test.ts +90 -94
- package/src/extensions/Blocks/api/blockTypes.ts +3 -2
- package/src/extensions/Blocks/helpers/getBlockInfoFromPos.ts +6 -0
- package/src/extensions/Blocks/nodes/BlockContainer.ts +12 -3
- package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +92 -104
- package/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts +178 -134
- package/src/extensions/Placeholder/PlaceholderExtension.ts +2 -2
- package/src/extensions/{DraggableBlocks/DraggableBlocksPlugin.ts → SideMenu/SideMenuPlugin.ts} +173 -163
- package/src/extensions/SlashMenu/BaseSlashMenuItem.ts +7 -30
- package/src/extensions/SlashMenu/SlashMenuPlugin.ts +51 -0
- package/src/extensions/SlashMenu/defaultSlashMenuItems.ts +109 -0
- package/src/extensions/UniqueID/UniqueID.ts +29 -30
- package/src/index.ts +9 -8
- package/src/node_modules/.vitest/results.json +1 -0
- package/src/shared/BaseUiElementTypes.ts +8 -0
- package/src/shared/EditorElement.ts +0 -16
- package/src/shared/EventEmitter.ts +58 -0
- package/src/shared/plugins/suggestion/SuggestionItem.ts +3 -6
- package/src/shared/plugins/suggestion/SuggestionPlugin.ts +333 -389
- package/types/src/BlockNoteEditor.d.ts +18 -10
- package/types/src/BlockNoteExtensions.d.ts +0 -19
- package/types/src/EventEmitter.d.ts +11 -0
- package/types/src/extensions/Blocks/api/blockTypes.d.ts +3 -2
- package/types/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.d.ts +0 -17
- package/types/src/extensions/DraggableBlocks/DraggableBlocksPlugin.d.ts +25 -19
- package/types/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.d.ts +2 -3
- package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +17 -24
- package/types/src/extensions/HyperlinkToolbar/HyperlinkToolbarFactoryTypes.d.ts +0 -12
- package/types/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.d.ts +37 -10
- package/types/src/extensions/SideMenu/MultipleNodeSelection.d.ts +24 -0
- package/types/src/extensions/SideMenu/SideMenuPlugin.d.ts +79 -0
- package/types/src/extensions/SlashMenu/BaseSlashMenuItem.d.ts +5 -18
- package/types/src/extensions/SlashMenu/SlashMenuPlugin.d.ts +13 -0
- package/types/src/extensions/SlashMenu/defaultSlashMenuItems.d.ts +1 -69
- package/types/src/extensions/SlashMenu/index.d.ts +2 -3
- package/types/src/index.d.ts +9 -8
- package/types/src/shared/BaseUiElementTypes.d.ts +7 -0
- package/types/src/shared/EditorElement.d.ts +0 -10
- package/types/src/shared/EventEmitter.d.ts +11 -0
- package/types/src/shared/plugins/suggestion/SuggestionItem.d.ts +2 -7
- package/types/src/shared/plugins/suggestion/SuggestionPlugin.d.ts +12 -43
- package/types/src/shared/plugins/suggestion/SuggestionsMenuFactoryTypes.d.ts +1 -1
- package/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.ts +0 -29
- package/src/extensions/DraggableBlocks/DraggableBlocksExtension.ts +0 -37
- package/src/extensions/FormattingToolbar/FormattingToolbarExtension.ts +0 -37
- package/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.ts +0 -20
- package/src/extensions/HyperlinkToolbar/HyperlinkMark.ts +0 -28
- package/src/extensions/HyperlinkToolbar/HyperlinkToolbarFactoryTypes.ts +0 -19
- package/src/extensions/SlashMenu/SlashMenuExtension.ts +0 -53
- package/src/extensions/SlashMenu/defaultSlashMenuItems.tsx +0 -195
- package/src/extensions/SlashMenu/index.ts +0 -5
- package/src/shared/plugins/suggestion/SuggestionsMenuFactoryTypes.ts +0 -21
- package/types/src/CustomBlock.d.ts +0 -15
- package/types/src/extensions/Blocks/nodes/BlockContent/TableContent/TableCol.d.ts +0 -2
- package/types/src/extensions/Blocks/nodes/BlockContent/TableContent/TableContent.d.ts +0 -2
- package/types/src/extensions/Blocks/nodes/BlockContent/TableContent/TableRow.d.ts +0 -2
- package/types/src/extensions/Placeholder/localisation/index.d.ts +0 -2
- package/types/src/extensions/Placeholder/localisation/translation.d.ts +0 -51
- /package/src/extensions/{DraggableBlocks → SideMenu}/MultipleNodeSelection.ts +0 -0
|
@@ -1,47 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Editor,
|
|
3
|
-
isNodeSelection,
|
|
4
|
-
isTextSelection,
|
|
5
|
-
posToDOMRect,
|
|
6
|
-
} from "@tiptap/core";
|
|
1
|
+
import { isNodeSelection, isTextSelection, posToDOMRect } from "@tiptap/core";
|
|
7
2
|
import { EditorState, Plugin, PluginKey } from "prosemirror-state";
|
|
8
3
|
import { EditorView } from "prosemirror-view";
|
|
9
|
-
import { BlockNoteEditor, BlockSchema } from "../..";
|
|
10
4
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} from "
|
|
16
|
-
|
|
17
|
-
// Same as TipTap bubblemenu plugin, but with these changes:
|
|
18
|
-
// https://github.com/ueberdosis/tiptap/pull/2596/files
|
|
19
|
-
export interface FormattingToolbarPluginProps<BSchema extends BlockSchema> {
|
|
20
|
-
pluginKey: PluginKey;
|
|
21
|
-
tiptapEditor: Editor;
|
|
22
|
-
editor: BlockNoteEditor<BSchema>;
|
|
23
|
-
formattingToolbarFactory: FormattingToolbarFactory<BSchema>;
|
|
24
|
-
}
|
|
5
|
+
BaseUiElementCallbacks,
|
|
6
|
+
BaseUiElementState,
|
|
7
|
+
BlockNoteEditor,
|
|
8
|
+
BlockSchema,
|
|
9
|
+
} from "../..";
|
|
10
|
+
import { EventEmitter } from "../../shared/EventEmitter";
|
|
25
11
|
|
|
26
|
-
export type
|
|
27
|
-
FormattingToolbarPluginProps<BSchema> & {
|
|
28
|
-
view: EditorView;
|
|
29
|
-
};
|
|
12
|
+
export type FormattingToolbarCallbacks = BaseUiElementCallbacks;
|
|
30
13
|
|
|
31
|
-
export
|
|
32
|
-
public editor: BlockNoteEditor<BSchema>;
|
|
33
|
-
private ttEditor: Editor;
|
|
34
|
-
|
|
35
|
-
public view: EditorView;
|
|
14
|
+
export type FormattingToolbarState = BaseUiElementState;
|
|
36
15
|
|
|
37
|
-
|
|
16
|
+
export class FormattingToolbarView<BSchema extends BlockSchema> {
|
|
17
|
+
private formattingToolbarState?: FormattingToolbarState;
|
|
18
|
+
public updateFormattingToolbar: () => void;
|
|
38
19
|
|
|
39
20
|
public preventHide = false;
|
|
40
|
-
|
|
41
21
|
public preventShow = false;
|
|
42
|
-
|
|
43
|
-
public toolbarIsOpen = false;
|
|
44
|
-
|
|
45
22
|
public prevWasEditable: boolean | null = null;
|
|
46
23
|
|
|
47
24
|
public shouldShow: (props: {
|
|
@@ -62,24 +39,29 @@ export class FormattingToolbarView<BSchema extends BlockSchema> {
|
|
|
62
39
|
return !(!view.hasFocus() || empty || isEmptyTextBlock);
|
|
63
40
|
};
|
|
64
41
|
|
|
65
|
-
constructor(
|
|
66
|
-
editor
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
this.
|
|
73
|
-
|
|
42
|
+
constructor(
|
|
43
|
+
private readonly editor: BlockNoteEditor<BSchema>,
|
|
44
|
+
private readonly pmView: EditorView,
|
|
45
|
+
updateFormattingToolbar: (
|
|
46
|
+
formattingToolbarState: FormattingToolbarState
|
|
47
|
+
) => void
|
|
48
|
+
) {
|
|
49
|
+
this.updateFormattingToolbar = () => {
|
|
50
|
+
if (!this.formattingToolbarState) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
"Attempting to update uninitialized formatting toolbar"
|
|
53
|
+
);
|
|
54
|
+
}
|
|
74
55
|
|
|
75
|
-
|
|
56
|
+
updateFormattingToolbar(this.formattingToolbarState);
|
|
57
|
+
};
|
|
76
58
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
59
|
+
pmView.dom.addEventListener("mousedown", this.viewMousedownHandler);
|
|
60
|
+
pmView.dom.addEventListener("mouseup", this.viewMouseupHandler);
|
|
61
|
+
pmView.dom.addEventListener("dragstart", this.dragstartHandler);
|
|
80
62
|
|
|
81
|
-
|
|
82
|
-
|
|
63
|
+
pmView.dom.addEventListener("focus", this.focusHandler);
|
|
64
|
+
pmView.dom.addEventListener("blur", this.blurHandler);
|
|
83
65
|
|
|
84
66
|
document.addEventListener("scroll", this.scrollHandler);
|
|
85
67
|
}
|
|
@@ -90,48 +72,54 @@ export class FormattingToolbarView<BSchema extends BlockSchema> {
|
|
|
90
72
|
|
|
91
73
|
viewMouseupHandler = () => {
|
|
92
74
|
this.preventShow = false;
|
|
93
|
-
setTimeout(() => this.update(this.
|
|
75
|
+
setTimeout(() => this.update(this.pmView));
|
|
94
76
|
};
|
|
95
77
|
|
|
78
|
+
// For dragging the whole editor.
|
|
96
79
|
dragstartHandler = () => {
|
|
97
|
-
this.
|
|
98
|
-
|
|
80
|
+
if (this.formattingToolbarState?.show) {
|
|
81
|
+
this.formattingToolbarState.show = false;
|
|
82
|
+
this.updateFormattingToolbar();
|
|
83
|
+
}
|
|
99
84
|
};
|
|
100
85
|
|
|
101
86
|
focusHandler = () => {
|
|
102
87
|
// we use `setTimeout` to make sure `selection` is already updated
|
|
103
|
-
setTimeout(() => this.update(this.
|
|
88
|
+
setTimeout(() => this.update(this.pmView));
|
|
104
89
|
};
|
|
105
90
|
|
|
106
|
-
blurHandler = (
|
|
91
|
+
blurHandler = (event: FocusEvent) => {
|
|
107
92
|
if (this.preventHide) {
|
|
108
93
|
this.preventHide = false;
|
|
109
94
|
|
|
110
95
|
return;
|
|
111
96
|
}
|
|
112
97
|
|
|
98
|
+
const editorWrapper = this.pmView.dom.parentElement!;
|
|
99
|
+
|
|
113
100
|
// Checks if the focus is moving to an element outside the editor. If it is,
|
|
114
101
|
// the toolbar is hidden.
|
|
115
102
|
if (
|
|
116
103
|
// An element is clicked.
|
|
117
104
|
event &&
|
|
118
105
|
event.relatedTarget &&
|
|
119
|
-
// Element is
|
|
120
|
-
(
|
|
121
|
-
|
|
106
|
+
// Element is inside the editor.
|
|
107
|
+
(editorWrapper === (event.relatedTarget as Node) ||
|
|
108
|
+
editorWrapper.contains(event.relatedTarget as Node))
|
|
122
109
|
) {
|
|
123
110
|
return;
|
|
124
111
|
}
|
|
125
112
|
|
|
126
|
-
if (this.
|
|
127
|
-
this.
|
|
128
|
-
this.
|
|
113
|
+
if (this.formattingToolbarState?.show) {
|
|
114
|
+
this.formattingToolbarState.show = false;
|
|
115
|
+
this.updateFormattingToolbar();
|
|
129
116
|
}
|
|
130
117
|
};
|
|
131
118
|
|
|
132
119
|
scrollHandler = () => {
|
|
133
|
-
if (this.
|
|
134
|
-
this.
|
|
120
|
+
if (this.formattingToolbarState?.show) {
|
|
121
|
+
this.formattingToolbarState.referencePos = this.getSelectionBoundingBox();
|
|
122
|
+
this.updateFormattingToolbar();
|
|
135
123
|
}
|
|
136
124
|
};
|
|
137
125
|
|
|
@@ -163,55 +151,48 @@ export class FormattingToolbarView<BSchema extends BlockSchema> {
|
|
|
163
151
|
to,
|
|
164
152
|
});
|
|
165
153
|
|
|
166
|
-
// Checks if menu should be shown.
|
|
154
|
+
// Checks if menu should be shown/updated.
|
|
167
155
|
if (
|
|
168
156
|
this.editor.isEditable &&
|
|
169
|
-
!this.toolbarIsOpen &&
|
|
170
157
|
!this.preventShow &&
|
|
171
158
|
(shouldShow || this.preventHide)
|
|
172
159
|
) {
|
|
173
|
-
this.
|
|
174
|
-
|
|
160
|
+
this.formattingToolbarState = {
|
|
161
|
+
show: true,
|
|
162
|
+
referencePos: this.getSelectionBoundingBox(),
|
|
163
|
+
};
|
|
175
164
|
|
|
176
|
-
|
|
177
|
-
}
|
|
165
|
+
this.updateFormattingToolbar();
|
|
178
166
|
|
|
179
|
-
// Checks if menu should be updated.
|
|
180
|
-
if (
|
|
181
|
-
this.toolbarIsOpen &&
|
|
182
|
-
!this.preventShow &&
|
|
183
|
-
(shouldShow || this.preventHide)
|
|
184
|
-
) {
|
|
185
|
-
this.formattingToolbar.render(this.getDynamicParams(), false);
|
|
186
167
|
return;
|
|
187
168
|
}
|
|
188
169
|
|
|
189
170
|
// Checks if menu should be hidden.
|
|
190
171
|
if (
|
|
191
|
-
this.
|
|
172
|
+
this.formattingToolbarState?.show &&
|
|
192
173
|
!this.preventHide &&
|
|
193
174
|
(!shouldShow || this.preventShow || !this.editor.isEditable)
|
|
194
175
|
) {
|
|
195
|
-
this.
|
|
196
|
-
this.
|
|
176
|
+
this.formattingToolbarState.show = false;
|
|
177
|
+
this.updateFormattingToolbar();
|
|
197
178
|
|
|
198
179
|
return;
|
|
199
180
|
}
|
|
200
181
|
}
|
|
201
182
|
|
|
202
183
|
destroy() {
|
|
203
|
-
this.
|
|
204
|
-
this.
|
|
205
|
-
this.
|
|
184
|
+
this.pmView.dom.removeEventListener("mousedown", this.viewMousedownHandler);
|
|
185
|
+
this.pmView.dom.removeEventListener("mouseup", this.viewMouseupHandler);
|
|
186
|
+
this.pmView.dom.removeEventListener("dragstart", this.dragstartHandler);
|
|
206
187
|
|
|
207
|
-
this.
|
|
208
|
-
this.
|
|
188
|
+
this.pmView.dom.removeEventListener("focus", this.focusHandler);
|
|
189
|
+
this.pmView.dom.removeEventListener("blur", this.blurHandler);
|
|
209
190
|
|
|
210
191
|
document.removeEventListener("scroll", this.scrollHandler);
|
|
211
192
|
}
|
|
212
193
|
|
|
213
194
|
getSelectionBoundingBox() {
|
|
214
|
-
const { state } = this.
|
|
195
|
+
const { state } = this.pmView;
|
|
215
196
|
const { selection } = state;
|
|
216
197
|
|
|
217
198
|
// support for CellSelections
|
|
@@ -220,34 +201,41 @@ export class FormattingToolbarView<BSchema extends BlockSchema> {
|
|
|
220
201
|
const to = Math.max(...ranges.map((range) => range.$to.pos));
|
|
221
202
|
|
|
222
203
|
if (isNodeSelection(selection)) {
|
|
223
|
-
const node = this.
|
|
204
|
+
const node = this.pmView.nodeDOM(from) as HTMLElement;
|
|
224
205
|
|
|
225
206
|
if (node) {
|
|
226
207
|
return node.getBoundingClientRect();
|
|
227
208
|
}
|
|
228
209
|
}
|
|
229
210
|
|
|
230
|
-
return posToDOMRect(this.
|
|
211
|
+
return posToDOMRect(this.pmView, from, to);
|
|
231
212
|
}
|
|
213
|
+
}
|
|
232
214
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
215
|
+
export const formattingToolbarPluginKey = new PluginKey(
|
|
216
|
+
"FormattingToolbarPlugin"
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
export class FormattingToolbarProsemirrorPlugin<
|
|
220
|
+
BSchema extends BlockSchema
|
|
221
|
+
> extends EventEmitter<any> {
|
|
222
|
+
private view: FormattingToolbarView<BSchema> | undefined;
|
|
223
|
+
public readonly plugin: Plugin;
|
|
224
|
+
|
|
225
|
+
constructor(editor: BlockNoteEditor<BSchema>) {
|
|
226
|
+
super();
|
|
227
|
+
this.plugin = new Plugin({
|
|
228
|
+
key: formattingToolbarPluginKey,
|
|
229
|
+
view: (editorView) => {
|
|
230
|
+
this.view = new FormattingToolbarView(editor, editorView, (state) => {
|
|
231
|
+
this.emit("update", state);
|
|
232
|
+
});
|
|
233
|
+
return this.view;
|
|
234
|
+
},
|
|
235
|
+
});
|
|
237
236
|
}
|
|
238
237
|
|
|
239
|
-
|
|
240
|
-
return
|
|
241
|
-
referenceRect: this.getSelectionBoundingBox(),
|
|
242
|
-
};
|
|
238
|
+
public onUpdate(callback: (state: FormattingToolbarState) => void) {
|
|
239
|
+
return this.on("update", callback);
|
|
243
240
|
}
|
|
244
241
|
}
|
|
245
|
-
|
|
246
|
-
export const createFormattingToolbarPlugin = <BSchema extends BlockSchema>(
|
|
247
|
-
options: FormattingToolbarPluginProps<BSchema>
|
|
248
|
-
) => {
|
|
249
|
-
return new Plugin({
|
|
250
|
-
key: new PluginKey("FormattingToolbarPlugin"),
|
|
251
|
-
view: (view) => new FormattingToolbarView({ view, ...options }),
|
|
252
|
-
});
|
|
253
|
-
};
|