@blocknote/core 0.38.0 → 0.39.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 (225) hide show
  1. package/dist/BlockNoteSchema-DmZ6UQfY.cjs +11 -0
  2. package/dist/BlockNoteSchema-DmZ6UQfY.cjs.map +1 -0
  3. package/dist/BlockNoteSchema-oR047ACf.js +4275 -0
  4. package/dist/BlockNoteSchema-oR047ACf.js.map +1 -0
  5. package/dist/blocknote.cjs +4 -12
  6. package/dist/blocknote.cjs.map +1 -1
  7. package/dist/blocknote.js +3296 -7187
  8. package/dist/blocknote.js.map +1 -1
  9. package/dist/blocks.cjs +2 -0
  10. package/dist/blocks.cjs.map +1 -0
  11. package/dist/blocks.js +71 -0
  12. package/dist/blocks.js.map +1 -0
  13. package/dist/style.css +1 -1
  14. package/dist/tsconfig.tsbuildinfo +1 -1
  15. package/dist/webpack-stats.json +1 -1
  16. package/package.json +19 -16
  17. package/src/api/blockManipulation/commands/insertBlocks/insertBlocks.ts +1 -1
  18. package/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.ts +2 -2
  19. package/src/api/blockManipulation/commands/splitBlock/splitBlock.ts +34 -25
  20. package/src/api/blockManipulation/setupTestEnv.ts +0 -1
  21. package/src/api/clipboard/fromClipboard/handleFileInsertion.ts +4 -8
  22. package/src/api/clipboard/toClipboard/copyExtension.ts +1 -1
  23. package/src/api/exporters/html/util/serializeBlocksExternalHTML.ts +128 -28
  24. package/src/api/exporters/html/util/serializeBlocksInternalHTML.ts +101 -41
  25. package/src/api/pmUtil.ts +1 -1
  26. package/src/api/positionMapping.test.ts +58 -15
  27. package/src/api/positionMapping.ts +2 -4
  28. package/src/blocks/Audio/block.ts +174 -0
  29. package/src/blocks/BlockNoteSchema.ts +59 -0
  30. package/src/blocks/Code/block.ts +303 -0
  31. package/src/blocks/Code/shiki.ts +73 -0
  32. package/src/blocks/File/block.ts +98 -0
  33. package/src/blocks/{FileBlockContent → File}/helpers/render/createAddFileButton.ts +5 -2
  34. package/src/blocks/{FileBlockContent → File}/helpers/render/createFileBlockWrapper.ts +15 -6
  35. package/src/blocks/{FileBlockContent → File}/helpers/render/createFileNameWithIcon.ts +15 -2
  36. package/src/blocks/{FileBlockContent → File}/helpers/render/createResizableFileBlockWrapper.ts +21 -2
  37. package/src/blocks/Heading/block.ts +138 -0
  38. package/src/blocks/Image/block.ts +190 -0
  39. package/src/blocks/ListItem/BulletListItem/block.ts +116 -0
  40. package/src/blocks/ListItem/CheckListItem/block.ts +175 -0
  41. package/src/blocks/ListItem/NumberedListItem/IndexingPlugin.ts +173 -0
  42. package/src/blocks/ListItem/NumberedListItem/block.ts +133 -0
  43. package/src/blocks/ListItem/ToggleListItem/block.ts +78 -0
  44. package/src/blocks/PageBreak/block.ts +72 -0
  45. package/src/blocks/{PageBreakBlockContent → PageBreak}/getPageBreakSlashMenuItems.ts +9 -7
  46. package/src/blocks/Paragraph/block.ts +80 -0
  47. package/src/blocks/Quote/block.ts +90 -0
  48. package/src/blocks/{TableBlockContent/TableBlockContent.ts → Table/block.ts} +169 -51
  49. package/src/blocks/ToggleWrapper/createToggleWrapper.ts +1 -1
  50. package/src/blocks/Video/block.ts +143 -0
  51. package/src/blocks/defaultBlockHelpers.ts +2 -2
  52. package/src/blocks/defaultBlockTypeGuards.ts +143 -174
  53. package/src/blocks/defaultBlocks.ts +107 -35
  54. package/src/blocks/defaultProps.ts +145 -4
  55. package/src/blocks/index.ts +26 -0
  56. package/src/blocks/utils/listItemEnterHandler.ts +42 -0
  57. package/src/editor/Block.css +54 -18
  58. package/src/editor/BlockNoteEditor.ts +251 -210
  59. package/src/editor/BlockNoteExtension.ts +92 -0
  60. package/src/editor/BlockNoteExtensions.ts +18 -17
  61. package/src/editor/defaultColors.ts +2 -2
  62. package/src/exporter/Exporter.ts +1 -1
  63. package/src/exporter/mapping.ts +1 -1
  64. package/src/extensions/BackgroundColor/BackgroundColorExtension.ts +3 -20
  65. package/src/extensions/BackgroundColor/BackgroundColorMark.ts +6 -8
  66. package/src/extensions/BlockChange/BlockChangePlugin.ts +2 -1
  67. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-editor-forked.json +2 -2
  68. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-editor.json +2 -2
  69. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-forked.html +1 -1
  70. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap.html +1 -1
  71. package/src/extensions/Collaboration/schemaMigration/SchemaMigrationPlugin.ts +52 -0
  72. package/src/extensions/Collaboration/schemaMigration/migrationRules/index.ts +4 -0
  73. package/src/extensions/Collaboration/schemaMigration/migrationRules/migrationRule.ts +4 -0
  74. package/src/extensions/Collaboration/schemaMigration/migrationRules/moveColorAttributes.ts +78 -0
  75. package/src/extensions/Comments/CommentsPlugin.ts +1 -1
  76. package/src/extensions/FilePanel/FilePanelPlugin.ts +5 -10
  77. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +1 -1
  78. package/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.ts +4 -3
  79. package/src/extensions/Placeholder/PlaceholderPlugin.ts +2 -2
  80. package/src/extensions/PreviousBlockType/PreviousBlockTypePlugin.ts +1 -23
  81. package/src/extensions/SuggestionMenu/SuggestionPlugin.ts +0 -5
  82. package/src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.ts +6 -2
  83. package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +24 -17
  84. package/src/extensions/TableHandles/TableHandlesPlugin.ts +2 -2
  85. package/src/extensions/TextAlignment/TextAlignmentExtension.ts +5 -11
  86. package/src/extensions/TextColor/TextColorExtension.ts +3 -17
  87. package/src/extensions/TextColor/TextColorMark.ts +4 -9
  88. package/src/extensions/UniqueID/UniqueID.ts +6 -13
  89. package/src/index.ts +2 -28
  90. package/src/schema/blocks/createSpec.ts +342 -169
  91. package/src/schema/blocks/internal.ts +77 -138
  92. package/src/schema/blocks/types.ts +264 -94
  93. package/src/schema/index.ts +1 -0
  94. package/src/schema/inlineContent/createSpec.ts +99 -21
  95. package/src/schema/inlineContent/internal.ts +16 -7
  96. package/src/schema/inlineContent/types.ts +24 -2
  97. package/src/schema/propTypes.ts +15 -9
  98. package/src/schema/schema.ts +209 -0
  99. package/src/schema/styles/createSpec.ts +79 -31
  100. package/src/schema/styles/internal.ts +61 -2
  101. package/src/schema/styles/types.ts +17 -3
  102. package/src/util/topo-sort.test.ts +125 -0
  103. package/src/util/topo-sort.ts +160 -0
  104. package/types/src/api/blockManipulation/commands/splitBlock/splitBlock.d.ts +2 -1
  105. package/types/src/api/blockManipulation/selections/selection.d.ts +1 -1
  106. package/types/src/api/blockManipulation/setupTestEnv.d.ts +29 -543
  107. package/types/src/api/exporters/html/util/serializeBlocksExternalHTML.d.ts +1 -1
  108. package/types/src/api/exporters/html/util/serializeBlocksInternalHTML.d.ts +1 -1
  109. package/types/src/api/pmUtil.d.ts +1 -1
  110. package/types/src/blocks/Audio/block.d.ts +58 -0
  111. package/types/src/blocks/BlockNoteSchema.d.ts +18 -0
  112. package/types/src/blocks/{CodeBlockContent/CodeBlockContent.d.ts → Code/block.d.ts} +25 -26
  113. package/types/src/blocks/Code/shiki.d.ts +4 -0
  114. package/types/src/blocks/File/block.d.ts +37 -0
  115. package/types/src/blocks/File/helpers/render/createAddFileButton.d.ts +6 -0
  116. package/types/src/blocks/File/helpers/render/createFileBlockWrapper.d.ts +25 -0
  117. package/types/src/blocks/{FileBlockContent → File}/helpers/render/createFileNameWithIcon.d.ts +6 -2
  118. package/types/src/blocks/File/helpers/render/createResizableFileBlockWrapper.d.ts +31 -0
  119. package/types/src/blocks/Heading/block.d.ts +71 -0
  120. package/types/src/blocks/Image/block.d.ts +102 -0
  121. package/types/src/blocks/ListItem/BulletListItem/block.d.ts +25 -0
  122. package/types/src/blocks/ListItem/CheckListItem/block.d.ts +33 -0
  123. package/types/src/blocks/ListItem/NumberedListItem/IndexingPlugin.d.ts +8 -0
  124. package/types/src/blocks/ListItem/NumberedListItem/block.d.ts +33 -0
  125. package/types/src/blocks/ListItem/ToggleListItem/block.d.ts +25 -0
  126. package/types/src/blocks/PageBreak/block.d.ts +11 -0
  127. package/types/src/blocks/{PageBreakBlockContent → PageBreak}/getPageBreakSlashMenuItems.d.ts +4 -2
  128. package/types/src/blocks/Paragraph/block.d.ts +25 -0
  129. package/types/src/blocks/Quote/block.d.ts +17 -0
  130. package/types/src/blocks/Table/block.d.ts +21 -0
  131. package/types/src/blocks/Video/block.d.ts +67 -0
  132. package/types/src/blocks/defaultBlockHelpers.d.ts +1 -1
  133. package/types/src/blocks/defaultBlockTypeGuards.d.ts +15 -36
  134. package/types/src/blocks/defaultBlocks.d.ts +221 -1060
  135. package/types/src/blocks/defaultProps.d.ts +17 -1
  136. package/types/src/blocks/index.d.ts +24 -0
  137. package/types/src/blocks/utils/listItemEnterHandler.d.ts +2 -0
  138. package/types/src/editor/BlockNoteEditor.d.ts +33 -66
  139. package/types/src/editor/BlockNoteExtension.d.ts +67 -0
  140. package/types/src/editor/BlockNoteExtensions.d.ts +1 -1
  141. package/types/src/editor/defaultColors.d.ts +8 -76
  142. package/types/src/exporter/Exporter.d.ts +1 -1
  143. package/types/src/exporter/mapping.d.ts +1 -1
  144. package/types/src/extensions/BackgroundColor/BackgroundColorMark.d.ts +4 -1
  145. package/types/src/extensions/Collaboration/schemaMigration/SchemaMigrationPlugin.d.ts +7 -0
  146. package/types/src/extensions/Collaboration/schemaMigration/migrationRules/index.d.ts +3 -0
  147. package/types/src/extensions/Collaboration/schemaMigration/migrationRules/migrationRule.d.ts +3 -0
  148. package/types/src/extensions/Collaboration/schemaMigration/migrationRules/moveColorAttributes.d.ts +2 -0
  149. package/types/src/extensions/Comments/CommentsPlugin.d.ts +1 -1
  150. package/types/src/extensions/FilePanel/FilePanelPlugin.d.ts +4 -4
  151. package/types/src/extensions/TextColor/TextColorMark.d.ts +4 -1
  152. package/types/src/index.d.ts +2 -25
  153. package/types/src/schema/blocks/createSpec.d.ts +16 -36
  154. package/types/src/schema/blocks/internal.d.ts +11 -33
  155. package/types/src/schema/blocks/types.d.ts +181 -57
  156. package/types/src/schema/index.d.ts +1 -0
  157. package/types/src/schema/inlineContent/createSpec.d.ts +36 -2
  158. package/types/src/schema/inlineContent/internal.d.ts +7 -15
  159. package/types/src/schema/inlineContent/types.d.ts +15 -1
  160. package/types/src/schema/propTypes.d.ts +4 -4
  161. package/types/src/schema/schema.d.ts +40 -0
  162. package/types/src/schema/styles/createSpec.d.ts +6 -4
  163. package/types/src/schema/styles/internal.d.ts +6 -3
  164. package/types/src/schema/styles/types.d.ts +11 -2
  165. package/types/src/util/topo-sort.d.ts +18 -0
  166. package/types/src/util/topo-sort.test.d.ts +1 -0
  167. package/src/blocks/AudioBlockContent/AudioBlockContent.ts +0 -144
  168. package/src/blocks/CodeBlockContent/CodeBlockContent.ts +0 -445
  169. package/src/blocks/FileBlockContent/FileBlockContent.ts +0 -100
  170. package/src/blocks/HeadingBlockContent/HeadingBlockContent.ts +0 -159
  171. package/src/blocks/ImageBlockContent/ImageBlockContent.ts +0 -159
  172. package/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +0 -134
  173. package/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.ts +0 -299
  174. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts +0 -86
  175. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +0 -172
  176. package/src/blocks/ListItemBlockContent/ToggleListItemBlockContent/ToggleListItemBlockContent.ts +0 -104
  177. package/src/blocks/PageBreakBlockContent/PageBreakBlockContent.ts +0 -49
  178. package/src/blocks/PageBreakBlockContent/schema.ts +0 -40
  179. package/src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts +0 -78
  180. package/src/blocks/QuoteBlockContent/QuoteBlockContent.ts +0 -121
  181. package/src/blocks/VideoBlockContent/VideoBlockContent.ts +0 -158
  182. package/src/editor/BlockNoteSchema.ts +0 -107
  183. package/src/editor/BlockNoteTipTapEditor.ts +0 -335
  184. package/types/src/blocks/AudioBlockContent/AudioBlockContent.d.ts +0 -99
  185. package/types/src/blocks/FileBlockContent/FileBlockContent.d.ts +0 -90
  186. package/types/src/blocks/FileBlockContent/helpers/render/createAddFileButton.d.ts +0 -6
  187. package/types/src/blocks/FileBlockContent/helpers/render/createFileBlockWrapper.d.ts +0 -9
  188. package/types/src/blocks/FileBlockContent/helpers/render/createResizableFileBlockWrapper.d.ts +0 -9
  189. package/types/src/blocks/HeadingBlockContent/HeadingBlockContent.d.ts +0 -67
  190. package/types/src/blocks/ImageBlockContent/ImageBlockContent.d.ts +0 -131
  191. package/types/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.d.ts +0 -46
  192. package/types/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.d.ts +0 -55
  193. package/types/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.d.ts +0 -2
  194. package/types/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.d.ts +0 -58
  195. package/types/src/blocks/ListItemBlockContent/ToggleListItemBlockContent/ToggleListItemBlockContent.d.ts +0 -46
  196. package/types/src/blocks/PageBreakBlockContent/PageBreakBlockContent.d.ts +0 -31
  197. package/types/src/blocks/PageBreakBlockContent/schema.d.ts +0 -86
  198. package/types/src/blocks/ParagraphBlockContent/ParagraphBlockContent.d.ts +0 -52
  199. package/types/src/blocks/QuoteBlockContent/QuoteBlockContent.d.ts +0 -52
  200. package/types/src/blocks/TableBlockContent/TableBlockContent.d.ts +0 -39
  201. package/types/src/blocks/VideoBlockContent/VideoBlockContent.d.ts +0 -131
  202. package/types/src/editor/BlockNoteSchema.d.ts +0 -34
  203. package/types/src/editor/BlockNoteTipTapEditor.d.ts +0 -43
  204. /package/src/blocks/{AudioBlockContent → Audio}/parseAudioElement.ts +0 -0
  205. /package/src/blocks/{FileBlockContent → File}/helpers/parse/parseEmbedElement.ts +0 -0
  206. /package/src/blocks/{FileBlockContent → File}/helpers/parse/parseFigureElement.ts +0 -0
  207. /package/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createFigureWithCaption.ts +0 -0
  208. /package/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createLinkWithCaption.ts +0 -0
  209. /package/src/blocks/{FileBlockContent → File/helpers}/uploadToTmpFilesDotOrg_DEV_ONLY.ts +0 -0
  210. /package/src/blocks/{ImageBlockContent → Image}/parseImageElement.ts +0 -0
  211. /package/src/blocks/{ListItemBlockContent → ListItem}/ListItemKeyboardShortcuts.ts +0 -0
  212. /package/src/blocks/{ListItemBlockContent → ListItem}/getListItemContent.ts +0 -0
  213. /package/src/blocks/{TableBlockContent → Table}/TableExtension.ts +0 -0
  214. /package/src/blocks/{VideoBlockContent → Video}/parseVideoElement.ts +0 -0
  215. /package/types/src/blocks/{AudioBlockContent → Audio}/parseAudioElement.d.ts +0 -0
  216. /package/types/src/blocks/{FileBlockContent → File}/helpers/parse/parseEmbedElement.d.ts +0 -0
  217. /package/types/src/blocks/{FileBlockContent → File}/helpers/parse/parseFigureElement.d.ts +0 -0
  218. /package/types/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createFigureWithCaption.d.ts +0 -0
  219. /package/types/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createLinkWithCaption.d.ts +0 -0
  220. /package/types/src/blocks/{FileBlockContent → File/helpers}/uploadToTmpFilesDotOrg_DEV_ONLY.d.ts +0 -0
  221. /package/types/src/blocks/{ImageBlockContent → Image}/parseImageElement.d.ts +0 -0
  222. /package/types/src/blocks/{ListItemBlockContent → ListItem}/ListItemKeyboardShortcuts.d.ts +0 -0
  223. /package/types/src/blocks/{ListItemBlockContent → ListItem}/getListItemContent.d.ts +0 -0
  224. /package/types/src/blocks/{TableBlockContent → Table}/TableExtension.d.ts +0 -0
  225. /package/types/src/blocks/{VideoBlockContent → Video}/parseVideoElement.d.ts +0 -0
@@ -1,100 +0,0 @@
1
- import type { BlockNoteEditor } from "../../editor/BlockNoteEditor.js";
2
- import {
3
- BlockFromConfig,
4
- FileBlockConfig,
5
- PropSchema,
6
- createBlockSpec,
7
- } from "../../schema/index.js";
8
- import { defaultProps } from "../defaultProps.js";
9
- import { parseEmbedElement } from "./helpers/parse/parseEmbedElement.js";
10
- import { parseFigureElement } from "./helpers/parse/parseFigureElement.js";
11
- import { createFileBlockWrapper } from "./helpers/render/createFileBlockWrapper.js";
12
- import { createLinkWithCaption } from "./helpers/toExternalHTML/createLinkWithCaption.js";
13
-
14
- export const filePropSchema = {
15
- backgroundColor: defaultProps.backgroundColor,
16
- // File name.
17
- name: {
18
- default: "" as const,
19
- },
20
- // File url.
21
- url: {
22
- default: "" as const,
23
- },
24
- // File caption.
25
- caption: {
26
- default: "" as const,
27
- },
28
- } satisfies PropSchema;
29
-
30
- export const fileBlockConfig = {
31
- type: "file" as const,
32
- propSchema: filePropSchema,
33
- content: "none",
34
- isFileBlock: true,
35
- } satisfies FileBlockConfig;
36
-
37
- export const fileRender = (
38
- block: BlockFromConfig<typeof fileBlockConfig, any, any>,
39
- editor: BlockNoteEditor<any, any, any>,
40
- ) => {
41
- return createFileBlockWrapper(block, editor);
42
- };
43
-
44
- export const fileParse = (element: HTMLElement) => {
45
- if (element.tagName === "EMBED") {
46
- // Ignore if parent figure has already been parsed.
47
- if (element.closest("figure")) {
48
- return undefined;
49
- }
50
-
51
- return parseEmbedElement(element as HTMLEmbedElement);
52
- }
53
-
54
- if (element.tagName === "FIGURE") {
55
- const parsedFigure = parseFigureElement(element, "embed");
56
- if (!parsedFigure) {
57
- return undefined;
58
- }
59
-
60
- const { targetElement, caption } = parsedFigure;
61
-
62
- return {
63
- ...parseEmbedElement(targetElement as HTMLEmbedElement),
64
- caption,
65
- };
66
- }
67
-
68
- return undefined;
69
- };
70
-
71
- export const fileToExternalHTML = (
72
- block: BlockFromConfig<typeof fileBlockConfig, any, any>,
73
- ) => {
74
- if (!block.props.url) {
75
- const div = document.createElement("p");
76
- div.textContent = "Add file";
77
-
78
- return {
79
- dom: div,
80
- };
81
- }
82
-
83
- const fileSrcLink = document.createElement("a");
84
- fileSrcLink.href = block.props.url;
85
- fileSrcLink.textContent = block.props.name || block.props.url;
86
-
87
- if (block.props.caption) {
88
- return createLinkWithCaption(fileSrcLink, block.props.caption);
89
- }
90
-
91
- return {
92
- dom: fileSrcLink,
93
- };
94
- };
95
-
96
- export const FileBlock = createBlockSpec(fileBlockConfig, {
97
- render: fileRender,
98
- parse: fileParse,
99
- toExternalHTML: fileToExternalHTML,
100
- });
@@ -1,159 +0,0 @@
1
- import { InputRule } from "@tiptap/core";
2
- import { updateBlockCommand } from "../../api/blockManipulation/commands/updateBlock/updateBlock.js";
3
- import { getBlockInfoFromSelection } from "../../api/getBlockInfoFromPos.js";
4
- import {
5
- PropSchema,
6
- createBlockSpecFromStronglyTypedTiptapNode,
7
- createStronglyTypedTiptapNode,
8
- getBlockFromPos,
9
- propsToAttributes,
10
- } from "../../schema/index.js";
11
- import { createDefaultBlockDOMOutputSpec } from "../defaultBlockHelpers.js";
12
- import { defaultProps } from "../defaultProps.js";
13
- import { createToggleWrapper } from "../ToggleWrapper/createToggleWrapper.js";
14
- import { BlockNoteEditor } from "../../editor/BlockNoteEditor.js";
15
-
16
- const HEADING_LEVELS = [1, 2, 3, 4, 5, 6] as const;
17
-
18
- export const headingPropSchema = {
19
- ...defaultProps,
20
- level: { default: 1, values: HEADING_LEVELS },
21
- isToggleable: { default: false },
22
- } satisfies PropSchema;
23
-
24
- const HeadingBlockContent = createStronglyTypedTiptapNode({
25
- name: "heading",
26
- content: "inline*",
27
- group: "blockContent",
28
-
29
- addAttributes() {
30
- return propsToAttributes(headingPropSchema);
31
- },
32
-
33
- addInputRules() {
34
- const editor = this.options.editor as BlockNoteEditor<any, any, any>;
35
- return [
36
- ...editor.settings.heading.levels.map((level) => {
37
- // Creates a heading of appropriate level when starting with "#", "##", or "###".
38
- return new InputRule({
39
- find: new RegExp(`^(#{${level}})\\s$`),
40
- handler: ({ state, chain, range }) => {
41
- const blockInfo = getBlockInfoFromSelection(state);
42
- if (
43
- !blockInfo.isBlockContainer ||
44
- blockInfo.blockContent.node.type.spec.content !== "inline*"
45
- ) {
46
- return;
47
- }
48
-
49
- chain()
50
- .command(
51
- updateBlockCommand(blockInfo.bnBlock.beforePos, {
52
- type: "heading",
53
- props: {
54
- level: level as any,
55
- },
56
- }),
57
- )
58
- // Removes the "#" character(s) used to set the heading.
59
- .deleteRange({ from: range.from, to: range.to })
60
- .run();
61
- },
62
- });
63
- }),
64
- ];
65
- },
66
-
67
- addKeyboardShortcuts() {
68
- const editor = this.options.editor as BlockNoteEditor<any, any, any>;
69
-
70
- return Object.fromEntries(
71
- editor.settings.heading.levels.map((level) => [
72
- `Mod-Alt-${level}`,
73
- () => {
74
- const blockInfo = getBlockInfoFromSelection(this.editor.state);
75
- if (
76
- !blockInfo.isBlockContainer ||
77
- blockInfo.blockContent.node.type.spec.content !== "inline*"
78
- ) {
79
- return true;
80
- }
81
-
82
- return this.editor.commands.command(
83
- updateBlockCommand(blockInfo.bnBlock.beforePos, {
84
- type: "heading",
85
- props: {
86
- level: level as any,
87
- },
88
- }),
89
- );
90
- },
91
- ]),
92
- );
93
- },
94
- parseHTML() {
95
- const editor = this.options.editor as BlockNoteEditor<any, any, any>;
96
-
97
- return [
98
- // Parse from internal HTML.
99
- {
100
- tag: "div[data-content-type=" + this.name + "]",
101
- contentElement: ".bn-inline-content",
102
- },
103
- ...editor.settings.heading.levels.map((level) => ({
104
- tag: `h${level}`,
105
- attrs: { level },
106
- node: "heading",
107
- })),
108
- ];
109
- },
110
-
111
- renderHTML({ node, HTMLAttributes }) {
112
- return createDefaultBlockDOMOutputSpec(
113
- this.name,
114
- `h${node.attrs.level}`,
115
- {
116
- ...(this.options.domAttributes?.blockContent || {}),
117
- ...HTMLAttributes,
118
- },
119
- this.options.domAttributes?.inlineContent || {},
120
- );
121
- },
122
-
123
- addNodeView() {
124
- return ({ node, HTMLAttributes, getPos }) => {
125
- const { dom, contentDOM } = createDefaultBlockDOMOutputSpec(
126
- this.name,
127
- `h${node.attrs.level}`,
128
- {
129
- ...(this.options.domAttributes?.blockContent || {}),
130
- ...HTMLAttributes,
131
- },
132
- this.options.domAttributes?.inlineContent || {},
133
- );
134
- dom.removeChild(contentDOM);
135
-
136
- const editor = this.options.editor;
137
- const block = getBlockFromPos(getPos, editor, this.editor, this.name);
138
-
139
- const toggleWrapper = createToggleWrapper(
140
- block as any,
141
- editor,
142
- contentDOM,
143
- );
144
- dom.appendChild(toggleWrapper.dom);
145
-
146
- return {
147
- dom,
148
- contentDOM,
149
- ignoreMutation: toggleWrapper.ignoreMutation,
150
- destroy: toggleWrapper.destroy,
151
- };
152
- };
153
- },
154
- });
155
-
156
- export const Heading = createBlockSpecFromStronglyTypedTiptapNode(
157
- HeadingBlockContent,
158
- headingPropSchema,
159
- );
@@ -1,159 +0,0 @@
1
- import type { BlockNoteEditor } from "../../editor/BlockNoteEditor.js";
2
- import {
3
- BlockFromConfig,
4
- createBlockSpec,
5
- FileBlockConfig,
6
- Props,
7
- PropSchema,
8
- } from "../../schema/index.js";
9
- import { defaultProps } from "../defaultProps.js";
10
- import { parseFigureElement } from "../FileBlockContent/helpers/parse/parseFigureElement.js";
11
- import { createFigureWithCaption } from "../FileBlockContent/helpers/toExternalHTML/createFigureWithCaption.js";
12
- import { createLinkWithCaption } from "../FileBlockContent/helpers/toExternalHTML/createLinkWithCaption.js";
13
- import { createResizableFileBlockWrapper } from "../FileBlockContent/helpers/render/createResizableFileBlockWrapper.js";
14
- import { parseImageElement } from "./parseImageElement.js";
15
-
16
- export const FILE_IMAGE_ICON_SVG =
17
- '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M5 11.1005L7 9.1005L12.5 14.6005L16 11.1005L19 14.1005V5H5V11.1005ZM4 3H20C20.5523 3 21 3.44772 21 4V20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V4C3 3.44772 3.44772 3 4 3ZM15.5 10C14.6716 10 14 9.32843 14 8.5C14 7.67157 14.6716 7 15.5 7C16.3284 7 17 7.67157 17 8.5C17 9.32843 16.3284 10 15.5 10Z"></path></svg>';
18
-
19
- export const imagePropSchema = {
20
- textAlignment: defaultProps.textAlignment,
21
- backgroundColor: defaultProps.backgroundColor,
22
- // File name.
23
- name: {
24
- default: "" as const,
25
- },
26
- // File url.
27
- url: {
28
- default: "" as const,
29
- },
30
- // File caption.
31
- caption: {
32
- default: "" as const,
33
- },
34
-
35
- showPreview: {
36
- default: true,
37
- },
38
- // File preview width in px.
39
- previewWidth: {
40
- default: undefined,
41
- type: "number",
42
- },
43
- } satisfies PropSchema;
44
-
45
- export const imageBlockConfig = {
46
- type: "image" as const,
47
- propSchema: imagePropSchema,
48
- content: "none",
49
- isFileBlock: true,
50
- fileBlockAccept: ["image/*"],
51
- } satisfies FileBlockConfig;
52
-
53
- export const imageRender = (
54
- block: BlockFromConfig<typeof imageBlockConfig, any, any>,
55
- editor: BlockNoteEditor<any, any, any>,
56
- ) => {
57
- const icon = document.createElement("div");
58
- icon.innerHTML = FILE_IMAGE_ICON_SVG;
59
-
60
- const imageWrapper = document.createElement("div");
61
- imageWrapper.className = "bn-visual-media-wrapper";
62
-
63
- const image = document.createElement("img");
64
- image.className = "bn-visual-media";
65
- if (editor.resolveFileUrl) {
66
- editor.resolveFileUrl(block.props.url).then((downloadUrl) => {
67
- image.src = downloadUrl;
68
- });
69
- } else {
70
- image.src = block.props.url;
71
- }
72
-
73
- image.alt = block.props.name || block.props.caption || "BlockNote image";
74
- image.contentEditable = "false";
75
- image.draggable = false;
76
- imageWrapper.appendChild(image);
77
-
78
- return createResizableFileBlockWrapper(
79
- block,
80
- editor,
81
- { dom: imageWrapper },
82
- imageWrapper,
83
- icon.firstElementChild as HTMLElement,
84
- );
85
- };
86
-
87
- export const imageParse = (
88
- element: HTMLElement,
89
- ): Partial<Props<typeof imageBlockConfig.propSchema>> | undefined => {
90
- if (element.tagName === "IMG") {
91
- // Ignore if parent figure has already been parsed.
92
- if (element.closest("figure")) {
93
- return undefined;
94
- }
95
-
96
- return parseImageElement(element as HTMLImageElement);
97
- }
98
-
99
- if (element.tagName === "FIGURE") {
100
- const parsedFigure = parseFigureElement(element, "img");
101
- if (!parsedFigure) {
102
- return undefined;
103
- }
104
-
105
- const { targetElement, caption } = parsedFigure;
106
-
107
- return {
108
- ...parseImageElement(targetElement as HTMLImageElement),
109
- caption,
110
- };
111
- }
112
-
113
- return undefined;
114
- };
115
-
116
- export const imageToExternalHTML = (
117
- block: BlockFromConfig<typeof imageBlockConfig, any, any>,
118
- ) => {
119
- if (!block.props.url) {
120
- const div = document.createElement("p");
121
- div.textContent = "Add image";
122
-
123
- return {
124
- dom: div,
125
- };
126
- }
127
-
128
- let image;
129
- if (block.props.showPreview) {
130
- image = document.createElement("img");
131
- image.src = block.props.url;
132
- image.alt = block.props.name || block.props.caption || "BlockNote image";
133
- if (block.props.previewWidth) {
134
- image.width = block.props.previewWidth;
135
- }
136
- } else {
137
- image = document.createElement("a");
138
- image.href = block.props.url;
139
- image.textContent = block.props.name || block.props.url;
140
- }
141
-
142
- if (block.props.caption) {
143
- if (block.props.showPreview) {
144
- return createFigureWithCaption(image, block.props.caption);
145
- } else {
146
- return createLinkWithCaption(image, block.props.caption);
147
- }
148
- }
149
-
150
- return {
151
- dom: image,
152
- };
153
- };
154
-
155
- export const ImageBlock = createBlockSpec(imageBlockConfig, {
156
- render: imageRender,
157
- parse: imageParse,
158
- toExternalHTML: imageToExternalHTML,
159
- });
@@ -1,134 +0,0 @@
1
- import { InputRule } from "@tiptap/core";
2
- import { updateBlockCommand } from "../../../api/blockManipulation/commands/updateBlock/updateBlock.js";
3
- import { getBlockInfoFromSelection } from "../../../api/getBlockInfoFromPos.js";
4
- import {
5
- PropSchema,
6
- createBlockSpecFromStronglyTypedTiptapNode,
7
- createStronglyTypedTiptapNode,
8
- } from "../../../schema/index.js";
9
- import { createDefaultBlockDOMOutputSpec } from "../../defaultBlockHelpers.js";
10
- import { defaultProps } from "../../defaultProps.js";
11
- import { getListItemContent } from "../getListItemContent.js";
12
- import { handleEnter } from "../ListItemKeyboardShortcuts.js";
13
-
14
- export const bulletListItemPropSchema = {
15
- ...defaultProps,
16
- } satisfies PropSchema;
17
-
18
- const BulletListItemBlockContent = createStronglyTypedTiptapNode({
19
- name: "bulletListItem",
20
- content: "inline*",
21
- group: "blockContent",
22
- // This is to make sure that check list parse rules run before, since they
23
- // both parse `li` elements but check lists are more specific.
24
- priority: 90,
25
- addInputRules() {
26
- return [
27
- // Creates an unordered list when starting with "-", "+", or "*".
28
- new InputRule({
29
- find: new RegExp(`^[-+*]\\s$`),
30
- handler: ({ state, chain, range }) => {
31
- const blockInfo = getBlockInfoFromSelection(state);
32
- if (
33
- !blockInfo.isBlockContainer ||
34
- blockInfo.blockContent.node.type.spec.content !== "inline*" ||
35
- blockInfo.blockNoteType === "heading"
36
- ) {
37
- return;
38
- }
39
-
40
- chain()
41
- .command(
42
- updateBlockCommand(blockInfo.bnBlock.beforePos, {
43
- type: "bulletListItem",
44
- props: {},
45
- }),
46
- )
47
- // Removes the "-", "+", or "*" character used to set the list.
48
- .deleteRange({ from: range.from, to: range.to });
49
- },
50
- }),
51
- ];
52
- },
53
-
54
- addKeyboardShortcuts() {
55
- return {
56
- Enter: () => handleEnter(this.options.editor),
57
- "Mod-Shift-8": () => {
58
- const blockInfo = getBlockInfoFromSelection(this.editor.state);
59
- if (
60
- !blockInfo.isBlockContainer ||
61
- blockInfo.blockContent.node.type.spec.content !== "inline*"
62
- ) {
63
- return true;
64
- }
65
-
66
- return this.editor.commands.command(
67
- updateBlockCommand(blockInfo.bnBlock.beforePos, {
68
- type: "bulletListItem",
69
- props: {},
70
- }),
71
- );
72
- },
73
- };
74
- },
75
-
76
- parseHTML() {
77
- return [
78
- // Parse from internal HTML.
79
- {
80
- tag: "div[data-content-type=" + this.name + "]",
81
- contentElement: ".bn-inline-content",
82
- },
83
- // Parse from external HTML.
84
- {
85
- tag: "li",
86
- getAttrs: (element) => {
87
- if (typeof element === "string") {
88
- return false;
89
- }
90
-
91
- const parent = element.parentElement;
92
-
93
- if (parent === null) {
94
- return false;
95
- }
96
-
97
- if (
98
- parent.tagName === "UL" ||
99
- (parent.tagName === "DIV" && parent.parentElement?.tagName === "UL")
100
- ) {
101
- return {};
102
- }
103
-
104
- return false;
105
- },
106
- // As `li` elements can contain multiple paragraphs, we need to merge their contents
107
- // into a single one so that ProseMirror can parse everything correctly.
108
- getContent: (node, schema) =>
109
- getListItemContent(node, schema, this.name),
110
- node: "bulletListItem",
111
- },
112
- ];
113
- },
114
-
115
- renderHTML({ HTMLAttributes }) {
116
- return createDefaultBlockDOMOutputSpec(
117
- this.name,
118
- // We use a <p> tag, because for <li> tags we'd need a <ul> element to put
119
- // them in to be semantically correct, which we can't have due to the
120
- // schema.
121
- "p",
122
- {
123
- ...(this.options.domAttributes?.blockContent || {}),
124
- ...HTMLAttributes,
125
- },
126
- this.options.domAttributes?.inlineContent || {},
127
- );
128
- },
129
- });
130
-
131
- export const BulletListItem = createBlockSpecFromStronglyTypedTiptapNode(
132
- BulletListItemBlockContent,
133
- bulletListItemPropSchema,
134
- );