92 lines
1.9 KiB
Svelte
92 lines
1.9 KiB
Svelte
|
<script lang="ts">
|
||
|
import { tick } from "svelte";
|
||
|
import Input from "./Input.svelte";
|
||
|
|
||
|
export let value = "";
|
||
|
export let type: "entity" | "attribute" | "value";
|
||
|
|
||
|
let options = [];
|
||
|
async function updateOptions(query: string) {
|
||
|
switch (type) {
|
||
|
case "entity":
|
||
|
throw new Error("unimplemented");
|
||
|
case "attribute":
|
||
|
const req = await fetch("/api/all/attributes");
|
||
|
const allAttributes: string[] = await req.json();
|
||
|
options = allAttributes.filter((attr) =>
|
||
|
attr.toLowerCase().includes(query.toLowerCase())
|
||
|
);
|
||
|
break;
|
||
|
case "value":
|
||
|
throw new Error("unimplemented");
|
||
|
}
|
||
|
}
|
||
|
$: updateOptions(value);
|
||
|
|
||
|
let inputFocused = false;
|
||
|
let hover = false;
|
||
|
$: visible = (inputFocused || hover) && Boolean(options.length);
|
||
|
</script>
|
||
|
|
||
|
<div class="selector">
|
||
|
<Input bind:value on:focusChange={(ev) => (inputFocused = ev.detail)} />
|
||
|
<ul
|
||
|
class="options"
|
||
|
class:visible
|
||
|
on:mouseenter={() => (hover = true)}
|
||
|
on:mouseleave={() => (hover = false)}
|
||
|
>
|
||
|
{#each options as option}
|
||
|
<li
|
||
|
on:click={() => {
|
||
|
value = option;
|
||
|
visible = false;
|
||
|
}}
|
||
|
>
|
||
|
{option}
|
||
|
</li>
|
||
|
{/each}
|
||
|
</ul>
|
||
|
</div>
|
||
|
|
||
|
<style lang="scss">
|
||
|
.selector {
|
||
|
position: relative;
|
||
|
}
|
||
|
|
||
|
.options {
|
||
|
position: absolute;
|
||
|
list-style: none;
|
||
|
margin: 0;
|
||
|
padding: 0;
|
||
|
border: 1px solid var(--foreground-lighter);
|
||
|
width: 100%;
|
||
|
border-radius: 4px;
|
||
|
margin-top: 2px;
|
||
|
background: var(--background);
|
||
|
font-size: smaller;
|
||
|
|
||
|
visibility: hidden;
|
||
|
opacity: 0;
|
||
|
|
||
|
transition: opacity 0.2s;
|
||
|
|
||
|
z-index: 99;
|
||
|
|
||
|
&.visible {
|
||
|
visibility: visible;
|
||
|
opacity: 1;
|
||
|
}
|
||
|
|
||
|
li {
|
||
|
cursor: pointer;
|
||
|
padding: 0.5em;
|
||
|
|
||
|
transition: background-color 0.2s;
|
||
|
&:hover {
|
||
|
background-color: var(--background-lighter);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
</style>
|