@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,201 +1,170 @@
1
1
  import { CellSelection } from "prosemirror-tables";
2
2
  import type { BlockNoteEditor } from "../editor/BlockNoteEditor.js";
3
- import {
4
- BlockConfig,
5
- BlockFromConfig,
6
- BlockSchema,
7
- FileBlockConfig,
8
- InlineContentConfig,
9
- InlineContentSchema,
10
- StyleSchema,
11
- } from "../schema/index.js";
12
- import {
13
- Block,
14
- DefaultBlockSchema,
15
- DefaultInlineContentSchema,
16
- defaultBlockSchema,
17
- defaultInlineContentSchema,
18
- } from "./defaultBlocks.js";
19
- import { defaultProps } from "./defaultProps.js";
3
+ import { BlockConfig, PropSchema, PropSpec } from "../schema/index.js";
4
+ import { Block } from "./defaultBlocks.js";
20
5
  import { Selection } from "prosemirror-state";
21
6
 
22
- export function checkDefaultBlockTypeInSchema<
23
- BlockType extends keyof DefaultBlockSchema,
24
- I extends InlineContentSchema,
25
- S extends StyleSchema,
7
+ export function editorHasBlockWithType<
8
+ BType extends string,
9
+ Props extends
10
+ | PropSchema
11
+ | Record<string, "boolean" | "number" | "string">
12
+ | undefined = undefined,
26
13
  >(
27
- blockType: BlockType,
28
- editor: BlockNoteEditor<any, I, S>,
14
+ editor: BlockNoteEditor<any, any, any>,
15
+ blockType: BType,
16
+ props?: Props,
29
17
  ): editor is BlockNoteEditor<
30
- { [K in BlockType]: DefaultBlockSchema[BlockType] },
31
- I,
32
- S
18
+ {
19
+ [BT in BType]: Props extends PropSchema
20
+ ? BlockConfig<BT, Props>
21
+ : Props extends Record<string, "boolean" | "number" | "string">
22
+ ? BlockConfig<
23
+ BT,
24
+ {
25
+ [PN in keyof Props]: {
26
+ default: undefined;
27
+ type: Props[PN];
28
+ values?: any[];
29
+ };
30
+ }
31
+ >
32
+ : BlockConfig<BT, PropSchema>;
33
+ },
34
+ any,
35
+ any
33
36
  > {
34
- return (
35
- blockType in editor.schema.blockSchema &&
36
- editor.schema.blockSchema[blockType] === defaultBlockSchema[blockType]
37
- );
38
- }
37
+ if (!(blockType in editor.schema.blockSpecs)) {
38
+ return false;
39
+ }
39
40
 
40
- export function checkBlockTypeInSchema<
41
- BlockType extends string,
42
- Config extends BlockConfig,
43
- >(
44
- blockType: BlockType,
45
- blockConfig: Config,
46
- editor: BlockNoteEditor<any, any, any>,
47
- ): editor is BlockNoteEditor<{ [T in BlockType]: Config }, any, any> {
48
- return (
49
- blockType in editor.schema.blockSchema &&
50
- editor.schema.blockSchema[blockType] === blockConfig
51
- );
52
- }
41
+ if (!props) {
42
+ return true;
43
+ }
53
44
 
54
- export function checkDefaultInlineContentTypeInSchema<
55
- InlineContentType extends keyof DefaultInlineContentSchema,
56
- B extends BlockSchema,
57
- S extends StyleSchema,
58
- >(
59
- inlineContentType: InlineContentType,
60
- editor: BlockNoteEditor<B, any, S>,
61
- ): editor is BlockNoteEditor<
62
- B,
63
- { [K in InlineContentType]: DefaultInlineContentSchema[InlineContentType] },
64
- S
65
- > {
66
- return (
67
- inlineContentType in editor.schema.inlineContentSchema &&
68
- editor.schema.inlineContentSchema[inlineContentType] ===
69
- defaultInlineContentSchema[inlineContentType]
70
- );
71
- }
45
+ for (const [propName, propSpec] of Object.entries(props)) {
46
+ if (!(propName in editor.schema.blockSpecs[blockType].config.propSchema)) {
47
+ return false;
48
+ }
72
49
 
73
- export function checkInlineContentTypeInSchema<
74
- InlineContentType extends string,
75
- Config extends InlineContentConfig,
76
- >(
77
- inlineContentType: InlineContentType,
78
- inlineContentConfig: Config,
79
- editor: BlockNoteEditor<any, any, any>,
80
- ): editor is BlockNoteEditor<any, { [T in InlineContentType]: Config }, any> {
81
- return (
82
- inlineContentType in editor.schema.inlineContentSchema &&
83
- editor.schema.inlineContentSchema[inlineContentType] === inlineContentConfig
84
- );
85
- }
50
+ if (typeof propSpec === "string") {
51
+ if (
52
+ editor.schema.blockSpecs[blockType].config.propSchema[propName]
53
+ .default &&
54
+ typeof editor.schema.blockSpecs[blockType].config.propSchema[propName]
55
+ .default !== propSpec
56
+ ) {
57
+ return false;
58
+ }
86
59
 
87
- export function checkBlockIsDefaultType<
88
- BlockType extends keyof DefaultBlockSchema,
89
- I extends InlineContentSchema,
90
- S extends StyleSchema,
91
- >(
92
- blockType: BlockType,
93
- block: Block<any, I, S>,
94
- editor: BlockNoteEditor<any, I, S>,
95
- ): block is BlockFromConfig<DefaultBlockSchema[BlockType], I, S> {
96
- return (
97
- block.type === blockType &&
98
- block.type in editor.schema.blockSchema &&
99
- checkDefaultBlockTypeInSchema(block.type, editor)
100
- );
101
- }
60
+ if (
61
+ editor.schema.blockSpecs[blockType].config.propSchema[propName].type &&
62
+ editor.schema.blockSpecs[blockType].config.propSchema[propName].type !==
63
+ propSpec
64
+ ) {
65
+ return false;
66
+ }
67
+ } else {
68
+ if (
69
+ editor.schema.blockSpecs[blockType].config.propSchema[propName]
70
+ .default !== propSpec.default
71
+ ) {
72
+ return false;
73
+ }
102
74
 
103
- export function checkBlockIsFileBlock<
104
- B extends BlockSchema,
105
- I extends InlineContentSchema,
106
- S extends StyleSchema,
107
- >(
108
- block: Block<any, I, S>,
109
- editor: BlockNoteEditor<B, I, S>,
110
- ): block is BlockFromConfig<FileBlockConfig, I, S> {
111
- return (
112
- (block.type in editor.schema.blockSchema &&
113
- editor.schema.blockSchema[block.type].isFileBlock) ||
114
- false
115
- );
116
- }
75
+ if (
76
+ editor.schema.blockSpecs[blockType].config.propSchema[propName]
77
+ .default === undefined &&
78
+ propSpec.default === undefined
79
+ ) {
80
+ if (
81
+ editor.schema.blockSpecs[blockType].config.propSchema[propName]
82
+ .type !== propSpec.type
83
+ ) {
84
+ return false;
85
+ }
86
+ }
117
87
 
118
- export function checkBlockIsFileBlockWithPreview<
119
- B extends BlockSchema,
120
- I extends InlineContentSchema,
121
- S extends StyleSchema,
122
- >(
123
- block: Block<any, I, S>,
124
- editor: BlockNoteEditor<B, I, S>,
125
- ): block is BlockFromConfig<
126
- FileBlockConfig & {
127
- propSchema: Required<FileBlockConfig["propSchema"]>;
128
- },
129
- I,
130
- S
131
- > {
132
- return (
133
- (block.type in editor.schema.blockSchema &&
134
- editor.schema.blockSchema[block.type].isFileBlock &&
135
- "showPreview" in editor.schema.blockSchema[block.type].propSchema) ||
136
- false
137
- );
138
- }
88
+ if (
89
+ typeof editor.schema.blockSpecs[blockType].config.propSchema[propName]
90
+ .values !== typeof propSpec.values
91
+ ) {
92
+ return false;
93
+ }
94
+
95
+ if (
96
+ typeof editor.schema.blockSpecs[blockType].config.propSchema[propName]
97
+ .values === "object" &&
98
+ typeof propSpec.values === "object"
99
+ ) {
100
+ if (
101
+ editor.schema.blockSpecs[blockType].config.propSchema[propName].values
102
+ .length !== propSpec.values.length
103
+ ) {
104
+ return false;
105
+ }
106
+
107
+ for (
108
+ let i = 0;
109
+ i <
110
+ editor.schema.blockSpecs[blockType].config.propSchema[propName].values
111
+ .length;
112
+ i++
113
+ ) {
114
+ if (
115
+ editor.schema.blockSpecs[blockType].config.propSchema[propName]
116
+ .values[i] !== propSpec.values[i]
117
+ ) {
118
+ return false;
119
+ }
120
+ }
121
+ }
122
+ }
123
+ }
139
124
 
140
- export function checkBlockIsFileBlockWithPlaceholder<
141
- B extends BlockSchema,
142
- I extends InlineContentSchema,
143
- S extends StyleSchema,
144
- >(block: Block<B, I, S>, editor: BlockNoteEditor<B, I, S>) {
145
- const config = editor.schema.blockSchema[block.type];
146
- return config.isFileBlock && !block.props.url;
125
+ return true;
147
126
  }
148
127
 
149
- export function checkBlockTypeHasDefaultProp<
150
- Prop extends keyof typeof defaultProps,
151
- I extends InlineContentSchema,
152
- S extends StyleSchema,
128
+ export function blockHasType<
129
+ BType extends string,
130
+ Props extends
131
+ | PropSchema
132
+ | Record<string, "boolean" | "number" | "string">
133
+ | undefined = undefined,
153
134
  >(
154
- prop: Prop,
155
- blockType: string,
156
- editor: BlockNoteEditor<any, I, S>,
157
- ): editor is BlockNoteEditor<
135
+ block: Block<any, any, any>,
136
+ editor: BlockNoteEditor<any, any, any>,
137
+ blockType: BType,
138
+ props?: Props,
139
+ ): block is Block<
158
140
  {
159
- [BT in string]: {
160
- type: BT;
161
- propSchema: {
162
- [P in Prop]: (typeof defaultProps)[P];
163
- };
164
- content: "table" | "inline" | "none";
165
- };
141
+ [BT in BType]: Props extends PropSchema
142
+ ? BlockConfig<BT, Props>
143
+ : Props extends Record<string, "boolean" | "number" | "string">
144
+ ? BlockConfig<
145
+ BT,
146
+ {
147
+ [PN in keyof Props]: PropSpec<
148
+ Props[PN] extends "boolean"
149
+ ? boolean
150
+ : Props[PN] extends "number"
151
+ ? number
152
+ : Props[PN] extends "string"
153
+ ? string
154
+ : never
155
+ >;
156
+ }
157
+ >
158
+ : BlockConfig<BT, PropSchema>;
166
159
  },
167
- I,
168
- S
160
+ any,
161
+ any
169
162
  > {
170
163
  return (
171
- blockType in editor.schema.blockSchema &&
172
- prop in editor.schema.blockSchema[blockType].propSchema &&
173
- editor.schema.blockSchema[blockType].propSchema[prop] === defaultProps[prop]
164
+ editorHasBlockWithType(editor, blockType, props) && block.type === blockType
174
165
  );
175
166
  }
176
167
 
177
- export function checkBlockHasDefaultProp<
178
- Prop extends keyof typeof defaultProps,
179
- I extends InlineContentSchema,
180
- S extends StyleSchema,
181
- >(
182
- prop: Prop,
183
- block: Block<any, I, S>,
184
- editor: BlockNoteEditor<any, I, S>,
185
- ): block is BlockFromConfig<
186
- {
187
- type: string;
188
- propSchema: {
189
- [P in Prop]: (typeof defaultProps)[P];
190
- };
191
- content: "table" | "inline" | "none";
192
- },
193
- I,
194
- S
195
- > {
196
- return checkBlockTypeHasDefaultProp(prop, block.type, editor);
197
- }
198
-
199
168
  export function isTableCellSelection(
200
169
  selection: Selection,
201
170
  ): selection is CellSelection {
@@ -3,60 +3,132 @@ import Code from "@tiptap/extension-code";
3
3
  import Italic from "@tiptap/extension-italic";
4
4
  import Strike from "@tiptap/extension-strike";
5
5
  import Underline from "@tiptap/extension-underline";
6
- import { BackgroundColor } from "../extensions/BackgroundColor/BackgroundColorMark.js";
7
- import { TextColor } from "../extensions/TextColor/TextColorMark.js";
6
+ import {
7
+ createAudioBlockSpec,
8
+ createBulletListItemBlockSpec,
9
+ createCheckListItemBlockSpec,
10
+ createCodeBlockSpec,
11
+ createFileBlockSpec,
12
+ createHeadingBlockSpec,
13
+ createImageBlockSpec,
14
+ createNumberedListItemBlockSpec,
15
+ createParagraphBlockSpec,
16
+ createQuoteBlockSpec,
17
+ createToggleListItemBlockSpec,
18
+ createVideoBlockSpec,
19
+ defaultProps,
20
+ } from "./index.js";
8
21
  import {
9
22
  BlockNoDefaults,
10
23
  BlockSchema,
11
- BlockSpecs,
12
24
  InlineContentSchema,
13
25
  InlineContentSpecs,
14
26
  PartialBlockNoDefaults,
15
27
  StyleSchema,
16
28
  StyleSpecs,
29
+ createStyleSpec,
17
30
  createStyleSpecFromTipTapMark,
18
- getBlockSchemaFromSpecs,
19
31
  getInlineContentSchemaFromSpecs,
20
32
  getStyleSchemaFromSpecs,
21
33
  } from "../schema/index.js";
22
-
23
- import { AudioBlock } from "./AudioBlockContent/AudioBlockContent.js";
24
- import { CodeBlock } from "./CodeBlockContent/CodeBlockContent.js";
25
- import { FileBlock } from "./FileBlockContent/FileBlockContent.js";
26
- import { Heading } from "./HeadingBlockContent/HeadingBlockContent.js";
27
- import { ImageBlock } from "./ImageBlockContent/ImageBlockContent.js";
28
- import { ToggleListItem } from "./ListItemBlockContent/ToggleListItemBlockContent/ToggleListItemBlockContent.js";
29
- import { BulletListItem } from "./ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.js";
30
- import { CheckListItem } from "./ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.js";
31
- import { NumberedListItem } from "./ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.js";
32
- import { Paragraph } from "./ParagraphBlockContent/ParagraphBlockContent.js";
33
- import { Quote } from "./QuoteBlockContent/QuoteBlockContent.js";
34
- import { Table } from "./TableBlockContent/TableBlockContent.js";
35
- import { VideoBlock } from "./VideoBlockContent/VideoBlockContent.js";
34
+ import { createTableBlockSpec } from "./Table/block.js";
35
+ import { COLORS_DEFAULT } from "../editor/defaultColors.js";
36
36
 
37
37
  export const defaultBlockSpecs = {
38
- paragraph: Paragraph,
39
- heading: Heading,
40
- quote: Quote,
41
- codeBlock: CodeBlock,
42
- toggleListItem: ToggleListItem,
43
- bulletListItem: BulletListItem,
44
- numberedListItem: NumberedListItem,
45
- checkListItem: CheckListItem,
46
- table: Table,
47
- file: FileBlock,
48
- image: ImageBlock,
49
- video: VideoBlock,
50
- audio: AudioBlock,
51
- } satisfies BlockSpecs;
52
-
53
- export const defaultBlockSchema = getBlockSchemaFromSpecs(defaultBlockSpecs);
38
+ audio: createAudioBlockSpec(),
39
+ bulletListItem: createBulletListItemBlockSpec(),
40
+ checkListItem: createCheckListItemBlockSpec(),
41
+ codeBlock: createCodeBlockSpec(),
42
+ file: createFileBlockSpec(),
43
+ heading: createHeadingBlockSpec(),
44
+ image: createImageBlockSpec(),
45
+ numberedListItem: createNumberedListItemBlockSpec(),
46
+ paragraph: createParagraphBlockSpec(),
47
+ quote: createQuoteBlockSpec(),
48
+ table: createTableBlockSpec(),
49
+ toggleListItem: createToggleListItemBlockSpec(),
50
+ video: createVideoBlockSpec(),
51
+ } as const;
54
52
 
55
53
  // underscore is used that in case a user overrides DefaultBlockSchema,
56
54
  // they can still access the original default block schema
57
- export type _DefaultBlockSchema = typeof defaultBlockSchema;
55
+ export type _DefaultBlockSchema = {
56
+ [K in keyof typeof defaultBlockSpecs]: (typeof defaultBlockSpecs)[K]["config"];
57
+ };
58
58
  export type DefaultBlockSchema = _DefaultBlockSchema;
59
59
 
60
+ const TextColor = createStyleSpec(
61
+ {
62
+ type: "textColor",
63
+ propSchema: "string",
64
+ },
65
+ {
66
+ render: () => {
67
+ const span = document.createElement("span");
68
+
69
+ return {
70
+ dom: span,
71
+ contentDOM: span,
72
+ };
73
+ },
74
+ toExternalHTML: (value) => {
75
+ const span = document.createElement("span");
76
+ if (value !== defaultProps.textColor.default) {
77
+ span.style.color =
78
+ value in COLORS_DEFAULT ? COLORS_DEFAULT[value].text : value;
79
+ }
80
+
81
+ return {
82
+ dom: span,
83
+ contentDOM: span,
84
+ };
85
+ },
86
+ parse: (element) => {
87
+ if (element.tagName === "SPAN" && element.style.color) {
88
+ return element.style.color;
89
+ }
90
+
91
+ return undefined;
92
+ },
93
+ },
94
+ );
95
+
96
+ const BackgroundColor = createStyleSpec(
97
+ {
98
+ type: "backgroundColor",
99
+ propSchema: "string",
100
+ },
101
+ {
102
+ render: () => {
103
+ const span = document.createElement("span");
104
+
105
+ return {
106
+ dom: span,
107
+ contentDOM: span,
108
+ };
109
+ },
110
+ toExternalHTML: (value) => {
111
+ const span = document.createElement("span");
112
+ if (value !== defaultProps.backgroundColor.default) {
113
+ span.style.backgroundColor =
114
+ value in COLORS_DEFAULT ? COLORS_DEFAULT[value].background : value;
115
+ }
116
+
117
+ return {
118
+ dom: span,
119
+ contentDOM: span,
120
+ };
121
+ },
122
+ parse: (element) => {
123
+ if (element.tagName === "SPAN" && element.style.backgroundColor) {
124
+ return element.style.backgroundColor;
125
+ }
126
+
127
+ return undefined;
128
+ },
129
+ },
130
+ );
131
+
60
132
  export const defaultStyleSpecs = {
61
133
  bold: createStyleSpecFromTipTapMark(Bold, "boolean"),
62
134
  italic: createStyleSpecFromTipTapMark(Italic, "boolean"),
@@ -1,3 +1,6 @@
1
+ import { Attribute } from "@tiptap/core";
2
+
3
+ import { COLORS_DEFAULT } from "../editor/defaultColors.js";
1
4
  import type { Props, PropSchema } from "../schema/index.js";
2
5
 
3
6
  // TODO: this system should probably be moved / refactored.
@@ -18,7 +21,145 @@ export const defaultProps = {
18
21
 
19
22
  export type DefaultProps = Props<typeof defaultProps>;
20
23
 
21
- // Default props which are set on `blockContainer` nodes rather than
22
- // `blockContent` nodes. Ensures that they are not redundantly added to
23
- // a custom block's TipTap node attributes.
24
- export const inheritedProps = ["backgroundColor", "textColor"];
24
+ export const parseDefaultProps = (element: HTMLElement) => {
25
+ const props: Partial<DefaultProps> = {};
26
+
27
+ // If the `data-` attribute is found, set the prop to the value, as this most
28
+ // likely means the parsed element was exported by BlockNote originally.
29
+ // Otherwise, just use whatever is found in the inline styles, if anything.
30
+ if (element.hasAttribute("data-background-color")) {
31
+ props.backgroundColor = element.getAttribute("data-background-color")!;
32
+ } else if (element.style.backgroundColor) {
33
+ props.backgroundColor = element.style.backgroundColor;
34
+ }
35
+
36
+ // If the `data-` attribute is found, set the prop to the value, as this most
37
+ // likely means the parsed element was exported by BlockNote originally.
38
+ // Otherwise, just use whatever is found in the inline styles, if anything.
39
+ if (element.hasAttribute("data-text-color")) {
40
+ props.textColor = element.getAttribute("data-text-color")!;
41
+ } else if (element.style.color) {
42
+ props.textColor = element.style.color;
43
+ }
44
+
45
+ props.textAlignment = defaultProps.textAlignment.values.includes(
46
+ element.style.textAlign as DefaultProps["textAlignment"],
47
+ )
48
+ ? (element.style.textAlign as DefaultProps["textAlignment"])
49
+ : undefined;
50
+
51
+ return props;
52
+ };
53
+
54
+ export const addDefaultPropsExternalHTML = (
55
+ props: Partial<DefaultProps>,
56
+ element: HTMLElement,
57
+ ) => {
58
+ if (
59
+ props.backgroundColor &&
60
+ props.backgroundColor !== defaultProps.backgroundColor.default
61
+ ) {
62
+ // The color can be any string. If the string matches one of the default
63
+ // theme color names, set the theme color. Otherwise, set the color as-is
64
+ // (may be a CSS color name, hex value, RGB value, etc).
65
+ element.style.backgroundColor =
66
+ props.backgroundColor in COLORS_DEFAULT
67
+ ? COLORS_DEFAULT[props.backgroundColor].background
68
+ : props.backgroundColor;
69
+ }
70
+
71
+ if (props.textColor && props.textColor !== defaultProps.textColor.default) {
72
+ // The color can be any string. If the string matches one of the default
73
+ // theme color names, set the theme color. Otherwise, set the color as-is
74
+ // (may be a CSS color name, hex value, RGB value, etc).
75
+ element.style.color =
76
+ props.textColor in COLORS_DEFAULT
77
+ ? COLORS_DEFAULT[props.textColor].text
78
+ : props.textColor;
79
+ }
80
+
81
+ if (
82
+ props.textAlignment &&
83
+ props.textAlignment !== defaultProps.textAlignment.default
84
+ ) {
85
+ element.style.textAlign = props.textAlignment;
86
+ }
87
+ };
88
+
89
+ export const getBackgroundColorAttribute = (
90
+ attributeName = "backgroundColor",
91
+ ): Attribute => ({
92
+ default: defaultProps.backgroundColor.default,
93
+ parseHTML: (element) => {
94
+ if (element.hasAttribute("data-background-color")) {
95
+ return element.getAttribute("data-background-color")!;
96
+ }
97
+
98
+ if (element.style.backgroundColor) {
99
+ return element.style.backgroundColor;
100
+ }
101
+
102
+ return defaultProps.backgroundColor.default;
103
+ },
104
+ renderHTML: (attributes) => {
105
+ if (attributes[attributeName] === defaultProps.backgroundColor.default) {
106
+ return {};
107
+ }
108
+
109
+ return {
110
+ "data-background-color": attributes[attributeName],
111
+ };
112
+ },
113
+ });
114
+
115
+ export const getTextColorAttribute = (
116
+ attributeName = "textColor",
117
+ ): Attribute => ({
118
+ default: defaultProps.textColor.default,
119
+ parseHTML: (element) => {
120
+ if (element.hasAttribute("data-text-color")) {
121
+ return element.getAttribute("data-text-color")!;
122
+ }
123
+
124
+ if (element.style.color) {
125
+ return element.style.color;
126
+ }
127
+
128
+ return defaultProps.textColor.default;
129
+ },
130
+ renderHTML: (attributes) => {
131
+ if (attributes[attributeName] === defaultProps.textColor.default) {
132
+ return {};
133
+ }
134
+
135
+ return {
136
+ "data-text-color": attributes[attributeName],
137
+ };
138
+ },
139
+ });
140
+
141
+ export const getTextAlignmentAttribute = (
142
+ attributeName = "textAlignment",
143
+ ): Attribute => ({
144
+ default: defaultProps.textAlignment.default,
145
+ parseHTML: (element) => {
146
+ if (element.hasAttribute("data-text-alignment")) {
147
+ return element.getAttribute("data-text-alignment");
148
+ }
149
+
150
+ if (element.style.textAlign) {
151
+ return element.style.textAlign;
152
+ }
153
+
154
+ return defaultProps.textAlignment.default;
155
+ },
156
+ renderHTML: (attributes) => {
157
+ if (attributes[attributeName] === defaultProps.textAlignment.default) {
158
+ return {};
159
+ }
160
+
161
+ return {
162
+ "data-text-alignment": attributes[attributeName],
163
+ };
164
+ },
165
+ });