[GH-ISSUE #560] bug: scrollbox with content longer than window breaks on scroll/resize #919

Open
opened 2026-03-14 09:02:21 +03:00 by kerem · 2 comments
Owner

Originally created by @safareli on GitHub (Jan 20, 2026).
Original GitHub issue: https://github.com/anomalyco/opentui/issues/560

https://github.com/user-attachments/assets/d41f52e7-d412-45f3-953d-b6492ed63016

code:

import React from "react";
import { createCliRenderer } from "@opentui/core";
import { createRoot } from "@opentui/react";

const generateRandomLine = (lineNumber: number): string => {
  const digit = Math.floor(Math.random() * 10);
  const length = 10 + Math.floor(Math.random() * 50);
  return `${String(lineNumber).padStart(4, " ")} | ${String(digit).repeat(length)}`;
};
const TOTAL_LINES = 1000;
const lines = Array.from({ length: TOTAL_LINES }, (_, i) => generateRandomLine(i + 1));
const COLORS = [
  "#e74c3c", // red
  "#e67e22", // orange
  "#f1c40f", // yellow
  "#2ecc71", // green
  "#1abc9c", // teal
  "#3498db", // blue
  "#9b59b6", // purple
  "#e91e63", // pink
  "#00bcd4", // cyan
  "#8bc34a", // lime
];

const ScrollboxTest: React.FC = () => {
  return (
    <scrollbox
      flexGrow={1}
      scrollY
      paddingLeft={1}
      paddingRight={1}
    >
      {lines.map((line, i) => (
        <box key={i} height={1}>
          <text content={line} fg={COLORS[i % COLORS.length]} />
        </box>
      ))}
    </scrollbox>
  );
};

const main = async () => {
  const renderer = await createCliRenderer({ exitOnCtrlC: true });
  const root = createRoot(renderer);
  root.render(<ScrollboxTest />);
  await new Promise<void>((resolve) => { renderer.on("destroy", () => resolve()); });
};

main().catch(console.error);
Originally created by @safareli on GitHub (Jan 20, 2026). Original GitHub issue: https://github.com/anomalyco/opentui/issues/560 https://github.com/user-attachments/assets/d41f52e7-d412-45f3-953d-b6492ed63016 code: ```ts import React from "react"; import { createCliRenderer } from "@opentui/core"; import { createRoot } from "@opentui/react"; const generateRandomLine = (lineNumber: number): string => { const digit = Math.floor(Math.random() * 10); const length = 10 + Math.floor(Math.random() * 50); return `${String(lineNumber).padStart(4, " ")} | ${String(digit).repeat(length)}`; }; const TOTAL_LINES = 1000; const lines = Array.from({ length: TOTAL_LINES }, (_, i) => generateRandomLine(i + 1)); const COLORS = [ "#e74c3c", // red "#e67e22", // orange "#f1c40f", // yellow "#2ecc71", // green "#1abc9c", // teal "#3498db", // blue "#9b59b6", // purple "#e91e63", // pink "#00bcd4", // cyan "#8bc34a", // lime ]; const ScrollboxTest: React.FC = () => { return ( <scrollbox flexGrow={1} scrollY paddingLeft={1} paddingRight={1} > {lines.map((line, i) => ( <box key={i} height={1}> <text content={line} fg={COLORS[i % COLORS.length]} /> </box> ))} </scrollbox> ); }; const main = async () => { const renderer = await createCliRenderer({ exitOnCtrlC: true }); const root = createRoot(renderer); root.render(<ScrollboxTest />); await new Promise<void>((resolve) => { renderer.on("destroy", () => resolve()); }); }; main().catch(console.error); ```
Author
Owner

@jettptacek commented on GitHub (Jan 26, 2026):

Found the problem! Your height can't be forced to 1 with wrapping enabled. Set it to "auto" and you should be good to for either char or word wrapping

const ScrollboxTest: React.FC = () => {
  return (
    <scrollbox
      flexGrow={1}
      scrollY
      paddingLeft={1}
      paddingRight={1}
    >
      {lines.map((line, i) => (
-       <box key={i} height={1}>
+      <box key={i} height={"auto")>
          <text content={line} fg={COLORS[i % COLORS.length]} />
        </box>
      ))}
    </scrollbox>
  );
};
<!-- gh-comment-id:3797490144 --> @jettptacek commented on GitHub (Jan 26, 2026): Found the problem! Your height can't be forced to 1 with wrapping enabled. Set it to `"auto"` and you should be good to for either char or word wrapping ``` diff const ScrollboxTest: React.FC = () => { return ( <scrollbox flexGrow={1} scrollY paddingLeft={1} paddingRight={1} > {lines.map((line, i) => ( - <box key={i} height={1}> + <box key={i} height={"auto")> <text content={line} fg={COLORS[i % COLORS.length]} /> </box> ))} </scrollbox> ); }; ```
Author
Owner

@remorses commented on GitHub (Jan 26, 2026):

Also try setting flexShrink to zero to all text elements

<!-- gh-comment-id:3798198189 --> @remorses commented on GitHub (Jan 26, 2026): Also try setting flexShrink to zero to all text elements
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/opentui#919
No description provided.