/**
 * To match accessibility requirement, we always provide an input in the component.
 * Other element will not set `tabIndex` to avoid `onBlur` sequence problem.
 * For focused select, we set `aria-live="polite"` to update the accessibility content.
 *
 * ref:
 * - keyboard: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/listbox_role#Keyboard_interactions
 */
import * as React from 'react';
import type { ScrollTo } from '../rc-virtual-list/List';
import type { RenderNode, Mode, RenderDOMFunc } from './interface';
import type { GetLabeledValue, FilterOptions, FilterFunc, DefaultValueType, RawValueType, LabelValueType, Key, FlattenOptionsType, SingleType, OnClear, SelectSource, CustomTagProps } from './interface/generator';
import type { OptionListProps, RefOptionListProps } from './OptionList';
export interface RefSelectProps {
    focus: () => void;
    blur: () => void;
    scrollTo?: ScrollTo;
}
export interface SelectProps<OptionsType extends object[], ValueType> extends React.AriaAttributes {
    prefixCls?: string;
    id?: string;
    className?: string;
    style?: React.CSSProperties;
    options?: OptionsType;
    children?: React.ReactNode;
    mode?: Mode;
    value?: ValueType;
    defaultValue?: ValueType;
    labelInValue?: boolean;
    /** Config max length of input. This is only work when `mode` is `combobox` */
    maxLength?: number;
    inputValue?: string;
    searchValue?: string;
    optionFilterProp?: string;
    /**
     * In Select, `false` means do nothing.
     * In TreeSelect, `false` will highlight match item.
     * It's by design.
     */
    filterOption?: boolean | FilterFunc<OptionsType[number]>;
    filterSort?: (optionA: OptionsType[number], optionB: OptionsType[number]) => number;
    showSearch?: boolean;
    autoClearSearchValue?: boolean;
    onSearch?: (value: string) => void;
    onClear?: OnClear;
    allowClear?: boolean;
    clearIcon?: React.ReactNode;
    showArrow?: boolean;
    inputIcon?: RenderNode;
    removeIcon?: React.ReactNode;
    menuItemSelectedIcon?: RenderNode;
    open?: boolean;
    defaultOpen?: boolean;
    listHeight?: number;
    listItemHeight?: number;
    dropdownStyle?: React.CSSProperties;
    dropdownClassName?: string;
    dropdownMatchSelectWidth?: boolean | number;
    virtual?: boolean;
    dropdownRender?: (menu: React.ReactElement) => React.ReactElement;
    dropdownAlign?: any;
    animation?: string;
    transitionName?: string;
    getPopupContainer?: RenderDOMFunc;
    direction?: string;
    disabled?: boolean;
    loading?: boolean;
    autoFocus?: boolean;
    defaultActiveFirstOption?: boolean;
    notFoundContent?: React.ReactNode;
    placeholder?: React.ReactNode;
    backfill?: boolean;
    getInputElement?: () => JSX.Element;
    optionLabelProp?: string;
    maxTagTextLength?: number;
    maxTagCount?: number | 'responsive';
    maxTagPlaceholder?: React.ReactNode | ((omittedValues: LabelValueType[]) => React.ReactNode);
    tokenSeparators?: string[];
    tagRender?: (props: CustomTagProps) => React.ReactElement;
    showAction?: ('focus' | 'click')[];
    tabIndex?: number;
    onKeyUp?: React.KeyboardEventHandler<HTMLDivElement>;
    onKeyDown?: React.KeyboardEventHandler<HTMLDivElement>;
    onPopupScroll?: React.UIEventHandler<HTMLDivElement>;
    onDropdownVisibleChange?: (open: boolean) => void;
    onSelect?: (value: SingleType<ValueType>, option: OptionsType[number]) => void;
    onDeselect?: (value: SingleType<ValueType>, option: OptionsType[number]) => void;
    onInputKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;
    onClick?: React.MouseEventHandler;
    onChange?: (value: ValueType, option: OptionsType[number] | OptionsType) => void;
    onBlur?: React.FocusEventHandler<HTMLElement>;
    onFocus?: React.FocusEventHandler<HTMLElement>;
    onMouseDown?: React.MouseEventHandler<HTMLDivElement>;
    onMouseEnter?: React.MouseEventHandler<HTMLDivElement>;
    onMouseLeave?: React.MouseEventHandler<HTMLDivElement>;
    choiceTransitionName?: string;
    /**
     * Only used in current version for internal event process.
     * Do not use in production environment.
     */
    internalProps?: {
        mark?: string;
        onClear?: OnClear;
        skipTriggerChange?: boolean;
        skipTriggerSelect?: boolean;
        onRawSelect?: (value: RawValueType, option: OptionsType[number], source: SelectSource) => void;
        onRawDeselect?: (value: RawValueType, option: OptionsType[number], source: SelectSource) => void;
    };
}
export interface GenerateConfig<OptionsType extends object[]> {
    prefixCls: string;
    components: {
        optionList: React.ForwardRefExoticComponent<React.PropsWithoutRef<Omit<OptionListProps<OptionsType>, 'options'> & {
            options: OptionsType;
        }> & React.RefAttributes<RefOptionListProps>>;
    };
    /** Convert jsx tree into `OptionsType` */
    convertChildrenToData: (children: React.ReactNode) => OptionsType;
    /** Flatten nest options into raw option list */
    flattenOptions: (options: OptionsType, props: any) => FlattenOptionsType<OptionsType>;
    /** Convert single raw value into { label, value } format. Will be called by each value */
    getLabeledValue: GetLabeledValue<FlattenOptionsType<OptionsType>>;
    filterOptions: FilterOptions<OptionsType>;
    findValueOption: ((values: RawValueType[], options: FlattenOptionsType<OptionsType>) => OptionsType) | ((values: RawValueType[], options: FlattenOptionsType<OptionsType>, info?: {
        prevValueOptions?: OptionsType[];
    }) => OptionsType);
    /** Check if a value is disabled */
    isValueDisabled: (value: RawValueType, options: FlattenOptionsType<OptionsType>) => boolean;
    warningProps?: (props: any) => void;
    fillOptionsWithMissingValue?: (options: OptionsType, value: DefaultValueType, optionLabelProp: string, labelInValue: boolean) => OptionsType;
    omitDOMProps?: (props: object) => object;
}
/**
 * This function is in internal usage.
 * Do not use it in your prod env since we may refactor this.
 */
export default function generateSelector<OptionsType extends {
    value?: RawValueType;
    label?: React.ReactNode;
    key?: Key;
    disabled?: boolean;
}[]>(config: GenerateConfig<OptionsType>): React.ForwardRefExoticComponent<SelectProps<OptionsType, DefaultValueType> & React.RefAttributes<RefSelectProps>>;
