@blocknote/core 0.19.1 → 0.20.0
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 +1791 -1483
- package/dist/blocknote.js.map +1 -1
- package/dist/blocknote.umd.cjs +6 -6
- package/dist/blocknote.umd.cjs.map +1 -1
- package/dist/src/api/blockManipulation/commands/insertBlocks/insertBlocks.js +6 -3
- package/dist/src/api/blockManipulation/commands/insertBlocks/insertBlocks.js.map +1 -1
- package/dist/src/api/blockManipulation/commands/moveBlocks/moveBlocks.js +219 -0
- package/dist/src/api/blockManipulation/commands/moveBlocks/moveBlocks.js.map +1 -0
- package/dist/src/api/blockManipulation/commands/moveBlocks/moveBlocks.test.js +175 -0
- package/dist/src/api/blockManipulation/commands/moveBlocks/moveBlocks.test.js.map +1 -0
- package/dist/src/api/blockManipulation/commands/splitBlock/splitBlock.test.js +3 -0
- package/dist/src/api/blockManipulation/commands/splitBlock/splitBlock.test.js.map +1 -1
- package/dist/src/api/blockManipulation/commands/updateBlock/updateBlock.js +6 -3
- package/dist/src/api/blockManipulation/commands/updateBlock/updateBlock.js.map +1 -1
- package/dist/src/api/blockManipulation/getBlock/getBlock.js +56 -0
- package/dist/src/api/blockManipulation/getBlock/getBlock.js.map +1 -0
- package/dist/src/api/blockManipulation/selections/selection.js +149 -0
- package/dist/src/api/blockManipulation/selections/selection.js.map +1 -0
- package/dist/src/api/blockManipulation/selections/selection.test.js +39 -0
- package/dist/src/api/blockManipulation/selections/selection.test.js.map +1 -0
- package/dist/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.js +3 -0
- package/dist/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.js.map +1 -1
- package/dist/src/api/clipboard/fromClipboard/handleVSCodePaste.js +3 -3
- package/dist/src/api/clipboard/fromClipboard/handleVSCodePaste.js.map +1 -1
- package/dist/src/api/nodeUtil.js +1 -1
- package/dist/src/api/nodeUtil.js.map +1 -1
- package/dist/src/blocks/CodeBlockContent/CodeBlockContent.js +15 -7
- package/dist/src/blocks/CodeBlockContent/CodeBlockContent.js.map +1 -1
- package/dist/src/blocks/CodeBlockContent/defaultSupportedLanguages.js +38 -18
- package/dist/src/blocks/CodeBlockContent/defaultSupportedLanguages.js.map +1 -1
- package/dist/src/blocks/TableBlockContent/TableExtension.js +8 -1
- package/dist/src/blocks/TableBlockContent/TableExtension.js.map +1 -1
- package/dist/src/editor/BlockNoteEditor.js +59 -57
- package/dist/src/editor/BlockNoteEditor.js.map +1 -1
- package/dist/src/editor/BlockNoteExtensions.js +2 -1
- package/dist/src/editor/BlockNoteExtensions.js.map +1 -1
- package/dist/src/extensions/FormattingToolbar/FormattingToolbarPlugin.js +4 -2
- package/dist/src/extensions/FormattingToolbar/FormattingToolbarPlugin.js.map +1 -1
- package/dist/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.js +10 -8
- package/dist/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.js.map +1 -1
- package/dist/src/extensions/LinkToolbar/LinkToolbarPlugin.js +7 -3
- package/dist/src/extensions/LinkToolbar/LinkToolbarPlugin.js.map +1 -1
- package/dist/src/extensions/Placeholder/PlaceholderPlugin.js +13 -7
- package/dist/src/extensions/Placeholder/PlaceholderPlugin.js.map +1 -1
- package/dist/src/extensions/SideMenu/SideMenuPlugin.js +5 -1
- package/dist/src/extensions/SideMenu/SideMenuPlugin.js.map +1 -1
- package/dist/src/extensions/SideMenu/dragging.js +5 -1
- package/dist/src/extensions/SideMenu/dragging.js.map +1 -1
- package/dist/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.js +0 -3
- package/dist/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.js.map +1 -1
- package/dist/src/extensions/TableHandles/TableHandlesPlugin.js +25 -8
- package/dist/src/extensions/TableHandles/TableHandlesPlugin.js.map +1 -1
- package/dist/src/i18n/locales/ru.js +1 -1
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.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 +3 -3
- package/src/api/blockManipulation/commands/insertBlocks/insertBlocks.ts +6 -6
- package/src/api/blockManipulation/commands/moveBlocks/__snapshots__/moveBlocks.test.ts.snap +9506 -0
- package/src/api/blockManipulation/commands/moveBlocks/moveBlocks.test.ts +295 -0
- package/src/api/blockManipulation/commands/moveBlocks/moveBlocks.ts +338 -0
- package/src/api/blockManipulation/commands/splitBlock/splitBlock.test.ts +4 -0
- package/src/api/blockManipulation/commands/updateBlock/updateBlock.ts +11 -3
- package/src/api/blockManipulation/getBlock/getBlock.ts +141 -0
- package/src/api/blockManipulation/selections/__snapshots__/selection.test.ts.snap +660 -0
- package/src/api/blockManipulation/selections/selection.test.ts +56 -0
- package/src/api/blockManipulation/selections/selection.ts +244 -0
- package/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.ts +4 -0
- package/src/api/clipboard/fromClipboard/handleVSCodePaste.ts +4 -4
- package/src/api/nodeUtil.ts +2 -2
- package/src/blocks/CodeBlockContent/CodeBlockContent.ts +18 -8
- package/src/blocks/CodeBlockContent/defaultSupportedLanguages.ts +38 -18
- package/src/blocks/TableBlockContent/TableExtension.ts +12 -1
- package/src/editor/Block.css +3 -0
- package/src/editor/BlockNoteEditor.ts +93 -85
- package/src/editor/BlockNoteExtensions.ts +3 -1
- package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +4 -2
- package/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.ts +11 -8
- package/src/extensions/LinkToolbar/LinkToolbarPlugin.ts +11 -4
- package/src/extensions/Placeholder/PlaceholderPlugin.ts +23 -15
- package/src/extensions/SideMenu/SideMenuPlugin.ts +5 -1
- package/src/extensions/SideMenu/dragging.ts +5 -1
- package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +0 -5
- package/src/extensions/TableHandles/TableHandlesPlugin.ts +34 -9
- package/src/i18n/locales/ru.ts +1 -1
- package/src/index.ts +1 -0
- package/types/src/api/blockManipulation/commands/moveBlocks/moveBlocks.d.ts +15 -0
- package/types/src/api/blockManipulation/getBlock/getBlock.d.ts +7 -0
- package/types/src/api/blockManipulation/selections/selection.d.ts +5 -0
- package/types/src/api/blockManipulation/selections/selection.test.d.ts +1 -0
- package/types/src/api/nodeUtil.d.ts +1 -1
- package/types/src/editor/BlockNoteEditor.d.ts +54 -10
- package/types/src/editor/BlockNoteExtensions.d.ts +1 -0
- package/types/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.d.ts +1 -0
- package/types/src/extensions/SideMenu/SideMenuPlugin.d.ts +1 -1
- package/types/src/index.d.ts +1 -0
- package/types/src/pm-nodes/BlockContainer.d.ts +2 -2
- package/types/src/pm-nodes/BlockGroup.d.ts +2 -2
- package/dist/src/api/blockManipulation/commands/moveBlock/moveBlock.js +0 -116
- package/dist/src/api/blockManipulation/commands/moveBlock/moveBlock.js.map +0 -1
- package/dist/src/api/blockManipulation/commands/moveBlock/moveBlock.test.js +0 -110
- package/dist/src/api/blockManipulation/commands/moveBlock/moveBlock.test.js.map +0 -1
- package/src/api/blockManipulation/commands/moveBlock/__snapshots__/moveBlock.test.ts.snap +0 -3799
- package/src/api/blockManipulation/commands/moveBlock/moveBlock.test.ts +0 -196
- package/src/api/blockManipulation/commands/moveBlock/moveBlock.ts +0 -176
- package/types/src/api/blockManipulation/commands/moveBlock/moveBlock.d.ts +0 -5
- /package/types/src/api/blockManipulation/commands/{moveBlock/moveBlock.test.d.ts → moveBlocks/moveBlocks.test.d.ts} +0 -0
|
@@ -9,11 +9,17 @@ import {
|
|
|
9
9
|
import { Node, Schema } from "prosemirror-model";
|
|
10
10
|
// import "./blocknote.css";
|
|
11
11
|
import * as Y from "yjs";
|
|
12
|
+
import {
|
|
13
|
+
getBlock,
|
|
14
|
+
getNextBlock,
|
|
15
|
+
getParentBlock,
|
|
16
|
+
getPrevBlock,
|
|
17
|
+
} from "../api/blockManipulation/getBlock/getBlock.js";
|
|
12
18
|
import { insertBlocks } from "../api/blockManipulation/commands/insertBlocks/insertBlocks.js";
|
|
13
19
|
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
} from "../api/blockManipulation/commands/
|
|
20
|
+
moveBlocksDown,
|
|
21
|
+
moveBlocksUp,
|
|
22
|
+
} from "../api/blockManipulation/commands/moveBlocks/moveBlocks.js";
|
|
17
23
|
import {
|
|
18
24
|
canNestBlock,
|
|
19
25
|
canUnnestBlock,
|
|
@@ -28,6 +34,10 @@ import {
|
|
|
28
34
|
getTextCursorPosition,
|
|
29
35
|
setTextCursorPosition,
|
|
30
36
|
} from "../api/blockManipulation/selections/textCursorPosition/textCursorPosition.js";
|
|
37
|
+
import {
|
|
38
|
+
getSelection,
|
|
39
|
+
setSelection,
|
|
40
|
+
} from "../api/blockManipulation/selections/selection.js";
|
|
31
41
|
import { createExternalHTMLExporter } from "../api/exporters/html/externalHTMLExporter.js";
|
|
32
42
|
import { blocksToMarkdown } from "../api/exporters/markdown/markdownExporter.js";
|
|
33
43
|
import { HTMLToBlocks } from "../api/parsers/html/parseHTML.js";
|
|
@@ -219,6 +229,21 @@ export type BlockNoteEditorOptions<
|
|
|
219
229
|
setIdAttribute?: boolean;
|
|
220
230
|
|
|
221
231
|
dropCursor?: (opts: any) => Plugin;
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
Select desired behavior when pressing `Tab` (or `Shift-Tab`). Specifically,
|
|
235
|
+
what should happen when a user has selected multiple blocks while a toolbar
|
|
236
|
+
is open:
|
|
237
|
+
- `"prefer-navigate-ui"`: Change focus to the toolbar. The user needs to
|
|
238
|
+
first press `Escape` to close the toolbar, and can then indent multiple
|
|
239
|
+
blocks. Better for keyboard accessibility.
|
|
240
|
+
- `"prefer-indent"`: Regardless of whether toolbars are open, indent the
|
|
241
|
+
selection of blocks. In this case, it's not possible to navigate toolbars
|
|
242
|
+
with the keyboard.
|
|
243
|
+
|
|
244
|
+
@default "prefer-navigate-ui"
|
|
245
|
+
*/
|
|
246
|
+
tabBehavior: "prefer-navigate-ui" | "prefer-indent";
|
|
222
247
|
};
|
|
223
248
|
|
|
224
249
|
const blockNoteTipTapOptions = {
|
|
@@ -395,6 +420,7 @@ export class BlockNoteEditor<
|
|
|
395
420
|
tableHandles: checkDefaultBlockTypeInSchema("table", this),
|
|
396
421
|
dropCursor: this.options.dropCursor ?? dropCursor,
|
|
397
422
|
placeholders: newOptions.placeholders,
|
|
423
|
+
tabBehavior: newOptions.tabBehavior,
|
|
398
424
|
});
|
|
399
425
|
|
|
400
426
|
// add extensions from _tiptapOptions
|
|
@@ -474,6 +500,12 @@ export class BlockNoteEditor<
|
|
|
474
500
|
return ext;
|
|
475
501
|
}
|
|
476
502
|
|
|
503
|
+
if (!ext.plugin) {
|
|
504
|
+
throw new Error(
|
|
505
|
+
"Extension should either be a TipTap extension or a ProseMirror plugin in a plugin property"
|
|
506
|
+
);
|
|
507
|
+
}
|
|
508
|
+
|
|
477
509
|
// "blocknote" extensions (prosemirror plugins)
|
|
478
510
|
return Extension.create({
|
|
479
511
|
name: key,
|
|
@@ -604,39 +636,57 @@ export class BlockNoteEditor<
|
|
|
604
636
|
|
|
605
637
|
/**
|
|
606
638
|
* Gets a snapshot of an existing block from the editor.
|
|
607
|
-
* @param blockIdentifier The identifier of an existing block that should be
|
|
608
|
-
*
|
|
639
|
+
* @param blockIdentifier The identifier of an existing block that should be
|
|
640
|
+
* retrieved.
|
|
641
|
+
* @returns The block that matches the identifier, or `undefined` if no
|
|
642
|
+
* matching block was found.
|
|
609
643
|
*/
|
|
610
644
|
public getBlock(
|
|
611
645
|
blockIdentifier: BlockIdentifier
|
|
612
646
|
): Block<BSchema, ISchema, SSchema> | undefined {
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
? blockIdentifier
|
|
616
|
-
: blockIdentifier.id;
|
|
617
|
-
let newBlock: Block<BSchema, ISchema, SSchema> | undefined = undefined;
|
|
618
|
-
|
|
619
|
-
this._tiptapEditor.state.doc.firstChild!.descendants((node) => {
|
|
620
|
-
if (typeof newBlock !== "undefined") {
|
|
621
|
-
return false;
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
if (node.type.name !== "blockContainer" || node.attrs.id !== id) {
|
|
625
|
-
return true;
|
|
626
|
-
}
|
|
647
|
+
return getBlock(this, blockIdentifier);
|
|
648
|
+
}
|
|
627
649
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
650
|
+
/**
|
|
651
|
+
* Gets a snapshot of the previous sibling of an existing block from the
|
|
652
|
+
* editor.
|
|
653
|
+
* @param blockIdentifier The identifier of an existing block for which the
|
|
654
|
+
* previous sibling should be retrieved.
|
|
655
|
+
* @returns The previous sibling of the block that matches the identifier.
|
|
656
|
+
* `undefined` if no matching block was found, or it's the first child/block
|
|
657
|
+
* in the document.
|
|
658
|
+
*/
|
|
659
|
+
public getPrevBlock(
|
|
660
|
+
blockIdentifier: BlockIdentifier
|
|
661
|
+
): Block<BSchema, ISchema, SSchema> | undefined {
|
|
662
|
+
return getPrevBlock(this, blockIdentifier);
|
|
663
|
+
}
|
|
635
664
|
|
|
636
|
-
|
|
637
|
-
|
|
665
|
+
/**
|
|
666
|
+
* Gets a snapshot of the next sibling of an existing block from the editor.
|
|
667
|
+
* @param blockIdentifier The identifier of an existing block for which the
|
|
668
|
+
* next sibling should be retrieved.
|
|
669
|
+
* @returns The next sibling of the block that matches the identifier.
|
|
670
|
+
* `undefined` if no matching block was found, or it's the last child/block in
|
|
671
|
+
* the document.
|
|
672
|
+
*/
|
|
673
|
+
public getNextBlock(
|
|
674
|
+
blockIdentifier: BlockIdentifier
|
|
675
|
+
): Block<BSchema, ISchema, SSchema> | undefined {
|
|
676
|
+
return getNextBlock(this, blockIdentifier);
|
|
677
|
+
}
|
|
638
678
|
|
|
639
|
-
|
|
679
|
+
/**
|
|
680
|
+
* Gets a snapshot of the parent of an existing block from the editor.
|
|
681
|
+
* @param blockIdentifier The identifier of an existing block for which the
|
|
682
|
+
* parent should be retrieved.
|
|
683
|
+
* @returns The parent of the block that matches the identifier. `undefined`
|
|
684
|
+
* if no matching block was found, or the block isn't nested.
|
|
685
|
+
*/
|
|
686
|
+
public getParentBlock(
|
|
687
|
+
blockIdentifier: BlockIdentifier
|
|
688
|
+
): Block<BSchema, ISchema, SSchema> | undefined {
|
|
689
|
+
return getParentBlock(this, blockIdentifier);
|
|
640
690
|
}
|
|
641
691
|
|
|
642
692
|
/**
|
|
@@ -722,53 +772,11 @@ export class BlockNoteEditor<
|
|
|
722
772
|
* Gets a snapshot of the current selection.
|
|
723
773
|
*/
|
|
724
774
|
public getSelection(): Selection<BSchema, ISchema, SSchema> | undefined {
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
if (
|
|
728
|
-
this._tiptapEditor.state.selection.from ===
|
|
729
|
-
this._tiptapEditor.state.selection.to ||
|
|
730
|
-
"node" in this._tiptapEditor.state.selection
|
|
731
|
-
) {
|
|
732
|
-
return undefined;
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
const blocks: Block<BSchema, ISchema, SSchema>[] = [];
|
|
736
|
-
|
|
737
|
-
// TODO: This adds all child blocks to the same array. Needs to find min
|
|
738
|
-
// depth and only add blocks at that depth.
|
|
739
|
-
this._tiptapEditor.state.doc.descendants((node, pos) => {
|
|
740
|
-
if (node.type.spec.group !== "blockContent") {
|
|
741
|
-
return true;
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
// Fixed the block pos and size
|
|
745
|
-
// all block is wrapped with a blockContent wrapper
|
|
746
|
-
// and blockContent wrapper pos = inner block pos - 1
|
|
747
|
-
// blockContent wrapper end = inner block pos + nodeSize + 1
|
|
748
|
-
// need to add 1 to start and -1 to end
|
|
749
|
-
const end = pos + node.nodeSize - 1;
|
|
750
|
-
const start = pos + 1;
|
|
751
|
-
if (
|
|
752
|
-
end <= this._tiptapEditor.state.selection.from ||
|
|
753
|
-
start >= this._tiptapEditor.state.selection.to
|
|
754
|
-
) {
|
|
755
|
-
return true;
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
blocks.push(
|
|
759
|
-
nodeToBlock(
|
|
760
|
-
this._tiptapEditor.state.doc.resolve(pos).node(),
|
|
761
|
-
this.schema.blockSchema,
|
|
762
|
-
this.schema.inlineContentSchema,
|
|
763
|
-
this.schema.styleSchema,
|
|
764
|
-
this.blockCache
|
|
765
|
-
)
|
|
766
|
-
);
|
|
767
|
-
|
|
768
|
-
return false;
|
|
769
|
-
});
|
|
775
|
+
return getSelection(this);
|
|
776
|
+
}
|
|
770
777
|
|
|
771
|
-
|
|
778
|
+
public setSelection(startBlock: BlockIdentifier, endBlock: BlockIdentifier) {
|
|
779
|
+
setSelection(this, startBlock, endBlock);
|
|
772
780
|
}
|
|
773
781
|
|
|
774
782
|
/**
|
|
@@ -1026,21 +1034,21 @@ export class BlockNoteEditor<
|
|
|
1026
1034
|
}
|
|
1027
1035
|
|
|
1028
1036
|
/**
|
|
1029
|
-
* Moves the
|
|
1030
|
-
*
|
|
1031
|
-
*
|
|
1037
|
+
* Moves the selected blocks up. If the previous block has children, moves
|
|
1038
|
+
* them to the end of its children. If there is no previous block, but the
|
|
1039
|
+
* current blocks share a common parent, moves them out of & before it.
|
|
1032
1040
|
*/
|
|
1033
|
-
public
|
|
1034
|
-
|
|
1041
|
+
public moveBlocksUp() {
|
|
1042
|
+
moveBlocksUp(this);
|
|
1035
1043
|
}
|
|
1036
1044
|
|
|
1037
1045
|
/**
|
|
1038
|
-
* Moves the
|
|
1039
|
-
*
|
|
1040
|
-
*
|
|
1046
|
+
* Moves the selected blocks down. If the next block has children, moves
|
|
1047
|
+
* them to the start of its children. If there is no next block, but the
|
|
1048
|
+
* current blocks share a common parent, moves them out of & after it.
|
|
1041
1049
|
*/
|
|
1042
|
-
public
|
|
1043
|
-
|
|
1050
|
+
public moveBlocksDown() {
|
|
1051
|
+
moveBlocksDown(this);
|
|
1044
1052
|
}
|
|
1045
1053
|
|
|
1046
1054
|
/**
|
|
@@ -67,6 +67,7 @@ type ExtensionOptions<
|
|
|
67
67
|
tableHandles: boolean;
|
|
68
68
|
dropCursor: (opts: any) => Plugin;
|
|
69
69
|
placeholders: Record<string | "default", string>;
|
|
70
|
+
tabBehavior?: "prefer-navigate-ui" | "prefer-indent";
|
|
70
71
|
};
|
|
71
72
|
|
|
72
73
|
/**
|
|
@@ -116,7 +117,7 @@ export const getBlockNoteExtensions = <
|
|
|
116
117
|
ret["nodeSelectionKeyboard"] = new NodeSelectionKeyboardPlugin();
|
|
117
118
|
|
|
118
119
|
const disableExtensions: string[] = opts.disableExtensions || [];
|
|
119
|
-
for (const ext of
|
|
120
|
+
for (const ext of disableExtensions) {
|
|
120
121
|
delete ret[ext];
|
|
121
122
|
}
|
|
122
123
|
|
|
@@ -200,6 +201,7 @@ const getTipTapExtensions = <
|
|
|
200
201
|
}),
|
|
201
202
|
KeyboardShortcutsExtension.configure({
|
|
202
203
|
editor: opts.editor,
|
|
204
|
+
tabBehavior: opts.tabBehavior,
|
|
203
205
|
}),
|
|
204
206
|
BlockGroup.configure({
|
|
205
207
|
domAttributes: opts.domAttributes,
|
|
@@ -139,9 +139,11 @@ export class FormattingToolbarView implements PluginView {
|
|
|
139
139
|
// Wrapping in a setTimeout gives enough time to wait for the blur event to
|
|
140
140
|
// occur before updating the toolbar.
|
|
141
141
|
const { state, composing } = view;
|
|
142
|
-
const {
|
|
142
|
+
const { selection } = state;
|
|
143
143
|
const isSame =
|
|
144
|
-
oldState &&
|
|
144
|
+
oldState &&
|
|
145
|
+
oldState.selection.from === state.selection.from &&
|
|
146
|
+
oldState.selection.to === state.selection.to;
|
|
145
147
|
|
|
146
148
|
if (composing || isSame) {
|
|
147
149
|
return;
|
|
@@ -16,6 +16,7 @@ import { BlockNoteEditor } from "../../editor/BlockNoteEditor.js";
|
|
|
16
16
|
|
|
17
17
|
export const KeyboardShortcutsExtension = Extension.create<{
|
|
18
18
|
editor: BlockNoteEditor<any, any, any>;
|
|
19
|
+
tabBehavior: "prefer-navigate-ui" | "prefer-indent";
|
|
19
20
|
}>({
|
|
20
21
|
priority: 50,
|
|
21
22
|
|
|
@@ -479,9 +480,10 @@ export const KeyboardShortcutsExtension = Extension.create<{
|
|
|
479
480
|
// editor since the browser will try to use tab for keyboard navigation.
|
|
480
481
|
Tab: () => {
|
|
481
482
|
if (
|
|
482
|
-
this.options.
|
|
483
|
-
this.options.editor.
|
|
484
|
-
|
|
483
|
+
this.options.tabBehavior !== "prefer-indent" &&
|
|
484
|
+
(this.options.editor.formattingToolbar?.shown ||
|
|
485
|
+
this.options.editor.linkToolbar?.shown ||
|
|
486
|
+
this.options.editor.filePanel?.shown)
|
|
485
487
|
) {
|
|
486
488
|
// don't handle tabs if a toolbar is shown, so we can tab into / out of it
|
|
487
489
|
return false;
|
|
@@ -491,9 +493,10 @@ export const KeyboardShortcutsExtension = Extension.create<{
|
|
|
491
493
|
},
|
|
492
494
|
"Shift-Tab": () => {
|
|
493
495
|
if (
|
|
494
|
-
this.options.
|
|
495
|
-
this.options.editor.
|
|
496
|
-
|
|
496
|
+
this.options.tabBehavior !== "prefer-indent" &&
|
|
497
|
+
(this.options.editor.formattingToolbar?.shown ||
|
|
498
|
+
this.options.editor.linkToolbar?.shown ||
|
|
499
|
+
this.options.editor.filePanel?.shown)
|
|
497
500
|
) {
|
|
498
501
|
// don't handle tabs if a toolbar is shown, so we can tab into / out of it
|
|
499
502
|
return false;
|
|
@@ -502,11 +505,11 @@ export const KeyboardShortcutsExtension = Extension.create<{
|
|
|
502
505
|
return true;
|
|
503
506
|
},
|
|
504
507
|
"Shift-Mod-ArrowUp": () => {
|
|
505
|
-
this.options.editor.
|
|
508
|
+
this.options.editor.moveBlocksUp();
|
|
506
509
|
return true;
|
|
507
510
|
},
|
|
508
511
|
"Shift-Mod-ArrowDown": () => {
|
|
509
|
-
this.options.editor.
|
|
512
|
+
this.options.editor.moveBlocksDown();
|
|
510
513
|
return true;
|
|
511
514
|
},
|
|
512
515
|
};
|
|
@@ -2,7 +2,7 @@ import { getMarkRange, posToDOMRect, Range } from "@tiptap/core";
|
|
|
2
2
|
|
|
3
3
|
import { EditorView } from "@tiptap/pm/view";
|
|
4
4
|
import { Mark } from "prosemirror-model";
|
|
5
|
-
import { Plugin, PluginKey, PluginView } from "prosemirror-state";
|
|
5
|
+
import { EditorState, Plugin, PluginKey, PluginView } from "prosemirror-state";
|
|
6
6
|
|
|
7
7
|
import type { BlockNoteEditor } from "../../editor/BlockNoteEditor.js";
|
|
8
8
|
import { UiElementPosition } from "../../extensions-shared/UiElementPosition.js";
|
|
@@ -52,7 +52,7 @@ class LinkToolbarView implements PluginView {
|
|
|
52
52
|
|
|
53
53
|
this.startMenuUpdateTimer = () => {
|
|
54
54
|
this.menuUpdateTimer = setTimeout(() => {
|
|
55
|
-
this.update();
|
|
55
|
+
this.update(this.pmView);
|
|
56
56
|
}, 250);
|
|
57
57
|
};
|
|
58
58
|
|
|
@@ -190,8 +190,15 @@ class LinkToolbarView implements PluginView {
|
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
-
update() {
|
|
194
|
-
|
|
193
|
+
update(view: EditorView, oldState?: EditorState) {
|
|
194
|
+
const { state } = view;
|
|
195
|
+
|
|
196
|
+
const isSame =
|
|
197
|
+
oldState &&
|
|
198
|
+
oldState.selection.from === state.selection.from &&
|
|
199
|
+
oldState.selection.to === state.selection.to;
|
|
200
|
+
|
|
201
|
+
if (isSame || !this.pmView.hasFocus()) {
|
|
195
202
|
return;
|
|
196
203
|
}
|
|
197
204
|
|
|
@@ -48,22 +48,30 @@ export class PlaceholderPlugin {
|
|
|
48
48
|
for (const [blockType, placeholder] of Object.entries(placeholders)) {
|
|
49
49
|
const mustBeFocused = blockType === "default";
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
`${getSelector(
|
|
53
|
-
blockType,
|
|
54
|
-
mustBeFocused
|
|
55
|
-
)}{ content: ${JSON.stringify(placeholder)}; }`
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
// For some reason, the placeholders which show when the block is focused
|
|
59
|
-
// take priority over ones which show depending on block type, so we need
|
|
60
|
-
// to make sure the block specific ones are also used when the block is
|
|
61
|
-
// focused.
|
|
62
|
-
if (!mustBeFocused) {
|
|
51
|
+
try {
|
|
63
52
|
styleSheet.insertRule(
|
|
64
|
-
`${getSelector(
|
|
65
|
-
|
|
66
|
-
|
|
53
|
+
`${getSelector(
|
|
54
|
+
blockType,
|
|
55
|
+
mustBeFocused
|
|
56
|
+
)} { content: ${JSON.stringify(placeholder)}; }`
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
// For some reason, the placeholders which show when the block is focused
|
|
60
|
+
// take priority over ones which show depending on block type, so we need
|
|
61
|
+
// to make sure the block specific ones are also used when the block is
|
|
62
|
+
// focused.
|
|
63
|
+
if (!mustBeFocused) {
|
|
64
|
+
styleSheet.insertRule(
|
|
65
|
+
`${getSelector(blockType, true)} { content: ${JSON.stringify(
|
|
66
|
+
placeholder
|
|
67
|
+
)}; }`
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
} catch (e) {
|
|
71
|
+
// eslint-disable-next-line no-console
|
|
72
|
+
console.warn(
|
|
73
|
+
`Failed to insert placeholder CSS rule - this is likely due to the browser not supporting certain CSS pseudo-element selectors (:has, :only-child:, or :before)`,
|
|
74
|
+
e
|
|
67
75
|
);
|
|
68
76
|
}
|
|
69
77
|
}
|
|
@@ -491,7 +491,11 @@ export class SideMenuProsemirrorPlugin<
|
|
|
491
491
|
* attached to the same block regardless of which block is hovered by the
|
|
492
492
|
* mouse cursor.
|
|
493
493
|
*/
|
|
494
|
-
freezeMenu = () =>
|
|
494
|
+
freezeMenu = () => {
|
|
495
|
+
this.view!.menuFrozen = true;
|
|
496
|
+
this.view!.state!.show = true;
|
|
497
|
+
this.view!.emitUpdate(this.view!.state!);
|
|
498
|
+
};
|
|
495
499
|
/**
|
|
496
500
|
* Unfreezes the side menu. When frozen, the side menu will stay
|
|
497
501
|
* attached to the same block regardless of which block is hovered by the
|
|
@@ -149,7 +149,11 @@ export function dragStart<
|
|
|
149
149
|
|
|
150
150
|
const view = editor.prosemirrorView;
|
|
151
151
|
|
|
152
|
-
const
|
|
152
|
+
const posInfo = getNodeById(block.id, view.state.doc);
|
|
153
|
+
if (!posInfo) {
|
|
154
|
+
throw new Error(`Block with ID ${block.id} not found`);
|
|
155
|
+
}
|
|
156
|
+
const pos = posInfo.posBeforeNode;
|
|
153
157
|
|
|
154
158
|
if (pos != null) {
|
|
155
159
|
const selection = view.state.selection;
|
|
@@ -176,14 +176,9 @@ export function getDefaultSlashMenuItems<
|
|
|
176
176
|
if (checkDefaultBlockTypeInSchema("codeBlock", editor)) {
|
|
177
177
|
items.push({
|
|
178
178
|
onItemClick: () => {
|
|
179
|
-
const pos = editor._tiptapEditor.state.selection.from;
|
|
180
|
-
|
|
181
179
|
insertOrUpdateBlock(editor, {
|
|
182
180
|
type: "codeBlock",
|
|
183
181
|
});
|
|
184
|
-
|
|
185
|
-
// Move the cursor inside the code block
|
|
186
|
-
editor._tiptapEditor.commands.setTextSelection(pos);
|
|
187
182
|
},
|
|
188
183
|
badge: formatKeyboardShortcut("Mod-Alt-c"),
|
|
189
184
|
key: "code_block",
|
|
@@ -236,6 +236,9 @@ export class TableHandlesView<
|
|
|
236
236
|
blockEl.id,
|
|
237
237
|
this.editor._tiptapEditor.state.doc
|
|
238
238
|
);
|
|
239
|
+
if (!pmNodeInfo) {
|
|
240
|
+
throw new Error(`Block with ID ${blockEl.id} not found`);
|
|
241
|
+
}
|
|
239
242
|
|
|
240
243
|
const block = nodeToBlock(
|
|
241
244
|
pmNodeInfo.node,
|
|
@@ -468,17 +471,26 @@ export class TableHandlesView<
|
|
|
468
471
|
// the existing selection out of the block.
|
|
469
472
|
this.editor.setTextCursorPosition(this.state.block.id);
|
|
470
473
|
};
|
|
471
|
-
// Updates drag
|
|
474
|
+
// Updates drag handles when the table is modified or removed.
|
|
472
475
|
update() {
|
|
473
476
|
if (!this.state || !this.state.show) {
|
|
474
477
|
return;
|
|
475
478
|
}
|
|
476
479
|
|
|
477
|
-
|
|
478
|
-
|
|
480
|
+
// Hide handles if the table block has been removed.
|
|
481
|
+
this.state.block = this.editor.getBlock(this.state.block.id)!;
|
|
482
|
+
if (!this.state.block) {
|
|
483
|
+
this.state.show = false;
|
|
484
|
+
this.state.showAddOrRemoveRowsButton = false;
|
|
485
|
+
this.state.showAddOrRemoveColumnsButton = false;
|
|
486
|
+
this.emitUpdate();
|
|
487
|
+
|
|
479
488
|
return;
|
|
480
489
|
}
|
|
481
490
|
|
|
491
|
+
const rowCount = this.state.block.content.rows.length;
|
|
492
|
+
const colCount = this.state.block.content.rows[0].cells.length;
|
|
493
|
+
|
|
482
494
|
if (
|
|
483
495
|
this.state.rowIndex !== undefined &&
|
|
484
496
|
this.state.colIndex !== undefined
|
|
@@ -486,20 +498,33 @@ export class TableHandlesView<
|
|
|
486
498
|
// If rows or columns are deleted in the update, the hovered indices for
|
|
487
499
|
// those may now be out of bounds. If this is the case, they are moved to
|
|
488
500
|
// the new last row or column.
|
|
489
|
-
if (this.state.rowIndex >=
|
|
490
|
-
this.state.rowIndex =
|
|
501
|
+
if (this.state.rowIndex >= rowCount) {
|
|
502
|
+
this.state.rowIndex = rowCount - 1;
|
|
491
503
|
}
|
|
492
|
-
if (this.state.colIndex >=
|
|
493
|
-
this.state.colIndex =
|
|
504
|
+
if (this.state.colIndex >= colCount) {
|
|
505
|
+
this.state.colIndex = colCount - 1;
|
|
494
506
|
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
// Update bounding boxes.
|
|
510
|
+
const tableBody = this.tableElement!.querySelector("tbody");
|
|
511
|
+
if (!tableBody) {
|
|
512
|
+
throw new Error(
|
|
513
|
+
"Table block does not contain a 'tbody' HTML element. This should never happen."
|
|
514
|
+
);
|
|
515
|
+
}
|
|
495
516
|
|
|
517
|
+
if (
|
|
518
|
+
this.state.rowIndex !== undefined &&
|
|
519
|
+
this.state.colIndex !== undefined
|
|
520
|
+
) {
|
|
496
521
|
const row = tableBody.children[this.state.rowIndex];
|
|
497
522
|
const cell = row.children[this.state.colIndex];
|
|
523
|
+
|
|
498
524
|
this.state.referencePosCell = cell.getBoundingClientRect();
|
|
499
525
|
}
|
|
500
|
-
|
|
501
|
-
this.state.block = this.editor.getBlock(this.state.block.id)!;
|
|
502
526
|
this.state.referencePosTable = tableBody.getBoundingClientRect();
|
|
527
|
+
|
|
503
528
|
this.emitUpdate();
|
|
504
529
|
}
|
|
505
530
|
|
package/src/i18n/locales/ru.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -46,6 +46,7 @@ export * from "./util/string.js";
|
|
|
46
46
|
export * from "./util/typescript.js";
|
|
47
47
|
export { UnreachableCaseError, assertEmpty } from "./util/typescript.js";
|
|
48
48
|
export { locales };
|
|
49
|
+
export * from "./api/blockManipulation/commands/updateBlock/updateBlock.js";
|
|
49
50
|
|
|
50
51
|
// for testing from react (TODO: move):
|
|
51
52
|
export * from "./api/nodeConversions/blockToNode.js";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { BlockNoteEditor } from "../../../../editor/BlockNoteEditor";
|
|
2
|
+
import { BlockIdentifier } from "../../../../schema/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Removes the selected blocks from the editor, then inserts them before/after a
|
|
5
|
+
* reference block. Also updates the selection to match the original selection
|
|
6
|
+
* using `getBlockSelectionData` and `updateBlockSelectionFromData`.
|
|
7
|
+
* @param editor The BlockNote editor instance to move the blocks in.
|
|
8
|
+
* @param referenceBlock The reference block to insert the selected blocks
|
|
9
|
+
* before/after.
|
|
10
|
+
* @param placement Whether to insert the selected blocks before or after the
|
|
11
|
+
* reference block.
|
|
12
|
+
*/
|
|
13
|
+
export declare function moveSelectedBlocksAndSelection(editor: BlockNoteEditor<any, any, any>, referenceBlock: BlockIdentifier, placement: "before" | "after"): void;
|
|
14
|
+
export declare function moveBlocksUp(editor: BlockNoteEditor<any, any, any>): void;
|
|
15
|
+
export declare function moveBlocksDown(editor: BlockNoteEditor<any, any, any>): void;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Block } from "../../../blocks/defaultBlocks.js";
|
|
2
|
+
import type { BlockNoteEditor } from "../../../editor/BlockNoteEditor.js";
|
|
3
|
+
import { BlockIdentifier, BlockSchema, InlineContentSchema, StyleSchema } from "../../../schema/index.js";
|
|
4
|
+
export declare function getBlock<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema>(editor: BlockNoteEditor<BSchema, I, S>, blockIdentifier: BlockIdentifier): Block<BSchema, I, S> | undefined;
|
|
5
|
+
export declare function getPrevBlock<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema>(editor: BlockNoteEditor<BSchema, I, S>, blockIdentifier: BlockIdentifier): Block<BSchema, I, S> | undefined;
|
|
6
|
+
export declare function getNextBlock<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema>(editor: BlockNoteEditor<BSchema, I, S>, blockIdentifier: BlockIdentifier): Block<BSchema, I, S> | undefined;
|
|
7
|
+
export declare function getParentBlock<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema>(editor: BlockNoteEditor<BSchema, I, S>, blockIdentifier: BlockIdentifier): Block<BSchema, I, S> | undefined;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { BlockNoteEditor } from "../../../editor/BlockNoteEditor";
|
|
2
|
+
import { Selection } from "../../../editor/selectionTypes.js";
|
|
3
|
+
import { BlockIdentifier, BlockSchema, InlineContentSchema, StyleSchema } from "../../../schema/index.js";
|
|
4
|
+
export declare function getSelection<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema>(editor: BlockNoteEditor<BSchema, I, S>): Selection<BSchema, I, S> | undefined;
|
|
5
|
+
export declare function setSelection<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema>(editor: BlockNoteEditor<BSchema, I, S>, startBlock: BlockIdentifier, endBlock: BlockIdentifier): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|