import React, { ReactNode } from 'react';
import { AlignType, PopupController } from "./popup/index";
export declare abstract class OptionAdapter<T> {
    abstract valueOf(item: T): string;
    abstract idOf(item: T): string;
    filter(items: T[], text: string): T[];
    renderOption(item: T): ReactNode;
    findById(items: T[], id: string): T | undefined;
    createItem(_value: string): T | null;
}
export declare class StringOptionAdapter extends OptionAdapter<string> {
    valueOf(item: string): string;
    idOf(item: string): string;
    static instance: StringOptionAdapter;
}
export declare class StringOptionAdapterWithCreate extends StringOptionAdapter {
    createItem(value: string): string;
    static instance: StringOptionAdapterWithCreate;
}
export interface ComboBoxLayoutProps<T> {
    buttonRight?: number;
    buttonWidth?: number;
    maxMenuHeight?: number;
    menuClass?: string;
    inputClass?: string;
    optionClass?: string;
    Input?: React.ComponentType<ComboInputProps<T>>;
    Menu?: React.ComponentType<ComboMenuProps<T>>;
    Toggle?: React.ComponentType<ComboToggleProps<T>> | null;
}
export type ComboBoxLayout<T> = Required<ComboBoxLayoutProps<T>>;
export declare function getDefaultComboBoxLayout<T>(fullWidth?: boolean, unstyledInput?: boolean): ComboBoxLayout<T>;
export interface ComboBoxApi<T> {
    open: () => void;
    close: () => void;
    toggle: () => void;
    inputValue: string;
    selectedItem: T | null;
    setInputValue: (value: string) => void;
    focus: () => void;
}
interface ComboBoxProps<T> {
    items: T[];
    adapter: OptionAdapter<T>;
    unstyledInput?: boolean;
    fullWidth?: boolean;
    layout?: ComboBoxLayoutProps<T>;
    placeholder?: string;
    api?: React.MutableRefObject<ComboBoxApi<T> | null>;
    value?: T | null;
    onSelect?: (value: T | null) => void;
    zIndex?: number;
    focusOnMount?: boolean;
    menuGap?: number;
    menuAlign?: AlignType;
}
export declare function ComboBox<T>({ menuAlign, menuGap, focusOnMount, onSelect, value, zIndex, unstyledInput, fullWidth, api, layout: layoutOpts, adapter, items, placeholder }: ComboBoxProps<T>): import("react/jsx-runtime").JSX.Element;
export interface ComboInputProps<T> {
    layout: ComboBoxLayout<T>;
    ctrl: ComboboxController<T>;
    placeholder?: string;
    boxRef?: React.RefObject<HTMLDivElement | null>;
    inputRef?: React.RefObject<HTMLInputElement | null>;
}
export interface ComboToggleProps<T> {
    ctrl: ComboboxController<T>;
    layout: ComboBoxLayout<T>;
}
export interface ComboMenuProps<T> {
    items: T[];
    layout: ComboBoxLayout<T>;
    ctrl: ComboboxController<T>;
    adapter: OptionAdapter<T>;
    fillWidth: boolean;
}
export interface ComboboxControllerProps<ItemT> {
    adapter: OptionAdapter<ItemT>;
    items: ItemT[];
    value?: ItemT | string | null;
    popupId: string;
}
export declare function useComboboxCtrl<ItemT>(props: ComboboxControllerProps<ItemT>): ComboboxController<ItemT>;
declare class ComboboxController<ItemT> {
    private popupId;
    items: ItemT[];
    private adapter;
    onSelect?: (item: ItemT | null) => void;
    private setState?;
    private _selectedItem;
    private _filteredItems;
    private _inputText;
    private _highlightedIndex;
    private _isMenuOpen;
    popupCtrl?: PopupController;
    constructor({ adapter, items, value, popupId }: ComboboxControllerProps<ItemT>);
    withState(setState: (ctrl: ComboboxController<ItemT>) => void): this;
    private clone;
    private updateState;
    get filteredItems(): ItemT[];
    get selectedItem(): ItemT | null;
    set selectedItem(item: ItemT | null);
    get isMenuOpen(): boolean;
    set inputText(inputText: string);
    get inputText(): string;
    set highlightedIndex(index: number | null);
    get highlightedIndex(): number | null;
    openMenu(): void;
    closeMenu(_item?: ItemT | null): void;
    toggleMenu(): void;
    private highlightIndex;
    getMenuProps(): {};
    getToggleButtonProps(): {
        onClick: () => void;
    };
    getItemProps(item: ItemT, index: number): React.HTMLProps<HTMLLIElement>;
    getInputProps(): {
        onClick: () => void;
        onChange: (ev: React.ChangeEvent<HTMLInputElement>) => void;
        value: string;
        onKeyDown: (ev: React.KeyboardEvent<HTMLInputElement>) => void;
    };
}
export {};
//# sourceMappingURL=ComboBox.d.ts.map