fix(runtime): nest Text ANSI styles per-style in Ink's order (Ink parity, G68) (#65)

Ink's Text.tsx transform applies each enabled style as a SEPARATE nested
chalk wrap, in the exact order dim -> color -> backgroundColor -> bold ->
italic -> underline -> strikethrough -> inverse. vue-tui's applyChalk built
ONE chained ChalkInstance (color -> bg -> dim -> bold -> ...) and invoked it
once, producing a different, non-Ink byte sequence for any multi-style Text:
e.g. color+bold emitted [31m[1mX[22m[39m vs Ink's [1m[31mX[39m[22m, and
dim+bold dropped the bold re-open after dim's SGR-22 reset.

Rewrite applyChalk to mirror Ink: apply each style as its own nested chalk(...)
call in Ink's order, reusing the existing color/background resolution. Chalk
level handling (FORCE_COLOR / level 0 -> no codes) is preserved and ANSI codes
remain zero-width, so styled-text measurement is unchanged. Multi-style Text now
produces byte-identical ANSI to Ink.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Yunfei He
2026-05-30 16:42:18 +08:00
committed by GitHub
parent e7992bb06b
commit 6b09a55a6d
4 changed files with 237 additions and 111 deletions
@@ -1340,7 +1340,7 @@ test("borderDimColor does not dim styled child Text touching left edge", async (
);
expect(lastFrame()).toMatchInlineSnapshot(`
"╭───────────╮
│styled text│
│styled text│
╰───────────╯"
`);
});