Skip to content

Commit 42e9081

Browse files
committed
🤖 Fix code review textarea wrapping
The review note textarea was extending horizontally beyond the visible viewport because it was inheriting the width of the scrollable content area (which expands for long diff lines) rather than the visible scrollport width. Solution: Use ResizeObserver to dynamically set InlineNoteContainer width to match the clientWidth of the scrollable parent (DiffContainer). This constrains the textarea to the visible viewport while allowing the diff lines to scroll horizontally as before. Changes: - NoteTextarea: Added overflow-y: auto, white-space: pre-wrap, word-wrap: break-word, box-sizing: border-box - ReviewNoteInput: Added ResizeObserver to track scrollParent width - InlineNoteContainer: Width set dynamically via JavaScript Result: Text in the review note input wraps within the visible viewport boundaries. Long diff lines can still scroll horizontally, but the textarea respects the visible container width.
1 parent dee39f5 commit 42e9081

File tree

1 file changed

+41
-2
lines changed

1 file changed

+41
-2
lines changed

src/components/shared/DiffRenderer.tsx

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,10 +333,12 @@ const InlineNoteContainer = styled.div`
333333
background: #1e1e1e;
334334
border-top: 1px solid hsl(from var(--color-review-accent) h s l / 0.3);
335335
margin: 0;
336+
/* Width set dynamically via ResizeObserver to match visible scrollport */
336337
`;
337338

338339
const NoteTextarea = styled.textarea`
339340
width: 100%;
341+
max-width: 100%;
340342
min-height: calc(12px * 1.4 * 3 + 12px); /* 3 lines + padding */
341343
padding: 6px 8px;
342344
font-family: var(--font-monospace);
@@ -347,7 +349,11 @@ const NoteTextarea = styled.textarea`
347349
border-radius: 2px;
348350
color: var(--color-text);
349351
resize: none; /* Disable manual resize since we auto-grow */
350-
overflow-y: hidden; /* Hide scrollbar during auto-grow */
352+
overflow-y: auto; /* Allow scrolling for tall content */
353+
overflow-x: hidden; /* Prevent horizontal scroll */
354+
white-space: pre-wrap; /* Wrap long lines to fit visible boundaries */
355+
word-wrap: break-word; /* Break long words if needed */
356+
box-sizing: border-box; /* Include padding in width calculation */
351357
352358
&:focus {
353359
outline: none;
@@ -373,12 +379,45 @@ const ReviewNoteInput: React.FC<ReviewNoteInputProps> = React.memo(
373379
({ selection, lineData, lines, filePath, onSubmit, onCancel }) => {
374380
const [noteText, setNoteText] = React.useState("");
375381
const textareaRef = React.useRef<HTMLTextAreaElement>(null);
382+
const containerRef = React.useRef<HTMLDivElement>(null);
376383

377384
// Auto-focus on mount
378385
React.useEffect(() => {
379386
textareaRef.current?.focus();
380387
}, []);
381388

389+
// Constrain container width to match visible scrollport (not scrollable content width)
390+
React.useEffect(() => {
391+
const container = containerRef.current;
392+
if (!container) return;
393+
394+
// Find the scrollable parent (DiffContainer) by walking up the tree
395+
let scrollParent = container.parentElement;
396+
while (scrollParent) {
397+
const style = window.getComputedStyle(scrollParent);
398+
const overflowX = style.overflowX;
399+
if (overflowX === "auto" || overflowX === "scroll") {
400+
break;
401+
}
402+
scrollParent = scrollParent.parentElement;
403+
}
404+
405+
if (!scrollParent) return;
406+
407+
const updateWidth = () => {
408+
// Set container width to scrollport width (clientWidth excludes scrollbar)
409+
container.style.width = `${scrollParent.clientWidth}px`;
410+
};
411+
412+
const observer = new ResizeObserver(updateWidth);
413+
observer.observe(scrollParent);
414+
415+
// Set initial width
416+
updateWidth();
417+
418+
return () => observer.disconnect();
419+
}, []);
420+
382421
// Auto-expand textarea as user types
383422
React.useEffect(() => {
384423
const textarea = textareaRef.current;
@@ -422,7 +461,7 @@ const ReviewNoteInput: React.FC<ReviewNoteInputProps> = React.memo(
422461
};
423462

424463
return (
425-
<InlineNoteContainer>
464+
<InlineNoteContainer ref={containerRef}>
426465
<NoteTextarea
427466
ref={textareaRef}
428467
placeholder="Add a review note to chat (Shift-click + button to select range, Enter to submit, Shift+Enter for newline, Esc to cancel)&#10;j, k to iterate through hunks, m to toggle as read"

0 commit comments

Comments
 (0)