From bc38d9b8442f932bebd181fad112ec71c11c49d1 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 18 Feb 2026 22:31:35 +0000 Subject: [PATCH] refactor(tui): share select list theme styles --- src/tui/theme/theme.test.ts | 23 ++++++++++++++++++++++- src/tui/theme/theme.ts | 12 +++++------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/tui/theme/theme.test.ts b/src/tui/theme/theme.test.ts index c466241af3..25344bb4be 100644 --- a/src/tui/theme/theme.test.ts +++ b/src/tui/theme/theme.test.ts @@ -7,7 +7,8 @@ const cliHighlightMocks = vi.hoisted(() => ({ vi.mock("cli-highlight", () => cliHighlightMocks); -const { markdownTheme, theme } = await import("./theme.js"); +const { markdownTheme, searchableSelectListTheme, selectListTheme, theme } = + await import("./theme.js"); const stripAnsi = (str: string) => str.replace(new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g"), ""); @@ -59,3 +60,23 @@ describe("theme", () => { expect(stripAnsi(theme.assistantText("hello"))).toBe("hello"); }); }); + +describe("list themes", () => { + it("reuses shared select-list styles in searchable list theme", () => { + expect(searchableSelectListTheme.selectedPrefix(">")).toBe(selectListTheme.selectedPrefix(">")); + expect(searchableSelectListTheme.selectedText("entry")).toBe( + selectListTheme.selectedText("entry"), + ); + expect(searchableSelectListTheme.description("desc")).toBe(selectListTheme.description("desc")); + expect(searchableSelectListTheme.scrollInfo("scroll")).toBe( + selectListTheme.scrollInfo("scroll"), + ); + expect(searchableSelectListTheme.noMatch("none")).toBe(selectListTheme.noMatch("none")); + }); + + it("keeps searchable list specific renderers readable", () => { + expect(stripAnsi(searchableSelectListTheme.searchPrompt("Search:"))).toBe("Search:"); + expect(stripAnsi(searchableSelectListTheme.searchInput("query"))).toBe("query"); + expect(stripAnsi(searchableSelectListTheme.matchHighlight("match"))).toBe("match"); + }); +}); diff --git a/src/tui/theme/theme.ts b/src/tui/theme/theme.ts index 2444cfd78f..9b2f1ad27c 100644 --- a/src/tui/theme/theme.ts +++ b/src/tui/theme/theme.ts @@ -99,7 +99,7 @@ export const markdownTheme: MarkdownTheme = { highlightCode, }; -export const selectListTheme: SelectListTheme = { +const baseSelectListTheme: SelectListTheme = { selectedPrefix: (text) => fg(palette.accent)(text), selectedText: (text) => chalk.bold(fg(palette.accent)(text)), description: (text) => fg(palette.dim)(text), @@ -107,8 +107,10 @@ export const selectListTheme: SelectListTheme = { noMatch: (text) => fg(palette.dim)(text), }; +export const selectListTheme: SelectListTheme = baseSelectListTheme; + export const filterableSelectListTheme = { - ...selectListTheme, + ...baseSelectListTheme, filterLabel: (text: string) => fg(palette.dim)(text), }; @@ -127,11 +129,7 @@ export const editorTheme: EditorTheme = { }; export const searchableSelectListTheme: SearchableSelectListTheme = { - selectedPrefix: (text) => fg(palette.accent)(text), - selectedText: (text) => chalk.bold(fg(palette.accent)(text)), - description: (text) => fg(palette.dim)(text), - scrollInfo: (text) => fg(palette.dim)(text), - noMatch: (text) => fg(palette.dim)(text), + ...baseSelectListTheme, searchPrompt: (text) => fg(palette.accentSoft)(text), searchInput: (text) => fg(palette.text)(text), matchHighlight: (text) => chalk.bold(fg(palette.accent)(text)),