import { blue, underline, yellow } from "./deps.ts";import { Figures } from "./figures.ts";import { GenericList, GenericListKeys, GenericListOption, GenericListOptions, GenericListOptionSettings, GenericListSettings,} from "./_generic_list.ts";import { GenericPrompt } from "./_generic_prompt.ts";
export type SelectKeys = GenericListKeys;
export type SelectOption = GenericListOption;
export type SelectOptionSettings = GenericListOptionSettings;
export type SelectValueOptions = (string | SelectOption)[];export type SelectValueSettings = SelectOptionSettings[];
export interface SelectOptions extends GenericListOptions<string, string> { options: SelectValueOptions; keys?: SelectKeys;}
export interface SelectSettings extends GenericListSettings<string, string> { options: SelectValueSettings; keys?: SelectKeys;}
export class Select<TSettings extends SelectSettings = SelectSettings> extends GenericList<string, string, TSettings> { protected listIndex: number = this.getListIndex(this.settings.default);
public static inject(value: string): void { GenericPrompt.inject(value); }
public static prompt(options: SelectOptions): Promise<string> { return new this({ pointer: blue(Figures.POINTER_SMALL), prefix: yellow("? "), indent: " ", listPointer: blue(Figures.POINTER), maxRows: 10, searchLabel: blue(Figures.SEARCH), ...options, options: Select.mapOptions(options), }).prompt(); }
protected static mapOptions(options: SelectOptions): SelectValueSettings { return options.options .map((item: string | SelectOption) => typeof item === "string" ? { value: item } : item ) .map((item) => this.mapOption(item)); }
protected input(): string { return underline(blue(this.inputValue)); }
protected getListItem( item: SelectOptionSettings, isSelected?: boolean, ): string { let line = this.settings.indent; line += isSelected ? `${this.settings.listPointer} ` : " "; line += `${ isSelected && !item.disabled ? this.highlight(item.name, (val) => val) : this.highlight(item.name) }`; return line; }
protected getValue(): string { return this.options[this.listIndex]?.value ?? this.settings.default; }
protected validate(value: string): boolean | string { return typeof value === "string" && value.length > 0 && this.options.findIndex((option: SelectOptionSettings) => option.value === value ) !== -1; }
protected transform(value: string): string { return value.trim(); }
protected format(value: string): string { return this.getOptionByValue(value)?.name ?? value; }}