Skip to content

Commit b75cd5f

Browse files
committed
feat: introduce BaseBlock, a base of the restraints
1 parent cf8c552 commit b75cd5f

File tree

4 files changed

+24
-38
lines changed

4 files changed

+24
-38
lines changed

packages/core/src/BlockNoteEditor.ts

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,33 @@ import { Editor, EditorOptions } from "@tiptap/core";
22
import { Node } from "prosemirror-model";
33
// import "./blocknote.css";
44
import { Editor as TiptapEditor } from "@tiptap/core/dist/packages/core/src/Editor";
5+
import { UiFactories, getBlockNoteExtensions } from "./BlockNoteExtensions";
56
import {
67
insertBlocks,
78
removeBlocks,
89
replaceBlocks,
910
updateBlock,
1011
} from "./api/blockManipulation/blockManipulation";
1112
import {
13+
HTMLToBlocks,
1214
blocksToHTML,
1315
blocksToMarkdown,
14-
HTMLToBlocks,
1516
markdownToBlocks,
1617
} from "./api/formatConversions/formatConversions";
1718
import { nodeToBlock } from "./api/nodeConversions/nodeConversions";
1819
import { getNodeById } from "./api/util/nodeUtil";
19-
import { getBlockNoteExtensions, UiFactories } from "./BlockNoteExtensions";
2020
import styles from "./editor.module.css";
2121
import {
22+
BaseBlock,
2223
BlockIdentifier,
2324
BlockSpec,
24-
BlockTemplate,
2525
PartialBlockTemplate,
2626
} from "./extensions/Blocks/api/blockTypes";
2727
import {
2828
MouseCursorPosition,
2929
TextCursorPosition,
3030
} from "./extensions/Blocks/api/cursorPositionTypes";
31-
import {
32-
defaultBlocks,
33-
DefaultBlockTypes,
34-
} from "./extensions/Blocks/api/defaultBlocks";
31+
import { defaultBlocks } from "./extensions/Blocks/api/defaultBlocks";
3532
import {
3633
ColorStyle,
3734
Styles,
@@ -44,16 +41,7 @@ import {
4441
defaultSlashMenuItems,
4542
} from "./extensions/SlashMenu";
4643

47-
// We need to separate WithChildren, otherwise we get issues with recursive types
48-
// maybe worth a revisit before merging
49-
type WithChildren<Block extends BlockTemplate<any, any>> = Block & {
50-
children: WithChildren<Block>[];
51-
};
52-
53-
export type BlockNoteEditorOptions<
54-
BareBlock extends BlockTemplate<any, any>,
55-
Block extends BareBlock = WithChildren<BareBlock>
56-
> = {
44+
export type BlockNoteEditorOptions<Block extends BaseBlock = BaseBlock> = {
5745
// TODO: Figure out if enableBlockNoteExtensions/disableHistoryExtension are needed and document them.
5846
enableBlockNoteExtensions: boolean;
5947
disableHistoryExtension: boolean;
@@ -116,10 +104,7 @@ const blockNoteTipTapOptions = {
116104
};
117105

118106
// TODO: make type of BareBlock / Block automatically based on options.blocks
119-
export class BlockNoteEditor<
120-
BareBlock extends BlockTemplate<any, any> = DefaultBlockTypes,
121-
Block extends BareBlock & { children: Block[] } = WithChildren<BareBlock>
122-
> {
107+
export class BlockNoteEditor<Block extends BaseBlock = BaseBlock> {
123108
public readonly _tiptapEditor: TiptapEditor & { contentComponent: any };
124109
private blockCache = new WeakMap<Node, Block>();
125110
private mousePos = { x: 0, y: 0 };
@@ -134,7 +119,6 @@ export class BlockNoteEditor<
134119
}
135120

136121
constructor(options: Partial<BlockNoteEditorOptions<Block>> = {}) {
137-
console.log("test");
138122
// apply defaults
139123
options = {
140124
defaultStyles: true,
@@ -266,7 +250,7 @@ export class BlockNoteEditor<
266250
* @param reverse Whether the blocks should be traversed in reverse order.
267251
*/
268252
public forEachBlock(
269-
callback: (block: Block) => boolean,
253+
callback: (block: BaseBlock) => boolean,
270254
reverse: boolean = false
271255
): void {
272256
const blocks = this.topLevelBlocks.slice();
@@ -275,15 +259,17 @@ export class BlockNoteEditor<
275259
blocks.reverse();
276260
}
277261

278-
function traverseBlockArray(blockArray: Block[]): boolean {
262+
function traverseBlockArray(blockArray: BaseBlock[]): boolean {
279263
for (const block of blockArray) {
280264
if (!callback(block)) {
281265
return false;
282266
}
283267

284-
const children = reverse
285-
? block.children.slice().reverse()
286-
: block.children;
268+
const children: BaseBlock[] = block.children
269+
? reverse
270+
? block.children.slice().reverse()
271+
: block.children
272+
: [];
287273

288274
if (!traverseBlockArray(children)) {
289275
return false;
@@ -685,12 +671,8 @@ export class BlockNoteEditor<
685671
* @param markdown The Markdown string to parse blocks from.
686672
* @returns The blocks parsed from the Markdown string.
687673
*/
688-
public async markdownToBlocks(markdown: string): Promise<Block[]> {
689-
return markdownToBlocks(
690-
markdown,
691-
this.schema,
692-
this._tiptapEditor.schema
693-
) as any; // TODO: fix type
674+
public async markdownToBlocks(markdown: string): Promise<BaseBlock[]> {
675+
return markdownToBlocks(markdown, this.schema, this._tiptapEditor.schema);
694676
}
695677
}
696678

packages/core/src/api/formatConversions/formatConversions.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import remarkRehype from "remark-rehype";
88
import remarkStringify from "remark-stringify";
99
import { unified } from "unified";
1010
import {
11+
BaseBlock,
1112
BlockSpec,
1213
BlockTemplate,
1314
} from "../../extensions/Blocks/api/blockTypes";
@@ -45,14 +46,14 @@ export async function HTMLToBlocks(
4546
html: string,
4647
schema: Map<string, BlockSpec>,
4748
pmSchema: Schema
48-
): Promise<BlockTemplate<any, any>[]> {
49+
): Promise<BaseBlock[]> {
4950
const htmlNode = document.createElement("div");
5051
htmlNode.innerHTML = html.trim();
5152

5253
const parser = DOMParser.fromSchema(pmSchema);
5354
const parentNode = parser.parse(htmlNode);
5455

55-
const blocks: BlockTemplate<any, any>[] = [];
56+
const blocks: BaseBlock[] = [];
5657

5758
for (let i = 0; i < parentNode.firstChild!.childCount; i++) {
5859
blocks.push(nodeToBlock(parentNode.firstChild!.child(i), schema));
@@ -62,7 +63,7 @@ export async function HTMLToBlocks(
6263
}
6364

6465
export async function blocksToMarkdown(
65-
blocks: BlockTemplate<any, any>[],
66+
blocks: BaseBlock[],
6667
schema: Schema
6768
): Promise<string> {
6869
const markdownString = await unified()

packages/core/src/extensions/Blocks/api/block.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Attribute, Node } from "@tiptap/core";
2-
import { PropsFromPropSpec, PropSpec } from "./blockTypes";
2+
import { PropSpec, PropsFromPropSpec } from "./blockTypes";
33

44
function camelToDataKebab(str: string): string {
55
return "data-" + str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
@@ -26,7 +26,7 @@ export function createBlockFromTiptapNode<
2626
) {
2727
if (node.name !== blockType) {
2828
throw Error(
29-
"Node must be of type " + blockType + ", but is of type" + node.name + "."
29+
`Node must be of type ${blockType}, but is of type ${node.name}.`
3030
);
3131
}
3232

packages/core/src/extensions/Blocks/api/blockTypes.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@ export type BlockTemplate<
1616
type: Type;
1717
props: Props;
1818
content: InlineContent[];
19+
children?: BlockTemplate<string, Record<string, string>>[];
1920
};
2021

22+
export type BaseBlock = BlockTemplate<string, Record<string, string>>;
23+
2124
// information about a blocks props when defining Block types
2225
export type PropSpec = {
2326
name: string;

0 commit comments

Comments
 (0)