93d032a144
Status presenters (showWarning/showError/showStatus and extension/tool error presenters) baked theme.fg() into Text at construction, so a warning shown while the auto-theme default guess was dark kept the dark-mode color after async appearance detection switched the active theme to light — dark-catppuccin Mocha yellow on the light Latte background (1.12:1 contrast, effectively invisible). Add Text.setStyleFn(), a foreground styler evaluated at render time, and route the transient status presenters through it. Because the coding agent invalidates status components on onThemeChange, a theme swap now re-shapes them against the live theme instead of replaying the palette active when they were constructed. Fixes #6337
37 lines
1.4 KiB
TypeScript
37 lines
1.4 KiB
TypeScript
import { describe, expect, it } from "bun:test";
|
|
import { Text } from "@oh-my-pi/pi-tui/components/text";
|
|
|
|
describe("Text component", () => {
|
|
it("reports whether setText changed the stored text", () => {
|
|
const text = new Text("a");
|
|
|
|
expect(text.setText("a")).toBe(false);
|
|
expect(text.setText("b")).toBe(true);
|
|
expect(text.getText()).toBe("b");
|
|
});
|
|
|
|
it("applies the style fn at render time, not construction time", () => {
|
|
const text = new Text("hello", 0, 0).setStyleFn(t => `<c>${t}</c>`);
|
|
expect(text.render(40).join("\n")).toContain("<c>hello</c>");
|
|
});
|
|
|
|
it("re-resolves the style fn after invalidate so a theme change re-shapes", () => {
|
|
// The styler reads a mutable `color`, standing in for the active theme.
|
|
// The coding-agent invalidates status components on `onThemeChange`, so a
|
|
// lazily-styled Text must pick up the new color on the next render —
|
|
// something a baked ANSI string can never do (issue #6337).
|
|
let color = "RED";
|
|
const text = new Text("hello", 0, 0).setStyleFn(t => `[${color}]${t}`);
|
|
expect(text.render(40).join("\n")).toContain("[RED]hello");
|
|
|
|
// Without invalidation the cached render is returned unchanged.
|
|
color = "BLUE";
|
|
expect(text.render(40).join("\n")).toContain("[RED]hello");
|
|
|
|
text.invalidate();
|
|
const out = text.render(40).join("\n");
|
|
expect(out).toContain("[BLUE]hello");
|
|
expect(out).not.toContain("[RED]hello");
|
|
});
|
|
});
|