|
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];
|
|
}
|
|
|