From ee5c361df0db8f264cf28f9baea863be23963ccc Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Thu, 26 Jun 2025 18:04:50 +0200 Subject: [PATCH 1/2] Fixed `bn-inline-content` class name being added to React custom block's inline content element whenever its content changed --- packages/react/src/schema/ReactBlockSpec.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/react/src/schema/ReactBlockSpec.tsx b/packages/react/src/schema/ReactBlockSpec.tsx index 9b15550d13..6ecf135d13 100644 --- a/packages/react/src/schema/ReactBlockSpec.tsx +++ b/packages/react/src/schema/ReactBlockSpec.tsx @@ -189,7 +189,10 @@ export function createReactBlockSpec< editor={editor as any} contentRef={(element) => { ref(element); - if (element) { + if ( + element && + !element.classList.contains("bn-inline-content") + ) { element.className = mergeCSSClasses( "bn-inline-content", element.className, @@ -268,7 +271,10 @@ export function createReactBlockSpec< editor={editor as any} contentRef={(element) => { refCB(element); - if (element) { + if ( + element && + !element.classList.contains("bn-inline-content") + ) { element.className = mergeCSSClasses( "bn-inline-content", element.className, From 8d15c2ac0b8aa657eee8590bfb59667c7f28cbf2 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Wed, 2 Jul 2025 14:09:29 +0200 Subject: [PATCH 2/2] Improved `mergeCSSClasses` --- packages/core/src/util/browser.ts | 12 +++++++++++- packages/react/src/schema/ReactBlockSpec.tsx | 10 ++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/core/src/util/browser.ts b/packages/core/src/util/browser.ts index 2a0a2905bd..118c138a48 100644 --- a/packages/core/src/util/browser.ts +++ b/packages/core/src/util/browser.ts @@ -13,7 +13,17 @@ export function formatKeyboardShortcut(shortcut: string, ctrlText = "Ctrl") { } export function mergeCSSClasses(...classes: (string | false | undefined)[]) { - return classes.filter((c) => c).join(" "); + return [ + // Converts to & from set to remove duplicates. + ...new Set( + classes + .filter((c) => c) + // Ensures that if multiple classes are passed as a single string, they + // are split. + .join(" ") + .split(" "), + ), + ].join(" "); } export const isSafari = () => diff --git a/packages/react/src/schema/ReactBlockSpec.tsx b/packages/react/src/schema/ReactBlockSpec.tsx index 6ecf135d13..9b15550d13 100644 --- a/packages/react/src/schema/ReactBlockSpec.tsx +++ b/packages/react/src/schema/ReactBlockSpec.tsx @@ -189,10 +189,7 @@ export function createReactBlockSpec< editor={editor as any} contentRef={(element) => { ref(element); - if ( - element && - !element.classList.contains("bn-inline-content") - ) { + if (element) { element.className = mergeCSSClasses( "bn-inline-content", element.className, @@ -271,10 +268,7 @@ export function createReactBlockSpec< editor={editor as any} contentRef={(element) => { refCB(element); - if ( - element && - !element.classList.contains("bn-inline-content") - ) { + if (element) { element.className = mergeCSSClasses( "bn-inline-content", element.className,