@blocknote/core 0.33.0 → 0.34.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.
Files changed (39) hide show
  1. package/dist/blocknote.cjs +9 -9
  2. package/dist/blocknote.cjs.map +1 -1
  3. package/dist/blocknote.js +1838 -1715
  4. package/dist/blocknote.js.map +1 -1
  5. package/dist/tsconfig.tsbuildinfo +1 -1
  6. package/dist/webpack-stats.json +1 -1
  7. package/package.json +2 -2
  8. package/src/api/__snapshots__/blocks-indented-changed.json +129 -0
  9. package/src/api/__snapshots__/blocks-moved-deeper-into-nesting.json +164 -0
  10. package/src/api/__snapshots__/blocks-moved-multiple-in-same-transaction.json +188 -0
  11. package/src/api/__snapshots__/blocks-moved-to-different-parent.json +78 -0
  12. package/src/api/__snapshots__/blocks-moved-to-root-level.json +78 -0
  13. package/src/api/__snapshots__/blocks-outdented-changed.json +129 -0
  14. package/src/api/blockManipulation/commands/nestBlock/nestBlock.ts +58 -59
  15. package/src/api/nodeUtil.test.ts +228 -1
  16. package/src/api/nodeUtil.ts +135 -118
  17. package/src/api/parsers/markdown/detectMarkdown.test.ts +211 -0
  18. package/src/api/parsers/markdown/detectMarkdown.ts +3 -2
  19. package/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +2 -1
  20. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +2 -1
  21. package/src/blocks/ToggleWrapper/createToggleWrapper.ts +2 -0
  22. package/src/blocks/defaultBlockTypeGuards.ts +30 -0
  23. package/src/editor/BlockNoteEditor.ts +27 -10
  24. package/src/editor/BlockNoteExtensions.ts +3 -5
  25. package/src/exporter/Exporter.ts +2 -0
  26. package/src/exporter/mapping.ts +1 -0
  27. package/src/extensions/BlockChange/BlockChangePlugin.ts +66 -0
  28. package/src/extensions/SideMenu/SideMenuPlugin.ts +290 -207
  29. package/src/schema/inlineContent/types.ts +8 -0
  30. package/types/src/api/nodeUtil.d.ts +15 -21
  31. package/types/src/api/parsers/markdown/detectMarkdown.test.d.ts +1 -0
  32. package/types/src/blocks/defaultBlockTypeGuards.d.ts +7 -1
  33. package/types/src/editor/BlockNoteEditor.d.ts +11 -8
  34. package/types/src/editor/BlockNoteExtensions.d.ts +0 -1
  35. package/types/src/exporter/Exporter.d.ts +1 -1
  36. package/types/src/exporter/mapping.d.ts +1 -1
  37. package/types/src/extensions/BlockChange/BlockChangePlugin.d.ts +15 -0
  38. package/types/src/extensions/SideMenu/SideMenuPlugin.d.ts +50 -9
  39. package/types/src/schema/inlineContent/types.d.ts +4 -0
@@ -16,31 +16,14 @@ export declare function isNodeBlock(node: Node): boolean;
16
16
  * This attributes the changes to a specific source.
17
17
  */
18
18
  export type BlockChangeSource = {
19
- /**
20
- * When an event is triggered by the local user, the source is "local".
21
- * This is the default source.
22
- */
23
19
  type: "local";
24
20
  } | {
25
- /**
26
- * When an event is triggered by a paste operation, the source is "paste".
27
- */
28
21
  type: "paste";
29
22
  } | {
30
- /**
31
- * When an event is triggered by a drop operation, the source is "drop".
32
- */
33
23
  type: "drop";
34
24
  } | {
35
- /**
36
- * When an event is triggered by an undo or redo operation, the source is "undo" or "redo".
37
- * @note Y.js undo/redo are not differentiated.
38
- */
39
25
  type: "undo" | "redo" | "undo-redo";
40
26
  } | {
41
- /**
42
- * When an event is triggered by a remote user, the source is "remote".
43
- */
44
27
  type: "yjs-remote";
45
28
  };
46
29
  export type BlocksChanged<BSchema extends BlockSchema = DefaultBlockSchema, ISchema extends InlineContentSchema = DefaultInlineContentSchema, SSchema extends StyleSchema = DefaultStyleSchema> = Array<{
@@ -61,14 +44,25 @@ export type BlocksChanged<BSchema extends BlockSchema = DefaultBlockSchema, ISch
61
44
  } | {
62
45
  type: "update";
63
46
  /**
64
- * The block before the update.
47
+ * The previous block.
48
+ */
49
+ prevBlock: Block<BSchema, ISchema, SSchema>;
50
+ } | {
51
+ type: "move";
52
+ /**
53
+ * The previous block.
65
54
  */
66
55
  prevBlock: Block<BSchema, ISchema, SSchema>;
56
+ /**
57
+ * The previous parent block (if it existed).
58
+ */
59
+ prevParent?: Block<BSchema, ISchema, SSchema>;
60
+ /**
61
+ * The current parent block (if it exists).
62
+ */
63
+ currentParent?: Block<BSchema, ISchema, SSchema>;
67
64
  })>;
68
65
  /**
69
66
  * Get the blocks that were changed by a transaction.
70
- * @param transaction The transaction to get the changes from.
71
- * @param editor The editor to get the changes from.
72
- * @returns The blocks that were changed by the transaction.
73
67
  */
74
68
  export declare function getBlocksChangedByTransaction<BSchema extends BlockSchema = DefaultBlockSchema, ISchema extends InlineContentSchema = DefaultInlineContentSchema, SSchema extends StyleSchema = DefaultStyleSchema>(transaction: Transaction, appendedTransactions?: Transaction[]): BlocksChanged<BSchema, ISchema, SSchema>;
@@ -1,15 +1,21 @@
1
1
  import { CellSelection } from "prosemirror-tables";
2
2
  import type { BlockNoteEditor } from "../editor/BlockNoteEditor.js";
3
- import { BlockFromConfig, BlockSchema, FileBlockConfig, InlineContentSchema, StyleSchema } from "../schema/index.js";
3
+ import { BlockConfig, BlockFromConfig, BlockSchema, FileBlockConfig, InlineContentConfig, InlineContentSchema, StyleSchema } from "../schema/index.js";
4
4
  import { Block, DefaultBlockSchema, DefaultInlineContentSchema } from "./defaultBlocks.js";
5
5
  import { defaultProps } from "./defaultProps.js";
6
6
  import { Selection } from "prosemirror-state";
7
7
  export declare function checkDefaultBlockTypeInSchema<BlockType extends keyof DefaultBlockSchema, I extends InlineContentSchema, S extends StyleSchema>(blockType: BlockType, editor: BlockNoteEditor<any, I, S>): editor is BlockNoteEditor<{
8
8
  [K in BlockType]: DefaultBlockSchema[BlockType];
9
9
  }, I, S>;
10
+ export declare function checkBlockTypeInSchema<BlockType extends string, Config extends BlockConfig>(blockType: BlockType, blockConfig: Config, editor: BlockNoteEditor<any, any, any>): editor is BlockNoteEditor<{
11
+ [T in BlockType]: Config;
12
+ }, any, any>;
10
13
  export declare function checkDefaultInlineContentTypeInSchema<InlineContentType extends keyof DefaultInlineContentSchema, B extends BlockSchema, S extends StyleSchema>(inlineContentType: InlineContentType, editor: BlockNoteEditor<B, any, S>): editor is BlockNoteEditor<B, {
11
14
  [K in InlineContentType]: DefaultInlineContentSchema[InlineContentType];
12
15
  }, S>;
16
+ export declare function checkInlineContentTypeInSchema<InlineContentType extends string, Config extends InlineContentConfig>(inlineContentType: InlineContentType, inlineContentConfig: Config, editor: BlockNoteEditor<any, any, any>): editor is BlockNoteEditor<any, {
17
+ [T in InlineContentType]: Config;
18
+ }, any>;
13
19
  export declare function checkBlockIsDefaultType<BlockType extends keyof DefaultBlockSchema, I extends InlineContentSchema, S extends StyleSchema>(blockType: BlockType, block: Block<any, I, S>, editor: BlockNoteEditor<any, I, S>): block is BlockFromConfig<DefaultBlockSchema[BlockType], I, S>;
14
20
  export declare function checkBlockIsFileBlock<B extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema>(block: Block<any, I, S>, editor: BlockNoteEditor<B, I, S>): block is BlockFromConfig<FileBlockConfig, I, S>;
15
21
  export declare function checkBlockIsFileBlockWithPreview<B extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema>(block: Block<any, I, S>, editor: BlockNoteEditor<B, I, S>): block is BlockFromConfig<FileBlockConfig & {
@@ -175,14 +175,6 @@ export type BlockNoteEditorOptions<BSchema extends BlockSchema, ISchema extends
175
175
  * (note that the id is always set on the `data-id` attribute)
176
176
  */
177
177
  setIdAttribute?: boolean;
178
- /**
179
- * The detection mode for showing the side menu - "viewport" always shows the
180
- * side menu for the block next to the mouse cursor, while "editor" only shows
181
- * it when hovering the editor or the side menu itself.
182
- *
183
- * @default "viewport"
184
- */
185
- sideMenuDetection: "viewport" | "editor";
186
178
  /**
187
179
  Select desired behavior when pressing `Tab` (or `Shift-Tab`). Specifically,
188
180
  what should happen when a user has selected multiple blocks while a toolbar
@@ -716,6 +708,17 @@ export declare class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockS
716
708
  name: string;
717
709
  color: string;
718
710
  }): void;
711
+ /**
712
+ * Registers a callback which will be called before any change is applied to the editor, allowing you to cancel the change.
713
+ */
714
+ beforeChange(
715
+ /**
716
+ * If the callback returns `false`, the change will be canceled & not applied to the editor.
717
+ */
718
+ callback: (editor: BlockNoteEditor<BSchema, ISchema, SSchema>, context: {
719
+ getChanges: () => BlocksChanged<BSchema, ISchema, SSchema>;
720
+ tr: Transaction;
721
+ }) => boolean | void): () => void;
719
722
  /**
720
723
  * A callback function that runs whenever the editor's contents change.
721
724
  *
@@ -28,7 +28,6 @@ type ExtensionOptions<BSchema extends BlockSchema, I extends InlineContentSchema
28
28
  dropCursor: (opts: any) => Plugin;
29
29
  placeholders: Record<string | "default" | "emptyDocument", string | undefined>;
30
30
  tabBehavior?: "prefer-navigate-ui" | "prefer-indent";
31
- sideMenuDetection: "viewport" | "editor";
32
31
  comments?: {
33
32
  threadStore: ThreadStore;
34
33
  };
@@ -39,5 +39,5 @@ export declare abstract class Exporter<B extends BlockSchema, I extends InlineCo
39
39
  mapInlineContent(inlineContent: InlineContent<I, S>): RI;
40
40
  transformInlineContent(inlineContentArray: InlineContent<I, S>[]): RI[];
41
41
  abstract transformStyledText(styledText: StyledText<S>): TS;
42
- mapBlock(block: BlockFromConfig<B[keyof B], I, S>, nestingLevel: number, numberedListIndex: number): Promise<RB>;
42
+ mapBlock(block: BlockFromConfig<B[keyof B], I, S>, nestingLevel: number, numberedListIndex: number, children?: Array<Awaited<RB>>): Promise<RB>;
43
43
  }
@@ -5,7 +5,7 @@ import type { Exporter } from "./Exporter.js";
5
5
  * Defines a mapping from all block types with a schema to a result type `R`.
6
6
  */
7
7
  export type BlockMapping<B extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema, RB, RI> = {
8
- [K in keyof B]: (block: BlockFromConfigNoChildren<B[K], I, S>, exporter: Exporter<any, any, any, RB, RI, any, any>, nestingLevel: number, numberedListIndex?: number) => RB | Promise<RB>;
8
+ [K in keyof B]: (block: BlockFromConfigNoChildren<B[K], I, S>, exporter: Exporter<any, any, any, RB, RI, any, any>, nestingLevel: number, numberedListIndex?: number, children?: Array<Awaited<RB>>) => RB | Promise<RB>;
9
9
  };
10
10
  /**
11
11
  * Defines a mapping from all inline content types with a schema to a result type R.
@@ -0,0 +1,15 @@
1
+ import { Transaction } from "prosemirror-state";
2
+ import { BlockNoteExtension } from "../../editor/BlockNoteExtension.js";
3
+ import { BlocksChanged } from "../../index.js";
4
+ /**
5
+ * This plugin can filter transactions before they are applied to the editor, but with a higher-level API than `filterTransaction` from prosemirror.
6
+ */
7
+ export declare class BlockChangePlugin extends BlockNoteExtension {
8
+ static key(): string;
9
+ private beforeChangeCallbacks;
10
+ constructor();
11
+ subscribe(callback: (context: {
12
+ getChanges: () => BlocksChanged<any, any, any>;
13
+ tr: Transaction;
14
+ }) => boolean | void): () => void;
15
+ }
@@ -13,7 +13,6 @@ export type SideMenuState<BSchema extends BlockSchema, I extends InlineContentSc
13
13
  */
14
14
  export declare class SideMenuView<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema> implements PluginView {
15
15
  private readonly editor;
16
- private readonly sideMenuDetection;
17
16
  private readonly pmView;
18
17
  state?: SideMenuState<BSchema, I, S>;
19
18
  readonly emitUpdate: (state: SideMenuState<BSchema, I, S>) => void;
@@ -21,11 +20,9 @@ export declare class SideMenuView<BSchema extends BlockSchema, I extends InlineC
21
20
  private hoveredBlock;
22
21
  menuFrozen: boolean;
23
22
  isDragOrigin: boolean;
24
- constructor(editor: BlockNoteEditor<BSchema, I, S>, sideMenuDetection: "viewport" | "editor", pmView: EditorView, emitUpdate: (state: SideMenuState<BSchema, I, S>) => void);
23
+ constructor(editor: BlockNoteEditor<BSchema, I, S>, pmView: EditorView, emitUpdate: (state: SideMenuState<BSchema, I, S>) => void);
25
24
  updateState: (state: SideMenuState<BSchema, I, S>) => void;
26
25
  updateStateFromMousePos: () => void;
27
- onDrop: (event: DragEvent) => void;
28
- onDragEnd: () => void;
29
26
  /**
30
27
  * If a block is being dragged, ProseMirror usually gets the context of what's
31
28
  * being dragged from `view.dragging`, which is automatically set when a
@@ -46,14 +43,58 @@ export declare class SideMenuView<BSchema extends BlockSchema, I extends InlineC
46
43
  */
47
44
  onDragStart: (event: DragEvent) => void;
48
45
  /**
49
- * If the event is outside the editor contents,
50
- * we dispatch a fake event, so that we can still drop the content
51
- * when dragging / dropping to the side of the editor
46
+ * Finds the closest editor visually to the given coordinates
47
+ */
48
+ private findClosestEditorElement;
49
+ /**
50
+ * This dragover event handler listens at the document level,
51
+ * and is trying to handle dragover events for all editors.
52
+ *
53
+ * It specifically is trying to handle the following cases:
54
+ * - If the dragover event is within the bounds of any editor, then it does nothing
55
+ * - If the dragover event is outside the bounds of any editor, but close enough (within DISTANCE_TO_CONSIDER_EDITOR_BOUNDS) to the closest editor,
56
+ * then it dispatches a synthetic dragover event to the closest editor (which will trigger the drop-cursor to be shown on that editor)
57
+ * - If the dragover event is outside the bounds of the current editor, then it will dispatch a synthetic dragleave event to the current editor
58
+ * (which will trigger the drop-cursor to be removed from the current editor)
59
+ *
60
+ * The synthetic event is a necessary evil because we do not control prosemirror-dropcursor to be able to show the drop-cursor within the range we want
52
61
  */
53
62
  onDragOver: (event: DragEvent) => void;
63
+ /**
64
+ * Closes the drop-cursor for the current editor
65
+ */
66
+ private closeDropCursor;
67
+ /**
68
+ * It is surprisingly difficult to determine the information we need to know about a drag event
69
+ *
70
+ * This function is trying to determine the following:
71
+ * - Whether the current editor instance is the drop point
72
+ * - Whether the current editor instance is the drag origin
73
+ * - Whether the drop event is within the bounds of the current editor instance
74
+ */
75
+ getDragEventContext: (event: DragEvent) => {
76
+ isDropPoint: boolean;
77
+ isDropWithinEditorBounds: boolean;
78
+ isDragOrigin: boolean;
79
+ } | undefined;
80
+ /**
81
+ * The drop event handler listens at the document level,
82
+ * and handles drop events for all editors.
83
+ *
84
+ * It specifically handles the following cases:
85
+ * - If we are both the drag origin and drop point:
86
+ * - Let normal drop handling take over
87
+ * - If we are the drop point but not the drag origin:
88
+ * - Collapse selection to prevent PM from deleting unrelated content
89
+ * - If drop event is outside our editor bounds, dispatch synthetic drop event to our editor
90
+ * - If we are the drag origin but not the drop point:
91
+ * - Delete the dragged content from our editor after a delay
92
+ */
93
+ onDrop: (event: DragEvent) => void;
94
+ onDragEnd: (event: DragEvent) => void;
54
95
  onKeyDown: (_event: KeyboardEvent) => void;
55
96
  onMouseMove: (event: MouseEvent) => void;
56
- private createSyntheticEvent;
97
+ private dispatchSyntheticEvent;
57
98
  onScroll: () => void;
58
99
  update(_view: EditorView, prevState: EditorState): void;
59
100
  destroy(): void;
@@ -63,7 +104,7 @@ export declare class SideMenuProsemirrorPlugin<BSchema extends BlockSchema, I ex
63
104
  private readonly editor;
64
105
  static key(): string;
65
106
  view: SideMenuView<BSchema, I, S> | undefined;
66
- constructor(editor: BlockNoteEditor<BSchema, I, S>, sideMenuDetection: "viewport" | "editor");
107
+ constructor(editor: BlockNoteEditor<BSchema, I, S>);
67
108
  onUpdate(callback: (state: SideMenuState<BSchema, I, S>) => void): () => void;
68
109
  /**
69
110
  * Handles drag & drop events for blocks.
@@ -4,12 +4,16 @@ import { StyleSchema, Styles } from "../styles/types.js";
4
4
  export type CustomInlineContentConfig = {
5
5
  type: string;
6
6
  content: "styled" | "none";
7
+ draggable?: boolean;
7
8
  readonly propSchema: PropSchema;
8
9
  };
9
10
  export type InlineContentConfig = CustomInlineContentConfig | "text" | "link";
10
11
  export type InlineContentImplementation<T extends InlineContentConfig> = T extends "link" | "text" ? undefined : {
11
12
  node: Node;
12
13
  };
14
+ export type InlineContentSchemaWithInlineContent<IType extends string, C extends InlineContentConfig> = {
15
+ [k in IType]: C;
16
+ };
13
17
  export type InlineContentSpec<T extends InlineContentConfig> = {
14
18
  config: T;
15
19
  implementation: InlineContentImplementation<T>;