| 34 | imports: [Combobox, ComboboxPopup, ComboboxWidget, Listbox, Option, OverlayModule], |
| 35 | }) |
| 36 | export class Select implements FormValueControl<string | null> { |
| 37 | readonly value = model<string | null>(null); |
| 38 | |
| 39 | readonly id = input.required<string>({alias: 'selectId'}); |
| 40 | readonly name = input.required<string>(); |
| 41 | readonly options = input.required<SelectOption[]>(); |
| 42 | |
| 43 | readonly listbox = viewChild(Listbox); |
| 44 | readonly combobox = viewChild(Combobox); |
| 45 | |
| 46 | readonly searchString = signal(''); |
| 47 | |
| 48 | readonly popupExpanded = signal(false); |
| 49 | readonly filteredOptions = computed(() => { |
| 50 | const search = this.searchString().toLowerCase(); |
| 51 | if (!search) { |
| 52 | return this.options(); |
| 53 | } |
| 54 | return this.options().filter((option) => option.label.toLowerCase().includes(search)); |
| 55 | }); |
| 56 | |
| 57 | readonly displayValue = computed(() => { |
| 58 | const currentValue = this.value(); |
| 59 | if (currentValue === null) { |
| 60 | return ''; |
| 61 | } |
| 62 | const option = this.options().find((opt) => opt.value === currentValue); |
| 63 | return option ? option.label : ''; |
| 64 | }); |
| 65 | |
| 66 | readonly selectedValues = signal<SelectOptionValue[]>([]); |
| 67 | |
| 68 | constructor() { |
| 69 | afterRenderEffect(() => { |
| 70 | this.listbox()?.scrollActiveItemIntoView(); |
| 71 | }); |
| 72 | } |
| 73 | |
| 74 | onCommit() { |
| 75 | const values = this.selectedValues(); |
| 76 | if (values.length) { |
| 77 | this.value.set(values[0]); |
| 78 | this.popupExpanded.set(false); |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | /** Dismisses the dialog overlay on Escape key. */ |
| 83 | onSearchEscape(event: Event) { |
| 84 | this.popupExpanded.set(false); |
| 85 | this.combobox()?.element.focus(); |
| 86 | } |
| 87 | |
| 88 | /** Handles keydown events on the clear button. */ |
| 89 | onKeydown(event: KeyboardEvent): void { |
| 90 | if (event.key === 'Enter') { |
| 91 | this.clear(); |
| 92 | this.popupExpanded.set(false); |
| 93 | event.stopPropagation(); |
nothing calls this directly
no test coverage detected
searching dependent graphs…