@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.
- package/dist/blocknote.js +1711 -1469
- package/dist/blocknote.js.map +1 -1
- package/dist/blocknote.umd.cjs +6 -2
- package/dist/blocknote.umd.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +3 -3
- package/src/BlockNoteEditor.ts +104 -53
- package/src/BlockNoteExtensions.ts +24 -14
- package/src/api/blockManipulation/blockManipulation.test.ts +6 -3
- package/src/api/blockManipulation/blockManipulation.ts +7 -6
- package/src/api/formatConversions/formatConversions.test.ts +13 -8
- package/src/api/formatConversions/formatConversions.ts +15 -12
- package/src/api/nodeConversions/__snapshots__/nodeConversions.test.ts.snap +292 -0
- package/src/api/nodeConversions/nodeConversions.test.ts +265 -10
- package/src/api/nodeConversions/nodeConversions.ts +199 -47
- package/src/api/nodeConversions/testUtil.ts +8 -4
- package/src/editor.module.css +5 -6
- package/src/extensions/Blocks/api/block.ts +229 -0
- package/src/extensions/Blocks/api/blockTypes.ts +158 -71
- package/src/extensions/Blocks/api/cursorPositionTypes.ts +5 -5
- package/src/extensions/Blocks/api/defaultBlocks.ts +44 -0
- package/src/extensions/Blocks/api/selectionTypes.ts +3 -3
- package/src/extensions/Blocks/api/serialization.ts +29 -0
- package/src/extensions/Blocks/index.ts +0 -8
- package/src/extensions/Blocks/nodes/Block.module.css +28 -16
- package/src/extensions/Blocks/nodes/BlockContainer.ts +8 -4
- package/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.ts +4 -4
- package/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +5 -5
- package/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +100 -97
- package/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.ts +4 -4
- package/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.ts +11 -9
- package/src/extensions/DraggableBlocks/DraggableBlocksExtension.ts +6 -5
- package/src/extensions/DraggableBlocks/DraggableBlocksPlugin.ts +57 -14
- package/src/extensions/FormattingToolbar/FormattingToolbarExtension.ts +21 -16
- package/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.ts +9 -5
- package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +38 -58
- package/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts +19 -0
- package/src/extensions/Placeholder/PlaceholderExtension.ts +1 -0
- package/src/extensions/SlashMenu/BaseSlashMenuItem.ts +5 -2
- package/src/extensions/SlashMenu/SlashMenuExtension.ts +37 -33
- package/src/extensions/SlashMenu/defaultSlashMenuItems.tsx +14 -10
- package/src/extensions/SlashMenu/index.ts +2 -2
- package/src/index.ts +4 -0
- package/src/shared/plugins/suggestion/SuggestionPlugin.ts +29 -13
- package/types/src/BlockNoteEditor.d.ts +38 -23
- package/types/src/BlockNoteExtensions.d.ts +15 -8
- package/types/src/api/blockManipulation/blockManipulation.d.ts +4 -4
- package/types/src/api/formatConversions/formatConversions.d.ts +5 -5
- package/types/src/api/nodeConversions/nodeConversions.d.ts +3 -3
- package/types/src/api/nodeConversions/testUtil.d.ts +2 -2
- package/types/src/extensions/Blocks/api/block.d.ts +2 -4
- package/types/src/extensions/Blocks/api/blockTypes.d.ts +77 -33
- package/types/src/extensions/Blocks/api/cursorPositionTypes.d.ts +5 -5
- package/types/src/extensions/Blocks/api/defaultBlocks.d.ts +4 -4
- package/types/src/extensions/Blocks/api/selectionTypes.d.ts +3 -3
- package/types/src/extensions/Blocks/api/serialization.d.ts +2 -0
- package/types/src/extensions/Blocks/nodes/BlockContainer.d.ts +3 -3
- package/types/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.d.ts +1 -2
- package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.d.ts +1 -2
- package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.d.ts +1 -2
- package/types/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.d.ts +1 -2
- package/types/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.d.ts +7 -7
- package/types/src/extensions/DraggableBlocks/DraggableBlocksExtension.d.ts +5 -4
- package/types/src/extensions/DraggableBlocks/DraggableBlocksPlugin.d.ts +12 -11
- package/types/src/extensions/FormattingToolbar/FormattingToolbarExtension.d.ts +6 -5
- package/types/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.d.ts +4 -3
- package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +16 -19
- package/types/src/extensions/Placeholder/localisation/index.d.ts +2 -0
- package/types/src/extensions/Placeholder/localisation/translation.d.ts +51 -0
- package/types/src/extensions/SlashMenu/BaseSlashMenuItem.d.ts +4 -3
- package/types/src/extensions/SlashMenu/SlashMenuExtension.d.ts +5 -4
- package/types/src/extensions/SlashMenu/defaultSlashMenuItems.d.ts +66 -1
- package/types/src/extensions/SlashMenu/index.d.ts +2 -2
- package/types/src/index.d.ts +4 -0
- package/types/src/shared/plugins/suggestion/SuggestionPlugin.d.ts +5 -4
- package/types/src/extensions/Blocks/api/alertBlock.d.ts +0 -13
- 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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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>;
|
|
@@ -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 #
|
|
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 #
|
|
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
|
-
.
|
|
229
|
-
.
|
|
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"] .
|
|
240
|
-
.
|
|
241
|
-
color: #
|
|
251
|
+
[data-theme="light"] .isEmpty .inlineContent:before,
|
|
252
|
+
.isFilter .inlineContent:before {
|
|
253
|
+
color: #CFCFCF;
|
|
242
254
|
}
|
|
243
255
|
|
|
244
|
-
[data-theme="dark"] .
|
|
245
|
-
.
|
|
246
|
-
color: #
|
|
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
|
-
.
|
|
263
|
+
.isEmpty.hasAnchor .inlineContent:before {
|
|
252
264
|
content: "Enter text or type '/' for commands";
|
|
253
265
|
}
|
|
254
266
|
|
|
255
|
-
.blockContent.isFilter.hasAnchor
|
|
267
|
+
.blockContent.isFilter.hasAnchor .inlineContent:before {
|
|
256
268
|
content: "Type to filter";
|
|
257
269
|
}
|
|
258
270
|
|
|
259
|
-
.blockContent[data-content-type="heading"].isEmpty
|
|
271
|
+
.blockContent[data-content-type="heading"].isEmpty .inlineContent:before {
|
|
260
272
|
content: "Heading";
|
|
261
273
|
}
|
|
262
274
|
|
|
263
|
-
.blockContent[data-content-type="bulletListItem"].isEmpty
|
|
275
|
+
.blockContent[data-content-type="bulletListItem"].isEmpty .inlineContent:before,
|
|
264
276
|
.blockContent[data-content-type="numberedListItem"].isEmpty
|
|
265
|
-
|
|
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
|
-
|
|
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:
|
|
27
|
-
|
|
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
|
|
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 =
|
|
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
|
|
2
|
-
import
|
|
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 =
|
|
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
|
});
|