studio/frontend: scroll long lines inside code blocks instead of overflowing

Cycle-33 probe (`scripts/r6_code_block_wrap_probe.py`) renders an
assistant message with four code fences containing unbreakable runs:
a 200-char hex string, a single-line curl with many flags, a JSON
value holding a long URL, and a 300-char ascii blob. All four blocks
measure with `overflow-x: visible`, `white-space: pre`, `word-break:
normal` -- streamdown's default <pre> styling -- so content escapes
the bubble laterally and reflows the chat column instead of staying
contained.

Three of the four blocks had scrollWidth > 2x clientWidth (1696,
2177, 2447 px inside a 710 px column).

Add two scoped rules in `index.css` alongside the existing
streamdown hardening section:

  - The inner `<pre>` switches to `overflow-x: auto` so a horizontal
    scrollbar appears on the code block itself.
  - The outer `[data-streamdown="code-block"]` wrapper gets
    `max-width: 100%; overflow-x: hidden` so any residual leak can't
    widen the bubble even if a downstream library tweak undoes the
    pre styling.

Code indentation is preserved (no wrap), the scrollbar appears only
when needed, and the rest of the chat column layout stays put.
This commit is contained in:
danielhanchen 2026-05-19 17:10:40 +00:00
commit a3b3ce6a6c

View file

@ -994,6 +994,22 @@
.aui-thread-root [data-streamdown="code-block"] [data-sd-animate] {
animation: none !important;
}
/* Long lines inside fenced code blocks should scroll horizontally
* within the block, not push the chat column wider. Streamdown's
* default <pre> ships with `overflow-x: visible` + `white-space:
* pre` + `word-break: normal`, so an unbreakable run (long URL,
* hex string, single-line curl command) escapes the bubble to the
* right and reflows the message column. Switch the inner <pre> to
* `overflow-x: auto` so the scrollbar appears on the code block
* itself; the parent stays clipped so it cannot widen the bubble. */
.aui-thread-root [data-streamdown="code-block"] pre {
overflow-x: auto;
}
.aui-thread-root [data-streamdown="code-block"] {
max-width: 100%;
overflow-x: hidden;
}
}
/* Lighter shadow + tighter vertical padding than Sonner's defaults; !important because Sonner injects its base rules at runtime. */