60 lines
1.6 KiB
Svelte
60 lines
1.6 KiB
Svelte
<script>
|
|
import { t } from '../translations.svelte.js'
|
|
import { tick } from "svelte";
|
|
|
|
let {
|
|
getCandidates = text => {},
|
|
onSelect = text => []
|
|
} = $props();
|
|
|
|
let text = $state('')
|
|
let options = $state({});
|
|
|
|
async function ondblclick(evt){
|
|
var select = evt.target;
|
|
let key = select.value;
|
|
text = options[key];
|
|
let result = {};
|
|
result[key]=text;
|
|
options={};
|
|
onSelect(result);
|
|
}
|
|
|
|
async function onkeyup(evt){
|
|
var select = evt.target;
|
|
var key = evt.key;
|
|
var ignore = ['Escape','Tab','ArrowUp','ArrowLeft','ArrowRight']
|
|
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);
|
|
console.log({options:options})
|
|
await tick();
|
|
for (let o of select.getElementsByTagName('option')) o.selected = false;
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
select{
|
|
min-width: 200px;
|
|
}
|
|
</style>
|
|
<select size={Object.keys(options).length<2?2:Object.keys(options).length+1} {onkeyup} {ondblclick} autofocus width="40">
|
|
<option>{text}</option>
|
|
{#each Object.entries(options) as [val,caption]}
|
|
<option value={val}>{caption}</option>
|
|
{/each}
|
|
</select>
|
|
|