fix(tui): stabilize dialog mouse selection
This commit is contained in:
parent
33f1b269e9
commit
870a10a7ba
2 changed files with 35 additions and 3 deletions
|
|
@ -283,7 +283,7 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
|
|||
setTimeout(() => {
|
||||
if (filter.length > 0) {
|
||||
moveTo(0, true, false)
|
||||
} else if (current && props.focusCurrent !== false) {
|
||||
} else if (current && props.focusCurrent !== false && store.input !== "mouse") {
|
||||
const currentIndex = flat().findIndex((opt) => isDeepEqual(opt.value, current))
|
||||
if (currentIndex >= 0) {
|
||||
moveTo(currentIndex, true)
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ async function renderSelect(
|
|||
return app
|
||||
}
|
||||
|
||||
async function mountSelect(root: string, initial: DialogSelectOption<string>[]) {
|
||||
async function mountSelect(root: string, initial: DialogSelectOption<string>[], trackCurrent = false) {
|
||||
const state = path.join(root, "state")
|
||||
await mkdir(state, { recursive: true })
|
||||
const config = createTuiResolvedConfig()
|
||||
|
|
@ -105,6 +105,7 @@ async function mountSelect(root: string, initial: DialogSelectOption<string>[])
|
|||
|
||||
function Harness() {
|
||||
const [options, setOptions] = createSignal(initial)
|
||||
const [current, setCurrent] = createSignal(initial[0]?.value)
|
||||
replaceOptions = setOptions
|
||||
|
||||
function Fixture() {
|
||||
|
|
@ -114,7 +115,11 @@ async function mountSelect(root: string, initial: DialogSelectOption<string>[])
|
|||
<DialogSelect
|
||||
title="Mutable options"
|
||||
options={options()}
|
||||
onMove={(option) => moved.push(option.value)}
|
||||
current={trackCurrent ? current() : undefined}
|
||||
onMove={(option) => {
|
||||
moved.push(option.value)
|
||||
if (trackCurrent) setCurrent(option.value)
|
||||
}}
|
||||
onSelect={(option) => selected.push(option.value)}
|
||||
/>
|
||||
)),
|
||||
|
|
@ -272,3 +277,30 @@ test("selects a repopulated option after removing the only option", async () =>
|
|||
select.app.renderer.destroy()
|
||||
}
|
||||
})
|
||||
|
||||
test("hover stays on the row when current follows selection", async () => {
|
||||
await using tmp = await tmpdir()
|
||||
const select = await mountSelect(
|
||||
tmp.path,
|
||||
["first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth"].map((value) => ({
|
||||
title: value,
|
||||
value,
|
||||
})),
|
||||
true,
|
||||
)
|
||||
|
||||
try {
|
||||
await select.app.mockMouse.moveTo(20, 11)
|
||||
await select.app.flush()
|
||||
await select.app.mockMouse.moveTo(20, 12)
|
||||
await select.app.waitFor(() => select.moved.includes("second"))
|
||||
select.moved.length = 0
|
||||
await select.app.mockMouse.moveTo(20, 14)
|
||||
await select.app.waitFor(() => select.moved.length > 0)
|
||||
await select.app.waitForVisualIdle()
|
||||
|
||||
expect(select.moved).toEqual(["fourth"])
|
||||
} finally {
|
||||
select.app.renderer.destroy()
|
||||
}
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue