@blocknote/core 0.11.2 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/README.md +13 -17
  2. package/dist/blocknote.js +1662 -1447
  3. package/dist/blocknote.js.map +1 -1
  4. package/dist/blocknote.umd.cjs +6 -6
  5. package/dist/blocknote.umd.cjs.map +1 -1
  6. package/dist/style.css +1 -1
  7. package/dist/webpack-stats.json +1 -1
  8. package/package.json +7 -3
  9. package/src/api/blockManipulation/blockManipulation.test.ts +19 -15
  10. package/src/api/blockManipulation/blockManipulation.ts +107 -17
  11. package/src/api/exporters/html/externalHTMLExporter.ts +3 -7
  12. package/src/api/exporters/html/htmlConversion.test.ts +6 -3
  13. package/src/api/exporters/html/internalHTMLSerializer.ts +3 -7
  14. package/src/api/exporters/html/util/sharedHTMLConversion.ts +3 -3
  15. package/src/api/exporters/markdown/markdownExporter.test.ts +7 -3
  16. package/src/api/exporters/markdown/markdownExporter.ts +2 -6
  17. package/src/api/getCurrentBlockContentType.ts +14 -0
  18. package/src/api/nodeConversions/nodeConversions.test.ts +14 -7
  19. package/src/api/nodeConversions/nodeConversions.ts +1 -2
  20. package/src/api/parsers/html/parseHTML.test.ts +5 -1
  21. package/src/api/parsers/html/parseHTML.ts +2 -6
  22. package/src/api/parsers/html/util/nestedLists.ts +11 -1
  23. package/src/api/parsers/markdown/parseMarkdown.test.ts +3 -0
  24. package/src/api/parsers/markdown/parseMarkdown.ts +2 -6
  25. package/src/api/testUtil/cases/customBlocks.ts +18 -16
  26. package/src/api/testUtil/cases/customInlineContent.ts +12 -13
  27. package/src/api/testUtil/cases/customStyles.ts +12 -10
  28. package/src/api/testUtil/index.ts +4 -2
  29. package/src/api/testUtil/partialBlockTestUtil.ts +2 -6
  30. package/src/blocks/HeadingBlockContent/HeadingBlockContent.ts +50 -21
  31. package/src/blocks/ImageBlockContent/ImageBlockContent.ts +1 -2
  32. package/src/blocks/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.ts +8 -1
  33. package/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +18 -5
  34. package/src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.ts +7 -1
  35. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +18 -5
  36. package/src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts +14 -5
  37. package/src/blocks/defaultBlockHelpers.ts +3 -3
  38. package/src/blocks/defaultBlockTypeGuards.ts +84 -0
  39. package/src/blocks/defaultBlocks.ts +29 -3
  40. package/src/editor/Block.css +2 -31
  41. package/src/editor/BlockNoteEditor.ts +223 -267
  42. package/src/editor/BlockNoteExtensions.ts +5 -2
  43. package/src/editor/BlockNoteSchema.ts +98 -0
  44. package/src/editor/BlockNoteTipTapEditor.ts +162 -0
  45. package/src/editor/cursorPositionTypes.ts +2 -6
  46. package/src/editor/editor.css +0 -1
  47. package/src/editor/selectionTypes.ts +2 -6
  48. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +22 -29
  49. package/src/extensions/{ImageToolbar → ImagePanel}/ImageToolbarPlugin.ts +54 -60
  50. package/src/extensions/LinkToolbar/LinkToolbarPlugin.ts +330 -0
  51. package/src/extensions/Placeholder/PlaceholderExtension.ts +81 -88
  52. package/src/extensions/SideMenu/SideMenuPlugin.ts +55 -56
  53. package/src/extensions/SuggestionMenu/DefaultSuggestionItem.ts +8 -0
  54. package/src/extensions/SuggestionMenu/SuggestionPlugin.ts +353 -0
  55. package/src/extensions/{SlashMenu/defaultSlashMenuItems.ts → SuggestionMenu/getDefaultSlashMenuItems.ts} +119 -89
  56. package/src/extensions/TableHandles/TableHandlesPlugin.ts +62 -45
  57. package/src/extensions-shared/UiElementPosition.ts +4 -0
  58. package/src/index.ts +8 -8
  59. package/src/pm-nodes/BlockContainer.ts +5 -5
  60. package/src/schema/blocks/types.ts +15 -15
  61. package/src/schema/inlineContent/createSpec.ts +2 -2
  62. package/src/schema/inlineContent/types.ts +1 -1
  63. package/src/util/browser.ts +6 -4
  64. package/src/util/typescript.ts +7 -4
  65. package/types/src/api/blockManipulation/blockManipulation.d.ts +6 -1
  66. package/types/src/api/exporters/html/externalHTMLExporter.d.ts +2 -1
  67. package/types/src/api/exporters/html/internalHTMLSerializer.d.ts +2 -1
  68. package/types/src/api/exporters/markdown/markdownExporter.d.ts +2 -1
  69. package/types/src/api/getCurrentBlockContentType.d.ts +2 -0
  70. package/types/src/api/nodeConversions/nodeConversions.d.ts +2 -1
  71. package/types/src/api/parsers/html/parseHTML.d.ts +2 -1
  72. package/types/src/api/parsers/markdown/parseMarkdown.d.ts +2 -1
  73. package/types/src/api/testUtil/cases/customBlocks.d.ts +72 -13
  74. package/types/src/api/testUtil/cases/customInlineContent.d.ts +281 -6
  75. package/types/src/api/testUtil/cases/customStyles.d.ts +247 -13
  76. package/types/src/api/testUtil/index.d.ts +4 -2
  77. package/types/src/api/testUtil/partialBlockTestUtil.d.ts +2 -1
  78. package/types/src/blocks/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.d.ts +6 -1
  79. package/types/src/blocks/defaultBlockHelpers.d.ts +2 -2
  80. package/types/src/blocks/defaultBlockTypeGuards.d.ts +24 -0
  81. package/types/src/blocks/defaultBlocks.d.ts +21 -15
  82. package/types/src/editor/BlockNoteEditor.d.ts +51 -56
  83. package/types/src/editor/BlockNoteExtensions.d.ts +1 -0
  84. package/types/src/editor/BlockNoteSchema.d.ts +34 -0
  85. package/types/src/editor/BlockNoteTipTapEditor.d.ts +28 -0
  86. package/types/src/editor/cursorPositionTypes.d.ts +2 -1
  87. package/types/src/editor/selectionTypes.d.ts +2 -1
  88. package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +5 -6
  89. package/types/src/extensions/ImagePanel/ImageToolbarPlugin.d.ts +32 -0
  90. package/types/src/extensions/LinkToolbar/LinkToolbarPlugin.d.ts +40 -0
  91. package/types/src/extensions/Placeholder/PlaceholderExtension.d.ts +2 -15
  92. package/types/src/extensions/SideMenu/SideMenuPlugin.d.ts +8 -7
  93. package/types/src/extensions/SuggestionMenu/DefaultSuggestionItem.d.ts +8 -0
  94. package/types/src/extensions/SuggestionMenu/SuggestionPlugin.d.ts +31 -0
  95. package/types/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.d.ts +10 -0
  96. package/types/src/extensions/TableHandles/TableHandlesPlugin.d.ts +7 -7
  97. package/types/src/extensions-shared/UiElementPosition.d.ts +4 -0
  98. package/types/src/index.d.ts +8 -8
  99. package/types/src/pm-nodes/BlockContainer.d.ts +3 -2
  100. package/types/src/pm-nodes/BlockGroup.d.ts +1 -1
  101. package/types/src/schema/blocks/types.d.ts +15 -15
  102. package/types/src/schema/inlineContent/types.d.ts +1 -1
  103. package/types/src/util/browser.d.ts +1 -0
  104. package/types/src/util/typescript.d.ts +1 -0
  105. package/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts +0 -335
  106. package/src/extensions/SlashMenu/BaseSlashMenuItem.ts +0 -12
  107. package/src/extensions/SlashMenu/SlashMenuPlugin.ts +0 -53
  108. package/src/extensions-shared/BaseUiElementTypes.ts +0 -8
  109. package/src/extensions-shared/README.md +0 -3
  110. package/src/extensions-shared/suggestion/SuggestionItem.ts +0 -3
  111. package/src/extensions-shared/suggestion/SuggestionPlugin.ts +0 -448
  112. package/types/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.d.ts +0 -38
  113. package/types/src/extensions/ImageToolbar/ImageToolbarPlugin.d.ts +0 -31
  114. package/types/src/extensions/SlashMenu/BaseSlashMenuItem.d.ts +0 -7
  115. package/types/src/extensions/SlashMenu/SlashMenuPlugin.d.ts +0 -13
  116. package/types/src/extensions/SlashMenu/defaultSlashMenuItems.d.ts +0 -3
  117. package/types/src/extensions-shared/BaseUiElementTypes.d.ts +0 -7
  118. package/types/src/extensions-shared/suggestion/SuggestionItem.d.ts +0 -3
  119. package/types/src/extensions-shared/suggestion/SuggestionPlugin.d.ts +0 -36
  120. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-100.woff +0 -0
  121. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-100.woff2 +0 -0
  122. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-200.woff +0 -0
  123. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-200.woff2 +0 -0
  124. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-300.woff +0 -0
  125. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-300.woff2 +0 -0
  126. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-500.woff +0 -0
  127. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-500.woff2 +0 -0
  128. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-600.woff +0 -0
  129. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-600.woff2 +0 -0
  130. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-700.woff +0 -0
  131. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-700.woff2 +0 -0
  132. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-800.woff +0 -0
  133. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-800.woff2 +0 -0
  134. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-900.woff +0 -0
  135. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-900.woff2 +0 -0
  136. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-regular.woff +0 -0
  137. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-regular.woff2 +0 -0
  138. /package/src/{assets/fonts-inter.css → fonts/inter.css} +0 -0
@@ -1,9 +1,9 @@
1
1
  import { Plugin, PluginKey, PluginView } from "prosemirror-state";
2
2
  import { EditorView } from "prosemirror-view";
3
- import { EventEmitter } from "../../util/EventEmitter";
4
3
  import { DefaultBlockSchema } from "../../blocks/defaultBlocks";
5
4
  import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
6
5
  import { BlockFromConfigNoChildren, BlockSchemaWithBlock, InlineContentSchema, StyleSchema } from "../../schema";
6
+ import { EventEmitter } from "../../util/EventEmitter";
7
7
  export type TableHandlesState<I extends InlineContentSchema, S extends StyleSchema> = {
8
8
  show: boolean;
9
9
  referencePosCell: DOMRect;
@@ -21,12 +21,12 @@ export declare class TableHandlesView<BSchema extends BlockSchemaWithBlock<"tabl
21
21
  private readonly editor;
22
22
  private readonly pmView;
23
23
  state?: TableHandlesState<I, S>;
24
- updateState: () => void;
24
+ emitUpdate: () => void;
25
25
  tableId: string | undefined;
26
26
  tablePos: number | undefined;
27
27
  menuFrozen: boolean;
28
28
  prevWasEditable: boolean | null;
29
- constructor(editor: BlockNoteEditor<BSchema, I, S>, pmView: EditorView, updateState: (state: TableHandlesState<I, S>) => void);
29
+ constructor(editor: BlockNoteEditor<BlockSchemaWithBlock<"table", DefaultBlockSchema["table"]>, I, S>, pmView: EditorView, emitUpdate: (state: TableHandlesState<I, S>) => void);
30
30
  mouseMoveHandler: (event: MouseEvent) => false | undefined;
31
31
  dragOverHandler: (event: DragEvent) => void;
32
32
  dropHandler: (event: DragEvent) => void;
@@ -34,11 +34,11 @@ export declare class TableHandlesView<BSchema extends BlockSchemaWithBlock<"tabl
34
34
  destroy(): void;
35
35
  }
36
36
  export declare const tableHandlesPluginKey: PluginKey<any>;
37
- export declare class TableHandlesProsemirrorPlugin<BSchema extends BlockSchemaWithBlock<"table", DefaultBlockSchema["table"]>, I extends InlineContentSchema, S extends StyleSchema> extends EventEmitter<any> {
37
+ export declare class TableHandlesProsemirrorPlugin<I extends InlineContentSchema, S extends StyleSchema> extends EventEmitter<any> {
38
38
  private readonly editor;
39
39
  private view;
40
40
  readonly plugin: Plugin;
41
- constructor(editor: BlockNoteEditor<BSchema, I, S>);
41
+ constructor(editor: BlockNoteEditor<BlockSchemaWithBlock<"table", DefaultBlockSchema["table"]>, I, S>);
42
42
  onUpdate(callback: (state: TableHandlesState<I, S>) => void): () => void;
43
43
  /**
44
44
  * Callback that should be set on the `dragStart` event for whichever element
@@ -65,10 +65,10 @@ export declare class TableHandlesProsemirrorPlugin<BSchema extends BlockSchemaWi
65
65
  * Freezes the drag handles. When frozen, they will stay attached to the same
66
66
  * cell regardless of which cell is hovered by the mouse cursor.
67
67
  */
68
- freezeHandles: () => boolean;
68
+ freezeHandles: () => void;
69
69
  /**
70
70
  * Unfreezes the drag handles. When frozen, they will stay attached to the
71
71
  * same cell regardless of which cell is hovered by the mouse cursor.
72
72
  */
73
- unfreezeHandles: () => boolean;
73
+ unfreezeHandles: () => void;
74
74
  }
@@ -0,0 +1,4 @@
1
+ export type UiElementPosition = {
2
+ show: boolean;
3
+ referencePos: DOMRect;
4
+ };
@@ -2,21 +2,21 @@ export * from "./api/exporters/html/externalHTMLExporter";
2
2
  export * from "./api/exporters/html/internalHTMLSerializer";
3
3
  export * from "./api/testUtil";
4
4
  export * from "./blocks/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY";
5
+ export * from "./blocks/defaultBlockTypeGuards";
5
6
  export * from "./blocks/defaultBlocks";
6
7
  export * from "./blocks/defaultProps";
7
8
  export * from "./editor/BlockNoteEditor";
8
9
  export * from "./editor/BlockNoteExtensions";
10
+ export * from "./editor/BlockNoteSchema";
9
11
  export * from "./editor/selectionTypes";
10
- export * from "./extensions-shared/BaseUiElementTypes";
11
- export type { SuggestionItem } from "./extensions-shared/suggestion/SuggestionItem";
12
- export * from "./extensions-shared/suggestion/SuggestionPlugin";
12
+ export * from "./extensions-shared/UiElementPosition";
13
13
  export * from "./extensions/FormattingToolbar/FormattingToolbarPlugin";
14
- export * from "./extensions/HyperlinkToolbar/HyperlinkToolbarPlugin";
15
- export * from "./extensions/ImageToolbar/ImageToolbarPlugin";
14
+ export * from "./extensions/ImagePanel/ImageToolbarPlugin";
15
+ export * from "./extensions/LinkToolbar/LinkToolbarPlugin";
16
16
  export * from "./extensions/SideMenu/SideMenuPlugin";
17
- export * from "./extensions/SlashMenu/BaseSlashMenuItem";
18
- export * from "./extensions/SlashMenu/SlashMenuPlugin";
19
- export { getDefaultSlashMenuItems } from "./extensions/SlashMenu/defaultSlashMenuItems";
17
+ export * from "./extensions/SuggestionMenu/DefaultSuggestionItem";
18
+ export * from "./extensions/SuggestionMenu/SuggestionPlugin";
19
+ export * from "./extensions/SuggestionMenu/getDefaultSlashMenuItems";
20
20
  export * from "./extensions/TableHandles/TableHandlesPlugin";
21
21
  export * from "./schema";
22
22
  export * from "./util/browser";
@@ -1,6 +1,7 @@
1
1
  import { Node } from "@tiptap/core";
2
+ import { PartialBlock } from "../blocks/defaultBlocks";
2
3
  import type { BlockNoteEditor } from "../editor/BlockNoteEditor";
3
- import { BlockSchema, InlineContentSchema, PartialBlock, StyleSchema } from "../schema";
4
+ import { BlockSchema, InlineContentSchema, StyleSchema } from "../schema";
4
5
  declare module "@tiptap/core" {
5
6
  interface Commands<ReturnType> {
6
7
  block: {
@@ -18,8 +19,8 @@ declare module "@tiptap/core" {
18
19
  */
19
20
  export declare const BlockContainer: Node<{
20
21
  domAttributes?: Partial<{
21
- blockContainer: Record<string, string>;
22
22
  blockGroup: Record<string, string>;
23
+ block: Record<string, string>;
23
24
  editor: Record<string, string>;
24
25
  blockContent: Record<string, string>;
25
26
  inlineContent: Record<string, string>;
@@ -1,8 +1,8 @@
1
1
  import { Node } from "@tiptap/core";
2
2
  export declare const BlockGroup: Node<{
3
3
  domAttributes?: Partial<{
4
- blockContainer: Record<string, string>;
5
4
  blockGroup: Record<string, string>;
5
+ block: Record<string, string>;
6
6
  editor: Record<string, string>;
7
7
  blockContent: Record<string, string>;
8
8
  inlineContent: Record<string, string>;
@@ -1,10 +1,10 @@
1
1
  /** Define the main block types **/
2
- import { Extension, Node } from "@tiptap/core";
2
+ import type { Extension, Node } from "@tiptap/core";
3
3
  import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
4
- import { InlineContent, InlineContentSchema, PartialInlineContent } from "../inlineContent/types";
5
- import { PropSchema, Props } from "../propTypes";
6
- import { StyleSchema } from "../styles/types";
7
- export type BlockNoteDOMElement = "editor" | "blockContainer" | "blockGroup" | "blockContent" | "inlineContent";
4
+ import type { InlineContent, InlineContentSchema, PartialInlineContent } from "../inlineContent/types";
5
+ import type { PropSchema, Props } from "../propTypes";
6
+ import type { StyleSchema } from "../styles/types";
7
+ export type BlockNoteDOMElement = "editor" | "block" | "blockGroup" | "blockContent" | "inlineContent";
8
8
  export type BlockNoteDOMAttributes = Partial<{
9
9
  [DOMElement in BlockNoteDOMElement]: Record<string, string>;
10
10
  }>;
@@ -17,13 +17,13 @@ export type TiptapBlockImplementation<T extends BlockConfig, B extends BlockSche
17
17
  requiredExtensions?: Array<Extension | Node>;
18
18
  node: Node;
19
19
  toInternalHTML: (block: BlockFromConfigNoChildren<T, I, S> & {
20
- children: Block<B, I, S>[];
20
+ children: BlockNoDefaults<B, I, S>[];
21
21
  }, editor: BlockNoteEditor<B, I, S>) => {
22
22
  dom: HTMLElement;
23
23
  contentDOM?: HTMLElement;
24
24
  };
25
25
  toExternalHTML: (block: BlockFromConfigNoChildren<T, I, S> & {
26
- children: Block<B, I, S>[];
26
+ children: BlockNoDefaults<B, I, S>[];
27
27
  }, editor: BlockNoteEditor<B, I, S>) => {
28
28
  dom: HTMLElement;
29
29
  contentDOM?: HTMLElement;
@@ -60,16 +60,16 @@ export type BlockFromConfigNoChildren<B extends BlockConfig, I extends InlineCon
60
60
  content: B["content"] extends "inline" ? InlineContent<I, S>[] : B["content"] extends "table" ? TableContent<I, S> : B["content"] extends "none" ? undefined : never;
61
61
  };
62
62
  export type BlockFromConfig<B extends BlockConfig, I extends InlineContentSchema, S extends StyleSchema> = BlockFromConfigNoChildren<B, I, S> & {
63
- children: Block<BlockSchema, I, S>[];
63
+ children: BlockNoDefaults<BlockSchema, I, S>[];
64
64
  };
65
65
  type BlocksWithoutChildren<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema> = {
66
66
  [BType in keyof BSchema]: BlockFromConfigNoChildren<BSchema[BType], I, S>;
67
67
  };
68
- export type Block<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema> = BlocksWithoutChildren<BSchema, I, S>[keyof BSchema] & {
69
- children: Block<BSchema, I, S>[];
68
+ export type BlockNoDefaults<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema> = BlocksWithoutChildren<BSchema, I, S>[keyof BSchema] & {
69
+ children: BlockNoDefaults<BSchema, I, S>[];
70
70
  };
71
71
  export type SpecificBlock<BSchema extends BlockSchema, BType extends keyof BSchema, I extends InlineContentSchema, S extends StyleSchema> = BlocksWithoutChildren<BSchema, I, S>[BType] & {
72
- children: Block<BSchema, I, S>[];
72
+ children: BlockNoDefaults<BSchema, I, S>[];
73
73
  };
74
74
  /** CODE FOR PARTIAL BLOCKS, analogous to above
75
75
  *
@@ -92,14 +92,14 @@ type PartialBlockFromConfigNoChildren<B extends BlockConfig, I extends InlineCon
92
92
  type PartialBlocksWithoutChildren<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema> = {
93
93
  [BType in keyof BSchema]: PartialBlockFromConfigNoChildren<BSchema[BType], I, S>;
94
94
  };
95
- export type PartialBlock<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema> = PartialBlocksWithoutChildren<BSchema, I, S>[keyof PartialBlocksWithoutChildren<BSchema, I, S>] & Partial<{
96
- children: PartialBlock<BSchema, I, S>[];
95
+ export type PartialBlockNoDefaults<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema> = PartialBlocksWithoutChildren<BSchema, I, S>[keyof PartialBlocksWithoutChildren<BSchema, I, S>] & Partial<{
96
+ children: PartialBlockNoDefaults<BSchema, I, S>[];
97
97
  }>;
98
98
  export type SpecificPartialBlock<BSchema extends BlockSchema, I extends InlineContentSchema, BType extends keyof BSchema, S extends StyleSchema> = PartialBlocksWithoutChildren<BSchema, I, S>[BType] & {
99
- children?: Block<BSchema, I, S>[];
99
+ children?: BlockNoDefaults<BSchema, I, S>[];
100
100
  };
101
101
  export type PartialBlockFromConfig<B extends BlockConfig, I extends InlineContentSchema, S extends StyleSchema> = PartialBlockFromConfigNoChildren<B, I, S> & {
102
- children?: Block<BlockSchema, I, S>[];
102
+ children?: BlockNoDefaults<BlockSchema, I, S>[];
103
103
  };
104
104
  export type BlockIdentifier = {
105
105
  id: string;
@@ -37,7 +37,7 @@ export type InlineContentFromConfig<I extends InlineContentConfig, S extends Sty
37
37
  export type PartialCustomInlineContentFromConfig<I extends CustomInlineContentConfig, S extends StyleSchema> = {
38
38
  type: I["type"];
39
39
  props?: Props<I["propSchema"]>;
40
- content: I["content"] extends "styled" ? StyledText<S>[] | string : I["content"] extends "plain" ? string : I["content"] extends "none" ? undefined : never;
40
+ content?: I["content"] extends "styled" ? StyledText<S>[] | string : I["content"] extends "plain" ? string : I["content"] extends "none" ? undefined : never;
41
41
  };
42
42
  export type PartialInlineContentFromConfig<I extends InlineContentConfig, S extends StyleSchema> = I extends "text" ? string | StyledText<S> : I extends "link" ? PartialLink<S> : I extends CustomInlineContentConfig ? PartialCustomInlineContentFromConfig<I, S> : never;
43
43
  export type StyledText<T extends StyleSchema> = {
@@ -1,3 +1,4 @@
1
1
  export declare const isAppleOS: () => boolean;
2
2
  export declare function formatKeyboardShortcut(shortcut: string): string;
3
3
  export declare function mergeCSSClasses(...classes: string[]): string;
4
+ export declare const isSafari: () => boolean;
@@ -1,3 +1,4 @@
1
1
  export declare class UnreachableCaseError extends Error {
2
2
  constructor(val: never);
3
3
  }
4
+ export type NoInfer<T> = [T][T extends any ? 0 : never];
@@ -1,335 +0,0 @@
1
- import { getMarkRange, posToDOMRect, Range } from "@tiptap/core";
2
- import { EditorView } from "@tiptap/pm/view";
3
- import { Mark } from "prosemirror-model";
4
- import { Plugin, PluginKey } from "prosemirror-state";
5
- import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
6
- import { BaseUiElementState } from "../../extensions-shared/BaseUiElementTypes";
7
- import { BlockSchema, InlineContentSchema, StyleSchema } from "../../schema";
8
- import { EventEmitter } from "../../util/EventEmitter";
9
-
10
- export type HyperlinkToolbarState = BaseUiElementState & {
11
- // The hovered hyperlink's URL, and the text it's displayed with in the
12
- // editor.
13
- url: string;
14
- text: string;
15
- };
16
-
17
- class HyperlinkToolbarView {
18
- private hyperlinkToolbarState?: HyperlinkToolbarState;
19
- public updateHyperlinkToolbar: () => void;
20
-
21
- menuUpdateTimer: ReturnType<typeof setTimeout> | undefined;
22
- startMenuUpdateTimer: () => void;
23
- stopMenuUpdateTimer: () => void;
24
-
25
- mouseHoveredHyperlinkMark: Mark | undefined;
26
- mouseHoveredHyperlinkMarkRange: Range | undefined;
27
-
28
- keyboardHoveredHyperlinkMark: Mark | undefined;
29
- keyboardHoveredHyperlinkMarkRange: Range | undefined;
30
-
31
- hyperlinkMark: Mark | undefined;
32
- hyperlinkMarkRange: Range | undefined;
33
-
34
- constructor(
35
- private readonly editor: BlockNoteEditor<any, any, any>,
36
- private readonly pmView: EditorView,
37
- updateHyperlinkToolbar: (
38
- hyperlinkToolbarState: HyperlinkToolbarState
39
- ) => void
40
- ) {
41
- this.updateHyperlinkToolbar = () => {
42
- if (!this.hyperlinkToolbarState) {
43
- throw new Error("Attempting to update uninitialized hyperlink toolbar");
44
- }
45
-
46
- updateHyperlinkToolbar(this.hyperlinkToolbarState);
47
- };
48
-
49
- this.startMenuUpdateTimer = () => {
50
- this.menuUpdateTimer = setTimeout(() => {
51
- this.update();
52
- }, 250);
53
- };
54
-
55
- this.stopMenuUpdateTimer = () => {
56
- if (this.menuUpdateTimer) {
57
- clearTimeout(this.menuUpdateTimer);
58
- this.menuUpdateTimer = undefined;
59
- }
60
-
61
- return false;
62
- };
63
-
64
- this.pmView.dom.addEventListener("mouseover", this.mouseOverHandler);
65
- document.addEventListener("click", this.clickHandler, true);
66
- document.addEventListener("scroll", this.scrollHandler);
67
- }
68
-
69
- mouseOverHandler = (event: MouseEvent) => {
70
- // Resets the hyperlink mark currently hovered by the mouse cursor.
71
- this.mouseHoveredHyperlinkMark = undefined;
72
- this.mouseHoveredHyperlinkMarkRange = undefined;
73
-
74
- this.stopMenuUpdateTimer();
75
-
76
- if (
77
- event.target instanceof HTMLAnchorElement &&
78
- event.target.nodeName === "A"
79
- ) {
80
- // Finds link mark at the hovered element's position to update mouseHoveredHyperlinkMark and
81
- // mouseHoveredHyperlinkMarkRange.
82
- const hoveredHyperlinkElement = event.target;
83
- const posInHoveredHyperlinkMark =
84
- this.pmView.posAtDOM(hoveredHyperlinkElement, 0) + 1;
85
- const resolvedPosInHoveredHyperlinkMark = this.pmView.state.doc.resolve(
86
- posInHoveredHyperlinkMark
87
- );
88
- const marksAtPos = resolvedPosInHoveredHyperlinkMark.marks();
89
-
90
- for (const mark of marksAtPos) {
91
- if (
92
- mark.type.name === this.pmView.state.schema.mark("link").type.name
93
- ) {
94
- this.mouseHoveredHyperlinkMark = mark;
95
- this.mouseHoveredHyperlinkMarkRange =
96
- getMarkRange(
97
- resolvedPosInHoveredHyperlinkMark,
98
- mark.type,
99
- mark.attrs
100
- ) || undefined;
101
-
102
- break;
103
- }
104
- }
105
- }
106
-
107
- this.startMenuUpdateTimer();
108
-
109
- return false;
110
- };
111
-
112
- clickHandler = (event: MouseEvent) => {
113
- const editorWrapper = this.pmView.dom.parentElement!;
114
-
115
- if (
116
- // Toolbar is open.
117
- this.hyperlinkMark &&
118
- // An element is clicked.
119
- event &&
120
- event.target &&
121
- // The clicked element is not the editor.
122
- !(
123
- editorWrapper === (event.target as Node) ||
124
- editorWrapper.contains(event.target as Node)
125
- )
126
- ) {
127
- if (this.hyperlinkToolbarState?.show) {
128
- this.hyperlinkToolbarState.show = false;
129
- this.updateHyperlinkToolbar();
130
- }
131
- }
132
- };
133
-
134
- scrollHandler = () => {
135
- if (this.hyperlinkMark !== undefined) {
136
- if (this.hyperlinkToolbarState?.show) {
137
- this.hyperlinkToolbarState.referencePos = posToDOMRect(
138
- this.pmView,
139
- this.hyperlinkMarkRange!.from,
140
- this.hyperlinkMarkRange!.to
141
- );
142
- this.updateHyperlinkToolbar();
143
- }
144
- }
145
- };
146
-
147
- editHyperlink(url: string, text: string) {
148
- const tr = this.pmView.state.tr.insertText(
149
- text,
150
- this.hyperlinkMarkRange!.from,
151
- this.hyperlinkMarkRange!.to
152
- );
153
- tr.addMark(
154
- this.hyperlinkMarkRange!.from,
155
- this.hyperlinkMarkRange!.from + text.length,
156
- this.pmView.state.schema.mark("link", { href: url })
157
- );
158
- this.pmView.dispatch(tr);
159
- this.pmView.focus();
160
-
161
- if (this.hyperlinkToolbarState?.show) {
162
- this.hyperlinkToolbarState.show = false;
163
- this.updateHyperlinkToolbar();
164
- }
165
- }
166
-
167
- deleteHyperlink() {
168
- this.pmView.dispatch(
169
- this.pmView.state.tr
170
- .removeMark(
171
- this.hyperlinkMarkRange!.from,
172
- this.hyperlinkMarkRange!.to,
173
- this.hyperlinkMark!.type
174
- )
175
- .setMeta("preventAutolink", true)
176
- );
177
- this.pmView.focus();
178
-
179
- if (this.hyperlinkToolbarState?.show) {
180
- this.hyperlinkToolbarState.show = false;
181
- this.updateHyperlinkToolbar();
182
- }
183
- }
184
-
185
- update() {
186
- if (!this.pmView.hasFocus()) {
187
- return;
188
- }
189
-
190
- // Saves the currently hovered hyperlink mark before it's updated.
191
- const prevHyperlinkMark = this.hyperlinkMark;
192
-
193
- // Resets the currently hovered hyperlink mark.
194
- this.hyperlinkMark = undefined;
195
- this.hyperlinkMarkRange = undefined;
196
-
197
- // Resets the hyperlink mark currently hovered by the keyboard cursor.
198
- this.keyboardHoveredHyperlinkMark = undefined;
199
- this.keyboardHoveredHyperlinkMarkRange = undefined;
200
-
201
- // Finds link mark at the editor selection's position to update keyboardHoveredHyperlinkMark and
202
- // keyboardHoveredHyperlinkMarkRange.
203
- if (this.pmView.state.selection.empty) {
204
- const marksAtPos = this.pmView.state.selection.$from.marks();
205
-
206
- for (const mark of marksAtPos) {
207
- if (
208
- mark.type.name === this.pmView.state.schema.mark("link").type.name
209
- ) {
210
- this.keyboardHoveredHyperlinkMark = mark;
211
- this.keyboardHoveredHyperlinkMarkRange =
212
- getMarkRange(
213
- this.pmView.state.selection.$from,
214
- mark.type,
215
- mark.attrs
216
- ) || undefined;
217
-
218
- break;
219
- }
220
- }
221
- }
222
-
223
- if (this.mouseHoveredHyperlinkMark) {
224
- this.hyperlinkMark = this.mouseHoveredHyperlinkMark;
225
- this.hyperlinkMarkRange = this.mouseHoveredHyperlinkMarkRange;
226
- }
227
-
228
- // Keyboard cursor position takes precedence over mouse hovered hyperlink.
229
- if (this.keyboardHoveredHyperlinkMark) {
230
- this.hyperlinkMark = this.keyboardHoveredHyperlinkMark;
231
- this.hyperlinkMarkRange = this.keyboardHoveredHyperlinkMarkRange;
232
- }
233
-
234
- if (this.hyperlinkMark && this.editor.isEditable) {
235
- this.hyperlinkToolbarState = {
236
- show: true,
237
- referencePos: posToDOMRect(
238
- this.pmView,
239
- this.hyperlinkMarkRange!.from,
240
- this.hyperlinkMarkRange!.to
241
- ),
242
- url: this.hyperlinkMark!.attrs.href,
243
- text: this.pmView.state.doc.textBetween(
244
- this.hyperlinkMarkRange!.from,
245
- this.hyperlinkMarkRange!.to
246
- ),
247
- };
248
- this.updateHyperlinkToolbar();
249
-
250
- return;
251
- }
252
-
253
- // Hides menu.
254
- if (
255
- this.hyperlinkToolbarState?.show &&
256
- prevHyperlinkMark &&
257
- (!this.hyperlinkMark || !this.editor.isEditable)
258
- ) {
259
- this.hyperlinkToolbarState.show = false;
260
- this.updateHyperlinkToolbar();
261
-
262
- return;
263
- }
264
- }
265
-
266
- destroy() {
267
- this.pmView.dom.removeEventListener("mouseover", this.mouseOverHandler);
268
- document.removeEventListener("scroll", this.scrollHandler);
269
- document.removeEventListener("click", this.clickHandler, true);
270
- }
271
- }
272
-
273
- export const hyperlinkToolbarPluginKey = new PluginKey(
274
- "HyperlinkToolbarPlugin"
275
- );
276
-
277
- export class HyperlinkToolbarProsemirrorPlugin<
278
- BSchema extends BlockSchema,
279
- I extends InlineContentSchema,
280
- S extends StyleSchema
281
- > extends EventEmitter<any> {
282
- private view: HyperlinkToolbarView | undefined;
283
- public readonly plugin: Plugin;
284
-
285
- constructor(editor: BlockNoteEditor<BSchema, I, S>) {
286
- super();
287
- this.plugin = new Plugin({
288
- key: hyperlinkToolbarPluginKey,
289
- view: (editorView) => {
290
- this.view = new HyperlinkToolbarView(editor, editorView, (state) => {
291
- this.emit("update", state);
292
- });
293
- return this.view;
294
- },
295
- });
296
- }
297
-
298
- public onUpdate(callback: (state: HyperlinkToolbarState) => void) {
299
- return this.on("update", callback);
300
- }
301
-
302
- /**
303
- * Edit the currently hovered hyperlink.
304
- */
305
- public editHyperlink = (url: string, text: string) => {
306
- this.view!.editHyperlink(url, text);
307
- };
308
-
309
- /**
310
- * Delete the currently hovered hyperlink.
311
- */
312
- public deleteHyperlink = () => {
313
- this.view!.deleteHyperlink();
314
- };
315
-
316
- /**
317
- * When hovering on/off hyperlinks using the mouse cursor, the hyperlink
318
- * toolbar will open & close with a delay.
319
- *
320
- * This function starts the delay timer, and should be used for when the mouse cursor enters the hyperlink toolbar.
321
- */
322
- public startHideTimer = () => {
323
- this.view!.startMenuUpdateTimer();
324
- };
325
-
326
- /**
327
- * When hovering on/off hyperlinks using the mouse cursor, the hyperlink
328
- * toolbar will open & close with a delay.
329
- *
330
- * This function stops the delay timer, and should be used for when the mouse cursor exits the hyperlink toolbar.
331
- */
332
- public stopHideTimer = () => {
333
- this.view!.stopMenuUpdateTimer();
334
- };
335
- }
@@ -1,12 +0,0 @@
1
- import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
2
- import { SuggestionItem } from "../../extensions-shared/suggestion/SuggestionItem";
3
- import { BlockSchema, InlineContentSchema, StyleSchema } from "../../schema";
4
-
5
- export type BaseSlashMenuItem<
6
- BSchema extends BlockSchema,
7
- I extends InlineContentSchema,
8
- S extends StyleSchema
9
- > = SuggestionItem & {
10
- execute: (editor: BlockNoteEditor<BSchema, I, S>) => void;
11
- aliases?: string[];
12
- };
@@ -1,53 +0,0 @@
1
- import { Plugin, PluginKey } from "prosemirror-state";
2
-
3
- import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
4
- import {
5
- SuggestionsMenuState,
6
- setupSuggestionsMenu,
7
- } from "../../extensions-shared/suggestion/SuggestionPlugin";
8
- import { BlockSchema, InlineContentSchema, StyleSchema } from "../../schema";
9
- import { EventEmitter } from "../../util/EventEmitter";
10
- import { BaseSlashMenuItem } from "./BaseSlashMenuItem";
11
-
12
- export const slashMenuPluginKey = new PluginKey("SlashMenuPlugin");
13
-
14
- export class SlashMenuProsemirrorPlugin<
15
- BSchema extends BlockSchema,
16
- I extends InlineContentSchema,
17
- S extends StyleSchema,
18
- SlashMenuItem extends BaseSlashMenuItem<BSchema, I, S>
19
- > extends EventEmitter<any> {
20
- public readonly plugin: Plugin;
21
- public readonly itemCallback: (item: SlashMenuItem) => void;
22
-
23
- constructor(editor: BlockNoteEditor<BSchema, I, S>, items: SlashMenuItem[]) {
24
- super();
25
- const suggestions = setupSuggestionsMenu<SlashMenuItem, BSchema, I, S>(
26
- editor,
27
- (state) => {
28
- this.emit("update", state);
29
- },
30
- slashMenuPluginKey,
31
- "/",
32
- (query) =>
33
- items.filter(
34
- ({ name, aliases }: SlashMenuItem) =>
35
- name.toLowerCase().startsWith(query.toLowerCase()) ||
36
- (aliases &&
37
- aliases.filter((alias) =>
38
- alias.toLowerCase().startsWith(query.toLowerCase())
39
- ).length !== 0)
40
- ),
41
- ({ item, editor }) => item.execute(editor)
42
- );
43
-
44
- this.plugin = suggestions.plugin;
45
- this.itemCallback = suggestions.itemCallback;
46
- }
47
-
48
- public onUpdate(
49
- callback: (state: SuggestionsMenuState<SlashMenuItem>) => void
50
- ) {
51
- return this.on("update", callback);
52
- }
53
- }
@@ -1,8 +0,0 @@
1
- export type BaseUiElementCallbacks = {
2
- destroy: () => void;
3
- };
4
-
5
- export type BaseUiElementState = {
6
- show: boolean;
7
- referencePos: DOMRect;
8
- };
@@ -1,3 +0,0 @@
1
- ### @blocknote/core/src/extensions-shared
2
-
3
- Helper functions / base plugins for @blocknote/core/src/extensions
@@ -1,3 +0,0 @@
1
- export type SuggestionItem = {
2
- name: string;
3
- };