fix(tui): show empty state when a flat picker has no matches (#41585)

This commit is contained in:
Aiden Cline
2026-08-10 14:26:29 -05:00
committed by GitHub
parent ceec9f5b66
commit b62dc4a636
2 changed files with 31 additions and 1 deletions
+1 -1
View File
@@ -212,7 +212,7 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
const flatten = createMemo(() => props.flat && store.filter.length > 0)
const grouped = createMemo<[string, DialogSelectOption<T>[]][]>(() => {
if (flatten()) return [["", filtered()]]
if (flatten()) return filtered().length ? [["", filtered()]] : []
const result = pipe(
filtered(),
groupBy((x) => x.category ?? ""),
@@ -87,6 +87,7 @@ async function mountSelect(
initial: DialogSelectOption<string>[],
current?: string,
focusCurrent?: boolean,
select?: { flat?: boolean },
) {
const state = path.join(root, "state")
await mkdir(state, { recursive: true })
@@ -124,6 +125,7 @@ async function mountSelect(
options={options()}
current={current}
focusCurrent={focusCurrent}
flat={select?.flat}
onMove={(option) => moved.push(option.value)}
onSelect={(option) => selected.push(option.value)}
/>
@@ -367,6 +369,34 @@ test("keeps the current option selected when options reorder", async () => {
}
})
test("shows no-match and still closes after a flat filter goes empty", async () => {
await using tmp = await tmpdir()
const select = await mountSelect(
tmp.path,
[
{ title: "models.dev", value: "models.dev", category: "Projects" },
{ title: "opencode2", value: "opencode2", category: "Projects" },
],
undefined,
undefined,
{ flat: true },
)
try {
await select.app.waitForFrame((frame) => frame.includes("models.dev"))
await select.app.mockInput.typeText("models")
await select.app.waitForFrame((frame) => frame.includes("models.dev") && !frame.includes("opencode2"))
await select.app.mockInput.typeText(" missing")
await select.app.waitForFrame((frame) => frame.includes("No results found"))
expect(select.app.captureCharFrame()).not.toContain("models.dev")
select.app.mockInput.pressEscape()
await select.app.waitForFrame((frame) => !frame.includes("Mutable options") && !frame.includes("No results found"))
} finally {
select.app.renderer.destroy()
}
})
test("keeps the first row selected when current is only a marker", async () => {
await using tmp = await tmpdir()
const project = { title: "project", value: "project" }