@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.
- package/README.md +13 -17
- package/dist/blocknote.js +1662 -1447
- 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/webpack-stats.json +1 -1
- package/package.json +7 -3
- package/src/api/blockManipulation/blockManipulation.test.ts +19 -15
- package/src/api/blockManipulation/blockManipulation.ts +107 -17
- package/src/api/exporters/html/externalHTMLExporter.ts +3 -7
- package/src/api/exporters/html/htmlConversion.test.ts +6 -3
- package/src/api/exporters/html/internalHTMLSerializer.ts +3 -7
- package/src/api/exporters/html/util/sharedHTMLConversion.ts +3 -3
- package/src/api/exporters/markdown/markdownExporter.test.ts +7 -3
- package/src/api/exporters/markdown/markdownExporter.ts +2 -6
- package/src/api/getCurrentBlockContentType.ts +14 -0
- package/src/api/nodeConversions/nodeConversions.test.ts +14 -7
- package/src/api/nodeConversions/nodeConversions.ts +1 -2
- package/src/api/parsers/html/parseHTML.test.ts +5 -1
- package/src/api/parsers/html/parseHTML.ts +2 -6
- package/src/api/parsers/html/util/nestedLists.ts +11 -1
- package/src/api/parsers/markdown/parseMarkdown.test.ts +3 -0
- package/src/api/parsers/markdown/parseMarkdown.ts +2 -6
- package/src/api/testUtil/cases/customBlocks.ts +18 -16
- package/src/api/testUtil/cases/customInlineContent.ts +12 -13
- package/src/api/testUtil/cases/customStyles.ts +12 -10
- package/src/api/testUtil/index.ts +4 -2
- package/src/api/testUtil/partialBlockTestUtil.ts +2 -6
- package/src/blocks/HeadingBlockContent/HeadingBlockContent.ts +50 -21
- package/src/blocks/ImageBlockContent/ImageBlockContent.ts +1 -2
- package/src/blocks/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.ts +8 -1
- package/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +18 -5
- package/src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.ts +7 -1
- package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +18 -5
- package/src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts +14 -5
- package/src/blocks/defaultBlockHelpers.ts +3 -3
- package/src/blocks/defaultBlockTypeGuards.ts +84 -0
- package/src/blocks/defaultBlocks.ts +29 -3
- package/src/editor/Block.css +2 -31
- package/src/editor/BlockNoteEditor.ts +223 -267
- package/src/editor/BlockNoteExtensions.ts +5 -2
- package/src/editor/BlockNoteSchema.ts +98 -0
- package/src/editor/BlockNoteTipTapEditor.ts +162 -0
- package/src/editor/cursorPositionTypes.ts +2 -6
- package/src/editor/editor.css +0 -1
- package/src/editor/selectionTypes.ts +2 -6
- package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +22 -29
- package/src/extensions/{ImageToolbar → ImagePanel}/ImageToolbarPlugin.ts +54 -60
- package/src/extensions/LinkToolbar/LinkToolbarPlugin.ts +330 -0
- package/src/extensions/Placeholder/PlaceholderExtension.ts +81 -88
- package/src/extensions/SideMenu/SideMenuPlugin.ts +55 -56
- package/src/extensions/SuggestionMenu/DefaultSuggestionItem.ts +8 -0
- package/src/extensions/SuggestionMenu/SuggestionPlugin.ts +353 -0
- package/src/extensions/{SlashMenu/defaultSlashMenuItems.ts → SuggestionMenu/getDefaultSlashMenuItems.ts} +119 -89
- package/src/extensions/TableHandles/TableHandlesPlugin.ts +62 -45
- package/src/extensions-shared/UiElementPosition.ts +4 -0
- package/src/index.ts +8 -8
- package/src/pm-nodes/BlockContainer.ts +5 -5
- package/src/schema/blocks/types.ts +15 -15
- package/src/schema/inlineContent/createSpec.ts +2 -2
- package/src/schema/inlineContent/types.ts +1 -1
- package/src/util/browser.ts +6 -4
- package/src/util/typescript.ts +7 -4
- package/types/src/api/blockManipulation/blockManipulation.d.ts +6 -1
- package/types/src/api/exporters/html/externalHTMLExporter.d.ts +2 -1
- package/types/src/api/exporters/html/internalHTMLSerializer.d.ts +2 -1
- package/types/src/api/exporters/markdown/markdownExporter.d.ts +2 -1
- package/types/src/api/getCurrentBlockContentType.d.ts +2 -0
- package/types/src/api/nodeConversions/nodeConversions.d.ts +2 -1
- package/types/src/api/parsers/html/parseHTML.d.ts +2 -1
- package/types/src/api/parsers/markdown/parseMarkdown.d.ts +2 -1
- package/types/src/api/testUtil/cases/customBlocks.d.ts +72 -13
- package/types/src/api/testUtil/cases/customInlineContent.d.ts +281 -6
- package/types/src/api/testUtil/cases/customStyles.d.ts +247 -13
- package/types/src/api/testUtil/index.d.ts +4 -2
- package/types/src/api/testUtil/partialBlockTestUtil.d.ts +2 -1
- package/types/src/blocks/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.d.ts +6 -1
- package/types/src/blocks/defaultBlockHelpers.d.ts +2 -2
- package/types/src/blocks/defaultBlockTypeGuards.d.ts +24 -0
- package/types/src/blocks/defaultBlocks.d.ts +21 -15
- package/types/src/editor/BlockNoteEditor.d.ts +51 -56
- package/types/src/editor/BlockNoteExtensions.d.ts +1 -0
- package/types/src/editor/BlockNoteSchema.d.ts +34 -0
- package/types/src/editor/BlockNoteTipTapEditor.d.ts +28 -0
- package/types/src/editor/cursorPositionTypes.d.ts +2 -1
- package/types/src/editor/selectionTypes.d.ts +2 -1
- package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +5 -6
- package/types/src/extensions/ImagePanel/ImageToolbarPlugin.d.ts +32 -0
- package/types/src/extensions/LinkToolbar/LinkToolbarPlugin.d.ts +40 -0
- package/types/src/extensions/Placeholder/PlaceholderExtension.d.ts +2 -15
- package/types/src/extensions/SideMenu/SideMenuPlugin.d.ts +8 -7
- package/types/src/extensions/SuggestionMenu/DefaultSuggestionItem.d.ts +8 -0
- package/types/src/extensions/SuggestionMenu/SuggestionPlugin.d.ts +31 -0
- package/types/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.d.ts +10 -0
- package/types/src/extensions/TableHandles/TableHandlesPlugin.d.ts +7 -7
- package/types/src/extensions-shared/UiElementPosition.d.ts +4 -0
- package/types/src/index.d.ts +8 -8
- package/types/src/pm-nodes/BlockContainer.d.ts +3 -2
- package/types/src/pm-nodes/BlockGroup.d.ts +1 -1
- package/types/src/schema/blocks/types.d.ts +15 -15
- package/types/src/schema/inlineContent/types.d.ts +1 -1
- package/types/src/util/browser.d.ts +1 -0
- package/types/src/util/typescript.d.ts +1 -0
- package/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts +0 -335
- package/src/extensions/SlashMenu/BaseSlashMenuItem.ts +0 -12
- package/src/extensions/SlashMenu/SlashMenuPlugin.ts +0 -53
- package/src/extensions-shared/BaseUiElementTypes.ts +0 -8
- package/src/extensions-shared/README.md +0 -3
- package/src/extensions-shared/suggestion/SuggestionItem.ts +0 -3
- package/src/extensions-shared/suggestion/SuggestionPlugin.ts +0 -448
- package/types/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.d.ts +0 -38
- package/types/src/extensions/ImageToolbar/ImageToolbarPlugin.d.ts +0 -31
- package/types/src/extensions/SlashMenu/BaseSlashMenuItem.d.ts +0 -7
- package/types/src/extensions/SlashMenu/SlashMenuPlugin.d.ts +0 -13
- package/types/src/extensions/SlashMenu/defaultSlashMenuItems.d.ts +0 -3
- package/types/src/extensions-shared/BaseUiElementTypes.d.ts +0 -7
- package/types/src/extensions-shared/suggestion/SuggestionItem.d.ts +0 -3
- package/types/src/extensions-shared/suggestion/SuggestionPlugin.d.ts +0 -36
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-100.woff +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-100.woff2 +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-200.woff +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-200.woff2 +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-300.woff +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-300.woff2 +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-500.woff +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-500.woff2 +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-600.woff +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-600.woff2 +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-700.woff +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-700.woff2 +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-800.woff +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-800.woff2 +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-900.woff +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-900.woff2 +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-regular.woff +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-regular.woff2 +0 -0
- /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
|
-
|
|
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<
|
|
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<
|
|
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<
|
|
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: () =>
|
|
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: () =>
|
|
73
|
+
unfreezeHandles: () => void;
|
|
74
74
|
}
|
package/types/src/index.d.ts
CHANGED
|
@@ -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/
|
|
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/
|
|
15
|
-
export * from "./extensions/
|
|
14
|
+
export * from "./extensions/ImagePanel/ImageToolbarPlugin";
|
|
15
|
+
export * from "./extensions/LinkToolbar/LinkToolbarPlugin";
|
|
16
16
|
export * from "./extensions/SideMenu/SideMenuPlugin";
|
|
17
|
-
export * from "./extensions/
|
|
18
|
-
export * from "./extensions/
|
|
19
|
-
export
|
|
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,
|
|
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" | "
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
69
|
-
children:
|
|
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:
|
|
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
|
|
96
|
-
children:
|
|
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?:
|
|
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?:
|
|
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
|
|
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,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
|
-
}
|