@blocknote/core 0.1.1 → 0.2.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/README.md +12 -6
- package/dist/blocknote.js +1425 -5114
- package/dist/blocknote.js.map +1 -1
- package/dist/blocknote.umd.cjs +1 -53
- package/dist/blocknote.umd.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +3 -16
- package/src/BlockNoteEditor.ts +54 -0
- package/src/BlockNoteExtensions.ts +52 -7
- package/src/assets/fonts-inter.css +92 -0
- package/src/editor.module.css +37 -0
- package/src/extensions/Blocks/BlockAttributes.ts +1 -3
- package/src/extensions/Blocks/PreviousBlockTypePlugin.ts +71 -18
- package/src/extensions/Blocks/helpers/getBlockInfoFromPos.ts +66 -0
- package/src/extensions/Blocks/index.ts +7 -3
- package/src/extensions/Blocks/nodes/Block.module.css +116 -74
- package/src/extensions/Blocks/nodes/Block.ts +415 -292
- package/src/extensions/Blocks/nodes/BlockGroup.ts +6 -6
- package/src/extensions/Blocks/nodes/BlockTypes/HeadingBlock/HeadingContent.ts +84 -0
- package/src/extensions/Blocks/nodes/BlockTypes/ListItemBlock/ListItemContent.ts +177 -0
- package/src/extensions/Blocks/nodes/BlockTypes/ListItemBlock/OrderedListItemIndexPlugin.ts +77 -0
- package/src/extensions/Blocks/nodes/BlockTypes/TextBlock/TextContent.ts +34 -0
- package/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.ts +20 -0
- package/src/extensions/DraggableBlocks/DraggableBlocksExtension.ts +27 -9
- package/src/extensions/DraggableBlocks/{DraggableBlocksPlugin.tsx → DraggableBlocksPlugin.ts} +227 -147
- package/src/extensions/FormattingToolbar/FormattingToolbarExtension.ts +29 -0
- package/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.ts +35 -0
- package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +308 -0
- package/src/extensions/HyperlinkToolbar/HyperlinkMark.ts +28 -0
- package/src/extensions/HyperlinkToolbar/HyperlinkToolbarFactoryTypes.ts +19 -0
- package/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts +251 -0
- package/src/extensions/Placeholder/PlaceholderExtension.ts +2 -2
- package/src/extensions/SlashMenu/SlashMenuExtension.ts +9 -1
- package/src/extensions/SlashMenu/SlashMenuItem.ts +1 -3
- package/src/extensions/SlashMenu/defaultCommands.tsx +33 -22
- package/src/extensions/TrailingNode/TrailingNodeExtension.ts +4 -4
- package/src/extensions/UniqueID/UniqueID.ts +14 -12
- package/src/index.ts +8 -4
- package/src/shared/EditorElement.ts +10 -0
- package/src/shared/plugins/suggestion/SuggestionItem.ts +1 -8
- package/src/shared/plugins/suggestion/SuggestionPlugin.ts +222 -101
- package/src/shared/plugins/suggestion/SuggestionsMenuFactoryTypes.ts +21 -0
- package/src/{utils.ts → shared/utils.ts} +0 -0
- package/types/src/BlockNoteEditor.d.ts +13 -0
- package/types/src/BlockNoteExtensions.d.ts +12 -1
- package/types/src/EditorElement.d.ts +7 -0
- package/types/src/extensions/Blocks/PreviousBlockTypePlugin.d.ts +1 -1
- package/types/src/extensions/Blocks/helpers/getBlockInfoFromPos.d.ts +19 -0
- package/types/src/extensions/Blocks/nodes/Block.d.ts +11 -19
- package/types/src/extensions/Blocks/nodes/BlockTypes/HeadingBlock/HeadingContent.d.ts +8 -0
- package/types/src/extensions/Blocks/nodes/BlockTypes/ListItemBlock/ListItemContent.d.ts +8 -0
- package/types/src/extensions/Blocks/nodes/BlockTypes/ListItemBlock/OrderedListItemIndexPlugin.d.ts +2 -0
- package/types/src/extensions/Blocks/nodes/BlockTypes/TextBlock/TextContent.d.ts +6 -0
- package/types/src/extensions/BubbleMenu/BubbleMenuExtension.d.ts +4 -1
- package/types/src/extensions/BubbleMenu/BubbleMenuFactoryTypes.d.ts +27 -0
- package/types/src/extensions/BubbleMenu/BubbleMenuPlugin.d.ts +10 -12
- package/types/src/extensions/DraggableBlocks/BlockMenuFactoryTypes.d.ts +12 -0
- package/types/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.d.ts +14 -0
- package/types/src/extensions/DraggableBlocks/DragMenuFactoryTypes.d.ts +18 -0
- package/types/src/extensions/DraggableBlocks/DraggableBlocksExtension.d.ts +9 -3
- package/types/src/extensions/DraggableBlocks/DraggableBlocksPlugin.d.ts +23 -1
- package/types/src/extensions/FormattingToolbar/FormattingToolbarExtension.d.ts +8 -0
- package/types/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.d.ts +23 -0
- package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +43 -0
- package/types/src/extensions/HyperlinkToolbar/HyperlinkMark.d.ts +8 -0
- package/types/src/extensions/HyperlinkToolbar/HyperlinkToolbarFactoryTypes.d.ts +12 -0
- package/types/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.d.ts +11 -0
- package/types/src/extensions/Hyperlinks/HyperlinkMark.d.ts +2 -1
- package/types/src/extensions/Hyperlinks/HyperlinkMenuFactoryTypes.d.ts +11 -0
- package/types/src/extensions/Hyperlinks/HyperlinkMenuPlugin.d.ts +10 -1
- package/types/src/extensions/SlashMenu/SlashMenuExtension.d.ts +3 -1
- package/types/src/extensions/SlashMenu/SlashMenuItem.d.ts +2 -4
- package/types/src/index.d.ts +8 -3
- package/types/src/shared/EditorElement.d.ts +6 -0
- package/types/src/shared/plugins/suggestion/SuggestionItem.d.ts +1 -6
- package/types/src/shared/plugins/suggestion/SuggestionPlugin.d.ts +15 -10
- package/types/src/shared/plugins/suggestion/SuggestionsMenuFactoryTypes.d.ts +12 -0
- package/types/src/shared/utils.d.ts +2 -0
- package/types/src/utils.d.ts +2 -2
- package/src/BlockNoteTheme.ts +0 -150
- package/src/EditorContent.tsx +0 -2
- package/src/extensions/Blocks/OrderedListPlugin.ts +0 -46
- package/src/extensions/Blocks/commands/joinBackward.ts +0 -274
- package/src/extensions/Blocks/helpers/setBlockHeading.ts +0 -30
- package/src/extensions/Blocks/nodes/Content.ts +0 -63
- package/src/extensions/Blocks/rule.ts +0 -48
- package/src/extensions/BubbleMenu/BubbleMenuExtension.tsx +0 -36
- package/src/extensions/BubbleMenu/BubbleMenuPlugin.ts +0 -245
- package/src/extensions/BubbleMenu/component/BubbleMenu.tsx +0 -240
- package/src/extensions/BubbleMenu/component/LinkToolbarButton.tsx +0 -67
- package/src/extensions/DraggableBlocks/components/DragHandle.tsx +0 -102
- package/src/extensions/DraggableBlocks/components/DragHandleMenu.tsx +0 -19
- package/src/extensions/Hyperlinks/HyperlinkMark.tsx +0 -16
- package/src/extensions/Hyperlinks/HyperlinkMenuPlugin.tsx +0 -165
- package/src/extensions/Hyperlinks/menus/EditHyperlinkMenu.tsx +0 -44
- package/src/extensions/Hyperlinks/menus/EditHyperlinkMenuItem.tsx +0 -34
- package/src/extensions/Hyperlinks/menus/EditHyperlinkMenuItemIcon.tsx +0 -31
- package/src/extensions/Hyperlinks/menus/EditHyperlinkMenuItemInput.tsx +0 -40
- package/src/extensions/Hyperlinks/menus/HoverHyperlinkMenu.tsx +0 -37
- package/src/extensions/Hyperlinks/menus/HyperlinkMenu.tsx +0 -63
- package/src/fonts-inter.css +0 -94
- package/src/globals.css +0 -28
- package/src/root.module.css +0 -19
- package/src/shared/components/toolbar/Toolbar.tsx +0 -10
- package/src/shared/components/toolbar/ToolbarButton.tsx +0 -57
- package/src/shared/components/toolbar/ToolbarDropdown.tsx +0 -35
- package/src/shared/components/toolbar/ToolbarDropdownItem.tsx +0 -35
- package/src/shared/components/toolbar/ToolbarDropdownTarget.tsx +0 -31
- package/src/shared/components/tooltip/TooltipContent.module.css +0 -15
- package/src/shared/components/tooltip/TooltipContent.tsx +0 -23
- package/src/shared/hooks/useEditorForceUpdate.tsx +0 -30
- package/src/shared/plugins/suggestion/SuggestionListReactRenderer.tsx +0 -236
- package/src/shared/plugins/suggestion/components/SuggestionGroup.tsx +0 -47
- package/src/shared/plugins/suggestion/components/SuggestionGroupItem.tsx +0 -82
- package/src/shared/plugins/suggestion/components/SuggestionList.tsx +0 -92
- package/src/useEditor.ts +0 -51
- package/types/src/BlockNoteTheme.d.ts +0 -2
- package/types/src/EditorContent.d.ts +0 -1
- package/types/src/commands/indentation.d.ts +0 -2
- package/types/src/extensions/Blocks/OrderedListPlugin.d.ts +0 -2
- package/types/src/extensions/Blocks/commands/joinBackward.d.ts +0 -14
- package/types/src/extensions/Blocks/helpers/setBlockHeading.d.ts +0 -5
- package/types/src/extensions/Blocks/nodes/Content.d.ts +0 -5
- package/types/src/extensions/Blocks/rule.d.ts +0 -16
- package/types/src/extensions/BubbleMenu/component/BubbleMenu.d.ts +0 -5
- package/types/src/extensions/BubbleMenu/component/DropdownBlockItem.d.ts +0 -10
- package/types/src/extensions/BubbleMenu/component/LinkToolbarButton.d.ts +0 -11
- package/types/src/extensions/DraggableBlocks/components/DragHandle.d.ts +0 -12
- package/types/src/extensions/DraggableBlocks/components/DragHandleMenu.d.ts +0 -6
- package/types/src/extensions/Hyperlinks/menus/EditHyperlinkMenu.d.ts +0 -11
- package/types/src/extensions/Hyperlinks/menus/EditHyperlinkMenuItem.d.ts +0 -13
- package/types/src/extensions/Hyperlinks/menus/EditHyperlinkMenuItemIcon.d.ts +0 -8
- package/types/src/extensions/Hyperlinks/menus/EditHyperlinkMenuItemInput.d.ts +0 -9
- package/types/src/extensions/Hyperlinks/menus/HoverHyperlinkMenu.d.ts +0 -12
- package/types/src/extensions/Hyperlinks/menus/HyperlinkBasicMenu.d.ts +0 -12
- package/types/src/extensions/Hyperlinks/menus/HyperlinkEditMenu.d.ts +0 -10
- package/types/src/extensions/Hyperlinks/menus/HyperlinkMenu.d.ts +0 -21
- package/types/src/extensions/Hyperlinks/menus/atlaskit/PanelTextInput.d.ts +0 -39
- package/types/src/extensions/Hyperlinks/menus/atlaskit/PanelTextInputStyles.d.ts +0 -1
- package/types/src/extensions/Hyperlinks/menus/atlaskit/ToolbarComponent.d.ts +0 -11
- package/types/src/extensions/Hyperlinks/menus/helpers/PanelTextInput.d.ts +0 -39
- package/types/src/extensions/Hyperlinks/menus/helpers/PanelTextInputStyles.d.ts +0 -3
- package/types/src/extensions/Hyperlinks/menus/helpers/ToolbarComponent.d.ts +0 -13
- package/types/src/extensions/helpers/formatKeyboardShortcut.d.ts +0 -1
- package/types/src/lib/atlaskit/browser.d.ts +0 -12
- package/types/src/nodes/ChildgroupNode.d.ts +0 -28
- package/types/src/nodes/patchNodes.d.ts +0 -1
- package/types/src/plugins/TreeViewPlugin/index.d.ts +0 -2
- package/types/src/plugins/animation.d.ts +0 -2
- package/types/src/react/BlockNoteComposer.d.ts +0 -17
- package/types/src/react/BlockNotePlugin.d.ts +0 -1
- package/types/src/react/index.d.ts +0 -3
- package/types/src/react/useBlockNoteSetup.d.ts +0 -2
- package/types/src/registerBlockNote.d.ts +0 -2
- package/types/src/shared/components/toolbar/SimpleToolbarButton.d.ts +0 -15
- package/types/src/shared/components/toolbar/SimpleToolbarDropdown.d.ts +0 -11
- package/types/src/shared/components/toolbar/SimpleToolbarDropdownItem.d.ts +0 -11
- package/types/src/shared/components/toolbar/Toolbar.d.ts +0 -4
- package/types/src/shared/components/toolbar/ToolbarButton.d.ts +0 -15
- package/types/src/shared/components/toolbar/ToolbarDropdown.d.ts +0 -17
- package/types/src/shared/components/toolbar/ToolbarDropdownItem.d.ts +0 -11
- package/types/src/shared/components/toolbar/ToolbarDropdownTarget.d.ts +0 -8
- package/types/src/shared/components/toolbar/ToolbarSeparator.d.ts +0 -2
- package/types/src/shared/components/tooltip/TooltipContent.d.ts +0 -15
- package/types/src/shared/hooks/useEditorForceUpdate.d.ts +0 -2
- package/types/src/shared/plugins/suggestion/SuggestionListReactRenderer.d.ts +0 -71
- package/types/src/shared/plugins/suggestion/components/SuggestionGroup.d.ts +0 -23
- package/types/src/shared/plugins/suggestion/components/SuggestionGroupItem.d.ts +0 -9
- package/types/src/shared/plugins/suggestion/components/SuggestionList.d.ts +0 -11
- package/types/src/themes/BlockNoteEditorTheme.d.ts +0 -11
- package/types/src/useEditor.d.ts +0 -11
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"homepage": "https://github.com/yousefed/blocknote",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.2.0",
|
|
7
7
|
"files": [
|
|
8
8
|
"dist",
|
|
9
9
|
"types",
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"scripts": {
|
|
42
42
|
"dev": "vite",
|
|
43
43
|
"build": "tsc && vite build",
|
|
44
|
+
"build-bundled": "tsc && vite build --config vite.config.bundled.ts && git checkout tmp-releases && rm -rf ../../release && mv ../../release-tmp ../../release",
|
|
44
45
|
"preview": "vite preview",
|
|
45
46
|
"lint": "eslint src --max-warnings 0"
|
|
46
47
|
},
|
|
@@ -48,8 +49,6 @@
|
|
|
48
49
|
"@emotion/cache": "^11.10.5",
|
|
49
50
|
"@emotion/serialize": "^1.1.1",
|
|
50
51
|
"@emotion/utils": "^1.2.0",
|
|
51
|
-
"@mantine/core": "^5.6.1",
|
|
52
|
-
"@tippyjs/react": "^4.2.6",
|
|
53
52
|
"@tiptap/core": "^2.0.0-beta.182",
|
|
54
53
|
"@tiptap/extension-bold": "^2.0.0-beta.28",
|
|
55
54
|
"@tiptap/extension-code": "^2.0.0-beta.28",
|
|
@@ -66,26 +65,14 @@
|
|
|
66
65
|
"@tiptap/extension-strike": "^2.0.0-beta.29",
|
|
67
66
|
"@tiptap/extension-text": "^2.0.0-beta.17",
|
|
68
67
|
"@tiptap/extension-underline": "^2.0.0-beta.25",
|
|
69
|
-
"@tiptap/react": "^2.0.0-beta.114",
|
|
70
68
|
"lodash": "^4.17.21",
|
|
71
69
|
"prosemirror-model": "1.18.1",
|
|
72
70
|
"prosemirror-state": "1.4.1",
|
|
73
71
|
"prosemirror-view": "1.26.2",
|
|
74
|
-
"react": "^17.0.2",
|
|
75
|
-
"react-dom": "^17.0.2",
|
|
76
|
-
"react-icons": "^4.3.1",
|
|
77
|
-
"styled-components": "^5.3.3",
|
|
78
72
|
"uuid": "^8.3.2"
|
|
79
73
|
},
|
|
80
|
-
"overrides": {
|
|
81
|
-
"react-dom": "$react-dom",
|
|
82
|
-
"react": "$react"
|
|
83
|
-
},
|
|
84
74
|
"devDependencies": {
|
|
85
75
|
"@types/lodash": "^4.14.179",
|
|
86
|
-
"@types/react": "^17.0.39",
|
|
87
|
-
"@types/react-dom": "^17.0.12",
|
|
88
|
-
"@types/styled-components": "^5.1.24",
|
|
89
76
|
"@types/uuid": "^8.3.4",
|
|
90
77
|
"eslint": "^8.10.0",
|
|
91
78
|
"eslint-config-react-app": "^7.0.0",
|
|
@@ -107,5 +94,5 @@
|
|
|
107
94
|
"access": "public",
|
|
108
95
|
"registry": "https://registry.npmjs.org/"
|
|
109
96
|
},
|
|
110
|
-
"gitHead": "
|
|
97
|
+
"gitHead": "5ccf86c22d62e87813d4314a5f9f0b24d8e1c9d5"
|
|
111
98
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Editor, EditorOptions } from "@tiptap/core";
|
|
2
|
+
|
|
3
|
+
// import "./blocknote.css";
|
|
4
|
+
import { getBlockNoteExtensions, UiFactories } from "./BlockNoteExtensions";
|
|
5
|
+
import styles from "./editor.module.css";
|
|
6
|
+
|
|
7
|
+
export type BlockNoteEditorOptions = EditorOptions & {
|
|
8
|
+
enableBlockNoteExtensions: boolean;
|
|
9
|
+
disableHistoryExtension: boolean;
|
|
10
|
+
uiFactories: UiFactories;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const blockNoteOptions = {
|
|
14
|
+
enableInputRules: true,
|
|
15
|
+
enablePasteRules: true,
|
|
16
|
+
enableCoreExtensions: false,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export class BlockNoteEditor {
|
|
20
|
+
public readonly tiptapEditor: Editor & { contentComponent: any };
|
|
21
|
+
|
|
22
|
+
constructor(options: Partial<BlockNoteEditorOptions> = {}) {
|
|
23
|
+
const blockNoteExtensions = getBlockNoteExtensions(
|
|
24
|
+
options.uiFactories || {}
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
let extensions = options.disableHistoryExtension
|
|
28
|
+
? blockNoteExtensions.filter((e) => e.name !== "history")
|
|
29
|
+
: blockNoteExtensions;
|
|
30
|
+
|
|
31
|
+
const tiptapOptions = {
|
|
32
|
+
...blockNoteOptions,
|
|
33
|
+
...options,
|
|
34
|
+
extensions:
|
|
35
|
+
options.enableBlockNoteExtensions === false
|
|
36
|
+
? options.extensions
|
|
37
|
+
: [...(options.extensions || []), ...extensions],
|
|
38
|
+
editorProps: {
|
|
39
|
+
attributes: {
|
|
40
|
+
...(options.editorProps?.attributes || {}),
|
|
41
|
+
class: [
|
|
42
|
+
styles.bnEditor,
|
|
43
|
+
styles.bnRoot,
|
|
44
|
+
(options.editorProps?.attributes as any)?.class || "",
|
|
45
|
+
].join(" "),
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
this.tiptapEditor = new Editor(tiptapOptions) as Editor & {
|
|
51
|
+
contentComponent: any;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -13,14 +13,20 @@ import Text from "@tiptap/extension-text";
|
|
|
13
13
|
import Underline from "@tiptap/extension-underline";
|
|
14
14
|
import { blocks } from "./extensions/Blocks";
|
|
15
15
|
import blockStyles from "./extensions/Blocks/nodes/Block.module.css";
|
|
16
|
-
import {
|
|
16
|
+
import { FormattingToolbarExtension } from "./extensions/FormattingToolbar/FormattingToolbarExtension";
|
|
17
17
|
import { DraggableBlocksExtension } from "./extensions/DraggableBlocks/DraggableBlocksExtension";
|
|
18
|
-
import HyperlinkMark from "./extensions/
|
|
18
|
+
import HyperlinkMark from "./extensions/HyperlinkToolbar/HyperlinkMark";
|
|
19
19
|
import { FixedParagraph } from "./extensions/Paragraph/FixedParagraph";
|
|
20
20
|
import { Placeholder } from "./extensions/Placeholder/PlaceholderExtension";
|
|
21
21
|
import SlashMenuExtension from "./extensions/SlashMenu";
|
|
22
22
|
import { TrailingNode } from "./extensions/TrailingNode/TrailingNodeExtension";
|
|
23
23
|
import UniqueID from "./extensions/UniqueID/UniqueID";
|
|
24
|
+
import { FormattingToolbarFactory } from "./extensions/FormattingToolbar/FormattingToolbarFactoryTypes";
|
|
25
|
+
import { HyperlinkToolbarFactory } from "./extensions/HyperlinkToolbar/HyperlinkToolbarFactoryTypes";
|
|
26
|
+
import { SuggestionsMenuFactory } from "./shared/plugins/suggestion/SuggestionsMenuFactoryTypes";
|
|
27
|
+
import { BlockSideMenuFactory } from "./extensions/DraggableBlocks/BlockSideMenuFactoryTypes";
|
|
28
|
+
import { Link } from "@tiptap/extension-link";
|
|
29
|
+
import { SlashMenuItem } from "./extensions/SlashMenu/SlashMenuItem";
|
|
24
30
|
|
|
25
31
|
export const Document = Node.create({
|
|
26
32
|
name: "doc",
|
|
@@ -28,10 +34,17 @@ export const Document = Node.create({
|
|
|
28
34
|
content: "block+",
|
|
29
35
|
});
|
|
30
36
|
|
|
37
|
+
export type UiFactories = Partial<{
|
|
38
|
+
formattingToolbarFactory: FormattingToolbarFactory;
|
|
39
|
+
hyperlinkToolbarFactory: HyperlinkToolbarFactory;
|
|
40
|
+
slashMenuFactory: SuggestionsMenuFactory<SlashMenuItem>;
|
|
41
|
+
blockSideMenuFactory: BlockSideMenuFactory;
|
|
42
|
+
}>;
|
|
43
|
+
|
|
31
44
|
/**
|
|
32
45
|
* Get all the Tiptap extensions BlockNote is configured with by default
|
|
33
46
|
*/
|
|
34
|
-
export const getBlockNoteExtensions = () => {
|
|
47
|
+
export const getBlockNoteExtensions = (uiFactories: UiFactories) => {
|
|
35
48
|
const ret: Extensions = [
|
|
36
49
|
extensions.ClipboardTextSerializer,
|
|
37
50
|
extensions.Commands,
|
|
@@ -65,19 +78,51 @@ export const getBlockNoteExtensions = () => {
|
|
|
65
78
|
Italic,
|
|
66
79
|
Strike,
|
|
67
80
|
Underline,
|
|
68
|
-
HyperlinkMark,
|
|
69
81
|
FixedParagraph,
|
|
70
82
|
|
|
71
83
|
// custom blocks:
|
|
72
84
|
...blocks,
|
|
73
|
-
|
|
85
|
+
|
|
74
86
|
DropCursor.configure({ width: 5, color: "#ddeeff" }),
|
|
75
|
-
BubbleMenuExtension,
|
|
76
87
|
History,
|
|
77
88
|
// This needs to be at the bottom of this list, because Key events (such as enter, when selecting a /command),
|
|
78
89
|
// should be handled before Enter handlers in other components like splitListItem
|
|
79
|
-
SlashMenuExtension,
|
|
80
90
|
TrailingNode,
|
|
81
91
|
];
|
|
92
|
+
|
|
93
|
+
if (uiFactories.blockSideMenuFactory) {
|
|
94
|
+
ret.push(
|
|
95
|
+
DraggableBlocksExtension.configure({
|
|
96
|
+
blockSideMenuFactory: uiFactories.blockSideMenuFactory,
|
|
97
|
+
})
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (uiFactories.formattingToolbarFactory) {
|
|
102
|
+
ret.push(
|
|
103
|
+
FormattingToolbarExtension.configure({
|
|
104
|
+
formattingToolbarFactory: uiFactories.formattingToolbarFactory,
|
|
105
|
+
})
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (uiFactories.hyperlinkToolbarFactory) {
|
|
110
|
+
ret.push(
|
|
111
|
+
HyperlinkMark.configure({
|
|
112
|
+
hyperlinkToolbarFactory: uiFactories.hyperlinkToolbarFactory,
|
|
113
|
+
})
|
|
114
|
+
);
|
|
115
|
+
} else {
|
|
116
|
+
ret.push(Link);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (uiFactories.slashMenuFactory) {
|
|
120
|
+
ret.push(
|
|
121
|
+
SlashMenuExtension.configure({
|
|
122
|
+
slashMenuFactory: uiFactories.slashMenuFactory,
|
|
123
|
+
})
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
82
127
|
return ret;
|
|
83
128
|
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/* Generated using https://google-webfonts-helper.herokuapp.com/fonts/inter?subsets=latin */
|
|
2
|
+
|
|
3
|
+
/* inter-100 - latin */
|
|
4
|
+
@font-face {
|
|
5
|
+
font-family: "Inter";
|
|
6
|
+
font-style: normal;
|
|
7
|
+
font-weight: 100;
|
|
8
|
+
src: local(""),
|
|
9
|
+
url("./inter-v12-latin/inter-v12-latin-100.woff2") format("woff2"),
|
|
10
|
+
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
|
11
|
+
url("./inter-v12-latin/inter-v12-latin-100.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
|
12
|
+
}
|
|
13
|
+
/* inter-200 - latin */
|
|
14
|
+
@font-face {
|
|
15
|
+
font-family: "Inter";
|
|
16
|
+
font-style: normal;
|
|
17
|
+
font-weight: 200;
|
|
18
|
+
src: local(""),
|
|
19
|
+
url("./inter-v12-latin/inter-v12-latin-200.woff2") format("woff2"),
|
|
20
|
+
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
|
21
|
+
url("./inter-v12-latin/inter-v12-latin-200.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
|
22
|
+
}
|
|
23
|
+
/* inter-300 - latin */
|
|
24
|
+
@font-face {
|
|
25
|
+
font-family: "Inter";
|
|
26
|
+
font-style: normal;
|
|
27
|
+
font-weight: 300;
|
|
28
|
+
src: local(""),
|
|
29
|
+
url("./inter-v12-latin/inter-v12-latin-300.woff2") format("woff2"),
|
|
30
|
+
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
|
31
|
+
url("./inter-v12-latin/inter-v12-latin-300.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
|
32
|
+
}
|
|
33
|
+
/* inter-regular - latin */
|
|
34
|
+
@font-face {
|
|
35
|
+
font-family: "Inter";
|
|
36
|
+
font-style: normal;
|
|
37
|
+
font-weight: 400;
|
|
38
|
+
src: local(""),
|
|
39
|
+
url("./inter-v12-latin/inter-v12-latin-regular.woff2") format("woff2"),
|
|
40
|
+
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
|
41
|
+
url("./inter-v12-latin/inter-v12-latin-regular.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
|
42
|
+
}
|
|
43
|
+
/* inter-500 - latin */
|
|
44
|
+
@font-face {
|
|
45
|
+
font-family: "Inter";
|
|
46
|
+
font-style: normal;
|
|
47
|
+
font-weight: 500;
|
|
48
|
+
src: local(""),
|
|
49
|
+
url("./inter-v12-latin/inter-v12-latin-500.woff2") format("woff2"),
|
|
50
|
+
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
|
51
|
+
url("./inter-v12-latin/inter-v12-latin-500.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
|
52
|
+
}
|
|
53
|
+
/* inter-600 - latin */
|
|
54
|
+
@font-face {
|
|
55
|
+
font-family: "Inter";
|
|
56
|
+
font-style: normal;
|
|
57
|
+
font-weight: 600;
|
|
58
|
+
src: local(""),
|
|
59
|
+
url("./inter-v12-latin/inter-v12-latin-600.woff2") format("woff2"),
|
|
60
|
+
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
|
61
|
+
url("./inter-v12-latin/inter-v12-latin-600.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
|
62
|
+
}
|
|
63
|
+
/* inter-700 - latin */
|
|
64
|
+
@font-face {
|
|
65
|
+
font-family: "Inter";
|
|
66
|
+
font-style: normal;
|
|
67
|
+
font-weight: 700;
|
|
68
|
+
src: local(""),
|
|
69
|
+
url("./inter-v12-latin/inter-v12-latin-700.woff2") format("woff2"),
|
|
70
|
+
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
|
71
|
+
url("./inter-v12-latin/inter-v12-latin-700.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
|
72
|
+
}
|
|
73
|
+
/* inter-800 - latin */
|
|
74
|
+
@font-face {
|
|
75
|
+
font-family: "Inter";
|
|
76
|
+
font-style: normal;
|
|
77
|
+
font-weight: 800;
|
|
78
|
+
src: local(""),
|
|
79
|
+
url("./inter-v12-latin/inter-v12-latin-800.woff2") format("woff2"),
|
|
80
|
+
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
|
81
|
+
url("./inter-v12-latin/inter-v12-latin-800.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
|
82
|
+
}
|
|
83
|
+
/* inter-900 - latin */
|
|
84
|
+
@font-face {
|
|
85
|
+
font-family: "Inter";
|
|
86
|
+
font-style: normal;
|
|
87
|
+
font-weight: 900;
|
|
88
|
+
src: local(""),
|
|
89
|
+
url("./inter-v12-latin/inter-v12-latin-900.woff2") format("woff2"),
|
|
90
|
+
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
|
91
|
+
url("./inter-v12-latin/inter-v12-latin-900.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
|
92
|
+
}
|
package/src/editor.module.css
CHANGED
|
@@ -1,3 +1,40 @@
|
|
|
1
|
+
@import url("./assets/fonts-inter.css");
|
|
2
|
+
|
|
1
3
|
.bnEditor {
|
|
2
4
|
outline: none;
|
|
3
5
|
}
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
bnRoot should be applied to all top-level elements
|
|
9
|
+
|
|
10
|
+
This includes the Prosemirror editor, but also <div> element such as
|
|
11
|
+
Tippy popups that are appended to document.body directly
|
|
12
|
+
*/
|
|
13
|
+
.bnRoot {
|
|
14
|
+
-webkit-box-sizing: border-box;
|
|
15
|
+
-moz-box-sizing: border-box;
|
|
16
|
+
box-sizing: border-box;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.bnRoot *,
|
|
20
|
+
.bnRoot *::before,
|
|
21
|
+
.bnRoot *::after {
|
|
22
|
+
-webkit-box-sizing: inherit;
|
|
23
|
+
-moz-box-sizing: inherit;
|
|
24
|
+
box-sizing: inherit;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.bnEditor, .dragPreview {
|
|
28
|
+
/* Define a set of colors to be used throughout the app for consistency
|
|
29
|
+
see https://atlassian.design/foundations/color for more info */
|
|
30
|
+
--N800: #172b4d; /* Dark neutral used for tooltips and text on light background */
|
|
31
|
+
--N40: #dfe1e6; /* Light neutral used for subtle borders and text on dark background */
|
|
32
|
+
|
|
33
|
+
font-family: "Inter", "SF Pro Display", -apple-system, BlinkMacSystemFont,
|
|
34
|
+
"Open Sans", "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell",
|
|
35
|
+
"Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
|
|
36
|
+
-webkit-font-smoothing: antialiased;
|
|
37
|
+
-moz-osx-font-smoothing: grayscale;
|
|
38
|
+
|
|
39
|
+
color: rgb(60, 65, 73);
|
|
40
|
+
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
// Object containing all possible block attributes.
|
|
2
2
|
const BlockAttributes: Record<string, string> = {
|
|
3
|
-
listType: "data-list-type",
|
|
4
3
|
blockColor: "data-block-color",
|
|
5
4
|
blockStyle: "data-block-style",
|
|
6
|
-
headingType: "data-heading-type",
|
|
7
5
|
id: "data-id",
|
|
8
6
|
depth: "data-depth",
|
|
9
7
|
depthChange: "data-depth-change",
|
|
10
8
|
};
|
|
11
9
|
|
|
12
|
-
export default BlockAttributes;
|
|
10
|
+
export default BlockAttributes;
|
|
@@ -5,18 +5,22 @@ import {
|
|
|
5
5
|
} from "@tiptap/core";
|
|
6
6
|
import { Plugin, PluginKey } from "prosemirror-state";
|
|
7
7
|
import { Decoration, DecorationSet } from "prosemirror-view";
|
|
8
|
-
import BlockAttributes from "./BlockAttributes";
|
|
9
8
|
|
|
10
9
|
const PLUGIN_KEY = new PluginKey(`previous-blocks`);
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
const nodeAttributes: Record<string, string> = {
|
|
12
|
+
listItemType: "list-item-type",
|
|
13
|
+
listItemIndex: "list-item-index",
|
|
14
|
+
headingLevel: "heading-level",
|
|
15
|
+
type: "type",
|
|
16
|
+
depth: "depth",
|
|
17
|
+
"depth-change": "depth-change",
|
|
18
|
+
};
|
|
15
19
|
|
|
16
20
|
/**
|
|
17
21
|
* This plugin tracks transformation of Block node attributes, so we can support CSS transitions.
|
|
18
22
|
*
|
|
19
|
-
* Problem it solves:
|
|
23
|
+
* Problem it solves: ProseMirror recreates the DOM when transactions happen. So when a transaction changes a Node attribute,
|
|
20
24
|
* it results in a completely new DOM element. This means CSS transitions don't work.
|
|
21
25
|
*
|
|
22
26
|
* Solution: When attributes change on a node, this plugin sets a data-* attribute with the "previous" value. This way we can still use CSS transitions. (See block.module.css)
|
|
@@ -75,7 +79,6 @@ export const PreviousBlockTypePlugin = () => {
|
|
|
75
79
|
|
|
76
80
|
changes.forEach(() => {
|
|
77
81
|
const oldNodes = findChildren(oldState.doc, (node) => node.attrs.id);
|
|
78
|
-
|
|
79
82
|
const oldNodesById = new Map(
|
|
80
83
|
oldNodes.map((node) => [node.node.attrs.id, node])
|
|
81
84
|
);
|
|
@@ -84,28 +87,68 @@ export const PreviousBlockTypePlugin = () => {
|
|
|
84
87
|
|
|
85
88
|
for (let node of newNodes) {
|
|
86
89
|
const oldNode = oldNodesById.get(node.node.attrs.id);
|
|
87
|
-
|
|
90
|
+
const oldContentNode = oldNode?.node.firstChild;
|
|
91
|
+
const newContentNode = node.node.firstChild;
|
|
92
|
+
if (oldNode && oldContentNode && newContentNode) {
|
|
88
93
|
const newAttrs = {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
94
|
+
listItemType: newContentNode.attrs.listItemType,
|
|
95
|
+
listItemIndex: newContentNode.attrs.listItemIndex,
|
|
96
|
+
headingLevel: newContentNode.attrs.headingLevel,
|
|
97
|
+
type: newContentNode.type.name,
|
|
93
98
|
depth: newState.doc.resolve(node.pos).depth,
|
|
94
99
|
};
|
|
95
100
|
|
|
96
101
|
const oldAttrs = {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
102
|
+
listItemType: oldContentNode.attrs.listItemType,
|
|
103
|
+
listItemIndex: oldContentNode.attrs.listItemIndex,
|
|
104
|
+
headingLevel: oldContentNode.attrs.headingLevel,
|
|
105
|
+
type: oldContentNode.type.name,
|
|
101
106
|
depth: oldState.doc.resolve(oldNode.pos).depth,
|
|
102
107
|
};
|
|
103
108
|
|
|
109
|
+
// Hacky fix to avoid processing certain transactions created by ordered list indexing plugin.
|
|
110
|
+
|
|
111
|
+
// True when an existing ordered list item is assigned an index for the first time, which happens
|
|
112
|
+
// immediately after it's created. Using this condition to start an animation ensures it's not
|
|
113
|
+
// immediately overridden by a different transaction created by the ordered list indexing plugin.
|
|
114
|
+
const indexInitialized =
|
|
115
|
+
oldAttrs.listItemIndex === null &&
|
|
116
|
+
newAttrs.listItemIndex !== null;
|
|
117
|
+
|
|
118
|
+
// True when an existing ordered list item changes nesting levels, before its index is updated by the
|
|
119
|
+
// ordered list indexing plugin. This condition ensures that animations for indentation still work with
|
|
120
|
+
// ordered list items, while preventing unnecessary animations being done when dragging/dropping them.
|
|
121
|
+
const depthChanged =
|
|
122
|
+
oldAttrs.listItemIndex !== null &&
|
|
123
|
+
newAttrs.listItemIndex !== null &&
|
|
124
|
+
oldAttrs.listItemIndex === newAttrs.listItemIndex;
|
|
125
|
+
|
|
126
|
+
// Only false for transactions in which the block remains an ordered list item before & after, but neither
|
|
127
|
+
// of the previous conditions apply.
|
|
128
|
+
const shouldUpdate =
|
|
129
|
+
oldAttrs.listItemType === "ordered" &&
|
|
130
|
+
newAttrs.listItemType === "ordered"
|
|
131
|
+
? indexInitialized || depthChanged
|
|
132
|
+
: true;
|
|
133
|
+
|
|
104
134
|
if (
|
|
105
|
-
JSON.stringify(oldAttrs) !== JSON.stringify(newAttrs) // TODO: faster deep equal?
|
|
135
|
+
JSON.stringify(oldAttrs) !== JSON.stringify(newAttrs) && // TODO: faster deep equal?
|
|
136
|
+
shouldUpdate
|
|
106
137
|
) {
|
|
107
|
-
(oldAttrs as any)
|
|
138
|
+
(oldAttrs as any)["depth-change"] =
|
|
139
|
+
oldAttrs.depth - newAttrs.depth;
|
|
108
140
|
prev.prevBlockAttrs[node.node.attrs.id] = oldAttrs;
|
|
141
|
+
|
|
142
|
+
// for debugging:
|
|
143
|
+
console.log(
|
|
144
|
+
"id:",
|
|
145
|
+
node.node.attrs.id,
|
|
146
|
+
"previousBlockTypePlugin changes detected, oldAttrs",
|
|
147
|
+
oldAttrs,
|
|
148
|
+
"new",
|
|
149
|
+
newAttrs
|
|
150
|
+
);
|
|
151
|
+
|
|
109
152
|
prev.needsUpdate = true;
|
|
110
153
|
}
|
|
111
154
|
}
|
|
@@ -119,6 +162,7 @@ export const PreviousBlockTypePlugin = () => {
|
|
|
119
162
|
decorations(state) {
|
|
120
163
|
const pluginState = (this as Plugin).getState(state);
|
|
121
164
|
if (!pluginState.needsUpdate) {
|
|
165
|
+
// console.log("0");
|
|
122
166
|
return undefined;
|
|
123
167
|
}
|
|
124
168
|
|
|
@@ -126,18 +170,27 @@ export const PreviousBlockTypePlugin = () => {
|
|
|
126
170
|
|
|
127
171
|
state.doc.descendants((node, pos) => {
|
|
128
172
|
if (!node.attrs.id) {
|
|
173
|
+
// console.log("1");
|
|
129
174
|
return;
|
|
130
175
|
}
|
|
131
176
|
const prevAttrs = pluginState.prevBlockAttrs[node.attrs.id];
|
|
132
177
|
if (!prevAttrs) {
|
|
178
|
+
// console.log("2");
|
|
133
179
|
return;
|
|
134
180
|
}
|
|
135
181
|
|
|
136
182
|
const decorationAttributes: any = {};
|
|
137
183
|
for (let [nodeAttr, val] of Object.entries(prevAttrs)) {
|
|
138
|
-
decorationAttributes[
|
|
184
|
+
decorationAttributes["data-prev-" + nodeAttributes[nodeAttr]] =
|
|
139
185
|
val || "none";
|
|
140
186
|
}
|
|
187
|
+
|
|
188
|
+
// for debugging:
|
|
189
|
+
console.log(
|
|
190
|
+
"previousBlockTypePlugin committing decorations",
|
|
191
|
+
decorationAttributes
|
|
192
|
+
);
|
|
193
|
+
|
|
141
194
|
const decoration = Decoration.node(pos, pos + node.nodeSize, {
|
|
142
195
|
...decorationAttributes,
|
|
143
196
|
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Node, NodeType } from "prosemirror-model";
|
|
2
|
+
|
|
3
|
+
export type BlockInfo = {
|
|
4
|
+
id: string;
|
|
5
|
+
node: Node;
|
|
6
|
+
contentNode: Node;
|
|
7
|
+
contentType: NodeType;
|
|
8
|
+
numChildBlocks: number;
|
|
9
|
+
startPos: number;
|
|
10
|
+
endPos: number;
|
|
11
|
+
depth: number;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Retrieves information regarding the most nested block node in a ProseMirror doc, that a given position lies in.
|
|
16
|
+
* @param doc The ProseMirror doc.
|
|
17
|
+
* @param posInBlock A position somewhere within a block node.
|
|
18
|
+
* @returns A BlockInfo object for the block the given position is in, or undefined if the position is not in a block
|
|
19
|
+
* for the given doc.
|
|
20
|
+
*/
|
|
21
|
+
export function getBlockInfoFromPos(
|
|
22
|
+
doc: Node,
|
|
23
|
+
posInBlock: number
|
|
24
|
+
): BlockInfo | undefined {
|
|
25
|
+
if (posInBlock <= 0 || posInBlock > doc.nodeSize) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const $pos = doc.resolve(posInBlock);
|
|
30
|
+
|
|
31
|
+
const maxDepth = $pos.depth;
|
|
32
|
+
let node = $pos.node(maxDepth);
|
|
33
|
+
let depth = maxDepth;
|
|
34
|
+
|
|
35
|
+
while (depth >= 0) {
|
|
36
|
+
// If the outermost node is not a block, it means the position does not lie within a block.
|
|
37
|
+
if (depth === 0) {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
if (node.type.name === "block") {
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
depth -= 1;
|
|
45
|
+
node = $pos.node(depth);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const id = node.attrs["id"];
|
|
49
|
+
const contentNode = node.firstChild!;
|
|
50
|
+
const contentType = contentNode.type;
|
|
51
|
+
const numChildBlocks = node.childCount === 2 ? node.lastChild!.childCount : 0;
|
|
52
|
+
|
|
53
|
+
const startPos = $pos.start(depth);
|
|
54
|
+
const endPos = $pos.end(depth);
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
id,
|
|
58
|
+
node,
|
|
59
|
+
contentNode,
|
|
60
|
+
contentType,
|
|
61
|
+
numChildBlocks,
|
|
62
|
+
startPos,
|
|
63
|
+
endPos,
|
|
64
|
+
depth,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { Node } from "@tiptap/core";
|
|
2
2
|
import { Block } from "./nodes/Block";
|
|
3
3
|
import { BlockGroup } from "./nodes/BlockGroup";
|
|
4
|
-
import {
|
|
4
|
+
import { TextContent } from "./nodes/BlockTypes/TextBlock/TextContent";
|
|
5
|
+
import { HeadingContent } from "./nodes/BlockTypes/HeadingBlock/HeadingContent";
|
|
6
|
+
import { ListItemContent } from "./nodes/BlockTypes/ListItemBlock/ListItemContent";
|
|
5
7
|
|
|
6
8
|
export const blocks: any[] = [
|
|
7
|
-
|
|
9
|
+
TextContent,
|
|
10
|
+
HeadingContent,
|
|
11
|
+
ListItemContent,
|
|
8
12
|
Block,
|
|
9
13
|
BlockGroup,
|
|
10
14
|
Node.create({
|
|
11
15
|
name: "doc",
|
|
12
16
|
topNode: true,
|
|
13
|
-
content: "
|
|
17
|
+
content: "blockGroup",
|
|
14
18
|
}),
|
|
15
19
|
];
|