feat(runtime): add per-side border dim and background color props

Adds borderTopDimColor/borderBottomDimColor/borderLeftDimColor/
borderRightDimColor and borderBackgroundColor with per-side variants.
Refactors drawBorder to use per-edge colorizers that respect
edge-specific color, dim, and background overrides.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Yunfei He
2026-05-25 20:46:47 +08:00
parent 1503c18a66
commit ffb5d69b0b
3 changed files with 43 additions and 8 deletions
+9
View File
@@ -69,6 +69,10 @@ export const Box = defineComponent({
borderStyle: String as PropType<BorderStyle>, borderStyle: String as PropType<BorderStyle>,
borderColor: [String, Array], borderColor: [String, Array],
borderDimColor: Boolean, borderDimColor: Boolean,
borderTopDimColor: Boolean,
borderBottomDimColor: Boolean,
borderLeftDimColor: Boolean,
borderRightDimColor: Boolean,
borderTop: { type: Boolean, default: true }, borderTop: { type: Boolean, default: true },
borderBottom: { type: Boolean, default: true }, borderBottom: { type: Boolean, default: true },
borderLeft: { type: Boolean, default: true }, borderLeft: { type: Boolean, default: true },
@@ -77,6 +81,11 @@ export const Box = defineComponent({
borderBottomColor: [String, Array], borderBottomColor: [String, Array],
borderLeftColor: [String, Array], borderLeftColor: [String, Array],
borderRightColor: [String, Array], borderRightColor: [String, Array],
borderBackgroundColor: [String, Array],
borderTopBackgroundColor: [String, Array],
borderBottomBackgroundColor: [String, Array],
borderLeftBackgroundColor: [String, Array],
borderRightBackgroundColor: [String, Array],
backgroundColor: [String, Array], backgroundColor: [String, Array],
overflow: String as PropType<"visible" | "hidden">, overflow: String as PropType<"visible" | "hidden">,
+9
View File
@@ -45,6 +45,15 @@ const STYLE_PROPS = new Set([
"borderBottomColor", "borderBottomColor",
"borderLeftColor", "borderLeftColor",
"borderRightColor", "borderRightColor",
"borderTopDimColor",
"borderBottomDimColor",
"borderLeftDimColor",
"borderRightDimColor",
"borderBackgroundColor",
"borderTopBackgroundColor",
"borderBottomBackgroundColor",
"borderLeftBackgroundColor",
"borderRightBackgroundColor",
// Per-edge toggles are dual: yoga uses them to size border space, paint // Per-edge toggles are dual: yoga uses them to size border space, paint
// uses them to decide which edges to draw. // uses them to decide which edges to draw.
"borderTop", "borderTop",
+25 -8
View File
@@ -128,24 +128,41 @@ function drawBorder(
const borderColor = props["borderColor"] as string | undefined; const borderColor = props["borderColor"] as string | undefined;
const bgColor = props["backgroundColor"] as string | undefined; const bgColor = props["backgroundColor"] as string | undefined;
const colorProps: TextProps = {}; const dimAll = !!props["borderDimColor"];
if (borderColor) colorProps.color = borderColor;
if (bgColor) colorProps.backgroundColor = bgColor; function colorizeEdge(s: string, edge: "top" | "bottom" | "left" | "right"): string {
const colorize = (s: string) => (borderColor || bgColor ? applyChalk(s, colorProps) : s); const capEdge = edge.charAt(0).toUpperCase() + edge.slice(1);
const edgeColor = (props[`border${capEdge}Color`] as string | undefined) ?? borderColor;
const edgeDim = (props[`border${capEdge}DimColor`] as boolean | undefined) || dimAll;
const edgeBg =
(props[`border${capEdge}BackgroundColor`] as string | undefined) ??
(props["borderBackgroundColor"] as string | undefined) ??
bgColor;
const p: TextProps = {};
if (edgeColor) p.color = edgeColor;
if (edgeBg) p.backgroundColor = edgeBg;
if (edgeDim) p.dimColor = true;
return Object.keys(p).length > 0 ? applyChalk(s, p) : s;
}
if (top) { if (top) {
const tl = left ? chars.topLeft : chars.top; const tl = left ? chars.topLeft : chars.top;
const tr = right ? chars.topRight : chars.top; const tr = right ? chars.topRight : chars.top;
output.write(x, y, [colorize(tl + chars.top.repeat(w - 2) + tr)], transformers); output.write(x, y, [colorizeEdge(tl + chars.top.repeat(w - 2) + tr, "top")], transformers);
} }
if (bottom) { if (bottom) {
const bl = left ? chars.bottomLeft : chars.bottom; const bl = left ? chars.bottomLeft : chars.bottom;
const br = right ? chars.bottomRight : chars.bottom; const br = right ? chars.bottomRight : chars.bottom;
output.write(x, y + h - 1, [colorize(bl + chars.bottom.repeat(w - 2) + br)], transformers); output.write(
x,
y + h - 1,
[colorizeEdge(bl + chars.bottom.repeat(w - 2) + br, "bottom")],
transformers,
);
} }
for (let i = 1; i < h - 1; i++) { for (let i = 1; i < h - 1; i++) {
if (left) output.write(x, y + i, [colorize(chars.left)], transformers); if (left) output.write(x, y + i, [colorizeEdge(chars.left, "left")], transformers);
if (right) output.write(x + w - 1, y + i, [colorize(chars.right)], transformers); if (right) output.write(x + w - 1, y + i, [colorizeEdge(chars.right, "right")], transformers);
} }
} }