Skip to content

Commit f28cdc2

Browse files
feat: move all blocks to use the custom blocks API (#1904)
Co-authored-by: Matthew Lipski <matthewlipski@gmail.com> Co-authored-by: Matthew Lipski <50169049+matthewlipski@users.noreply.github.com>
1 parent 43bf109 commit f28cdc2

File tree

458 files changed

+10623
-8162
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

458 files changed

+10623
-8162
lines changed

docs/content/docs/features/blocks/code-blocks.mdx

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,27 @@ Code blocks by default are a simple way to display code. But, BlockNote also sup
2020
experience easy to use and reduce bundle size.
2121
</Callout>
2222

23-
You can enable more advanced features by passing the `codeBlock` option when creating the editor.
23+
You can enable more advanced features by extending the editor's default schema with a new `codeBlock`, which you can pass options into when creating. For more on extending the editor schema, see [Custom Schemas](/docs/features/custom-schemas).
2424

2525
```ts
2626
const editor = new BlockNoteEditor({
27-
codeBlock: {
28-
indentLineWithTab: true,
29-
defaultLanguage: "typescript",
30-
supportedLanguages: {
31-
typescript: {
32-
name: "TypeScript",
33-
aliases: ["ts"],
27+
schema: BlockNoteSchema.create().extend({
28+
codeBlock: createCodeBlockSpec({
29+
indentLineWithTab: true,
30+
defaultLanguage: "typescript",
31+
supportedLanguages: {
32+
typescript: {
33+
name: "TypeScript",
34+
aliases: ["ts"],
35+
},
3436
},
35-
},
36-
createHighlighter: () =>
37-
createHighlighter({
38-
themes: ["light-plus", "dark-plus"],
39-
langs: [],
40-
}),
41-
},
37+
createHighlighter: () =>
38+
createHighlighter({
39+
themes: ["light-plus", "dark-plus"],
40+
langs: [],
41+
}),
42+
}),
43+
}),
4244
});
4345
```
4446

@@ -64,7 +66,7 @@ type CodeBlock = {
6466

6567
### Basic Setup
6668

67-
To enable code block syntax highlighting, you can use the `codeBlock` option in the `useCreateBlockNote` hook.
69+
To enable code block syntax highlighting, you can extend the editor's default schema with a new `codeBlock`.
6870

6971
First, install the package:
7072

@@ -75,20 +77,24 @@ npm install @blocknote/code-block
7577
Then use it like this:
7678

7779
```tsx
78-
import { codeBlock } from "@blocknote/code-block";
80+
import { codeBlockOptions } from "@blocknote/code-block";
7981

8082
export default function App() {
8183
const editor = useCreateBlockNote({
82-
codeBlock,
84+
schema: BlockNoteSchema.create().extend({
85+
codeBlock: createCodeBlockSpec(codeBlockOptions),
86+
}),
8387
});
8488

8589
return <BlockNoteView editor={editor} />;
8690
}
8791
```
8892

93+
This will extend the default schema with a custom `codeBlock` that includes options from `@blocknote/code-block`, enabling syntax highlighting.
94+
8995
### Custom Themes & Languages
9096

91-
To configure a code block highlighting theme and language, you can use the `codeBlock` option in the `useCreateBlockNote` hook.
97+
To configure a code block highlighting theme and language, you can again extend the editor's default schema with a new `codeBlock`.
9298

9399
This allows you to configure a [shiki](https://shiki.style) highlighter for the code blocks of your editor, allowing you to tailor the themes and languages you would like to use.
94100

@@ -109,21 +115,23 @@ import { createHighlighter } from "./shiki.bundle.js";
109115

110116
export default function App() {
111117
const editor = useCreateBlockNote({
112-
codeBlock: {
113-
indentLineWithTab: true,
114-
defaultLanguage: "typescript",
115-
supportedLanguages: {
116-
typescript: {
117-
name: "TypeScript",
118-
aliases: ["ts"],
118+
schema: BlockNoteSchema.create().extend({
119+
codeBlock: createCodeBlockSpec({
120+
indentLineWithTab: true,
121+
defaultLanguage: "typescript",
122+
supportedLanguages: {
123+
typescript: {
124+
name: "TypeScript",
125+
aliases: ["ts"],
126+
},
119127
},
120-
},
121-
createHighlighter: () =>
122-
createHighlighter({
123-
themes: ["light-plus", "dark-plus"],
124-
langs: [],
125-
}),
126-
},
128+
createHighlighter: () =>
129+
createHighlighter({
130+
themes: ["light-plus", "dark-plus"],
131+
langs: [],
132+
}),
133+
}),
134+
}),
127135
});
128136

129137
return <BlockNoteView editor={editor} />;

docs/content/docs/features/custom-schemas/custom-inline-content.mdx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ type CustomInlineContentConfig = {
5151
type: string;
5252
content: "styled" | "none";
5353
readonly propSchema: PropSchema;
54-
draggable?: boolean;
5554
};
5655
```
5756

@@ -100,14 +99,15 @@ If you do not want the prop to have a default value, you can define it as an obj
10099
mentioned._
101100
</Callout>
102101

103-
`draggable?:` Whether the inline content should be draggable.
104-
105102
### Inline Content Implementation (`ReactCustomInlineContentImplementation`)
106103

107104
The Inline Content Implementation defines how the inline content should be rendered to HTML.
108105

109106
```typescript
110107
type ReactCustomInlineContentImplementation = {
108+
meta?: {
109+
draggable?: boolean;
110+
};
111111
render: React.FC<{
112112
inlineContent: InlineContent;
113113
contentRef?: (node: HTMLElement | null) => void;
@@ -124,6 +124,8 @@ type ReactCustomInlineContentImplementation = {
124124

125125
- `draggable:` Specifies whether the inline content can be dragged within the editor. If set to `true`, the inline content will be draggable. Defaults to `false` if not specified. If this is true, you should add `data-drag-handle` to the DOM element that should function as the drag handle.
126126

127+
`meta?.draggable?:` Whether the inline content should be draggable.
128+
127129
<Callout type="info">
128130
_Note that since inline content is, by definition, inline, your component
129131
should also return an HTML inline element._

docs/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,4 @@
140140
"y-partykit": "^0.0.33",
141141
"yjs": "^13.6.27"
142142
}
143-
}
143+
}

examples/03-ui-components/03-formatting-toolbar-block-type-items/src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const schema = BlockNoteSchema.create({
2020
// Adds all default blocks.
2121
...defaultBlockSpecs,
2222
// Adds the Alert block.
23-
alert: Alert,
23+
alert: Alert(),
2424
},
2525
});
2626

examples/03-ui-components/11-uppy-file-panel/src/FileReplaceButton.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {
22
BlockSchema,
3-
checkBlockIsFileBlock,
3+
blockHasType,
44
InlineContentSchema,
55
StyleSchema,
66
} from "@blocknote/core";
@@ -41,7 +41,7 @@ export const FileReplaceButton = () => {
4141

4242
if (
4343
block === undefined ||
44-
!checkBlockIsFileBlock(block, editor) ||
44+
!blockHasType(block, editor, "file", { url: "string" }) ||
4545
!editor.isEditable
4646
) {
4747
return null;

examples/03-ui-components/13-custom-ui/src/MUIFormattingToolbar.tsx

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -266,18 +266,24 @@ function MUITextAlignButton(props: {
266266
const editor = useBlockNoteEditor<TextBlockSchema>();
267267

268268
// The text alignment of the block currently containing the text cursor.
269-
const [activeTextAlignment, setActiveTextAlignment] = useState(
270-
() => editor.getTextCursorPosition().block.props.textAlignment,
271-
);
269+
const [activeTextAlignment, setActiveTextAlignment] = useState(() => {
270+
const props = editor.getTextCursorPosition().block.props;
271+
if ("textAlignment" in props) {
272+
return props.textAlignment;
273+
}
274+
return undefined;
275+
});
272276

273277
// Updates the text alignment when the editor content or selection changes.
274-
useEditorContentOrSelectionChange(
275-
() =>
276-
setActiveTextAlignment(
277-
editor.getTextCursorPosition().block.props.textAlignment,
278-
),
279-
editor,
280-
);
278+
useEditorContentOrSelectionChange(() => {
279+
setActiveTextAlignment(() => {
280+
const props = editor.getTextCursorPosition().block.props;
281+
if ("textAlignment" in props) {
282+
return props.textAlignment;
283+
}
284+
return undefined;
285+
});
286+
}, editor);
281287

282288
// Tooltip for the button.
283289
const tooltip = useMemo(
@@ -297,6 +303,10 @@ function MUITextAlignButton(props: {
297303
editor.focus();
298304
}, [editor, props.textAlignment]);
299305

306+
if (!activeTextAlignment) {
307+
return null;
308+
}
309+
300310
return (
301311
<MUIToolbarButton
302312
tooltip={tooltip}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# Code Block Syntax Highlighting
22

3-
To enable code block syntax highlighting, you can use the `codeBlock` option in the `useCreateBlockNote` hook. This is excluded by default to reduce bundle size.
3+
To enable code block syntax highlighting, you can extend the editor's default schema with a new `codeBlock`, which you can pass options into when creating. By passing the default options from `@blocknote/code-block`, you can enable syntax highlighting. This is excluded by default to reduce bundle size.
44

55
**Relevant Docs:**
66

77
- [Code Block Syntax Highlighting](/docs/features/blocks/code-blocks)
88
- [Editor Setup](/docs/getting-started/editor-setup)
9+
- [Custom Schema](/docs/features/custom-schemas)

examples/04-theming/06-code-block/src/App.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1+
import { BlockNoteSchema, createCodeBlockSpec } from "@blocknote/core";
12
import "@blocknote/core/fonts/inter.css";
23
import { BlockNoteView } from "@blocknote/mantine";
34
import "@blocknote/mantine/style.css";
45
import { useCreateBlockNote } from "@blocknote/react";
56
// This packages some of the most used languages in on-demand bundle
6-
import { codeBlock } from "@blocknote/code-block";
7+
import { codeBlockOptions } from "@blocknote/code-block";
78

89
export default function App() {
910
// Creates a new editor instance.
1011
const editor = useCreateBlockNote({
11-
codeBlock,
12+
schema: BlockNoteSchema.create().extend({
13+
blockSpecs: {
14+
codeBlock: createCodeBlockSpec(codeBlockOptions),
15+
},
16+
}),
1217
initialContent: [
1318
{
1419
type: "codeBlock",
Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,11 @@
11
# Custom Code Block Theme & Language
22

3-
To configure a code block highlighting theme and language, you can use the `codeBlock` option in the `useCreateBlockNote` hook.
3+
To configure a code block highlighting theme and language, you can extend the editor's default schema with a new `codeBlock`, which you can pass options into when creating. You can then use a shiki highlighter to add custom syntax highlighting.
44

5-
This allows you to configure a shiki highlighter for the code blocks of your editor, allowing you to tailor the themes and languages you would like to use.
6-
7-
To create a syntax highlighter, you can use the [shiki-codegen](https://shiki.style/packages/codegen) CLI for generating the code to create a syntax highlighter for your languages and themes.
8-
9-
For example to create a syntax highlighter using the optimized javascript engine, javascript, typescript, vue, with light and dark themes, you can run the following command:
10-
11-
```bash
12-
npx shiki-codegen --langs javascript,typescript,vue --themes light,dark --engine javascript --precompiled ./shiki.bundle.ts
13-
```
14-
15-
This will generate a `shiki.bundle.ts` file that you can use to create a syntax highlighter for your editor.
16-
17-
Like this:
18-
19-
```ts
20-
import { createHighlighter } from "./shiki.bundle";
21-
22-
export default function App() {
23-
// Creates a new editor instance.
24-
const editor = useCreateBlockNote({
25-
codeBlock: {
26-
indentLineWithTab: true,
27-
defaultLanguage: "typescript",
28-
supportedLanguages: {
29-
typescript: {
30-
name: "TypeScript",
31-
aliases: ["ts"],
32-
},
33-
},
34-
createHighlighter: () =>
35-
createHighlighter({
36-
themes: ["light-plus", "dark-plus"],
37-
langs: [],
38-
}),
39-
},
40-
});
41-
42-
return <BlockNoteView editor={editor} />;
43-
}
44-
```
5+
First use the [shiki-codegen](https://shiki.style/packages/codegen) CLI to create a `shiki.bundle.ts` file. You can then pass this file into the `codeBlock` options when creating it.
456

467
**Relevant Docs:**
478

489
- [Code Blocks](/docs/features/blocks/code-blocks)
4910
- [shiki-codegen](https://shiki.style/packages/codegen)
11+
- [Custom Schema](/docs/features/custom-schemas)

examples/04-theming/07-custom-code-block/src/App.tsx

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { BlockNoteSchema, createCodeBlockSpec } from "@blocknote/core";
12
import "@blocknote/core/fonts/inter.css";
23
import { BlockNoteView } from "@blocknote/mantine";
34
import "@blocknote/mantine/style.css";
@@ -8,29 +9,33 @@ import { createHighlighter } from "./shiki.bundle";
89
export default function App() {
910
// Creates a new editor instance.
1011
const editor = useCreateBlockNote({
11-
codeBlock: {
12-
indentLineWithTab: true,
13-
defaultLanguage: "typescript",
14-
supportedLanguages: {
15-
typescript: {
16-
name: "TypeScript",
17-
aliases: ["ts"],
18-
},
19-
javascript: {
20-
name: "JavaScript",
21-
aliases: ["js"],
22-
},
23-
vue: {
24-
name: "Vue",
25-
},
26-
},
27-
// This creates a highlighter, it can be asynchronous to load it afterwards
28-
createHighlighter: () =>
29-
createHighlighter({
30-
themes: ["dark-plus", "light-plus"],
31-
langs: [],
12+
schema: BlockNoteSchema.create().extend({
13+
blockSpecs: {
14+
codeBlock: createCodeBlockSpec({
15+
indentLineWithTab: true,
16+
defaultLanguage: "typescript",
17+
supportedLanguages: {
18+
typescript: {
19+
name: "TypeScript",
20+
aliases: ["ts"],
21+
},
22+
javascript: {
23+
name: "JavaScript",
24+
aliases: ["js"],
25+
},
26+
vue: {
27+
name: "Vue",
28+
},
29+
},
30+
// This creates a highlighter, it can be asynchronous to load it afterwards
31+
createHighlighter: () =>
32+
createHighlighter({
33+
themes: ["dark-plus", "light-plus"],
34+
langs: [],
35+
}),
3236
}),
33-
},
37+
},
38+
}),
3439
initialContent: [
3540
{
3641
type: "codeBlock",

0 commit comments

Comments
 (0)