Merge branch 'improvement/autocomplete' into dev

This commit is contained in:
2026-04-24 11:45:39 +02:00
+13 -3
View File
@@ -17,6 +17,7 @@
let selected = $state(null); let selected = $state(null);
let candidates = $state([]); let candidates = $state([]);
let timer = null; let timer = null;
let list_elem;
async function dummyGetCandidates(text){ async function dummyGetCandidates(text){
console.warn(`getCandidates(${text}) not overridden!`); console.warn(`getCandidates(${text}) not overridden!`);
@@ -58,9 +59,8 @@
} }
async function fetchCandidates(){ async function fetchCandidates(){
candidates = await getCandidates(candidate.display); candidates = candidate.display ? await getCandidates(candidate.display) : [];
selected = null; selected = null;
if (selected>candidates.length) selected = candidates.length;
} }
async function onkeyup(ev){ async function onkeyup(ev){
@@ -69,12 +69,14 @@
ev.preventDefault(); ev.preventDefault();
selected = selected == null ? 0: selected +1; selected = selected == null ? 0: selected +1;
if (selected >= candidates.length) selected = 0; if (selected >= candidates.length) selected = 0;
scrollTo(selected);
return false; return false;
} }
if (ev.key == 'ArrowUp'){ if (ev.key == 'ArrowUp'){
ev.preventDefault(); ev.preventDefault();
selected = selected == null ? candidates.length -1 : selected -1; selected = selected == null ? candidates.length -1 : selected -1;
if (selected < 0) selected = candidates.length -1; if (selected < 0) selected = candidates.length -1;
scrollTo(selected);
return false; return false;
} }
if (ev.key == 'Enter'|| ev.key == 'Tab'){ if (ev.key == 'Enter'|| ev.key == 'Tab'){
@@ -113,6 +115,11 @@
onSelect(candidate); onSelect(candidate);
} }
function scrollTo(index){
let list_elements = list_elem.children;
if (list_elements) list_elements[index].scrollIntoView({block:'center'});
}
</script> </script>
<style> <style>
@@ -129,6 +136,9 @@
list-style: none; list-style: none;
padding: 4px; padding: 4px;
margin: 0; margin: 0;
min-width: 400px;
max-height: 200px;
overflow: scroll;
} }
.highlight { background: orange; color: black; } .highlight { background: orange; color: black; }
@@ -137,7 +147,7 @@
<span> <span>
<input type="text" bind:value={candidate.display} {onkeyup} autofocus={autofocus} /> <input type="text" bind:value={candidate.display} {onkeyup} autofocus={autofocus} />
{#if candidates && candidates.length > 0} {#if candidates && candidates.length > 0}
<ul> <ul bind:this={list_elem}>
{#each candidates as candidate,i} {#each candidates as candidate,i}
<li class="option {selected==i?'highlight':''}" onclick={e => selected = i} ondblclick={e => select(i)}>{candidate.display}</li> <li class="option {selected==i?'highlight':''}" onclick={e => selected = i} ondblclick={e => select(i)}>{candidate.display}</li>
{/each} {/each}