@blocknote/core 0.8.5 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blocknote.js +614 -520
- package/dist/blocknote.js.map +1 -1
- package/dist/blocknote.umd.cjs +4 -4
- package/dist/blocknote.umd.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +2 -2
- package/src/BlockNoteEditor.ts +11 -15
- package/src/BlockNoteExtensions.ts +18 -5
- package/src/editor.module.css +0 -11
- package/src/extensions/Blocks/api/block.ts +55 -22
- package/src/extensions/Blocks/api/blockTypes.ts +22 -3
- package/src/extensions/Blocks/index.ts +7 -12
- package/src/extensions/Blocks/nodes/Block.module.css +1 -1
- package/src/extensions/Blocks/nodes/BlockContainer.ts +19 -18
- package/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.ts +20 -2
- package/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +20 -2
- package/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +20 -2
- package/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.ts +29 -6
- package/src/extensions/Blocks/nodes/BlockGroup.ts +19 -11
- package/src/index.ts +1 -0
- package/src/shared/utils.ts +4 -0
- package/types/src/BlockNoteEditor.d.ts +4 -10
- package/types/src/BlockNoteExtensions.d.ts +2 -0
- package/types/src/extensions/Blocks/api/block.d.ts +6 -1
- package/types/src/extensions/Blocks/api/blockTypes.d.ts +15 -3
- package/types/src/extensions/Blocks/api/defaultBlocks.d.ts +36 -4
- package/types/src/extensions/Blocks/index.d.ts +4 -1
- package/types/src/extensions/Blocks/nodes/BlockContainer.d.ts +9 -4
- package/types/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.d.ts +9 -1
- package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.d.ts +9 -1
- package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.d.ts +9 -1
- package/types/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.d.ts +9 -1
- package/types/src/extensions/Blocks/nodes/BlockGroup.d.ts +9 -1
- package/types/src/index.d.ts +1 -0
- package/types/src/shared/utils.d.ts +1 -0
- package/src/node_modules/.vitest/results.json +0 -1
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"homepage": "https://github.com/TypeCellOS/BlockNote",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.9.0",
|
|
7
7
|
"files": [
|
|
8
8
|
"dist",
|
|
9
9
|
"types",
|
|
@@ -109,5 +109,5 @@
|
|
|
109
109
|
"access": "public",
|
|
110
110
|
"registry": "https://registry.npmjs.org/"
|
|
111
111
|
},
|
|
112
|
-
"gitHead": "
|
|
112
|
+
"gitHead": "75d9591eef6f06f78bdd8dadc32d0ee66c57c4d2"
|
|
113
113
|
}
|
package/src/BlockNoteEditor.ts
CHANGED
|
@@ -11,9 +11,9 @@ import {
|
|
|
11
11
|
updateBlock,
|
|
12
12
|
} from "./api/blockManipulation/blockManipulation";
|
|
13
13
|
import {
|
|
14
|
-
HTMLToBlocks,
|
|
15
14
|
blocksToHTML,
|
|
16
15
|
blocksToMarkdown,
|
|
16
|
+
HTMLToBlocks,
|
|
17
17
|
markdownToBlocks,
|
|
18
18
|
} from "./api/formatConversions/formatConversions";
|
|
19
19
|
import {
|
|
@@ -25,6 +25,7 @@ import styles from "./editor.module.css";
|
|
|
25
25
|
import {
|
|
26
26
|
Block,
|
|
27
27
|
BlockIdentifier,
|
|
28
|
+
BlockNoteDOMAttributes,
|
|
28
29
|
BlockSchema,
|
|
29
30
|
PartialBlock,
|
|
30
31
|
} from "./extensions/Blocks/api/blockTypes";
|
|
@@ -48,6 +49,7 @@ import { BaseSlashMenuItem } from "./extensions/SlashMenu/BaseSlashMenuItem";
|
|
|
48
49
|
import { SlashMenuProsemirrorPlugin } from "./extensions/SlashMenu/SlashMenuPlugin";
|
|
49
50
|
import { getDefaultSlashMenuItems } from "./extensions/SlashMenu/defaultSlashMenuItems";
|
|
50
51
|
import { UniqueID } from "./extensions/UniqueID/UniqueID";
|
|
52
|
+
import { mergeCSSClasses } from "./shared/utils";
|
|
51
53
|
|
|
52
54
|
export type BlockNoteEditorOptions<BSchema extends BlockSchema> = {
|
|
53
55
|
// TODO: Figure out if enableBlockNoteExtensions/disableHistoryExtension are needed and document them.
|
|
@@ -67,11 +69,11 @@ export type BlockNoteEditorOptions<BSchema extends BlockSchema> = {
|
|
|
67
69
|
*/
|
|
68
70
|
parentElement: HTMLElement;
|
|
69
71
|
/**
|
|
70
|
-
* An object containing attributes that should be added to the editor
|
|
72
|
+
* An object containing attributes that should be added to HTML elements of the editor.
|
|
71
73
|
*
|
|
72
|
-
* @example { class: "my-editor-class" }
|
|
74
|
+
* @example { editor: { class: "my-editor-class" } }
|
|
73
75
|
*/
|
|
74
|
-
|
|
76
|
+
domAttributes: Partial<BlockNoteDOMAttributes>;
|
|
75
77
|
/**
|
|
76
78
|
* A callback function that runs when the editor is ready to be used.
|
|
77
79
|
*/
|
|
@@ -98,12 +100,6 @@ export type BlockNoteEditorOptions<BSchema extends BlockSchema> = {
|
|
|
98
100
|
* @default true
|
|
99
101
|
*/
|
|
100
102
|
defaultStyles: boolean;
|
|
101
|
-
/**
|
|
102
|
-
* Whether to use the light or dark theme.
|
|
103
|
-
*
|
|
104
|
-
* @default "light"
|
|
105
|
-
*/
|
|
106
|
-
theme: "light" | "dark";
|
|
107
103
|
|
|
108
104
|
/**
|
|
109
105
|
* A list of block types that should be available in the editor.
|
|
@@ -185,6 +181,7 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
|
|
|
185
181
|
|
|
186
182
|
const extensions = getBlockNoteExtensions<BSchema>({
|
|
187
183
|
editor: this,
|
|
184
|
+
domAttributes: newOptions.domAttributes || {},
|
|
188
185
|
blockSchema: newOptions.blockSchema,
|
|
189
186
|
collaboration: newOptions.collaboration,
|
|
190
187
|
});
|
|
@@ -266,14 +263,13 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
|
|
|
266
263
|
: [...(newOptions._tiptapOptions?.extensions || []), ...extensions],
|
|
267
264
|
editorProps: {
|
|
268
265
|
attributes: {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
class: [
|
|
266
|
+
...newOptions.domAttributes?.editor,
|
|
267
|
+
class: mergeCSSClasses(
|
|
272
268
|
styles.bnEditor,
|
|
273
269
|
styles.bnRoot,
|
|
274
270
|
newOptions.defaultStyles ? styles.defaultStyles : "",
|
|
275
|
-
newOptions.
|
|
276
|
-
|
|
271
|
+
newOptions.domAttributes?.editor?.class || ""
|
|
272
|
+
),
|
|
277
273
|
},
|
|
278
274
|
},
|
|
279
275
|
};
|
|
@@ -19,8 +19,11 @@ import * as Y from "yjs";
|
|
|
19
19
|
import styles from "./editor.module.css";
|
|
20
20
|
import { BackgroundColorExtension } from "./extensions/BackgroundColor/BackgroundColorExtension";
|
|
21
21
|
import { BackgroundColorMark } from "./extensions/BackgroundColor/BackgroundColorMark";
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
22
|
+
import { BlockContainer, BlockGroup, Doc } from "./extensions/Blocks";
|
|
23
|
+
import {
|
|
24
|
+
BlockNoteDOMAttributes,
|
|
25
|
+
BlockSchema,
|
|
26
|
+
} from "./extensions/Blocks/api/blockTypes";
|
|
24
27
|
import { CustomBlockSerializerExtension } from "./extensions/Blocks/api/serialization";
|
|
25
28
|
import blockStyles from "./extensions/Blocks/nodes/Block.module.css";
|
|
26
29
|
import { Placeholder } from "./extensions/Placeholder/PlaceholderExtension";
|
|
@@ -35,6 +38,7 @@ import UniqueID from "./extensions/UniqueID/UniqueID";
|
|
|
35
38
|
*/
|
|
36
39
|
export const getBlockNoteExtensions = <BSchema extends BlockSchema>(opts: {
|
|
37
40
|
editor: BlockNoteEditor<BSchema>;
|
|
41
|
+
domAttributes: Partial<BlockNoteDOMAttributes>;
|
|
38
42
|
blockSchema: BSchema;
|
|
39
43
|
collaboration?: {
|
|
40
44
|
fragment: Y.XmlFragment;
|
|
@@ -86,10 +90,19 @@ export const getBlockNoteExtensions = <BSchema extends BlockSchema>(opts: {
|
|
|
86
90
|
BackgroundColorExtension,
|
|
87
91
|
TextAlignmentExtension,
|
|
88
92
|
|
|
89
|
-
//
|
|
90
|
-
|
|
93
|
+
// nodes
|
|
94
|
+
Doc,
|
|
95
|
+
BlockContainer.configure({
|
|
96
|
+
domAttributes: opts.domAttributes,
|
|
97
|
+
}),
|
|
98
|
+
BlockGroup.configure({
|
|
99
|
+
domAttributes: opts.domAttributes,
|
|
100
|
+
}),
|
|
91
101
|
...Object.values(opts.blockSchema).map((blockSpec) =>
|
|
92
|
-
blockSpec.node.configure({
|
|
102
|
+
blockSpec.node.configure({
|
|
103
|
+
editor: opts.editor,
|
|
104
|
+
domAttributes: opts.domAttributes,
|
|
105
|
+
})
|
|
93
106
|
),
|
|
94
107
|
CustomBlockSerializerExtension,
|
|
95
108
|
|
package/src/editor.module.css
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
.bnEditor {
|
|
4
4
|
outline: none;
|
|
5
5
|
padding-inline: 54px;
|
|
6
|
-
border-radius: 8px;
|
|
7
6
|
|
|
8
7
|
/* Define a set of colors to be used throughout the app for consistency
|
|
9
8
|
see https://atlassian.design/foundations/color for more info */
|
|
@@ -55,16 +54,6 @@ Tippy popups that are appended to document.body directly
|
|
|
55
54
|
-moz-osx-font-smoothing: grayscale;
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
[data-theme="light"] {
|
|
59
|
-
background-color: #FFFFFF;
|
|
60
|
-
color: #3F3F3F;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
[data-theme="dark"] {
|
|
64
|
-
background-color: #1F1F1F;
|
|
65
|
-
color: #CFCFCF;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
57
|
.dragPreview {
|
|
69
58
|
position: absolute;
|
|
70
59
|
top: -1000px;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Attribute, Node } from "@tiptap/core";
|
|
2
|
-
import { BlockNoteEditor } from "../../..";
|
|
2
|
+
import { BlockNoteDOMAttributes, BlockNoteEditor } from "../../..";
|
|
3
3
|
import styles from "../nodes/Block.module.css";
|
|
4
4
|
import {
|
|
5
5
|
BlockConfig,
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
TipTapNode,
|
|
10
10
|
TipTapNodeConfig,
|
|
11
11
|
} from "./blockTypes";
|
|
12
|
+
import { mergeCSSClasses } from "../../../shared/utils";
|
|
12
13
|
|
|
13
14
|
export function camelToDataKebab(str: string): string {
|
|
14
15
|
return "data-" + str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
@@ -124,17 +125,17 @@ export function createBlockSpec<
|
|
|
124
125
|
>(
|
|
125
126
|
blockConfig: BlockConfig<BType, PSchema, ContainsInlineContent, BSchema>
|
|
126
127
|
): BlockSpec<BType, PSchema> {
|
|
127
|
-
const node = createTipTapBlock<
|
|
128
|
+
const node = createTipTapBlock<
|
|
129
|
+
BType,
|
|
130
|
+
{
|
|
131
|
+
editor: BlockNoteEditor<BSchema>;
|
|
132
|
+
domAttributes?: BlockNoteDOMAttributes;
|
|
133
|
+
}
|
|
134
|
+
>({
|
|
128
135
|
name: blockConfig.type,
|
|
129
136
|
content: blockConfig.containsInlineContent ? "inline*" : "",
|
|
130
137
|
selectable: blockConfig.containsInlineContent,
|
|
131
138
|
|
|
132
|
-
addOptions() {
|
|
133
|
-
return {
|
|
134
|
-
editor: undefined,
|
|
135
|
-
};
|
|
136
|
-
},
|
|
137
|
-
|
|
138
139
|
addAttributes() {
|
|
139
140
|
return propsToAttributes(blockConfig);
|
|
140
141
|
},
|
|
@@ -151,8 +152,21 @@ export function createBlockSpec<
|
|
|
151
152
|
return ({ HTMLAttributes, getPos }) => {
|
|
152
153
|
// Create blockContent element
|
|
153
154
|
const blockContent = document.createElement("div");
|
|
154
|
-
//
|
|
155
|
-
|
|
155
|
+
// Add custom HTML attributes
|
|
156
|
+
const blockContentDOMAttributes =
|
|
157
|
+
this.options.domAttributes?.blockContent || {};
|
|
158
|
+
for (const [attribute, value] of Object.entries(
|
|
159
|
+
blockContentDOMAttributes
|
|
160
|
+
)) {
|
|
161
|
+
if (attribute !== "class") {
|
|
162
|
+
blockContent.setAttribute(attribute, value);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Set blockContent & custom classes
|
|
166
|
+
blockContent.className = mergeCSSClasses(
|
|
167
|
+
styles.blockContent,
|
|
168
|
+
blockContentDOMAttributes.class
|
|
169
|
+
);
|
|
156
170
|
// Add blockContent HTML attribute
|
|
157
171
|
blockContent.setAttribute("data-content-type", blockConfig.type);
|
|
158
172
|
// Add props as HTML attributes in kebab-case with "data-" prefix
|
|
@@ -186,13 +200,24 @@ export function createBlockSpec<
|
|
|
186
200
|
|
|
187
201
|
// Render elements
|
|
188
202
|
const rendered = blockConfig.render(block as any, editor);
|
|
189
|
-
// Add
|
|
203
|
+
// Add HTML attributes to contentDOM
|
|
190
204
|
if ("contentDOM" in rendered) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
205
|
+
const inlineContentDOMAttributes =
|
|
206
|
+
this.options.domAttributes?.inlineContent || {};
|
|
207
|
+
// Add custom HTML attributes
|
|
208
|
+
for (const [attribute, value] of Object.entries(
|
|
209
|
+
inlineContentDOMAttributes
|
|
210
|
+
)) {
|
|
211
|
+
if (attribute !== "class") {
|
|
212
|
+
rendered.contentDOM.setAttribute(attribute, value);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// Merge existing classes with inlineContent & custom classes
|
|
216
|
+
rendered.contentDOM.className = mergeCSSClasses(
|
|
217
|
+
rendered.contentDOM.className,
|
|
218
|
+
styles.inlineContent,
|
|
219
|
+
inlineContentDOMAttributes.class
|
|
220
|
+
);
|
|
196
221
|
}
|
|
197
222
|
// Add elements to blockContent
|
|
198
223
|
blockContent.appendChild(rendered.dom);
|
|
@@ -210,20 +235,28 @@ export function createBlockSpec<
|
|
|
210
235
|
});
|
|
211
236
|
|
|
212
237
|
return {
|
|
213
|
-
node: node
|
|
238
|
+
node: node as TipTapNode<BType>,
|
|
214
239
|
propSchema: blockConfig.propSchema,
|
|
215
240
|
};
|
|
216
241
|
}
|
|
217
242
|
|
|
218
|
-
export function createTipTapBlock<
|
|
219
|
-
|
|
220
|
-
|
|
243
|
+
export function createTipTapBlock<
|
|
244
|
+
Type extends string,
|
|
245
|
+
Options extends {
|
|
246
|
+
domAttributes?: BlockNoteDOMAttributes;
|
|
247
|
+
} = {
|
|
248
|
+
domAttributes?: BlockNoteDOMAttributes;
|
|
249
|
+
},
|
|
250
|
+
Storage = any
|
|
251
|
+
>(
|
|
252
|
+
config: TipTapNodeConfig<Type, Options, Storage>
|
|
253
|
+
): TipTapNode<Type, Options, Storage> {
|
|
221
254
|
// Type cast is needed as Node.name is mutable, though there is basically no
|
|
222
255
|
// reason to change it after creation. Alternative is to wrap Node in a new
|
|
223
256
|
// class, which I don't think is worth it since we'd only be changing 1
|
|
224
257
|
// attribute to be read only.
|
|
225
|
-
return Node.create({
|
|
258
|
+
return Node.create<Options, Storage>({
|
|
226
259
|
...config,
|
|
227
260
|
group: "blockContent",
|
|
228
|
-
}) as TipTapNode<Type>;
|
|
261
|
+
}) as TipTapNode<Type, Options, Storage>;
|
|
229
262
|
}
|
|
@@ -4,13 +4,28 @@ import { BlockNoteEditor } from "../../../BlockNoteEditor";
|
|
|
4
4
|
import { InlineContent, PartialInlineContent } from "./inlineContentTypes";
|
|
5
5
|
import { DefaultBlockSchema } from "./defaultBlocks";
|
|
6
6
|
|
|
7
|
+
export type BlockNoteDOMElement =
|
|
8
|
+
| "editor"
|
|
9
|
+
| "blockContainer"
|
|
10
|
+
| "blockGroup"
|
|
11
|
+
| "blockContent"
|
|
12
|
+
| "inlineContent";
|
|
13
|
+
|
|
14
|
+
export type BlockNoteDOMAttributes = Partial<{
|
|
15
|
+
[DOMElement in BlockNoteDOMElement]: Record<string, string>;
|
|
16
|
+
}>;
|
|
17
|
+
|
|
7
18
|
// A configuration for a TipTap node, but with stricter type constraints on the
|
|
8
19
|
// "name" and "group" properties. The "name" property is now always a string
|
|
9
20
|
// literal type, and the "blockGroup" property cannot be configured as it should
|
|
10
21
|
// always be "blockContent". Used as the parameter in `createTipTapNode`.
|
|
11
22
|
export type TipTapNodeConfig<
|
|
12
23
|
Name extends string,
|
|
13
|
-
Options
|
|
24
|
+
Options extends {
|
|
25
|
+
domAttributes?: BlockNoteDOMAttributes;
|
|
26
|
+
} = {
|
|
27
|
+
domAttributes?: BlockNoteDOMAttributes;
|
|
28
|
+
},
|
|
14
29
|
Storage = any
|
|
15
30
|
> = {
|
|
16
31
|
[K in keyof NodeConfig<Options, Storage>]: K extends "name"
|
|
@@ -25,7 +40,11 @@ export type TipTapNodeConfig<
|
|
|
25
40
|
// "blockGroup" property is now "blockContent". Returned by `createTipTapNode`.
|
|
26
41
|
export type TipTapNode<
|
|
27
42
|
Name extends string,
|
|
28
|
-
Options
|
|
43
|
+
Options extends {
|
|
44
|
+
domAttributes?: BlockNoteDOMAttributes;
|
|
45
|
+
} = {
|
|
46
|
+
domAttributes?: BlockNoteDOMAttributes;
|
|
47
|
+
},
|
|
29
48
|
Storage = any
|
|
30
49
|
> = Node<Options, Storage> & {
|
|
31
50
|
name: Name;
|
|
@@ -104,7 +123,7 @@ export type BlockConfig<
|
|
|
104
123
|
// allowing for more advanced custom blocks.
|
|
105
124
|
export type BlockSpec<Type extends string, PSchema extends PropSchema> = {
|
|
106
125
|
readonly propSchema: PSchema;
|
|
107
|
-
node: TipTapNode<Type>;
|
|
126
|
+
node: TipTapNode<Type, any>;
|
|
108
127
|
};
|
|
109
128
|
|
|
110
129
|
// Utility type. For a given object block schema, ensures that the key of each
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import { Node } from "@tiptap/core";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
name: "doc",
|
|
10
|
-
topNode: true,
|
|
11
|
-
content: "blockGroup",
|
|
12
|
-
}),
|
|
13
|
-
];
|
|
2
|
+
export { BlockContainer } from "./nodes/BlockContainer";
|
|
3
|
+
export { BlockGroup } from "./nodes/BlockGroup";
|
|
4
|
+
export const Doc = Node.create({
|
|
5
|
+
name: "doc",
|
|
6
|
+
topNode: true,
|
|
7
|
+
content: "blockGroup",
|
|
8
|
+
});
|
|
@@ -10,12 +10,12 @@ import { getBlockInfoFromPos } from "../helpers/getBlockInfoFromPos";
|
|
|
10
10
|
import { PreviousBlockTypePlugin } from "../PreviousBlockTypePlugin";
|
|
11
11
|
import styles from "./Block.module.css";
|
|
12
12
|
import BlockAttributes from "./BlockAttributes";
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
13
|
+
import {
|
|
14
|
+
BlockNoteDOMAttributes,
|
|
15
|
+
BlockSchema,
|
|
16
|
+
PartialBlock,
|
|
17
|
+
} from "../api/blockTypes";
|
|
18
|
+
import { mergeCSSClasses } from "../../../shared/utils";
|
|
19
19
|
|
|
20
20
|
declare module "@tiptap/core" {
|
|
21
21
|
interface Commands<ReturnType> {
|
|
@@ -39,7 +39,9 @@ declare module "@tiptap/core" {
|
|
|
39
39
|
/**
|
|
40
40
|
* The main "Block node" documents consist of
|
|
41
41
|
*/
|
|
42
|
-
export const BlockContainer = Node.create<
|
|
42
|
+
export const BlockContainer = Node.create<{
|
|
43
|
+
domAttributes?: BlockNoteDOMAttributes;
|
|
44
|
+
}>({
|
|
43
45
|
name: "blockContainer",
|
|
44
46
|
group: "blockContainer",
|
|
45
47
|
// A block always contains content, and optionally a blockGroup which contains nested blocks
|
|
@@ -48,12 +50,6 @@ export const BlockContainer = Node.create<IBlock>({
|
|
|
48
50
|
priority: 50,
|
|
49
51
|
defining: true,
|
|
50
52
|
|
|
51
|
-
addOptions() {
|
|
52
|
-
return {
|
|
53
|
-
HTMLAttributes: {},
|
|
54
|
-
};
|
|
55
|
-
},
|
|
56
|
-
|
|
57
53
|
parseHTML() {
|
|
58
54
|
return [
|
|
59
55
|
{
|
|
@@ -81,6 +77,8 @@ export const BlockContainer = Node.create<IBlock>({
|
|
|
81
77
|
},
|
|
82
78
|
|
|
83
79
|
renderHTML({ HTMLAttributes }) {
|
|
80
|
+
const domAttributes = this.options.domAttributes?.blockContainer || {};
|
|
81
|
+
|
|
84
82
|
return [
|
|
85
83
|
"div",
|
|
86
84
|
mergeAttributes(HTMLAttributes, {
|
|
@@ -89,11 +87,14 @@ export const BlockContainer = Node.create<IBlock>({
|
|
|
89
87
|
}),
|
|
90
88
|
[
|
|
91
89
|
"div",
|
|
92
|
-
mergeAttributes(
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
90
|
+
mergeAttributes(
|
|
91
|
+
{
|
|
92
|
+
...domAttributes,
|
|
93
|
+
class: mergeCSSClasses(styles.block, domAttributes.class),
|
|
94
|
+
"data-node-type": this.name,
|
|
95
|
+
},
|
|
96
|
+
HTMLAttributes
|
|
97
|
+
),
|
|
97
98
|
0,
|
|
98
99
|
],
|
|
99
100
|
];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { InputRule, mergeAttributes } from "@tiptap/core";
|
|
2
2
|
import { createTipTapBlock } from "../../../api/block";
|
|
3
3
|
import styles from "../../Block.module.css";
|
|
4
|
+
import { mergeCSSClasses } from "../../../../../shared/utils";
|
|
4
5
|
|
|
5
6
|
export const HeadingBlockContent = createTipTapBlock<"heading">({
|
|
6
7
|
name: "heading",
|
|
@@ -64,13 +65,30 @@ export const HeadingBlockContent = createTipTapBlock<"heading">({
|
|
|
64
65
|
},
|
|
65
66
|
|
|
66
67
|
renderHTML({ node, HTMLAttributes }) {
|
|
68
|
+
const blockContentDOMAttributes =
|
|
69
|
+
this.options.domAttributes?.blockContent || {};
|
|
70
|
+
const inlineContentDOMAttributes =
|
|
71
|
+
this.options.domAttributes?.inlineContent || {};
|
|
72
|
+
|
|
67
73
|
return [
|
|
68
74
|
"div",
|
|
69
75
|
mergeAttributes(HTMLAttributes, {
|
|
70
|
-
class:
|
|
76
|
+
class: mergeCSSClasses(
|
|
77
|
+
styles.blockContent,
|
|
78
|
+
blockContentDOMAttributes.class
|
|
79
|
+
),
|
|
71
80
|
"data-content-type": this.name,
|
|
72
81
|
}),
|
|
73
|
-
[
|
|
82
|
+
[
|
|
83
|
+
"h" + node.attrs.level,
|
|
84
|
+
{
|
|
85
|
+
class: mergeCSSClasses(
|
|
86
|
+
styles.inlineContent,
|
|
87
|
+
inlineContentDOMAttributes.class
|
|
88
|
+
),
|
|
89
|
+
},
|
|
90
|
+
0,
|
|
91
|
+
],
|
|
74
92
|
];
|
|
75
93
|
},
|
|
76
94
|
});
|
|
@@ -2,6 +2,7 @@ import { InputRule, mergeAttributes } from "@tiptap/core";
|
|
|
2
2
|
import { createTipTapBlock } from "../../../../api/block";
|
|
3
3
|
import { handleEnter } from "../ListItemKeyboardShortcuts";
|
|
4
4
|
import styles from "../../../Block.module.css";
|
|
5
|
+
import { mergeCSSClasses } from "../../../../../../shared/utils";
|
|
5
6
|
|
|
6
7
|
export const BulletListItemBlockContent = createTipTapBlock<"bulletListItem">({
|
|
7
8
|
name: "bulletListItem",
|
|
@@ -82,13 +83,30 @@ export const BulletListItemBlockContent = createTipTapBlock<"bulletListItem">({
|
|
|
82
83
|
},
|
|
83
84
|
|
|
84
85
|
renderHTML({ HTMLAttributes }) {
|
|
86
|
+
const blockContentDOMAttributes =
|
|
87
|
+
this.options.domAttributes?.blockContent || {};
|
|
88
|
+
const inlineContentDOMAttributes =
|
|
89
|
+
this.options.domAttributes?.inlineContent || {};
|
|
90
|
+
|
|
85
91
|
return [
|
|
86
92
|
"div",
|
|
87
93
|
mergeAttributes(HTMLAttributes, {
|
|
88
|
-
class:
|
|
94
|
+
class: mergeCSSClasses(
|
|
95
|
+
styles.blockContent,
|
|
96
|
+
blockContentDOMAttributes.class
|
|
97
|
+
),
|
|
89
98
|
"data-content-type": this.name,
|
|
90
99
|
}),
|
|
91
|
-
[
|
|
100
|
+
[
|
|
101
|
+
"p",
|
|
102
|
+
{
|
|
103
|
+
class: mergeCSSClasses(
|
|
104
|
+
styles.inlineContent,
|
|
105
|
+
inlineContentDOMAttributes.class
|
|
106
|
+
),
|
|
107
|
+
},
|
|
108
|
+
0,
|
|
109
|
+
],
|
|
92
110
|
];
|
|
93
111
|
},
|
|
94
112
|
});
|
|
@@ -3,6 +3,7 @@ import { createTipTapBlock } from "../../../../api/block";
|
|
|
3
3
|
import { handleEnter } from "../ListItemKeyboardShortcuts";
|
|
4
4
|
import { NumberedListIndexingPlugin } from "./NumberedListIndexingPlugin";
|
|
5
5
|
import styles from "../../../Block.module.css";
|
|
6
|
+
import { mergeCSSClasses } from "../../../../../../shared/utils";
|
|
6
7
|
|
|
7
8
|
export const NumberedListItemBlockContent =
|
|
8
9
|
createTipTapBlock<"numberedListItem">({
|
|
@@ -106,15 +107,32 @@ export const NumberedListItemBlockContent =
|
|
|
106
107
|
},
|
|
107
108
|
|
|
108
109
|
renderHTML({ HTMLAttributes }) {
|
|
110
|
+
const blockContentDOMAttributes =
|
|
111
|
+
this.options.domAttributes?.blockContent || {};
|
|
112
|
+
const inlineContentDOMAttributes =
|
|
113
|
+
this.options.domAttributes?.inlineContent || {};
|
|
114
|
+
|
|
109
115
|
return [
|
|
110
116
|
"div",
|
|
111
117
|
mergeAttributes(HTMLAttributes, {
|
|
112
|
-
class:
|
|
118
|
+
class: mergeCSSClasses(
|
|
119
|
+
styles.blockContent,
|
|
120
|
+
blockContentDOMAttributes.class
|
|
121
|
+
),
|
|
113
122
|
"data-content-type": this.name,
|
|
114
123
|
}),
|
|
115
124
|
// we use a <p> tag, because for <li> tags we'd need to add a <ul> parent for around siblings to be semantically correct,
|
|
116
125
|
// which would be quite cumbersome
|
|
117
|
-
[
|
|
126
|
+
[
|
|
127
|
+
"p",
|
|
128
|
+
{
|
|
129
|
+
class: mergeCSSClasses(
|
|
130
|
+
styles.inlineContent,
|
|
131
|
+
inlineContentDOMAttributes.class
|
|
132
|
+
),
|
|
133
|
+
},
|
|
134
|
+
0,
|
|
135
|
+
],
|
|
118
136
|
];
|
|
119
137
|
},
|
|
120
138
|
});
|
package/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { mergeAttributes } from "@tiptap/core";
|
|
2
2
|
import { createTipTapBlock } from "../../../api/block";
|
|
3
3
|
import styles from "../../Block.module.css";
|
|
4
|
+
import { mergeCSSClasses } from "../../../../../shared/utils";
|
|
4
5
|
|
|
5
|
-
export const ParagraphBlockContent = createTipTapBlock
|
|
6
|
+
export const ParagraphBlockContent = createTipTapBlock({
|
|
6
7
|
name: "paragraph",
|
|
7
8
|
content: "inline*",
|
|
8
9
|
|
|
@@ -17,13 +18,35 @@ export const ParagraphBlockContent = createTipTapBlock<"paragraph">({
|
|
|
17
18
|
},
|
|
18
19
|
|
|
19
20
|
renderHTML({ HTMLAttributes }) {
|
|
21
|
+
const blockContentDOMAttributes =
|
|
22
|
+
this.options.domAttributes?.blockContent || {};
|
|
23
|
+
const inlineContentDOMAttributes =
|
|
24
|
+
this.options.domAttributes?.inlineContent || {};
|
|
25
|
+
|
|
20
26
|
return [
|
|
21
27
|
"div",
|
|
22
|
-
mergeAttributes(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
mergeAttributes(
|
|
29
|
+
{
|
|
30
|
+
...blockContentDOMAttributes,
|
|
31
|
+
class: mergeCSSClasses(
|
|
32
|
+
styles.blockContent,
|
|
33
|
+
blockContentDOMAttributes.class
|
|
34
|
+
),
|
|
35
|
+
"data-content-type": this.name,
|
|
36
|
+
},
|
|
37
|
+
HTMLAttributes
|
|
38
|
+
),
|
|
39
|
+
[
|
|
40
|
+
"p",
|
|
41
|
+
{
|
|
42
|
+
...inlineContentDOMAttributes,
|
|
43
|
+
class: mergeCSSClasses(
|
|
44
|
+
styles.inlineContent,
|
|
45
|
+
inlineContentDOMAttributes.class
|
|
46
|
+
),
|
|
47
|
+
},
|
|
48
|
+
0,
|
|
49
|
+
],
|
|
27
50
|
];
|
|
28
51
|
},
|
|
29
52
|
});
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import { mergeAttributes, Node } from "@tiptap/core";
|
|
2
2
|
import styles from "./Block.module.css";
|
|
3
|
+
import { BlockNoteDOMAttributes } from "../api/blockTypes";
|
|
4
|
+
import { mergeCSSClasses } from "../../../shared/utils";
|
|
3
5
|
|
|
4
|
-
export const BlockGroup = Node.create
|
|
6
|
+
export const BlockGroup = Node.create<{
|
|
7
|
+
domAttributes?: BlockNoteDOMAttributes;
|
|
8
|
+
}>({
|
|
5
9
|
name: "blockGroup",
|
|
6
10
|
group: "blockGroup",
|
|
7
11
|
content: "blockContainer+",
|
|
8
12
|
|
|
9
|
-
addOptions() {
|
|
10
|
-
return {
|
|
11
|
-
HTMLAttributes: {},
|
|
12
|
-
};
|
|
13
|
-
},
|
|
14
|
-
|
|
15
13
|
parseHTML() {
|
|
16
14
|
return [
|
|
17
15
|
{
|
|
@@ -33,12 +31,22 @@ export const BlockGroup = Node.create({
|
|
|
33
31
|
},
|
|
34
32
|
|
|
35
33
|
renderHTML({ HTMLAttributes }) {
|
|
34
|
+
const blockGroupDOMAttributes =
|
|
35
|
+
this.options.domAttributes?.blockGroup || {};
|
|
36
|
+
|
|
36
37
|
return [
|
|
37
38
|
"div",
|
|
38
|
-
mergeAttributes(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
mergeAttributes(
|
|
40
|
+
{
|
|
41
|
+
...blockGroupDOMAttributes,
|
|
42
|
+
class: mergeCSSClasses(
|
|
43
|
+
styles.blockGroup,
|
|
44
|
+
blockGroupDOMAttributes.class
|
|
45
|
+
),
|
|
46
|
+
"data-node-type": "blockGroup",
|
|
47
|
+
},
|
|
48
|
+
HTMLAttributes
|
|
49
|
+
),
|
|
42
50
|
0,
|
|
43
51
|
];
|
|
44
52
|
},
|