Make menu lists searchable (#1499)

* Searchable font list

* Bug fixes and UX polish for edge cases

* More work, still more bugs to fix

* Don't update highlight when not open

* Bug fixes

* Additional bug fixes and code review

* Fix keyboard input being sent to backend

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
0HyperCube
2024-03-09 10:58:13 +00:00
committed by GitHub
co-authored by Keavon Chambers
parent 4cbba3d92b
commit b31e8f7b6d
12 changed files with 297 additions and 82 deletions
@@ -8,7 +8,7 @@
import IconLabel from "@graphite/components/widgets/labels/IconLabel.svelte";
import TextLabel from "@graphite/components/widgets/labels/TextLabel.svelte";
const DASH_ENTRY = { label: "-" };
const DASH_ENTRY = { value: "", label: "-" };
const dispatch = createEventDispatcher<{ selectedIndex: number }>();
@@ -56,7 +56,7 @@
function unFocusDropdownBox(e: FocusEvent) {
const blurTarget = (e.target as HTMLDivElement | undefined)?.closest("[data-dropdown-input]") || undefined;
if (blurTarget !== self?.div()) open = false;
if (blurTarget !== self?.div?.()) open = false;
}
</script>
@@ -68,7 +68,6 @@
{tooltip}
on:click={() => !disabled && (open = true)}
on:blur={unFocusDropdownBox}
on:keydown={(e) => menuList?.keydown(e, false)}
tabindex={disabled ? -1 : 0}
data-floating-menu-spawner
>
@@ -104,16 +104,7 @@
<!-- TODO: Combine this widget into the DropdownInput widget -->
<LayoutRow class="font-input">
<LayoutRow
class="dropdown-box"
classes={{ disabled }}
styles={{ "min-width": `${minWidth}px` }}
{tooltip}
tabindex={disabled ? -1 : 0}
on:click={toggleOpen}
on:keydown={(e) => menuList?.keydown(e, false)}
data-floating-menu-spawner
>
<LayoutRow class="dropdown-box" classes={{ disabled }} styles={{ "min-width": `${minWidth}px` }} {tooltip} tabindex={disabled ? -1 : 0} on:click={toggleOpen} data-floating-menu-spawner>
<TextLabel class="dropdown-label">{activeEntry?.value || ""}</TextLabel>
<IconLabel class="dropdown-arrow" icon="DropdownArrow" />
</LayoutRow>
@@ -17,6 +17,10 @@
export let centered = false;
export let minWidth = 0;
let className = "";
export { className as class };
export let classes: Record<string, boolean> = {};
let self: FieldInput | undefined;
let editing = false;
@@ -50,11 +54,15 @@
export function focus() {
self?.focus();
}
export function element(): HTMLInputElement | HTMLTextAreaElement | undefined {
return self?.element();
}
</script>
<FieldInput
class="text-input"
classes={{ centered }}
class={`text-input ${className}`.trim()}
classes={{ centered, ...classes }}
styles={{ "min-width": minWidth > 0 ? `${minWidth}px` : undefined }}
{value}
on:value
@@ -71,6 +79,8 @@
<style lang="scss" global>
.text-input {
flex-shrink: 0;
input {
text-align: left;
}