Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
f7f4c9e
build: apply zizmor recommended fixes (#2764)
nperez0111 May 21, 2026
118d8dc
chore: bump to latest pnpm
nperez0111 May 22, 2026
4a2d45a
fix: table cell colors (BLO-1198) (#2770)
matthewlipski May 26, 2026
ba4af09
chore: bump pnpm version
nperez0111 May 26, 2026
d609476
chore(release): publish 0.51.3
nperez0111 May 26, 2026
e4fb5c1
ci: add github-actions ecosystem to dependabot
nperez0111 May 28, 2026
9cbf2ad
fix(table): prevent crash when pressing Enter in a table cell (#2793)
y-temp4 May 29, 2026
f8b59e9
docs: remove private discord support (#2805)
YousefED Jun 1, 2026
faae3d5
fix: add explicit type annotations for callback params losing context…
nperez0111 Jun 1, 2026
8b3118f
fix(core): add editor cleanup in BlockNoteEditor.test.ts to prevent u…
nperez0111 Jun 1, 2026
e6493ee
fix: Comments emoji picker button issues (BLO-1199) (#2769)
matthewlipski Jun 2, 2026
3209491
chore(release): publish 0.51.4
nperez0111 Jun 2, 2026
e0c67af
chore: use pnpm@11.5.1
nperez0111 Jun 2, 2026
4f499f8
build: remove unused dependencies and bundle react-icons (#2796)
nperez0111 Jun 2, 2026
767a82f
feat: migrate to Vite+ (#2745)
matthewlipski Jun 3, 2026
ec9c151
test: migrate E2E tests to Vitest Browser Mode (#2800)
matthewlipski Jun 3, 2026
7399a46
fix: base nodeviews on current doc
nperez0111 Jun 8, 2026
7a89547
fix: align side menu to tables (BLO-1117) (#2837)
matthewlipski Jun 9, 2026
62f4570
fix: remove cursor flicker in trailing block (#2839)
matthewlipski Jun 9, 2026
a36e183
fix(table): guard stale block after changes for table handles (#2821)
satoren Jun 11, 2026
0f50a69
matchNodes demo
YousefED Jun 11, 2026
a2812ee
remove log from patch
YousefED Jun 11, 2026
33dcff6
feat: lie about suggested delete node's ids
nperez0111 Jun 11, 2026
cbb4e51
test: add lying id tests
nperez0111 Jun 11, 2026
9eacdf1
Merge remote-tracking branch 'origin/y-prosemirror-v14' into y-prosem…
YousefED Jun 11, 2026
c6143ef
fix: properly go into suggestion mode and edit suggestions mode
nperez0111 Jun 11, 2026
78e4f3e
Merge branch 'y-prosemirror-v14' into y-prosemirror-tests-matchnodes
nperez0111 Jun 12, 2026
a28f472
chore: improvements for agents (#2761)
matthewlipski Jun 15, 2026
bb6ead5
Merge remote-tracking branch 'origin/main' into decouple-yjs
nperez0111 Jun 15, 2026
4ea20f5
chore: disable import/no-cycle lint rule (pre-existing core cycles cr…
nperez0111 Jun 15, 2026
4793434
fix: clean up awareness change listener on YCursorExtension unmount
nperez0111 Jun 15, 2026
cb5d19a
Merge branch 'decouple-yjs' into y-prosemirror-v14
nperez0111 Jun 15, 2026
7ede846
Merge y-prosemirror-v14: combine @y/y v14 upgrade with vite-plus test…
nperez0111 Jun 15, 2026
e751408
Fix browserExpected.ts: use expect() for screenshot assertions
nperez0111 Jun 15, 2026
3efc4cd
test: update e2e tests
nperez0111 Jun 15, 2026
0747e5f
feat: some sort of demo
nperez0111 Jun 15, 2026
f05e53c
chore: update preload
nperez0111 Jun 15, 2026
7789e2e
fix: add output field to vp build tasks so cache restores dist files
nperez0111 Jun 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
72 changes: 72 additions & 0 deletions .claude/skills/create-example/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
name: create-example
description: Creates a new example under the `/examples` directory.
---

This skill provides instructions on how to create a BlockNote editor example correctly.

# Creating an example root directory

Under the `/examples` directory, each subdirectory is a category of examples. It's name consists of a 2 digit index, followed by a dash and the category name.

Each of these contains another set of subdirectories, where each one contains a single example. The naming of these is the same, but the category name is swapped for the example name.

Based on the user's prompt, the most relevant category should be chosen, and a new directory for the example should be created. The index in the example directory's name should be the lowest unused one to avoid large diffs from having to reorder & rename the existing example directories. It is very unlikely that a new category directory should need to be created for the new example, but it should use the same convention.

# Source & metadata files

## Source files

Any source files must be inside a `/src` directory at the root of the example directory. Within these, there must also be an `App.tsx` file, which default exports a React component. This component is responsible for rendering the entire example.

## Metadata files

There are two files containing metadata that must also be added at the root of the example directory:

`.bnexample.json`

Contains all of the example's configuration. Here's an annotated example (from `/examples/03-ui-components/13-custom-ui/.bnexample.json`):

```
<!-- Whether the example should be visible in the playground (i.e. when running `vp dev` in the project's root directory). This should default to `true` unless instructed otherwise. -->
"playground": true,
<!-- Whether the example should be visible on the BlockNote website. This should usually be `true`, unless the example is just for testing. -->
"docs": true,
<!-- The author's name. Can be left blank for the user to fill out. -->
"author": "matthewlipski",
<!-- Relevant tags for the example. Should aim to reuse ones from existing examples rather than creating new ones. -->
"tags": [
"Advanced",
"Inline Content",
"UI Components",
"Block Side Menu",
"Formatting Toolbar",
"Suggestion Menus",
"Slash Menu",
"Appearance & Styling"
],
<!-- NPM dependencies the source files rely on. -->
"dependencies": {
"@mui/icons-material": "^5.16.1",
"@mui/material": "^5.16.1"
},
<!-- Whether to hide the example behind a subscription on the BlockNote website. Default to `false` unless instructed otherwise. -->
"pro": true
```

`README.md`

A Markdown description of the example. Made of four parts:

1. Heading with the example name. This does not necessarily need to be the same as the example directory name and can be more verbose.
2. Description of the example, which should be no longer than a paragraph of three sentences.
3. An optional "Try me out!" callout. Should be a single sentence instructing the user how to see the changes made to the editor in the example.
4. A list of relevant docs. These are mostly internal but may also refer to e.g. dependencies used in the example.

See `/examples/07-collaboration/01-partykit` for reference on the exact markup of these sections.

# Generated files

Once the source & metadata files are done, `vp run gen` should be executed from the project root directory to auto-generate additional files in the example directory, as well as the playground & docs.

One of the generated files is `package.json` in the example directory. If the `bnexample.json` specified any dependencies, these will be included here. Therefore, `vp install` should always be executed in the project root directory after, to ensure these are installed.
70 changes: 70 additions & 0 deletions .claude/skills/debug-skill/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
name: debug-skill
description: Instructions for navigating and debugging BlockNote in a browser. Shows how to open specific menus & toolbars, as well select content. Should be used when prompted to fix a bug that requires inspecting the editor's appearance or rendered HTML.
---

# General loop

When fixing a bug, the following feedback loop should be used.

1. Apply a code change that you think will fix the issue.
2. Test the change in a browser environment.
3. Take screenshots to verify that the issue is fixed.
4. Repeat until the bug is indeed fixed.

# Browser environment

Before starting up a browser environment, you need to ensure the dev server is running. This can be done by checking if port 5173 is in use. If it isn't, running `vp run dev` at the project root will start the server.

The Playwright CLI should be used for the browser environment. It can be used to navigate to the dev server and programmatically issue mouse clicks/keyboard inputs. If not installed, stop what you're doing and notify the user to install it.

# Selecting an example

After navigating to `localhost:5173`, an example must be selected. These are listed in the navbar (`mantine-AppShell-navbar` CSS class). The "Default Schema Showcase" should be selected, unless stated otherwise by the user.

Each example will contain a BlockNote editor, and possibly additional elements like text fields or static toolbars.

# Editor HTML structure

Below is a list of elements that make up a BlockNote editor. This is helpful for mapping BlockNote concepts to what's actually visible in the browser. The nesting of the list items is representative of how the corresponding elements are nested in the rendered HTML. The elements are referenced by their main CSS class.

- `bn-container`: Wrapper element for the editor.
- `bn-editor`: Root element for the BlockNote editor.
- `bn-block-group`: Root container for blocks.
- `bn-block-outer`: Wrapper element for a block.
- `bn-block`: Root element for a block.
- `bn-block-content`: Container element for all content rendered by the block itself. Also renders a `data-content-type` attribute which stores the block's type, and additional `data-*` for every non-default prop that the block has.
- `bn-inline-content`: Container element for user-editable rich text within a block. Note that not all blocks will contain this element.
- `bn-block-group`: Container for nested blocks. Note that if a block doesn't contain nested blocks, it won't have this element.
- `bn-block-column-list`: Container element for columns.
- `bn-block-column`: Column element containing blocks.

Each element only appears once in its parent, except `bn-block-outer` and `bn-block-column-list`, which can appear multiple times.

Each `bn-block-group` and `bn-block-column` also contain `bn-block-outer` elements. These are not listed as they can be nested to an arbitrary depth.

Note that additional UI elements like menus and toolbars are mounted in a portal attached to the `body`.

# Keyboard navigation

Assume you are on a machine running macOS. You can use the following key combinations to navigate through the editor and create selections:

- Left/Right Arrow: Moves the text cursor back/forward one character.
- Up/Down Arrow: Moves the text cursor to the previous/next block.
- Option + Left/Right Arrow: Moves the text cursor to the start/end of the current word. If already at the start/end of a word, moves it to the start/end of the previous/next one instead.
- Cmd + Left/Right Arrow: Moves the text cursor to the start/end of the line.
- Cmd + Up/Down Arrow: Moves the text cursor to the start/end of the document.

Each of these can also be used with Shift to create/extend a selection instead of just moving the cursor.

It is extremely important to note that these key combinations are only relevant for debugging and NOT for writing end-to-end tests. While Playwright is used for both, tests run in a Linux environment which has different bindings for keyboard navigation.

# Opening menus & toolbars

Here are the most often used UI elements, and how to find/open them.

- **Formatting toolbar**: Create a selection using the keyboard and look for an element with the `bn-formatting-toolbar` CSS class. Buttons/dropdowns within it should be interacted with using the mouse instead. The `data-test` attribute will inform you what a given button or dropdown is for. Press escape to dismiss the toolbar.
- **Side menu**: Hover a block with the mouse, i.e. a `bn-block` element, and look for an element with the `bn-side-menu` CSS class. Unless specified otherwise, it contains a button to add a block ("Add block" ARIA label) and a drag handle which opens a menu on click ("Open block menu" ARIA label). Typing in the editor or moving the mouse cursor above/below it will hide the side menu, unless the drag handle menu is open. Then, it's "frozen" until dismissed by an outside click or pressing Escape.
- **Slash menu**: Type the "/" key while in a block and look for an element with the `bn-suggestion-menu` CSS class. It contains a list of items with the `bn-suggestion-menu-item` CSS class. While the menu is open, the up/down arrows navigate through items instead of moving the text cursor. Items can be triggered with a mouse click or pressing Enter while selected. Each item will convert the type of the current block to one of a given type, if it's empty. Otherwise, it will create a new block below with that type. The `bn-suggestion-menu-item-title` element's text content will indicate the new type. Pressing Escape closes the menu.
- **Link toolbar**: Hover a link in a block (anchor element within a `bn-inline-content` element), or move the text selection inside it using the arrow keys, and look for an element with the `bn-link-toolbar` CSS class. Unless specified otherwise, it contains three buttons. The first has the text, "Edit link". On click, it opens a popup to edit the link text and URL. You can locate these inputs with the "Edit title" and "Edit URL" placeholders. The other two buttons are for opening the link in a new tab ("Open in new tab" ARIA label) and deleting the link ("Remove link" ARIA label). If the toolbar was opened via mouse hover, moving the mouse off of the link or toolbar will close it after half a second. Otherwise, moving the text cursor outside the link will close the toolbar. It can also be dismissed by pressing Escape.
- **File panel**: After creating a file, image, video, or audio block, it will render a button with the text "Add file" (`bn-add-file-button` CSS class). Clicking the button will open the file panel. When the block is created using the slash menu (typically the case), the file panel will be open immediately. It always has an "Embed" tab (`data-test="embed-tab"` attribute). While this tab is selected, the file panel displays an input for the file URL ("Enter URL" placeholder) and "Embed file" button. For some examples, an "Upload" tab (`data-test="upload-tab"` attribute) will also be present. While it's selected, the file panel will display a file input (`data-test="upload-input"` attribute). After embedding/uploading a file, the block will render said file instead of displaying the "Add file" button.
Loading
Loading