diff --git a/packages/loopover-ui-kit/src/components/sidebar.test.tsx b/packages/loopover-ui-kit/src/components/sidebar.test.tsx
new file mode 100644
index 0000000000..27d3fbc893
--- /dev/null
+++ b/packages/loopover-ui-kit/src/components/sidebar.test.tsx
@@ -0,0 +1,87 @@
+import { fireEvent, render, screen } from "@testing-library/react";
+import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
+import { SidebarProvider, useSidebar } from "./sidebar";
+
+// jsdom implements no window.matchMedia; SidebarProvider pulls it in via useIsMobile. Stub it desktop-shaped
+// (matches:false), the standard shadcn use-mobile test setup.
+beforeEach(() => {
+ vi.stubGlobal(
+ "matchMedia",
+ vi.fn(() => ({
+ matches: false,
+ media: "",
+ addEventListener: () => {},
+ removeEventListener: () => {},
+ })),
+ );
+});
+afterEach(() => vi.unstubAllGlobals());
+
+// #8305: SidebarProvider's global Cmd/Ctrl+B keydown handler used to toggle the sidebar (and preventDefault())
+// no matter what had focus — hijacking the browser-native Bold shortcut inside text fields. These pin the
+// isTyping() guard: the shortcut still works from non-editable targets, and is inert inside a form field or
+// contenteditable element (target's own text-editing keeps the native behavior).
+
+function StateProbe() {
+ const { open } = useSidebar();
+ return {open ? "open" : "closed"};
+}
+
+function setup() {
+ const utils = render(
+
+
+
+
+
+ ,
+ );
+ // jsdom does not derive `isContentEditable` from the contentEditable attribute, so define it explicitly to
+ // represent a real contenteditable element the way a browser reports it to the guard.
+ const editable = screen.getByTestId("field-editable");
+ Object.defineProperty(editable, "isContentEditable", {
+ value: true,
+ configurable: true,
+ });
+ return utils;
+}
+
+const openState = () => screen.getByTestId("sidebar-open").textContent;
+
+describe("SidebarProvider Cmd/Ctrl+B guard (#8305)", () => {
+ it("toggles the sidebar on Cmd/Ctrl+B from a non-editable target and prevents the default", () => {
+ setup();
+ const before = openState();
+ // fireEvent returns false when the event's default was prevented.
+ const notPrevented = fireEvent.keyDown(document.body, {
+ key: "b",
+ ctrlKey: true,
+ });
+ expect(notPrevented).toBe(false); // preventDefault() ran
+ expect(openState()).not.toBe(before); // state flipped
+ });
+
+ it("does not toggle and does not preventDefault when the target is an input/textarea/contenteditable", () => {
+ setup();
+ for (const id of ["field-input", "field-textarea", "field-editable"]) {
+ const before = openState();
+ const notPrevented = fireEvent.keyDown(screen.getByTestId(id), {
+ key: "b",
+ metaKey: true,
+ });
+ expect(notPrevented, id).toBe(true); // default NOT prevented — native Bold survives
+ expect(openState(), id).toBe(before); // sidebar unchanged
+ }
+ });
+
+ it("leaves an unrelated Cmd/Ctrl chord (not 'b') alone", () => {
+ setup();
+ const before = openState();
+ const notPrevented = fireEvent.keyDown(document.body, {
+ key: "k",
+ ctrlKey: true,
+ });
+ expect(notPrevented).toBe(true);
+ expect(openState()).toBe(before);
+ });
+});
diff --git a/packages/loopover-ui-kit/src/components/sidebar.tsx b/packages/loopover-ui-kit/src/components/sidebar.tsx
index 5d79a39b43..874b08ce29 100644
--- a/packages/loopover-ui-kit/src/components/sidebar.tsx
+++ b/packages/loopover-ui-kit/src/components/sidebar.tsx
@@ -30,6 +30,21 @@ const SIDEBAR_WIDTH_MOBILE = "18rem";
const SIDEBAR_WIDTH_ICON = "3rem";
const SIDEBAR_KEYBOARD_SHORTCUT = "b";
+/** Whether a keyboard event originates from a text field or contenteditable element, in which case a global
+ * shortcut handler must not act (Cmd/Ctrl+B is the browser-native Bold inside editable text). Mirrors exactly
+ * the `isTyping` guard apps/loopover-ui's keyboard-shortcuts.tsx and app-shell.tsx already apply to their own
+ * global keydown handlers (#8305). */
+function isTyping(target: EventTarget | null): boolean {
+ if (!(target instanceof HTMLElement)) return false;
+ const tag = target.tagName;
+ return (
+ tag === "INPUT" ||
+ tag === "TEXTAREA" ||
+ tag === "SELECT" ||
+ target.isContentEditable
+ );
+}
+
type SidebarContextProps = {
state: "expanded" | "collapsed";
open: boolean;
@@ -107,6 +122,10 @@ const SidebarProvider = React.forwardRef<
event.key === SIDEBAR_KEYBOARD_SHORTCUT &&
(event.metaKey || event.ctrlKey)
) {
+ // #8305: don't hijack the browser-native Cmd/Ctrl+B (Bold) while the user is typing in a text field
+ // or contenteditable element — return before preventDefault()/toggle, matching the other two global
+ // keydown handlers in this repo (keyboard-shortcuts.tsx, app-shell.tsx).
+ if (isTyping(event.target)) return;
event.preventDefault();
toggleSidebar();
}