-
Notifications
You must be signed in to change notification settings - Fork 240
Description
Problem Statement
When a streamed (or static) response contains a large code block or table, it grows without bound and pushes everything else off-screen. The user has to scroll past hundreds of lines of code just to see the next paragraph. During streaming (isAnimating={true}) the problem is worse: new lines are appended at the bottom but the container keeps growing, so the user constantly loses their place.
Current behavior in the codebase:
| Element | Container file | Overflow handling | Height constraint |
|---|---|---|---|
| Code block body | lib/code-block/body.tsx |
overflow-hidden — content is clipped, not scrollable |
None (auto) |
| Code block wrapper | lib/code-block/container.tsx |
None (uses content-visibility: auto) |
None |
| Table wrapper | lib/table/index.tsx |
overflow-x-auto overflow-y-auto |
None (auto) |
Because there is no max-height, both code blocks and tables expand to their full content height regardless of how long they are.
Proposed Solution
1. Constrain height with max-height + vertical scroll
Apply a sensible default max-height (e.g. 400px for code blocks, 300px for tables) so that long content becomes scrollable instead of stretching the page. The feature should be on by default but allow consumers to override or disable it.
2. Auto-scroll to bottom during streaming
When isAnimating is true and new content is appended, the scrollable container should automatically stay pinned to the bottom - just like a terminal emulator.
If the user manually scrolls up to read earlier content, auto-scroll must pause (scroll-anchoring pattern). It re-engages only if the user scrolls back to the bottom, or when a new streaming response begins.
Auto-scroll applies only during streaming (isAnimating={true}), not during static rendering.
Proposed API
<Streamdown
isAnimating={isLoading}
codeBlockMaxHeight={400} // default: 400 (px). Set to 0 or Infinity to disable.
tableMaxHeight={300} // default: 300 (px). Set to 0 or Infinity to disable.
>
{streamingContent}
</Streamdown>Both props are optional. When omitted, the defaults kick in.
Alternatives Considered
No response
Use Case
Priority
Important
Contribution
- I am willing to help implement this feature
Additional Context
No response