@blocknote/core 0.23.1 → 0.23.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/dist/blocknote.js +2819 -2500
- package/dist/blocknote.js.map +1 -1
- package/dist/blocknote.umd.cjs +6 -6
- package/dist/blocknote.umd.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/webpack-stats.json +1 -1
- package/package.json +2 -2
- package/src/api/blockManipulation/commands/updateBlock/updateBlock.ts +4 -2
- package/src/api/exporters/html/__snapshots__/codeBlock/contains-newlines/external.html +1 -0
- package/src/api/exporters/html/__snapshots__/codeBlock/contains-newlines/internal.html +3 -0
- package/src/api/exporters/html/util/serializeBlocksInternalHTML.ts +6 -2
- package/src/api/exporters/markdown/__snapshots__/codeBlock/contains-newlines/markdown.md +4 -0
- package/src/api/nodeConversions/__snapshots__/nodeConversions.test.ts.snap +27 -0
- package/src/api/nodeConversions/blockToNode.ts +35 -9
- package/src/api/testUtil/cases/defaultSchema.ts +9 -0
- package/src/editor/BlockNoteExtensions.ts +4 -128
- package/src/editor/editor.css +19 -11
- package/src/extensions/Collaboration/createCollaborationExtensions.ts +151 -0
- package/src/extensions/SideMenu/SideMenuPlugin.ts +76 -28
- package/src/i18n/locales/fr.ts +2 -2
- package/src/i18n/locales/index.ts +2 -1
- package/src/i18n/locales/uk.ts +289 -0
- package/types/src/api/exporters/html/util/serializeBlocksInternalHTML.d.ts +1 -1
- package/types/src/api/nodeConversions/blockToNode.d.ts +1 -1
- package/types/src/editor/BlockNoteExtensions.d.ts +1 -1
- package/types/src/extensions/Collaboration/createCollaborationExtensions.d.ts +17 -0
- package/types/src/extensions/SideMenu/SideMenuPlugin.d.ts +0 -5
- package/types/src/i18n/locales/index.d.ts +2 -1
- package/types/src/i18n/locales/uk.d.ts +2 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import Collaboration from "@tiptap/extension-collaboration";
|
|
2
|
+
import { Awareness } from "y-protocols/awareness";
|
|
3
|
+
import CollaborationCursor from "@tiptap/extension-collaboration-cursor";
|
|
4
|
+
import * as Y from "yjs";
|
|
5
|
+
|
|
6
|
+
export const createCollaborationExtensions = (collaboration: {
|
|
7
|
+
fragment: Y.XmlFragment;
|
|
8
|
+
user: {
|
|
9
|
+
name: string;
|
|
10
|
+
color: string;
|
|
11
|
+
[key: string]: string;
|
|
12
|
+
};
|
|
13
|
+
provider: any;
|
|
14
|
+
renderCursor?: (user: any) => HTMLElement;
|
|
15
|
+
showCursorLabels?: "always" | "activity";
|
|
16
|
+
}) => {
|
|
17
|
+
const tiptapExtensions = [];
|
|
18
|
+
|
|
19
|
+
tiptapExtensions.push(
|
|
20
|
+
Collaboration.configure({
|
|
21
|
+
fragment: collaboration.fragment,
|
|
22
|
+
})
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const awareness = collaboration.provider?.awareness as Awareness | undefined;
|
|
26
|
+
|
|
27
|
+
if (awareness) {
|
|
28
|
+
const cursors = new Map<
|
|
29
|
+
number,
|
|
30
|
+
{ element: HTMLElement; hideTimeout: NodeJS.Timeout | undefined }
|
|
31
|
+
>();
|
|
32
|
+
|
|
33
|
+
if (collaboration.showCursorLabels !== "always") {
|
|
34
|
+
awareness.on(
|
|
35
|
+
"change",
|
|
36
|
+
({
|
|
37
|
+
updated,
|
|
38
|
+
}: {
|
|
39
|
+
added: Array<number>;
|
|
40
|
+
updated: Array<number>;
|
|
41
|
+
removed: Array<number>;
|
|
42
|
+
}) => {
|
|
43
|
+
for (const clientID of updated) {
|
|
44
|
+
const cursor = cursors.get(clientID);
|
|
45
|
+
|
|
46
|
+
if (cursor) {
|
|
47
|
+
cursor.element.setAttribute("data-active", "");
|
|
48
|
+
|
|
49
|
+
if (cursor.hideTimeout) {
|
|
50
|
+
clearTimeout(cursor.hideTimeout);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
cursors.set(clientID, {
|
|
54
|
+
element: cursor.element,
|
|
55
|
+
hideTimeout: setTimeout(() => {
|
|
56
|
+
cursor.element.removeAttribute("data-active");
|
|
57
|
+
}, 2000),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const renderCursor = (user: { name: string; color: string }) => {
|
|
66
|
+
const cursorElement = document.createElement("span");
|
|
67
|
+
|
|
68
|
+
cursorElement.classList.add("collaboration-cursor__caret");
|
|
69
|
+
cursorElement.setAttribute("style", `outline-color: ${user.color}`);
|
|
70
|
+
if (collaboration?.showCursorLabels === "always") {
|
|
71
|
+
cursorElement.setAttribute("data-active", "");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const labelElement = document.createElement("span");
|
|
75
|
+
|
|
76
|
+
labelElement.classList.add("collaboration-cursor__label");
|
|
77
|
+
labelElement.setAttribute("style", `background-color: ${user.color}`);
|
|
78
|
+
labelElement.insertBefore(document.createTextNode(user.name), null);
|
|
79
|
+
|
|
80
|
+
cursorElement.insertBefore(document.createTextNode("\u2060"), null); // Non-breaking space
|
|
81
|
+
cursorElement.insertBefore(labelElement, null);
|
|
82
|
+
cursorElement.insertBefore(document.createTextNode("\u2060"), null); // Non-breaking space
|
|
83
|
+
|
|
84
|
+
return cursorElement;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const render = (user: { color: string; name: string }) => {
|
|
88
|
+
const clientState = [...awareness.getStates().entries()].find(
|
|
89
|
+
(state) => state[1].user === user
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
if (!clientState) {
|
|
93
|
+
throw new Error("Could not find client state for user");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const clientID = clientState[0];
|
|
97
|
+
|
|
98
|
+
let cursorData = cursors.get(clientID);
|
|
99
|
+
|
|
100
|
+
if (!cursorData) {
|
|
101
|
+
const cursorElement =
|
|
102
|
+
collaboration?.renderCursor?.(user) || renderCursor(user);
|
|
103
|
+
|
|
104
|
+
if (collaboration?.showCursorLabels !== "always") {
|
|
105
|
+
cursorElement.addEventListener("mouseenter", () => {
|
|
106
|
+
const cursor = cursors.get(clientID)!;
|
|
107
|
+
cursor.element.setAttribute("data-active", "");
|
|
108
|
+
|
|
109
|
+
if (cursor.hideTimeout) {
|
|
110
|
+
clearTimeout(cursor.hideTimeout);
|
|
111
|
+
cursors.set(clientID, {
|
|
112
|
+
element: cursor.element,
|
|
113
|
+
hideTimeout: undefined,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
cursorElement.addEventListener("mouseleave", () => {
|
|
119
|
+
const cursor = cursors.get(clientID)!;
|
|
120
|
+
|
|
121
|
+
cursors.set(clientID, {
|
|
122
|
+
element: cursor.element,
|
|
123
|
+
hideTimeout: setTimeout(() => {
|
|
124
|
+
cursor.element.removeAttribute("data-active");
|
|
125
|
+
}, 2000),
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
cursorData = {
|
|
131
|
+
element: cursorElement,
|
|
132
|
+
hideTimeout: undefined,
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
cursors.set(clientID, cursorData);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return cursorData.element;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
tiptapExtensions.push(
|
|
142
|
+
CollaborationCursor.configure({
|
|
143
|
+
user: collaboration.user,
|
|
144
|
+
render,
|
|
145
|
+
provider: collaboration.provider,
|
|
146
|
+
})
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return tiptapExtensions;
|
|
151
|
+
};
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { DOMParser, Slice } from "@tiptap/pm/model";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
EditorState,
|
|
4
|
+
Plugin,
|
|
5
|
+
PluginKey,
|
|
6
|
+
TextSelection,
|
|
7
|
+
PluginView,
|
|
8
|
+
} from "@tiptap/pm/state";
|
|
3
9
|
import { EditorView } from "@tiptap/pm/view";
|
|
4
10
|
|
|
5
11
|
import { Block } from "../../blocks/defaultBlocks.js";
|
|
@@ -268,21 +274,56 @@ export class SideMenuView<
|
|
|
268
274
|
}
|
|
269
275
|
};
|
|
270
276
|
|
|
271
|
-
/**
|
|
272
|
-
* If the event is outside the editor contents,
|
|
273
|
-
* we dispatch a fake event, so that we can still drop the content
|
|
274
|
-
* when dragging / dropping to the side of the editor
|
|
275
|
-
*/
|
|
276
277
|
onDrop = (event: DragEvent) => {
|
|
278
|
+
// Content from outside a BlockNote editor is being dropped - just let
|
|
279
|
+
// ProseMirror's default behaviour handle it.
|
|
280
|
+
if (this.pmView.dragging === null) {
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
|
|
277
284
|
this.editor._tiptapEditor.commands.blur();
|
|
278
285
|
|
|
279
|
-
// ProseMirror
|
|
280
|
-
//
|
|
281
|
-
//
|
|
282
|
-
//
|
|
283
|
-
if (this.isDragOrigin &&
|
|
284
|
-
|
|
286
|
+
// When ProseMirror handles a drop event on the editor while
|
|
287
|
+
// `view.dragging` is set, it deletes the selected content. However, if
|
|
288
|
+
// a block from a different editor is being dropped, this causes some
|
|
289
|
+
// issues that the code below fixes:
|
|
290
|
+
if (!this.isDragOrigin && this.pmView.dom.contains(event.target as Node)) {
|
|
291
|
+
// 1. Because the editor selection is unrelated to the dragged content,
|
|
292
|
+
// we don't want PM to delete its content. Therefore, we collapse the
|
|
293
|
+
// selection.
|
|
294
|
+
this.pmView.dispatch(
|
|
295
|
+
this.pmView.state.tr.setSelection(
|
|
296
|
+
TextSelection.create(
|
|
297
|
+
this.pmView.state.tr.doc,
|
|
298
|
+
this.pmView.state.tr.selection.to
|
|
299
|
+
)
|
|
300
|
+
)
|
|
301
|
+
);
|
|
302
|
+
} else if (
|
|
303
|
+
this.isDragOrigin &&
|
|
304
|
+
!this.pmView.dom.contains(event.target as Node)
|
|
305
|
+
) {
|
|
306
|
+
// 2. Because the editor from which the block originates doesn't get a
|
|
307
|
+
// drop event on it, PM doesn't delete its selected content. Therefore, we
|
|
308
|
+
// need to do so manually.
|
|
309
|
+
//
|
|
310
|
+
// Note: Deleting the selected content from the editor from which the
|
|
311
|
+
// block originates, may change its height. This can cause the position of
|
|
312
|
+
// the editor in which the block is being dropping to shift, before it
|
|
313
|
+
// can handle the drop event. That in turn can cause the drop to happen
|
|
314
|
+
// somewhere other than the user intended. To get around this, we delay
|
|
315
|
+
// deleting the selected content until all editors have had the chance to
|
|
316
|
+
// handle the event.
|
|
317
|
+
setTimeout(
|
|
318
|
+
() => this.pmView.dispatch(this.pmView.state.tr.deleteSelection()),
|
|
319
|
+
0
|
|
320
|
+
);
|
|
285
321
|
}
|
|
322
|
+
// 3. PM only clears `view.dragging` on the editor that the block was
|
|
323
|
+
// dropped, so we manually have to clear it on all the others. However,
|
|
324
|
+
// PM also needs to read `view.dragging` while handling the event, so we
|
|
325
|
+
// use a `setTimeout` to ensure it's only cleared after that.
|
|
326
|
+
setTimeout(() => (this.pmView.dragging = null), 0);
|
|
286
327
|
|
|
287
328
|
if (
|
|
288
329
|
this.sideMenuDetection === "editor" ||
|
|
@@ -298,6 +339,11 @@ export class SideMenuView<
|
|
|
298
339
|
});
|
|
299
340
|
|
|
300
341
|
if (!pos || pos.inside === -1) {
|
|
342
|
+
/**
|
|
343
|
+
* When `this.sideMenuSelection === "viewport"`, if the event is outside the
|
|
344
|
+
* editor contents, we dispatch a fake event, so that we can still drop the
|
|
345
|
+
* content when dragging / dropping to the side of the editor
|
|
346
|
+
*/
|
|
301
347
|
const evt = this.createSyntheticEvent(event);
|
|
302
348
|
// console.log("dispatch fake drop");
|
|
303
349
|
this.pmView.dom.dispatchEvent(evt);
|
|
@@ -323,25 +369,27 @@ export class SideMenuView<
|
|
|
323
369
|
* access `dataTransfer` contents on `dragstart` and `drop` events.
|
|
324
370
|
*/
|
|
325
371
|
onDragStart = (event: DragEvent) => {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
372
|
+
const html = event.dataTransfer?.getData("blocknote/html");
|
|
373
|
+
if (!html) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
if (this.pmView.dragging) {
|
|
378
|
+
throw new Error("New drag was started while an existing drag is ongoing");
|
|
379
|
+
}
|
|
331
380
|
|
|
332
|
-
|
|
333
|
-
|
|
381
|
+
const element = document.createElement("div");
|
|
382
|
+
element.innerHTML = html;
|
|
334
383
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
384
|
+
const parser = DOMParser.fromSchema(this.pmView.state.schema);
|
|
385
|
+
const node = parser.parse(element, {
|
|
386
|
+
topNode: this.pmView.state.schema.nodes["blockGroup"].create(),
|
|
387
|
+
});
|
|
339
388
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
}
|
|
389
|
+
this.pmView.dragging = {
|
|
390
|
+
slice: new Slice(node.content, 0, 0),
|
|
391
|
+
move: true,
|
|
392
|
+
};
|
|
345
393
|
};
|
|
346
394
|
|
|
347
395
|
/**
|
package/src/i18n/locales/fr.ts
CHANGED
|
@@ -281,11 +281,11 @@ export const fr: Dictionary = {
|
|
|
281
281
|
tooltip: "Basculer l'aperçu",
|
|
282
282
|
},
|
|
283
283
|
nest: {
|
|
284
|
-
tooltip: "
|
|
284
|
+
tooltip: "Augmenter le retrait du bloc",
|
|
285
285
|
secondary_tooltip: "Tab",
|
|
286
286
|
},
|
|
287
287
|
unnest: {
|
|
288
|
-
tooltip: "
|
|
288
|
+
tooltip: "Diminuer le retait du bloc",
|
|
289
289
|
secondary_tooltip: "Shift+Tab",
|
|
290
290
|
},
|
|
291
291
|
align_left: {
|
|
@@ -5,12 +5,13 @@ export * from "./es.js";
|
|
|
5
5
|
export * from "./fr.js";
|
|
6
6
|
export * from "./hr.js";
|
|
7
7
|
export * from "./is.js";
|
|
8
|
+
export * from "./it.js";
|
|
8
9
|
export * from "./ja.js";
|
|
9
10
|
export * from "./ko.js";
|
|
10
11
|
export * from "./nl.js";
|
|
11
12
|
export * from "./pl.js";
|
|
12
13
|
export * from "./pt.js";
|
|
13
14
|
export * from "./ru.js";
|
|
15
|
+
export * from "./uk.js";
|
|
14
16
|
export * from "./vi.js";
|
|
15
17
|
export * from "./zh.js";
|
|
16
|
-
export * from "./it.js"
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import { Dictionary } from "../dictionary.js";
|
|
2
|
+
|
|
3
|
+
export const uk: Dictionary = {
|
|
4
|
+
slash_menu: {
|
|
5
|
+
heading: {
|
|
6
|
+
title: "Заголовок 1",
|
|
7
|
+
subtext: "Заголовок найвищого рівня",
|
|
8
|
+
aliases: ["h", "heading1", "h1", "заголовок1"],
|
|
9
|
+
group: "Заголовки",
|
|
10
|
+
},
|
|
11
|
+
heading_2: {
|
|
12
|
+
title: "Заголовок 2",
|
|
13
|
+
subtext: "Основний заголовок розділу",
|
|
14
|
+
aliases: ["h2", "heading2", "subheading", "заголовок2"],
|
|
15
|
+
group: "Заголовки",
|
|
16
|
+
},
|
|
17
|
+
heading_3: {
|
|
18
|
+
title: "Заголовок 3",
|
|
19
|
+
subtext: "Підзаголовок і груповий заголовок",
|
|
20
|
+
aliases: ["h3", "heading3", "subheading", "заголовок3"],
|
|
21
|
+
group: "Заголовки",
|
|
22
|
+
},
|
|
23
|
+
numbered_list: {
|
|
24
|
+
title: "Нумерований список",
|
|
25
|
+
subtext: "Список із впорядкованими елементами",
|
|
26
|
+
aliases: ["ol", "li", "list", "numberedlist", "numbered list", "список", "нумерований список"],
|
|
27
|
+
group: "Базові блоки",
|
|
28
|
+
},
|
|
29
|
+
bullet_list: {
|
|
30
|
+
title: "Маркований список",
|
|
31
|
+
subtext: "Список із невпорядкованими елементами",
|
|
32
|
+
aliases: ["ul", "li", "list", "bulletlist", "bullet list", "список", "маркований список"],
|
|
33
|
+
group: "Базові блоки",
|
|
34
|
+
},
|
|
35
|
+
check_list: {
|
|
36
|
+
title: "Чек-лист",
|
|
37
|
+
subtext: "Список із чекбоксами",
|
|
38
|
+
aliases: ["ul", "li", "list", "checklist", "check list", "checked list", "checkbox", "чекбокс", "чек-лист"],
|
|
39
|
+
group: "Базові блоки",
|
|
40
|
+
},
|
|
41
|
+
paragraph: {
|
|
42
|
+
title: "Параграф",
|
|
43
|
+
subtext: "Основний текст документа",
|
|
44
|
+
aliases: ["p", "paragraph", "параграф"],
|
|
45
|
+
group: "Базові блоки",
|
|
46
|
+
},
|
|
47
|
+
code_block: {
|
|
48
|
+
title: "Блок коду",
|
|
49
|
+
subtext: "Блок коду з підсвіткою синтаксису",
|
|
50
|
+
aliases: ["code", "pre", "блок коду"],
|
|
51
|
+
group: "Базові блоки",
|
|
52
|
+
},
|
|
53
|
+
page_break: {
|
|
54
|
+
title: "Розрив сторінки",
|
|
55
|
+
subtext: "Роздільник сторінки",
|
|
56
|
+
aliases: ["page", "break", "separator", "розрив сторінки", "розділювач"],
|
|
57
|
+
group: "Базові блоки",
|
|
58
|
+
},
|
|
59
|
+
table: {
|
|
60
|
+
title: "Таблиця",
|
|
61
|
+
subtext: "Таблиця з редагованими клітинками",
|
|
62
|
+
aliases: ["table", "таблиця"],
|
|
63
|
+
group: "Розширені",
|
|
64
|
+
},
|
|
65
|
+
image: {
|
|
66
|
+
title: "Зображення",
|
|
67
|
+
subtext: "Масштабоване зображення з підписом",
|
|
68
|
+
aliases: ["image", "imageUpload", "upload", "img", "picture", "media", "url", "зображення", "медіа"],
|
|
69
|
+
group: "Медіа",
|
|
70
|
+
},
|
|
71
|
+
video: {
|
|
72
|
+
title: "Відео",
|
|
73
|
+
subtext: "Масштабоване відео з підписом",
|
|
74
|
+
aliases: ["video", "videoUpload", "upload", "mp4", "film", "media", "url", "відео", "медіа"],
|
|
75
|
+
group: "Медіа",
|
|
76
|
+
},
|
|
77
|
+
audio: {
|
|
78
|
+
title: "Аудіо",
|
|
79
|
+
subtext: "Вбудоване аудіо з підписом",
|
|
80
|
+
aliases: ["audio", "audioUpload", "upload", "mp3", "sound", "media", "url", "аудіо", "медіа"],
|
|
81
|
+
group: "Медіа",
|
|
82
|
+
},
|
|
83
|
+
file: {
|
|
84
|
+
title: "Файл",
|
|
85
|
+
subtext: "Вбудований файл",
|
|
86
|
+
aliases: ["file", "upload", "embed", "media", "url", "файл", "медіа"],
|
|
87
|
+
group: "Медіа",
|
|
88
|
+
},
|
|
89
|
+
emoji: {
|
|
90
|
+
title: "Емодзі",
|
|
91
|
+
subtext: "Пошук і вставка емодзі",
|
|
92
|
+
aliases: ["emoji", "emote", "emotion", "face", "смайлик", "емодзі"],
|
|
93
|
+
group: "Інше",
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
placeholders: {
|
|
97
|
+
default: "Введіть текст або наберіть '/' для команд",
|
|
98
|
+
heading: "Заголовок",
|
|
99
|
+
bulletListItem: "Список",
|
|
100
|
+
numberedListItem: "Список",
|
|
101
|
+
checkListItem: "Список",
|
|
102
|
+
},
|
|
103
|
+
file_blocks: {
|
|
104
|
+
image: {
|
|
105
|
+
add_button_text: "Додати зображення",
|
|
106
|
+
},
|
|
107
|
+
video: {
|
|
108
|
+
add_button_text: "Додати відео",
|
|
109
|
+
},
|
|
110
|
+
audio: {
|
|
111
|
+
add_button_text: "Додати аудіо",
|
|
112
|
+
},
|
|
113
|
+
file: {
|
|
114
|
+
add_button_text: "Додати файл",
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
// from react package:
|
|
118
|
+
side_menu: {
|
|
119
|
+
add_block_label: "Додати блок",
|
|
120
|
+
drag_handle_label: "Відкрити меню блока",
|
|
121
|
+
},
|
|
122
|
+
drag_handle: {
|
|
123
|
+
delete_menuitem: "Видалити",
|
|
124
|
+
colors_menuitem: "Кольори",
|
|
125
|
+
},
|
|
126
|
+
table_handle: {
|
|
127
|
+
delete_column_menuitem: "Видалити стовпець",
|
|
128
|
+
delete_row_menuitem: "Видалити рядок",
|
|
129
|
+
add_left_menuitem: "Додати стовпець зліва",
|
|
130
|
+
add_right_menuitem: "Додати стовпець справа",
|
|
131
|
+
add_above_menuitem: "Додати рядок вище",
|
|
132
|
+
add_below_menuitem: "Додати рядок нижче",
|
|
133
|
+
},
|
|
134
|
+
suggestion_menu: {
|
|
135
|
+
no_items_title: "Нічого не знайдено",
|
|
136
|
+
loading: "Завантаження…",
|
|
137
|
+
},
|
|
138
|
+
color_picker: {
|
|
139
|
+
text_title: "Текст",
|
|
140
|
+
background_title: "Фон",
|
|
141
|
+
colors: {
|
|
142
|
+
default: "За замовчуванням",
|
|
143
|
+
gray: "Сірий",
|
|
144
|
+
brown: "Коричневий",
|
|
145
|
+
red: "Червоний",
|
|
146
|
+
orange: "Помаранчевий",
|
|
147
|
+
yellow: "Жовтий",
|
|
148
|
+
green: "Зелений",
|
|
149
|
+
blue: "Блакитний",
|
|
150
|
+
purple: "Фіолетовий",
|
|
151
|
+
pink: "Рожевий",
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
formatting_toolbar: {
|
|
155
|
+
bold: {
|
|
156
|
+
tooltip: "Жирний",
|
|
157
|
+
secondary_tooltip: "Mod+B",
|
|
158
|
+
},
|
|
159
|
+
italic: {
|
|
160
|
+
tooltip: "Курсив",
|
|
161
|
+
secondary_tooltip: "Mod+I",
|
|
162
|
+
},
|
|
163
|
+
underline: {
|
|
164
|
+
tooltip: "Підкреслений",
|
|
165
|
+
secondary_tooltip: "Mod+U",
|
|
166
|
+
},
|
|
167
|
+
strike: {
|
|
168
|
+
tooltip: "Закреслений",
|
|
169
|
+
secondary_tooltip: "Mod+Shift+X",
|
|
170
|
+
},
|
|
171
|
+
code: {
|
|
172
|
+
tooltip: "Код",
|
|
173
|
+
secondary_tooltip: "",
|
|
174
|
+
},
|
|
175
|
+
colors: {
|
|
176
|
+
tooltip: "Кольори",
|
|
177
|
+
},
|
|
178
|
+
link: {
|
|
179
|
+
tooltip: "Створити посилання",
|
|
180
|
+
secondary_tooltip: "Mod+K",
|
|
181
|
+
},
|
|
182
|
+
file_caption: {
|
|
183
|
+
tooltip: "Редагувати підпис",
|
|
184
|
+
input_placeholder: "Редагувати підпис",
|
|
185
|
+
},
|
|
186
|
+
file_replace: {
|
|
187
|
+
tooltip: {
|
|
188
|
+
image: "Замінити зображення",
|
|
189
|
+
video: "Замінити відео",
|
|
190
|
+
audio: "Замінити аудіо",
|
|
191
|
+
file: "Замінити файл",
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
file_rename: {
|
|
195
|
+
tooltip: {
|
|
196
|
+
image: "Перейменувати зображення",
|
|
197
|
+
video: "Перейменувати відео",
|
|
198
|
+
audio: "Перейменувати аудіо",
|
|
199
|
+
file: "Перейменувати файл",
|
|
200
|
+
},
|
|
201
|
+
input_placeholder: {
|
|
202
|
+
image: "Перейменувати зображення",
|
|
203
|
+
video: "Перейменувати відео",
|
|
204
|
+
audio: "Перейменувати аудіо",
|
|
205
|
+
file: "Перейменувати файл",
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
file_download: {
|
|
209
|
+
tooltip: {
|
|
210
|
+
image: "Завантажити зображення",
|
|
211
|
+
video: "Завантажити відео",
|
|
212
|
+
audio: "Завантажити аудіо",
|
|
213
|
+
file: "Завантажити файл",
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
file_delete: {
|
|
217
|
+
tooltip: {
|
|
218
|
+
image: "Видалити зображення",
|
|
219
|
+
video: "Видалити відео",
|
|
220
|
+
audio: "Видалити аудіо",
|
|
221
|
+
file: "Видалити файл",
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
file_preview_toggle: {
|
|
225
|
+
tooltip: "Перемкнути попередній перегляд",
|
|
226
|
+
},
|
|
227
|
+
nest: {
|
|
228
|
+
tooltip: "Вкладений блок",
|
|
229
|
+
secondary_tooltip: "Tab",
|
|
230
|
+
},
|
|
231
|
+
unnest: {
|
|
232
|
+
tooltip: "Розгрупувати блок",
|
|
233
|
+
secondary_tooltip: "Shift+Tab",
|
|
234
|
+
},
|
|
235
|
+
align_left: {
|
|
236
|
+
tooltip: "Вирівняти за лівим краєм",
|
|
237
|
+
},
|
|
238
|
+
align_center: {
|
|
239
|
+
tooltip: "Вирівняти по центру",
|
|
240
|
+
},
|
|
241
|
+
align_right: {
|
|
242
|
+
tooltip: "Вирівняти за правим краєм",
|
|
243
|
+
},
|
|
244
|
+
align_justify: {
|
|
245
|
+
tooltip: "Вирівняти за шириною",
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
file_panel: {
|
|
249
|
+
upload: {
|
|
250
|
+
title: "Завантажити",
|
|
251
|
+
file_placeholder: {
|
|
252
|
+
image: "Завантажити зображення",
|
|
253
|
+
video: "Завантажити відео",
|
|
254
|
+
audio: "Завантажити аудіо",
|
|
255
|
+
file: "Завантажити файл",
|
|
256
|
+
},
|
|
257
|
+
upload_error: "Помилка: не вдалося завантажити",
|
|
258
|
+
},
|
|
259
|
+
embed: {
|
|
260
|
+
title: "Вставити",
|
|
261
|
+
embed_button: {
|
|
262
|
+
image: "Вставити зображення",
|
|
263
|
+
video: "Вставити відео",
|
|
264
|
+
audio: "Вставити аудіо",
|
|
265
|
+
file: "Вставити файл",
|
|
266
|
+
},
|
|
267
|
+
url_placeholder: "Введіть URL",
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
link_toolbar: {
|
|
271
|
+
delete: {
|
|
272
|
+
tooltip: "Видалити посилання",
|
|
273
|
+
},
|
|
274
|
+
edit: {
|
|
275
|
+
text: "Редагувати посилання",
|
|
276
|
+
tooltip: "Редагувати",
|
|
277
|
+
},
|
|
278
|
+
open: {
|
|
279
|
+
tooltip: "Відкрити в новій вкладці",
|
|
280
|
+
},
|
|
281
|
+
form: {
|
|
282
|
+
title_placeholder: "Редагувати заголовок",
|
|
283
|
+
url_placeholder: "Редагувати URL",
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
generic: {
|
|
287
|
+
ctrl_shortcut: "Ctrl",
|
|
288
|
+
},
|
|
289
|
+
};
|
|
@@ -2,7 +2,7 @@ import { DOMSerializer } from "prosemirror-model";
|
|
|
2
2
|
import { PartialBlock } from "../../../../blocks/defaultBlocks.js";
|
|
3
3
|
import type { BlockNoteEditor } from "../../../../editor/BlockNoteEditor.js";
|
|
4
4
|
import { BlockSchema, InlineContentSchema, StyleSchema } from "../../../../schema/index.js";
|
|
5
|
-
export declare function serializeInlineContentInternalHTML<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema>(editor: BlockNoteEditor<any, I, S>, blockContent: PartialBlock<BSchema, I, S>["content"], serializer: DOMSerializer, options?: {
|
|
5
|
+
export declare function serializeInlineContentInternalHTML<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema>(editor: BlockNoteEditor<any, I, S>, blockContent: PartialBlock<BSchema, I, S>["content"], serializer: DOMSerializer, blockType?: string, options?: {
|
|
6
6
|
document?: Document;
|
|
7
7
|
}): HTMLElement | DocumentFragment;
|
|
8
8
|
export declare const serializeBlocksInternalHTML: <BSchema extends Record<string, import("../../../../schema/index.js").BlockConfig>, I extends InlineContentSchema, S extends StyleSchema>(editor: BlockNoteEditor<BSchema, I, S>, blocks: PartialBlock<BSchema, I, S>[], serializer: DOMSerializer, options?: {
|
|
@@ -4,7 +4,7 @@ import type { PartialBlock } from "../../blocks/defaultBlocks";
|
|
|
4
4
|
/**
|
|
5
5
|
* converts an array of inline content elements to prosemirror nodes
|
|
6
6
|
*/
|
|
7
|
-
export declare function inlineContentToNodes<I extends InlineContentSchema, S extends StyleSchema>(blockContent: PartialInlineContent<I, S>, schema: Schema, styleSchema: S): Node[];
|
|
7
|
+
export declare function inlineContentToNodes<I extends InlineContentSchema, S extends StyleSchema>(blockContent: PartialInlineContent<I, S>, schema: Schema, styleSchema: S, blockType?: string): Node[];
|
|
8
8
|
/**
|
|
9
9
|
* converts an array of inline content elements to prosemirror nodes
|
|
10
10
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { BlockNoteEditor, BlockNoteExtension } from "./BlockNoteEditor.js";
|
|
2
1
|
import { Plugin } from "prosemirror-state";
|
|
3
2
|
import * as Y from "yjs";
|
|
3
|
+
import type { BlockNoteEditor, BlockNoteExtension } from "./BlockNoteEditor.js";
|
|
4
4
|
import { BlockNoteDOMAttributes, BlockSchema, BlockSpecs, InlineContentSchema, InlineContentSpecs, StyleSchema, StyleSpecs } from "../schema/index.js";
|
|
5
5
|
type ExtensionOptions<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema> = {
|
|
6
6
|
editor: BlockNoteEditor<BSchema, I, S>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as Y from "yjs";
|
|
2
|
+
export declare const createCollaborationExtensions: (collaboration: {
|
|
3
|
+
fragment: Y.XmlFragment;
|
|
4
|
+
user: {
|
|
5
|
+
name: string;
|
|
6
|
+
color: string;
|
|
7
|
+
[key: string]: string;
|
|
8
|
+
};
|
|
9
|
+
provider: any;
|
|
10
|
+
renderCursor?: (user: any) => HTMLElement;
|
|
11
|
+
showCursorLabels?: "always" | "activity";
|
|
12
|
+
}) => (import("@tiptap/core").Extension<import("@tiptap/extension-collaboration").CollaborationOptions, any> | import("@tiptap/core").Extension<import("@tiptap/extension-collaboration-cursor").CollaborationCursorOptions, {
|
|
13
|
+
users: {
|
|
14
|
+
[key: string]: any;
|
|
15
|
+
clientId: number;
|
|
16
|
+
}[];
|
|
17
|
+
}>)[];
|
|
@@ -24,11 +24,6 @@ export declare class SideMenuView<BSchema extends BlockSchema, I extends InlineC
|
|
|
24
24
|
constructor(editor: BlockNoteEditor<BSchema, I, S>, sideMenuDetection: "viewport" | "editor", pmView: EditorView, emitUpdate: (state: SideMenuState<BSchema, I, S>) => void);
|
|
25
25
|
updateState: (state: SideMenuState<BSchema, I, S>) => void;
|
|
26
26
|
updateStateFromMousePos: () => void;
|
|
27
|
-
/**
|
|
28
|
-
* If the event is outside the editor contents,
|
|
29
|
-
* we dispatch a fake event, so that we can still drop the content
|
|
30
|
-
* when dragging / dropping to the side of the editor
|
|
31
|
-
*/
|
|
32
27
|
onDrop: (event: DragEvent) => void;
|
|
33
28
|
/**
|
|
34
29
|
* If a block is being dragged, ProseMirror usually gets the context of what's
|