From e62c80282966bbd28c66eedf996f7d3438f16aac Mon Sep 17 00:00:00 2001 From: Yunfei He Date: Mon, 25 May 2026 11:24:36 +0800 Subject: [PATCH] fix(paint): continuous backgroundColor with borders - Fill background inside border area only (not under border chars) so border placeLine doesn't overwrite background ANSI codes - Pad text lines to full layout width when inheritedBg is set so background extends past text content to fill the row Co-Authored-By: Claude Opus 4.7 (1M context) --- packages/runtime/src/paint/paint.ts | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/packages/runtime/src/paint/paint.ts b/packages/runtime/src/paint/paint.ts index 8978f6f..8c05f4c 100644 --- a/packages/runtime/src/paint/paint.ts +++ b/packages/runtime/src/paint/paint.ts @@ -195,12 +195,17 @@ function paintNode( const w = Math.max(0, Math.floor(layout.width)); const h = Math.max(0, Math.floor(layout.height)); const bg = (node.props["backgroundColor"] as string | undefined) ?? inheritedBg; - if (node.props["backgroundColor"]) { - fillBackground(output, x, y, w, h, node.props["backgroundColor"], transformers); - } if (node.props["borderStyle"]) { drawBorder(output, x, y, w, h, node.props, transformers); } + if (bg) { + const hasBorder = !!node.props["borderStyle"]; + const bt = hasBorder && node.props["borderTop"] !== false ? 1 : 0; + const bb = hasBorder && node.props["borderBottom"] !== false ? 1 : 0; + const bl = hasBorder && node.props["borderLeft"] !== false ? 1 : 0; + const br = hasBorder && node.props["borderRight"] !== false ? 1 : 0; + fillBackground(output, x + bl, y + bt, w - bl - br, h - bt - bb, bg, transformers); + } for (const child of node.children) paintNode(child, output, x, y, transformers, bg); return; } @@ -208,11 +213,16 @@ function paintNode( const layout = node.yoga.getComputedLayout(); const bgProps: TextProps = inheritedBg ? { backgroundColor: inheritedBg } : {}; const text = renderTextWithInlineStyles(node, bgProps); - const wrapped = wrapText( - text, - Math.max(1, Math.floor(layout.width)), - node.props.wrap ?? "wrap", - ); + const cellWidth = Math.max(1, Math.floor(layout.width)); + const wrapped = wrapText(text, cellWidth, node.props.wrap ?? "wrap"); + if (inheritedBg) { + for (let i = 0; i < wrapped.length; i++) { + const lineW = stringWidth(wrapped[i]!); + if (lineW < cellWidth) { + wrapped[i] = wrapped[i]! + applyChalk(" ".repeat(cellWidth - lineW), bgProps); + } + } + } output.write(x0 + layout.left, y0 + layout.top, wrapped, transformers); return; }