From 615748657aaf5c0b5d19c7ff046346a29275ed81 Mon Sep 17 00:00:00 2001
From: Elvin <eaghammad@gmail.com>
Date: Tue, 15 Jul 2025 19:35:03 -0400
Subject: Update MaxSizedBox.tsx (#2233)

Co-authored-by: Jacob Richman <jacob314@gmail.com>
Co-authored-by: Scott Densmore <scottdensmore@mac.com>
Co-authored-by: Pascal Birchler <pascalb@google.com>
---
 .../cli/src/ui/components/shared/MaxSizedBox.tsx   | 81 +++++++++++++++++++++-
 1 file changed, 79 insertions(+), 2 deletions(-)

(limited to 'packages/cli/src/ui/components/shared/MaxSizedBox.tsx')

diff --git a/packages/cli/src/ui/components/shared/MaxSizedBox.tsx b/packages/cli/src/ui/components/shared/MaxSizedBox.tsx
index eb5ef6b4..346472bf 100644
--- a/packages/cli/src/ui/components/shared/MaxSizedBox.tsx
+++ b/packages/cli/src/ui/components/shared/MaxSizedBox.tsx
@@ -432,8 +432,85 @@ function layoutInkElementAsStyledText(
   const availableWidth = maxWidth - noWrappingWidth;
 
   if (availableWidth < 1) {
-    // No room to render the wrapping segments. TODO(jacob314): consider an alternative fallback strategy.
-    output.push(nonWrappingContent);
+    // No room to render the wrapping segments. Truncate the non-wrapping
+    // content and append an ellipsis so the line always fits within maxWidth.
+
+    // Handle line breaks in non-wrapping content when truncating
+    const lines: StyledText[][] = [];
+    let currentLine: StyledText[] = [];
+    let currentLineWidth = 0;
+
+    for (const segment of nonWrappingContent) {
+      const textLines = segment.text.split('\n');
+      textLines.forEach((text, index) => {
+        if (index > 0) {
+          // New line encountered, finish current line and start new one
+          lines.push(currentLine);
+          currentLine = [];
+          currentLineWidth = 0;
+        }
+
+        if (text) {
+          const textWidth = stringWidth(text);
+
+          // When there's no room for wrapping content, be very conservative
+          // For lines after the first line break, show only ellipsis if the text would be truncated
+          if (index > 0 && textWidth > 0) {
+            // This is content after a line break - just show ellipsis to indicate truncation
+            currentLine.push({ text: '…', props: {} });
+            currentLineWidth = stringWidth('…');
+          } else {
+            // This is the first line or a continuation, try to fit what we can
+            const maxContentWidth = Math.max(0, maxWidth - stringWidth('…'));
+
+            if (textWidth <= maxContentWidth && currentLineWidth === 0) {
+              // Text fits completely on this line
+              currentLine.push({ text, props: segment.props });
+              currentLineWidth += textWidth;
+            } else {
+              // Text needs truncation
+              const codePoints = toCodePoints(text);
+              let truncatedWidth = currentLineWidth;
+              let sliceEndIndex = 0;
+
+              for (const char of codePoints) {
+                const charWidth = stringWidth(char);
+                if (truncatedWidth + charWidth > maxContentWidth) {
+                  break;
+                }
+                truncatedWidth += charWidth;
+                sliceEndIndex++;
+              }
+
+              const slice = codePoints.slice(0, sliceEndIndex).join('');
+              if (slice) {
+                currentLine.push({ text: slice, props: segment.props });
+              }
+              currentLine.push({ text: '…', props: {} });
+              currentLineWidth = truncatedWidth + stringWidth('…');
+            }
+          }
+        }
+      });
+    }
+
+    // Add the last line if it has content or if the last segment ended with \n
+    if (
+      currentLine.length > 0 ||
+      (nonWrappingContent.length > 0 &&
+        nonWrappingContent[nonWrappingContent.length - 1].text.endsWith('\n'))
+    ) {
+      lines.push(currentLine);
+    }
+
+    // If we don't have any lines yet, add an ellipsis line
+    if (lines.length === 0) {
+      lines.push([{ text: '…', props: {} }]);
+    }
+
+    for (const line of lines) {
+      output.push(line);
+    }
     return;
   }
 
-- 
cgit v1.2.3

