import { CSSProperties, Ref, RefObject } from 'react';
import { AsyncAdditionalProps } from 'react-select/dist/declarations/src/useAsync';
import { Placement } from '@popperjs/core';
import { MenuProps } from '@parlor/components/select-v4';
import { ModelWithId } from '../exported-compositions';
import { Option } from '../select';
export type LoadSelectOptions<T extends Record<'id', string> = Record<'id', string>, F extends Record<any, any> = Record<any, any>> = (options?: {
    [key: string]: any;
    filter?: F;
    nextToken?: string;
    pageSize?: number;
    parent?: ModelWithId;
    searchTerm?: string;
}) => Promise<{
    data: T[];
    nextToken?: string;
}>;
export type Selectable<T extends Option = Option, IsMulti extends boolean = false, P = Partial<T>> = MenuProps<T> & Omit<AsyncAdditionalProps<T, any>, 'defaultOptions' | 'loadOptions'> & {
    defaultValue?: T;
    extraOptions?: ({
        Component?: (option: P) => JSX.Element;
    } & P)[];
    filterOptions?: {
        ignoreAccents?: boolean;
        ignoreCase?: boolean;
        matchFrom?: 'any' | 'start';
        stringify?: (option: {
            data: T;
            label?: string;
        }) => string;
        trim?: boolean;
    };
    /** isThreeDots - used to make long selector box text displayed with three dots*/
    isThreeDots?: boolean;
    loadOptions?: LoadSelectOptions<T>;
    noOptionsMessage?(): JSX.Element | string;
    onBlur?(): void;
    onChange?(v: IsMulti extends true ? T[] : T | null): void;
    onCreate?(value: string): Promise<T>;
    onInputChange?(searchTerm: string): void;
    onMenuClose?(): void;
    onMenuOpen?(): void;
    onMenuScrollToBottom?(): void;
    onSearch?: (value: string) => void;
    options?: T[];
    placeholder?: string;
    selectorControlsRef?: Ref<SelectControls<T>>;
    /** @description use this if you want to select an option which resets the value */
    showPlaceholderWhen?: (option: T) => boolean;
    value?: T;
    wrap?: boolean;
};
export type SelectControls<T extends Record<string, any> = Record<string, any>> = {
    getValue: () => T | T[];
    onChange: (v: T | T[]) => void;
};
export type OriginalMenuProps<T extends Option> = {
    getMenuWidth?: (menReferenceElement: RefObject<HTMLDivElement>) => string | number;
    hideSelectedOptions?: boolean;
    isDisabled?: boolean;
    isError?: boolean;
    isFetched?: boolean;
    isFetching?: boolean;
    menuControlsRef?: Ref<MenuControls>;
    menuPlacement?: Placement;
    menuWidth?: CSSProperties['width'];
    renderMenuFooter?(o: MenuActions): JSX.Element;
    renderMenuHeader?(o: MenuActions): JSX.Element;
    renderOption(option: T): JSX.Element;
};
export type MenuActions = {
    clearValue(): void;
    closeMenu(): void;
};
export type CustomProps<T extends Option = Option> = MenuProps<T> & MenuActions & Pick<MenuControls, 'openMenu' | 'openMenuIfEmpty'> & {
    menuIsWithArrow?: boolean;
    menuReferenceElement: RefObject<HTMLDivElement>;
    name?: string;
    placeholder?: string;
};
export type MenuControls = {
    closeMenu(): void;
    menuIsOpen: boolean;
    openMenu(): void;
    openMenuIfEmpty(e: React.MouseEvent): void;
    toggleMenu(): void;
};
