fix(runtime): let per-edge borderDimColor=false override general dim (Ink parity, G16) (#44)

* fix(runtime): let per-edge borderDimColor=false override general dim (Ink parity, G16)

edgeDim now uses `?? generalDim` (nullish) instead of `|| dimAll`, so an explicit per-edge false wins — matching Ink render-border.ts:54. The five borderDimColor prop declarations in Box.ts are changed from bare `Boolean` to `{ type: Boolean, default: undefined }` so Vue does not boolean-coerce absent per-edge dim props to false (Vue only applies absent→false casting when no explicit default is provided), preserving the undefined sentinel needed for the nullish fallback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* chore(parity): ledger — G16 pr-open, reconcile G14 merged

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Yunfei He
2026-05-30 04:19:57 +08:00
committed by GitHub
parent 2e9c938f5f
commit 067826c756
4 changed files with 46 additions and 9 deletions
+15 -5
View File
@@ -117,11 +117,21 @@ const BoxImpl = defineComponent({
// Ink types borderStyle as `keyof Boxes | BoxStyle`; we mirror that here.
borderStyle: [String, Object] as PropType<BorderStyle | BoxStyle>,
borderColor: [String, Array],
borderDimColor: Boolean,
borderTopDimColor: Boolean,
borderBottomDimColor: Boolean,
borderLeftDimColor: Boolean,
borderRightDimColor: Boolean,
// `default: undefined` is intentional and load-bearing: Vue's boolean-casting
// rule coerces absent Boolean props to `false` only when there is no explicit
// default. Adding `default: undefined` suppresses that coercion so absent
// per-edge dim props arrive in the paint pass as `undefined`, not `false`.
// This lets `edgeDim = (perEdge ?? generalDim)` correctly fall back to the
// general value only when the per-edge prop was truly omitted — mirroring
// Ink render-border.ts:54 which uses real-undefined via React's prop model
// (G16). The `Boolean` type is kept so Vue still accepts bare-attribute
// `<Box borderDimColor>` in templates (coerces `""` → `true`) and passes
// TypeScript type-checking for consumers.
borderDimColor: { type: Boolean as PropType<boolean | undefined>, default: undefined },
borderTopDimColor: { type: Boolean as PropType<boolean | undefined>, default: undefined },
borderBottomDimColor: { type: Boolean as PropType<boolean | undefined>, default: undefined },
borderLeftDimColor: { type: Boolean as PropType<boolean | undefined>, default: undefined },
borderRightDimColor: { type: Boolean as PropType<boolean | undefined>, default: undefined },
borderTop: { type: Boolean, default: true },
borderBottom: { type: Boolean, default: true },
borderLeft: { type: Boolean, default: true },
+6 -2
View File
@@ -354,12 +354,16 @@ function drawBorder(
const right = props["borderRight"] !== false;
const borderColor = props["borderColor"] as string | undefined;
const dimAll = !!props["borderDimColor"];
// Keep the raw (non-coerced) general dim value so per-edge overrides work correctly.
const generalDim = props["borderDimColor"] as boolean | undefined;
function colorizeEdge(s: string, edge: "top" | "bottom" | "left" | "right"): string {
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;
// Use nullish coalescing (not ||) so an explicit per-edge `false` wins over
// generalDim — only `undefined` falls back to the general value.
// Mirrors Ink render-border.ts:54: `borderTopDimColor ?? borderDimColor`.
const edgeDim = (props[`border${capEdge}DimColor`] as boolean | undefined) ?? generalDim;
// Ink parity (render-border.ts:44-52): an edge's background comes only from the
// per-edge or general border background — never from the Box's own backgroundColor.
const edgeBg =