@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.
Files changed (171) hide show
  1. package/README.md +12 -6
  2. package/dist/blocknote.js +1425 -5114
  3. package/dist/blocknote.js.map +1 -1
  4. package/dist/blocknote.umd.cjs +1 -53
  5. package/dist/blocknote.umd.cjs.map +1 -1
  6. package/dist/style.css +1 -1
  7. package/package.json +3 -16
  8. package/src/BlockNoteEditor.ts +54 -0
  9. package/src/BlockNoteExtensions.ts +52 -7
  10. package/src/assets/fonts-inter.css +92 -0
  11. package/src/editor.module.css +37 -0
  12. package/src/extensions/Blocks/BlockAttributes.ts +1 -3
  13. package/src/extensions/Blocks/PreviousBlockTypePlugin.ts +71 -18
  14. package/src/extensions/Blocks/helpers/getBlockInfoFromPos.ts +66 -0
  15. package/src/extensions/Blocks/index.ts +7 -3
  16. package/src/extensions/Blocks/nodes/Block.module.css +116 -74
  17. package/src/extensions/Blocks/nodes/Block.ts +415 -292
  18. package/src/extensions/Blocks/nodes/BlockGroup.ts +6 -6
  19. package/src/extensions/Blocks/nodes/BlockTypes/HeadingBlock/HeadingContent.ts +84 -0
  20. package/src/extensions/Blocks/nodes/BlockTypes/ListItemBlock/ListItemContent.ts +177 -0
  21. package/src/extensions/Blocks/nodes/BlockTypes/ListItemBlock/OrderedListItemIndexPlugin.ts +77 -0
  22. package/src/extensions/Blocks/nodes/BlockTypes/TextBlock/TextContent.ts +34 -0
  23. package/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.ts +20 -0
  24. package/src/extensions/DraggableBlocks/DraggableBlocksExtension.ts +27 -9
  25. package/src/extensions/DraggableBlocks/{DraggableBlocksPlugin.tsx → DraggableBlocksPlugin.ts} +227 -147
  26. package/src/extensions/FormattingToolbar/FormattingToolbarExtension.ts +29 -0
  27. package/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.ts +35 -0
  28. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +308 -0
  29. package/src/extensions/HyperlinkToolbar/HyperlinkMark.ts +28 -0
  30. package/src/extensions/HyperlinkToolbar/HyperlinkToolbarFactoryTypes.ts +19 -0
  31. package/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts +251 -0
  32. package/src/extensions/Placeholder/PlaceholderExtension.ts +2 -2
  33. package/src/extensions/SlashMenu/SlashMenuExtension.ts +9 -1
  34. package/src/extensions/SlashMenu/SlashMenuItem.ts +1 -3
  35. package/src/extensions/SlashMenu/defaultCommands.tsx +33 -22
  36. package/src/extensions/TrailingNode/TrailingNodeExtension.ts +4 -4
  37. package/src/extensions/UniqueID/UniqueID.ts +14 -12
  38. package/src/index.ts +8 -4
  39. package/src/shared/EditorElement.ts +10 -0
  40. package/src/shared/plugins/suggestion/SuggestionItem.ts +1 -8
  41. package/src/shared/plugins/suggestion/SuggestionPlugin.ts +222 -101
  42. package/src/shared/plugins/suggestion/SuggestionsMenuFactoryTypes.ts +21 -0
  43. package/src/{utils.ts → shared/utils.ts} +0 -0
  44. package/types/src/BlockNoteEditor.d.ts +13 -0
  45. package/types/src/BlockNoteExtensions.d.ts +12 -1
  46. package/types/src/EditorElement.d.ts +7 -0
  47. package/types/src/extensions/Blocks/PreviousBlockTypePlugin.d.ts +1 -1
  48. package/types/src/extensions/Blocks/helpers/getBlockInfoFromPos.d.ts +19 -0
  49. package/types/src/extensions/Blocks/nodes/Block.d.ts +11 -19
  50. package/types/src/extensions/Blocks/nodes/BlockTypes/HeadingBlock/HeadingContent.d.ts +8 -0
  51. package/types/src/extensions/Blocks/nodes/BlockTypes/ListItemBlock/ListItemContent.d.ts +8 -0
  52. package/types/src/extensions/Blocks/nodes/BlockTypes/ListItemBlock/OrderedListItemIndexPlugin.d.ts +2 -0
  53. package/types/src/extensions/Blocks/nodes/BlockTypes/TextBlock/TextContent.d.ts +6 -0
  54. package/types/src/extensions/BubbleMenu/BubbleMenuExtension.d.ts +4 -1
  55. package/types/src/extensions/BubbleMenu/BubbleMenuFactoryTypes.d.ts +27 -0
  56. package/types/src/extensions/BubbleMenu/BubbleMenuPlugin.d.ts +10 -12
  57. package/types/src/extensions/DraggableBlocks/BlockMenuFactoryTypes.d.ts +12 -0
  58. package/types/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.d.ts +14 -0
  59. package/types/src/extensions/DraggableBlocks/DragMenuFactoryTypes.d.ts +18 -0
  60. package/types/src/extensions/DraggableBlocks/DraggableBlocksExtension.d.ts +9 -3
  61. package/types/src/extensions/DraggableBlocks/DraggableBlocksPlugin.d.ts +23 -1
  62. package/types/src/extensions/FormattingToolbar/FormattingToolbarExtension.d.ts +8 -0
  63. package/types/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.d.ts +23 -0
  64. package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +43 -0
  65. package/types/src/extensions/HyperlinkToolbar/HyperlinkMark.d.ts +8 -0
  66. package/types/src/extensions/HyperlinkToolbar/HyperlinkToolbarFactoryTypes.d.ts +12 -0
  67. package/types/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.d.ts +11 -0
  68. package/types/src/extensions/Hyperlinks/HyperlinkMark.d.ts +2 -1
  69. package/types/src/extensions/Hyperlinks/HyperlinkMenuFactoryTypes.d.ts +11 -0
  70. package/types/src/extensions/Hyperlinks/HyperlinkMenuPlugin.d.ts +10 -1
  71. package/types/src/extensions/SlashMenu/SlashMenuExtension.d.ts +3 -1
  72. package/types/src/extensions/SlashMenu/SlashMenuItem.d.ts +2 -4
  73. package/types/src/index.d.ts +8 -3
  74. package/types/src/shared/EditorElement.d.ts +6 -0
  75. package/types/src/shared/plugins/suggestion/SuggestionItem.d.ts +1 -6
  76. package/types/src/shared/plugins/suggestion/SuggestionPlugin.d.ts +15 -10
  77. package/types/src/shared/plugins/suggestion/SuggestionsMenuFactoryTypes.d.ts +12 -0
  78. package/types/src/shared/utils.d.ts +2 -0
  79. package/types/src/utils.d.ts +2 -2
  80. package/src/BlockNoteTheme.ts +0 -150
  81. package/src/EditorContent.tsx +0 -2
  82. package/src/extensions/Blocks/OrderedListPlugin.ts +0 -46
  83. package/src/extensions/Blocks/commands/joinBackward.ts +0 -274
  84. package/src/extensions/Blocks/helpers/setBlockHeading.ts +0 -30
  85. package/src/extensions/Blocks/nodes/Content.ts +0 -63
  86. package/src/extensions/Blocks/rule.ts +0 -48
  87. package/src/extensions/BubbleMenu/BubbleMenuExtension.tsx +0 -36
  88. package/src/extensions/BubbleMenu/BubbleMenuPlugin.ts +0 -245
  89. package/src/extensions/BubbleMenu/component/BubbleMenu.tsx +0 -240
  90. package/src/extensions/BubbleMenu/component/LinkToolbarButton.tsx +0 -67
  91. package/src/extensions/DraggableBlocks/components/DragHandle.tsx +0 -102
  92. package/src/extensions/DraggableBlocks/components/DragHandleMenu.tsx +0 -19
  93. package/src/extensions/Hyperlinks/HyperlinkMark.tsx +0 -16
  94. package/src/extensions/Hyperlinks/HyperlinkMenuPlugin.tsx +0 -165
  95. package/src/extensions/Hyperlinks/menus/EditHyperlinkMenu.tsx +0 -44
  96. package/src/extensions/Hyperlinks/menus/EditHyperlinkMenuItem.tsx +0 -34
  97. package/src/extensions/Hyperlinks/menus/EditHyperlinkMenuItemIcon.tsx +0 -31
  98. package/src/extensions/Hyperlinks/menus/EditHyperlinkMenuItemInput.tsx +0 -40
  99. package/src/extensions/Hyperlinks/menus/HoverHyperlinkMenu.tsx +0 -37
  100. package/src/extensions/Hyperlinks/menus/HyperlinkMenu.tsx +0 -63
  101. package/src/fonts-inter.css +0 -94
  102. package/src/globals.css +0 -28
  103. package/src/root.module.css +0 -19
  104. package/src/shared/components/toolbar/Toolbar.tsx +0 -10
  105. package/src/shared/components/toolbar/ToolbarButton.tsx +0 -57
  106. package/src/shared/components/toolbar/ToolbarDropdown.tsx +0 -35
  107. package/src/shared/components/toolbar/ToolbarDropdownItem.tsx +0 -35
  108. package/src/shared/components/toolbar/ToolbarDropdownTarget.tsx +0 -31
  109. package/src/shared/components/tooltip/TooltipContent.module.css +0 -15
  110. package/src/shared/components/tooltip/TooltipContent.tsx +0 -23
  111. package/src/shared/hooks/useEditorForceUpdate.tsx +0 -30
  112. package/src/shared/plugins/suggestion/SuggestionListReactRenderer.tsx +0 -236
  113. package/src/shared/plugins/suggestion/components/SuggestionGroup.tsx +0 -47
  114. package/src/shared/plugins/suggestion/components/SuggestionGroupItem.tsx +0 -82
  115. package/src/shared/plugins/suggestion/components/SuggestionList.tsx +0 -92
  116. package/src/useEditor.ts +0 -51
  117. package/types/src/BlockNoteTheme.d.ts +0 -2
  118. package/types/src/EditorContent.d.ts +0 -1
  119. package/types/src/commands/indentation.d.ts +0 -2
  120. package/types/src/extensions/Blocks/OrderedListPlugin.d.ts +0 -2
  121. package/types/src/extensions/Blocks/commands/joinBackward.d.ts +0 -14
  122. package/types/src/extensions/Blocks/helpers/setBlockHeading.d.ts +0 -5
  123. package/types/src/extensions/Blocks/nodes/Content.d.ts +0 -5
  124. package/types/src/extensions/Blocks/rule.d.ts +0 -16
  125. package/types/src/extensions/BubbleMenu/component/BubbleMenu.d.ts +0 -5
  126. package/types/src/extensions/BubbleMenu/component/DropdownBlockItem.d.ts +0 -10
  127. package/types/src/extensions/BubbleMenu/component/LinkToolbarButton.d.ts +0 -11
  128. package/types/src/extensions/DraggableBlocks/components/DragHandle.d.ts +0 -12
  129. package/types/src/extensions/DraggableBlocks/components/DragHandleMenu.d.ts +0 -6
  130. package/types/src/extensions/Hyperlinks/menus/EditHyperlinkMenu.d.ts +0 -11
  131. package/types/src/extensions/Hyperlinks/menus/EditHyperlinkMenuItem.d.ts +0 -13
  132. package/types/src/extensions/Hyperlinks/menus/EditHyperlinkMenuItemIcon.d.ts +0 -8
  133. package/types/src/extensions/Hyperlinks/menus/EditHyperlinkMenuItemInput.d.ts +0 -9
  134. package/types/src/extensions/Hyperlinks/menus/HoverHyperlinkMenu.d.ts +0 -12
  135. package/types/src/extensions/Hyperlinks/menus/HyperlinkBasicMenu.d.ts +0 -12
  136. package/types/src/extensions/Hyperlinks/menus/HyperlinkEditMenu.d.ts +0 -10
  137. package/types/src/extensions/Hyperlinks/menus/HyperlinkMenu.d.ts +0 -21
  138. package/types/src/extensions/Hyperlinks/menus/atlaskit/PanelTextInput.d.ts +0 -39
  139. package/types/src/extensions/Hyperlinks/menus/atlaskit/PanelTextInputStyles.d.ts +0 -1
  140. package/types/src/extensions/Hyperlinks/menus/atlaskit/ToolbarComponent.d.ts +0 -11
  141. package/types/src/extensions/Hyperlinks/menus/helpers/PanelTextInput.d.ts +0 -39
  142. package/types/src/extensions/Hyperlinks/menus/helpers/PanelTextInputStyles.d.ts +0 -3
  143. package/types/src/extensions/Hyperlinks/menus/helpers/ToolbarComponent.d.ts +0 -13
  144. package/types/src/extensions/helpers/formatKeyboardShortcut.d.ts +0 -1
  145. package/types/src/lib/atlaskit/browser.d.ts +0 -12
  146. package/types/src/nodes/ChildgroupNode.d.ts +0 -28
  147. package/types/src/nodes/patchNodes.d.ts +0 -1
  148. package/types/src/plugins/TreeViewPlugin/index.d.ts +0 -2
  149. package/types/src/plugins/animation.d.ts +0 -2
  150. package/types/src/react/BlockNoteComposer.d.ts +0 -17
  151. package/types/src/react/BlockNotePlugin.d.ts +0 -1
  152. package/types/src/react/index.d.ts +0 -3
  153. package/types/src/react/useBlockNoteSetup.d.ts +0 -2
  154. package/types/src/registerBlockNote.d.ts +0 -2
  155. package/types/src/shared/components/toolbar/SimpleToolbarButton.d.ts +0 -15
  156. package/types/src/shared/components/toolbar/SimpleToolbarDropdown.d.ts +0 -11
  157. package/types/src/shared/components/toolbar/SimpleToolbarDropdownItem.d.ts +0 -11
  158. package/types/src/shared/components/toolbar/Toolbar.d.ts +0 -4
  159. package/types/src/shared/components/toolbar/ToolbarButton.d.ts +0 -15
  160. package/types/src/shared/components/toolbar/ToolbarDropdown.d.ts +0 -17
  161. package/types/src/shared/components/toolbar/ToolbarDropdownItem.d.ts +0 -11
  162. package/types/src/shared/components/toolbar/ToolbarDropdownTarget.d.ts +0 -8
  163. package/types/src/shared/components/toolbar/ToolbarSeparator.d.ts +0 -2
  164. package/types/src/shared/components/tooltip/TooltipContent.d.ts +0 -15
  165. package/types/src/shared/hooks/useEditorForceUpdate.d.ts +0 -2
  166. package/types/src/shared/plugins/suggestion/SuggestionListReactRenderer.d.ts +0 -71
  167. package/types/src/shared/plugins/suggestion/components/SuggestionGroup.d.ts +0 -23
  168. package/types/src/shared/plugins/suggestion/components/SuggestionGroupItem.d.ts +0 -9
  169. package/types/src/shared/plugins/suggestion/components/SuggestionList.d.ts +0 -11
  170. package/types/src/themes/BlockNoteEditorTheme.d.ts +0 -11
  171. package/types/src/useEditor.d.ts +0 -11
@@ -1,2 +1,2 @@
1
- export declare const isAppleOS: () => boolean;
2
- export declare function formatKeyboardShortcut(shortcut: string): string;
1
+ export const isAppleOS: () => boolean;
2
+ export function formatKeyboardShortcut(shortcut: string): string;
@@ -1,150 +0,0 @@
1
- import { MantineThemeOverride } from "@mantine/core";
2
-
3
- export const BlockNoteTheme: MantineThemeOverride = {
4
- activeStyles: {
5
- // Removes button press effect.
6
- transform: "none",
7
- },
8
- colorScheme: "light",
9
- colors: {
10
- brandFinal: [
11
- "#F6F6F8",
12
- "#ECEDF0",
13
- "#DFE1E6",
14
- "#C2C7D0",
15
- "#A6ADBA",
16
- "#8993A4",
17
- "#6D798F",
18
- "#505F79",
19
- "#344563",
20
- "#172B4D",
21
- ],
22
- },
23
- components: {
24
- Menu: {
25
- styles: (theme) => ({
26
- dropdown: {
27
- backgroundColor: "white",
28
- boxShadow: `0px 4px 8px ${theme.colors.brandFinal[2]}, 0px 0px 1px ${theme.colors.brandFinal[2]}`,
29
- border: `1px solid ${theme.colors.brandFinal[1]}`,
30
- borderRadius: "6px",
31
- padding: "2px",
32
- },
33
- }),
34
- },
35
- DragHandleMenu: {
36
- styles: (theme) => ({
37
- root: {
38
- ".mantine-Menu-item": {
39
- color: theme.colors.brandFinal,
40
- fontSize: "12px",
41
- height: "34px",
42
- },
43
- },
44
- }),
45
- },
46
- EditHyperlinkMenu: {
47
- styles: (theme) => ({
48
- root: {
49
- backgroundColor: "white",
50
- boxShadow: `0px 4px 8px ${theme.colors.brandFinal[2]}, 0px 0px 1px ${theme.colors.brandFinal[2]}`,
51
- border: `1px solid ${theme.colors.brandFinal[1]}`,
52
- borderRadius: "6px",
53
- gap: "4px",
54
- minWidth: "145px",
55
- padding: "2px",
56
- // Row
57
- ".mantine-Group-root": {
58
- flexWrap: "nowrap",
59
- gap: "8px",
60
- paddingInline: "6px",
61
- // Row icon
62
- ".mantine-Container-root": {
63
- color: theme.colors.brandFinal,
64
- display: "flex",
65
- justifyContent: "center",
66
- padding: "0",
67
- width: "fit-content",
68
- },
69
- // Row input field
70
- ".mantine-TextInput-root": {
71
- background: "transparent",
72
- width: "300px",
73
- ".mantine-TextInput-wrapper": {
74
- ".mantine-TextInput-input": {
75
- fontSize: "12px",
76
- border: 0,
77
- padding: 0,
78
- },
79
- },
80
- },
81
- },
82
- },
83
- }),
84
- },
85
- Toolbar: {
86
- styles: (theme) => ({
87
- root: {
88
- backgroundColor: "white",
89
- boxShadow: `0px 4px 8px ${theme.colors.brandFinal[2]}, 0px 0px 1px ${theme.colors.brandFinal[2]}`,
90
- border: `1px solid ${theme.colors.brandFinal[1]}`,
91
- borderRadius: "6px",
92
- flexWrap: "nowrap",
93
- gap: "2px",
94
- padding: "2px",
95
- width: "fit-content",
96
- // Button (including dropdown target)
97
- ".mantine-UnstyledButton-root": {
98
- borderRadius: "4px",
99
- },
100
- // Dropdown
101
- ".mantine-Menu-dropdown": {
102
- // Dropdown item
103
- ".mantine-Menu-item": {
104
- color: theme.colors.brandFinal,
105
- fontSize: "12px",
106
- height: "34px",
107
- ".mantine-Menu-itemRightSection": {
108
- paddingLeft: "5px",
109
- },
110
- },
111
- },
112
- },
113
- }),
114
- },
115
- SuggestionList: {
116
- styles: (theme) => ({
117
- root: {
118
- // ...theme.other.defaultMenuStyles(theme),
119
- ".mantine-Menu-item": {
120
- // Icon
121
- ".mantine-Menu-itemIcon": {
122
- padding: "8px",
123
- border: `1px solid ${theme.colors.brandFinal[2]}`,
124
- backgroundColor: theme.colors.brandFinal[0],
125
- borderRadius: "4px",
126
- color: theme.colors.brandFinal,
127
- },
128
- // Text
129
- ".mantine-Menu-itemLabel": {
130
- color: theme.colors.brandFinal,
131
- paddingRight: "16px",
132
- ".mantine-Stack-root": {
133
- gap: "0",
134
- },
135
- },
136
- // Badge (keyboard shortcut)
137
- ".mantine-Menu-itemRightSection": {
138
- ".mantine-Badge-root": {
139
- border: `1px solid ${theme.colors.brandFinal[2]}`,
140
- },
141
- },
142
- },
143
- },
144
- }),
145
- },
146
- },
147
- fontFamily: "Inter",
148
- primaryColor: "brandFinal",
149
- primaryShade: 9,
150
- };
@@ -1,2 +0,0 @@
1
- // BlockNote uses a similar pattern as Tiptap, so for now we can just export that
2
- export { EditorContent } from "@tiptap/react";
@@ -1,46 +0,0 @@
1
- import { Plugin, PluginKey } from "prosemirror-state";
2
-
3
- const PLUGIN_KEY = new PluginKey(`ordered-list`);
4
-
5
- export const OrderedListPlugin = () => {
6
- return new Plugin({
7
- key: PLUGIN_KEY,
8
- appendTransaction: (_transactions, _oldState, newState) => {
9
- const newTr = newState.tr;
10
- let modified = false;
11
- let count = 1;
12
- let skip = 0;
13
- newState.doc.descendants((node, pos) => {
14
- if (node.type.name === "block" && !node.attrs.listType) {
15
- count = 1;
16
- }
17
- if (
18
- skip === 0 &&
19
- node.type.name === "block" &&
20
- node.attrs.listType === "oli"
21
- ) {
22
- skip = node.content.childCount;
23
- // This assumes that the content node is always the first child of the oli block,
24
- // as the content model grows this assumption may need to change
25
- if (node.content.child(0).attrs.position !== `${count}.`) {
26
- // TODO: @DAlperin currently sub-items just continue from the order of the parent,
27
- // sub-items should be ordered separately with letters or roman numerals or some such
28
- newTr.setNodeMarkup(pos + 1, undefined, {
29
- ...node.attrs,
30
- position: `${count}.`,
31
- });
32
- modified = true;
33
- }
34
-
35
- count++;
36
- } else if (skip > 0) {
37
- skip--;
38
- }
39
- });
40
- if (modified) {
41
- return newTr;
42
- }
43
- return null;
44
- },
45
- });
46
- };
@@ -1,274 +0,0 @@
1
- import { Fragment, Node, ResolvedPos, Slice } from "prosemirror-model";
2
- import { EditorState, NodeSelection, Selection } from "prosemirror-state";
3
- import {
4
- canJoin,
5
- liftTarget,
6
- ReplaceAroundStep,
7
- replaceStep,
8
- } from "prosemirror-transform";
9
-
10
- import { Command, TextSelection, Transaction } from "prosemirror-state";
11
- import { ReplaceStep } from "prosemirror-transform";
12
-
13
- /**
14
- * Code taken from https://github.com/ProseMirror/prosemirror-commands/blob/97a8cb5fac25e697d4693ce343e2e3b020a7fa2f/src/commands.ts
15
- * Reason for modification: https://github.com/YousefED/BlockNote/pull/11
16
- *
17
- * BlockA
18
- * BlockB
19
- * Order of behavior has been switched to make first and second blocks content
20
- * merge before trying to add second block as child of first
21
- *
22
- * behavior responsible for joining BlockB as A child of BlockA moved to (line 379 - 393 original file) after
23
- * behavior responsible for joining content of BlockA and BlockB (line 402 - 422 original file)
24
- */
25
- export const joinBackward: Command = (state, dispatch, view) => {
26
- let { $cursor } = state.selection as TextSelection;
27
- if (
28
- !$cursor ||
29
- (view ? !view.endOfTextblock("backward", state) : $cursor.parentOffset > 0)
30
- ) {
31
- return false;
32
- }
33
-
34
- let $cut = findCutBefore($cursor);
35
-
36
- // If there is no node before this, try to lift
37
- if (!$cut) {
38
- let range = $cursor.blockRange(),
39
- target = range && liftTarget(range);
40
- if (target === null) {
41
- return false;
42
- }
43
- if (dispatch) {
44
- dispatch(state.tr.lift(range!, target).scrollIntoView());
45
- }
46
- return true;
47
- }
48
-
49
- let before = $cut.nodeBefore!;
50
- // Apply the joining algorithm
51
- if (!before.type.spec.isolating && deleteBarrier(state, $cut, dispatch)) {
52
- return true;
53
- }
54
-
55
- // If the node below has no content and the node above is
56
- // selectable, delete the node below and select the one above.
57
- if (
58
- $cursor.parent.content.size === 0 &&
59
- (textblockAt(before, "end") || NodeSelection.isSelectable(before))
60
- ) {
61
- let delStep = replaceStep(
62
- state.doc,
63
- $cursor.before(),
64
- $cursor.after(),
65
- Slice.empty
66
- );
67
- if (
68
- delStep &&
69
- (delStep as ReplaceStep).slice.size <
70
- (delStep as ReplaceStep).to - (delStep as ReplaceStep).from
71
- ) {
72
- if (dispatch) {
73
- let tr = state.tr.step(delStep);
74
- tr.setSelection(
75
- textblockAt(before, "end")
76
- ? Selection.findFrom(
77
- tr.doc.resolve(tr.mapping.map($cut.pos, -1)),
78
- -1
79
- )!
80
- : NodeSelection.create(tr.doc, $cut.pos - before.nodeSize)
81
- );
82
- dispatch(tr.scrollIntoView());
83
- }
84
- return true;
85
- }
86
- }
87
-
88
- // If the node before is an atom, delete it
89
- if (before.isAtom && $cut.depth === $cursor.depth - 1) {
90
- if (dispatch) {
91
- dispatch(
92
- state.tr.delete($cut.pos - before.nodeSize, $cut.pos).scrollIntoView()
93
- );
94
- }
95
- return true;
96
- }
97
-
98
- return false;
99
- };
100
-
101
- function findCutBefore($pos: ResolvedPos): ResolvedPos | null {
102
- if (!$pos.parent.type.spec.isolating) {
103
- for (let i = $pos.depth - 1; i >= 0; i--) {
104
- if ($pos.index(i) > 0) {
105
- return $pos.doc.resolve($pos.before(i + 1));
106
- }
107
- if ($pos.node(i).type.spec.isolating) {
108
- break;
109
- }
110
- }
111
- }
112
- return null;
113
- }
114
-
115
- function deleteBarrier(
116
- state: EditorState,
117
- $cut: ResolvedPos,
118
- dispatch: ((tr: Transaction) => void) | undefined
119
- ) {
120
- let before = $cut.nodeBefore!,
121
- after = $cut.nodeAfter!,
122
- conn,
123
- match;
124
- if (before.type.spec.isolating || after.type.spec.isolating) {
125
- return false;
126
- }
127
- if (joinMaybeClear(state, $cut, dispatch)) {
128
- return true;
129
- }
130
-
131
- let canDelAfter = $cut.parent.canReplace($cut.index(), $cut.index() + 1);
132
-
133
- let selAfter = Selection.findFrom($cut, 1);
134
- let range = selAfter && selAfter.$from.blockRange(selAfter.$to),
135
- target = range && liftTarget(range);
136
- if (target != null && target >= $cut.depth) {
137
- if (dispatch) {
138
- dispatch(state.tr.lift(range!, target).scrollIntoView());
139
- }
140
- return true;
141
- }
142
-
143
- if (
144
- canDelAfter &&
145
- textblockAt(after, "start", true) &&
146
- textblockAt(before, "end")
147
- ) {
148
- let at = before,
149
- wrap = [];
150
- for (;;) {
151
- wrap.push(at);
152
- if (at.isTextblock) {
153
- break;
154
- }
155
- at = at.lastChild!;
156
- }
157
- let afterText = after,
158
- afterDepth = 1;
159
- for (; !afterText.isTextblock; afterText = afterText.firstChild!) {
160
- afterDepth++;
161
- }
162
- if (at.canReplace(at.childCount, at.childCount, afterText.content)) {
163
- if (dispatch) {
164
- let end = Fragment.empty;
165
- for (let i = wrap.length - 1; i >= 0; i--) {
166
- end = Fragment.from(wrap[i].copy(end));
167
- }
168
- let tr = state.tr.step(
169
- new ReplaceAroundStep(
170
- $cut.pos - wrap.length,
171
- $cut.pos + after.nodeSize,
172
- $cut.pos + afterDepth,
173
- $cut.pos + after.nodeSize - afterDepth,
174
- new Slice(end, wrap.length, 0),
175
- 0,
176
- true
177
- )
178
- );
179
- dispatch(tr.scrollIntoView());
180
- }
181
- return true;
182
- }
183
- }
184
-
185
- if (
186
- canDelAfter &&
187
- (conn = (match = before.contentMatchAt(before.childCount)).findWrapping(
188
- after.type
189
- )) &&
190
- match.matchType(conn[0] || after.type)!.validEnd
191
- ) {
192
- if (dispatch) {
193
- let end = $cut.pos + after.nodeSize,
194
- wrap = Fragment.empty;
195
- for (let i = conn.length - 1; i >= 0; i--) {
196
- wrap = Fragment.from(conn[i].create(null, wrap));
197
- }
198
- wrap = Fragment.from(before.copy(wrap));
199
- let tr = state.tr.step(
200
- new ReplaceAroundStep(
201
- $cut.pos - 1,
202
- end,
203
- $cut.pos,
204
- end,
205
- new Slice(wrap, 1, 0),
206
- conn.length,
207
- true
208
- )
209
- );
210
- let joinAt = end + 2 * conn.length;
211
- if (canJoin(tr.doc, joinAt)) {
212
- tr.join(joinAt);
213
- }
214
- dispatch(tr.scrollIntoView());
215
- }
216
- return true;
217
- }
218
- return false;
219
- }
220
-
221
- function textblockAt(node: Node, side: "start" | "end", only = false) {
222
- for (
223
- let scan: Node | null = node;
224
- scan;
225
- scan = side === "start" ? scan.firstChild : scan.lastChild
226
- ) {
227
- if (scan.isTextblock) {
228
- return true;
229
- }
230
- if (only && scan.childCount !== 1) {
231
- return false;
232
- }
233
- }
234
- return false;
235
- }
236
- function joinMaybeClear(
237
- state: EditorState,
238
- $pos: ResolvedPos,
239
- dispatch: ((tr: Transaction) => void) | undefined
240
- ) {
241
- let before = $pos.nodeBefore,
242
- after = $pos.nodeAfter,
243
- index = $pos.index();
244
- if (!before || !after || !before.type.compatibleContent(after.type)) {
245
- return false;
246
- }
247
- if (!before.content.size && $pos.parent.canReplace(index - 1, index)) {
248
- if (dispatch) {
249
- dispatch(
250
- state.tr.delete($pos.pos - before.nodeSize, $pos.pos).scrollIntoView()
251
- );
252
- }
253
- return true;
254
- }
255
- if (
256
- !$pos.parent.canReplace(index, index + 1) ||
257
- !(after.isTextblock || canJoin(state.doc, $pos.pos))
258
- ) {
259
- return false;
260
- }
261
- if (dispatch) {
262
- dispatch(
263
- state.tr
264
- .clearIncompatible(
265
- $pos.pos,
266
- before.type,
267
- before.contentMatchAt(before.childCount)
268
- )
269
- .join($pos.pos)
270
- .scrollIntoView()
271
- );
272
- }
273
- return true;
274
- }
@@ -1,30 +0,0 @@
1
- import { Transaction } from "prosemirror-state";
2
- import { Level } from "../nodes/Block";
3
- import { findBlock } from "./findBlock";
4
-
5
- type Dispatch = ((args?: any) => any) | undefined;
6
-
7
- export function setBlockHeading(
8
- tr: Transaction,
9
- dispatch: Dispatch,
10
- level?: Level
11
- ) {
12
- // Get parent of TextNode
13
- const containingBlock = findBlock(tr.selection);
14
-
15
- // Should not be possible because schema dictates
16
- // that each text node is nested in a BlockContent
17
- // node which is nested inside a BlockNode
18
- if (!containingBlock) {
19
- return false;
20
- }
21
-
22
- // Add heading attribute to Block
23
- if (dispatch) {
24
- tr.setNodeMarkup(containingBlock.pos, undefined, {
25
- ...containingBlock.node.attrs,
26
- headingType: level,
27
- });
28
- }
29
- return true;
30
- }
@@ -1,63 +0,0 @@
1
- import { mergeAttributes, Node } from "@tiptap/core";
2
- import styles from "./Block.module.css";
3
- export interface IBlock {
4
- HTMLAttributes: Record<string, any>;
5
- }
6
-
7
- export const ContentBlock = Node.create<IBlock>({
8
- name: "content",
9
-
10
- addOptions() {
11
- return {
12
- HTMLAttributes: {},
13
- };
14
- },
15
- addAttributes() {
16
- return {
17
- position: {
18
- default: undefined,
19
- renderHTML: (attributes) => {
20
- return {
21
- "data-position": attributes.position,
22
- };
23
- },
24
- parseHTML: (element) => element.getAttribute("data-position"),
25
- },
26
- };
27
- },
28
-
29
- content: "inline*",
30
-
31
- parseHTML() {
32
- return [
33
- {
34
- tag: "div",
35
- getAttrs: (element) => {
36
- if(typeof element === "string") {
37
- return false;
38
- }
39
-
40
- if(element.getAttribute("data-node-type") === "block-content") {
41
- // Null means the element matches, but we don't want to add any attributes to the node.
42
- return null;
43
- }
44
-
45
- return false;
46
- }
47
- }
48
- ];
49
- },
50
-
51
- renderHTML({ HTMLAttributes }) {
52
- return [
53
- "div",
54
- mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
55
- class: styles.blockContent,
56
- "data-node-type": "block-content"
57
- }),
58
- // TODO: The extra nested div is only needed for placeholders, different solution (without extra div) would be preferable
59
- // We can't use the other div because the ::before attribute on that one is already reserved for list-bullets
60
- ["div", 0],
61
- ];
62
- },
63
- });
@@ -1,48 +0,0 @@
1
- import {
2
- callOrReturn,
3
- ExtendedRegExpMatchArray,
4
- InputRule,
5
- InputRuleFinder,
6
- } from "@tiptap/core";
7
- import { NodeType } from "prosemirror-model";
8
-
9
- /**
10
- * Modified version of https://github.com/ueberdosis/tiptap/blob/6a813686f5e87cebac49a624936dbeadb5a29f95/packages/core/src/inputRules/textblockTypeInputRule.ts
11
- * But instead of changing the type of a node, we use setNodeMarkup to change some of it's current attributes
12
- *
13
- * Build an input rule that changes the type of a textblock when the
14
- * matched text is typed into it. When using a regular expresion you’ll
15
- * probably want the regexp to start with `^`, so that the pattern can
16
- * only occur at the start of a textblock.
17
- */
18
- export function textblockTypeInputRuleSameNodeType(config: {
19
- find: InputRuleFinder;
20
- type: NodeType;
21
- getAttributes?:
22
- | Record<string, any>
23
- | ((match: ExtendedRegExpMatchArray) => Record<string, any>)
24
- | false
25
- | null;
26
- }) {
27
- return new InputRule({
28
- find: config.find,
29
- handler: ({ state, range, match }) => {
30
- const $start = state.doc.resolve(range.from);
31
- const attributes =
32
- callOrReturn(config.getAttributes, undefined, match) || {};
33
-
34
- const blockNode = $start.node(-1);
35
- if (blockNode.type !== config.type) {
36
- return null;
37
- }
38
-
39
- state.tr
40
- .setNodeMarkup(range.from - 2, undefined, {
41
- ...blockNode.attrs,
42
- ...attributes,
43
- })
44
- .delete(range.from, range.to);
45
- return;
46
- },
47
- });
48
- }
@@ -1,36 +0,0 @@
1
- import { MantineProvider } from "@mantine/core";
2
- import { Extension } from "@tiptap/core";
3
- import { PluginKey } from "prosemirror-state";
4
- import ReactDOM from "react-dom";
5
- import { BlockNoteTheme } from "../../BlockNoteTheme";
6
- import rootStyles from "../../root.module.css";
7
- import { createBubbleMenuPlugin } from "./BubbleMenuPlugin";
8
- import { BubbleMenu } from "./component/BubbleMenu";
9
-
10
- /**
11
- * The menu that is displayed when selecting a piece of text.
12
- */
13
- export const BubbleMenuExtension = Extension.create<{}>({
14
- name: "BubbleMenuExtension",
15
-
16
- addProseMirrorPlugins() {
17
- const element = document.createElement("div");
18
- element.className = rootStyles.bnRoot;
19
- ReactDOM.render(
20
- <MantineProvider theme={BlockNoteTheme}>
21
- <BubbleMenu editor={this.editor} />
22
- </MantineProvider>,
23
- element
24
- );
25
- return [
26
- createBubbleMenuPlugin({
27
- editor: this.editor,
28
- element,
29
- pluginKey: new PluginKey("BubbleMenuPlugin"),
30
- tippyOptions: {
31
- appendTo: document.body,
32
- },
33
- }),
34
- ];
35
- },
36
- });