Files
Umbrella/frontend/src/Components/Autocomplete.svelte

61 lines
1.7 KiB
Svelte

<script>
import { t } from '../translations.svelte.js'
import { tick } from "svelte";
let {
getCandidates = async text => { conole.log('no handler for getCandidates('+text+')'); return {};},
onSelect = text => []
} = $props();
const ignore = ['Escape','Tab','ArrowUp','ArrowLeft','ArrowRight']
let options = $state({});
let text = $state('')
async function ondblclick(evt){
const select = evt.target;
const key = select.value;
text = options[key];
let result = {};
result[key] = text;
options = {};
text = '';
onSelect(result);
}
async function onkeyup(evt){
const select = evt.target;
const key = evt.key;
if (ignore.includes(key)) return;
if (key == 'ArrowDown'){
if (select.selectedIndex == 0) select.selectedIndex=1;
return;
}
if (key == 'Enter'){
ondblclick(evt);
return;
}
if (key == 'Backspace'){
text = text.substring(0,text.length-1)
} else if (key.length<2){
text += evt.key
}
options = await getCandidates(text);
await tick();
for (let o of select.getElementsByTagName('option')) o.selected = false;
}
</script>
<style>
select{
min-width: 200px;
}
</style>
{#if options}
<select size={Object.keys(options).length<2?2:Object.keys(options).length+1} {onkeyup} {ondblclick} width="40">
<option>{text}</option>
{#each Object.entries(options) as [val,caption]}
<option value={val}>{caption}</option>
{/each}
</select>
{/if}