diff --git a/src/core/gui/ComboBox.ts b/src/core/gui/ComboBox.ts index d526596e..73e8cbb5 100644 --- a/src/core/gui/ComboBox.ts +++ b/src/core/gui/ComboBox.ts @@ -10,8 +10,9 @@ import { WidgetProperty } from "../observable/property/WidgetProperty"; export type ComboBoxOptions = LabelledControlOptions & { items: T[] | Property; - to_label: (item: T) => string; + to_label(item: T): string; placeholder_text?: string; + filter?(text: string): void; }; export class ComboBox extends LabelledControl { @@ -41,6 +42,7 @@ export class ComboBox extends LabelledControl { this.input_element.onmousedown = () => { menu_visible.val = true; }; + this.input_element.onkeydown = (e: Event) => { const key = (e as KeyboardEvent).key; @@ -60,6 +62,24 @@ export class ComboBox extends LabelledControl { break; } }; + + const filter = options.filter; + + if (filter) { + let input_value = ""; + + this.input_element.onkeyup = () => { + if (this.input_element.value !== input_value) { + input_value = this.input_element.value; + filter(input_value); + + if (this.menu.visible.val || input_value) { + this.menu.hover_next(); + } + } + }; + } + this.input_element.onblur = () => { menu_visible.val = false; }; @@ -92,6 +112,12 @@ export class ComboBox extends LabelledControl { this.disposables( this.menu.visible.bind_bi(menu_visible), + menu_visible.observe(({ value: visible }) => { + if (visible) { + this.menu.hover_next(); + } + }), + this.menu.selected.observe(({ value }) => { this.selected.set_val(value, { silent: false }); this.input_element.focus(); diff --git a/src/core/gui/Menu.ts b/src/core/gui/Menu.ts index a1db270d..d2981243 100644 --- a/src/core/gui/Menu.ts +++ b/src/core/gui/Menu.ts @@ -48,6 +48,7 @@ export class Menu extends Widget { el.div({ text: to_label(item), data: { index: index.toString() } }), ), ); + this.hover_item(); }, { call_now: true }, ), @@ -83,7 +84,7 @@ export class Menu extends Widget { if (this.visible.val != visible) { this.hover_item(); - this.inner_element.scrollTo(0, 0); + this.inner_element.scrollTop = 0; } } diff --git a/src/hunt_optimizer/gui/WantedItemsView.ts b/src/hunt_optimizer/gui/WantedItemsView.ts index a87e909f..3e035c03 100644 --- a/src/hunt_optimizer/gui/WantedItemsView.ts +++ b/src/hunt_optimizer/gui/WantedItemsView.ts @@ -23,12 +23,19 @@ export class WantedItemsView extends Widget { super(el.div({ class: "hunt_optimizer_WantedItemsView" })); const huntable_items = list_property(); + const filtered_huntable_items = list_property(); const combo_box = this.disposable( new ComboBox({ - items: huntable_items, + items: filtered_huntable_items, to_label: item_type => item_type.name, placeholder_text: "Add an item", + filter(text: string): void { + const text_lower = text.toLowerCase(); + filtered_huntable_items.val = huntable_items.val.filter(item_type => + item_type.name.toLowerCase().includes(text_lower), + ); + }, }), ); @@ -60,6 +67,7 @@ export class WantedItemsView extends Widget { huntable_items.val = hunt_optimizer_store.huntable_item_types .slice() .sort((a, b) => a.name.localeCompare(b.name)); + filtered_huntable_items.val = huntable_items.val; }, { call_now: true }, ),