| function positive_mod(n: number, m: number): number { | |
| return ((n % m) + m) % m; | |
| } | |
| export function handle_filter( | |
| choices: [string, string | number][], | |
| input_text: string | |
| ): number[] { | |
| return choices.reduce((filtered_indices, o, index) => { | |
| if ( | |
| input_text ? o[0].toLowerCase().includes(input_text.toLowerCase()) : true | |
| ) { | |
| filtered_indices.push(index); | |
| } | |
| return filtered_indices; | |
| }, [] as number[]); | |
| } | |
| export function handle_change( | |
| dispatch: any, | |
| value: string | number | (string | number)[] | undefined, | |
| value_is_output: boolean | |
| ): void { | |
| dispatch("change", value); | |
| if (!value_is_output) { | |
| dispatch("input"); | |
| } | |
| } | |
| export function handle_shared_keys( | |
| e: KeyboardEvent, | |
| active_index: number | null, | |
| filtered_indices: number[] | |
| ): [boolean, number | null] { | |
| if (e.key === "Escape") { | |
| return [false, active_index]; | |
| } | |
| if (e.key === "ArrowDown" || e.key === "ArrowUp") { | |
| if (filtered_indices.length >= 0) { | |
| if (active_index === null) { | |
| active_index = | |
| e.key === "ArrowDown" | |
| ? filtered_indices[0] | |
| : filtered_indices[filtered_indices.length - 1]; | |
| } else { | |
| const index_in_filtered = filtered_indices.indexOf(active_index); | |
| const increment = e.key === "ArrowUp" ? -1 : 1; | |
| active_index = | |
| filtered_indices[ | |
| positive_mod(index_in_filtered + increment, filtered_indices.length) | |
| ]; | |
| } | |
| } | |
| } | |
| return [true, active_index]; | |
| } | |