From 1a888087bca3303c604357edd6b7284204ec7945 Mon Sep 17 00:00:00 2001
From: Matthew Lipski
Date: Sat, 24 Feb 2024 13:29:28 +0100
Subject: [PATCH 1/9] Added proposals for editor basics docs changes
---
docs/pages/docs/_meta.json | 2 +-
docs/pages/docs/editor-api/_meta.json | 5 +-
docs/pages/docs/editor-api/block-content.mdx | 179 --------------
docs/pages/docs/editor-api/blocks.mdx | 53 ----
.../manipulating-inline-content.mdx | 232 ++++++++++++++++++
docs/pages/docs/editor-basics/_meta.json | 7 +
docs/pages/docs/editor-basics/blocks.mdx | 53 ++++
.../default-blocks.mdx | 10 +-
.../editor-basics/default-inline-content.mdx | 73 ++++++
.../{editor-api => editor-basics}/editor.mdx | 64 +++--
.../docs/editor-basics/inline-content.mdx | 74 ++++++
11 files changed, 491 insertions(+), 261 deletions(-)
delete mode 100644 docs/pages/docs/editor-api/block-content.mdx
delete mode 100644 docs/pages/docs/editor-api/blocks.mdx
create mode 100644 docs/pages/docs/editor-api/manipulating-inline-content.mdx
create mode 100644 docs/pages/docs/editor-basics/_meta.json
create mode 100644 docs/pages/docs/editor-basics/blocks.mdx
rename docs/pages/docs/{editor-api => editor-basics}/default-blocks.mdx (87%)
create mode 100644 docs/pages/docs/editor-basics/default-inline-content.mdx
rename docs/pages/docs/{editor-api => editor-basics}/editor.mdx (54%)
create mode 100644 docs/pages/docs/editor-basics/inline-content.mdx
diff --git a/docs/pages/docs/_meta.json b/docs/pages/docs/_meta.json
index bfd05ce72a..9d5049f9ce 100644
--- a/docs/pages/docs/_meta.json
+++ b/docs/pages/docs/_meta.json
@@ -1,7 +1,7 @@
{
-
"index": "Introduction",
"quickstart": "Quickstart",
+ "editor-basics": "Editor Basics",
"editor-api": "Editor API",
"styling-theming": "Styling & Theming",
"ui-components": "UI Components",
diff --git a/docs/pages/docs/editor-api/_meta.json b/docs/pages/docs/editor-api/_meta.json
index 325393d7bb..7d69575259 100644
--- a/docs/pages/docs/editor-api/_meta.json
+++ b/docs/pages/docs/editor-api/_meta.json
@@ -1,9 +1,6 @@
{
- "editor":"",
- "blocks": "",
- "default-blocks":"",
"manipulating-blocks":"",
- "block-content":"",
+ "manipulating-inline-content":"",
"cursor-selections":"",
"converting-blocks":""
}
diff --git a/docs/pages/docs/editor-api/block-content.mdx b/docs/pages/docs/editor-api/block-content.mdx
deleted file mode 100644
index 45fa95ade0..0000000000
--- a/docs/pages/docs/editor-api/block-content.mdx
+++ /dev/null
@@ -1,179 +0,0 @@
----
-title: Block Content
-description: TODO
-imageTitle: Block Content
-path: /docs/block-content
----
-
-TODO: where should this page be? and / or do we need API changes? (matthew has some thoughts on this)
-
-# Block Content
-
-The `content` field of a `Block` describes the content of the block. For all blocks except tables, this field is an array of `InlineContent` objects and describes the rich text content typed inside the block.
-
-In the example below, you can see how a sentence like "Hello __there__, [BlockNote](https://www.blocknotejs.org)" is represented as an array of `InlineContent` objects:
-
-TODO: DEMO
-
-
-## `InlineContent` Types
-
-`InlineContent` can be styled text (rich text), a link, or a mention:
-
-### Styled Text
-
-`StyledText` is a type of `InlineContent` used to display pieces of text with styles:
-
-```typescript
-type StyledText = {
- type: "text";
- text: string;
- styles: Styles;
-};
-```
-
-`text:` The displayed text.
-
-`styles:` The styles that are applied to the text.
-
-**Styles Object**
-
-`StyledText` supports a variety of styles, including bold, underline, and text color, which are represented using a `Styles` object:
-
-```typescript
-type Styles = Partial<{
- bold: true;
- italic: true;
- underline: true;
- strikethrough: true;
- textColor: string;
- backgroundColor: string;
-}>;
-```
-
-### Links
-
-`Link` objects represent links to a URL:
-
-```typescript
-type Link = {
- type: "link";
- content: StyledText[];
- href: string;
-};
-```
-
-`content:` The styled text used to display the link.
-
-`href:` The URL that opens when clicking the link.
-
-### Mentions
-
-TODO
-
-### Custom `InlineContent` and `Styles`
-
-You can create your own types of `InlineContent` and `Styles` using React. Skip to the Advanced "custom schemas" section to learn more about extending the editor. (TODO: link)
-
-## TableContent
-
-Most blocks use an array of `InlineContent` objects to describe their content, but tables are slightly different. Table blocks have `TableContent` as their content, in which each row contains an array of cells, that
-
-
-```typescript
-type TableContent = {
- type: "tableContent";
- rows: {
- cells: InlineContent[][];
- }[];
-};
-```
-
-## Editor Functions
-
-TODO: where should this be?
-
-While `InlineContent` objects are used to describe a block's content, they can be cumbersome to work with directly. Therefore, BlockNote exposes functions which make it easier to edit block contents.
-
-### Accessing Styles
-
-You can get the styles at the current [Text Cursor Position](/docs/cursor-selections#text-cursor) using the following function:
-
-```typescript
-getActiveStyles(): Styles;
-
-// Usage
-const styles = editor.getActiveStyles();
-```
-
-If a [Selection](/docs/cursor-selections#selections) is active, this function returns the active styles at the end of the selection.
-
-### Adding Styles
-
-You can add styles to the currently selected text using the following function:
-
-```typescript
-addStyles(styles: Styles): void;
-
-// Usage
-editor.addStyles({ textColor: "red" });
-```
-
-### Removing Styles
-
-You can remove styles from the currently selected text using the following function:
-
-```typescript
-removeStyles(styles: Styles): void;
-
-// Usage
-editor.removeStyles({ bold: true });
-```
-
-### Toggling Styles
-
-You can toggle styles on the currently selected text using the following function:
-
-```typescript
-toggleStyles(styles: Styles): void;
-
-// Usage
-editor.toggleStyles({ bold: true, italic: true });
-```
-
-### Accessing Selected Text
-
-You can get the currently selected text using the following function:
-
-```typescript
-getSelectedText(): string;
-
-// Usage
-const text = editor.getSelectedText();
-```
-
-### Accessing Selected Link
-
-You can get the URL of the link in the current selection the following function:
-
-```typescript
-getSelectedLink(): string | undefined;
-
-// Usage
-const linkUrl = editor.getSelectedLink();
-```
-
-If there are multiple links in the selection, this function only returns the last one's URL. If there are no links, returns `undefined`.
-
-### Creating a Link
-
-You can create a new link using the following function:
-
-```typescript
-createLink(url: string, text?: string): void;
-
-// Usage
-editor.createLink("https://www.blocknotejs.org/", "BlockNote");
-```
-
-If a [Selection](/docs/cursor-selections#selections) is active, the new link will replace the currently selected content.
diff --git a/docs/pages/docs/editor-api/blocks.mdx b/docs/pages/docs/editor-api/blocks.mdx
deleted file mode 100644
index 133e435af3..0000000000
--- a/docs/pages/docs/editor-api/blocks.mdx
+++ /dev/null
@@ -1,53 +0,0 @@
----
-title: Introduction to Blocks
-description: So, you've set up a BlockNote editor and your users can start writing content, organized in blocks. What are blocks exactly, and how do we access the blocks from code?
-imageTitle: Introduction to Blocks
----
-
-import { Example } from "@/components/example";
-
-[ ] Maybe move outside of "Editor API" or create separate "Editor basics" page?
-
-# Introduction to Blocks
-
-So, you've set up a BlockNote editor and your users can start writing content, organized in blocks. What are blocks exactly, and how do we access the blocks from code?
-
-## Editor Functions
-
-The `editor` returned from `useCreateBlockNote` exposes functions to access and update blocks.
-We'll go through the full API later, but let's start with a simple example that shows the document (a list of blocks) in JSON.
-Play around with the editor to see how blocks are represented in JSON.
-
-
-
-## Block Objects
-
-So, BlockNote is centered around the idea of blocks. A block - like a heading, paragraph, or list item - contains a piece of content and optionally nested blocks:
-
-
-
-In code, the `Block` type is used to describe any given block in the editor:
-
-```typescript
-type Block = {
- id: string;
- type: string; // the block type, e.g. 'paragraph', 'heading'
- props: Record; // exact props depends on the Block type
- content: InlineContent[] | TableContent;
- children: Block[];
-};
-```
-
-`id:` The block's ID. Multiple blocks cannot share a single ID, and a block will keep the same ID from when it's created until it's removed.
-
-`type:` The block's type, such as a paragraph, heading, or list item. For an overview of built-in block types, see [Built-In Block Types](/docs/block-types#built-in-block-types).
-
-`props:` The block's properties, which are stored in a set of key/value pairs and specify how the block looks and behaves. Different block types have different props - see [Block Types & Properties](/docs/block-types) for more.
-
-`content:` The block's rich text content, represented as an array of `InlineContent` objects. This does not include content from any nested blocks. [Table](/docs/block-types#table) blocks are slightly different, as they contain `TableContent`, where each table cell is represented as an array of `InlineContent` objects. For more information on `InlineContent` and `TableContent` objects, visit [Inline Content](/docs/inline-content).
-
-`children:` Any blocks nested inside the block. The nested blocks are also represented using `Block` objects.
diff --git a/docs/pages/docs/editor-api/manipulating-inline-content.mdx b/docs/pages/docs/editor-api/manipulating-inline-content.mdx
new file mode 100644
index 0000000000..738d5754b5
--- /dev/null
+++ b/docs/pages/docs/editor-api/manipulating-inline-content.mdx
@@ -0,0 +1,232 @@
+---
+title: Manipulating Inline Content
+description: TODO
+imageTitle: Manipulating Inline Content
+path: /docs/block-content
+---
+
+TODO: API For this is pretty weird vs blocks
+
+[//]: # (# Block Content)
+
+[//]: # ()
+[//]: # (The `content` field of a `Block` describes the content of the block. For all blocks except tables, this field is an array of `InlineContent` objects and describes the rich text content typed inside the block.)
+
+[//]: # ()
+[//]: # (In the example below, you can see how a sentence like "Hello __there__, [BlockNote](https://www.blocknotejs.org)" is represented as an array of `InlineContent` objects:)
+
+[//]: # ()
+[//]: # (TODO: DEMO)
+
+[//]: # ()
+[//]: # ()
+[//]: # (## `InlineContent` Types)
+
+[//]: # ()
+[//]: # (`InlineContent` can be styled text (rich text), a link, or a mention:)
+
+[//]: # ()
+[//]: # (### Styled Text)
+
+[//]: # ()
+[//]: # (`StyledText` is a type of `InlineContent` used to display pieces of text with styles:)
+
+[//]: # ()
+[//]: # (```typescript)
+
+[//]: # (type StyledText = {)
+
+[//]: # ( type: "text";)
+
+[//]: # ( text: string;)
+
+[//]: # ( styles: Styles;)
+
+[//]: # (};)
+
+[//]: # (```)
+
+[//]: # ()
+[//]: # (`text:` The displayed text.)
+
+[//]: # ()
+[//]: # (`styles:` The styles that are applied to the text.)
+
+[//]: # ()
+[//]: # (**Styles Object**)
+
+[//]: # ()
+[//]: # (`StyledText` supports a variety of styles, including bold, underline, and text color, which are represented using a `Styles` object:)
+
+[//]: # ()
+[//]: # (```typescript)
+
+[//]: # (type Styles = Partial<{)
+
+[//]: # ( bold: true;)
+
+[//]: # ( italic: true;)
+
+[//]: # ( underline: true;)
+
+[//]: # ( strikethrough: true;)
+
+[//]: # ( textColor: string;)
+
+[//]: # ( backgroundColor: string;)
+
+[//]: # (}>;)
+
+[//]: # (```)
+
+[//]: # ()
+[//]: # (### Links)
+
+[//]: # ()
+[//]: # (`Link` objects represent links to a URL:)
+
+[//]: # ()
+[//]: # (```typescript)
+
+[//]: # (type Link = {)
+
+[//]: # ( type: "link";)
+
+[//]: # ( content: StyledText[];)
+
+[//]: # ( href: string;)
+
+[//]: # (};)
+
+[//]: # (```)
+
+[//]: # ()
+[//]: # (`content:` The styled text used to display the link.)
+
+[//]: # ()
+[//]: # (`href:` The URL that opens when clicking the link.)
+
+[//]: # ()
+[//]: # (### Mentions)
+
+[//]: # ()
+[//]: # (TODO)
+
+[//]: # ()
+[//]: # (### Custom `InlineContent` and `Styles`)
+
+[//]: # ()
+[//]: # (You can create your own types of `InlineContent` and `Styles` using React. Skip to the Advanced "custom schemas" section to learn more about extending the editor. (TODO: link))
+
+[//]: # ()
+[//]: # (## TableContent)
+
+[//]: # ()
+[//]: # (Most blocks use an array of `InlineContent` objects to describe their content, but tables are slightly different. Table blocks have `TableContent` as their content, in which each row contains an array of cells, that)
+
+[//]: # ()
+[//]: # ()
+[//]: # (```typescript)
+
+[//]: # (type TableContent = {)
+
+[//]: # ( type: "tableContent";)
+
+[//]: # ( rows: {)
+
+[//]: # ( cells: InlineContent[][];)
+
+[//]: # ( }[];)
+
+[//]: # (};)
+
+[//]: # (```)
+
+# Manipulating Inline Content
+
+TODO: where should this be?
+
+While `InlineContent` objects are used to describe a block's content, they can be cumbersome to work with directly. Therefore, BlockNote exposes functions which make it easier to edit block contents.
+
+## Accessing Styles
+
+You can get the styles at the current [Text Cursor Position](/docs/cursor-selections#text-cursor) using the following function:
+
+```typescript
+getActiveStyles(): Styles;
+
+// Usage
+const styles = editor.getActiveStyles();
+```
+
+If a [Selection](/docs/cursor-selections#selections) is active, this function returns the active styles at the end of the selection.
+
+## Adding Styles
+
+You can add styles to the currently selected text using the following function:
+
+```typescript
+addStyles(styles: Styles): void;
+
+// Usage
+editor.addStyles({ textColor: "red" });
+```
+
+## Removing Styles
+
+You can remove styles from the currently selected text using the following function:
+
+```typescript
+removeStyles(styles: Styles): void;
+
+// Usage
+editor.removeStyles({ bold: true });
+```
+
+## Toggling Styles
+
+You can toggle styles on the currently selected text using the following function:
+
+```typescript
+toggleStyles(styles: Styles): void;
+
+// Usage
+editor.toggleStyles({ bold: true, italic: true });
+```
+
+## Accessing Selected Text
+
+You can get the currently selected text using the following function:
+
+```typescript
+getSelectedText(): string;
+
+// Usage
+const text = editor.getSelectedText();
+```
+
+## Accessing Selected Link
+
+You can get the URL of the link in the current selection the following function:
+
+```typescript
+getSelectedLink(): string | undefined;
+
+// Usage
+const linkUrl = editor.getSelectedLink();
+```
+
+If there are multiple links in the selection, this function only returns the last one's URL. If there are no links, returns `undefined`.
+
+## Creating a Link
+
+You can create a new link using the following function:
+
+```typescript
+createLink(url: string, text?: string): void;
+
+// Usage
+editor.createLink("https://www.blocknotejs.org/", "BlockNote");
+```
+
+If a [Selection](/docs/cursor-selections#selections) is active, the new link will replace the currently selected content.
diff --git a/docs/pages/docs/editor-basics/_meta.json b/docs/pages/docs/editor-basics/_meta.json
new file mode 100644
index 0000000000..1b07a43c0b
--- /dev/null
+++ b/docs/pages/docs/editor-basics/_meta.json
@@ -0,0 +1,7 @@
+{
+ "editor": "Editor Setup",
+ "blocks": "Intro to Blocks",
+ "inline-content": "Intro to Inline Content",
+ "default-blocks": "Default Blocks",
+ "default-inline-content": "Default Inline Content"
+}
diff --git a/docs/pages/docs/editor-basics/blocks.mdx b/docs/pages/docs/editor-basics/blocks.mdx
new file mode 100644
index 0000000000..1d0956a6e8
--- /dev/null
+++ b/docs/pages/docs/editor-basics/blocks.mdx
@@ -0,0 +1,53 @@
+---
+title: Introduction to Blocks
+description: Once you create an editor, you'll need to understand how its content is structured into blocks.
+imageTitle: Introduction to Blocks
+---
+
+import { Example } from "@/components/example";
+
+# Intro to Blocks
+
+Each BlockNote editor is made up of a list of blocks. This page explains what blocks are, and how they're represented in code.
+
+## Block Objects
+
+A block - like a heading, paragraph, or list item - contains a piece of content and optionally nested blocks:
+
+
+
+In code, the `Block` type is used to describe any given block in the editor:
+
+```typescript
+type Block = {
+ id: string;
+ type: string; // the block type, e.g. 'paragraph', 'heading'
+ props: Record; // exact props depends on the Block type
+ content: InlineContent[] | TableContent | undefined;
+ children: Block[];
+};
+```
+
+`id:` The block's ID. Multiple blocks cannot share a single ID, and a block will keep the same ID from when it's created until it's removed.
+
+`type:` The block's type, such as a paragraph, heading, or list item. For an overview of built-in block types, see [Default Blocks](/docs/editor-basics/default-blocks).
+
+`props:` The block's properties, which are stored in a set of key/value pairs and specify how the block looks and behaves. Different block types have different props - see [Default Blocks](/docs/editor-basics/default-blocks) for more.
+
+`content:` The block's rich text content, usually represented as an array of `InlineContent` objects. This does not include content from any nested blocks. For more information visit [Intro to Inline Content](/docs/editor-api/block-content).
+
+[Table](/docs/editor-basics/default-blocks#table) blocks are slightly different, as they contain `TableContent`, where each table cell is represented as an array of `InlineContent` objects. Some blocks, like [Image](/docs/editor-basics/default-blocks#image) blocks, don't contain any rich text content, so their `content` is `undefined`.
+
+`children:` Any blocks nested inside the block. The nested blocks are also represented using `Block` objects.
+
+## Displaying Editor Content
+
+After [creating an editor](/docs/editor-basics/editor#creating-the-editor), you'll have a `BlockNoteEditor` object, which exposes various functions to read and modify the editor.
+
+We'll go through the full API later, but let's start with a simple example that shows the editor content - notice that it's in JSON as an array of `Block` objects.
+
+
diff --git a/docs/pages/docs/editor-api/default-blocks.mdx b/docs/pages/docs/editor-basics/default-blocks.mdx
similarity index 87%
rename from docs/pages/docs/editor-api/default-blocks.mdx
rename to docs/pages/docs/editor-basics/default-blocks.mdx
index 024f858bca..d7b22f96a0 100644
--- a/docs/pages/docs/editor-api/default-blocks.mdx
+++ b/docs/pages/docs/editor-basics/default-blocks.mdx
@@ -6,9 +6,7 @@ imageTitle: Default Blocks
import { Example } from "@/components/example";
-# Default blocks
-
-TBD: move to a separate "reference" section?
+# Default Blocks
BlockNote includes a number of built-in block types. The demo editor below displays all of them:
@@ -142,7 +140,7 @@ type TableBlock = {
## Default Block Properties
-While each type of block can have its own set of properties, there are some properties that all built-in block types have by default, which you can find in the definition for `DefaultProps`:
+There are some default block props that BlockNote uses for its default block types, and also exports for use in your own [custom blocks](/docs/custom-schemas/custom-blocks):
```typescript
type DefaultProps = {
@@ -158,6 +156,6 @@ type DefaultProps = {
`textAlignment:` The text alignment of the block.
-## Creating your own blocks
+## Creating New Block Types
-You can create your own custom blocks using React. Skip to the Advanced "custom schemas" section to learn more about extending the editor. (TODO: link)
\ No newline at end of file
+Skip to [Custom Blocks](/docs/custom-schemas/custom-blocks) to learn how to do this.
\ No newline at end of file
diff --git a/docs/pages/docs/editor-basics/default-inline-content.mdx b/docs/pages/docs/editor-basics/default-inline-content.mdx
new file mode 100644
index 0000000000..3b7a37ca8f
--- /dev/null
+++ b/docs/pages/docs/editor-basics/default-inline-content.mdx
@@ -0,0 +1,73 @@
+---
+title: Default Inline Content
+description: Overview of all default inline content types and their properties in BlockNote.
+imageTitle: Default Inline Content
+---
+
+# Default Inline Content
+
+BlockNote includes a number of built-in inline content types. The demo editor below displays all of them:
+
+TODO: demo
+
+## Reference
+
+Here's an overview of all default inline content and the properties they support:
+
+### Styled Text
+
+`StyledText` is a type of `InlineContent` used to display pieces of text with styles:
+
+```typescript
+type Styles = {
+ bold: true;
+ italic: true;
+ underline: true;
+ strikethrough: true;
+ textColor: string;
+ backgroundColor: string;
+}
+
+type StyledText = {
+ type: "text";
+ text: string;
+ styles: Styles;
+};
+```
+
+### Links
+
+`Link` objects represent links to a URL:
+
+```typescript
+type Link = {
+ type: "link";
+ content: StyledText[];
+ href: string;
+};
+```
+
+## Default Inline Content Properties
+
+There are some default inline content props that BlockNote uses for its default inline content types, and also exports for use in your own [custom inline content](/docs/custom-schemas/custom-inline-content):
+
+```typescript
+type Styles = {
+ bold: true;
+ italic: true;
+ underline: true;
+ strikethrough: true;
+ textColor: string;
+ backgroundColor: string;
+}
+
+type DefaultInlineContentProps = {
+ styles: Styles
+};
+```
+
+`styles:` The text styles applied to the inline content. Only useful for editable inline content types.
+
+## Creating New Inline Content Types
+
+You can create your own custom blocks using React. Skip to [Custom Inline Content](/docs/custom-schemas/custom-inline-content) to learn how to do this.
\ No newline at end of file
diff --git a/docs/pages/docs/editor-api/editor.mdx b/docs/pages/docs/editor-basics/editor.mdx
similarity index 54%
rename from docs/pages/docs/editor-api/editor.mdx
rename to docs/pages/docs/editor-basics/editor.mdx
index 5429872d54..5349080d0d 100644
--- a/docs/pages/docs/editor-api/editor.mdx
+++ b/docs/pages/docs/editor-basics/editor.mdx
@@ -1,8 +1,8 @@
---
title: Editor Setup
-description: While you can get started with BlockNote in minutes, it's likely that you'll want to customize its features and functionality to better suit your app.
-imageTitle: Customizing the Editor
-path: /docs/editor
+description: While BlockNote is ready to use out-of-the-box, there are a number of ways in which you can set it up, to better suit your use case.
+imageTitle: Editor Setup
+path: /docs/editor-basics/editor
---
import { Example } from "@/components/example";
@@ -18,13 +18,42 @@ TODO:
# Editor Setup
-While you can get started with BlockNote in minutes, it's likely that you'll
-want to customize its features and functionality to better suit your app.
+While BlockNote is ready to use out-of-the-box, there are a number of ways in which you can set it up, to better suit your use case.
-## Editor Options
+## Creating the Editor
-There are a number of options that you can pass to `useCreateBlockNote()`, which you
-can use to customize the editor. You can find the full list of these below:
+### Using a React Hook
+
+Most of the time, you'll want to create the BlockNote editor using the `useCreateBlockNote` hook. This will create a new editor as your React component gets mounted, and you can pass a dependency array as with other React hooks.
+
+```ts
+useCreateBlockNote = (
+ options?: Partial,
+ deps?: React.DependencyList
+) => BlockNoteEditor;
+```
+
+Read on to [Options](/docs/editor-basics/editor#options) to see what options you can pass to the editor.
+
+### Using a Method
+
+You can also create a new editor using `BlockNoteEditor.create`. You should use this when you want to wait after your React component gets mounted before creating the editor.
+
+```ts
+BlockNoteEditor.create = (
+ options?: Partial,
+) => BlockNoteEditor;
+```
+
+In the demo below, we use `BlockNoteEditor.create` so we can fetch the editor's initial content from `localStorage` before creating it.
+
+
+
+Read on to [Options](/docs/editor-basics/editor#options) to see what options you can pass to the editor.
+
+### Options
+
+There are a number of options that you can pass to `useCreateBlockNote()` and `BlockNoteEditor.create`. You can find the full list of these below:
```typescript
export type BlockNoteEditorOptions = Partial<{
@@ -58,19 +87,18 @@ export type BlockNoteEditorOptions = Partial<{
`styleSpecs` (_advanced_): Specifications for Custom Styles. See [Style Specs](/docs/style-specs) for more info.
-## `useCreateBlockNote`
-
-## `BlockNoteView`
+## Rendering the Editor
-- editable
-- events
+### Using a React Component
-### Removing UI Elements
+To, render the editor, you should use the `BlockNoteView` component, and pass in the editor created using `useCreateBlockNote` or `BlockNoteEditor.create`:
-TODO: probably just explain the props of BlockNoteView
+```tsx
+const editor = useCreateBlockNote();
-In the following example, we remove the Side Menu from the editor. This is done by adding all `Positioner` components as children of `BlockNoteView`, for each UI element except the Side Menu:
+return
+```
-
+### Props
-Each further `Positioner` component you remove will remove its corresponding UI element from the editor. If you only want to keep the editor itself, add only an empty fragment (`<>>`) to `BlockNoteView`'s children.
+TODO
diff --git a/docs/pages/docs/editor-basics/inline-content.mdx b/docs/pages/docs/editor-basics/inline-content.mdx
new file mode 100644
index 0000000000..bf22efda21
--- /dev/null
+++ b/docs/pages/docs/editor-basics/inline-content.mdx
@@ -0,0 +1,74 @@
+---
+title: Introduction to Blocks
+description: Once you create an editor, you'll need to understand how its content is structured into blocks.
+imageTitle: Introduction to Blocks
+---
+
+import { Example } from "@/components/example";
+
+# Intro to Inline Content
+
+Many blocks contain inline content. This page explains what inline content is, and how it's represented in code.
+
+## Inline Content Objects
+
+A block's content is referred to as inline content, and is used to represent rich text.
+
+TODO: Between custom & default inline content types, the shapes on inline content objects are not standardized.
+e.g. `Link`s have `href` and no props, custom IC will have props. `StyledText` can be IC itself, or used in other IC types.
+
+I think we should have smth like this:
+```typescript
+// Helper types
+type Styles = {
+ bold: boolean;
+ textColor: string;
+ ...
+}
+
+// Inline Content types
+type StyledText = {
+ type: "richText";
+ props: {
+ styles: Styles;
+ }
+ editable: true;
+}
+type Link = {
+ type: "link";
+ props: {
+ styles: Styles;
+ href: string;
+ }
+ editable: true;
+}
+type Mention = {
+ type: "mention";
+ props: {
+ user: string;
+ }
+ editable: false;
+}
+```
+This is way cleaner, but means that links cannot have mixed styles. I think we either:
+- Convert links to styles (they're already marks in TipTap)
+- Not do anything bc I don't think having mixed styles on links is ever useful
+
+## Table Content
+
+Most blocks use an array of `InlineContent` objects to describe their content, but tables are slightly different. Table blocks have `TableContent` as their content, in which each row contains an array of cells, that each have an array of `InlineContent` objects.
+
+```typescript
+type TableContent = {
+ type: "tableContent";
+ rows: {
+ cells: InlineContent[][];
+ }[];
+};
+```
+
+## Displaying Block Content
+
+In the example below, you can see how a block with the content, "Hello __there__, [BlockNote](https://www.blocknotejs.org)", is represented as an array of `InlineContent` objects:
+
+TODO: DEMO
From d6bc4347cc78a07ccddd354138fcd5d5b18c84dc Mon Sep 17 00:00:00 2001
From: Matthew Lipski
Date: Mon, 26 Feb 2024 15:42:25 +0100
Subject: [PATCH 2/9] Addressed editor basics TODOs
---
docs/pages/docs/editor-basics/_meta.json | 8 +-
docs/pages/docs/editor-basics/blocks.mdx | 53 -------
.../docs/editor-basics/content-structure.mdx | 134 ++++++++++++++++++
...t-blocks.mdx => default-content-types.mdx} | 112 ++++++++++++---
.../editor-basics/default-inline-content.mdx | 73 ----------
docs/pages/docs/editor-basics/editor.mdx | 52 ++++++-
.../docs/editor-basics/inline-content.mdx | 74 ----------
examples/01-basic/02-block-objects/App.tsx | 20 ++-
examples/01-basic/02-block-objects/README.md | 4 +-
examples/01-basic/all-blocks/.bnexample.json | 4 +
examples/01-basic/all-blocks/App.tsx | 53 +++++++
examples/01-basic/all-blocks/README.md | 7 +
.../all-inline-content/.bnexample.json | 4 +
examples/01-basic/all-inline-content/App.tsx | 45 ++++++
.../01-basic/all-inline-content/README.md | 8 ++
.../inline-content-objects/.bnexample.json | 4 +
.../01-basic/inline-content-objects/App.tsx | 71 ++++++++++
.../01-basic/inline-content-objects/README.md | 7 +
.../inline-content-objects/styles.css | 3 +
19 files changed, 505 insertions(+), 231 deletions(-)
delete mode 100644 docs/pages/docs/editor-basics/blocks.mdx
create mode 100644 docs/pages/docs/editor-basics/content-structure.mdx
rename docs/pages/docs/editor-basics/{default-blocks.mdx => default-content-types.mdx} (51%)
delete mode 100644 docs/pages/docs/editor-basics/default-inline-content.mdx
delete mode 100644 docs/pages/docs/editor-basics/inline-content.mdx
create mode 100644 examples/01-basic/all-blocks/.bnexample.json
create mode 100644 examples/01-basic/all-blocks/App.tsx
create mode 100644 examples/01-basic/all-blocks/README.md
create mode 100644 examples/01-basic/all-inline-content/.bnexample.json
create mode 100644 examples/01-basic/all-inline-content/App.tsx
create mode 100644 examples/01-basic/all-inline-content/README.md
create mode 100644 examples/01-basic/inline-content-objects/.bnexample.json
create mode 100644 examples/01-basic/inline-content-objects/App.tsx
create mode 100644 examples/01-basic/inline-content-objects/README.md
create mode 100644 examples/01-basic/inline-content-objects/styles.css
diff --git a/docs/pages/docs/editor-basics/_meta.json b/docs/pages/docs/editor-basics/_meta.json
index 1b07a43c0b..347454b190 100644
--- a/docs/pages/docs/editor-basics/_meta.json
+++ b/docs/pages/docs/editor-basics/_meta.json
@@ -1,7 +1,5 @@
{
- "editor": "Editor Setup",
- "blocks": "Intro to Blocks",
- "inline-content": "Intro to Inline Content",
- "default-blocks": "Default Blocks",
- "default-inline-content": "Default Inline Content"
+ "content-structure": "Content Structure",
+ "default-content-types": "Default Content Types",
+ "editor": "Editor Setup"
}
diff --git a/docs/pages/docs/editor-basics/blocks.mdx b/docs/pages/docs/editor-basics/blocks.mdx
deleted file mode 100644
index 1d0956a6e8..0000000000
--- a/docs/pages/docs/editor-basics/blocks.mdx
+++ /dev/null
@@ -1,53 +0,0 @@
----
-title: Introduction to Blocks
-description: Once you create an editor, you'll need to understand how its content is structured into blocks.
-imageTitle: Introduction to Blocks
----
-
-import { Example } from "@/components/example";
-
-# Intro to Blocks
-
-Each BlockNote editor is made up of a list of blocks. This page explains what blocks are, and how they're represented in code.
-
-## Block Objects
-
-A block - like a heading, paragraph, or list item - contains a piece of content and optionally nested blocks:
-
-
-
-In code, the `Block` type is used to describe any given block in the editor:
-
-```typescript
-type Block = {
- id: string;
- type: string; // the block type, e.g. 'paragraph', 'heading'
- props: Record; // exact props depends on the Block type
- content: InlineContent[] | TableContent | undefined;
- children: Block[];
-};
-```
-
-`id:` The block's ID. Multiple blocks cannot share a single ID, and a block will keep the same ID from when it's created until it's removed.
-
-`type:` The block's type, such as a paragraph, heading, or list item. For an overview of built-in block types, see [Default Blocks](/docs/editor-basics/default-blocks).
-
-`props:` The block's properties, which are stored in a set of key/value pairs and specify how the block looks and behaves. Different block types have different props - see [Default Blocks](/docs/editor-basics/default-blocks) for more.
-
-`content:` The block's rich text content, usually represented as an array of `InlineContent` objects. This does not include content from any nested blocks. For more information visit [Intro to Inline Content](/docs/editor-api/block-content).
-
-[Table](/docs/editor-basics/default-blocks#table) blocks are slightly different, as they contain `TableContent`, where each table cell is represented as an array of `InlineContent` objects. Some blocks, like [Image](/docs/editor-basics/default-blocks#image) blocks, don't contain any rich text content, so their `content` is `undefined`.
-
-`children:` Any blocks nested inside the block. The nested blocks are also represented using `Block` objects.
-
-## Displaying Editor Content
-
-After [creating an editor](/docs/editor-basics/editor#creating-the-editor), you'll have a `BlockNoteEditor` object, which exposes various functions to read and modify the editor.
-
-We'll go through the full API later, but let's start with a simple example that shows the editor content - notice that it's in JSON as an array of `Block` objects.
-
-
diff --git a/docs/pages/docs/editor-basics/content-structure.mdx b/docs/pages/docs/editor-basics/content-structure.mdx
new file mode 100644
index 0000000000..2b973f05c2
--- /dev/null
+++ b/docs/pages/docs/editor-basics/content-structure.mdx
@@ -0,0 +1,134 @@
+---
+title: Content Structure
+description: If you want to make the most out of BlockNote, it's important to understand how the editor's content is structured.
+imageTitle: Content Structure
+---
+
+import { Example } from "@/components/example";
+
+# Content Structure
+
+If you want to make the most out of BlockNote, it's important to understand how the editor's content is structured.
+
+## Blocks
+
+Each BlockNote editor is made up of a list of blocks. A block - like a heading, paragraph, or list item - contains a piece of content and optionally nested blocks:
+
+
+
+### Block Objects
+
+In code, the `Block` type is used to describe any given block in the editor:
+
+```typescript
+type Block = {
+ id: string;
+ type: string;
+ props: Record;
+ content: InlineContent[] | TableContent | undefined;
+ children: Block[];
+};
+```
+
+`id:` The block's ID. Multiple blocks cannot share a single ID, and a block will keep the same ID from when it's created until it's removed.
+
+`type:` The block's type, such as a paragraph, heading, or list item. For an overview of built-in block types, see [Default Blocks](/docs/editor-basics/default-content-types#default-blocks).
+
+`props:` The block's properties, which is a set of key/value pairs that further specify how the block looks and behaves. Different block types have different props - see [Default Blocks](/docs/editor-basics/default-content-types#default-blocks) for more.
+
+`content:` The block's rich text content, usually represented as an array of `InlineContent` objects. This does not include content from any nested blocks. Read on to [Inline Content](/docs/editor-basics/content-structure#inline-content) for more on this.
+
+`children:` Any blocks nested inside the block. The nested blocks are also represented using `Block` objects.
+
+### Editor Content in JSON
+
+The demo below shows how the editor content is represented in code - notice that it's in JSON as an array of `Block` objects.
+
+
+
+## Inline Content
+
+A block's content is referred to as inline content, and is used to represent rich text.
+
+TODO: Between custom & default inline content types, the shapes on inline content objects are not standardized.
+e.g. `Link`s have `href` and no props, custom IC will have props. `StyledText` can be IC itself, or used in other IC types.
+
+I think we should have smth like this:
+```typescript
+// Helper types
+type Styles = {
+ bold: boolean;
+ textColor: string;
+ ...
+}
+
+// Inline Content types
+type StyledText = {
+ type: "richText";
+ props: {
+ styles: Styles;
+ }
+ editable: true;
+}
+type Link = {
+ type: "link";
+ props: {
+ styles: Styles;
+ href: string;
+ }
+ editable: true;
+}
+type Mention = {
+ type: "mention";
+ props: {
+ user: string;
+ }
+ editable: false;
+}
+```
+This is way cleaner, but means that links cannot have mixed styles. I think we either:
+- Convert links to styles (they're already marks in TipTap)
+- Not do anything bc I don't think having mixed styles on links is ever useful
+
+### Inline Content Objects
+
+In code, the `InlineContent` type is used to describe a piece of inline content:
+
+```typescript
+type InlineContent = {
+ type: string;
+ props: Record;
+ editable: boolean;
+};
+```
+
+`type:` The inline content's type, such as a mention or styled text. For an overview of built-in inline content types, see [Default Inline Content](/docs/editor-basics/default-content-types#default-inline-content).
+
+`props:` The inline content's properties, which are stored in a set of key/value pairs and specify how the inline content looks and behaves. Different inline content types have different props - see [Default Inline Content](/docs/editor-basics/default-content-types#default-inline-content) for more.
+
+`editable`: Whether the inline content contains editable text.
+
+### Types of Block Content
+
+Most blocks will use an array of `InlineContent` objects to describe their content, such as paragraphs, headings and list items. Some blocks, like [images](/docs/editor-basics/default-content-types#image), don't contain any rich text content, so their `content` fields will be `undefined`.
+
+[Tables](/docs/editor-basics/default-content-types#table) are also different, as they contain `TableContent`. Here, each table cell is represented as an array of `InlineContent` objects:
+
+```typescript
+type TableContent = {
+ type: "tableContent";
+ rows: {
+ cells: InlineContent[][];
+ }[];
+};
+```
+
+### Block Content in JSON
+
+The demo below shows how the block content is represented in code by outputting only the `content` field of each top level block. As in the [previous demo](/docs/editor-basics/content-structure#editor-content-in-json), notice that it's in JSON.
+
+
\ No newline at end of file
diff --git a/docs/pages/docs/editor-basics/default-blocks.mdx b/docs/pages/docs/editor-basics/default-content-types.mdx
similarity index 51%
rename from docs/pages/docs/editor-basics/default-blocks.mdx
rename to docs/pages/docs/editor-basics/default-content-types.mdx
index d7b22f96a0..2c0fae1bb5 100644
--- a/docs/pages/docs/editor-basics/default-blocks.mdx
+++ b/docs/pages/docs/editor-basics/default-content-types.mdx
@@ -1,22 +1,26 @@
---
-title: Default Blocks
-description: Overview of all default block types and their properties in BlockNote.
-imageTitle: Default Blocks
+title: Default Content Types
+description: BlockNote supports a variety on built-in block and inline content types that are included in the editor by default.
+imageTitle: Default Content Types
---
import { Example } from "@/components/example";
-# Default Blocks
+# Default Content Types
-BlockNote includes a number of built-in block types. The demo editor below displays all of them:
+BlockNote supports a variety on built-in block and inline content types that are included in the editor by default. To create your own content types, see [Custom Schemas](/docs/custom-schemas).
-TODO: demo
+## Default Blocks
-## Reference
+BlockNote includes a number of built-in block types. The demo below contains each of them:
+
+
+
+### Reference
Here's an overview of all default blocks and the properties they support:
-### Paragraph
+#### Paragraph
**Appearance**
@@ -34,7 +38,7 @@ type ParagraphBlock = {
};
```
-### Heading
+#### Heading
**Appearance**
@@ -56,7 +60,7 @@ type HeadingBlock = {
`level:` The heading level, representing a title (`level: 1`), heading (`level: 2`), and subheading (`level: 3`).
-### Bullet List Item
+#### Bullet List Item
**Appearance**
@@ -74,7 +78,7 @@ type BulletListItemBlock = {
};
```
-### Numbered List Item
+#### Numbered List Item
**Appearance**
@@ -92,7 +96,7 @@ type NumberedListItemBlock = {
};
```
-### Image
+#### Image
**Appearance**
@@ -108,8 +112,8 @@ type ImageBlock = {
url: string = "";
caption: string = "";
width: number = 512;
- } & Omit;
- content: InlineContent[];
+ } & DefaultProps;
+ content: undefined;
children: Block[];
};
```
@@ -120,7 +124,7 @@ type ImageBlock = {
`width:` The image width in pixels.
-### Table
+#### Table
**Appearance**
@@ -138,7 +142,7 @@ type TableBlock = {
};
```
-## Default Block Properties
+### Default Block Properties
There are some default block props that BlockNote uses for its default block types, and also exports for use in your own [custom blocks](/docs/custom-schemas/custom-blocks):
@@ -156,6 +160,78 @@ type DefaultProps = {
`textAlignment:` The text alignment of the block.
-## Creating New Block Types
+### Creating New Block Types
+
+Skip to [Custom Blocks](/docs/custom-schemas/custom-blocks) to learn how to do this.
+
+## Default Inline Content
+
+BlockNote includes a number of built-in inline content types. The demo editor below displays all of them:
+
+
+
+### Reference
+
+Here's an overview of all default inline content and the properties they support:
+
+#### Styled Text
+
+`StyledText` is a type of `InlineContent` used to display pieces of text with styles:
+
+```typescript
+type Styles = {
+ bold: true;
+ italic: true;
+ underline: true;
+ strikethrough: true;
+ textColor: string;
+ backgroundColor: string;
+}
+
+type StyledText = {
+ type: "text";
+ text: string;
+ styles: Styles;
+};
+```
+
+#### Link
+
+`Link` objects represent links to a URL:
+
+```typescript
+type Link = {
+ type: "link";
+ content: StyledText[];
+ href: string;
+};
+```
+
+### Default Inline Content Properties
+
+TODO: This section only makes sense with the proposal in [Inline Content](/docs/editor-basics/content-structure#inline-content)
+
+There are some default inline content props that BlockNote uses for its default inline content types, and also exports for use in your own [custom inline content](/docs/custom-schemas/custom-inline-content):
+
+```typescript
+type Styles = {
+ bold: true;
+ italic: true;
+ underline: true;
+ strikethrough: true;
+ textColor: string;
+ backgroundColor: string;
+}
+
+type DefaultInlineContentProps = {
+ styles: Styles
+};
+```
+
+`styles:` The text styles applied to the inline content. Only useful for editable inline content types.
+
+### Creating New Inline Content Types
+
+You can create your own custom inline content using React - skip to [Custom Inline Content](/docs/custom-schemas/custom-inline-content) to learn how to do this.
-Skip to [Custom Blocks](/docs/custom-schemas/custom-blocks) to learn how to do this.
\ No newline at end of file
+You can also create custom styles to apply to `StyledText` - skip to [Custom Styles](/docs/custom-schemas/custom-styles) to learn how to do this.
\ No newline at end of file
diff --git a/docs/pages/docs/editor-basics/default-inline-content.mdx b/docs/pages/docs/editor-basics/default-inline-content.mdx
deleted file mode 100644
index 3b7a37ca8f..0000000000
--- a/docs/pages/docs/editor-basics/default-inline-content.mdx
+++ /dev/null
@@ -1,73 +0,0 @@
----
-title: Default Inline Content
-description: Overview of all default inline content types and their properties in BlockNote.
-imageTitle: Default Inline Content
----
-
-# Default Inline Content
-
-BlockNote includes a number of built-in inline content types. The demo editor below displays all of them:
-
-TODO: demo
-
-## Reference
-
-Here's an overview of all default inline content and the properties they support:
-
-### Styled Text
-
-`StyledText` is a type of `InlineContent` used to display pieces of text with styles:
-
-```typescript
-type Styles = {
- bold: true;
- italic: true;
- underline: true;
- strikethrough: true;
- textColor: string;
- backgroundColor: string;
-}
-
-type StyledText = {
- type: "text";
- text: string;
- styles: Styles;
-};
-```
-
-### Links
-
-`Link` objects represent links to a URL:
-
-```typescript
-type Link = {
- type: "link";
- content: StyledText[];
- href: string;
-};
-```
-
-## Default Inline Content Properties
-
-There are some default inline content props that BlockNote uses for its default inline content types, and also exports for use in your own [custom inline content](/docs/custom-schemas/custom-inline-content):
-
-```typescript
-type Styles = {
- bold: true;
- italic: true;
- underline: true;
- strikethrough: true;
- textColor: string;
- backgroundColor: string;
-}
-
-type DefaultInlineContentProps = {
- styles: Styles
-};
-```
-
-`styles:` The text styles applied to the inline content. Only useful for editable inline content types.
-
-## Creating New Inline Content Types
-
-You can create your own custom blocks using React. Skip to [Custom Inline Content](/docs/custom-schemas/custom-inline-content) to learn how to do this.
\ No newline at end of file
diff --git a/docs/pages/docs/editor-basics/editor.mdx b/docs/pages/docs/editor-basics/editor.mdx
index 5349080d0d..46f4ddb575 100644
--- a/docs/pages/docs/editor-basics/editor.mdx
+++ b/docs/pages/docs/editor-basics/editor.mdx
@@ -1,6 +1,6 @@
---
title: Editor Setup
-description: While BlockNote is ready to use out-of-the-box, there are a number of ways in which you can set it up, to better suit your use case.
+description: While BlockNote is ready to use out-of-the-box, there are a number of setup options you can choose to fit your use case.
imageTitle: Editor Setup
path: /docs/editor-basics/editor
---
@@ -18,13 +18,13 @@ TODO:
# Editor Setup
-While BlockNote is ready to use out-of-the-box, there are a number of ways in which you can set it up, to better suit your use case.
+While BlockNote is ready to use out-of-the-box, there are a number of setup options you can choose to fit your use case.
## Creating the Editor
### Using a React Hook
-Most of the time, you'll want to create the BlockNote editor using the `useCreateBlockNote` hook. This will create a new editor as your React component gets mounted, and you can pass a dependency array as with other React hooks.
+Most of the time, you'll want to create the BlockNote editor using the `useCreateBlockNote` hook. This will create a new editor when your React component gets mounted, and accepts a dependency array as with other React hooks.
```ts
useCreateBlockNote = (
@@ -101,4 +101,48 @@ return
### Props
-TODO
+There are a number of additional props you can pass to `BlockNoteView`. You can find the full list of these below:
+
+```typescript
+export type BlockNoteViewProps = Partial<{
+ formattingToolbar?: boolean;
+ hyperlinkToolbar?: boolean;
+ sideMenu?: boolean;
+ slashMenu?: boolean;
+ imageToolbar?: boolean;
+ tableHandles?: boolean;
+ theme:
+ | "light"
+ | "dark"
+ | Theme
+ | {
+ light: Theme;
+ dark: Theme;
+ };
+ editable?: boolean;
+ onSelectionChange?: () => void;
+ onChange?: () => void;
+}>;
+```
+
+`formattingToolbar`: Whether the [Formatting Toolbar](/docs/ui-components/formatting-toolbar) should be enabled.
+
+`hyperlinkToolbar`: Whether the Hyperlink Toolbar should be enabled.
+
+`sideMenu`: Whether the [Block Side Menu](/docs/ui-components/side-menu) should be enabled.
+
+`slashMenu`: Whether the [Slash Menu](/docs/ui-components/suggestion-menus#slash-menu) should be enabled.
+
+`imageToolbar`: Whether the Image Toolbar should be enabled.
+
+`tableHandles`: Whether the Table Handles should be enabled.
+
+`theme`: The editor's theme, see [Themes](/docs/styling-theming/themes) for more about this.
+
+`editable`: Whether the editor should be editable.
+
+`onSelectionChange`: Callback for when the editor selection changes.
+
+`onChange`: Callback for when the editor selection or content changes.
+
+`BlockNoteView` also takes props that you can pass to any HTML `div` element.
\ No newline at end of file
diff --git a/docs/pages/docs/editor-basics/inline-content.mdx b/docs/pages/docs/editor-basics/inline-content.mdx
deleted file mode 100644
index bf22efda21..0000000000
--- a/docs/pages/docs/editor-basics/inline-content.mdx
+++ /dev/null
@@ -1,74 +0,0 @@
----
-title: Introduction to Blocks
-description: Once you create an editor, you'll need to understand how its content is structured into blocks.
-imageTitle: Introduction to Blocks
----
-
-import { Example } from "@/components/example";
-
-# Intro to Inline Content
-
-Many blocks contain inline content. This page explains what inline content is, and how it's represented in code.
-
-## Inline Content Objects
-
-A block's content is referred to as inline content, and is used to represent rich text.
-
-TODO: Between custom & default inline content types, the shapes on inline content objects are not standardized.
-e.g. `Link`s have `href` and no props, custom IC will have props. `StyledText` can be IC itself, or used in other IC types.
-
-I think we should have smth like this:
-```typescript
-// Helper types
-type Styles = {
- bold: boolean;
- textColor: string;
- ...
-}
-
-// Inline Content types
-type StyledText = {
- type: "richText";
- props: {
- styles: Styles;
- }
- editable: true;
-}
-type Link = {
- type: "link";
- props: {
- styles: Styles;
- href: string;
- }
- editable: true;
-}
-type Mention = {
- type: "mention";
- props: {
- user: string;
- }
- editable: false;
-}
-```
-This is way cleaner, but means that links cannot have mixed styles. I think we either:
-- Convert links to styles (they're already marks in TipTap)
-- Not do anything bc I don't think having mixed styles on links is ever useful
-
-## Table Content
-
-Most blocks use an array of `InlineContent` objects to describe their content, but tables are slightly different. Table blocks have `TableContent` as their content, in which each row contains an array of cells, that each have an array of `InlineContent` objects.
-
-```typescript
-type TableContent = {
- type: "tableContent";
- rows: {
- cells: InlineContent[][];
- }[];
-};
-```
-
-## Displaying Block Content
-
-In the example below, you can see how a block with the content, "Hello __there__, [BlockNote](https://www.blocknotejs.org)", is represented as an array of `InlineContent` objects:
-
-TODO: DEMO
diff --git a/examples/01-basic/02-block-objects/App.tsx b/examples/01-basic/02-block-objects/App.tsx
index 305c41ec18..1939ccdad2 100644
--- a/examples/01-basic/02-block-objects/App.tsx
+++ b/examples/01-basic/02-block-objects/App.tsx
@@ -7,7 +7,25 @@ export default function App() {
// Stores the editor's contents as an array of Block objects.
const [blocks, setBlocks] = useState([]);
// Creates a new editor instance.
- const editor = useCreateBlockNote();
+ const editor = useCreateBlockNote({
+ initialContent: [
+ {
+ type: "paragraph",
+ content: "Welcome to this demo!",
+ },
+ {
+ type: "heading",
+ content: "This is a heading block",
+ },
+ {
+ type: "paragraph",
+ content: "This is a paragraph block",
+ },
+ {
+ type: "paragraph",
+ },
+ ],
+ });
// Renders the editor instance and its contents, as an array of Block
// objects, below.
diff --git a/examples/01-basic/02-block-objects/README.md b/examples/01-basic/02-block-objects/README.md
index 7a1c328f88..fc20420f90 100644
--- a/examples/01-basic/02-block-objects/README.md
+++ b/examples/01-basic/02-block-objects/README.md
@@ -1,8 +1,6 @@
# Displaying Block Objects
-Here, we use the `onChange` handler to listen to updates to the BlockNote document and display them below the editor.
-
-**Try it out:** Type in the editor and see the JSON representation of the document.
+In this example, below the editor, we display its contents as they're represented in code - i.e. as a JSON array of `Block` objects.
**Relevant Docs:**
diff --git a/examples/01-basic/all-blocks/.bnexample.json b/examples/01-basic/all-blocks/.bnexample.json
new file mode 100644
index 0000000000..0993be7115
--- /dev/null
+++ b/examples/01-basic/all-blocks/.bnexample.json
@@ -0,0 +1,4 @@
+{
+ "playground": true,
+ "docs": true
+}
diff --git a/examples/01-basic/all-blocks/App.tsx b/examples/01-basic/all-blocks/App.tsx
new file mode 100644
index 0000000000..9063303e84
--- /dev/null
+++ b/examples/01-basic/all-blocks/App.tsx
@@ -0,0 +1,53 @@
+import { BlockNoteView, useCreateBlockNote } from "@blocknote/react";
+import "@blocknote/react/style.css";
+
+export default function App() {
+ // Creates a new editor instance.
+ const editor = useCreateBlockNote({
+ initialContent: [
+ {
+ type: "paragraph",
+ content: "Welcome to this demo!",
+ },
+ {
+ type: "paragraph",
+ content: "Paragraph",
+ },
+ {
+ type: "heading",
+ content: "Heading",
+ },
+ {
+ type: "bulletListItem",
+ content: "Bullet List Item",
+ },
+ {
+ type: "numberedListItem",
+ content: "Numbered List Item",
+ },
+ {
+ type: "image",
+ },
+ {
+ type: "table",
+ content: {
+ type: "tableContent",
+ rows: [
+ {
+ cells: ["Table Cell", "Table Cell", "Table Cell"],
+ },
+ {
+ cells: ["Table Cell", "Table Cell", "Table Cell"],
+ },
+ {
+ cells: ["Table Cell", "Table Cell", "Table Cell"],
+ },
+ ],
+ },
+ },
+ ],
+ });
+
+ // Renders the editor instance using a React component.
+ return ;
+}
diff --git a/examples/01-basic/all-blocks/README.md b/examples/01-basic/all-blocks/README.md
new file mode 100644
index 0000000000..d84f931110
--- /dev/null
+++ b/examples/01-basic/all-blocks/README.md
@@ -0,0 +1,7 @@
+# All Block Types
+
+In this example, the editor contains each of BlockNote's built-in block types.
+
+**Relevant Docs:**
+
+- TODO
diff --git a/examples/01-basic/all-inline-content/.bnexample.json b/examples/01-basic/all-inline-content/.bnexample.json
new file mode 100644
index 0000000000..0993be7115
--- /dev/null
+++ b/examples/01-basic/all-inline-content/.bnexample.json
@@ -0,0 +1,4 @@
+{
+ "playground": true,
+ "docs": true
+}
diff --git a/examples/01-basic/all-inline-content/App.tsx b/examples/01-basic/all-inline-content/App.tsx
new file mode 100644
index 0000000000..585db97021
--- /dev/null
+++ b/examples/01-basic/all-inline-content/App.tsx
@@ -0,0 +1,45 @@
+import { BlockNoteView, useCreateBlockNote } from "@blocknote/react";
+import "@blocknote/react/style.css";
+
+export default function App() {
+ // Creates a new editor instance.
+ const editor = useCreateBlockNote({
+ initialContent: [
+ {
+ type: "paragraph",
+ content: "Welcome to this demo!",
+ },
+ {
+ type: "paragraph",
+ content: [
+ {
+ type: "text",
+ text: "Styled Text",
+ styles: {
+ bold: true,
+ italic: true,
+ textColor: "red",
+ backgroundColor: "blue",
+ },
+ },
+ {
+ type: "text",
+ text: " ",
+ styles: {},
+ },
+ {
+ type: "link",
+ content: "Link",
+ href: "https://www.blocknotejs.org",
+ },
+ ],
+ },
+ {
+ type: "paragraph",
+ },
+ ],
+ });
+
+ // Renders the editor instance using a React component.
+ return ;
+}
diff --git a/examples/01-basic/all-inline-content/README.md b/examples/01-basic/all-inline-content/README.md
new file mode 100644
index 0000000000..4dff460052
--- /dev/null
+++ b/examples/01-basic/all-inline-content/README.md
@@ -0,0 +1,8 @@
+# All Inline Content Types
+
+In this example, the editor contains each of BlockNote's built-in inline content
+types.
+
+**Relevant Docs:**
+
+- TODO
diff --git a/examples/01-basic/inline-content-objects/.bnexample.json b/examples/01-basic/inline-content-objects/.bnexample.json
new file mode 100644
index 0000000000..0993be7115
--- /dev/null
+++ b/examples/01-basic/inline-content-objects/.bnexample.json
@@ -0,0 +1,4 @@
+{
+ "playground": true,
+ "docs": true
+}
diff --git a/examples/01-basic/inline-content-objects/App.tsx b/examples/01-basic/inline-content-objects/App.tsx
new file mode 100644
index 0000000000..a06785f6b5
--- /dev/null
+++ b/examples/01-basic/inline-content-objects/App.tsx
@@ -0,0 +1,71 @@
+import {
+ DefaultInlineContentSchema,
+ DefaultStyleSchema,
+ InlineContent,
+ TableContent,
+} from "@blocknote/core";
+import { BlockNoteView, useCreateBlockNote } from "@blocknote/react";
+import "@blocknote/react/style.css";
+import { useState } from "react";
+
+export default function App() {
+ // Stores the editor's contents as an array of Block objects.
+ // TODO: InlineContent and TableContent should have default type args
+ const [inlineContent, setInlineContent] = useState<
+ (
+ | InlineContent[]
+ | TableContent
+ | undefined
+ )[]
+ >([]);
+ // Creates a new editor instance.
+ const editor = useCreateBlockNote({
+ initialContent: [
+ {
+ type: "paragraph",
+ content: "Welcome to this demo!",
+ },
+ {
+ type: "paragraph",
+ content: [
+ {
+ type: "text",
+ text: "Hello ",
+ styles: {},
+ },
+ {
+ type: "text",
+ text: "there, ",
+ styles: {
+ bold: true,
+ },
+ },
+ {
+ type: "link",
+ content: "BlockNote",
+ href: "https://www.blocknotejs.org",
+ },
+ ],
+ },
+ {
+ type: "paragraph",
+ },
+ ],
+ });
+
+ // Renders the editor instance and the contents of its blocks below.
+ return (
+
+ {
+ // Converts the editor's contents to an array with each top level
+ // block's content.
+ setInlineContent(editor.topLevelBlocks.map((block) => block.content));
+ }}
+ />
+
Document JSON:
+
{JSON.stringify(inlineContent, null, 2)}
+
+ );
+}
diff --git a/examples/01-basic/inline-content-objects/README.md b/examples/01-basic/inline-content-objects/README.md
new file mode 100644
index 0000000000..7c2641a47d
--- /dev/null
+++ b/examples/01-basic/inline-content-objects/README.md
@@ -0,0 +1,7 @@
+# Displaying Inline Content Objects
+
+In this example, below the editor, we display the contents of each block as they're represented in code. This changes based on block type, but is always valid JSON.
+
+**Relevant Docs:**
+
+- TODO
diff --git a/examples/01-basic/inline-content-objects/styles.css b/examples/01-basic/inline-content-objects/styles.css
new file mode 100644
index 0000000000..a7753b012f
--- /dev/null
+++ b/examples/01-basic/inline-content-objects/styles.css
@@ -0,0 +1,3 @@
+pre {
+ color: grey;
+}
\ No newline at end of file
From 2f80b56959db04108bfb515eb8dd3fbebbcb12a3 Mon Sep 17 00:00:00 2001
From: yousefed
Date: Mon, 26 Feb 2024 16:04:45 +0100
Subject: [PATCH 3/9] fix build
---
docs/package.json | 2 +-
packages/dev-scripts/examples/genDocs.ts | 57 +++++++++++-------------
2 files changed, 28 insertions(+), 31 deletions(-)
diff --git a/docs/package.json b/docs/package.json
index 3b1d5147ac..8ec05f7036 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -4,7 +4,7 @@
"private": true,
"scripts": {
"dev": "next dev",
- "build": "next build",
+ "docs:build": "next build",
"start": "next start",
"lint": "next lint"
},
diff --git a/packages/dev-scripts/examples/genDocs.ts b/packages/dev-scripts/examples/genDocs.ts
index 384db3d4ac..4f31ff41c5 100644
--- a/packages/dev-scripts/examples/genDocs.ts
+++ b/packages/dev-scripts/examples/genDocs.ts
@@ -43,17 +43,19 @@ ${file.code}
`;
+const COMPONENT_DIR = path.resolve(
+ dir,
+ "../../../docs/components/example/generated/"
+);
+
+const EXAMPLES_PAGES_DIR = path.resolve(dir, "../../../docs/pages/examples/");
+
/**
* Generates the component that has all the source code of the example
* This block can be used both in the /docs and in the /example page
*/
async function generateCodeForExample(project: Project) {
- const target = path.resolve(
- dir,
- "../../../docs/components/example/generated/mdx/" +
- project.fullSlug +
- ".mdx"
- );
+ const target = path.join(COMPONENT_DIR, "mdx", project.fullSlug + ".mdx");
const files = getProjectFiles(project);
const filtered = Object.fromEntries(
@@ -82,10 +84,7 @@ ${readme}
* Consists of the contents of the readme + the interactive example
*/
async function generatePageForExample(project: Project) {
- const target = path.resolve(
- dir,
- "../../../docs/pages/examples/" + project.fullSlug + ".mdx"
- );
+ const target = path.join(EXAMPLES_PAGES_DIR, project.fullSlug + ".mdx");
const files = getProjectFiles(project);
@@ -102,20 +101,11 @@ async function generateMetaForExampleGroup(group: {
slug: string;
projects: Project[];
}) {
- if (
- !fs.existsSync(
- path.resolve(dir, "../../../docs/pages/examples/" + group.slug)
- )
- ) {
- fs.mkdirSync(
- path.resolve(dir, "../../../docs/pages/examples/" + group.slug)
- );
+ if (!fs.existsSync(path.join(EXAMPLES_PAGES_DIR, group.slug))) {
+ fs.mkdirSync(path.join(EXAMPLES_PAGES_DIR, group.slug));
}
- const target = path.resolve(
- dir,
- "../../../docs/pages/examples/" + group.slug + "/_meta.json"
- );
+ const target = path.join(EXAMPLES_PAGES_DIR, group.slug, "_meta.json");
const meta = Object.fromEntries(
group.projects.map((project) => [
@@ -160,10 +150,7 @@ ${projects
* Generate the file with all the dynamic imports for examples (exampleComponents.gen.tsx)
*/
async function generateExampleComponents(projects: Project[]) {
- const target = path.resolve(
- dir,
- "../../../docs/components/example/generated/exampleComponents.gen.tsx"
- );
+ const target = path.join(COMPONENT_DIR, "exampleComponents.gen.tsx");
const code = templateExampleComponents(projects);
@@ -174,10 +161,7 @@ async function generateExampleComponents(projects: Project[]) {
* generates exampleList.gen.ts file with data about all the examples
*/
async function generateExampleList(projects: Project[]) {
- const target = path.resolve(
- dir,
- "../../../docs/components/example/generated/exampleList.gen.ts"
- );
+ const target = path.join(COMPONENT_DIR, "exampleList.gen.ts");
const groups = groupProjects(projects);
@@ -199,6 +183,19 @@ async function generateExampleList(projects: Project[]) {
fs.writeFileSync(target, code);
}
+// clean old files / dirs
+fs.rmSync(COMPONENT_DIR, { recursive: true, force: true });
+
+fs.readdirSync(EXAMPLES_PAGES_DIR, { withFileTypes: true }).forEach((file) => {
+ if (file.isDirectory()) {
+ fs.rmSync(path.join(EXAMPLES_PAGES_DIR, file.name), {
+ recursive: true,
+ force: true,
+ });
+ }
+});
+
+// generate new files
const projects = getExampleProjects(); // TODO: .filter((p) => p.config?.docs === true);
const groups = groupProjects(projects);
From f407230e00962626c8b0e45cfcb9393cad6b0528 Mon Sep 17 00:00:00 2001
From: yousefed
Date: Mon, 26 Feb 2024 16:21:59 +0100
Subject: [PATCH 4/9] fix
---
docs/api/og.tsx | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/docs/api/og.tsx b/docs/api/og.tsx
index b7794f6e1b..96e4514e02 100644
--- a/docs/api/og.tsx
+++ b/docs/api/og.tsx
@@ -1,12 +1,11 @@
import { ImageResponse } from "@vercel/og";
-import React from "react";
export const config = {
runtime: "edge",
};
const font = fetch(
- new URL("../docs/public/fonts/Gilroy-Regular.ttf", import.meta.url)
+ new URL("../public/fonts/Gilroy-Regular.ttf", import.meta.url),
).then((res) => res.arrayBuffer());
export default async function handler(request: { url: string }) {
From f6d82f32fd429bdb204551cbc530f7e7875e8f1e Mon Sep 17 00:00:00 2001
From: Matthew Lipski
Date: Mon, 26 Feb 2024 16:24:37 +0100
Subject: [PATCH 5/9] Updated editor api links
---
.../docs/editor-api/cursor-selections.mdx | 3 +-
.../docs/editor-api/manipulating-blocks.mdx | 49 +++---
.../manipulating-inline-content.mdx | 145 +-----------------
3 files changed, 29 insertions(+), 168 deletions(-)
diff --git a/docs/pages/docs/editor-api/cursor-selections.mdx b/docs/pages/docs/editor-api/cursor-selections.mdx
index 571a9b6e74..83f3429308 100644
--- a/docs/pages/docs/editor-api/cursor-selections.mdx
+++ b/docs/pages/docs/editor-api/cursor-selections.mdx
@@ -5,6 +5,7 @@ imageTitle: Cursor & Selections
path: /docs/cursor-selections
---
+
import { Example } from "@/components/example";
# Cursor & Selections
@@ -59,7 +60,7 @@ setTextCursorPosition(
editor.setTextCursorPosition(targetBlock, placement);
```
-`targetBlock:` The [identifier](/docs/manipulating-blocks#block-identifiers) of an existing block that the text cursor should be moved to.
+`targetBlock:` The [identifier](/docs/editor-api/manipulating-blocks#block-identifiers) of an existing block that the text cursor should be moved to.
`placement:` Whether the text cursor should be placed at the start or end of the block.
diff --git a/docs/pages/docs/editor-api/manipulating-blocks.mdx b/docs/pages/docs/editor-api/manipulating-blocks.mdx
index 3b72676d1b..3f9dc69f65 100644
--- a/docs/pages/docs/editor-api/manipulating-blocks.mdx
+++ b/docs/pages/docs/editor-api/manipulating-blocks.mdx
@@ -9,18 +9,17 @@ path: /docs/manipulating-blocks
Below, we explain the methods on `editor` you can use to read Blocks from the editor, and how to create / remove / update Blocks:
-- topLevelBlocks
-- getBlock
-- forEachBlock
-- insertBlocks
-- updateBlock
-- removeBlocks
-- replaceBlocks
-- canNestBlock
-- nestBlock
-- canUnnestBlock
-
-(TODO: link)
+- [topLevelBlocks](/docs/editor-api/manipulating-blocks#getting-all-top-level-blocks)
+- [getBlock](/docs/editor-api/manipulating-blocks#getting-a-specific-block)
+- [forEachBlock](/docs/editor-api/manipulating-blocks#traversing-all-blocks)
+- [insertBlocks](/docs/editor-api/manipulating-blocks#inserting-new-blocks)
+- [updateBlock](/docs/editor-api/manipulating-blocks#updating-blocks)
+- [removeBlocks](/docs/editor-api/manipulating-blocks#removing-blocks)
+- [replaceBlocks](/docs/editor-api/manipulating-blocks#replacing-blocks)
+- [canNestBlock](/docs/editor-api/manipulating-blocks#nesting-blocks)
+- [nestBlock](/docs/editor-api/manipulating-blocks#nesting-blocks)
+- [canUnnestBlock](/docs/editor-api/manipulating-blocks#un-nesting-blocks)
+- [unnestBlock](/docs/editor-api/manipulating-blocks#un-nesting-blocks)
## Common types
@@ -70,7 +69,7 @@ const blocks = editor.topLevelBlocks;
`returns:` The document; a snapshot of all top-level (non-nested) blocks in the editor.
-We already used this for the demo in [Getting Familiar with Block Objects](/docs/blocks#demo-getting-familiar-with-block-objects), to show the JSON representation of blocks below the editor.
+We already used this for the [Editor Content in JSON](/docs/editor-basics/content-structure#editor-content-in-json) demo.
### Getting a Specific Block
@@ -83,7 +82,7 @@ getBlock(blockIdentifier: BlockIdentifier): Block | undefined;
const block = editor.getBlock(blockIdentifier);
```
-`blockIdentifier:` The [identifier](#block-identifiers) of an existing block that should be retrieved.
+`blockIdentifier:` The [identifier](/docs/editor-api/manipulating-blocks#block-identifiers) of an existing block that should be retrieved.
`returns:` The block that matches the identifier, or `undefined` if no matching block was found.
@@ -107,7 +106,7 @@ editor.forEachBlock((block) => {...});
### Getting the hovered / selected Block
-See [Cursor & Selections](/docs/cursor-selections) to learn how to retrieve the block a user is interacting with.
+See [Cursor & Selections](/docs/editor-api/cursor-selections) to learn how to retrieve the block a user is interacting with.
## Inserting New Blocks
@@ -124,9 +123,9 @@ insertBlocks(
editor.insertBlocks([{type: "paragraph", text: "Hello World"}], referenceBlock, placement)
```
-`blocksToInsert:` An array of [partial blocks](#partial-blocks) that should be inserted.
+`blocksToInsert:` An array of [partial blocks](/docs/editor-api/manipulating-blocks#partial-blocks) that should be inserted.
-`referenceBlock:` An [identifier](#block-identifiers) for an existing block, at which the new blocks should be inserted.
+`referenceBlock:` An [identifier](/docs/editor-api/manipulating-blocks#block-identifiers) for an existing block, at which the new blocks should be inserted.
`placement:` Whether the blocks should be inserted just before, just after, or nested inside the `referenceBlock`. Inserts the blocks at the start of the existing block's children if `"nested"` is used.
@@ -148,9 +147,9 @@ updateBlock(
editor.updateBlock(blockToUpdate, { type: "paragraph" });
```
-`blockToUpdate:` The [identifier](#block-identifiers) of an existing block that should be updated.
+`blockToUpdate:` The [identifier](/docs/editor-api/manipulating-blocks#block-identifiers) of an existing block that should be updated.
-`update:` A [partial block](#partial-blocks) which defines how the existing block should be changed.
+`update:` A [partial blocks](/docs/editor-api/manipulating-blocks#partial-blocks) which defines how the existing block should be changed.
Since `blockToUpdate` is a `PartialBlock` object, some fields might not be defined. These undefined fields are kept as-is from the existing block.
@@ -169,7 +168,7 @@ removeBlocks(
editor.removeBlocks(blocksToRemove)
```
-`blocksToRemove:` An array of [identifiers](#block-identifiers) for existing blocks that should be removed.
+`blocksToRemove:` An array of [identifier](/docs/editor-api/manipulating-blocks#block-identifiers) for existing blocks that should be removed.
Throws an error if any of the blocks could not be found.
@@ -187,9 +186,9 @@ replaceBlocks(
editor.replaceBlocks(blocksToRemove, blocksToInsert)
```
-`blocksToRemove:` An array of [identifiers](#block-identifiers) for existing blocks that should be replaced.
+`blocksToRemove:` An array of [identifier](/docs/editor-api/manipulating-blocks#block-identifiers) for existing blocks that should be replaced.
-`blocksToInsert:` An array of [partial blocks](#partial-blocks) that the existing ones should be replaced with.
+`blocksToInsert:` An array of [partial blocks](/docs/editor-api/manipulating-blocks#partial-blocks) that the existing ones should be replaced with.
If the blocks that should be removed are not adjacent or are at different nesting levels, `blocksToInsert` will be inserted at the position of the first block in `blocksToRemove`.
@@ -197,13 +196,13 @@ Throws an error if any of the blocks to remove could not be found.
## Nesting & Un-nesting Blocks
-BlockNote also provides functions to nest & un-nest the block containing the [Text Cursor](/docs/cursor-selections#text-cursor).
+BlockNote also provides functions to nest & un-nest the block containing the [Text Cursor](/docs/editor-api/cursor-selections#text-cursor).
### Nesting Blocks
TODO: this API seems different as it doesn't require a block id. should we make it possible to pass an identifier?
-Use `canNestBlock` to check whether the block containing the [Text Cursor](/docs/cursor-selections#text-cursor) can be nested (i.e. if there is a block above it at the same nesting level):
+Use `canNestBlock` to check whether the block containing the [Text Cursor](/docs/editor-api/cursor-selections#text-cursor) can be nested (i.e. if there is a block above it at the same nesting level):
```typescript
canNestBlock(): boolean;
@@ -223,7 +222,7 @@ editor.nestBlock();
### Un-nesting Blocks
-Use `canUnnestBlock` to check whether the block containing the [Text Cursor](/docs/cursor-selections#text-cursor) can be un-nested (i.e. if it's nested in another block):
+Use `canUnnestBlock` to check whether the block containing the [Text Cursor](/docs/editor-api/cursor-selections#text-cursor) can be un-nested (i.e. if it's nested in another block):
```typescript
canUnnestBlock(): boolean;
diff --git a/docs/pages/docs/editor-api/manipulating-inline-content.mdx b/docs/pages/docs/editor-api/manipulating-inline-content.mdx
index 738d5754b5..b0ead98c1d 100644
--- a/docs/pages/docs/editor-api/manipulating-inline-content.mdx
+++ b/docs/pages/docs/editor-api/manipulating-inline-content.mdx
@@ -5,152 +5,13 @@ imageTitle: Manipulating Inline Content
path: /docs/block-content
---
-TODO: API For this is pretty weird vs blocks
-
-[//]: # (# Block Content)
-
-[//]: # ()
-[//]: # (The `content` field of a `Block` describes the content of the block. For all blocks except tables, this field is an array of `InlineContent` objects and describes the rich text content typed inside the block.)
-
-[//]: # ()
-[//]: # (In the example below, you can see how a sentence like "Hello __there__, [BlockNote](https://www.blocknotejs.org)" is represented as an array of `InlineContent` objects:)
-
-[//]: # ()
-[//]: # (TODO: DEMO)
-
-[//]: # ()
-[//]: # ()
-[//]: # (## `InlineContent` Types)
-
-[//]: # ()
-[//]: # (`InlineContent` can be styled text (rich text), a link, or a mention:)
-
-[//]: # ()
-[//]: # (### Styled Text)
-
-[//]: # ()
-[//]: # (`StyledText` is a type of `InlineContent` used to display pieces of text with styles:)
-
-[//]: # ()
-[//]: # (```typescript)
-
-[//]: # (type StyledText = {)
-
-[//]: # ( type: "text";)
-
-[//]: # ( text: string;)
-
-[//]: # ( styles: Styles;)
-
-[//]: # (};)
-
-[//]: # (```)
-
-[//]: # ()
-[//]: # (`text:` The displayed text.)
-
-[//]: # ()
-[//]: # (`styles:` The styles that are applied to the text.)
-
-[//]: # ()
-[//]: # (**Styles Object**)
-
-[//]: # ()
-[//]: # (`StyledText` supports a variety of styles, including bold, underline, and text color, which are represented using a `Styles` object:)
-
-[//]: # ()
-[//]: # (```typescript)
-
-[//]: # (type Styles = Partial<{)
-
-[//]: # ( bold: true;)
-
-[//]: # ( italic: true;)
-
-[//]: # ( underline: true;)
-
-[//]: # ( strikethrough: true;)
-
-[//]: # ( textColor: string;)
-
-[//]: # ( backgroundColor: string;)
-
-[//]: # (}>;)
-
-[//]: # (```)
-
-[//]: # ()
-[//]: # (### Links)
-
-[//]: # ()
-[//]: # (`Link` objects represent links to a URL:)
-
-[//]: # ()
-[//]: # (```typescript)
-
-[//]: # (type Link = {)
-
-[//]: # ( type: "link";)
-
-[//]: # ( content: StyledText[];)
-
-[//]: # ( href: string;)
-
-[//]: # (};)
-
-[//]: # (```)
-
-[//]: # ()
-[//]: # (`content:` The styled text used to display the link.)
-
-[//]: # ()
-[//]: # (`href:` The URL that opens when clicking the link.)
-
-[//]: # ()
-[//]: # (### Mentions)
-
-[//]: # ()
-[//]: # (TODO)
-
-[//]: # ()
-[//]: # (### Custom `InlineContent` and `Styles`)
-
-[//]: # ()
-[//]: # (You can create your own types of `InlineContent` and `Styles` using React. Skip to the Advanced "custom schemas" section to learn more about extending the editor. (TODO: link))
-
-[//]: # ()
-[//]: # (## TableContent)
-
-[//]: # ()
-[//]: # (Most blocks use an array of `InlineContent` objects to describe their content, but tables are slightly different. Table blocks have `TableContent` as their content, in which each row contains an array of cells, that)
-
-[//]: # ()
-[//]: # ()
-[//]: # (```typescript)
-
-[//]: # (type TableContent = {)
-
-[//]: # ( type: "tableContent";)
-
-[//]: # ( rows: {)
-
-[//]: # ( cells: InlineContent[][];)
-
-[//]: # ( }[];)
-
-[//]: # (};)
-
-[//]: # (```)
-
# Manipulating Inline Content
-TODO: where should this be?
-
While `InlineContent` objects are used to describe a block's content, they can be cumbersome to work with directly. Therefore, BlockNote exposes functions which make it easier to edit block contents.
## Accessing Styles
-You can get the styles at the current [Text Cursor Position](/docs/cursor-selections#text-cursor) using the following function:
+You can get the styles at the current [Text Cursor Position](/docs/editor-api/cursor-selections#text-cursor) using the following function:
```typescript
getActiveStyles(): Styles;
@@ -159,7 +20,7 @@ getActiveStyles(): Styles;
const styles = editor.getActiveStyles();
```
-If a [Selection](/docs/cursor-selections#selections) is active, this function returns the active styles at the end of the selection.
+If a [Selection](/docs/editor-api/cursor-selections#selections) is active, this function returns the active styles at the end of the selection.
## Adding Styles
@@ -229,4 +90,4 @@ createLink(url: string, text?: string): void;
editor.createLink("https://www.blocknotejs.org/", "BlockNote");
```
-If a [Selection](/docs/cursor-selections#selections) is active, the new link will replace the currently selected content.
+If a [Selection](/docs/editor-api/cursor-selections#selections) is active, the new link will replace the currently selected content.
From 30ba0d7e8fe6a563aa8bd60c8cd852754070f0eb Mon Sep 17 00:00:00 2001
From: yousefed
Date: Mon, 26 Feb 2024 16:27:04 +0100
Subject: [PATCH 6/9] generate + clean some comments
---
docs/pages/docs/editor-basics/editor.mdx | 21 ++++------
examples/01-basic/all-blocks/index.html | 14 +++++++
examples/01-basic/all-blocks/main.tsx | 11 +++++
examples/01-basic/all-blocks/package.json | 34 +++++++++++++++
examples/01-basic/all-blocks/tsconfig.json | 36 ++++++++++++++++
examples/01-basic/all-blocks/vite.config.ts | 32 ++++++++++++++
.../01-basic/all-inline-content/index.html | 14 +++++++
examples/01-basic/all-inline-content/main.tsx | 11 +++++
.../01-basic/all-inline-content/package.json | 34 +++++++++++++++
.../01-basic/all-inline-content/tsconfig.json | 36 ++++++++++++++++
.../all-inline-content/vite.config.ts | 32 ++++++++++++++
.../inline-content-objects/index.html | 14 +++++++
.../01-basic/inline-content-objects/main.tsx | 11 +++++
.../inline-content-objects/package.json | 34 +++++++++++++++
.../inline-content-objects/tsconfig.json | 36 ++++++++++++++++
.../inline-content-objects/vite.config.ts | 32 ++++++++++++++
playground/src/examples.gen.tsx | 42 +++++++++++++++++++
17 files changed, 431 insertions(+), 13 deletions(-)
create mode 100644 examples/01-basic/all-blocks/index.html
create mode 100644 examples/01-basic/all-blocks/main.tsx
create mode 100644 examples/01-basic/all-blocks/package.json
create mode 100644 examples/01-basic/all-blocks/tsconfig.json
create mode 100644 examples/01-basic/all-blocks/vite.config.ts
create mode 100644 examples/01-basic/all-inline-content/index.html
create mode 100644 examples/01-basic/all-inline-content/main.tsx
create mode 100644 examples/01-basic/all-inline-content/package.json
create mode 100644 examples/01-basic/all-inline-content/tsconfig.json
create mode 100644 examples/01-basic/all-inline-content/vite.config.ts
create mode 100644 examples/01-basic/inline-content-objects/index.html
create mode 100644 examples/01-basic/inline-content-objects/main.tsx
create mode 100644 examples/01-basic/inline-content-objects/package.json
create mode 100644 examples/01-basic/inline-content-objects/tsconfig.json
create mode 100644 examples/01-basic/inline-content-objects/vite.config.ts
diff --git a/docs/pages/docs/editor-basics/editor.mdx b/docs/pages/docs/editor-basics/editor.mdx
index 46f4ddb575..b4080f12a1 100644
--- a/docs/pages/docs/editor-basics/editor.mdx
+++ b/docs/pages/docs/editor-basics/editor.mdx
@@ -8,13 +8,9 @@ path: /docs/editor-basics/editor
import { Example } from "@/components/example";
TODO:
-[x] review API
-[x] what needs to be part of useBlockNote vs the component?
-[ ] document instantiation / useBlockNote
[ ] expose / document hooks
[ ] document events
[ ] explain controlled / uncontrolled
-[ ] Maybe move outside of "Editor API"?
# Editor Setup
@@ -29,7 +25,7 @@ Most of the time, you'll want to create the BlockNote editor using the `useCreat
```ts
useCreateBlockNote = (
options?: Partial,
- deps?: React.DependencyList
+ deps?: React.DependencyList,
) => BlockNoteEditor;
```
@@ -40,9 +36,8 @@ Read on to [Options](/docs/editor-basics/editor#options) to see what options you
You can also create a new editor using `BlockNoteEditor.create`. You should use this when you want to wait after your React component gets mounted before creating the editor.
```ts
-BlockNoteEditor.create = (
- options?: Partial,
-) => BlockNoteEditor;
+BlockNoteEditor.create = (options?: Partial) =>
+ BlockNoteEditor;
```
In the demo below, we use `BlockNoteEditor.create` so we can fetch the editor's initial content from `localStorage` before creating it.
@@ -96,7 +91,7 @@ To, render the editor, you should use the `BlockNoteView` component, and pass in
```tsx
const editor = useCreateBlockNote();
-return
+return ;
```
### Props
@@ -119,9 +114,9 @@ export type BlockNoteViewProps = Partial<{
light: Theme;
dark: Theme;
};
- editable?: boolean;
- onSelectionChange?: () => void;
- onChange?: () => void;
+ editable?: boolean;
+ onSelectionChange?: () => void;
+ onChange?: () => void;
}>;
```
@@ -145,4 +140,4 @@ export type BlockNoteViewProps = Partial<{
`onChange`: Callback for when the editor selection or content changes.
-`BlockNoteView` also takes props that you can pass to any HTML `div` element.
\ No newline at end of file
+`BlockNoteView` also takes props that you can pass to any HTML `div` element.
diff --git a/examples/01-basic/all-blocks/index.html b/examples/01-basic/all-blocks/index.html
new file mode 100644
index 0000000000..cd00e7388b
--- /dev/null
+++ b/examples/01-basic/all-blocks/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+ All Block Types
+
+
+
+
+
+
diff --git a/examples/01-basic/all-blocks/main.tsx b/examples/01-basic/all-blocks/main.tsx
new file mode 100644
index 0000000000..f88b490fbd
--- /dev/null
+++ b/examples/01-basic/all-blocks/main.tsx
@@ -0,0 +1,11 @@
+// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY
+import React from "react";
+import { createRoot } from "react-dom/client";
+import App from "./App";
+
+const root = createRoot(document.getElementById("root")!);
+root.render(
+
+
+
+);
diff --git a/examples/01-basic/all-blocks/package.json b/examples/01-basic/all-blocks/package.json
new file mode 100644
index 0000000000..953d7ba6aa
--- /dev/null
+++ b/examples/01-basic/all-blocks/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "@blocknote/example-all-blocks",
+ "description": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY",
+ "private": true,
+ "version": "0.11.1",
+ "scripts": {
+ "start": "vite",
+ "dev": "vite",
+ "build": "tsc && vite build",
+ "preview": "vite preview",
+ "lint": "eslint . --max-warnings 0"
+ },
+ "dependencies": {
+ "@blocknote/core": "^0.11.1",
+ "@blocknote/react": "^0.11.1",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "@types/react": "^18.0.25",
+ "@types/react-dom": "^18.0.9",
+ "@vitejs/plugin-react": "^4.0.4",
+ "eslint": "^8.10.0",
+ "vite": "^4.4.8"
+ },
+ "eslintConfig": {
+ "extends": [
+ "../../../.eslintrc.js"
+ ]
+ },
+ "eslintIgnore": [
+ "dist"
+ ]
+}
\ No newline at end of file
diff --git a/examples/01-basic/all-blocks/tsconfig.json b/examples/01-basic/all-blocks/tsconfig.json
new file mode 100644
index 0000000000..bb6637c459
--- /dev/null
+++ b/examples/01-basic/all-blocks/tsconfig.json
@@ -0,0 +1,36 @@
+{
+ "__comment": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY",
+ "compilerOptions": {
+ "target": "ESNext",
+ "useDefineForClassFields": true,
+ "lib": [
+ "DOM",
+ "DOM.Iterable",
+ "ESNext"
+ ],
+ "allowJs": false,
+ "skipLibCheck": true,
+ "esModuleInterop": false,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "module": "ESNext",
+ "moduleResolution": "Node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+ "composite": true
+ },
+ "include": [
+ "."
+ ],
+ "references": [
+ {
+ "path": "../../../packages/core/"
+ },
+ {
+ "path": "../../../packages/react/"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/examples/01-basic/all-blocks/vite.config.ts b/examples/01-basic/all-blocks/vite.config.ts
new file mode 100644
index 0000000000..f62ab20bc2
--- /dev/null
+++ b/examples/01-basic/all-blocks/vite.config.ts
@@ -0,0 +1,32 @@
+// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY
+import react from "@vitejs/plugin-react";
+import * as fs from "fs";
+import * as path from "path";
+import { defineConfig } from "vite";
+// import eslintPlugin from "vite-plugin-eslint";
+// https://vitejs.dev/config/
+export default defineConfig((conf) => ({
+ plugins: [react()],
+ optimizeDeps: {},
+ build: {
+ sourcemap: true,
+ },
+ resolve: {
+ alias:
+ conf.command === "build" ||
+ !fs.existsSync(path.resolve(__dirname, "../../packages/core/src"))
+ ? {}
+ : ({
+ // Comment out the lines below to load a built version of blocknote
+ // or, keep as is to load live from sources with live reload working
+ "@blocknote/core": path.resolve(
+ __dirname,
+ "../../packages/core/src/"
+ ),
+ "@blocknote/react": path.resolve(
+ __dirname,
+ "../../packages/react/src/"
+ ),
+ } as any),
+ },
+}));
diff --git a/examples/01-basic/all-inline-content/index.html b/examples/01-basic/all-inline-content/index.html
new file mode 100644
index 0000000000..8097927a03
--- /dev/null
+++ b/examples/01-basic/all-inline-content/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+ All Inline Content Types
+
+
+
+
+
+
diff --git a/examples/01-basic/all-inline-content/main.tsx b/examples/01-basic/all-inline-content/main.tsx
new file mode 100644
index 0000000000..f88b490fbd
--- /dev/null
+++ b/examples/01-basic/all-inline-content/main.tsx
@@ -0,0 +1,11 @@
+// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY
+import React from "react";
+import { createRoot } from "react-dom/client";
+import App from "./App";
+
+const root = createRoot(document.getElementById("root")!);
+root.render(
+
+
+
+);
diff --git a/examples/01-basic/all-inline-content/package.json b/examples/01-basic/all-inline-content/package.json
new file mode 100644
index 0000000000..12af279d98
--- /dev/null
+++ b/examples/01-basic/all-inline-content/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "@blocknote/example-all-inline-content",
+ "description": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY",
+ "private": true,
+ "version": "0.11.1",
+ "scripts": {
+ "start": "vite",
+ "dev": "vite",
+ "build": "tsc && vite build",
+ "preview": "vite preview",
+ "lint": "eslint . --max-warnings 0"
+ },
+ "dependencies": {
+ "@blocknote/core": "^0.11.1",
+ "@blocknote/react": "^0.11.1",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "@types/react": "^18.0.25",
+ "@types/react-dom": "^18.0.9",
+ "@vitejs/plugin-react": "^4.0.4",
+ "eslint": "^8.10.0",
+ "vite": "^4.4.8"
+ },
+ "eslintConfig": {
+ "extends": [
+ "../../../.eslintrc.js"
+ ]
+ },
+ "eslintIgnore": [
+ "dist"
+ ]
+}
\ No newline at end of file
diff --git a/examples/01-basic/all-inline-content/tsconfig.json b/examples/01-basic/all-inline-content/tsconfig.json
new file mode 100644
index 0000000000..bb6637c459
--- /dev/null
+++ b/examples/01-basic/all-inline-content/tsconfig.json
@@ -0,0 +1,36 @@
+{
+ "__comment": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY",
+ "compilerOptions": {
+ "target": "ESNext",
+ "useDefineForClassFields": true,
+ "lib": [
+ "DOM",
+ "DOM.Iterable",
+ "ESNext"
+ ],
+ "allowJs": false,
+ "skipLibCheck": true,
+ "esModuleInterop": false,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "module": "ESNext",
+ "moduleResolution": "Node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+ "composite": true
+ },
+ "include": [
+ "."
+ ],
+ "references": [
+ {
+ "path": "../../../packages/core/"
+ },
+ {
+ "path": "../../../packages/react/"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/examples/01-basic/all-inline-content/vite.config.ts b/examples/01-basic/all-inline-content/vite.config.ts
new file mode 100644
index 0000000000..f62ab20bc2
--- /dev/null
+++ b/examples/01-basic/all-inline-content/vite.config.ts
@@ -0,0 +1,32 @@
+// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY
+import react from "@vitejs/plugin-react";
+import * as fs from "fs";
+import * as path from "path";
+import { defineConfig } from "vite";
+// import eslintPlugin from "vite-plugin-eslint";
+// https://vitejs.dev/config/
+export default defineConfig((conf) => ({
+ plugins: [react()],
+ optimizeDeps: {},
+ build: {
+ sourcemap: true,
+ },
+ resolve: {
+ alias:
+ conf.command === "build" ||
+ !fs.existsSync(path.resolve(__dirname, "../../packages/core/src"))
+ ? {}
+ : ({
+ // Comment out the lines below to load a built version of blocknote
+ // or, keep as is to load live from sources with live reload working
+ "@blocknote/core": path.resolve(
+ __dirname,
+ "../../packages/core/src/"
+ ),
+ "@blocknote/react": path.resolve(
+ __dirname,
+ "../../packages/react/src/"
+ ),
+ } as any),
+ },
+}));
diff --git a/examples/01-basic/inline-content-objects/index.html b/examples/01-basic/inline-content-objects/index.html
new file mode 100644
index 0000000000..19aee77636
--- /dev/null
+++ b/examples/01-basic/inline-content-objects/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+ Displaying Inline Content Objects
+
+
+
+
+
+
diff --git a/examples/01-basic/inline-content-objects/main.tsx b/examples/01-basic/inline-content-objects/main.tsx
new file mode 100644
index 0000000000..f88b490fbd
--- /dev/null
+++ b/examples/01-basic/inline-content-objects/main.tsx
@@ -0,0 +1,11 @@
+// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY
+import React from "react";
+import { createRoot } from "react-dom/client";
+import App from "./App";
+
+const root = createRoot(document.getElementById("root")!);
+root.render(
+
+
+
+);
diff --git a/examples/01-basic/inline-content-objects/package.json b/examples/01-basic/inline-content-objects/package.json
new file mode 100644
index 0000000000..e4666f13bc
--- /dev/null
+++ b/examples/01-basic/inline-content-objects/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "@blocknote/example-inline-content-objects",
+ "description": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY",
+ "private": true,
+ "version": "0.11.1",
+ "scripts": {
+ "start": "vite",
+ "dev": "vite",
+ "build": "tsc && vite build",
+ "preview": "vite preview",
+ "lint": "eslint . --max-warnings 0"
+ },
+ "dependencies": {
+ "@blocknote/core": "^0.11.1",
+ "@blocknote/react": "^0.11.1",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "@types/react": "^18.0.25",
+ "@types/react-dom": "^18.0.9",
+ "@vitejs/plugin-react": "^4.0.4",
+ "eslint": "^8.10.0",
+ "vite": "^4.4.8"
+ },
+ "eslintConfig": {
+ "extends": [
+ "../../../.eslintrc.js"
+ ]
+ },
+ "eslintIgnore": [
+ "dist"
+ ]
+}
\ No newline at end of file
diff --git a/examples/01-basic/inline-content-objects/tsconfig.json b/examples/01-basic/inline-content-objects/tsconfig.json
new file mode 100644
index 0000000000..bb6637c459
--- /dev/null
+++ b/examples/01-basic/inline-content-objects/tsconfig.json
@@ -0,0 +1,36 @@
+{
+ "__comment": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY",
+ "compilerOptions": {
+ "target": "ESNext",
+ "useDefineForClassFields": true,
+ "lib": [
+ "DOM",
+ "DOM.Iterable",
+ "ESNext"
+ ],
+ "allowJs": false,
+ "skipLibCheck": true,
+ "esModuleInterop": false,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "module": "ESNext",
+ "moduleResolution": "Node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+ "composite": true
+ },
+ "include": [
+ "."
+ ],
+ "references": [
+ {
+ "path": "../../../packages/core/"
+ },
+ {
+ "path": "../../../packages/react/"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/examples/01-basic/inline-content-objects/vite.config.ts b/examples/01-basic/inline-content-objects/vite.config.ts
new file mode 100644
index 0000000000..f62ab20bc2
--- /dev/null
+++ b/examples/01-basic/inline-content-objects/vite.config.ts
@@ -0,0 +1,32 @@
+// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY
+import react from "@vitejs/plugin-react";
+import * as fs from "fs";
+import * as path from "path";
+import { defineConfig } from "vite";
+// import eslintPlugin from "vite-plugin-eslint";
+// https://vitejs.dev/config/
+export default defineConfig((conf) => ({
+ plugins: [react()],
+ optimizeDeps: {},
+ build: {
+ sourcemap: true,
+ },
+ resolve: {
+ alias:
+ conf.command === "build" ||
+ !fs.existsSync(path.resolve(__dirname, "../../packages/core/src"))
+ ? {}
+ : ({
+ // Comment out the lines below to load a built version of blocknote
+ // or, keep as is to load live from sources with live reload working
+ "@blocknote/core": path.resolve(
+ __dirname,
+ "../../packages/core/src/"
+ ),
+ "@blocknote/react": path.resolve(
+ __dirname,
+ "../../packages/react/src/"
+ ),
+ } as any),
+ },
+}));
diff --git a/playground/src/examples.gen.tsx b/playground/src/examples.gen.tsx
index 30b425ae8f..2418e33558 100644
--- a/playground/src/examples.gen.tsx
+++ b/playground/src/examples.gen.tsx
@@ -89,6 +89,48 @@
"pathFromRoot": "examples/01-basic",
"slug": "basic"
}
+ },
+ {
+ "projectSlug": "all-blocks",
+ "fullSlug": "basic/all-blocks",
+ "pathFromRoot": "examples/01-basic/all-blocks",
+ "config": {
+ "playground": true,
+ "docs": true
+ },
+ "title": "All Block Types",
+ "group": {
+ "pathFromRoot": "examples/01-basic",
+ "slug": "basic"
+ }
+ },
+ {
+ "projectSlug": "all-inline-content",
+ "fullSlug": "basic/all-inline-content",
+ "pathFromRoot": "examples/01-basic/all-inline-content",
+ "config": {
+ "playground": true,
+ "docs": true
+ },
+ "title": "All Inline Content Types",
+ "group": {
+ "pathFromRoot": "examples/01-basic",
+ "slug": "basic"
+ }
+ },
+ {
+ "projectSlug": "inline-content-objects",
+ "fullSlug": "basic/inline-content-objects",
+ "pathFromRoot": "examples/01-basic/inline-content-objects",
+ "config": {
+ "playground": true,
+ "docs": true
+ },
+ "title": "Displaying Inline Content Objects",
+ "group": {
+ "pathFromRoot": "examples/01-basic",
+ "slug": "basic"
+ }
}
]
},
From 22c0a7f0bd791da07d8bf9dab85699b3b17d5206 Mon Sep 17 00:00:00 2001
From: yousefed
Date: Mon, 26 Feb 2024 16:42:36 +0100
Subject: [PATCH 7/9] fix?
---
docs/api/og.tsx | 2 +-
docs/{public => assets}/fonts/Gilroy-Bold.ttf | Bin
docs/{public => assets}/fonts/Gilroy-ExtraBold.ttf | Bin
docs/{public => assets}/fonts/Gilroy-Medium.ttf | Bin
docs/{public => assets}/fonts/Gilroy-Regular.ttf | Bin
docs/{public => assets}/fonts/Gilroy-SemiBold.ttf | Bin
docs/{public => assets}/fonts/gilroy-bold.woff2 | Bin
.../{public => assets}/fonts/gilroy-extrabold.woff2 | Bin
docs/{public => assets}/fonts/gilroy-medium.woff2 | Bin
docs/{public => assets}/fonts/gilroy-regular.woff2 | Bin
docs/{public => assets}/fonts/gilroy-semibold.woff2 | Bin
11 files changed, 1 insertion(+), 1 deletion(-)
rename docs/{public => assets}/fonts/Gilroy-Bold.ttf (100%)
rename docs/{public => assets}/fonts/Gilroy-ExtraBold.ttf (100%)
rename docs/{public => assets}/fonts/Gilroy-Medium.ttf (100%)
rename docs/{public => assets}/fonts/Gilroy-Regular.ttf (100%)
rename docs/{public => assets}/fonts/Gilroy-SemiBold.ttf (100%)
rename docs/{public => assets}/fonts/gilroy-bold.woff2 (100%)
rename docs/{public => assets}/fonts/gilroy-extrabold.woff2 (100%)
rename docs/{public => assets}/fonts/gilroy-medium.woff2 (100%)
rename docs/{public => assets}/fonts/gilroy-regular.woff2 (100%)
rename docs/{public => assets}/fonts/gilroy-semibold.woff2 (100%)
diff --git a/docs/api/og.tsx b/docs/api/og.tsx
index 96e4514e02..dd02f0b647 100644
--- a/docs/api/og.tsx
+++ b/docs/api/og.tsx
@@ -5,7 +5,7 @@ export const config = {
};
const font = fetch(
- new URL("../public/fonts/Gilroy-Regular.ttf", import.meta.url),
+ new URL("../../assets/fonts/Gilroy-Regular.ttf", import.meta.url),
).then((res) => res.arrayBuffer());
export default async function handler(request: { url: string }) {
diff --git a/docs/public/fonts/Gilroy-Bold.ttf b/docs/assets/fonts/Gilroy-Bold.ttf
similarity index 100%
rename from docs/public/fonts/Gilroy-Bold.ttf
rename to docs/assets/fonts/Gilroy-Bold.ttf
diff --git a/docs/public/fonts/Gilroy-ExtraBold.ttf b/docs/assets/fonts/Gilroy-ExtraBold.ttf
similarity index 100%
rename from docs/public/fonts/Gilroy-ExtraBold.ttf
rename to docs/assets/fonts/Gilroy-ExtraBold.ttf
diff --git a/docs/public/fonts/Gilroy-Medium.ttf b/docs/assets/fonts/Gilroy-Medium.ttf
similarity index 100%
rename from docs/public/fonts/Gilroy-Medium.ttf
rename to docs/assets/fonts/Gilroy-Medium.ttf
diff --git a/docs/public/fonts/Gilroy-Regular.ttf b/docs/assets/fonts/Gilroy-Regular.ttf
similarity index 100%
rename from docs/public/fonts/Gilroy-Regular.ttf
rename to docs/assets/fonts/Gilroy-Regular.ttf
diff --git a/docs/public/fonts/Gilroy-SemiBold.ttf b/docs/assets/fonts/Gilroy-SemiBold.ttf
similarity index 100%
rename from docs/public/fonts/Gilroy-SemiBold.ttf
rename to docs/assets/fonts/Gilroy-SemiBold.ttf
diff --git a/docs/public/fonts/gilroy-bold.woff2 b/docs/assets/fonts/gilroy-bold.woff2
similarity index 100%
rename from docs/public/fonts/gilroy-bold.woff2
rename to docs/assets/fonts/gilroy-bold.woff2
diff --git a/docs/public/fonts/gilroy-extrabold.woff2 b/docs/assets/fonts/gilroy-extrabold.woff2
similarity index 100%
rename from docs/public/fonts/gilroy-extrabold.woff2
rename to docs/assets/fonts/gilroy-extrabold.woff2
diff --git a/docs/public/fonts/gilroy-medium.woff2 b/docs/assets/fonts/gilroy-medium.woff2
similarity index 100%
rename from docs/public/fonts/gilroy-medium.woff2
rename to docs/assets/fonts/gilroy-medium.woff2
diff --git a/docs/public/fonts/gilroy-regular.woff2 b/docs/assets/fonts/gilroy-regular.woff2
similarity index 100%
rename from docs/public/fonts/gilroy-regular.woff2
rename to docs/assets/fonts/gilroy-regular.woff2
diff --git a/docs/public/fonts/gilroy-semibold.woff2 b/docs/assets/fonts/gilroy-semibold.woff2
similarity index 100%
rename from docs/public/fonts/gilroy-semibold.woff2
rename to docs/assets/fonts/gilroy-semibold.woff2
From ad799b35cdfec7b11fc238e28896a7a5758e7352 Mon Sep 17 00:00:00 2001
From: yousefed
Date: Mon, 26 Feb 2024 16:49:58 +0100
Subject: [PATCH 8/9] disable og
---
docs/api/{og.tsx => og.tsx.bak} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename docs/api/{og.tsx => og.tsx.bak} (100%)
diff --git a/docs/api/og.tsx b/docs/api/og.tsx.bak
similarity index 100%
rename from docs/api/og.tsx
rename to docs/api/og.tsx.bak
From 43e9796842b109adba77ad0241ece9b28ad262df Mon Sep 17 00:00:00 2001
From: Yousef
Date: Tue, 27 Feb 2024 20:07:27 +0100
Subject: [PATCH 9/9] docs review (#596)
* docs review
* Fixed PR feedback
---------
Co-authored-by: Matthew Lipski
---
docs/pages/docs/advanced/vanilla-js.mdx | 110 +++++++-------
docs/pages/docs/custom-schemas.mdx | 2 +-
.../docs/custom-schemas/custom-styles.mdx | 21 +--
docs/pages/docs/editor-api.mdx | 10 +-
.../docs/editor-api/converting-blocks.mdx | 6 +-
.../docs/editor-api/manipulating-blocks.mdx | 47 +++---
.../manipulating-inline-content.mdx | 2 +-
docs/pages/docs/editor-basics.mdx | 5 +
docs/pages/docs/editor-basics/_meta.json | 6 +-
.../docs/editor-basics/content-structure.mdx | 134 ----------------
...t-content-types.mdx => default-schema.mdx} | 74 ++-------
.../docs/editor-basics/document-structure.mdx | 103 +++++++++++++
docs/pages/docs/editor-basics/editor.mdx | 143 ------------------
docs/pages/docs/editor-basics/setup.mdx | 135 +++++++++++++++++
docs/pages/docs/glossary.mdx | 18 ---
docs/pages/docs/index.mdx | 22 ++-
docs/pages/docs/quickstart.mdx | 35 +----
docs/pages/docs/styling-theming.mdx | 4 +-
.../docs/styling-theming/overriding-css.mdx | 22 ++-
docs/pages/docs/styling-theming/themes.mdx | 44 +++---
docs/pages/docs/ui-components.mdx | 43 +-----
.../docs/ui-components/suggestion-menus.mdx | 4 +-
examples/01-basic/02-block-objects/App.tsx | 6 +-
.../01-basic/03-block-manipulation/App.tsx | 8 +-
examples/01-basic/04-saving-loading/App.tsx | 2 +-
.../01-basic/inline-content-objects/App.tsx | 2 +-
.../suggestion-menus-slash-menu-items/App.tsx | 1 -
examples/05-custom-schema/font-style/App.tsx | 22 +--
.../01-converting-blocks-to-html/App.tsx | 2 +-
.../02-converting-blocks-from-html/App.tsx | 4 +-
.../03-converting-blocks-to-md/App.tsx | 2 +-
.../04-converting-blocks-from-md/App.tsx | 4 +-
.../blockManipulation.test.ts | 28 ++--
.../src/api/parsers/html/parseHTML.test.ts | 2 +-
packages/core/src/editor/BlockNoteEditor.ts | 15 +-
.../customblocks/TableOfContents.tsx.bak | 2 +-
36 files changed, 481 insertions(+), 609 deletions(-)
create mode 100644 docs/pages/docs/editor-basics.mdx
delete mode 100644 docs/pages/docs/editor-basics/content-structure.mdx
rename docs/pages/docs/editor-basics/{default-content-types.mdx => default-schema.mdx} (53%)
create mode 100644 docs/pages/docs/editor-basics/document-structure.mdx
delete mode 100644 docs/pages/docs/editor-basics/editor.mdx
create mode 100644 docs/pages/docs/editor-basics/setup.mdx
delete mode 100644 docs/pages/docs/glossary.mdx
diff --git a/docs/pages/docs/advanced/vanilla-js.mdx b/docs/pages/docs/advanced/vanilla-js.mdx
index 518ed18903..0921d07b11 100644
--- a/docs/pages/docs/advanced/vanilla-js.mdx
+++ b/docs/pages/docs/advanced/vanilla-js.mdx
@@ -12,7 +12,10 @@ import { Callout } from "nextra/components";
BlockNote is mainly designed as a quick and easy drop-in block-based editor for React apps, but can also be used in vanilla JavaScript apps. However, this does involve writing your own UI elements.
- We recommend using BlockNote with React so you can use the built-in UI components. This document will explain how you can use BlockNote without React, and write your own components, but this is not recommended as you'll lose the great out-of-the-box experience that BlockNote offers.
+ We recommend using BlockNote with React so you can use the built-in UI
+ components. This document will explain how you can use BlockNote without
+ React, and write your own components, but this is not recommended as you'll
+ lose the great out-of-the-box experience that BlockNote offers.
## Installing with NPM
@@ -25,19 +28,14 @@ npm install @blocknote/core
## Creating an editor
-TODO: AFAIK there is actually just no way of doing this anymore
-
This is how to create a new BlockNote editor:
-``` typescript
+```typescript
import { BlockNoteEditor } from "@blocknote/core";
-const editor = BlockNoteEditor.create({
- element: document.getElementById("root")!, // element to append the editor to
- onEditorContentChange: ({) => {
- console.log(editor.getJSON());
- }
-});
+const editor = BlockNoteEditor.create();
+
+editor.mount(document.getElementById("root")); // element to append the editor to
```
Now, you'll have a plain BlockNote instance on your page. However, it's missing some menus and other UI elements.
@@ -70,60 +68,58 @@ Let's look at how you could add the [Side Menu]() to your editor:
import { BlockNoteEditor } from "@blocknote/core";
const editor = BlockNoteEditor.create({
- element: document.getElementById("root")!
+ element: document.getElementById("root")!,
});
export function createButton(text: string, onClick?: () => void) {
- const element = document.createElement("a");
- element.href = "#";
- element.text = text;
- element.style.margin = "10px";
-
- if (onClick) {
- element.addEventListener("click", (e) => {
- onClick();
- e.preventDefault();
- });
- }
-
- return element;
+ const element = document.createElement("a");
+ element.href = "#";
+ element.text = text;
+ element.style.margin = "10px";
+
+ if (onClick) {
+ element.addEventListener("click", (e) => {
+ onClick();
+ e.preventDefault();
+ });
+ }
+
+ return element;
}
let element: HTMLElement;
editor.sideMenu.onUpdate((sideMenuState) => {
- if (!element) {
- element = document.createElement("div");
- element.style.background = "gray";
- element.style.position = "absolute";
- element.style.padding = "10px";
- element.style.opacity = "0.8";
- const addBtn = createButton("+", () => {
- editor.sideMenu.addBlock();
- });
- element.appendChild(addBtn);
-
- const dragBtn = createButton("::", () => {});
-
- dragBtn.addEventListener("dragstart", editor.sideMenu.blockDragStart);
- dragBtn.addEventListener("dragend", editor.sideMenu.blockDragEnd);
- dragBtn.draggable = true;
- element.style.display = "none";
- element.appendChild(dragBtn);
-
- document.getElementById("root")!.appendChild(element);
- }
-
- if (sideMenuState.show) {
- element.style.display = "block";
-
- element.style.top = sideMenuState.referencePos.top + "px";
- element.style.left =
- sideMenuState.referencePos.x - element.offsetWidth + "px";
- } else {
- element.style.display = "none";
- }
+ if (!element) {
+ element = document.createElement("div");
+ element.style.background = "gray";
+ element.style.position = "absolute";
+ element.style.padding = "10px";
+ element.style.opacity = "0.8";
+ const addBtn = createButton("+", () => {
+ editor.sideMenu.addBlock();
+ });
+ element.appendChild(addBtn);
+
+ const dragBtn = createButton("::", () => {});
+
+ dragBtn.addEventListener("dragstart", editor.sideMenu.blockDragStart);
+ dragBtn.addEventListener("dragend", editor.sideMenu.blockDragEnd);
+ dragBtn.draggable = true;
+ element.style.display = "none";
+ element.appendChild(dragBtn);
+
+ document.getElementById("root")!.appendChild(element);
+ }
+
+ if (sideMenuState.show) {
+ element.style.display = "block";
+
+ element.style.top = sideMenuState.referencePos.top + "px";
+ element.style.left =
+ sideMenuState.referencePos.x - element.offsetWidth + "px";
+ } else {
+ element.style.display = "none";
+ }
});
```
-
-TODO: Bring back vanilla example?
diff --git a/docs/pages/docs/custom-schemas.mdx b/docs/pages/docs/custom-schemas.mdx
index 700a40cdda..b83c34a1a6 100644
--- a/docs/pages/docs/custom-schemas.mdx
+++ b/docs/pages/docs/custom-schemas.mdx
@@ -5,7 +5,7 @@ description: Learn how to create custom schemas for your BlockNote editor
# Custom Schemas (advanced)
-By default, BlockNote documents support different kind of blocks, inline content and text styles. See xxxx.
+By default, BlockNote documents support different kind of blocks, inline content and text styles (see [default schema](/docs/editor-basics/default-schema)).
However, you can extend BlockNote and create custom schemas to support your own blocks, inline content and text styles.
## Custom Blocks
diff --git a/docs/pages/docs/custom-schemas/custom-styles.mdx b/docs/pages/docs/custom-schemas/custom-styles.mdx
index 7a2e79d55c..729d6415ce 100644
--- a/docs/pages/docs/custom-schemas/custom-styles.mdx
+++ b/docs/pages/docs/custom-schemas/custom-styles.mdx
@@ -20,19 +20,14 @@ function createReactStyleSpec(
Let's look at our custom font style from the demo, and go over each field to explain how it works:
```typescript
-const Mention = createReactStyleSpec(
+export const Font = createReactStyleSpec(
{
- type: "mention",
- propSchema: {
- user: {
- default: "Unknown",
- },
- },
- content: "none",
- } as const,
+ type: "font",
+ propSchema: "string",
+ },
{
render: (props) => (
- ...
+
),
}
);
@@ -57,7 +52,7 @@ Defines the identifier of the custom style.
The `PropSchema` specifies whether the style can only be toggled (`"boolean"`), or whether it can take a string value (`"string"`). Having a string value is useful for e.g. setting a color on the style.
-_In the font style demo, we set this to `"string"` so we can store the font name._
+_In the font style demo, we set this to `"string"` so we can store the font family._
#### Style Implementation (`ReactCustomStyleImplementation`)
@@ -78,9 +73,9 @@ This is your React component which defines how your custom style should be rende
`value:` The string value of the style, this is only available if your style config contains `propSchema: "string"`.
-`contentRef:` A React `ref` you can use to mark which element in your style is editable.
+`contentRef:` A React `ref` to mark the editable element.
-_Note that since styles are applied to text, you must set `contentRef` somewhere in you component, and should also return an HTML inline element._
+_Note that in contrast to Custom Blocks and Inline Content, the `render` function of Custom Styles cannot access React Context or other state. They should be plain React functions analogous to the example._
### Adding Custom Style to the Editor
diff --git a/docs/pages/docs/editor-api.mdx b/docs/pages/docs/editor-api.mdx
index b6fc4c620b..45cd273b96 100644
--- a/docs/pages/docs/editor-api.mdx
+++ b/docs/pages/docs/editor-api.mdx
@@ -1 +1,9 @@
-hello
\ No newline at end of file
+# Editor API
+
+BlockNote exposes an API to interact with the editor and its contents from code.
+These methods are directly available on the `BlockNoteEditor` object you created when instantiating your editor.
+
+- [Manipulating Blocks](/docs/editor-api/manipulating-blocks.md) explains how to read / update Blocks in the document.
+- [Manipulating Inline Content](/docs/editor-api/manipulating-inline-content.md) explains how to update / read data from selected text.
+- [Cursors & Selections](/docs/editor-api/cursor-selections) explains methods related to cursor positions and selections.
+- [Markdown & HTML](/docs/converting-blocks) explains how to convert the document to and from Markdown and HTML.
diff --git a/docs/pages/docs/editor-api/converting-blocks.mdx b/docs/pages/docs/editor-api/converting-blocks.mdx
index ce4fea298c..26f4b9fc95 100644
--- a/docs/pages/docs/editor-api/converting-blocks.mdx
+++ b/docs/pages/docs/editor-api/converting-blocks.mdx
@@ -10,15 +10,13 @@ import { Callout } from "nextra/components";
# Markdown & HTML
-TODO: use hooks in examples
-TODO: use examples with content
-
It's possible to export or import Blocks to and from Markdown and HTML.
The functions to import/export to and from Markdown/HTML are considered "lossy"; some information might be dropped when you export Blocks to those formats.
- To serialize Blocks to a non-lossy format (for example, to store the contents of the editor in your backend), simply export the built-in Block format using `JSON.stringify(editor.topLevelBlocks)`.
+ To serialize Blocks to a non-lossy format (for example, to store the contents of the editor in your backend), simply export the built-in Block format using `JSON.stringify(editor.document)`.
+
## Markdown
diff --git a/docs/pages/docs/editor-api/manipulating-blocks.mdx b/docs/pages/docs/editor-api/manipulating-blocks.mdx
index 3f9dc69f65..24b0dd63fa 100644
--- a/docs/pages/docs/editor-api/manipulating-blocks.mdx
+++ b/docs/pages/docs/editor-api/manipulating-blocks.mdx
@@ -9,17 +9,17 @@ path: /docs/manipulating-blocks
Below, we explain the methods on `editor` you can use to read Blocks from the editor, and how to create / remove / update Blocks:
-- [topLevelBlocks](/docs/editor-api/manipulating-blocks#getting-all-top-level-blocks)
-- [getBlock](/docs/editor-api/manipulating-blocks#getting-a-specific-block)
-- [forEachBlock](/docs/editor-api/manipulating-blocks#traversing-all-blocks)
-- [insertBlocks](/docs/editor-api/manipulating-blocks#inserting-new-blocks)
-- [updateBlock](/docs/editor-api/manipulating-blocks#updating-blocks)
-- [removeBlocks](/docs/editor-api/manipulating-blocks#removing-blocks)
-- [replaceBlocks](/docs/editor-api/manipulating-blocks#replacing-blocks)
-- [canNestBlock](/docs/editor-api/manipulating-blocks#nesting-blocks)
-- [nestBlock](/docs/editor-api/manipulating-blocks#nesting-blocks)
-- [canUnnestBlock](/docs/editor-api/manipulating-blocks#un-nesting-blocks)
-- [unnestBlock](/docs/editor-api/manipulating-blocks#un-nesting-blocks)
+- [`get document`](/docs/editor-api/manipulating-blocks#getting-the-document)
+- [`getBlock`](/docs/editor-api/manipulating-blocks#getting-a-specific-block)
+- [`forEachBlock`](/docs/editor-api/manipulating-blocks#traversing-all-blocks)
+- [`insertBlocks`](/docs/editor-api/manipulating-blocks#inserting-new-blocks)
+- [`updateBlock`](/docs/editor-api/manipulating-blocks#updating-blocks)
+- [`removeBlocks`](/docs/editor-api/manipulating-blocks#removing-blocks)
+- [`replaceBlocks`](/docs/editor-api/manipulating-blocks#replacing-blocks)
+- [`canNestBlock`](/docs/editor-api/manipulating-blocks#nesting-blocks)
+- [`nestBlock`](/docs/editor-api/manipulating-blocks#nesting-blocks)
+- [`canUnnestBlock`](/docs/editor-api/manipulating-blocks#un-nesting-blocks)
+- [`unnestBlock`](/docs/editor-api/manipulating-blocks#un-nesting-blocks)
## Common types
@@ -27,7 +27,7 @@ Before we dive into the methods, let's discuss some common types used in paramet
### Block Identifiers
-The methods to access, insert, update, remove, or replace blocks, can require a `BlockIdentifier` as reference to an existing block in the document.
+The methods to access, insert, update, remove, or replace blocks, can require a `BlockIdentifier` as reference to an existing block in the document.
This is either a `string` representing the block ID, or a `Block` object from which the ID is taken:
```typescript
@@ -36,7 +36,7 @@ type BlockIdentifier = string | Block;
### Partial Blocks
-When retrieving blocks from the editor, you always receive complete `Block` objects.
+When retrieving blocks from the editor, you always receive complete `Block` objects.
For updating or creating blocks, you don't need to pass all properties and you can use a `PartialBlock` type instead:
```typescript
@@ -51,25 +51,24 @@ type PartialBlock = {
`PartialBlock` objects are almost the same as regular `Block` objects, but with all members optional and partial `props`. This makes updating or creating simpler blocks much easier. We'll see this below.
-
## Accessing Blocks
There are a few different ways to retrieve Blocks from the editor:
-### Getting All Top-Level Blocks
+### Getting the Document
-Retrieve a snapshot of all top-level (non-nested) blocks in the editor using the following call:
+Retrieve a snapshot of the document (all top-level, non-nested blocks) in the editor using the following call:
```typescript
-topLevelBlocks: Block[];
+document: Block[];
// Usage
-const blocks = editor.topLevelBlocks;
+const blocks = editor.document;
```
`returns:` The document; a snapshot of all top-level (non-nested) blocks in the editor.
-We already used this for the [Editor Content in JSON](/docs/editor-basics/content-structure#editor-content-in-json) demo.
+We already used this for the [Editor Content in JSON](/docs/editor-basics/content-structure#editor-content-in-json) demo.
### Getting a Specific Block
@@ -129,7 +128,7 @@ editor.insertBlocks([{type: "paragraph", text: "Hello World"}], referenceBlock,
`placement:` Whether the blocks should be inserted just before, just after, or nested inside the `referenceBlock`. Inserts the blocks at the start of the existing block's children if `"nested"` is used.
-If a block's `id` is undefined, BlockNote generates one automatically.
+If a block's `id` is undefined, BlockNote generates one automatically.
The method throws an error if the reference block could not be found.
@@ -151,7 +150,7 @@ editor.updateBlock(blockToUpdate, { type: "paragraph" });
`update:` A [partial blocks](/docs/editor-api/manipulating-blocks#partial-blocks) which defines how the existing block should be changed.
-Since `blockToUpdate` is a `PartialBlock` object, some fields might not be defined. These undefined fields are kept as-is from the existing block.
+Since `blockToUpdate` is a `PartialBlock` object, some fields might not be defined. These undefined fields are kept as-is from the existing block.
Throws an error if the block to update could not be found.
@@ -190,7 +189,7 @@ editor.replaceBlocks(blocksToRemove, blocksToInsert)
`blocksToInsert:` An array of [partial blocks](/docs/editor-api/manipulating-blocks#partial-blocks) that the existing ones should be replaced with.
-If the blocks that should be removed are not adjacent or are at different nesting levels, `blocksToInsert` will be inserted at the position of the first block in `blocksToRemove`.
+If the blocks that should be removed are not adjacent or are at different nesting levels, `blocksToInsert` will be inserted at the position of the first block in `blocksToRemove`.
Throws an error if any of the blocks to remove could not be found.
@@ -200,7 +199,7 @@ BlockNote also provides functions to nest & un-nest the block containing the [Te
### Nesting Blocks
-TODO: this API seems different as it doesn't require a block id. should we make it possible to pass an identifier?
+{/* TODO: this API seems different as it doesn't require a block id. should we make it possible to pass an identifier? */}
Use `canNestBlock` to check whether the block containing the [Text Cursor](/docs/editor-api/cursor-selections#text-cursor) can be nested (i.e. if there is a block above it at the same nesting level):
@@ -238,4 +237,4 @@ unnestBlock(): void;
// Usage
editor.unnestBlock();
-```
\ No newline at end of file
+```
diff --git a/docs/pages/docs/editor-api/manipulating-inline-content.mdx b/docs/pages/docs/editor-api/manipulating-inline-content.mdx
index b0ead98c1d..0f90561e11 100644
--- a/docs/pages/docs/editor-api/manipulating-inline-content.mdx
+++ b/docs/pages/docs/editor-api/manipulating-inline-content.mdx
@@ -7,7 +7,7 @@ path: /docs/block-content
# Manipulating Inline Content
-While `InlineContent` objects are used to describe a block's content, they can be cumbersome to work with directly. Therefore, BlockNote exposes functions which make it easier to edit block contents.
+`BlockNoteEditor` exposes a number of functions to interact with the currently selected content.
## Accessing Styles
diff --git a/docs/pages/docs/editor-basics.mdx b/docs/pages/docs/editor-basics.mdx
new file mode 100644
index 0000000000..08889d9421
--- /dev/null
+++ b/docs/pages/docs/editor-basics.mdx
@@ -0,0 +1,5 @@
+# Editor basics
+
+In this section, we first explore the [methods to setup your editor](/docs/editor-basics/setup).
+Then, we'll dive into the structure of documents, Blocks and rich text content in BlockNote ([document structure](/docs/editor-basics/document-structure)).
+We'll also go over the blocks and content types that are part of BlockNote's [default built-in schema](/docs/editor-basics/default-schema).
diff --git a/docs/pages/docs/editor-basics/_meta.json b/docs/pages/docs/editor-basics/_meta.json
index 347454b190..56345dccb5 100644
--- a/docs/pages/docs/editor-basics/_meta.json
+++ b/docs/pages/docs/editor-basics/_meta.json
@@ -1,5 +1,5 @@
{
- "content-structure": "Content Structure",
- "default-content-types": "Default Content Types",
- "editor": "Editor Setup"
+ "setup": "Editor Setup",
+ "document-structure": "Document Structure",
+ "default-schema": "Default Schema"
}
diff --git a/docs/pages/docs/editor-basics/content-structure.mdx b/docs/pages/docs/editor-basics/content-structure.mdx
deleted file mode 100644
index 2b973f05c2..0000000000
--- a/docs/pages/docs/editor-basics/content-structure.mdx
+++ /dev/null
@@ -1,134 +0,0 @@
----
-title: Content Structure
-description: If you want to make the most out of BlockNote, it's important to understand how the editor's content is structured.
-imageTitle: Content Structure
----
-
-import { Example } from "@/components/example";
-
-# Content Structure
-
-If you want to make the most out of BlockNote, it's important to understand how the editor's content is structured.
-
-## Blocks
-
-Each BlockNote editor is made up of a list of blocks. A block - like a heading, paragraph, or list item - contains a piece of content and optionally nested blocks:
-
-
-
-### Block Objects
-
-In code, the `Block` type is used to describe any given block in the editor:
-
-```typescript
-type Block = {
- id: string;
- type: string;
- props: Record;
- content: InlineContent[] | TableContent | undefined;
- children: Block[];
-};
-```
-
-`id:` The block's ID. Multiple blocks cannot share a single ID, and a block will keep the same ID from when it's created until it's removed.
-
-`type:` The block's type, such as a paragraph, heading, or list item. For an overview of built-in block types, see [Default Blocks](/docs/editor-basics/default-content-types#default-blocks).
-
-`props:` The block's properties, which is a set of key/value pairs that further specify how the block looks and behaves. Different block types have different props - see [Default Blocks](/docs/editor-basics/default-content-types#default-blocks) for more.
-
-`content:` The block's rich text content, usually represented as an array of `InlineContent` objects. This does not include content from any nested blocks. Read on to [Inline Content](/docs/editor-basics/content-structure#inline-content) for more on this.
-
-`children:` Any blocks nested inside the block. The nested blocks are also represented using `Block` objects.
-
-### Editor Content in JSON
-
-The demo below shows how the editor content is represented in code - notice that it's in JSON as an array of `Block` objects.
-
-
-
-## Inline Content
-
-A block's content is referred to as inline content, and is used to represent rich text.
-
-TODO: Between custom & default inline content types, the shapes on inline content objects are not standardized.
-e.g. `Link`s have `href` and no props, custom IC will have props. `StyledText` can be IC itself, or used in other IC types.
-
-I think we should have smth like this:
-```typescript
-// Helper types
-type Styles = {
- bold: boolean;
- textColor: string;
- ...
-}
-
-// Inline Content types
-type StyledText = {
- type: "richText";
- props: {
- styles: Styles;
- }
- editable: true;
-}
-type Link = {
- type: "link";
- props: {
- styles: Styles;
- href: string;
- }
- editable: true;
-}
-type Mention = {
- type: "mention";
- props: {
- user: string;
- }
- editable: false;
-}
-```
-This is way cleaner, but means that links cannot have mixed styles. I think we either:
-- Convert links to styles (they're already marks in TipTap)
-- Not do anything bc I don't think having mixed styles on links is ever useful
-
-### Inline Content Objects
-
-In code, the `InlineContent` type is used to describe a piece of inline content:
-
-```typescript
-type InlineContent = {
- type: string;
- props: Record;
- editable: boolean;
-};
-```
-
-`type:` The inline content's type, such as a mention or styled text. For an overview of built-in inline content types, see [Default Inline Content](/docs/editor-basics/default-content-types#default-inline-content).
-
-`props:` The inline content's properties, which are stored in a set of key/value pairs and specify how the inline content looks and behaves. Different inline content types have different props - see [Default Inline Content](/docs/editor-basics/default-content-types#default-inline-content) for more.
-
-`editable`: Whether the inline content contains editable text.
-
-### Types of Block Content
-
-Most blocks will use an array of `InlineContent` objects to describe their content, such as paragraphs, headings and list items. Some blocks, like [images](/docs/editor-basics/default-content-types#image), don't contain any rich text content, so their `content` fields will be `undefined`.
-
-[Tables](/docs/editor-basics/default-content-types#table) are also different, as they contain `TableContent`. Here, each table cell is represented as an array of `InlineContent` objects:
-
-```typescript
-type TableContent = {
- type: "tableContent";
- rows: {
- cells: InlineContent[][];
- }[];
-};
-```
-
-### Block Content in JSON
-
-The demo below shows how the block content is represented in code by outputting only the `content` field of each top level block. As in the [previous demo](/docs/editor-basics/content-structure#editor-content-in-json), notice that it's in JSON.
-
-
\ No newline at end of file
diff --git a/docs/pages/docs/editor-basics/default-content-types.mdx b/docs/pages/docs/editor-basics/default-schema.mdx
similarity index 53%
rename from docs/pages/docs/editor-basics/default-content-types.mdx
rename to docs/pages/docs/editor-basics/default-schema.mdx
index 2c0fae1bb5..4f2cebf656 100644
--- a/docs/pages/docs/editor-basics/default-content-types.mdx
+++ b/docs/pages/docs/editor-basics/default-schema.mdx
@@ -8,24 +8,20 @@ import { Example } from "@/components/example";
# Default Content Types
-BlockNote supports a variety on built-in block and inline content types that are included in the editor by default. To create your own content types, see [Custom Schemas](/docs/custom-schemas).
+BlockNote supports a number of built-in blocks, inline content types, and styles that are included in the editor by default. This is called the Default Schema. To create your own content types, see [Custom Schemas](/docs/custom-schemas).
## Default Blocks
-BlockNote includes a number of built-in block types. The demo below contains each of them:
+Quickly explore the default blocks in this demo:
### Reference
-Here's an overview of all default blocks and the properties they support:
+Let's look more in-depth at the default blocks and the properties they support:
#### Paragraph
-**Appearance**
-
-
-
**Type & Props**
```typescript
@@ -40,10 +36,6 @@ type ParagraphBlock = {
#### Heading
-**Appearance**
-
-
-
**Type & Props**
```typescript
@@ -62,10 +54,6 @@ type HeadingBlock = {
#### Bullet List Item
-**Appearance**
-
-
-
**Type & Props**
```typescript
@@ -80,10 +68,6 @@ type BulletListItemBlock = {
#### Numbered List Item
-**Appearance**
-
-
-
**Type & Props**
```typescript
@@ -98,10 +82,6 @@ type NumberedListItemBlock = {
#### Image
-**Appearance**
-
-
-
**Type & Props**
```typescript
@@ -126,10 +106,6 @@ type ImageBlock = {
#### Table
-**Appearance**
-
-
-
**Type & Props**
```typescript
@@ -144,7 +120,7 @@ type TableBlock = {
### Default Block Properties
-There are some default block props that BlockNote uses for its default block types, and also exports for use in your own [custom blocks](/docs/custom-schemas/custom-blocks):
+There are some default block props that BlockNote uses for the built-in blocks:
```typescript
type DefaultProps = {
@@ -160,13 +136,9 @@ type DefaultProps = {
`textAlignment:` The text alignment of the block.
-### Creating New Block Types
-
-Skip to [Custom Blocks](/docs/custom-schemas/custom-blocks) to learn how to do this.
-
## Default Inline Content
-BlockNote includes a number of built-in inline content types. The demo editor below displays all of them:
+By default, `InlineContent` (the content of text blocks like paragraphs) in BlockNote can either be a `StyledText` or a `Link` object. Inspect them in the editor below:
@@ -179,15 +151,6 @@ Here's an overview of all default inline content and the properties they support
`StyledText` is a type of `InlineContent` used to display pieces of text with styles:
```typescript
-type Styles = {
- bold: true;
- italic: true;
- underline: true;
- strikethrough: true;
- textColor: string;
- backgroundColor: string;
-}
-
type StyledText = {
type: "text";
text: string;
@@ -207,31 +170,22 @@ type Link = {
};
```
-### Default Inline Content Properties
-
-TODO: This section only makes sense with the proposal in [Inline Content](/docs/editor-basics/content-structure#inline-content)
+## Default Styles
-There are some default inline content props that BlockNote uses for its default inline content types, and also exports for use in your own [custom inline content](/docs/custom-schemas/custom-inline-content):
+The default text formatting options in BlockNote are represented by the `Styles` in the default schema:
```typescript
type Styles = {
- bold: true;
- italic: true;
- underline: true;
- strikethrough: true;
+ bold: boolean;
+ italic: boolean;
+ underline: boolean;
+ strikethrough: boolean;
textColor: string;
backgroundColor: string;
-}
-
-type DefaultInlineContentProps = {
- styles: Styles
};
```
-`styles:` The text styles applied to the inline content. Only useful for editable inline content types.
-
-### Creating New Inline Content Types
-
-You can create your own custom inline content using React - skip to [Custom Inline Content](/docs/custom-schemas/custom-inline-content) to learn how to do this.
+## Creating New Block or Inline Content Types
-You can also create custom styles to apply to `StyledText` - skip to [Custom Styles](/docs/custom-schemas/custom-styles) to learn how to do this.
\ No newline at end of file
+You can also extend your editor and create your own Blocks, Inline Content or Styles using React.
+Skip to [Custom Schemas (advanced)](/docs/custom-schemas) to learn how to do this.
diff --git a/docs/pages/docs/editor-basics/document-structure.mdx b/docs/pages/docs/editor-basics/document-structure.mdx
new file mode 100644
index 0000000000..1cc95a1682
--- /dev/null
+++ b/docs/pages/docs/editor-basics/document-structure.mdx
@@ -0,0 +1,103 @@
+---
+description: Learn how documents (the content of the rich text editor) are structured to make the most out of BlockNote.
+---
+
+import { Example } from "@/components/example";
+
+# Document Structure
+
+Learn how documents (the content of the rich text editor) are structured to make the most out of BlockNote.
+
+## Blocks
+
+Each BlockNote document is made up of a list of blocks.
+A block is a piece of content like a paragraph, heading, list item or image. Blocks can be dragged around by users in the editor. A block contains a piece of content and optionally nested (child) blocks:
+
+
+
+### Block Objects
+
+The `Block` type is used to describe any given block in the editor:
+
+```typescript
+type Block = {
+ id: string;
+ type: string;
+ props: Record;
+ content: InlineContent[] | TableContent | undefined;
+ children: Block[];
+};
+```
+
+`id:` The block's ID. Multiple blocks cannot share a single ID, and a block will keep the same ID from when it's created until it's removed.
+
+`type:` The block's type, such as a paragraph, heading, or list item. For an overview of built-in block types, see [Default Blocks](/docs/editor-basics/default-content-types#default-blocks).
+
+`props:` The block's properties, which is a set of key/value pairs that further specify how the block looks and behaves. Different block types have different props - see [Default Blocks](/docs/editor-basics/default-content-types#default-blocks) for more.
+
+`content:` The block's rich text content, usually represented as an array of `InlineContent` objects. This does not include content from any nested blocks. Read on to [Inline Content](/docs/editor-basics/content-structure#inline-content) for more on this.
+
+`children:` Any blocks nested inside the block. The nested blocks are also represented using `Block` objects.
+
+### Editor Content in JSON
+
+The demo below shows the editor contents (document) in JSON. It's basically an array of `Block` objects that updates as you type in the editor:
+
+
+
+## Inline Content
+
+The `content` field of a block contains the rich-text content of a block. This is defined as an array of `InlineContent` objects. Inline content can either be styled text or a link (or a custom inline content type if you customize the editor schema).
+
+### Inline Content Objects
+
+The `InlineContent` type is used to describe a piece of inline content:
+
+```typescript
+type Link = {
+ type: "link";
+ content: StyledText[];
+ href: string;
+};
+
+type StyledText = {
+ type: "text";
+ text: string;
+ styles: Styles;
+};
+
+type InlineContent = Link | StyledText;
+```
+
+The `styles` property is explained below.
+
+### Other types of Block Content
+
+While most blocks use an array of `InlineContent` objects to describe their content (e.g.: paragraphs, headings, list items). Some blocks, like [images](/docs/editor-basics/default-content-types#image), don't contain any rich text content, so their `content` fields will be `undefined`.
+
+[Tables](/docs/editor-basics/default-content-types#table) are also different, as they contain `TableContent`. Here, each table cell is represented as an array of `InlineContent` objects:
+
+```typescript
+type TableContent = {
+ type: "tableContent";
+ rows: {
+ cells: InlineContent[][];
+ }[];
+};
+```
+
+## Styles and rich text
+
+The `styles` property of `StyledText` objects is used to describe the rich text styles (e.g.: bold, italic, color) or other attributes of a piece of text. It's a set of key / value pairs that specify the styles applied to the text.
+
+See the [Default Schema](/docs/editor-basics/default-schema) to learn which styles are included in BlockNote by default.
+
+## Demo: Block Content
+
+In the demo below, you can explore how the block content and styles are represented in JSON by outputting only the `content` field of each top level block.
+
+
diff --git a/docs/pages/docs/editor-basics/editor.mdx b/docs/pages/docs/editor-basics/editor.mdx
deleted file mode 100644
index b4080f12a1..0000000000
--- a/docs/pages/docs/editor-basics/editor.mdx
+++ /dev/null
@@ -1,143 +0,0 @@
----
-title: Editor Setup
-description: While BlockNote is ready to use out-of-the-box, there are a number of setup options you can choose to fit your use case.
-imageTitle: Editor Setup
-path: /docs/editor-basics/editor
----
-
-import { Example } from "@/components/example";
-
-TODO:
-[ ] expose / document hooks
-[ ] document events
-[ ] explain controlled / uncontrolled
-
-# Editor Setup
-
-While BlockNote is ready to use out-of-the-box, there are a number of setup options you can choose to fit your use case.
-
-## Creating the Editor
-
-### Using a React Hook
-
-Most of the time, you'll want to create the BlockNote editor using the `useCreateBlockNote` hook. This will create a new editor when your React component gets mounted, and accepts a dependency array as with other React hooks.
-
-```ts
-useCreateBlockNote = (
- options?: Partial,
- deps?: React.DependencyList,
-) => BlockNoteEditor;
-```
-
-Read on to [Options](/docs/editor-basics/editor#options) to see what options you can pass to the editor.
-
-### Using a Method
-
-You can also create a new editor using `BlockNoteEditor.create`. You should use this when you want to wait after your React component gets mounted before creating the editor.
-
-```ts
-BlockNoteEditor.create = (options?: Partial) =>
- BlockNoteEditor;
-```
-
-In the demo below, we use `BlockNoteEditor.create` so we can fetch the editor's initial content from `localStorage` before creating it.
-
-
-
-Read on to [Options](/docs/editor-basics/editor#options) to see what options you can pass to the editor.
-
-### Options
-
-There are a number of options that you can pass to `useCreateBlockNote()` and `BlockNoteEditor.create`. You can find the full list of these below:
-
-```typescript
-export type BlockNoteEditorOptions = Partial<{
- initialContent: PartialBlock[];
- domAttributes: Record;
- slashMenuItems: ReactSlashMenuItem[];
- defaultStyles: boolean;
- uploadFile: (file: File) => Promise;
- collaboration: CollaborationOptions;
- blockSpecs: BlockSpecs;
- inlineContentSpecs: InlineContentSpecs;
- styleSpecs: StyleSpecs;
-}>;
-```
-
-`initialContent:` The content that should be in the editor when it's created, represented as an array of [partial block objects](/docs/manipulating-blocks#partial-blocks).
-
-`domAttributes:` An object containing HTML attributes that should be added to various DOM elements in the editor. See [Adding DOM Attributes](/docs/theming#adding-dom-attributes) for more.
-
-`slashMenuItems:` The commands that are listed in the editor's [Slash Menu](/docs/slash-menu). If this option isn't defined, a default list of commands is loaded.
-
-`defaultStyles`: Whether to use the default font and reset the styles of `
`, `
`, `
`, etc. elements that are used in BlockNote. Defaults to true if undefined.
-
-`uploadFile`: A function which handles file uploads and eventually returns the URL to the uploaded file. Used by the [Image Toolbar](/docs/image-toolbar).
-
-`collaboration`: Options for enabling real-time collaboration. See [Collaboration](/docs/collaboration) for more info.
-
-`blockSpecs` (_advanced_): _advanced_ Specifications for Custom Blocks. See [Block Specs](/docs/block-specs) more info.
-
-`inlineContentSpecs` (_advanced_): Specifications for Custom Inline Content. See [Inline Content Specs](/docs/inline-content-specs) for more info.
-
-`styleSpecs` (_advanced_): Specifications for Custom Styles. See [Style Specs](/docs/style-specs) for more info.
-
-## Rendering the Editor
-
-### Using a React Component
-
-To, render the editor, you should use the `BlockNoteView` component, and pass in the editor created using `useCreateBlockNote` or `BlockNoteEditor.create`:
-
-```tsx
-const editor = useCreateBlockNote();
-
-return ;
-```
-
-### Props
-
-There are a number of additional props you can pass to `BlockNoteView`. You can find the full list of these below:
-
-```typescript
-export type BlockNoteViewProps = Partial<{
- formattingToolbar?: boolean;
- hyperlinkToolbar?: boolean;
- sideMenu?: boolean;
- slashMenu?: boolean;
- imageToolbar?: boolean;
- tableHandles?: boolean;
- theme:
- | "light"
- | "dark"
- | Theme
- | {
- light: Theme;
- dark: Theme;
- };
- editable?: boolean;
- onSelectionChange?: () => void;
- onChange?: () => void;
-}>;
-```
-
-`formattingToolbar`: Whether the [Formatting Toolbar](/docs/ui-components/formatting-toolbar) should be enabled.
-
-`hyperlinkToolbar`: Whether the Hyperlink Toolbar should be enabled.
-
-`sideMenu`: Whether the [Block Side Menu](/docs/ui-components/side-menu) should be enabled.
-
-`slashMenu`: Whether the [Slash Menu](/docs/ui-components/suggestion-menus#slash-menu) should be enabled.
-
-`imageToolbar`: Whether the Image Toolbar should be enabled.
-
-`tableHandles`: Whether the Table Handles should be enabled.
-
-`theme`: The editor's theme, see [Themes](/docs/styling-theming/themes) for more about this.
-
-`editable`: Whether the editor should be editable.
-
-`onSelectionChange`: Callback for when the editor selection changes.
-
-`onChange`: Callback for when the editor selection or content changes.
-
-`BlockNoteView` also takes props that you can pass to any HTML `div` element.
diff --git a/docs/pages/docs/editor-basics/setup.mdx b/docs/pages/docs/editor-basics/setup.mdx
new file mode 100644
index 0000000000..05a926253d
--- /dev/null
+++ b/docs/pages/docs/editor-basics/setup.mdx
@@ -0,0 +1,135 @@
+---
+description: Learn how to setup your BlockNote editor using the `useCreateBlockNote` hook and the ``BlockNoteView` component.
+---
+
+import { Example } from "@/components/example";
+import { Callout } from "nextra/components";
+
+# Editor Setup
+
+You can customize your editor when you instantiate it. Let's take a closer looks at the basic methods and components to set up your BlockNote editor.
+
+## `useCreateBlockNote` hook
+
+Create a new `BlockNoteEditor` by calling the `useCreateBlockNote` hook. This instantiates a new editor and its required state. You can later interact with the editor using the Editor API and pass it to the `BlockNoteView` component.
+
+```ts
+function useCreateBlockNote(
+ options?: BlockNoteEditorOptions,
+ deps?: React.DependencyList = [],
+): BlockNoteEditor;
+
+type BlockNoteEditorOptions = {
+ initialContent?: PartialBlock[];
+ domAttributes?: Record;
+ defaultStyles?: boolean;
+ uploadFile?: (file: File) => Promise;
+ collaboration?: CollaborationOptions;
+ schema?: BlockNoteSchema;
+};
+```
+
+The hook takes two optional parameters:
+
+**options:** An object containing options for the editor:
+
+`initialContent:` The content that should be in the editor when it's created, represented as an array of [partial block objects](/docs/manipulating-blocks#partial-blocks).
+
+`domAttributes:` An object containing HTML attributes that should be added to various DOM elements in the editor. See [Adding DOM Attributes](/docs/theming#adding-dom-attributes) for more.
+
+`defaultStyles`: Whether to use the default font and reset the styles of `
`, `
`, `
`, etc. elements that are used in BlockNote. Defaults to true if undefined.
+
+`uploadFile`: A function which handles file uploads and eventually returns the URL to the uploaded file. Used by the [Image Toolbar](/docs/image-toolbar). TODO
+
+`collaboration`: Options for enabling real-time collaboration. See [Collaboration](/docs/collaboration) for more info.
+
+`schema` (_advanced_): The editor schema if you want to extend your editor with custom blocks, styles, or inline content [Custom Schemas](/docs/custom-schemas).
+
+**deps:** Dependency array that's internally passed to `useMemo`. A new editor will only be created when this array changes.
+
+
+ Manually creating the editor (`BlockNoteEditor.create`)
+
+ The `useCreateBlockNote` hook is actually a simple `useMemo` wrapper around
+ the `BlockNoteEditor.create` method. You can use this method directly if you
+ want to control the editor lifecycle manually. For example, we do this in
+ the [Saving & Loading example](/examples/basic/saving-loading) to delay the
+ editor creation until some content has been fetched from an external data
+ source.
+
+
+
+## Rendering the Editor with ``
+
+Use the `` component to render the `BlockNoteEditor` instance you just created:
+
+```tsx
+const editor = useCreateBlockNote();
+
+return ;
+```
+
+### Props
+
+There are a number of additional props you can pass to `BlockNoteView`. You can find the full list of these below:
+
+```typescript
+export type BlockNoteViewProps = {
+ editor: BlockNoteEditor;
+ editable?: boolean;
+ onSelectionChange?: () => void;
+ onChange?: () => void;
+ theme?:
+ | "light"
+ | "dark"
+ | Theme
+ | {
+ light: Theme;
+ dark: Theme;
+ };
+ formattingToolbar?: boolean;
+ hyperlinkToolbar?: boolean;
+ sideMenu?: boolean;
+ slashMenu?: boolean;
+ imageToolbar?: boolean;
+ tableHandles?: boolean;
+ children?:
+} & HTMLAttributes;
+```
+
+`editor`: The `BlockNoteEditor` instance to render.
+
+`editable`: Whether the editor should be editable.
+
+`onSelectionChange`: Callback for when the editor selection changes.
+
+`onChange`: Callback for when the editor selection or content changes.
+
+`theme`: The editor's theme, see [Themes](/docs/styling-theming/themes) for more about this.
+
+`formattingToolbar`: Whether the [Formatting Toolbar](/docs/ui-components/formatting-toolbar) should be enabled.
+
+`hyperlinkToolbar`: Whether the Hyperlink Toolbar should be enabled.
+
+`sideMenu`: Whether the [Block Side Menu](/docs/ui-components/side-menu) should be enabled.
+
+`slashMenu`: Whether the [Slash Menu](/docs/ui-components/suggestion-menus#slash-menu) should be enabled.
+
+`imageToolbar`: Whether the Image Toolbar should be enabled.
+
+`tableHandles`: Whether the Table Handles should be enabled.
+
+`children`: Pass child elements to the `BlockNoteView` to create or customize toolbars, menus, or other UI components. See [UI Components](/docs/ui-components) for more.
+
+Additional props passed are forwarded to the HTML `div` element BlockNote renders internally.
+
+
+ Uncontrolled component
+
+ Note that the `BlockNoteView` component is an [uncontrolled component](https://react.dev/learn/sharing-state-between-components#controlled-and-uncontrolled-components).
+ This means you don't pass in the editor content directly as a prop. You can use the `initialContent` option in the `useCreateBlockNote` hook to set the initial content of the editor (similar to the `defaultValue` prop in a regular React `
+
+ BlockNote handles the complexities and performance optimizations of managing editor state internally. You can interact with the editor content using the [Editor API](/docs/editor-api).
+
+
diff --git a/docs/pages/docs/glossary.mdx b/docs/pages/docs/glossary.mdx
deleted file mode 100644
index fafdbe06dd..0000000000
--- a/docs/pages/docs/glossary.mdx
+++ /dev/null
@@ -1,18 +0,0 @@
----
-title: Glossary
-description: Getting started with BlockNote is quick and easy. All you need to do is install the package and add the React component to your app!
-imageTitle: Quickstart
-path: /docs/quickstart
----
-
-import { Callout } from "nextra/components";
-
-- _Editor_: TBD
-- _Document_: The document a user creates with BlockNote, which is a collection of blocks.
-- _Block_: A single unit of content in a document. Blocks can be text, images, headings, or other types of content. See [TODO]
-- _Block Content_: The content of a block, such as the text in a paragraph or the cells in a table. See [TODO]
-- _Styles_: The styles applied to a piece of rich text (`StyledText`), such as bold or italic text. See [TODO]
-- _Block Children_: The blocks that are nested inside another block (when the user presses `tab`, for example)
-- _UI Components_: TODO
-- _Cursor_: TODO
-- _Selection_: TODO
diff --git a/docs/pages/docs/index.mdx b/docs/pages/docs/index.mdx
index 27a0dcdf2e..c2819c0896 100644
--- a/docs/pages/docs/index.mdx
+++ b/docs/pages/docs/index.mdx
@@ -4,13 +4,7 @@ imageTitle: Introduction to BlockNote
path: /docs/introduction
---
-import {Example} from "@/components/example";
-
-TODO:
-- make shorter?
-- add "Main Features"? similar to nextjs
-- Remove example?
-- Add cards to bottom?
+import { Example } from "@/components/example";
# Introduction to BlockNote
@@ -18,24 +12,28 @@ TODO:
BlockNote is a block-based rich-text editor for [React](https://reactjs.org/), focused on providing a great out-of-the-box experience with minimal setup.
-With BlockNote, we want to make it easy for developers to add a next-generation text editing experience to their app, with a UX that's on-par with industry leaders like Notion or Coda.
-
-Unlike other rich-text editor libraries, BlockNote organizes documents into blocks, giving them a more rigid structure and making it easy to interact with the document from code.
+With BlockNote, we want to make it easy for developers to add a next-generation text editing experience to their app, with a UX that's on-par with industry leaders like Notion, Google Docs or Coda.
-Conceptually, you can think of a block as a paragraph, heading, image, or some other individual piece of content. Blocks can have more blocks nested inside of them, and can also be moved by dragging and dropping them inside or around each other.
+Unlike other rich-text editor libraries, BlockNote organizes documents into blocks. This makes it easy for the user to organize their document, and for developers to interact with the document from code.
BlockNote has been created with extensibility in mind. You can customize the document, create custom block types and customize UX elements like menu items. Advanced users can even create their own UI from scratch and use BlockNote with vanilla JavaScript instead of React.
+- Jump right into the [quickstart](/docs/quickstart) to get started
+- Learn about [blocks and the editor basics](/docs/editor-basics) and how to interact with the editor using the [editor API](/docs/editor-api)
+- See [UI Components](/docs/ui-components) to customize built-in menus and toolbars and [Styling & Theming](/docs/styling-theming) to customize the look and feel of the editor
+- Further extend the editor with your own Blocks using [Custom Schemas](/docs/custom-schemas) or add [Real-Time Collaboration](/docs/advanced/real-time-collaboration)
+
## Why BlockNote?
There are plenty of libraries out there for creating rich-text editors. In fact, BlockNote is built on top of the widely used [ProseMirror](https://prosemirror.net/) and [TipTap](https://tiptap.dev/).
-As powerful as they are, these libraries often have quite a steep learning-curve and require you to customize every single detail of your editor, and then you still need to add your own UI elements.
+As powerful as they are, these libraries often have quite a steep learning-curve and require you to customize every single detail of your editor. This can require months of specialized work.
BlockNote instead, offers a great experience with minimal setup, including a ready-made and animated UI.
On top of that, it comes with a modern block-based design. This gives documents more structure, allow for a richer user experience while simultaneously making it easier to customize the editor's functionality.
+
## Community
We'd love your feedback! If you have questions, need help, or want to contribute reach out to the community on [Discord](https://discord.gg/Qc2QTTH5dF) and [GitHub](https://github.com/TypeCellOS/BlockNote).
diff --git a/docs/pages/docs/quickstart.mdx b/docs/pages/docs/quickstart.mdx
index 99704896fa..605858e39d 100644
--- a/docs/pages/docs/quickstart.mdx
+++ b/docs/pages/docs/quickstart.mdx
@@ -24,20 +24,9 @@ npm install @blocknote/core @blocknote/react
With the `useCreateBlockNote` hook, we can create a new editor instance, then use the`BlockNoteView` component to render it. See below:
-```typescript jsx
-import { BlockNoteView, useCreateBlockNote } from "@blocknote/react";
-import "@blocknote/react/style.css";
-
-function App() {
- // Creates a new editor instance.
- const editor = useCreateBlockNote();
-
- // Renders the editor instance using a React component.
- return ;
-}
-```
+
-As well as `BlockNoteView` and `useCreateBlockNote`, we import `@blocknote/react/style.css` to provide default styling for the editor.
+We also import `@blocknote/react/style.css` to add default styling for the editor.
Next.js usage (or other server-side React frameworks)
@@ -57,24 +46,10 @@ As well as `BlockNoteView` and `useCreateBlockNote`, we import `@blocknote/react
-## Demo: Basic App Using BlockNote
-
-Taking the same code, the live preview below turns it into a super simple, working app:
-
-
-
## Next steps
You now know how to integrate BlockNote into your React app! However, this is just scratching the surface of what you can do with BlockNote.
-### Editor API
-
-TODO: Learn about how to interact with the editor, documents and blocks from code.
-
-### UI Components
-
-TODO: BlockNote comes with a default UI. Learn how to customize them, or create your own components.
-
-### Custom schemas
-
-TODO: A document consists of blocks, inline content and styles that the user can edit. Learn how to create your own Custom Blocks, inline content and styles.
+- Learn about [blocks and the editor basics](/docs/editor-basics) and how to interact with the editor using the [editor API](/docs/editor-api)
+- See [UI Components](/docs/ui-components) to customize built-in menus and toolbars and [Styling & Theming](/docs/styling-theming) to customize the look and feel of the editor
+- Further extend the editor with your own Blocks using [Custom Schemas](/docs/custom-schemas) or add [Real-Time Collaboration](/docs/advanced/real-time-collaboration)
diff --git a/docs/pages/docs/styling-theming.mdx b/docs/pages/docs/styling-theming.mdx
index 7108202571..9ea847fe42 100644
--- a/docs/pages/docs/styling-theming.mdx
+++ b/docs/pages/docs/styling-theming.mdx
@@ -7,4 +7,6 @@ path: /docs/styling-theming
# Styling & Theming
-You can completely change the look and feel of the BlockNote editor. Change basic styling quickly with theme CSS variables, or apply more complex styles with additional CSS rules. If you want to change, remove, or entirely replace the React components for menus & toolbars, see [UI Components](/docs/ui-components).
+You can completely change the look and feel of the BlockNote editor. Change basic styling quickly with [theme CSS variables](/docs/styling-theming/themes), or apply more complex styles with [additional CSS rules](/docs/styling-theming/overriding-css).
+
+If you want to change, remove, or entirely replace the React components for menus & toolbars, see [UI Components](/docs/ui-components).
diff --git a/docs/pages/docs/styling-theming/overriding-css.mdx b/docs/pages/docs/styling-theming/overriding-css.mdx
index b654b27a39..c0dfd4cd19 100644
--- a/docs/pages/docs/styling-theming/overriding-css.mdx
+++ b/docs/pages/docs/styling-theming/overriding-css.mdx
@@ -9,7 +9,27 @@ import { Example } from "@/components/example";
# Overriding CSS
-You can change any styles applied to the editor by adding your own CSS rules. If you just want to quickly change the basic look of the editor, [Themes](TODO) might be more useful.
+Within the editor's DOM structure, you'll find many elements have classes with the `bn-` prefix. BlockNote uses these to apply CSS styles to the editor, which you can override with your own. Here are some of the most useful BlockNote classes that you can use for your CSS rules:
+
+`bn-container`: Container element for the editor, as well as all menus and toolbars.
+
+`bn-editor`: Element for only the editor.
+
+`bn-block`: Element for a block, including nested blocks.
+
+`bn-group`: Container element for nested blocks.
+
+`bn-inline-content`: Element for a block's content.
+
+`bn-toolbar`: Element for the formatting & hyperlink toolbars.
+
+`bn-side-menu`: Element for the side menu.
+
+`bn-drag-handle-menu`: Element for the drag handle menu.
+
+`bn-slash-menu`: Element for the slash menu.
+
+Because BlockNote uses [Mantine](https://mantine.dev/) for its UI, you can also write CSS rules using any of the default Mantine component classes. To figure out what CSS selector you need to use to target a specific DOM element, it's easiest to just inspect the DOM tree using your browser's dev tools.
In the demo below, we create additional CSS rules to add some simple styling to the editor, and also make all hovered slash menu items blue:
diff --git a/docs/pages/docs/styling-theming/themes.mdx b/docs/pages/docs/styling-theming/themes.mdx
index 73c26d3d73..793a131620 100644
--- a/docs/pages/docs/styling-theming/themes.mdx
+++ b/docs/pages/docs/styling-theming/themes.mdx
@@ -18,22 +18,22 @@ A theme is made up of a set of CSS variables, which can be overwritten to change
Here are each of the theme CSS variables you can set, with values from the default light theme:
```
---bn-colors-editor-text: #3F3F3F;
---bn-colors-editor-background: #FFFFFF;
---bn-colors-menu-text: #3F3F3F;
---bn-colors-menu-background: #FFFFFF;
---bn-colors-tooltip-text: #3F3F3F;
---bn-colors-tooltip-background: #EFEFEF;
---bn-colors-hovered-text: #3F3F3F;
---bn-colors-hovered-background: #EFEFEF;
---bn-colors-selected-text: #FFFFFF;
---bn-colors-selected-background: #3F3F3F;
---bn-colors-disabled-text: #AFAFAF;
---bn-colors-disabled-background: #EFEFEF;
-
---bn-colors-shadow: #CFCFCF;
---bn-colors-border: #EFEFEF;
---bn-colors-side-menu: #CFCFCF;
+--bn-colors-editor-text: #3f3f3f;
+--bn-colors-editor-background: #ffffff;
+--bn-colors-menu-text: #3f3f3f;
+--bn-colors-menu-background: #ffffff;
+--bn-colors-tooltip-text: #3f3f3f;
+--bn-colors-tooltip-background: #efefef;
+--bn-colors-hovered-text: #3f3f3f;
+--bn-colors-hovered-background: #efefef;
+--bn-colors-selected-text: #ffffff;
+--bn-colors-selected-background: #3f3f3f;
+--bn-colors-disabled-text: #afafaf;
+--bn-colors-disabled-background: #efefef;
+
+--bn-colors-shadow: #cfcfcf;
+--bn-colors-border: #efefef;
+--bn-colors-side-menu: #cfcfcf;
--bn-colors-highlights-gray-text: #9b9a97;
--bn-colors-highlights-gray-background: #ebeced;
@@ -54,19 +54,21 @@ Here are each of the theme CSS variables you can set, with values from the defau
--bn-colors-highlights-pink-text: #ad1a72;
--bn-colors-highlights-pink-background: #f4dfeb;
---bn-font-family: "Inter", "SF Pro Display", -apple-system, BlinkMacSystemFont, "Open Sans", "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
+--bn-font-family: "Inter", "SF Pro Display", -apple-system, BlinkMacSystemFont, "Open Sans",
+ "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",
+ "Helvetica Neue", sans-serif;
--bn-border-radius: 6px;
```
-Setting these variables on the `.bn-container[data-color-scheme]` selector will overwrite them for both default light & dark themes. To overwrite variables separately for light & dark themes, use the `.bn-container[data-color-scheme="light"]` & `.bn-container[data-color-scheme="dark"]` selectors.
+Setting these variables on the `.bn-container[data-color-scheme]` selector will overwrite them for both default light & dark themes. To overwrite variables separately for light & dark themes, use the `.bn-container[data-color-scheme="light"]` and `.bn-container[data-color-scheme="dark"]` selectors.
-In the demo below, we set a red theme for the editor which changes based on if light or dark mode is selected:
+In the demo below, we set a red theme for the editor which changes based on if light or dark mode is selected (see this in action by changing the website theme in the footer):
## Changing CSS Variables Through Code
-You can also set the theme CSS variables using the `theme` prop in [`BlockNoteView`](TODO).Passing a `Theme` object will overwrite CSS variables for both light & dark themes with values from the object:
+You can also set the theme CSS variables using the `theme` prop in [`BlockNoteView`](/docs/editor-basics/setup#rendering-the-editor-with-blocknoteview). Passing a `Theme` object will overwrite CSS variables for both light & dark themes with values from the object:
```ts
type CombinedColor = Partial<{
@@ -119,4 +121,4 @@ In the demo below, we create the same red theme as from the previous demo, but t
### Forcing Light/Dark Mode
-By passing `"light"` or `"dark"` to the `theme` prop instead of a `Theme` object, you can also force BlockNote to always use the light or dark theme.
\ No newline at end of file
+By passing `"light"` or `"dark"` to the `theme` prop instead of a `Theme` object, you can also force BlockNote to always use the light or dark theme.
diff --git a/docs/pages/docs/ui-components.mdx b/docs/pages/docs/ui-components.mdx
index f447346909..135e1c3d8c 100644
--- a/docs/pages/docs/ui-components.mdx
+++ b/docs/pages/docs/ui-components.mdx
@@ -1,45 +1,16 @@
---
title: UI Components
-description: Along with the editor itself, BlockNote includes a few additional UI elements in the forms of menus and toolbars.
+description: BlockNote includes a number of UI Components (like menus and toolbars) that can be completely customized.
imageTitle: UI Components
path: /docs/ui-components
---
-# Changing UI Elements
+# Changing UI Components
-Along with the editor itself, BlockNote includes a few additional UI elements in the forms of menus and toolbars:
+BlockNote includes a number of UI Components (like menus and toolbars) that can be completely customized:
+- [Block Side Menu](/docs/side-menu)
- [Formatting Toolbar](/docs/formatting-toolbar)
-- Hyperlink Toolbar
-- [Slash Menu](/docs/slash-menu)
-- [Side Menu](/docs/side-menu)
-- [Image Toolbar](/docs/image-toolbar)
-
-By default, these are all included in the editor (TODO: see BlockNoteView), but you can remove or replace each of them with your own React components.
-
-User stories:
-
-As a developer, I want to:
-
-- Removing ui elements
-- changing the appearance / styling of some components
-- changing the appearance / styling of the editor itself
-- Adding a button to Menu X
-- Removing a button from Menu X
-- Adding items to Menu X
-- Reordering items in Menu X
-- Changing Formatting toolbar dropdown
-- Creating their own suggestions menu
-- Replace Menu X with my own component that uses my own UI library
-- I want to create a sticky formatting toolbar
-
-
-Menu X =
-- Formatting Toolbar
-- Hyperlink Toolbar
-- Slash Menu
-- Side Menu
-- Drag Handle menu
-- Image Toolbar
-
-
+- [Suggestion Menus](/docs/suggestion-menus)
+ {/* - Hyperlink Toolbar */}
+ {/* - [Image Toolbar](/docs/image-toolbar) */}
diff --git a/docs/pages/docs/ui-components/suggestion-menus.mdx b/docs/pages/docs/ui-components/suggestion-menus.mdx
index 5e14d74bd2..bd145e5c35 100644
--- a/docs/pages/docs/ui-components/suggestion-menus.mdx
+++ b/docs/pages/docs/ui-components/suggestion-menus.mdx
@@ -23,13 +23,13 @@ The Slash Menu is a Suggestion Menu that opens with the `/` character (or when c
### Changing Slash Menu Items
-You can change the items in the Slash Menu. The demo below adds an item that inserts a new block below, with "Hello World" in bold.
+You can change the items in the Slash Menu. The demo below adds an item that inserts a new block, with "Hello World" in bold.
Passing `slashMenu={false}` to `BlockNoteView` tells BlockNote not to show the default Slash Menu. Adding the `SuggestionMenuController` with `triggerCharacter={"/"}` and a custom `getItems` function tells BlockNote to show one with custom items instead.
-`getItems` should return the items that need to be shown in the Slash Menu, based on a `query` entered by the user (anything the user types after the `triggerCharacter`.
+`getItems` should return the items that need to be shown in the Slash Menu, based on a `query` entered by the user (anything the user types after the `triggerCharacter`).
### Replacing the Suggestion Menu Component
diff --git a/examples/01-basic/02-block-objects/App.tsx b/examples/01-basic/02-block-objects/App.tsx
index 1939ccdad2..c1a43dba6b 100644
--- a/examples/01-basic/02-block-objects/App.tsx
+++ b/examples/01-basic/02-block-objects/App.tsx
@@ -4,7 +4,7 @@ import "@blocknote/react/style.css";
import { useState } from "react";
export default function App() {
- // Stores the editor's contents as an array of Block objects.
+ // Stores the editor's contents (document) as an array of Block objects.
const [blocks, setBlocks] = useState([]);
// Creates a new editor instance.
const editor = useCreateBlockNote({
@@ -34,8 +34,8 @@ export default function App() {
{
- // Converts the editor's contents to an array of Block objects.
- setBlocks(editor.topLevelBlocks);
+ // Get the editor content (document) and store on the state.
+ setBlocks(editor.document);
}}
/>
Document JSON:
diff --git a/examples/01-basic/03-block-manipulation/App.tsx b/examples/01-basic/03-block-manipulation/App.tsx
index e02ef010b8..aaad3710e4 100644
--- a/examples/01-basic/03-block-manipulation/App.tsx
+++ b/examples/01-basic/03-block-manipulation/App.tsx
@@ -18,7 +18,7 @@ export default function App() {
new Date().toLocaleTimeString(),
},
],
- editor.topLevelBlocks[editor.topLevelBlocks.length - 1],
+ editor.document[editor.document.length - 1],
"after"
)
}>
@@ -27,7 +27,7 @@ export default function App() {
{/*Updates the currently selected block*/}
{/*Removes the currently selected block*/}
-