@blocknote/core 0.38.0 → 0.39.1-capitol
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/BlockNoteSchema-Bsa_tSAC.cjs +11 -0
- package/dist/BlockNoteSchema-Bsa_tSAC.cjs.map +1 -0
- package/dist/BlockNoteSchema-CZez1nQf.js +4244 -0
- package/dist/BlockNoteSchema-CZez1nQf.js.map +1 -0
- package/dist/blocknote.cjs +4 -12
- package/dist/blocknote.cjs.map +1 -1
- package/dist/blocknote.js +3401 -7305
- package/dist/blocknote.js.map +1 -1
- package/dist/blocks.cjs +2 -0
- package/dist/blocks.cjs.map +1 -0
- package/dist/blocks.js +71 -0
- package/dist/blocks.js.map +1 -0
- package/dist/style.css +1 -1
- package/dist/webpack-stats.json +1 -1
- package/package.json +19 -17
- package/src/api/blockManipulation/commands/insertBlocks/insertBlocks.ts +1 -1
- package/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.ts +2 -2
- package/src/api/blockManipulation/commands/splitBlock/splitBlock.ts +34 -25
- package/src/api/blockManipulation/setupTestEnv.ts +0 -1
- package/src/api/clipboard/fromClipboard/handleFileInsertion.ts +6 -10
- package/src/api/clipboard/fromClipboard/pasteExtension.ts +1 -1
- package/src/api/clipboard/toClipboard/copyExtension.ts +1 -1
- package/src/api/exporters/html/util/serializeBlocksExternalHTML.ts +128 -28
- package/src/api/exporters/html/util/serializeBlocksInternalHTML.ts +101 -41
- package/src/api/pmUtil.ts +1 -1
- package/src/api/positionMapping.test.ts +58 -15
- package/src/api/positionMapping.ts +2 -4
- package/src/blocks/Audio/block.ts +174 -0
- package/src/blocks/BlockNoteSchema.ts +59 -0
- package/src/blocks/Code/block.ts +299 -0
- package/src/blocks/File/block.ts +98 -0
- package/src/blocks/{FileBlockContent → File}/helpers/render/createAddFileButton.ts +5 -2
- package/src/blocks/{FileBlockContent → File}/helpers/render/createFileBlockWrapper.ts +15 -6
- package/src/blocks/{FileBlockContent → File}/helpers/render/createFileNameWithIcon.ts +15 -2
- package/src/blocks/{FileBlockContent → File}/helpers/render/createResizableFileBlockWrapper.ts +21 -2
- package/src/blocks/Heading/block.ts +138 -0
- package/src/blocks/Image/block.ts +190 -0
- package/src/blocks/ListItem/BulletListItem/block.ts +116 -0
- package/src/blocks/ListItem/CheckListItem/block.ts +175 -0
- package/src/blocks/ListItem/NumberedListItem/IndexingPlugin.ts +173 -0
- package/src/blocks/ListItem/NumberedListItem/block.ts +133 -0
- package/src/blocks/ListItem/ToggleListItem/block.ts +78 -0
- package/src/blocks/PageBreak/block.ts +72 -0
- package/src/blocks/{PageBreakBlockContent → PageBreak}/getPageBreakSlashMenuItems.ts +9 -7
- package/src/blocks/Paragraph/block.ts +80 -0
- package/src/blocks/Quote/block.ts +90 -0
- package/src/blocks/{TableBlockContent/TableBlockContent.ts → Table/block.ts} +169 -51
- package/src/blocks/ToggleWrapper/createToggleWrapper.ts +1 -1
- package/src/blocks/Video/block.ts +143 -0
- package/src/blocks/defaultBlockHelpers.ts +2 -2
- package/src/blocks/defaultBlockTypeGuards.ts +143 -174
- package/src/blocks/defaultBlocks.ts +107 -35
- package/src/blocks/defaultProps.ts +145 -4
- package/src/blocks/index.ts +26 -0
- package/src/blocks/utils/listItemEnterHandler.ts +42 -0
- package/src/editor/Block.css +54 -18
- package/src/editor/BlockNoteEditor.ts +256 -211
- package/src/editor/BlockNoteExtension.ts +92 -0
- package/src/editor/BlockNoteExtensions.ts +18 -17
- package/src/editor/defaultColors.ts +2 -2
- package/src/exporter/Exporter.ts +1 -1
- package/src/exporter/mapping.ts +1 -1
- package/src/extensions/BackgroundColor/BackgroundColorExtension.ts +3 -20
- package/src/extensions/BackgroundColor/BackgroundColorMark.ts +6 -8
- package/src/extensions/BlockChange/BlockChangePlugin.ts +2 -1
- package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-editor-forked.json +2 -2
- package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-editor.json +2 -2
- package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-forked.html +1 -1
- package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap.html +1 -1
- package/src/extensions/Collaboration/schemaMigration/SchemaMigrationPlugin.ts +52 -0
- package/src/extensions/Collaboration/schemaMigration/migrationRules/index.ts +4 -0
- package/src/extensions/Collaboration/schemaMigration/migrationRules/migrationRule.ts +4 -0
- package/src/extensions/Collaboration/schemaMigration/migrationRules/moveColorAttributes.ts +78 -0
- package/src/extensions/Comments/CommentsPlugin.ts +1 -1
- package/src/extensions/FilePanel/FilePanelPlugin.ts +5 -10
- package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +1 -1
- package/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.ts +4 -3
- package/src/extensions/Placeholder/PlaceholderPlugin.ts +6 -6
- package/src/extensions/PreviousBlockType/PreviousBlockTypePlugin.ts +1 -23
- package/src/extensions/SideMenu/SideMenuPlugin.ts +1 -3
- package/src/extensions/SideMenu/dragging.ts +2 -2
- package/src/extensions/SuggestionMenu/SuggestionPlugin.ts +4 -7
- package/src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.ts +6 -2
- package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +24 -17
- package/src/extensions/TableHandles/TableHandlesPlugin.ts +8 -8
- package/src/extensions/TextAlignment/TextAlignmentExtension.ts +5 -11
- package/src/extensions/TextColor/TextColorExtension.ts +3 -17
- package/src/extensions/TextColor/TextColorMark.ts +4 -9
- package/src/extensions/UniqueID/UniqueID.ts +6 -13
- package/src/index.ts +2 -28
- package/src/schema/blocks/createSpec.ts +342 -169
- package/src/schema/blocks/internal.ts +77 -138
- package/src/schema/blocks/types.ts +264 -94
- package/src/schema/index.ts +1 -0
- package/src/schema/inlineContent/createSpec.ts +99 -21
- package/src/schema/inlineContent/internal.ts +16 -7
- package/src/schema/inlineContent/types.ts +24 -2
- package/src/schema/propTypes.ts +15 -9
- package/src/schema/schema.ts +209 -0
- package/src/schema/styles/createSpec.ts +79 -31
- package/src/schema/styles/internal.ts +61 -2
- package/src/schema/styles/types.ts +17 -3
- package/src/util/topo-sort.test.ts +125 -0
- package/src/util/topo-sort.ts +160 -0
- package/types/src/api/blockManipulation/commands/splitBlock/splitBlock.d.ts +2 -1
- package/types/src/api/blockManipulation/selections/selection.d.ts +1 -1
- package/types/src/api/blockManipulation/setupTestEnv.d.ts +29 -543
- package/types/src/api/exporters/html/util/serializeBlocksExternalHTML.d.ts +1 -1
- package/types/src/api/exporters/html/util/serializeBlocksInternalHTML.d.ts +1 -1
- package/types/src/api/exporters/markdown/util/convertVideoToMarkdownRehypePlugin.d.ts +2 -0
- package/types/src/api/exporters/markdown/util/removeUnderlinesRehypePlugin.d.ts +6 -0
- package/types/src/api/pmUtil.d.ts +1 -1
- package/types/src/blocks/Audio/block.d.ts +58 -0
- package/types/src/blocks/BlockNoteSchema.d.ts +18 -0
- package/types/src/blocks/{CodeBlockContent/CodeBlockContent.d.ts → Code/block.d.ts} +25 -26
- package/types/src/blocks/Code/shiki.d.ts +4 -0
- package/types/src/blocks/Divider/block.d.ts +3 -0
- package/types/src/blocks/File/block.d.ts +37 -0
- package/types/src/blocks/File/helpers/render/createAddFileButton.d.ts +6 -0
- package/types/src/blocks/File/helpers/render/createFileBlockWrapper.d.ts +25 -0
- package/types/src/blocks/{FileBlockContent → File}/helpers/render/createFileNameWithIcon.d.ts +6 -2
- package/types/src/blocks/File/helpers/render/createResizableFileBlockWrapper.d.ts +31 -0
- package/types/src/blocks/Heading/block.d.ts +71 -0
- package/types/src/blocks/Image/block.d.ts +102 -0
- package/types/src/blocks/ListItem/BulletListItem/block.d.ts +25 -0
- package/types/src/blocks/ListItem/CheckListItem/block.d.ts +33 -0
- package/types/src/blocks/ListItem/NumberedListItem/IndexingPlugin.d.ts +8 -0
- package/types/src/blocks/ListItem/NumberedListItem/block.d.ts +33 -0
- package/types/src/blocks/ListItem/ToggleListItem/block.d.ts +25 -0
- package/types/src/blocks/PageBreak/block.d.ts +11 -0
- package/types/src/blocks/{PageBreakBlockContent → PageBreak}/getPageBreakSlashMenuItems.d.ts +4 -2
- package/types/src/blocks/Paragraph/block.d.ts +25 -0
- package/types/src/blocks/Quote/block.d.ts +17 -0
- package/types/src/blocks/Table/block.d.ts +21 -0
- package/types/src/blocks/Video/block.d.ts +67 -0
- package/types/src/blocks/defaultBlockHelpers.d.ts +1 -1
- package/types/src/blocks/defaultBlockTypeGuards.d.ts +15 -36
- package/types/src/blocks/defaultBlocks.d.ts +221 -1060
- package/types/src/blocks/defaultProps.d.ts +17 -1
- package/types/src/blocks/index.d.ts +24 -0
- package/types/src/blocks/utils/listItemEnterHandler.d.ts +2 -0
- package/types/src/editor/BlockNoteEditor.d.ts +36 -67
- package/types/src/editor/BlockNoteExtension.d.ts +67 -0
- package/types/src/editor/BlockNoteExtensions.d.ts +1 -1
- package/types/src/editor/defaultColors.d.ts +8 -76
- package/types/src/editor/managers/BlockManager.d.ts +114 -0
- package/types/src/editor/managers/CollaborationManager.d.ts +115 -0
- package/types/src/editor/managers/EventManager.d.ts +58 -0
- package/types/src/editor/managers/ExportManager.d.ts +64 -0
- package/types/src/editor/managers/ExtensionManager.d.ts +68 -0
- package/types/src/editor/managers/SelectionManager.d.ts +54 -0
- package/types/src/editor/managers/StateManager.d.ts +115 -0
- package/types/src/editor/managers/StyleManager.d.ts +48 -0
- package/types/src/editor/managers/index.d.ts +8 -0
- package/types/src/exporter/Exporter.d.ts +1 -1
- package/types/src/exporter/mapping.d.ts +1 -1
- package/types/src/extensions/BackgroundColor/BackgroundColorMark.d.ts +4 -1
- package/types/src/extensions/Collaboration/schemaMigration/SchemaMigrationPlugin.d.ts +7 -0
- package/types/src/extensions/Collaboration/schemaMigration/migrationRules/index.d.ts +3 -0
- package/types/src/extensions/Collaboration/schemaMigration/migrationRules/migrationRule.d.ts +3 -0
- package/types/src/extensions/Collaboration/schemaMigration/migrationRules/moveColorAttributes.d.ts +2 -0
- package/types/src/extensions/Comments/CommentsPlugin.d.ts +1 -1
- package/types/src/extensions/FilePanel/FilePanelPlugin.d.ts +4 -4
- package/types/src/extensions/TextColor/TextColorMark.d.ts +4 -1
- package/types/src/index.d.ts +2 -25
- package/types/src/schema/blocks/createSpec.d.ts +16 -36
- package/types/src/schema/blocks/internal.d.ts +11 -33
- package/types/src/schema/blocks/types.d.ts +181 -57
- package/types/src/schema/index.d.ts +1 -0
- package/types/src/schema/inlineContent/createSpec.d.ts +36 -2
- package/types/src/schema/inlineContent/internal.d.ts +7 -15
- package/types/src/schema/inlineContent/types.d.ts +15 -1
- package/types/src/schema/propTypes.d.ts +4 -4
- package/types/src/schema/schema.d.ts +40 -0
- package/types/src/schema/styles/createSpec.d.ts +6 -4
- package/types/src/schema/styles/internal.d.ts +6 -3
- package/types/src/schema/styles/types.d.ts +11 -2
- package/types/src/util/topo-sort.d.ts +18 -0
- package/types/src/util/topo-sort.test.d.ts +1 -0
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/blocks/AudioBlockContent/AudioBlockContent.ts +0 -144
- package/src/blocks/CodeBlockContent/CodeBlockContent.ts +0 -445
- package/src/blocks/FileBlockContent/FileBlockContent.ts +0 -100
- package/src/blocks/HeadingBlockContent/HeadingBlockContent.ts +0 -159
- package/src/blocks/ImageBlockContent/ImageBlockContent.ts +0 -159
- package/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +0 -134
- package/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.ts +0 -299
- package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts +0 -86
- package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +0 -172
- package/src/blocks/ListItemBlockContent/ToggleListItemBlockContent/ToggleListItemBlockContent.ts +0 -104
- package/src/blocks/PageBreakBlockContent/PageBreakBlockContent.ts +0 -49
- package/src/blocks/PageBreakBlockContent/schema.ts +0 -40
- package/src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts +0 -78
- package/src/blocks/QuoteBlockContent/QuoteBlockContent.ts +0 -121
- package/src/blocks/VideoBlockContent/VideoBlockContent.ts +0 -158
- package/src/editor/BlockNoteSchema.ts +0 -107
- package/src/editor/BlockNoteTipTapEditor.ts +0 -335
- package/types/src/blocks/AudioBlockContent/AudioBlockContent.d.ts +0 -99
- package/types/src/blocks/FileBlockContent/FileBlockContent.d.ts +0 -90
- package/types/src/blocks/FileBlockContent/helpers/render/createAddFileButton.d.ts +0 -6
- package/types/src/blocks/FileBlockContent/helpers/render/createFileBlockWrapper.d.ts +0 -9
- package/types/src/blocks/FileBlockContent/helpers/render/createResizableFileBlockWrapper.d.ts +0 -9
- package/types/src/blocks/HeadingBlockContent/HeadingBlockContent.d.ts +0 -67
- package/types/src/blocks/ImageBlockContent/ImageBlockContent.d.ts +0 -131
- package/types/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.d.ts +0 -46
- package/types/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.d.ts +0 -55
- package/types/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.d.ts +0 -2
- package/types/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.d.ts +0 -58
- package/types/src/blocks/ListItemBlockContent/ToggleListItemBlockContent/ToggleListItemBlockContent.d.ts +0 -46
- package/types/src/blocks/PageBreakBlockContent/PageBreakBlockContent.d.ts +0 -31
- package/types/src/blocks/PageBreakBlockContent/schema.d.ts +0 -86
- package/types/src/blocks/ParagraphBlockContent/ParagraphBlockContent.d.ts +0 -52
- package/types/src/blocks/QuoteBlockContent/QuoteBlockContent.d.ts +0 -52
- package/types/src/blocks/TableBlockContent/TableBlockContent.d.ts +0 -39
- package/types/src/blocks/VideoBlockContent/VideoBlockContent.d.ts +0 -131
- package/types/src/editor/BlockNoteSchema.d.ts +0 -34
- package/types/src/editor/BlockNoteTipTapEditor.d.ts +0 -43
- /package/src/blocks/{AudioBlockContent → Audio}/parseAudioElement.ts +0 -0
- /package/src/blocks/{FileBlockContent → File}/helpers/parse/parseEmbedElement.ts +0 -0
- /package/src/blocks/{FileBlockContent → File}/helpers/parse/parseFigureElement.ts +0 -0
- /package/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createFigureWithCaption.ts +0 -0
- /package/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createLinkWithCaption.ts +0 -0
- /package/src/blocks/{FileBlockContent → File/helpers}/uploadToTmpFilesDotOrg_DEV_ONLY.ts +0 -0
- /package/src/blocks/{ImageBlockContent → Image}/parseImageElement.ts +0 -0
- /package/src/blocks/{ListItemBlockContent → ListItem}/ListItemKeyboardShortcuts.ts +0 -0
- /package/src/blocks/{ListItemBlockContent → ListItem}/getListItemContent.ts +0 -0
- /package/src/blocks/{TableBlockContent → Table}/TableExtension.ts +0 -0
- /package/src/blocks/{VideoBlockContent → Video}/parseVideoElement.ts +0 -0
- /package/types/src/blocks/{AudioBlockContent → Audio}/parseAudioElement.d.ts +0 -0
- /package/types/src/blocks/{FileBlockContent → File}/helpers/parse/parseEmbedElement.d.ts +0 -0
- /package/types/src/blocks/{FileBlockContent → File}/helpers/parse/parseFigureElement.d.ts +0 -0
- /package/types/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createFigureWithCaption.d.ts +0 -0
- /package/types/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createLinkWithCaption.d.ts +0 -0
- /package/types/src/blocks/{FileBlockContent → File/helpers}/uploadToTmpFilesDotOrg_DEV_ONLY.d.ts +0 -0
- /package/types/src/blocks/{ImageBlockContent → Image}/parseImageElement.d.ts +0 -0
- /package/types/src/blocks/{ListItemBlockContent → ListItem}/ListItemKeyboardShortcuts.d.ts +0 -0
- /package/types/src/blocks/{ListItemBlockContent → ListItem}/getListItemContent.d.ts +0 -0
- /package/types/src/blocks/{TableBlockContent → Table}/TableExtension.d.ts +0 -0
- /package/types/src/blocks/{VideoBlockContent → Video}/parseVideoElement.d.ts +0 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { BlockNoteEditor } from "../../editor/BlockNoteEditor.js";
|
|
2
|
+
import {
|
|
3
|
+
BlockFromConfig,
|
|
4
|
+
createBlockConfig,
|
|
5
|
+
createBlockSpec,
|
|
6
|
+
} from "../../schema/index.js";
|
|
7
|
+
import { defaultProps, parseDefaultProps } from "../defaultProps.js";
|
|
8
|
+
import { parseFigureElement } from "../File/helpers/parse/parseFigureElement.js";
|
|
9
|
+
import { createFileBlockWrapper } from "../File/helpers/render/createFileBlockWrapper.js";
|
|
10
|
+
import { createFigureWithCaption } from "../File/helpers/toExternalHTML/createFigureWithCaption.js";
|
|
11
|
+
import { createLinkWithCaption } from "../File/helpers/toExternalHTML/createLinkWithCaption.js";
|
|
12
|
+
import { parseAudioElement } from "./parseAudioElement.js";
|
|
13
|
+
|
|
14
|
+
export const FILE_AUDIO_ICON_SVG =
|
|
15
|
+
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M2 16.0001H5.88889L11.1834 20.3319C11.2727 20.405 11.3846 20.4449 11.5 20.4449C11.7761 20.4449 12 20.2211 12 19.9449V4.05519C12 3.93977 11.9601 3.8279 11.887 3.73857C11.7121 3.52485 11.3971 3.49335 11.1834 3.66821L5.88889 8.00007H2C1.44772 8.00007 1 8.44778 1 9.00007V15.0001C1 15.5524 1.44772 16.0001 2 16.0001ZM23 12C23 15.292 21.5539 18.2463 19.2622 20.2622L17.8445 18.8444C19.7758 17.1937 21 14.7398 21 12C21 9.26016 19.7758 6.80629 17.8445 5.15557L19.2622 3.73779C21.5539 5.75368 23 8.70795 23 12ZM18 12C18 10.0883 17.106 8.38548 15.7133 7.28673L14.2842 8.71584C15.3213 9.43855 16 10.64 16 12C16 13.36 15.3213 14.5614 14.2842 15.2841L15.7133 16.7132C17.106 15.6145 18 13.9116 18 12Z"></path></svg>';
|
|
16
|
+
|
|
17
|
+
export interface AudioOptions {
|
|
18
|
+
icon?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type AudioBlockConfig = ReturnType<typeof createAudioBlockConfig>;
|
|
22
|
+
|
|
23
|
+
export const createAudioBlockConfig = createBlockConfig(
|
|
24
|
+
(_ctx: AudioOptions) =>
|
|
25
|
+
({
|
|
26
|
+
type: "audio" as const,
|
|
27
|
+
propSchema: {
|
|
28
|
+
backgroundColor: defaultProps.backgroundColor,
|
|
29
|
+
// File name.
|
|
30
|
+
name: {
|
|
31
|
+
default: "" as const,
|
|
32
|
+
},
|
|
33
|
+
// File url.
|
|
34
|
+
url: {
|
|
35
|
+
default: "" as const,
|
|
36
|
+
},
|
|
37
|
+
// File caption.
|
|
38
|
+
caption: {
|
|
39
|
+
default: "" as const,
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
showPreview: {
|
|
43
|
+
default: true,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
content: "none",
|
|
47
|
+
}) as const,
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
export const audioParse =
|
|
51
|
+
(_config: AudioOptions = {}) =>
|
|
52
|
+
(element: HTMLElement) => {
|
|
53
|
+
if (element.tagName === "AUDIO") {
|
|
54
|
+
// Ignore if parent figure has already been parsed.
|
|
55
|
+
if (element.closest("figure")) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const { backgroundColor } = parseDefaultProps(element);
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
...parseAudioElement(element as HTMLAudioElement),
|
|
63
|
+
backgroundColor,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (element.tagName === "FIGURE") {
|
|
68
|
+
const parsedFigure = parseFigureElement(element, "audio");
|
|
69
|
+
if (!parsedFigure) {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const { targetElement, caption } = parsedFigure;
|
|
74
|
+
|
|
75
|
+
const { backgroundColor } = parseDefaultProps(element);
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
...parseAudioElement(targetElement as HTMLAudioElement),
|
|
79
|
+
backgroundColor,
|
|
80
|
+
caption,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return undefined;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const audioRender =
|
|
88
|
+
(config: AudioOptions = {}) =>
|
|
89
|
+
(
|
|
90
|
+
block: BlockFromConfig<ReturnType<typeof createAudioBlockConfig>, any, any>,
|
|
91
|
+
editor: BlockNoteEditor<
|
|
92
|
+
Record<"audio", ReturnType<typeof createAudioBlockConfig>>,
|
|
93
|
+
any,
|
|
94
|
+
any
|
|
95
|
+
>,
|
|
96
|
+
) => {
|
|
97
|
+
const icon = document.createElement("div");
|
|
98
|
+
icon.innerHTML = config.icon ?? FILE_AUDIO_ICON_SVG;
|
|
99
|
+
|
|
100
|
+
const audio = document.createElement("audio");
|
|
101
|
+
audio.className = "bn-audio";
|
|
102
|
+
if (editor.resolveFileUrl) {
|
|
103
|
+
editor.resolveFileUrl(block.props.url).then((downloadUrl) => {
|
|
104
|
+
audio.src = downloadUrl;
|
|
105
|
+
});
|
|
106
|
+
} else {
|
|
107
|
+
audio.src = block.props.url;
|
|
108
|
+
}
|
|
109
|
+
audio.controls = true;
|
|
110
|
+
audio.contentEditable = "false";
|
|
111
|
+
audio.draggable = false;
|
|
112
|
+
|
|
113
|
+
return createFileBlockWrapper(
|
|
114
|
+
block,
|
|
115
|
+
editor,
|
|
116
|
+
{ dom: audio },
|
|
117
|
+
icon.firstElementChild as HTMLElement,
|
|
118
|
+
);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export const audioToExternalHTML =
|
|
122
|
+
(_config: AudioOptions = {}) =>
|
|
123
|
+
(
|
|
124
|
+
block: BlockFromConfig<ReturnType<typeof createAudioBlockConfig>, any, any>,
|
|
125
|
+
_editor: BlockNoteEditor<
|
|
126
|
+
Record<"audio", ReturnType<typeof createAudioBlockConfig>>,
|
|
127
|
+
any,
|
|
128
|
+
any
|
|
129
|
+
>,
|
|
130
|
+
) => {
|
|
131
|
+
if (!block.props.url) {
|
|
132
|
+
const div = document.createElement("p");
|
|
133
|
+
div.textContent = "Add audio";
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
dom: div,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
let audio;
|
|
141
|
+
if (block.props.showPreview) {
|
|
142
|
+
audio = document.createElement("audio");
|
|
143
|
+
audio.src = block.props.url;
|
|
144
|
+
} else {
|
|
145
|
+
audio = document.createElement("a");
|
|
146
|
+
audio.href = block.props.url;
|
|
147
|
+
audio.textContent = block.props.name || block.props.url;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (block.props.caption) {
|
|
151
|
+
if (block.props.showPreview) {
|
|
152
|
+
return createFigureWithCaption(audio, block.props.caption);
|
|
153
|
+
} else {
|
|
154
|
+
return createLinkWithCaption(audio, block.props.caption);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
dom: audio,
|
|
160
|
+
};
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export const createAudioBlockSpec = createBlockSpec(
|
|
164
|
+
createAudioBlockConfig,
|
|
165
|
+
(config) => ({
|
|
166
|
+
meta: {
|
|
167
|
+
fileBlockAccept: ["audio/*"],
|
|
168
|
+
},
|
|
169
|
+
parse: audioParse(config),
|
|
170
|
+
render: audioRender(config),
|
|
171
|
+
toExternalHTML: audioToExternalHTML(config),
|
|
172
|
+
runsBefore: ["file"],
|
|
173
|
+
}),
|
|
174
|
+
);
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BlockSchema,
|
|
3
|
+
BlockSchemaFromSpecs,
|
|
4
|
+
BlockSpecs,
|
|
5
|
+
CustomBlockNoteSchema,
|
|
6
|
+
InlineContentSchema,
|
|
7
|
+
InlineContentSchemaFromSpecs,
|
|
8
|
+
InlineContentSpecs,
|
|
9
|
+
StyleSchema,
|
|
10
|
+
StyleSchemaFromSpecs,
|
|
11
|
+
StyleSpecs,
|
|
12
|
+
} from "../schema/index.js";
|
|
13
|
+
import {
|
|
14
|
+
defaultBlockSpecs,
|
|
15
|
+
defaultInlineContentSpecs,
|
|
16
|
+
defaultStyleSpecs,
|
|
17
|
+
} from "./defaultBlocks.js";
|
|
18
|
+
|
|
19
|
+
export class BlockNoteSchema<
|
|
20
|
+
BSchema extends BlockSchema,
|
|
21
|
+
ISchema extends InlineContentSchema,
|
|
22
|
+
SSchema extends StyleSchema,
|
|
23
|
+
> extends CustomBlockNoteSchema<BSchema, ISchema, SSchema> {
|
|
24
|
+
public static create<
|
|
25
|
+
BSpecs extends BlockSpecs | undefined = undefined,
|
|
26
|
+
ISpecs extends InlineContentSpecs | undefined = undefined,
|
|
27
|
+
SSpecs extends StyleSpecs | undefined = undefined,
|
|
28
|
+
>(options?: {
|
|
29
|
+
/**
|
|
30
|
+
* A list of custom block types that should be available in the editor.
|
|
31
|
+
*/
|
|
32
|
+
blockSpecs?: BSpecs;
|
|
33
|
+
/**
|
|
34
|
+
* A list of custom InlineContent types that should be available in the editor.
|
|
35
|
+
*/
|
|
36
|
+
inlineContentSpecs?: ISpecs;
|
|
37
|
+
/**
|
|
38
|
+
* A list of custom Styles that should be available in the editor.
|
|
39
|
+
*/
|
|
40
|
+
styleSpecs?: SSpecs;
|
|
41
|
+
}): BlockNoteSchema<
|
|
42
|
+
BSpecs extends undefined
|
|
43
|
+
? BlockSchemaFromSpecs<typeof defaultBlockSpecs>
|
|
44
|
+
: BlockSchemaFromSpecs<NonNullable<BSpecs>>,
|
|
45
|
+
ISpecs extends undefined
|
|
46
|
+
? InlineContentSchemaFromSpecs<typeof defaultInlineContentSpecs>
|
|
47
|
+
: InlineContentSchemaFromSpecs<NonNullable<ISpecs>>,
|
|
48
|
+
SSpecs extends undefined
|
|
49
|
+
? StyleSchemaFromSpecs<typeof defaultStyleSpecs>
|
|
50
|
+
: StyleSchemaFromSpecs<NonNullable<SSpecs>>
|
|
51
|
+
> {
|
|
52
|
+
return new BlockNoteSchema<any, any, any>({
|
|
53
|
+
blockSpecs: options?.blockSpecs ?? defaultBlockSpecs,
|
|
54
|
+
inlineContentSpecs:
|
|
55
|
+
options?.inlineContentSpecs ?? defaultInlineContentSpecs,
|
|
56
|
+
styleSpecs: options?.styleSpecs ?? defaultStyleSpecs,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import type { HighlighterGeneric } from "@shikijs/types";
|
|
2
|
+
import { createBlockNoteExtension } from "../../editor/BlockNoteExtension.js";
|
|
3
|
+
import { createBlockConfig, createBlockSpec } from "../../schema/index.js";
|
|
4
|
+
|
|
5
|
+
import { DOMParser } from "@tiptap/pm/model";
|
|
6
|
+
|
|
7
|
+
export type CodeBlockOptions = {
|
|
8
|
+
/**
|
|
9
|
+
* Whether to indent lines with a tab when the user presses `Tab` in a code block.
|
|
10
|
+
*
|
|
11
|
+
* @default true
|
|
12
|
+
*/
|
|
13
|
+
indentLineWithTab?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* The default language to use for code blocks.
|
|
16
|
+
*
|
|
17
|
+
* @default "text"
|
|
18
|
+
*/
|
|
19
|
+
defaultLanguage?: string;
|
|
20
|
+
/**
|
|
21
|
+
* The languages that are supported in the editor.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* {
|
|
25
|
+
* javascript: {
|
|
26
|
+
* name: "JavaScript",
|
|
27
|
+
* aliases: ["js"],
|
|
28
|
+
* },
|
|
29
|
+
* typescript: {
|
|
30
|
+
* name: "TypeScript",
|
|
31
|
+
* aliases: ["ts"],
|
|
32
|
+
* },
|
|
33
|
+
* }
|
|
34
|
+
*/
|
|
35
|
+
supportedLanguages?: Record<
|
|
36
|
+
string,
|
|
37
|
+
{
|
|
38
|
+
/**
|
|
39
|
+
* The display name of the language.
|
|
40
|
+
*/
|
|
41
|
+
name: string;
|
|
42
|
+
/**
|
|
43
|
+
* Aliases for this language.
|
|
44
|
+
*/
|
|
45
|
+
aliases?: string[];
|
|
46
|
+
}
|
|
47
|
+
>;
|
|
48
|
+
/**
|
|
49
|
+
* The highlighter to use for code blocks.
|
|
50
|
+
*/
|
|
51
|
+
createHighlighter?: () => Promise<HighlighterGeneric<any, any>>;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export type CodeBlockConfig = ReturnType<typeof createCodeBlockConfig>;
|
|
55
|
+
|
|
56
|
+
export const createCodeBlockConfig = createBlockConfig(
|
|
57
|
+
({ defaultLanguage = "text" }: CodeBlockOptions) =>
|
|
58
|
+
({
|
|
59
|
+
type: "codeBlock" as const,
|
|
60
|
+
propSchema: {
|
|
61
|
+
language: {
|
|
62
|
+
default: defaultLanguage,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
content: "inline",
|
|
66
|
+
}) as const,
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
export const createCodeBlockSpec = createBlockSpec(
|
|
70
|
+
createCodeBlockConfig,
|
|
71
|
+
(options) => ({
|
|
72
|
+
meta: {
|
|
73
|
+
code: true,
|
|
74
|
+
defining: true,
|
|
75
|
+
isolating: false,
|
|
76
|
+
},
|
|
77
|
+
parse: (e) => {
|
|
78
|
+
if (e.tagName !== "PRE") {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (
|
|
83
|
+
e.childElementCount !== 1 ||
|
|
84
|
+
e.firstElementChild?.tagName !== "CODE"
|
|
85
|
+
) {
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const code = e.firstElementChild!;
|
|
90
|
+
const language =
|
|
91
|
+
code.getAttribute("data-language") ||
|
|
92
|
+
code.className
|
|
93
|
+
.split(" ")
|
|
94
|
+
.find((name) => name.includes("language-"))
|
|
95
|
+
?.replace("language-", "");
|
|
96
|
+
|
|
97
|
+
return { language };
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
parseContent: ({ el, schema }) => {
|
|
101
|
+
const parser = DOMParser.fromSchema(schema);
|
|
102
|
+
const code = el.firstElementChild!;
|
|
103
|
+
|
|
104
|
+
return parser.parse(code, {
|
|
105
|
+
topNode: schema.nodes["codeBlock"].create(),
|
|
106
|
+
}).content;
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
render(block, editor) {
|
|
110
|
+
const wrapper = document.createDocumentFragment();
|
|
111
|
+
const pre = document.createElement("pre");
|
|
112
|
+
const code = document.createElement("code");
|
|
113
|
+
pre.appendChild(code);
|
|
114
|
+
|
|
115
|
+
let removeSelectChangeListener = undefined;
|
|
116
|
+
|
|
117
|
+
if (options.supportedLanguages) {
|
|
118
|
+
const select = document.createElement("select");
|
|
119
|
+
|
|
120
|
+
const handleLanguageChange = (event: Event) => {
|
|
121
|
+
const language = (event.target as HTMLSelectElement).value;
|
|
122
|
+
|
|
123
|
+
editor.updateBlock(block.id, { props: { language } });
|
|
124
|
+
};
|
|
125
|
+
select.addEventListener("change", handleLanguageChange);
|
|
126
|
+
|
|
127
|
+
const selectWrapper = document.createElement("div");
|
|
128
|
+
selectWrapper.contentEditable = "false";
|
|
129
|
+
select.value =
|
|
130
|
+
block.props.language || options.defaultLanguage || "text";
|
|
131
|
+
|
|
132
|
+
Object.entries(options.supportedLanguages ?? {}).forEach(
|
|
133
|
+
([id, { name }]) => {
|
|
134
|
+
const option = document.createElement("option");
|
|
135
|
+
|
|
136
|
+
option.value = id;
|
|
137
|
+
option.text = name;
|
|
138
|
+
select.appendChild(option);
|
|
139
|
+
},
|
|
140
|
+
);
|
|
141
|
+
selectWrapper.appendChild(select);
|
|
142
|
+
wrapper.appendChild(selectWrapper);
|
|
143
|
+
|
|
144
|
+
removeSelectChangeListener = () =>
|
|
145
|
+
select.removeEventListener("change", handleLanguageChange);
|
|
146
|
+
}
|
|
147
|
+
wrapper.appendChild(pre);
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
dom: wrapper,
|
|
151
|
+
contentDOM: code,
|
|
152
|
+
destroy: () => {
|
|
153
|
+
removeSelectChangeListener?.();
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
},
|
|
157
|
+
toExternalHTML(block) {
|
|
158
|
+
const pre = document.createElement("pre");
|
|
159
|
+
const code = document.createElement("code");
|
|
160
|
+
code.className = `language-${block.props.language}`;
|
|
161
|
+
code.dataset.language = block.props.language;
|
|
162
|
+
pre.appendChild(code);
|
|
163
|
+
return {
|
|
164
|
+
dom: pre,
|
|
165
|
+
contentDOM: code,
|
|
166
|
+
};
|
|
167
|
+
},
|
|
168
|
+
}),
|
|
169
|
+
(options) => {
|
|
170
|
+
return [
|
|
171
|
+
createBlockNoteExtension({
|
|
172
|
+
key: "code-block-keyboard-shortcuts",
|
|
173
|
+
keyboardShortcuts: {
|
|
174
|
+
Delete: ({ editor }) => {
|
|
175
|
+
return editor.transact((tr) => {
|
|
176
|
+
const { block } = editor.getTextCursorPosition();
|
|
177
|
+
if (block.type !== "codeBlock") {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
const { $from } = tr.selection;
|
|
181
|
+
|
|
182
|
+
// When inside empty codeblock, on `DELETE` key press, delete the codeblock
|
|
183
|
+
if (!$from.parent.textContent) {
|
|
184
|
+
editor.removeBlocks([block]);
|
|
185
|
+
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return false;
|
|
190
|
+
});
|
|
191
|
+
},
|
|
192
|
+
Tab: ({ editor }) => {
|
|
193
|
+
if (options.indentLineWithTab === false) {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return editor.transact((tr) => {
|
|
198
|
+
const { block } = editor.getTextCursorPosition();
|
|
199
|
+
if (block.type === "codeBlock") {
|
|
200
|
+
// TODO should probably only tab when at a line start or already tabbed in
|
|
201
|
+
tr.insertText(" ");
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return false;
|
|
206
|
+
});
|
|
207
|
+
},
|
|
208
|
+
Enter: ({ editor }) => {
|
|
209
|
+
return editor.transact((tr) => {
|
|
210
|
+
const { block, nextBlock } = editor.getTextCursorPosition();
|
|
211
|
+
if (block.type !== "codeBlock") {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
const { $from } = tr.selection;
|
|
215
|
+
|
|
216
|
+
const isAtEnd = $from.parentOffset === $from.parent.nodeSize - 2;
|
|
217
|
+
const endsWithDoubleNewline =
|
|
218
|
+
$from.parent.textContent.endsWith("\n\n");
|
|
219
|
+
|
|
220
|
+
// The user is trying to exit the code block by pressing enter at the end of the code block
|
|
221
|
+
if (isAtEnd && endsWithDoubleNewline) {
|
|
222
|
+
// Remove the double newline
|
|
223
|
+
tr.delete($from.pos - 2, $from.pos);
|
|
224
|
+
|
|
225
|
+
// If there is a next block, move the cursor to it
|
|
226
|
+
if (nextBlock) {
|
|
227
|
+
editor.setTextCursorPosition(nextBlock, "start");
|
|
228
|
+
return true;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// If there is no next block, insert a new paragraph
|
|
232
|
+
const [newBlock] = editor.insertBlocks(
|
|
233
|
+
[{ type: "paragraph" }],
|
|
234
|
+
block,
|
|
235
|
+
"after",
|
|
236
|
+
);
|
|
237
|
+
// Move the cursor to the new block
|
|
238
|
+
editor.setTextCursorPosition(newBlock, "start");
|
|
239
|
+
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
tr.insertText("\n");
|
|
244
|
+
return true;
|
|
245
|
+
});
|
|
246
|
+
},
|
|
247
|
+
"Shift-Enter": ({ editor }) => {
|
|
248
|
+
return editor.transact(() => {
|
|
249
|
+
const { block } = editor.getTextCursorPosition();
|
|
250
|
+
if (block.type !== "codeBlock") {
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const [newBlock] = editor.insertBlocks(
|
|
255
|
+
// insert a new paragraph
|
|
256
|
+
[{ type: "paragraph" }],
|
|
257
|
+
block,
|
|
258
|
+
"after",
|
|
259
|
+
);
|
|
260
|
+
// move the cursor to the new block
|
|
261
|
+
editor.setTextCursorPosition(newBlock, "start");
|
|
262
|
+
return true;
|
|
263
|
+
});
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
inputRules: [
|
|
267
|
+
{
|
|
268
|
+
find: /^```(.*?)\s$/,
|
|
269
|
+
replace: ({ match }) => {
|
|
270
|
+
const languageName = match[1].trim();
|
|
271
|
+
const attributes = {
|
|
272
|
+
language: getLanguageId(options, languageName) ?? languageName,
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
return {
|
|
276
|
+
type: "codeBlock",
|
|
277
|
+
props: {
|
|
278
|
+
language: attributes.language,
|
|
279
|
+
},
|
|
280
|
+
content: [],
|
|
281
|
+
};
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
],
|
|
285
|
+
}),
|
|
286
|
+
];
|
|
287
|
+
},
|
|
288
|
+
);
|
|
289
|
+
|
|
290
|
+
export function getLanguageId(
|
|
291
|
+
options: CodeBlockOptions,
|
|
292
|
+
languageName: string,
|
|
293
|
+
): string | undefined {
|
|
294
|
+
return Object.entries(options.supportedLanguages ?? {}).find(
|
|
295
|
+
([id, { aliases }]) => {
|
|
296
|
+
return aliases?.includes(languageName) || id === languageName;
|
|
297
|
+
},
|
|
298
|
+
)?.[0];
|
|
299
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { createBlockConfig, createBlockSpec } from "../../schema/index.js";
|
|
2
|
+
import { defaultProps, parseDefaultProps } from "../defaultProps.js";
|
|
3
|
+
import { parseEmbedElement } from "./helpers/parse/parseEmbedElement.js";
|
|
4
|
+
import { parseFigureElement } from "./helpers/parse/parseFigureElement.js";
|
|
5
|
+
import { createFileBlockWrapper } from "./helpers/render/createFileBlockWrapper.js";
|
|
6
|
+
import { createLinkWithCaption } from "./helpers/toExternalHTML/createLinkWithCaption.js";
|
|
7
|
+
|
|
8
|
+
export type FileBlockConfig = ReturnType<typeof createFileBlockConfig>;
|
|
9
|
+
|
|
10
|
+
export const createFileBlockConfig = createBlockConfig(
|
|
11
|
+
() =>
|
|
12
|
+
({
|
|
13
|
+
type: "file" as const,
|
|
14
|
+
propSchema: {
|
|
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
|
+
},
|
|
29
|
+
content: "none" as const,
|
|
30
|
+
}) as const,
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
export const fileParse = () => (element: HTMLElement) => {
|
|
34
|
+
if (element.tagName === "EMBED") {
|
|
35
|
+
// Ignore if parent figure has already been parsed.
|
|
36
|
+
if (element.closest("figure")) {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const { backgroundColor } = parseDefaultProps(element);
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
...parseEmbedElement(element as HTMLEmbedElement),
|
|
44
|
+
backgroundColor,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (element.tagName === "FIGURE") {
|
|
49
|
+
const parsedFigure = parseFigureElement(element, "embed");
|
|
50
|
+
if (!parsedFigure) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const { targetElement, caption } = parsedFigure;
|
|
55
|
+
|
|
56
|
+
const { backgroundColor } = parseDefaultProps(element);
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
...parseEmbedElement(targetElement as HTMLEmbedElement),
|
|
60
|
+
backgroundColor,
|
|
61
|
+
caption,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return undefined;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const createFileBlockSpec = createBlockSpec(createFileBlockConfig, {
|
|
69
|
+
meta: {
|
|
70
|
+
fileBlockAccept: ["*/*"],
|
|
71
|
+
},
|
|
72
|
+
parse: fileParse(),
|
|
73
|
+
render(block, editor) {
|
|
74
|
+
return createFileBlockWrapper(block, editor);
|
|
75
|
+
},
|
|
76
|
+
toExternalHTML(block) {
|
|
77
|
+
if (!block.props.url) {
|
|
78
|
+
const div = document.createElement("p");
|
|
79
|
+
div.textContent = "Add file";
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
dom: div,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const fileSrcLink = document.createElement("a");
|
|
87
|
+
fileSrcLink.href = block.props.url;
|
|
88
|
+
fileSrcLink.textContent = block.props.name || block.props.url;
|
|
89
|
+
|
|
90
|
+
if (block.props.caption) {
|
|
91
|
+
return createLinkWithCaption(fileSrcLink, block.props.caption);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
dom: fileSrcLink,
|
|
96
|
+
};
|
|
97
|
+
},
|
|
98
|
+
});
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type { BlockNoteEditor } from "../../../../editor/BlockNoteEditor.js";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
BlockConfig,
|
|
4
|
+
BlockFromConfigNoChildren,
|
|
5
|
+
} from "../../../../schema/index.js";
|
|
3
6
|
|
|
4
7
|
export const createAddFileButton = (
|
|
5
|
-
block:
|
|
8
|
+
block: BlockFromConfigNoChildren<BlockConfig<string, any, "none">, any, any>,
|
|
6
9
|
editor: BlockNoteEditor<any, any, any>,
|
|
7
10
|
buttonIcon?: HTMLElement,
|
|
8
11
|
) => {
|
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
import type { BlockNoteEditor } from "../../../../editor/BlockNoteEditor.js";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
FileBlockConfig,
|
|
3
|
+
BlockConfig,
|
|
4
|
+
BlockFromConfigNoChildren,
|
|
6
5
|
} from "../../../../schema/index.js";
|
|
7
6
|
import { createAddFileButton } from "./createAddFileButton.js";
|
|
8
7
|
import { createFileNameWithIcon } from "./createFileNameWithIcon.js";
|
|
9
8
|
|
|
10
9
|
export const createFileBlockWrapper = (
|
|
11
|
-
block:
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
block: BlockFromConfigNoChildren<
|
|
11
|
+
BlockConfig<
|
|
12
|
+
string,
|
|
13
|
+
{
|
|
14
|
+
backgroundColor: { default: "default" };
|
|
15
|
+
name: { default: "" };
|
|
16
|
+
url: { default: "" };
|
|
17
|
+
caption: { default: "" };
|
|
18
|
+
showPreview?: { default: true };
|
|
19
|
+
},
|
|
20
|
+
"none"
|
|
21
|
+
>,
|
|
14
22
|
any,
|
|
15
23
|
any
|
|
16
24
|
>,
|
|
25
|
+
editor: BlockNoteEditor<any, any, any>,
|
|
17
26
|
element?: { dom: HTMLElement; destroy?: () => void },
|
|
18
27
|
buttonIcon?: HTMLElement,
|
|
19
28
|
) => {
|
|
@@ -1,9 +1,22 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
BlockConfig,
|
|
3
|
+
BlockFromConfigNoChildren,
|
|
4
|
+
} from "../../../../schema/index.js";
|
|
2
5
|
|
|
3
6
|
export const FILE_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M3 8L9.00319 2H19.9978C20.5513 2 21 2.45531 21 2.9918V21.0082C21 21.556 20.5551 22 20.0066 22H3.9934C3.44476 22 3 21.5501 3 20.9932V8ZM10 4V9H5V20H19V4H10Z"></path></svg>`;
|
|
4
7
|
|
|
5
8
|
export const createFileNameWithIcon = (
|
|
6
|
-
block:
|
|
9
|
+
block: BlockFromConfigNoChildren<
|
|
10
|
+
BlockConfig<
|
|
11
|
+
string,
|
|
12
|
+
{
|
|
13
|
+
name: { default: "" };
|
|
14
|
+
},
|
|
15
|
+
"none"
|
|
16
|
+
>,
|
|
17
|
+
any,
|
|
18
|
+
any
|
|
19
|
+
>,
|
|
7
20
|
): { dom: HTMLElement; destroy?: () => void } => {
|
|
8
21
|
const file = document.createElement("div");
|
|
9
22
|
file.className = "bn-file-name-with-icon";
|