mirror of
https://github.com/DaanVandenBosch/phantasmal-world.git
synced 2025-04-04 22:58:29 +08:00
The ComboBox menu can now be filtered by typing.
This commit is contained in:
parent
c8ff72726e
commit
58939b2ff5
@ -10,8 +10,9 @@ import { WidgetProperty } from "../observable/property/WidgetProperty";
|
||||
|
||||
export type ComboBoxOptions<T> = LabelledControlOptions & {
|
||||
items: T[] | Property<T[]>;
|
||||
to_label: (item: T) => string;
|
||||
to_label(item: T): string;
|
||||
placeholder_text?: string;
|
||||
filter?(text: string): void;
|
||||
};
|
||||
|
||||
export class ComboBox<T> extends LabelledControl {
|
||||
@ -41,6 +42,7 @@ export class ComboBox<T> 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<T> 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<T> 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();
|
||||
|
@ -48,6 +48,7 @@ export class Menu<T> 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<T> extends Widget {
|
||||
|
||||
if (this.visible.val != visible) {
|
||||
this.hover_item();
|
||||
this.inner_element.scrollTo(0, 0);
|
||||
this.inner_element.scrollTop = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,12 +23,19 @@ export class WantedItemsView extends Widget {
|
||||
super(el.div({ class: "hunt_optimizer_WantedItemsView" }));
|
||||
|
||||
const huntable_items = list_property<ItemType>();
|
||||
const filtered_huntable_items = list_property<ItemType>();
|
||||
|
||||
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 },
|
||||
),
|
||||
|
Loading…
Reference in New Issue
Block a user