From 7b6d2cfeab1ee65de1acb0b4e2938984b8324110 Mon Sep 17 00:00:00 2001 From: Bernhard Jackiewicz Date: Sun, 4 Oct 2026 15:24:10 +0200 Subject: [PATCH] fix(ui): wrap long lines of code blocks in chat answers The lines read from JSONBAgg ended mid-template at the panel edge, behind the scrollbar macOS hides. Code blocks in chat answers now wrap long lines, as the Source block does since K15. Signed-off-by: Bernhard Jackiewicz --- .../src/browser-ai/browser-chat-css.code.test.ts | 14 ++++++++++++++ graph-ui/src/browser-ai/browser-chat.css | 6 ++++-- 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 graph-ui/src/browser-ai/browser-chat-css.code.test.ts diff --git a/graph-ui/src/browser-ai/browser-chat-css.code.test.ts b/graph-ui/src/browser-ai/browser-chat-css.code.test.ts new file mode 100644 index 000000000..9b308704c --- /dev/null +++ b/graph-ui/src/browser-ai/browser-chat-css.code.test.ts @@ -0,0 +1,14 @@ +import { readFileSync } from 'node:fs'; +import { describe, expect, it } from 'vitest'; + +const css = readFileSync(new URL('./browser-chat.css', import.meta.url), 'utf8').replace(/\/\*[\s\S]*?\*\//g, ''); +const rule = (selector: string) => [...css.matchAll(/([^{}]+)\{([^}]*)\}/g)].filter(match => match[1].split(',').map(item => item.trim()).includes(selector)).map(match => match[2]).join(';'); + +/** The lines read from JSONBAgg ended mid-template at the panel edge, behind a hidden scrollbar (B2). */ +describe('code blocks in a chat answer', () => { + it('wrap long lines instead of clipping them at the panel edge', () => { + expect(rule('.cbm-chat-markdown .cbm-chat-code-block pre')).toMatch(/white-space:\s*pre-wrap/); + expect(rule('.cbm-chat-markdown .cbm-chat-code-block pre')).toMatch(/overflow-wrap:\s*anywhere/); + expect(rule('.cbm-chat-code-block pre > code')).not.toMatch(/width:\s*max-content/); + }); +}); diff --git a/graph-ui/src/browser-ai/browser-chat.css b/graph-ui/src/browser-ai/browser-chat.css index 3e7ce0b7c..012e3afe8 100644 --- a/graph-ui/src/browser-ai/browser-chat.css +++ b/graph-ui/src/browser-ai/browser-chat.css @@ -99,8 +99,10 @@ .cbm-chat-code-header > div { display: flex; align-items: center; gap: 7px; flex-shrink: 0; } .cbm-chat-dock .cbm-chat-code-header button { padding: 2px 7px; min-width: 44px; font-size: 10px; background: transparent; } .cbm-chat-code-copy-error { color: #ffb6bd; font-size: 10px; } -.cbm-chat-markdown .cbm-chat-code-block pre { margin: 0; padding: 11px; max-width: 100%; max-height: 360px; overflow: auto; overscroll-behavior: contain; white-space: pre; tab-size: 4; } -.cbm-chat-code-block pre > code { display: block; width: max-content; min-width: 100%; background: transparent; color: #d0e8d8; font: 11px/1.65 ui-monospace, SFMono-Regular, monospace; } +/* The panel is narrow and macOS hides scrollbars: a long line wraps instead of ending at the + * edge, as in the Source block (K15). The lines read from the code ended mid-template (B2). */ +.cbm-chat-markdown .cbm-chat-code-block pre { margin: 0; padding: 11px; max-width: 100%; max-height: 360px; overflow: auto; overscroll-behavior: contain; white-space: pre-wrap; overflow-wrap: anywhere; tab-size: 4; } +.cbm-chat-code-block pre > code { display: block; min-width: 100%; background: transparent; color: #d0e8d8; font: 11px/1.65 ui-monospace, SFMono-Regular, monospace; } .cbm-chat-table-scroll { max-width: 100%; overflow-x: auto; } .cbm-chat-markdown table { width: 100%; border-collapse: collapse; font-size: 12px; } .cbm-chat-markdown :is(th, td) { padding: 7px 9px; border: 1px solid var(--chat-border); vertical-align: top; text-align: left; }