@blocknote/core 0.7.1-alpha.0 → 0.8.1

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 (77) hide show
  1. package/dist/blocknote.js +1711 -1469
  2. package/dist/blocknote.js.map +1 -1
  3. package/dist/blocknote.umd.cjs +6 -2
  4. package/dist/blocknote.umd.cjs.map +1 -1
  5. package/dist/style.css +1 -1
  6. package/package.json +3 -3
  7. package/src/BlockNoteEditor.ts +104 -53
  8. package/src/BlockNoteExtensions.ts +24 -14
  9. package/src/api/blockManipulation/blockManipulation.test.ts +6 -3
  10. package/src/api/blockManipulation/blockManipulation.ts +7 -6
  11. package/src/api/formatConversions/formatConversions.test.ts +13 -8
  12. package/src/api/formatConversions/formatConversions.ts +15 -12
  13. package/src/api/nodeConversions/__snapshots__/nodeConversions.test.ts.snap +292 -0
  14. package/src/api/nodeConversions/nodeConversions.test.ts +265 -10
  15. package/src/api/nodeConversions/nodeConversions.ts +199 -47
  16. package/src/api/nodeConversions/testUtil.ts +8 -4
  17. package/src/editor.module.css +5 -6
  18. package/src/extensions/Blocks/api/block.ts +229 -0
  19. package/src/extensions/Blocks/api/blockTypes.ts +158 -71
  20. package/src/extensions/Blocks/api/cursorPositionTypes.ts +5 -5
  21. package/src/extensions/Blocks/api/defaultBlocks.ts +44 -0
  22. package/src/extensions/Blocks/api/selectionTypes.ts +3 -3
  23. package/src/extensions/Blocks/api/serialization.ts +29 -0
  24. package/src/extensions/Blocks/index.ts +0 -8
  25. package/src/extensions/Blocks/nodes/Block.module.css +28 -16
  26. package/src/extensions/Blocks/nodes/BlockContainer.ts +8 -4
  27. package/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.ts +4 -4
  28. package/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +5 -5
  29. package/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +100 -97
  30. package/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.ts +4 -4
  31. package/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.ts +11 -9
  32. package/src/extensions/DraggableBlocks/DraggableBlocksExtension.ts +6 -5
  33. package/src/extensions/DraggableBlocks/DraggableBlocksPlugin.ts +57 -14
  34. package/src/extensions/FormattingToolbar/FormattingToolbarExtension.ts +21 -16
  35. package/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.ts +9 -5
  36. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +38 -58
  37. package/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts +19 -0
  38. package/src/extensions/Placeholder/PlaceholderExtension.ts +1 -0
  39. package/src/extensions/SlashMenu/BaseSlashMenuItem.ts +5 -2
  40. package/src/extensions/SlashMenu/SlashMenuExtension.ts +37 -33
  41. package/src/extensions/SlashMenu/defaultSlashMenuItems.tsx +14 -10
  42. package/src/extensions/SlashMenu/index.ts +2 -2
  43. package/src/index.ts +4 -0
  44. package/src/shared/plugins/suggestion/SuggestionPlugin.ts +29 -13
  45. package/types/src/BlockNoteEditor.d.ts +38 -23
  46. package/types/src/BlockNoteExtensions.d.ts +15 -8
  47. package/types/src/api/blockManipulation/blockManipulation.d.ts +4 -4
  48. package/types/src/api/formatConversions/formatConversions.d.ts +5 -5
  49. package/types/src/api/nodeConversions/nodeConversions.d.ts +3 -3
  50. package/types/src/api/nodeConversions/testUtil.d.ts +2 -2
  51. package/types/src/extensions/Blocks/api/block.d.ts +2 -4
  52. package/types/src/extensions/Blocks/api/blockTypes.d.ts +77 -33
  53. package/types/src/extensions/Blocks/api/cursorPositionTypes.d.ts +5 -5
  54. package/types/src/extensions/Blocks/api/defaultBlocks.d.ts +4 -4
  55. package/types/src/extensions/Blocks/api/selectionTypes.d.ts +3 -3
  56. package/types/src/extensions/Blocks/api/serialization.d.ts +2 -0
  57. package/types/src/extensions/Blocks/nodes/BlockContainer.d.ts +3 -3
  58. package/types/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.d.ts +1 -2
  59. package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.d.ts +1 -2
  60. package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.d.ts +1 -2
  61. package/types/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.d.ts +1 -2
  62. package/types/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.d.ts +7 -7
  63. package/types/src/extensions/DraggableBlocks/DraggableBlocksExtension.d.ts +5 -4
  64. package/types/src/extensions/DraggableBlocks/DraggableBlocksPlugin.d.ts +12 -11
  65. package/types/src/extensions/FormattingToolbar/FormattingToolbarExtension.d.ts +6 -5
  66. package/types/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.d.ts +4 -3
  67. package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +16 -19
  68. package/types/src/extensions/Placeholder/localisation/index.d.ts +2 -0
  69. package/types/src/extensions/Placeholder/localisation/translation.d.ts +51 -0
  70. package/types/src/extensions/SlashMenu/BaseSlashMenuItem.d.ts +4 -3
  71. package/types/src/extensions/SlashMenu/SlashMenuExtension.d.ts +5 -4
  72. package/types/src/extensions/SlashMenu/defaultSlashMenuItems.d.ts +66 -1
  73. package/types/src/extensions/SlashMenu/index.d.ts +2 -2
  74. package/types/src/index.d.ts +4 -0
  75. package/types/src/shared/plugins/suggestion/SuggestionPlugin.d.ts +5 -4
  76. package/types/src/extensions/Blocks/api/alertBlock.d.ts +0 -13
  77. package/types/src/extensions/Blocks/api/alertBlock2.d.ts +0 -13
@@ -1,90 +1,177 @@
1
1
  /** Define the main block types **/
2
-
2
+ import { Node, NodeConfig } from "@tiptap/core";
3
+ import { BlockNoteEditor } from "../../../BlockNoteEditor";
3
4
  import { InlineContent, PartialInlineContent } from "./inlineContentTypes";
4
5
 
5
- export type BlockTemplate<
6
- // Type of the block.
7
- // Examples might include: "paragraph", "heading", or "bulletListItem".
8
- Type extends string,
9
- // Changeable props which affect the block's behaviour or appearance.
10
- // An example might be: { textAlignment: "left" | "right" | "center" } for a paragraph block.
11
- Props extends Record<string, string>
6
+ // A configuration for a TipTap node, but with stricter type constraints on the
7
+ // "name" and "group" properties. The "name" property is now always a string
8
+ // literal type, and the "blockGroup" property cannot be configured as it should
9
+ // always be "blockContent". Used as the parameter in `createTipTapNode`.
10
+ export type TipTapNodeConfig<
11
+ Name extends string,
12
+ Options = any,
13
+ Storage = any
12
14
  > = {
13
- id: string;
14
- type: Type;
15
- props: Props;
16
- content: InlineContent[];
17
- children: Block[];
15
+ [K in keyof NodeConfig<Options, Storage>]: K extends "name"
16
+ ? Name
17
+ : K extends "group"
18
+ ? never
19
+ : NodeConfig<Options, Storage>[K];
18
20
  };
19
21
 
20
- export type DefaultBlockProps = {
21
- backgroundColor: string;
22
- textColor: string;
23
- textAlignment: "left" | "center" | "right" | "justify";
22
+ // A TipTap node with stricter type constraints on the "name" and "group"
23
+ // properties. The "name" property is now a string literal type, and the
24
+ // "blockGroup" property is now "blockContent". Returned by `createTipTapNode`.
25
+ export type TipTapNode<
26
+ Name extends string,
27
+ Options = any,
28
+ Storage = any
29
+ > = Node<Options, Storage> & {
30
+ name: Name;
31
+ group: "blockContent";
24
32
  };
25
33
 
26
- export type NumberedListItemBlock = BlockTemplate<
27
- "numberedListItem",
28
- DefaultBlockProps
29
- >;
34
+ // Defines a single prop spec, which includes the default value the prop should
35
+ // take and possible values it can take.
36
+ export type PropSpec = {
37
+ values?: readonly string[];
38
+ default: string;
39
+ };
30
40
 
31
- export type BulletListItemBlock = BlockTemplate<
32
- "bulletListItem",
33
- DefaultBlockProps
34
- >;
41
+ // Defines multiple block prop specs. The key of each prop is the name of the
42
+ // prop, while the value is a corresponding prop spec. This should be included
43
+ // in a block config or schema. From a prop schema, we can derive both the props'
44
+ // internal implementation (as TipTap node attributes) and the type information
45
+ // for the external API.
46
+ export type PropSchema = Record<string, PropSpec>;
35
47
 
36
- export type HeadingBlock = BlockTemplate<
37
- "heading",
38
- DefaultBlockProps & {
39
- level: "1" | "2" | "3";
40
- }
41
- >;
48
+ // Defines Props objects for use in Block objects in the external API. Converts
49
+ // each prop spec into a union type of its possible values, or a string if no
50
+ // values are specified.
51
+ export type Props<PSchema extends PropSchema> = {
52
+ [PType in keyof PSchema]: PSchema[PType]["values"] extends readonly string[]
53
+ ? PSchema[PType]["values"][number]
54
+ : string;
55
+ };
42
56
 
43
- export type ParagraphBlock = BlockTemplate<"paragraph", DefaultBlockProps>;
57
+ // Defines the config for a single block. Meant to be used as an argument to
58
+ // `createBlockSpec`, which will create a new block spec from it. This is the
59
+ // main way we expect people to create custom blocks as consumers don't need to
60
+ // know anything about the TipTap API since the associated nodes are created
61
+ // automatically.
62
+ export type BlockConfig<
63
+ Type extends string,
64
+ PSchema extends PropSchema,
65
+ ContainsInlineContent extends boolean,
66
+ BSchema extends BlockSchema
67
+ > = {
68
+ // Attributes to define block in the API as well as a TipTap node.
69
+ type: Type;
70
+ readonly propSchema: PSchema;
44
71
 
45
- export type Block =
46
- | ParagraphBlock
47
- | HeadingBlock
48
- | BulletListItemBlock
49
- | NumberedListItemBlock;
72
+ // Additional attributes to help define block as a TipTap node.
73
+ containsInlineContent: ContainsInlineContent;
74
+ render: (
75
+ /**
76
+ * The custom block to render
77
+ */
78
+ block: SpecificBlock<
79
+ BSchema & { [k in Type]: BlockSpec<Type, PSchema> },
80
+ Type
81
+ >,
82
+ /**
83
+ * The BlockNote editor instance
84
+ * This is typed generically. If you want an editor with your custom schema, you need to
85
+ * cast it manually, e.g.: `const e = editor as BlockNoteEditor<typeof mySchema>;`
86
+ */
87
+ editor: BlockNoteEditor<BSchema & { [k in Type]: BlockSpec<Type, PSchema> }>
88
+ // (note) if we want to fix the manual cast, we need to prevent circular references and separate block definition and render implementations
89
+ // or allow manually passing <BSchema>, but that's not possible without passing the other generics because Typescript doesn't support partial inferred generics
90
+ ) => ContainsInlineContent extends true
91
+ ? {
92
+ dom: HTMLElement;
93
+ contentDOM: HTMLElement;
94
+ }
95
+ : {
96
+ dom: HTMLElement;
97
+ };
98
+ };
50
99
 
51
- export type BlockIdentifier = string | Block;
100
+ // Defines a single block spec, which includes the props that the block has and
101
+ // the TipTap node used to implement it. Usually created using `createBlockSpec`
102
+ // though it can also be defined from scratch by providing your own TipTap node,
103
+ // allowing for more advanced custom blocks.
104
+ export type BlockSpec<Type extends string, PSchema extends PropSchema> = {
105
+ readonly propSchema: PSchema;
106
+ node: TipTapNode<Type>;
107
+ };
52
108
 
53
- /** Define "Partial Blocks", these are for updating or creating blocks */
54
- export type PartialBlockTemplate<B extends Block> = B extends Block
55
- ? Partial<Omit<B, "props" | "children" | "content" | "type">> & {
56
- type?: B["type"];
57
- props?: Partial<B["props"]>;
58
- content?: string | PartialInlineContent[];
59
- children?: PartialBlock[];
60
- }
109
+ // Utility type. For a given object block schema, ensures that the key of each
110
+ // block spec matches the name of the TipTap node in it.
111
+ export type TypesMatch<
112
+ Blocks extends Record<string, BlockSpec<string, PropSchema>>
113
+ > = Blocks extends {
114
+ [Type in keyof Blocks]: Type extends string
115
+ ? Blocks[Type] extends BlockSpec<Type, PropSchema>
116
+ ? Blocks[Type]
117
+ : never
118
+ : never;
119
+ }
120
+ ? Blocks
61
121
  : never;
62
122
 
63
- export type PartialBlock = PartialBlockTemplate<Block>;
123
+ // Defines multiple block specs. Also ensures that the key of each block schema
124
+ // is the same as name of the TipTap node in it. This should be passed in the
125
+ // `blocks` option of the BlockNoteEditor. From a block schema, we can derive
126
+ // both the blocks' internal implementation (as TipTap nodes) and the type
127
+ // information for the external API.
128
+ export type BlockSchema = TypesMatch<
129
+ Record<string, BlockSpec<string, PropSchema>>
130
+ >;
64
131
 
65
- export type BlockPropsTemplate<Props> = Props extends Block["props"]
66
- ? keyof Props
67
- : never;
132
+ // Converts each block spec into a Block object without children. We later merge
133
+ // them into a union type and add a children property to create the Block and
134
+ // PartialBlock objects we use in the external API.
135
+ type BlocksWithoutChildren<BSchema extends BlockSchema> = {
136
+ [BType in keyof BSchema]: {
137
+ id: string;
138
+ type: BType;
139
+ props: Props<BSchema[BType]["propSchema"]>;
140
+ content: InlineContent[];
141
+ };
142
+ };
68
143
 
69
- /**
70
- * Expose blockProps. This is currently not very nice, but it's expected this
71
- * will change anyway once we allow for custom blocks
72
- */
73
-
74
- export const globalProps: Array<keyof DefaultBlockProps> = [
75
- "backgroundColor",
76
- "textColor",
77
- "textAlignment",
78
- ];
79
-
80
- export const blockProps: Record<Block["type"], Set<string>> = {
81
- paragraph: new Set<keyof ParagraphBlock["props"]>([...globalProps]),
82
- heading: new Set<keyof HeadingBlock["props"]>([
83
- ...globalProps,
84
- "level" as const,
85
- ]),
86
- numberedListItem: new Set<keyof NumberedListItemBlock["props"]>([
87
- ...globalProps,
88
- ]),
89
- bulletListItem: new Set<keyof BulletListItemBlock["props"]>([...globalProps]),
144
+ // Converts each block spec into a Block object without children, merges them
145
+ // into a union type, and adds a children property
146
+ export type Block<BSchema extends BlockSchema> =
147
+ BlocksWithoutChildren<BSchema>[keyof BlocksWithoutChildren<BSchema>] & {
148
+ children: Block<BSchema>[];
149
+ };
150
+
151
+ export type SpecificBlock<
152
+ BSchema extends BlockSchema,
153
+ BlockType extends keyof BSchema
154
+ > = BlocksWithoutChildren<BSchema>[BlockType] & {
155
+ children: Block<BSchema>[];
156
+ };
157
+
158
+ // Same as BlockWithoutChildren, but as a partial type with some changes to make
159
+ // it easier to create/update blocks in the editor.
160
+ type PartialBlocksWithoutChildren<BSchema extends BlockSchema> = {
161
+ [BType in keyof BSchema]: Partial<{
162
+ id: string;
163
+ type: BType;
164
+ props: Partial<Props<BSchema[BType]["propSchema"]>>;
165
+ content: PartialInlineContent[] | string;
166
+ }>;
90
167
  };
168
+
169
+ // Same as Block, but as a partial type with some changes to make it easier to
170
+ // create/update blocks in the editor.
171
+ export type PartialBlock<BSchema extends BlockSchema> =
172
+ PartialBlocksWithoutChildren<BSchema>[keyof PartialBlocksWithoutChildren<BSchema>] &
173
+ Partial<{
174
+ children: PartialBlock<BSchema>[];
175
+ }>;
176
+
177
+ export type BlockIdentifier = { id: string } | string;
@@ -1,7 +1,7 @@
1
- import { Block } from "./blockTypes";
1
+ import { Block, BlockSchema } from "./blockTypes";
2
2
 
3
- export type TextCursorPosition = {
4
- block: Block;
5
- prevBlock: Block | undefined;
6
- nextBlock: Block | undefined;
3
+ export type TextCursorPosition<BSchema extends BlockSchema> = {
4
+ block: Block<BSchema>;
5
+ prevBlock: Block<BSchema> | undefined;
6
+ nextBlock: Block<BSchema> | undefined;
7
7
  };
@@ -0,0 +1,44 @@
1
+ import { HeadingBlockContent } from "../nodes/BlockContent/HeadingBlockContent/HeadingBlockContent";
2
+ import { BulletListItemBlockContent } from "../nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent";
3
+ import { NumberedListItemBlockContent } from "../nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent";
4
+ import { ParagraphBlockContent } from "../nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent";
5
+ import { PropSchema, TypesMatch } from "./blockTypes";
6
+
7
+ export const defaultProps = {
8
+ backgroundColor: {
9
+ default: "transparent" as const,
10
+ },
11
+ textColor: {
12
+ default: "black" as const, // TODO
13
+ },
14
+ textAlignment: {
15
+ default: "left" as const,
16
+ values: ["left", "center", "right", "justify"] as const,
17
+ },
18
+ } satisfies PropSchema;
19
+
20
+ export type DefaultProps = typeof defaultProps;
21
+
22
+ export const defaultBlockSchema = {
23
+ paragraph: {
24
+ propSchema: defaultProps,
25
+ node: ParagraphBlockContent,
26
+ },
27
+ heading: {
28
+ propSchema: {
29
+ ...defaultProps,
30
+ level: { default: "1", values: ["1", "2", "3"] as const },
31
+ },
32
+ node: HeadingBlockContent,
33
+ },
34
+ bulletListItem: {
35
+ propSchema: defaultProps,
36
+ node: BulletListItemBlockContent,
37
+ },
38
+ numberedListItem: {
39
+ propSchema: defaultProps,
40
+ node: NumberedListItemBlockContent,
41
+ },
42
+ } as const;
43
+
44
+ export type DefaultBlockSchema = TypesMatch<typeof defaultBlockSchema>;
@@ -1,5 +1,5 @@
1
- import { Block } from "./blockTypes";
1
+ import { Block, BlockSchema } from "./blockTypes";
2
2
 
3
- export type Selection = {
4
- blocks: Block[];
3
+ export type Selection<BSchema extends BlockSchema> = {
4
+ blocks: Block<BSchema>[];
5
5
  };
@@ -0,0 +1,29 @@
1
+ import { Extension } from "@tiptap/core";
2
+ import { Plugin } from "prosemirror-state";
3
+ import { DOMSerializer, Schema } from "prosemirror-model";
4
+
5
+ const customBlockSerializer = (schema: Schema) => {
6
+ const defaultSerializer = DOMSerializer.fromSchema(schema);
7
+
8
+ return new DOMSerializer(
9
+ {
10
+ ...defaultSerializer.nodes,
11
+ // TODO: If a serializer is defined in the config for a custom block, it
12
+ // should be added here. We still need to figure out how the serializer
13
+ // should be defined in the custom blocks API though, and implement that,
14
+ // before we can do this.
15
+ },
16
+ defaultSerializer.marks
17
+ );
18
+ };
19
+ export const CustomBlockSerializerExtension = Extension.create({
20
+ addProseMirrorPlugins() {
21
+ return [
22
+ new Plugin({
23
+ props: {
24
+ clipboardSerializer: customBlockSerializer(this.editor.schema),
25
+ },
26
+ }),
27
+ ];
28
+ },
29
+ });
@@ -1,16 +1,8 @@
1
1
  import { Node } from "@tiptap/core";
2
2
  import { BlockContainer } from "./nodes/BlockContainer";
3
3
  import { BlockGroup } from "./nodes/BlockGroup";
4
- import { ParagraphBlockContent } from "./nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent";
5
- import { HeadingBlockContent } from "./nodes/BlockContent/HeadingBlockContent/HeadingBlockContent";
6
- import { BulletListItemBlockContent } from "./nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent";
7
- import { NumberedListItemBlockContent } from "./nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent";
8
4
 
9
5
  export const blocks: any[] = [
10
- ParagraphBlockContent,
11
- HeadingBlockContent,
12
- BulletListItemBlockContent,
13
- NumberedListItemBlockContent,
14
6
  BlockContainer,
15
7
  BlockGroup,
16
8
  Node.create({
@@ -7,14 +7,26 @@ BASIC STYLES
7
7
  transition: margin 0.2s;
8
8
  }
9
9
 
10
+ /*Ensures blocks & block content spans editor width*/
11
+ .block {
12
+ display: flex;
13
+ flex-direction: column;
14
+ }
15
+
16
+ /*Ensures block content inside React node views spans editor width*/
17
+ .reactNodeViewRenderer {
18
+ display: flex;
19
+ flex-grow: 1;
20
+ }
21
+
10
22
  .blockContent {
11
23
  padding: 3px 0;
24
+ flex-grow: 1;
12
25
  transition: font-size 0.2s;
13
26
  /*
14
27
  because the content elements are display: block
15
28
  we use flex to position them next to list markers
16
29
  */
17
- display: flex;
18
30
  }
19
31
 
20
32
  .blockContent::before {
@@ -48,14 +60,14 @@ NESTED BLOCKS
48
60
  .blockGroup
49
61
  .blockGroup
50
62
  > .blockOuter:not([data-prev-depth-changed])::before {
51
- border-left: 1px solid #cccccc;
63
+ border-left: 1px solid #AFAFAF;
52
64
  }
53
65
 
54
66
  [data-theme="dark"]
55
67
  .blockGroup
56
68
  .blockGroup
57
69
  > .blockOuter:not([data-prev-depth-changed])::before {
58
- border-left: 1px solid #999999;
70
+ border-left: 1px solid #7F7F7F;
59
71
  }
60
72
 
61
73
  .blockGroup .blockGroup > .blockOuter[data-prev-depth-change="-2"]::before {
@@ -225,8 +237,8 @@ NESTED BLOCKS
225
237
 
226
238
  /* PLACEHOLDERS*/
227
239
 
228
- .blockContent.isEmpty > :first-child:before,
229
- .blockContent.isFilter > :first-child:before {
240
+ .isEmpty .inlineContent:before,
241
+ .isFilter .inlineContent:before {
230
242
  /*float: left; */
231
243
  content: "";
232
244
  pointer-events: none;
@@ -236,33 +248,33 @@ NESTED BLOCKS
236
248
  font-style: italic;
237
249
  }
238
250
 
239
- [data-theme="light"] .blockContent.isEmpty > :first-child:before,
240
- .blockContent.isFilter > :first-child:before {
241
- color: #cccccc;
251
+ [data-theme="light"] .isEmpty .inlineContent:before,
252
+ .isFilter .inlineContent:before {
253
+ color: #CFCFCF;
242
254
  }
243
255
 
244
- [data-theme="dark"] .blockContent.isEmpty > :first-child:before,
245
- .blockContent.isFilter > :first-child:before {
246
- color: #999999;
256
+ [data-theme="dark"] .isEmpty .inlineContent:before,
257
+ .isFilter .inlineContent:before {
258
+ color: #7F7F7F;
247
259
  }
248
260
 
249
261
  /* TODO: would be nicer if defined from code */
250
262
 
251
- .blockContent.isEmpty.hasAnchor > :first-child:before {
263
+ .isEmpty.hasAnchor .inlineContent:before {
252
264
  content: "Enter text or type '/' for commands";
253
265
  }
254
266
 
255
- .blockContent.isFilter.hasAnchor > :first-child:before {
267
+ .blockContent.isFilter.hasAnchor .inlineContent:before {
256
268
  content: "Type to filter";
257
269
  }
258
270
 
259
- .blockContent[data-content-type="heading"].isEmpty > :first-child::before {
271
+ .blockContent[data-content-type="heading"].isEmpty .inlineContent:before {
260
272
  content: "Heading";
261
273
  }
262
274
 
263
- .blockContent[data-content-type="bulletListItem"].isEmpty > :first-child:before,
275
+ .blockContent[data-content-type="bulletListItem"].isEmpty .inlineContent:before,
264
276
  .blockContent[data-content-type="numberedListItem"].isEmpty
265
- > :first-child:before {
277
+ .inlineContent:before {
266
278
  content: "List";
267
279
  }
268
280
 
@@ -5,11 +5,12 @@ import {
5
5
  blockToNode,
6
6
  inlineContentToNodes,
7
7
  } from "../../../api/nodeConversions/nodeConversions";
8
- import { PartialBlock } from "../api/blockTypes";
8
+
9
9
  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 { BlockSchema, PartialBlock } from "../api/blockTypes";
13
14
 
14
15
  // TODO
15
16
  export interface IBlock {
@@ -23,10 +24,13 @@ declare module "@tiptap/core" {
23
24
  BNDeleteBlock: (posInBlock: number) => ReturnType;
24
25
  BNMergeBlocks: (posBetweenBlocks: number) => ReturnType;
25
26
  BNSplitBlock: (posInBlock: number, keepType: boolean) => ReturnType;
26
- BNUpdateBlock: (posInBlock: number, block: PartialBlock) => ReturnType;
27
- BNCreateOrUpdateBlock: (
27
+ BNUpdateBlock: <BSchema extends BlockSchema>(
28
+ posInBlock: number,
29
+ block: PartialBlock<BSchema>
30
+ ) => ReturnType;
31
+ BNCreateOrUpdateBlock: <BSchema extends BlockSchema>(
28
32
  posInBlock: number,
29
- block: PartialBlock
33
+ block: PartialBlock<BSchema>
30
34
  ) => ReturnType;
31
35
  };
32
36
  }
@@ -1,9 +1,9 @@
1
- import { InputRule, mergeAttributes, Node } from "@tiptap/core";
1
+ import { InputRule, mergeAttributes } from "@tiptap/core";
2
+ import { createTipTapBlock } from "../../../api/block";
2
3
  import styles from "../../Block.module.css";
3
4
 
4
- export const HeadingBlockContent = Node.create({
5
+ export const HeadingBlockContent = createTipTapBlock<"heading">({
5
6
  name: "heading",
6
- group: "blockContent",
7
7
  content: "inline*",
8
8
 
9
9
  addAttributes() {
@@ -70,7 +70,7 @@ export const HeadingBlockContent = Node.create({
70
70
  class: styles.blockContent,
71
71
  "data-content-type": this.name,
72
72
  }),
73
- ["h" + node.attrs.level, 0],
73
+ ["h" + node.attrs.level, { class: styles.inlineContent }, 0],
74
74
  ];
75
75
  },
76
76
  });
@@ -1,10 +1,10 @@
1
- import { InputRule, mergeAttributes, Node } from "@tiptap/core";
2
- import styles from "../../../Block.module.css";
1
+ import { InputRule, mergeAttributes } from "@tiptap/core";
2
+ import { createTipTapBlock } from "../../../../api/block";
3
3
  import { handleEnter } from "../ListItemKeyboardShortcuts";
4
+ import styles from "../../../Block.module.css";
4
5
 
5
- export const BulletListItemBlockContent = Node.create({
6
+ export const BulletListItemBlockContent = createTipTapBlock<"bulletListItem">({
6
7
  name: "bulletListItem",
7
- group: "blockContent",
8
8
  content: "inline*",
9
9
 
10
10
  addInputRules() {
@@ -88,7 +88,7 @@ export const BulletListItemBlockContent = Node.create({
88
88
  class: styles.blockContent,
89
89
  "data-content-type": this.name,
90
90
  }),
91
- ["p", 0],
91
+ ["p", { class: styles.inlineContent }, 0],
92
92
  ];
93
93
  },
94
94
  });