import * as _inquirer_type from '@inquirer/type';
import { Prettify, PartialDeep } from '@inquirer/type';
import { Separator, Theme } from '@inquirer/core';
export { Separator } from '@inquirer/core';

type SelectOption<Value> = {
    name?: string;
    value: Value;
    disabled?: boolean | string;
};
/**
 * @internal
 */
type SelectedOption<Value> = SelectOption<Value> & {
    focused?: boolean;
};
declare enum SelectStatus {
    UNLOADED = "unloaded",
    FILTERING = "filtering",
    LOADED = "loaded",
    SUBMITTED = "submitted"
}
type SelectItem<Value> = Separator | SelectOption<Value>;
/**
 * @internal
 */
type InternalSelectItem<Value> = Separator | (SelectOption<Value> & {
    checked?: boolean;
});
type SelectTheme = {
    icon: {
        checked: string;
        unchecked: string;
        cursor: string;
        inputCursor: string;
    };
    style: {
        disabledOption: (text: string) => string;
        renderSelectedOptions: <T>(selectedOptions: ReadonlyArray<SelectedOption<T>>, allOptions: ReadonlyArray<SelectItem<T>>) => string;
        emptyText: (text: string) => string;
        placeholder: (text: string) => string;
    };
    helpMode: 'always' | 'never' | 'auto';
};
type SelectValue<Value, Multiple> = Multiple extends true ? Value[] : Value | null;
type SelectFilterItems<Value> = (input?: string) => Promise<ReadonlyArray<SelectItem<Value>>> | ReadonlyArray<SelectItem<Value>>;
/**
 * Options of useSelect
 */
interface UseSelectOptions<Value, Multiple extends boolean = true> {
    /**
     * The options displayed can be an array or an async function.
     */
    options: ReadonlyArray<SelectItem<Value>> | SelectFilterItems<Value>;
    /**
     * Whether to enable the filter function
     *
     * @defaultValue
     * `true`
     */
    filter?: boolean;
    /**
     * Clear the filter input when the option is selected (also causes the option list to change)
     *
     * @defaultValue
     * `false`
     */
    clearInputWhenSelected?: boolean;
    /**
     * Only valid when multiple is true, confirmation is required when deleting selectable options
     *
     * @defaultValue
     * `false`
     */
    confirmDelete?: boolean;
    /**
     * Enable toggle all options
     *
     * @defaultValue
     * `false`
     */
    canToggleAll?: boolean;
    /**
     * The user's input is debounced, and the default debounce delay is 200ms.
     *
     * @defaultValue
     * `200` ms
     */
    inputDelay?: number;
    /**
     * display options in a loop
     *
     * @defaultValue
     * `false`
     */
    loop?: boolean;
    /**
     * Determine whether two options are equivalent,
     *
     * @defaultValue
     * `(a, b) => (a === b)`;
     */
    equals?: (a: Value, b: Value) => boolean;
    /**
     * Default selected options
     */
    defaultValue?: SelectValue<Value, Multiple>;
    /**
     * triggered after the user completes the selection (or skips)
     */
    onSubmitted?: (value: SelectValue<Value, Multiple>) => void;
    /**
     * Required(true), or skip(false)
     *
     * @defaultValue
     * `false`
     */
    required?: boolean;
    /**
     * select multiple options
     *
     * @defaultValue
     * `true`
     */
    multiple?: Multiple;
    /**
     * Select the currently focused option when submitting (press enter), if no other options are already selected.
     *
     * @defaultValue
     * `false`
     */
    selectFocusedOnSubmit?: boolean;
    /**
     * validate when submitting (press enter). Only when true is returned will the validation pass.
     *
     * @defaultValue
     * `() => true`
     */
    validate?: (options: ReadonlyArray<SelectOption<Value>>) => boolean | string | Promise<string | boolean>;
}
interface SelectBehaviors {
    submit: boolean;
    select: boolean;
    deselect: boolean;
    setCursor: boolean;
    filter: boolean;
    deleteOption: boolean;
    blur: boolean;
}
interface UseSelectReturnValue<Value> {
    selections: SelectOption<Value>[];
    focusedSelection: number;
    confirmDelete: boolean;
    filterInput: string;
    displayItems: ReadonlyArray<InternalSelectItem<Value>>;
    cursor: number;
    status: SelectStatus;
    error: string;
    loop: boolean;
    multiple: boolean;
    enableFilter: boolean;
    canToggleAll: boolean;
    required: boolean;
    behaviors: SelectBehaviors;
}
/**
 * @internal
 */
interface SelectContext<Value> extends UseSelectReturnValue<Value> {
    theme: Prettify<Theme<SelectTheme>>;
    pageSize: number;
    instructions: SelectProps<Value>['instructions'];
    emptyText: string;
    placeholder: string;
}
interface SelectProps<Value, Multiple extends boolean = true> extends UseSelectOptions<Value, Multiple> {
    /**
     * prompt message
     */
    message: string;
    /**
     * page size
     */
    pageSize?: number;
    /**
     * Pass in false to directly close the instructions.
     * If you need to display dynamic instructions based on the state of the select,
     * you can also use the function.
     */
    instructions?: boolean | ((context: SelectContext<Value>) => string);
    /**
     * The text displayed when the search results are empty
     *
     * @defaultValue
     * `"No results."`
     */
    emptyText?: string;
    /**
     * filter input placeholder
     *
     * @defaultValue
     * `"Type to search"`
     */
    placeholder?: string;
    /**
     * theming
     */
    theme?: PartialDeep<Theme<SelectTheme>>;
}

/**
 * @beta
 * @group API
 */
declare function useSelect<Value, Multiple extends boolean>(props: UseSelectOptions<Value, Multiple>): UseSelectReturnValue<Value>;

/**
 * An inquirer select that supports multiple selections and filtering
 * @public
 * @group API
 * @example
 * ```ts
 * import { select } from 'inquirer-select-pro';
 * const answer = await select({
 *   message: 'select',
 *   options: async (input) => {
 *     const res = await fetch('<url>', {
 *        body: new URLSearchParams({ keyword: input }),
 *     });
 *     if (!res.ok) throw new Error('fail to get list!');
 *     return await res.json();
 *   },
 * });
 * ```
 */
declare const select: <Value, Multiple extends boolean = true>(config: {
    message: string;
    pageSize?: number | undefined;
    instructions?: boolean | ((context: SelectContext<Value>) => string) | undefined;
    emptyText?: string | undefined;
    placeholder?: string | undefined;
    theme?: {
        icon?: {
            checked?: string | undefined;
            unchecked?: string | undefined;
            cursor?: string | undefined;
            inputCursor?: string | undefined;
        } | undefined;
        style?: {
            disabledOption?: {} | undefined;
            renderSelectedOptions?: {} | undefined;
            emptyText?: {} | undefined;
            placeholder?: {} | undefined;
            answer?: {} | undefined;
            message?: {} | undefined;
            error?: {} | undefined;
            defaultAnswer?: {} | undefined;
            help?: {} | undefined;
            highlight?: {} | undefined;
            key?: {} | undefined;
        } | undefined;
        helpMode?: "auto" | "always" | "never" | undefined;
        prefix?: string | undefined;
        spinner?: {
            interval?: number | undefined;
            frames?: (string | undefined)[] | undefined;
        } | undefined;
    } | undefined;
    options: readonly SelectItem<Value>[] | SelectFilterItems<Value>;
    filter?: boolean | undefined;
    clearInputWhenSelected?: boolean | undefined;
    confirmDelete?: boolean | undefined;
    canToggleAll?: boolean | undefined;
    inputDelay?: number | undefined;
    loop?: boolean | undefined;
    equals?: ((a: Value, b: Value) => boolean) | undefined;
    defaultValue?: SelectValue<Value, Multiple> | undefined;
    onSubmitted?: ((value: SelectValue<Value, Multiple>) => void) | undefined;
    required?: boolean | undefined;
    multiple?: Multiple | undefined;
    selectFocusedOnSubmit?: boolean | undefined;
    validate?: ((options: readonly SelectOption<Value>[]) => string | boolean | Promise<string | boolean>) | undefined;
}, context?: _inquirer_type.Context | undefined) => _inquirer_type.CancelablePromise<SelectValue<Value, Multiple>>;

export { type InternalSelectItem, type SelectBehaviors, type SelectContext, type SelectFilterItems, type SelectItem, type SelectOption, type SelectProps, SelectStatus, type SelectTheme, type SelectValue, type SelectedOption, type UseSelectOptions, type UseSelectReturnValue, select, useSelect };
