Files
vue-tui/packages/runtime-tests
Yunfei He 6469b08c46 fix(runtime): skip eager visual validation under screen-reader mode (Ink parity) (#197)
assertBoxValid (Box) and text.vue's validate() run eager render-time validation
of paint-time VISUAL props (backgroundColor, border fg/bg colors, borderStyle
shape) and throw into the error boundary on an invalid value (e.g. a chalk
modifier name like "bold" used as a color). They were gated only by the per-node
ariaHidden skip (srHidden), not by GLOBAL screen-reader mode.

Under global SR mode (isScreenReaderEnabled; INK_SCREEN_READER=true) vue-tui,
like Ink, linearizes the whole tree to PLAIN TEXT and never colorizes / draws
borders for any node — Ink's colorize path is bypassed entirely, so it never
throws on an invalid color. vue-tui still ran the eager validation for non-
ariaHidden boxes under SR and threw, crashing a screen-reader user out of
accessible content over a paint-only prop value.

Skip the eager visual validation when global SR is on, in addition to the
existing per-node srHidden skip: box.vue gates `!srHidden && (srEnabled ||
assertBoxValid(props))`, text.vue gates `!srHidden && (srEnabled || validate())
&& hasContent`. The validation is all paint-time visual input (no structural
checks), so skipping it under SR is safe and matches Ink.

Verified against real Ink v7.0.4: with INK_SCREEN_READER=true a
<Box backgroundColor="bold"> renders plain text and does NOT throw; without it
Ink throws in colorize.js. This is an alignment fix (removes a vue-tui
over-throw), not a new divergence — the existing ink-divergences entry gets a
factual, unstamped note about the SR carve-out.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 03:04:54 +08:00
..