From b89283f59d65fc2b57895e87f57a96853ffb88be Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Thu, 2 Apr 2026 15:10:58 +0200 Subject: [PATCH 01/11] Made inserting links not call `insertText` when text is the same --- packages/core/src/editor/managers/StyleManager.ts | 7 ++++++- packages/core/src/extensions/LinkToolbar/LinkToolbar.ts | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/core/src/editor/managers/StyleManager.ts b/packages/core/src/editor/managers/StyleManager.ts index e03c46a6d1..e8ffa99881 100644 --- a/packages/core/src/editor/managers/StyleManager.ts +++ b/packages/core/src/editor/managers/StyleManager.ts @@ -169,7 +169,12 @@ export class StyleManager< const { from, to } = tr.selection; if (text) { - tr.insertText(text, from, to).addMark(from, from + text.length, mark); + const existingText = tr.doc.textBetween(from, to); + if (text !== existingText) { + tr.insertText(text, from, to); + } + + tr.addMark(from, from + text.length, mark); } else { tr.setSelection(TextSelection.create(tr.doc, to)).addMark( from, diff --git a/packages/core/src/extensions/LinkToolbar/LinkToolbar.ts b/packages/core/src/extensions/LinkToolbar/LinkToolbar.ts index 1a61d67d44..f190bc97e6 100644 --- a/packages/core/src/extensions/LinkToolbar/LinkToolbar.ts +++ b/packages/core/src/extensions/LinkToolbar/LinkToolbar.ts @@ -88,7 +88,12 @@ export const LinkToolbarExtension = createExtension(({ editor }) => { if (!range) { return; } - tr.insertText(text, range.from, range.to); + + const existingText = tr.doc.textBetween(range.from, range.to); + if (text !== existingText) { + tr.insertText(text, range.from, range.to); + } + tr.addMark( range.from, range.from + text.length, From 5a7a186ad733577aad6776a2e7ded294a26aeb65 Mon Sep 17 00:00:00 2001 From: mianguyen Date: Sun, 5 Apr 2026 17:41:50 -0500 Subject: [PATCH 02/11] test: add e2e test for preserving marks when editing a link (#2573) --- .../linktoolbar/linktoolbar.test.ts | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 tests/src/end-to-end/linktoolbar/linktoolbar.test.ts diff --git a/tests/src/end-to-end/linktoolbar/linktoolbar.test.ts b/tests/src/end-to-end/linktoolbar/linktoolbar.test.ts new file mode 100644 index 0000000000..9a047f8f53 --- /dev/null +++ b/tests/src/end-to-end/linktoolbar/linktoolbar.test.ts @@ -0,0 +1,50 @@ +import { expect } from "@playwright/test"; +import { test } from "../../setup/setupScript.js"; +import { BASE_URL, LINK_BUTTON_SELECTOR } from "../../utils/const.js"; +import { focusOnEditor } from "../../utils/editor.js"; + +test.beforeEach(async ({ page }) => { + await page.goto(BASE_URL); +}); + +test.describe("Check Link Toolbar functionality", () => { + test("Should preserve existing marks when editing a link", async ({ + page, + }) => { + await focusOnEditor(page); + + // Type bold text + await page.keyboard.type("hello"); + await page.keyboard.press("Shift+Home"); + + // Make it bold via formatting toolbar + await page.waitForSelector(`[data-test="bold"]`); + await page.click(`[data-test="bold"]`); + + // Add link + await page.keyboard.press("Shift+Home"); + await page.waitForSelector(LINK_BUTTON_SELECTOR); + await page.click(LINK_BUTTON_SELECTOR); + await page.keyboard.type("https://example.com"); + await page.keyboard.press("Enter"); + + // Move cursor back onto the linked text to trigger link toolbar + await page.keyboard.press("ArrowLeft"); + await page.waitForTimeout(500); + + // Click Edit link button + const editButton = page.getByText("Edit link"); + await editButton.waitFor({ state: "visible" }); + await editButton.click(); + + await page.keyboard.press("Control+A"); + await page.keyboard.type("https://example2.com"); + await page.keyboard.press("Enter"); + + await page.waitForTimeout(300); + + // Verify bold mark is still present on the text + const boldText = page.locator("strong a, a strong"); + await expect(boldText).toBeVisible(); + }); +}); \ No newline at end of file From 17386a6b9a390456bc0d80feea14d1caf7be118e Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Tue, 14 Apr 2026 17:54:30 +0200 Subject: [PATCH 03/11] Fixed some comments UI issues, updated test and added comments testing example --- .../10-comments-testing/.bnexample.json | 9 +++ .../10-comments-testing/README.md | 3 + .../10-comments-testing/index.html | 14 ++++ .../10-comments-testing/main.tsx | 11 ++++ .../10-comments-testing/package.json | 32 +++++++++ .../10-comments-testing/src/App.tsx | 44 +++++++++++++ .../10-comments-testing/tsconfig.json | 36 ++++++++++ .../10-comments-testing/vite.config.ts | 32 +++++++++ packages/core/src/comments/extension.ts | 1 + .../components/Comments/FloatingComposer.tsx | 26 +++++++- playground/src/examples.gen.tsx | 24 +++++++ pnpm-lock.yaml | 65 ++++++++++++++++--- .../src/end-to-end/comments/comments.test.ts | 43 ++++++++++++ .../linktoolbar/linktoolbar.test.ts | 50 -------------- tests/src/utils/const.ts | 4 ++ 15 files changed, 334 insertions(+), 60 deletions(-) create mode 100644 examples/07-collaboration/10-comments-testing/.bnexample.json create mode 100644 examples/07-collaboration/10-comments-testing/README.md create mode 100644 examples/07-collaboration/10-comments-testing/index.html create mode 100644 examples/07-collaboration/10-comments-testing/main.tsx create mode 100644 examples/07-collaboration/10-comments-testing/package.json create mode 100644 examples/07-collaboration/10-comments-testing/src/App.tsx create mode 100644 examples/07-collaboration/10-comments-testing/tsconfig.json create mode 100644 examples/07-collaboration/10-comments-testing/vite.config.ts create mode 100644 tests/src/end-to-end/comments/comments.test.ts delete mode 100644 tests/src/end-to-end/linktoolbar/linktoolbar.test.ts diff --git a/examples/07-collaboration/10-comments-testing/.bnexample.json b/examples/07-collaboration/10-comments-testing/.bnexample.json new file mode 100644 index 0000000000..5d7d986420 --- /dev/null +++ b/examples/07-collaboration/10-comments-testing/.bnexample.json @@ -0,0 +1,9 @@ +{ + "playground": true, + "docs": false, + "author": "matthewlipski", + "tags": ["Advanced", "Comments", "Testing"], + "dependencies": { + "yjs": "^13.6.27" + } +} diff --git a/examples/07-collaboration/10-comments-testing/README.md b/examples/07-collaboration/10-comments-testing/README.md new file mode 100644 index 0000000000..b59f2ecd1b --- /dev/null +++ b/examples/07-collaboration/10-comments-testing/README.md @@ -0,0 +1,3 @@ +# Comments Testing + +A minimal comments example used for end-to-end testing. Uses a local Y.Doc (no collaboration provider) with a single hardcoded editor user. diff --git a/examples/07-collaboration/10-comments-testing/index.html b/examples/07-collaboration/10-comments-testing/index.html new file mode 100644 index 0000000000..f50976be79 --- /dev/null +++ b/examples/07-collaboration/10-comments-testing/index.html @@ -0,0 +1,14 @@ + + + + + Comments Testing + + + +
+ + + diff --git a/examples/07-collaboration/10-comments-testing/main.tsx b/examples/07-collaboration/10-comments-testing/main.tsx new file mode 100644 index 0000000000..677c7f7eed --- /dev/null +++ b/examples/07-collaboration/10-comments-testing/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 "./src/App.jsx"; + +const root = createRoot(document.getElementById("root")!); +root.render( + + + +); diff --git a/examples/07-collaboration/10-comments-testing/package.json b/examples/07-collaboration/10-comments-testing/package.json new file mode 100644 index 0000000000..6c4e09d1ae --- /dev/null +++ b/examples/07-collaboration/10-comments-testing/package.json @@ -0,0 +1,32 @@ +{ + "name": "@blocknote/example-collaboration-comments-testing", + "description": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY", + "type": "module", + "private": true, + "version": "0.12.4", + "scripts": { + "start": "vite", + "dev": "vite", + "build:prod": "tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@blocknote/ariakit": "latest", + "@blocknote/core": "latest", + "@blocknote/mantine": "latest", + "@blocknote/react": "latest", + "@blocknote/shadcn": "latest", + "@mantine/core": "^8.3.11", + "@mantine/hooks": "^8.3.11", + "@mantine/utils": "^6.0.22", + "react": "^19.2.3", + "react-dom": "^19.2.3", + "yjs": "^13.6.27" + }, + "devDependencies": { + "@types/react": "^19.2.3", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^4.7.0", + "vite": "^5.4.20" + } +} \ No newline at end of file diff --git a/examples/07-collaboration/10-comments-testing/src/App.tsx b/examples/07-collaboration/10-comments-testing/src/App.tsx new file mode 100644 index 0000000000..3bada358c1 --- /dev/null +++ b/examples/07-collaboration/10-comments-testing/src/App.tsx @@ -0,0 +1,44 @@ +"use client"; + +import { + CommentsExtension, + DefaultThreadStoreAuth, + YjsThreadStore, +} from "@blocknote/core/comments"; +import { BlockNoteView } from "@blocknote/mantine"; +import "@blocknote/mantine/style.css"; +import { useCreateBlockNote } from "@blocknote/react"; +import { useMemo } from "react"; +import * as Y from "yjs"; + +const USER = { + id: "1", + username: "John Doe", + avatarUrl: "https://placehold.co/100x100?text=John", + role: "editor" as const, +}; + +async function resolveUsers(userIds: string[]) { + return [USER].filter((user) => userIds.includes(user.id)); +} + +export default function App() { + const doc = useMemo(() => new Y.Doc(), []); + + const threadStore = useMemo(() => { + return new YjsThreadStore( + USER.id, + doc.getMap("threads"), + new DefaultThreadStoreAuth(USER.id, USER.role), + ); + }, [doc]); + + const editor = useCreateBlockNote( + { + extensions: [CommentsExtension({ threadStore, resolveUsers })], + }, + [threadStore], + ); + + return ; +} diff --git a/examples/07-collaboration/10-comments-testing/tsconfig.json b/examples/07-collaboration/10-comments-testing/tsconfig.json new file mode 100644 index 0000000000..dbe3e6f62d --- /dev/null +++ b/examples/07-collaboration/10-comments-testing/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": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + "composite": true + }, + "include": [ + "." + ], + "__ADD_FOR_LOCAL_DEV_references": [ + { + "path": "../../../packages/core/" + }, + { + "path": "../../../packages/react/" + } + ] +} \ No newline at end of file diff --git a/examples/07-collaboration/10-comments-testing/vite.config.ts b/examples/07-collaboration/10-comments-testing/vite.config.ts new file mode 100644 index 0000000000..f62ab20bc2 --- /dev/null +++ b/examples/07-collaboration/10-comments-testing/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/packages/core/src/comments/extension.ts b/packages/core/src/comments/extension.ts index 4e8e566cef..2e8632296d 100644 --- a/packages/core/src/comments/extension.ts +++ b/packages/core/src/comments/extension.ts @@ -306,6 +306,7 @@ export const CommentsExtension = createExtension( selectedThreadId: undefined, pendingComment: true, })); + editor.focus(); editor .getExtension(ShowSelectionExtension) ?.showSelection(true, "comments"); diff --git a/packages/react/src/components/Comments/FloatingComposer.tsx b/packages/react/src/components/Comments/FloatingComposer.tsx index 1cc72d634d..aa3e786dd9 100644 --- a/packages/react/src/components/Comments/FloatingComposer.tsx +++ b/packages/react/src/components/Comments/FloatingComposer.tsx @@ -1,4 +1,12 @@ -import { mergeCSSClasses } from "@blocknote/core"; +import { + BlockSchema, + DefaultBlockSchema, + DefaultInlineContentSchema, + DefaultStyleSchema, + InlineContentSchema, + mergeCSSClasses, + StyleSchema, +} from "@blocknote/core"; import { CommentsExtension } from "@blocknote/core/comments"; import { useComponentsContext } from "../../editor/ComponentsContext.js"; @@ -7,13 +15,21 @@ import { useExtension } from "../../hooks/useExtension.js"; import { useDictionary } from "../../i18n/dictionary.js"; import { CommentEditor } from "./CommentEditor.js"; import { defaultCommentEditorSchema } from "./defaultCommentEditorSchema.js"; +import { useBlockNoteEditor } from "../../hooks/useBlockNoteEditor.js"; +import { TextSelection } from "@tiptap/pm/state"; /** * The FloatingComposer component displays a comment editor "floating" card. * * It's used when the user highlights a parts of the document to create a new comment / thread. */ -export function FloatingComposer() { +export function FloatingComposer< + B extends BlockSchema = DefaultBlockSchema, + I extends InlineContentSchema = DefaultInlineContentSchema, + S extends StyleSchema = DefaultStyleSchema, +>() { + const editor = useBlockNoteEditor(); + const comments = useExtension(CommentsExtension); const Components = useComponentsContext()!; @@ -57,6 +73,12 @@ export function FloatingComposer() { }, }); comments.stopPendingComment(); + editor.transact((tr) => { + tr.setSelection( + TextSelection.create(tr.doc, tr.selection.to), + ); + }); + editor.focus(); }} > Save diff --git a/playground/src/examples.gen.tsx b/playground/src/examples.gen.tsx index 00a2e5afe5..ebe940400d 100644 --- a/playground/src/examples.gen.tsx +++ b/playground/src/examples.gen.tsx @@ -1687,6 +1687,30 @@ "slug": "collaboration" }, "readme": "In this example, we can fork a document and edit it independently of other collaborators. Then, we can choose to merge the changes back into the original document, or discard the changes.\n\n**Try it out:** Open this page in a new browser tab or window to see it in action!\n\n**Relevant Docs:**\n\n- [Editor Setup](/docs/getting-started/editor-setup)" + }, + { + "projectSlug": "comments-testing", + "fullSlug": "collaboration/comments-testing", + "pathFromRoot": "examples/07-collaboration/10-comments-testing", + "config": { + "playground": true, + "docs": false, + "author": "matthewlipski", + "tags": [ + "Advanced", + "Comments", + "Testing" + ], + "dependencies": { + "yjs": "^13.6.27" + } as any + }, + "title": "Comments Testing", + "group": { + "pathFromRoot": "examples/07-collaboration", + "slug": "collaboration" + }, + "readme": "A minimal comments example used for end-to-end testing. Uses a local Y.Doc (no collaboration provider) with a single hardcoded editor user." } ] }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5d3078f28a..70315f0ee6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4004,6 +4004,55 @@ importers: specifier: ^5.4.20 version: 5.4.21(@types/node@25.6.0)(lightningcss@1.32.0)(terser@5.46.1) + examples/07-collaboration/10-comments-testing: + dependencies: + '@blocknote/ariakit': + specifier: latest + version: link:../../../packages/ariakit + '@blocknote/core': + specifier: latest + version: link:../../../packages/core + '@blocknote/mantine': + specifier: latest + version: link:../../../packages/mantine + '@blocknote/react': + specifier: latest + version: link:../../../packages/react + '@blocknote/shadcn': + specifier: latest + version: link:../../../packages/shadcn + '@mantine/core': + specifier: ^8.3.11 + version: 8.3.18(@mantine/hooks@8.3.18(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@mantine/hooks': + specifier: ^8.3.11 + version: 8.3.18(react@19.2.4) + '@mantine/utils': + specifier: ^6.0.22 + version: 6.0.22(react@19.2.4) + react: + specifier: ^19.2.3 + version: 19.2.4 + react-dom: + specifier: ^19.2.3 + version: 19.2.4(react@19.2.4) + yjs: + specifier: ^13.6.27 + version: 13.6.30 + devDependencies: + '@types/react': + specifier: ^19.2.3 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.14) + '@vitejs/plugin-react': + specifier: ^4.7.0 + version: 4.7.0(vite@5.4.21(@types/node@25.6.0)(lightningcss@1.32.0)(terser@5.46.1)) + vite: + specifier: ^5.4.20 + version: 5.4.21(@types/node@25.6.0)(lightningcss@1.32.0)(terser@5.46.1) + examples/08-extensions/01-tiptap-arrow-conversion: dependencies: '@blocknote/ariakit': @@ -23889,8 +23938,8 @@ snapshots: '@next/eslint-plugin-next': 16.2.2 eslint: 9.39.4(jiti@2.6.1) eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@2.6.1)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-react: 7.37.5(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-react-hooks: 7.0.1(eslint@9.39.4(jiti@2.6.1)) @@ -23939,7 +23988,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@2.6.1)): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.3 @@ -23950,7 +23999,7 @@ snapshots: tinyglobby: 0.2.15 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.6.1)) transitivePeerDependencies: - supports-color @@ -23964,14 +24013,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.6.1)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.4(jiti@2.6.1) eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@2.6.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)) transitivePeerDependencies: - supports-color @@ -24012,7 +24061,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -24023,7 +24072,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.39.4(jiti@2.6.1) eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.6.1)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)))(eslint@9.39.4(jiti@2.6.1)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 diff --git a/tests/src/end-to-end/comments/comments.test.ts b/tests/src/end-to-end/comments/comments.test.ts new file mode 100644 index 0000000000..fd68d462ea --- /dev/null +++ b/tests/src/end-to-end/comments/comments.test.ts @@ -0,0 +1,43 @@ +import { expect } from "@playwright/test"; +import { test } from "../../setup/setupScript.js"; +import { COMMENTS_URL, LINK_BUTTON_SELECTOR } from "../../utils/const.js"; +import { focusOnEditor } from "../../utils/editor.js"; + +test.beforeEach(async ({ page }) => { + await page.goto(COMMENTS_URL); +}); + +test.describe("Check Comments functionality", () => { + test("Should preserve existing comments when adding a link", async ({ + page, + }) => { + await focusOnEditor(page); + + // Type text and select it + await page.keyboard.type("hello"); + await page.keyboard.press("Shift+Home"); + + await page.click('[data-test="addcomment"]'); + await page.waitForSelector(".bn-thread"); + + await page.keyboard.type("test comment"); + await page.click('button[data-test="save"]'); + + // Wait for the comment mark to appear on the text + await page.click("span.bn-thread-mark", { position: { x: 1, y: 1 } }); + + // Re-select the commented text by clicking at the start and shift-clicking + // at the end, staying within the editor + await page.keyboard.press("Shift+End"); + + // Add a link via the formatting toolbar + await page.waitForSelector(LINK_BUTTON_SELECTOR); + await page.click(LINK_BUTTON_SELECTOR); + await page.waitForSelector("input"); + + await page.keyboard.type("https://example.com"); + await page.keyboard.press("Enter"); + + await expect(await page.locator("span.bn-thread-mark")).toBeVisible(); + }); +}); diff --git a/tests/src/end-to-end/linktoolbar/linktoolbar.test.ts b/tests/src/end-to-end/linktoolbar/linktoolbar.test.ts deleted file mode 100644 index 9a047f8f53..0000000000 --- a/tests/src/end-to-end/linktoolbar/linktoolbar.test.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { expect } from "@playwright/test"; -import { test } from "../../setup/setupScript.js"; -import { BASE_URL, LINK_BUTTON_SELECTOR } from "../../utils/const.js"; -import { focusOnEditor } from "../../utils/editor.js"; - -test.beforeEach(async ({ page }) => { - await page.goto(BASE_URL); -}); - -test.describe("Check Link Toolbar functionality", () => { - test("Should preserve existing marks when editing a link", async ({ - page, - }) => { - await focusOnEditor(page); - - // Type bold text - await page.keyboard.type("hello"); - await page.keyboard.press("Shift+Home"); - - // Make it bold via formatting toolbar - await page.waitForSelector(`[data-test="bold"]`); - await page.click(`[data-test="bold"]`); - - // Add link - await page.keyboard.press("Shift+Home"); - await page.waitForSelector(LINK_BUTTON_SELECTOR); - await page.click(LINK_BUTTON_SELECTOR); - await page.keyboard.type("https://example.com"); - await page.keyboard.press("Enter"); - - // Move cursor back onto the linked text to trigger link toolbar - await page.keyboard.press("ArrowLeft"); - await page.waitForTimeout(500); - - // Click Edit link button - const editButton = page.getByText("Edit link"); - await editButton.waitFor({ state: "visible" }); - await editButton.click(); - - await page.keyboard.press("Control+A"); - await page.keyboard.type("https://example2.com"); - await page.keyboard.press("Enter"); - - await page.waitForTimeout(300); - - // Verify bold mark is still present on the text - const boldText = page.locator("strong a, a strong"); - await expect(boldText).toBeVisible(); - }); -}); \ No newline at end of file diff --git a/tests/src/utils/const.ts b/tests/src/utils/const.ts index 61cedc194d..b04b77d6a2 100644 --- a/tests/src/utils/const.ts +++ b/tests/src/utils/const.ts @@ -43,6 +43,10 @@ export const ALERT_BLOCK_URL = !process.env.RUN_IN_DOCKER ? `http://localhost:${PORT}/custom-schema/alert-block?hideMenu` : `http://host.docker.internal:${PORT}/custom-schema/alert-block?hideMenu`; +export const COMMENTS_URL = !process.env.RUN_IN_DOCKER + ? `http://localhost:${PORT}/collaboration/comments-testing?hideMenu` + : `http://host.docker.internal:${PORT}/collaboration/comments-testing?hideMenu`; + export const PASTE_ZONE_SELECTOR = "#pasteZone"; export const EDITOR_SELECTOR = `.bn-editor`; From 50fdda42afc1ff3cb85b723854d0f654e521d761 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Tue, 14 Apr 2026 18:09:49 +0200 Subject: [PATCH 04/11] Updated test --- tests/src/end-to-end/comments/comments.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/src/end-to-end/comments/comments.test.ts b/tests/src/end-to-end/comments/comments.test.ts index fd68d462ea..b7354cf616 100644 --- a/tests/src/end-to-end/comments/comments.test.ts +++ b/tests/src/end-to-end/comments/comments.test.ts @@ -33,7 +33,6 @@ test.describe("Check Comments functionality", () => { // Add a link via the formatting toolbar await page.waitForSelector(LINK_BUTTON_SELECTOR); await page.click(LINK_BUTTON_SELECTOR); - await page.waitForSelector("input"); await page.keyboard.type("https://example.com"); await page.keyboard.press("Enter"); From 437a7d366c9f18bcba78398dfecb1c98cb600c5b Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Tue, 14 Apr 2026 19:53:12 +0200 Subject: [PATCH 05/11] Fixed failing link toolbar tests --- tests/src/end-to-end/ariakit/ariakit.test.ts | 2 ++ tests/src/end-to-end/shadcn/shadcn.test.ts | 2 ++ tests/src/end-to-end/theming/theming.test.ts | 2 ++ 3 files changed, 6 insertions(+) diff --git a/tests/src/end-to-end/ariakit/ariakit.test.ts b/tests/src/end-to-end/ariakit/ariakit.test.ts index aa8c05c7d6..dd5fa0eccf 100644 --- a/tests/src/end-to-end/ariakit/ariakit.test.ts +++ b/tests/src/end-to-end/ariakit/ariakit.test.ts @@ -35,7 +35,9 @@ test.describe("Check Ariakit UI", () => { await page.keyboard.type("link"); await page.keyboard.press("Enter"); + await page.waitForTimeout(500); await page.keyboard.press("ArrowLeft"); + await page.keyboard.press("ArrowRight"); await page.waitForTimeout(500); expect(await page.screenshot()).toMatchSnapshot("ariakit-link-toolbar.png"); diff --git a/tests/src/end-to-end/shadcn/shadcn.test.ts b/tests/src/end-to-end/shadcn/shadcn.test.ts index c4a46ed8cc..fe1a2e385f 100644 --- a/tests/src/end-to-end/shadcn/shadcn.test.ts +++ b/tests/src/end-to-end/shadcn/shadcn.test.ts @@ -35,7 +35,9 @@ test.describe("Check ShadCN UI", () => { await page.keyboard.type("link"); await page.keyboard.press("Enter"); + await page.waitForTimeout(500); await page.keyboard.press("ArrowLeft"); + await page.keyboard.press("ArrowRight"); await page.waitForTimeout(700); expect(await page.screenshot()).toMatchSnapshot("shadcn-link-toolbar.png"); diff --git a/tests/src/end-to-end/theming/theming.test.ts b/tests/src/end-to-end/theming/theming.test.ts index 8bc75a6fab..1647cda1a9 100644 --- a/tests/src/end-to-end/theming/theming.test.ts +++ b/tests/src/end-to-end/theming/theming.test.ts @@ -46,7 +46,9 @@ test.describe("Check Dark Theme is Automatically Applied", () => { await page.waitForTimeout(500); await page.keyboard.type("link"); await page.keyboard.press("Enter"); + await page.waitForTimeout(500); await page.keyboard.press("ArrowLeft"); + await page.keyboard.press("ArrowRight"); await page.waitForTimeout(500); expect(await page.screenshot()).toMatchSnapshot("dark-link-toolbar.png"); From 46c0600026f77b5ba383bdb914622c8c3c9297b8 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Thu, 16 Apr 2026 20:11:34 +0200 Subject: [PATCH 06/11] Small fix --- packages/core/src/comments/extension.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/core/src/comments/extension.ts b/packages/core/src/comments/extension.ts index 2e8632296d..515a740c34 100644 --- a/packages/core/src/comments/extension.ts +++ b/packages/core/src/comments/extension.ts @@ -306,7 +306,11 @@ export const CommentsExtension = createExtension( selectedThreadId: undefined, pendingComment: true, })); - editor.focus(); + // Use `editor.domElement` as `editor.focus()` doesn't do anything if + // the editor is non-editable. Editor needs to be focused as + // `showSelection` will otherwise trigger a selection update which + // triggers `stopPendingComment`. + editor.domElement?.focus(); editor .getExtension(ShowSelectionExtension) ?.showSelection(true, "comments"); From 82c59718b91a609a63aab1ae8ede2e899106bcbd Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Mon, 20 Apr 2026 16:04:14 +0200 Subject: [PATCH 07/11] Implemented PR feedback --- tests/src/end-to-end/comments/comments.test.ts | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/tests/src/end-to-end/comments/comments.test.ts b/tests/src/end-to-end/comments/comments.test.ts index b7354cf616..db29498359 100644 --- a/tests/src/end-to-end/comments/comments.test.ts +++ b/tests/src/end-to-end/comments/comments.test.ts @@ -13,9 +13,8 @@ test.describe("Check Comments functionality", () => { }) => { await focusOnEditor(page); - // Type text and select it await page.keyboard.type("hello"); - await page.keyboard.press("Shift+Home"); + await page.locator("text=hello").dblclick(); await page.click('[data-test="addcomment"]'); await page.waitForSelector(".bn-thread"); @@ -23,15 +22,9 @@ test.describe("Check Comments functionality", () => { await page.keyboard.type("test comment"); await page.click('button[data-test="save"]'); - // Wait for the comment mark to appear on the text - await page.click("span.bn-thread-mark", { position: { x: 1, y: 1 } }); + await page.locator("span.bn-thread-mark").first().dblclick(); - // Re-select the commented text by clicking at the start and shift-clicking - // at the end, staying within the editor - await page.keyboard.press("Shift+End"); - - // Add a link via the formatting toolbar - await page.waitForSelector(LINK_BUTTON_SELECTOR); + await expect(page.locator(LINK_BUTTON_SELECTOR)).toBeVisible(); await page.click(LINK_BUTTON_SELECTOR); await page.keyboard.type("https://example.com"); From 3543c94da88dd342e514e1afc58bfd6813bcc682 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Mon, 20 Apr 2026 16:39:46 +0200 Subject: [PATCH 08/11] Fixed example generated `package.json` files --- docs/package.json | 2 +- examples/01-basic/03-multi-column/package.json | 4 ++-- examples/02-backend/03-s3/package.json | 6 +++--- .../04-rendering-static-documents/package.json | 4 ++-- .../03-ui-components/11-uppy-file-panel/package.json | 4 ++-- examples/03-ui-components/13-custom-ui/package.json | 6 +++--- examples/04-theming/06-code-block/package.json | 4 ++-- .../04-theming/07-custom-code-block/.bnexample.json | 10 +++++----- examples/04-theming/07-custom-code-block/package.json | 10 +++++----- .../05-converting-blocks-to-pdf/package.json | 8 ++++---- .../06-converting-blocks-to-docx/package.json | 6 +++--- .../07-converting-blocks-to-odt/package.json | 6 +++--- .../08-converting-blocks-to-react-email/package.json | 6 +++--- examples/07-collaboration/02-liveblocks/package.json | 10 +++++----- examples/07-collaboration/03-y-sweet/package.json | 4 ++-- examples/07-collaboration/05-comments/package.json | 4 ++-- .../07-collaboration/10-comments-testing/package.json | 4 ++-- .../01-tiptap-arrow-conversion/package.json | 4 ++-- examples/09-ai/01-minimal/package.json | 6 +++--- examples/09-ai/02-playground/package.json | 6 +++--- examples/09-ai/03-custom-ai-menu-items/package.json | 4 ++-- examples/09-ai/04-with-collaboration/package.json | 4 ++-- examples/09-ai/05-manual-execution/package.json | 4 ++-- examples/09-ai/06-client-side-transport/package.json | 8 ++++---- examples/09-ai/07-server-persistence/package.json | 6 +++--- .../examples/template-react/package.json.template.tsx | 4 ++-- playground/src/examples.gen.tsx | 10 +++++----- 27 files changed, 77 insertions(+), 77 deletions(-) diff --git a/docs/package.json b/docs/package.json index 0ffbc251cc..bcd31a57ea 100644 --- a/docs/package.json +++ b/docs/package.json @@ -131,4 +131,4 @@ "tw-animate-css": "^1.4.0", "typescript": "^5.9.3" } -} +} \ No newline at end of file diff --git a/examples/01-basic/03-multi-column/package.json b/examples/01-basic/03-multi-column/package.json index 482c7409d8..590b6adc07 100644 --- a/examples/01-basic/03-multi-column/package.json +++ b/examples/01-basic/03-multi-column/package.json @@ -16,12 +16,12 @@ "@blocknote/mantine": "latest", "@blocknote/react": "latest", "@blocknote/shadcn": "latest", - "@blocknote/xl-multi-column": "latest", "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", "react": "^19.2.3", - "react-dom": "^19.2.3" + "react-dom": "^19.2.3", + "@blocknote/xl-multi-column": "latest" }, "devDependencies": { "@types/react": "^19.2.3", diff --git a/examples/02-backend/03-s3/package.json b/examples/02-backend/03-s3/package.json index 32f939f061..2c2c249b08 100644 --- a/examples/02-backend/03-s3/package.json +++ b/examples/02-backend/03-s3/package.json @@ -11,8 +11,6 @@ "preview": "vite preview" }, "dependencies": { - "@aws-sdk/client-s3": "^3.609.0", - "@aws-sdk/s3-request-presigner": "^3.609.0", "@blocknote/ariakit": "latest", "@blocknote/core": "latest", "@blocknote/mantine": "latest", @@ -22,7 +20,9 @@ "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", "react": "^19.2.3", - "react-dom": "^19.2.3" + "react-dom": "^19.2.3", + "@aws-sdk/client-s3": "^3.609.0", + "@aws-sdk/s3-request-presigner": "^3.609.0" }, "devDependencies": { "@types/react": "^19.2.3", diff --git a/examples/02-backend/04-rendering-static-documents/package.json b/examples/02-backend/04-rendering-static-documents/package.json index 14c1dd6aa7..41aeab8c5c 100644 --- a/examples/02-backend/04-rendering-static-documents/package.json +++ b/examples/02-backend/04-rendering-static-documents/package.json @@ -15,13 +15,13 @@ "@blocknote/core": "latest", "@blocknote/mantine": "latest", "@blocknote/react": "latest", - "@blocknote/server-util": "latest", "@blocknote/shadcn": "latest", "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", "react": "^19.2.3", - "react-dom": "^19.2.3" + "react-dom": "^19.2.3", + "@blocknote/server-util": "latest" }, "devDependencies": { "@types/react": "^19.2.3", diff --git a/examples/03-ui-components/11-uppy-file-panel/package.json b/examples/03-ui-components/11-uppy-file-panel/package.json index d65faa9792..5523df0951 100644 --- a/examples/03-ui-components/11-uppy-file-panel/package.json +++ b/examples/03-ui-components/11-uppy-file-panel/package.json @@ -19,6 +19,8 @@ "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", + "react": "^19.2.3", + "react-dom": "^19.2.3", "@uppy/core": "^3.13.1", "@uppy/dashboard": "^3.9.1", "@uppy/drag-drop": "^3.1.1", @@ -30,8 +32,6 @@ "@uppy/status-bar": "^3.1.1", "@uppy/webcam": "^3.4.2", "@uppy/xhr-upload": "^3.4.0", - "react": "^19.2.3", - "react-dom": "^19.2.3", "react-icons": "^5.5.0" }, "devDependencies": { diff --git a/examples/03-ui-components/13-custom-ui/package.json b/examples/03-ui-components/13-custom-ui/package.json index 1c45dea04a..97585870e0 100644 --- a/examples/03-ui-components/13-custom-ui/package.json +++ b/examples/03-ui-components/13-custom-ui/package.json @@ -19,10 +19,10 @@ "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", - "@mui/icons-material": "^5.16.1", - "@mui/material": "^5.16.1", "react": "^19.2.3", - "react-dom": "^19.2.3" + "react-dom": "^19.2.3", + "@mui/icons-material": "^5.16.1", + "@mui/material": "^5.16.1" }, "devDependencies": { "@types/react": "^19.2.3", diff --git a/examples/04-theming/06-code-block/package.json b/examples/04-theming/06-code-block/package.json index dd4d7472f5..037641e740 100644 --- a/examples/04-theming/06-code-block/package.json +++ b/examples/04-theming/06-code-block/package.json @@ -12,7 +12,6 @@ }, "dependencies": { "@blocknote/ariakit": "latest", - "@blocknote/code-block": "latest", "@blocknote/core": "latest", "@blocknote/mantine": "latest", "@blocknote/react": "latest", @@ -21,7 +20,8 @@ "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", "react": "^19.2.3", - "react-dom": "^19.2.3" + "react-dom": "^19.2.3", + "@blocknote/code-block": "latest" }, "devDependencies": { "@types/react": "^19.2.3", diff --git a/examples/04-theming/07-custom-code-block/.bnexample.json b/examples/04-theming/07-custom-code-block/.bnexample.json index 5776d2de67..84166710e3 100644 --- a/examples/04-theming/07-custom-code-block/.bnexample.json +++ b/examples/04-theming/07-custom-code-block/.bnexample.json @@ -5,10 +5,10 @@ "tags": ["Basic"], "dependencies": { "@blocknote/code-block": "latest", - "@shikijs/core": "^3.19.0", - "@shikijs/engine-javascript": "^3.19.0", - "@shikijs/langs-precompiled": "^3.19.0", - "@shikijs/themes": "^3.19.0", - "@shikijs/types": "^3.19.0" + "@shikijs/core": "^4", + "@shikijs/engine-javascript": "^4", + "@shikijs/langs-precompiled": "^4", + "@shikijs/themes": "^4", + "@shikijs/types": "^4" } } diff --git a/examples/04-theming/07-custom-code-block/package.json b/examples/04-theming/07-custom-code-block/package.json index df3d173512..d381ab18f1 100644 --- a/examples/04-theming/07-custom-code-block/package.json +++ b/examples/04-theming/07-custom-code-block/package.json @@ -12,7 +12,6 @@ }, "dependencies": { "@blocknote/ariakit": "latest", - "@blocknote/code-block": "latest", "@blocknote/core": "latest", "@blocknote/mantine": "latest", "@blocknote/react": "latest", @@ -20,13 +19,14 @@ "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", + "react": "^19.2.3", + "react-dom": "^19.2.3", + "@blocknote/code-block": "latest", "@shikijs/core": "^4", "@shikijs/engine-javascript": "^4", "@shikijs/langs-precompiled": "^4", "@shikijs/themes": "^4", - "@shikijs/types": "^4", - "react": "^19.2.3", - "react-dom": "^19.2.3" + "@shikijs/types": "^4" }, "devDependencies": { "@types/react": "^19.2.3", @@ -34,4 +34,4 @@ "@vitejs/plugin-react": "^6.0.1", "vite": "^8.0.8" } -} +} \ No newline at end of file diff --git a/examples/05-interoperability/05-converting-blocks-to-pdf/package.json b/examples/05-interoperability/05-converting-blocks-to-pdf/package.json index a470b3892e..f402e292d7 100644 --- a/examples/05-interoperability/05-converting-blocks-to-pdf/package.json +++ b/examples/05-interoperability/05-converting-blocks-to-pdf/package.json @@ -16,14 +16,14 @@ "@blocknote/mantine": "latest", "@blocknote/react": "latest", "@blocknote/shadcn": "latest", - "@blocknote/xl-multi-column": "latest", - "@blocknote/xl-pdf-exporter": "latest", "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", - "@react-pdf/renderer": "^4.3.0", "react": "^19.2.3", - "react-dom": "^19.2.3" + "react-dom": "^19.2.3", + "@blocknote/xl-pdf-exporter": "latest", + "@blocknote/xl-multi-column": "latest", + "@react-pdf/renderer": "^4.3.0" }, "devDependencies": { "@types/react": "^19.2.3", diff --git a/examples/05-interoperability/06-converting-blocks-to-docx/package.json b/examples/05-interoperability/06-converting-blocks-to-docx/package.json index dead9892bb..9f29639db1 100644 --- a/examples/05-interoperability/06-converting-blocks-to-docx/package.json +++ b/examples/05-interoperability/06-converting-blocks-to-docx/package.json @@ -16,13 +16,13 @@ "@blocknote/mantine": "latest", "@blocknote/react": "latest", "@blocknote/shadcn": "latest", - "@blocknote/xl-docx-exporter": "latest", - "@blocknote/xl-multi-column": "latest", "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", "react": "^19.2.3", - "react-dom": "^19.2.3" + "react-dom": "^19.2.3", + "@blocknote/xl-docx-exporter": "latest", + "@blocknote/xl-multi-column": "latest" }, "devDependencies": { "@types/react": "^19.2.3", diff --git a/examples/05-interoperability/07-converting-blocks-to-odt/package.json b/examples/05-interoperability/07-converting-blocks-to-odt/package.json index afc26ae220..4c30dd0d65 100644 --- a/examples/05-interoperability/07-converting-blocks-to-odt/package.json +++ b/examples/05-interoperability/07-converting-blocks-to-odt/package.json @@ -16,13 +16,13 @@ "@blocknote/mantine": "latest", "@blocknote/react": "latest", "@blocknote/shadcn": "latest", - "@blocknote/xl-multi-column": "latest", - "@blocknote/xl-odt-exporter": "latest", "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", "react": "^19.2.3", - "react-dom": "^19.2.3" + "react-dom": "^19.2.3", + "@blocknote/xl-odt-exporter": "latest", + "@blocknote/xl-multi-column": "latest" }, "devDependencies": { "@types/react": "^19.2.3", diff --git a/examples/05-interoperability/08-converting-blocks-to-react-email/package.json b/examples/05-interoperability/08-converting-blocks-to-react-email/package.json index d5a60f1f1e..15b4292fd7 100644 --- a/examples/05-interoperability/08-converting-blocks-to-react-email/package.json +++ b/examples/05-interoperability/08-converting-blocks-to-react-email/package.json @@ -16,13 +16,13 @@ "@blocknote/mantine": "latest", "@blocknote/react": "latest", "@blocknote/shadcn": "latest", - "@blocknote/xl-email-exporter": "latest", "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", - "@react-email/render": "^2.0.4", "react": "^19.2.3", - "react-dom": "^19.2.3" + "react-dom": "^19.2.3", + "@blocknote/xl-email-exporter": "latest", + "@react-email/render": "^2.0.4" }, "devDependencies": { "@types/react": "^19.2.3", diff --git a/examples/07-collaboration/02-liveblocks/package.json b/examples/07-collaboration/02-liveblocks/package.json index 8da1946fac..52e5f94320 100644 --- a/examples/07-collaboration/02-liveblocks/package.json +++ b/examples/07-collaboration/02-liveblocks/package.json @@ -16,16 +16,16 @@ "@blocknote/mantine": "latest", "@blocknote/react": "latest", "@blocknote/shadcn": "latest", - "@liveblocks/client": "^3.17.0", - "@liveblocks/react": "^3.17.0", - "@liveblocks/react-blocknote": "^3.17.0", - "@liveblocks/react-tiptap": "^3.17.0", - "@liveblocks/react-ui": "^3.17.0", "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", "react": "^19.2.3", "react-dom": "^19.2.3", + "@liveblocks/client": "^3.17.0", + "@liveblocks/react": "^3.17.0", + "@liveblocks/react-blocknote": "^3.17.0", + "@liveblocks/react-tiptap": "^3.17.0", + "@liveblocks/react-ui": "^3.17.0", "yjs": "^13.6.27" }, "devDependencies": { diff --git a/examples/07-collaboration/03-y-sweet/package.json b/examples/07-collaboration/03-y-sweet/package.json index 8270d8195d..e1dcc579ca 100644 --- a/examples/07-collaboration/03-y-sweet/package.json +++ b/examples/07-collaboration/03-y-sweet/package.json @@ -19,9 +19,9 @@ "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", - "@y-sweet/react": "^0.6.3", "react": "^19.2.3", - "react-dom": "^19.2.3" + "react-dom": "^19.2.3", + "@y-sweet/react": "^0.6.3" }, "devDependencies": { "@types/react": "^19.2.3", diff --git a/examples/07-collaboration/05-comments/package.json b/examples/07-collaboration/05-comments/package.json index 7f675d3e2d..e1902158f5 100644 --- a/examples/07-collaboration/05-comments/package.json +++ b/examples/07-collaboration/05-comments/package.json @@ -19,9 +19,9 @@ "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", - "@y-sweet/react": "^0.6.3", "react": "^19.2.3", - "react-dom": "^19.2.3" + "react-dom": "^19.2.3", + "@y-sweet/react": "^0.6.3" }, "devDependencies": { "@types/react": "^19.2.3", diff --git a/examples/07-collaboration/10-comments-testing/package.json b/examples/07-collaboration/10-comments-testing/package.json index 6c4e09d1ae..070af0d48e 100644 --- a/examples/07-collaboration/10-comments-testing/package.json +++ b/examples/07-collaboration/10-comments-testing/package.json @@ -26,7 +26,7 @@ "devDependencies": { "@types/react": "^19.2.3", "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react": "^4.7.0", - "vite": "^5.4.20" + "@vitejs/plugin-react": "^6.0.1", + "vite": "^8.0.8" } } \ No newline at end of file diff --git a/examples/08-extensions/01-tiptap-arrow-conversion/package.json b/examples/08-extensions/01-tiptap-arrow-conversion/package.json index 5bca11ea17..b1055a283f 100644 --- a/examples/08-extensions/01-tiptap-arrow-conversion/package.json +++ b/examples/08-extensions/01-tiptap-arrow-conversion/package.json @@ -19,9 +19,9 @@ "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", - "@tiptap/core": "^3.13.0", "react": "^19.2.3", - "react-dom": "^19.2.3" + "react-dom": "^19.2.3", + "@tiptap/core": "^3.13.0" }, "devDependencies": { "@types/react": "^19.2.3", diff --git a/examples/09-ai/01-minimal/package.json b/examples/09-ai/01-minimal/package.json index 92c27364e7..d78b179eb4 100644 --- a/examples/09-ai/01-minimal/package.json +++ b/examples/09-ai/01-minimal/package.json @@ -16,13 +16,13 @@ "@blocknote/mantine": "latest", "@blocknote/react": "latest", "@blocknote/shadcn": "latest", - "@blocknote/xl-ai": "latest", "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", - "ai": "^6.0.5", "react": "^19.2.3", - "react-dom": "^19.2.3" + "react-dom": "^19.2.3", + "@blocknote/xl-ai": "latest", + "ai": "^6.0.5" }, "devDependencies": { "@types/react": "^19.2.3", diff --git a/examples/09-ai/02-playground/package.json b/examples/09-ai/02-playground/package.json index ed3c58dab8..7824de1c5b 100644 --- a/examples/09-ai/02-playground/package.json +++ b/examples/09-ai/02-playground/package.json @@ -16,13 +16,13 @@ "@blocknote/mantine": "latest", "@blocknote/react": "latest", "@blocknote/shadcn": "latest", - "@blocknote/xl-ai": "latest", "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", - "ai": "^6.0.5", "react": "^19.2.3", - "react-dom": "^19.2.3" + "react-dom": "^19.2.3", + "@blocknote/xl-ai": "latest", + "ai": "^6.0.5" }, "devDependencies": { "@types/react": "^19.2.3", diff --git a/examples/09-ai/03-custom-ai-menu-items/package.json b/examples/09-ai/03-custom-ai-menu-items/package.json index fb628a4aa9..d6a2573f8e 100644 --- a/examples/09-ai/03-custom-ai-menu-items/package.json +++ b/examples/09-ai/03-custom-ai-menu-items/package.json @@ -16,13 +16,13 @@ "@blocknote/mantine": "latest", "@blocknote/react": "latest", "@blocknote/shadcn": "latest", - "@blocknote/xl-ai": "latest", "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", - "ai": "^6.0.5", "react": "^19.2.3", "react-dom": "^19.2.3", + "@blocknote/xl-ai": "latest", + "ai": "^6.0.5", "react-icons": "^5.5.0" }, "devDependencies": { diff --git a/examples/09-ai/04-with-collaboration/package.json b/examples/09-ai/04-with-collaboration/package.json index 75daec4c9f..ef36c46e88 100644 --- a/examples/09-ai/04-with-collaboration/package.json +++ b/examples/09-ai/04-with-collaboration/package.json @@ -16,13 +16,13 @@ "@blocknote/mantine": "latest", "@blocknote/react": "latest", "@blocknote/shadcn": "latest", - "@blocknote/xl-ai": "latest", "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", - "ai": "^6.0.5", "react": "^19.2.3", "react-dom": "^19.2.3", + "@blocknote/xl-ai": "latest", + "ai": "^6.0.5", "y-partykit": "^0.0.25", "yjs": "^13.6.27" }, diff --git a/examples/09-ai/05-manual-execution/package.json b/examples/09-ai/05-manual-execution/package.json index a1b130faa8..dd5e66ef92 100644 --- a/examples/09-ai/05-manual-execution/package.json +++ b/examples/09-ai/05-manual-execution/package.json @@ -16,13 +16,13 @@ "@blocknote/mantine": "latest", "@blocknote/react": "latest", "@blocknote/shadcn": "latest", - "@blocknote/xl-ai": "latest", "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", - "ai": "^6.0.5", "react": "^19.2.3", "react-dom": "^19.2.3", + "@blocknote/xl-ai": "latest", + "ai": "^6.0.5", "y-partykit": "^0.0.25", "yjs": "^13.6.27" }, diff --git a/examples/09-ai/06-client-side-transport/package.json b/examples/09-ai/06-client-side-transport/package.json index 8cc1777300..64b09bc543 100644 --- a/examples/09-ai/06-client-side-transport/package.json +++ b/examples/09-ai/06-client-side-transport/package.json @@ -11,19 +11,19 @@ "preview": "vite preview" }, "dependencies": { - "@ai-sdk/groq": "^3.0.2", "@blocknote/ariakit": "latest", "@blocknote/core": "latest", "@blocknote/mantine": "latest", "@blocknote/react": "latest", "@blocknote/shadcn": "latest", - "@blocknote/xl-ai": "latest", "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", - "ai": "^6.0.5", "react": "^19.2.3", - "react-dom": "^19.2.3" + "react-dom": "^19.2.3", + "@ai-sdk/groq": "^3.0.2", + "@blocknote/xl-ai": "latest", + "ai": "^6.0.5" }, "devDependencies": { "@types/react": "^19.2.3", diff --git a/examples/09-ai/07-server-persistence/package.json b/examples/09-ai/07-server-persistence/package.json index 0ee494038b..0ac67163a2 100644 --- a/examples/09-ai/07-server-persistence/package.json +++ b/examples/09-ai/07-server-persistence/package.json @@ -16,13 +16,13 @@ "@blocknote/mantine": "latest", "@blocknote/react": "latest", "@blocknote/shadcn": "latest", - "@blocknote/xl-ai": "latest", "@mantine/core": "^8.3.11", "@mantine/hooks": "^8.3.11", "@mantine/utils": "^6.0.22", - "ai": "^6.0.5", "react": "^19.2.3", - "react-dom": "^19.2.3" + "react-dom": "^19.2.3", + "@blocknote/xl-ai": "latest", + "ai": "^6.0.5" }, "devDependencies": { "@types/react": "^19.2.3", diff --git a/packages/dev-scripts/examples/template-react/package.json.template.tsx b/packages/dev-scripts/examples/template-react/package.json.template.tsx index a08cdc93ad..98c67f3e50 100644 --- a/packages/dev-scripts/examples/template-react/package.json.template.tsx +++ b/packages/dev-scripts/examples/template-react/package.json.template.tsx @@ -39,8 +39,8 @@ const template = (project: Project) => ({ : {}), "@types/react": "^19.2.3", "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react": "^4.7.0", - vite: "^5.4.20", + "@vitejs/plugin-react": "^6.0.1", + vite: "^8.0.8", ...(project.config?.devDependencies || {}), }, }); diff --git a/playground/src/examples.gen.tsx b/playground/src/examples.gen.tsx index ebe940400d..130f92fefb 100644 --- a/playground/src/examples.gen.tsx +++ b/playground/src/examples.gen.tsx @@ -997,11 +997,11 @@ ], "dependencies": { "@blocknote/code-block": "latest", - "@shikijs/core": "^3.19.0", - "@shikijs/engine-javascript": "^3.19.0", - "@shikijs/langs-precompiled": "^3.19.0", - "@shikijs/themes": "^3.19.0", - "@shikijs/types": "^3.19.0" + "@shikijs/core": "^4", + "@shikijs/engine-javascript": "^4", + "@shikijs/langs-precompiled": "^4", + "@shikijs/themes": "^4", + "@shikijs/types": "^4" } as any }, "title": "Custom Code Block Theme & Language", From c58be94a517370d4ee0522b0cb122d9ccfacf566 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Mon, 20 Apr 2026 16:42:50 +0200 Subject: [PATCH 09/11] Updated lock file --- pnpm-lock.yaml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b96c8bcefd..a5ad72becd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4025,19 +4025,19 @@ importers: version: link:../../../packages/shadcn '@mantine/core': specifier: ^8.3.11 - version: 8.3.18(@mantine/hooks@8.3.18(react@19.2.4))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 8.3.18(@mantine/hooks@8.3.18(react@19.2.5))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@mantine/hooks': specifier: ^8.3.11 - version: 8.3.18(react@19.2.4) + version: 8.3.18(react@19.2.5) '@mantine/utils': specifier: ^6.0.22 - version: 6.0.22(react@19.2.4) + version: 6.0.22(react@19.2.5) react: specifier: ^19.2.3 - version: 19.2.4 + version: 19.2.5 react-dom: specifier: ^19.2.3 - version: 19.2.4(react@19.2.4) + version: 19.2.5(react@19.2.5) yjs: specifier: ^13.6.27 version: 13.6.30 @@ -4049,11 +4049,11 @@ importers: specifier: ^19.2.3 version: 19.2.3(@types/react@19.2.14) '@vitejs/plugin-react': - specifier: ^4.7.0 - version: 4.7.0(vite@5.4.21(@types/node@25.6.0)(lightningcss@1.32.0)(terser@5.46.1)) + specifier: ^6.0.1 + version: 6.0.1(babel-plugin-react-compiler@1.0.0)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.5)(jiti@2.6.1)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) vite: - specifier: ^5.4.20 - version: 5.4.21(@types/node@25.6.0)(lightningcss@1.32.0)(terser@5.46.1) + specifier: ^8.0.8 + version: 8.0.8(@types/node@25.6.0)(esbuild@0.27.5)(jiti@2.6.1)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) examples/08-extensions/01-tiptap-arrow-conversion: dependencies: From 703e2fd3886e8d0ab7717d2dc9b2a5caefe76f77 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Mon, 20 Apr 2026 16:46:05 +0200 Subject: [PATCH 10/11] Changed example number --- .../.bnexample.json | 0 .../{10-comments-testing => 09-comments-testing}/README.md | 0 .../{10-comments-testing => 09-comments-testing}/index.html | 0 .../{10-comments-testing => 09-comments-testing}/main.tsx | 0 .../{10-comments-testing => 09-comments-testing}/package.json | 0 .../{10-comments-testing => 09-comments-testing}/src/App.tsx | 0 .../{10-comments-testing => 09-comments-testing}/tsconfig.json | 0 .../{10-comments-testing => 09-comments-testing}/vite.config.ts | 0 playground/src/examples.gen.tsx | 2 +- 9 files changed, 1 insertion(+), 1 deletion(-) rename examples/07-collaboration/{10-comments-testing => 09-comments-testing}/.bnexample.json (100%) rename examples/07-collaboration/{10-comments-testing => 09-comments-testing}/README.md (100%) rename examples/07-collaboration/{10-comments-testing => 09-comments-testing}/index.html (100%) rename examples/07-collaboration/{10-comments-testing => 09-comments-testing}/main.tsx (100%) rename examples/07-collaboration/{10-comments-testing => 09-comments-testing}/package.json (100%) rename examples/07-collaboration/{10-comments-testing => 09-comments-testing}/src/App.tsx (100%) rename examples/07-collaboration/{10-comments-testing => 09-comments-testing}/tsconfig.json (100%) rename examples/07-collaboration/{10-comments-testing => 09-comments-testing}/vite.config.ts (100%) diff --git a/examples/07-collaboration/10-comments-testing/.bnexample.json b/examples/07-collaboration/09-comments-testing/.bnexample.json similarity index 100% rename from examples/07-collaboration/10-comments-testing/.bnexample.json rename to examples/07-collaboration/09-comments-testing/.bnexample.json diff --git a/examples/07-collaboration/10-comments-testing/README.md b/examples/07-collaboration/09-comments-testing/README.md similarity index 100% rename from examples/07-collaboration/10-comments-testing/README.md rename to examples/07-collaboration/09-comments-testing/README.md diff --git a/examples/07-collaboration/10-comments-testing/index.html b/examples/07-collaboration/09-comments-testing/index.html similarity index 100% rename from examples/07-collaboration/10-comments-testing/index.html rename to examples/07-collaboration/09-comments-testing/index.html diff --git a/examples/07-collaboration/10-comments-testing/main.tsx b/examples/07-collaboration/09-comments-testing/main.tsx similarity index 100% rename from examples/07-collaboration/10-comments-testing/main.tsx rename to examples/07-collaboration/09-comments-testing/main.tsx diff --git a/examples/07-collaboration/10-comments-testing/package.json b/examples/07-collaboration/09-comments-testing/package.json similarity index 100% rename from examples/07-collaboration/10-comments-testing/package.json rename to examples/07-collaboration/09-comments-testing/package.json diff --git a/examples/07-collaboration/10-comments-testing/src/App.tsx b/examples/07-collaboration/09-comments-testing/src/App.tsx similarity index 100% rename from examples/07-collaboration/10-comments-testing/src/App.tsx rename to examples/07-collaboration/09-comments-testing/src/App.tsx diff --git a/examples/07-collaboration/10-comments-testing/tsconfig.json b/examples/07-collaboration/09-comments-testing/tsconfig.json similarity index 100% rename from examples/07-collaboration/10-comments-testing/tsconfig.json rename to examples/07-collaboration/09-comments-testing/tsconfig.json diff --git a/examples/07-collaboration/10-comments-testing/vite.config.ts b/examples/07-collaboration/09-comments-testing/vite.config.ts similarity index 100% rename from examples/07-collaboration/10-comments-testing/vite.config.ts rename to examples/07-collaboration/09-comments-testing/vite.config.ts diff --git a/playground/src/examples.gen.tsx b/playground/src/examples.gen.tsx index 130f92fefb..5f219ff7fa 100644 --- a/playground/src/examples.gen.tsx +++ b/playground/src/examples.gen.tsx @@ -1691,7 +1691,7 @@ { "projectSlug": "comments-testing", "fullSlug": "collaboration/comments-testing", - "pathFromRoot": "examples/07-collaboration/10-comments-testing", + "pathFromRoot": "examples/07-collaboration/09-comments-testing", "config": { "playground": true, "docs": false, From 03d90d99682cdbf7c1372ee09d8c1e2f7a967227 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Mon, 20 Apr 2026 16:49:07 +0200 Subject: [PATCH 11/11] Updated lock file --- pnpm-lock.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a5ad72becd..202a26aeda 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4006,7 +4006,7 @@ importers: specifier: ^8.0.8 version: 8.0.8(@types/node@25.6.0)(esbuild@0.27.5)(jiti@2.6.1)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) - examples/07-collaboration/10-comments-testing: + examples/07-collaboration/09-comments-testing: dependencies: '@blocknote/ariakit': specifier: latest