import type { ReactNode, ReactPortal, AriaAttributes, HTMLAttributes } from 'react';
import React from 'react';
import type { ButtonUse } from '../Button';
import type { Nullable } from '../../typings/utility-types';
import type { Theme, ThemeIn } from '../../lib/theming/Theme';
import type { CommonProps } from '../../internal/CommonWrapper';
import type { TGetRootNode } from '../../lib/rootNode';
import type { SizeProp } from '../../lib/types/props';
import { type PopupPositionsType } from '../../internal/Popup';
import { Item } from './Item';
export * from './tids';
export interface ButtonParams extends Pick<AriaAttributes, 'aria-describedby' | 'aria-controls' | 'aria-label' | 'aria-expanded'> {
    /** Блокирует компонент. */
    disabled?: boolean;
    /** Задаёт лейбл. */
    label: React.ReactNode;
    /** Задаёт функцию, которая вызывается при клике на компонент. */
    onClick: () => void;
    /** Задает функцию, которая вызывается при нажатии кнопки на клавиатуре. */
    onKeyDown: (event: React.KeyboardEvent<HTMLElement>) => void;
    /** Определяет, открыто ли выпадающее меню. */
    opened: boolean;
    /** Определяет, есть ли Placeholder. */
    isPlaceholder: boolean;
    /** Задает размер контрола. */
    size: SizeProp;
}
export declare const SelectIds: {
    readonly menu: "Select__menu";
};
type SelectItem<TValue, TItem> = [TValue, TItem, React.ReactNode?] | TItem | TValue | React.ReactElement | (() => React.ReactElement);
export interface SelectProps<TValue, TItem> extends CommonProps, Pick<AriaAttributes, 'aria-describedby' | 'aria-label'>, Pick<HTMLAttributes<HTMLElement>, 'id'> {
    /** @ignore */
    _icon?: React.ReactNode;
    /** Отрисовывает кнопку. */
    _renderButton?: (params: ButtonParams) => React.ReactNode;
    /** @ignore */
    corners?: React.CSSProperties;
    /** Значение по умолчанию. */
    defaultValue?: TValue;
    /** Смещение списка относительно поля по горизонтали. При нуле смещения нет, при положительном значении — список сдвигается вправо, при отрицательном — влево.
     * @default 0
     */
    menuOffset?: number;
    /** По умолчанию список рендерится через [паттерн Portal](https://react.dev/reference/react-dom/createPortal). Проп отключает использование Portal и список рендерится как обычный блок с абсолютным позиционированием внутри компонента. */
    disablePortal?: boolean;
    /** Блокирует раскрывающийся список. */
    disabled?: boolean;
    /** Меняет визуальное отображение раскрывающегося списка на состояние ошибки. Может быть полезен при разработке собственной валидации, если вы не используете пакет [React UI Validations](https://tech.skbkontur.ru/kontur-ui/?path=/docs/react-ui-validations_displaying-getting-started--docs). */
    error?: boolean;
    /** Отфильтровывает элементы по заданному паттерну. */
    filterItem?: (value: TValue, item: TItem, pattern: string) => boolean;
    /** Набор значений. Поддерживаются любые перечисляемые типы, в том числе `Array`, `Map`, `Immutable.Map`.
     *
     * Элементы воспринимаются следующим образом:
     * - если элемент — это массив, то первый элемент является значением, второй — отображается в списке, а третий – комментарий;
     * - если элемент не является массивом, то он используется и для отображения, и для значения.
     *
     * Для вставки разделителя между значениями можно использовать `Select.SEP`.
     *
     * @example
     * Вставить невыделяемый элемент со своей разметкой можно так:
     * ```
     * <Select ...
     *   items={[Select.staticElement(() => <div>My Element</div>)]}
     * />
     * ```
     * @example
     * Чтобы добавить стандартный отступ для статического элемента:
     * ```
     * <Select.Item>My Element</Select.Item>
     * ``` */
    items?: Array<SelectItem<TValue, TItem>>;
    /** Максимальная высота раскрывающегося списка. */
    maxMenuHeight?: number;
    /** Максимальная ширина кнопки. */
    maxWidth?: React.CSSProperties['maxWidth'];
    /** Список значений, определяющих расположение списка относительно кнопки. Если во всех позициях список выходит за пределы `viewport`, будет использована первая из этого списка.
     *
     * `"top left"`, `"top center"`, `"top right"`, `"right top"`, `"right middle"`, `"right bottom"`, `"bottom left"`, `"bottom center"`, `"bottom right"`, `"left top"`, `"left middle"`, `"left bottom"`.
     * @default ['bottom left', 'bottom right', 'top left', 'top right'] */
    positions?: PopupPositionsType[];
    /** Фиксирует расположение списка относительно кнопки. */
    menuPos?: 'top' | 'bottom' | 'middle';
    /** Выравнивание списка. */
    menuAlign?: 'left' | 'right';
    /** Ширина списка. */
    menuWidth?: React.CSSProperties['width'];
    /** Событие изменения значения (`value`) в поле. */
    onValueChange?: (value: TValue) => void;
    /** Событие закрытия меню. */
    onClose?: () => void;
    /** Событие наведения мышкой (событие `onmouseenter`). Смотрите разницу с `onMouseOver` в [документации](https://learn.javascript.ru/mousemove-mouseover-mouseout-mouseenter-mouseleave). */
    onMouseEnter?: (e: React.MouseEvent<HTMLElement>) => void;
    /** Событие ухода мышки с объекта (событие `onmouseleave`). */
    onMouseLeave?: (e: React.MouseEvent<HTMLElement>) => void;
    /** Событие наведения мышкой (событие `onmouseover`). */
    onMouseOver?: (e: React.MouseEvent<HTMLElement>) => void;
    /** Событие нажатия кнопки на клавиатуре. */
    onKeyDown?: (e: React.KeyboardEvent<HTMLElement>) => void;
    /** Событие открытия меню. */
    onOpen?: () => void;
    /** Текст, который отображается если не введено никакое значение. */
    placeholder?: React.ReactNode;
    /** Отрисовывает элементы в списке. */
    renderItem?: (value: TValue, item?: TItem) => React.ReactNode;
    /** Отрисовывает выбранный элемент. */
    renderValue?: (value: TValue, item?: TItem) => React.ReactNode;
    /** Сравнивает `value` с элементом из `items`. */
    areValuesEqual?: (value1: TValue, value2: TValue) => boolean;
    /** Отображает строчку поиска в списке значений. */
    search?: boolean;
    /** Задаёт значение. */
    value?: TValue;
    /** Объект с переменными темы. */
    theme?: ThemeIn | Theme;
    /** Ширина раскрывающегося списка. */
    width?: number | string;
    /** Меняет визуальное отображение поля на состояние предупреждения. Может быть полезен при разработке собственной валидации, если вы не используете пакет [React UI Validations](https://tech.skbkontur.ru/kontur-ui/?path=/docs/react-ui-validations_displaying-getting-started--docs). */
    warning?: boolean;
    /** Стиль кнопки. Примеры стилей смотрите [в документации компонента Button](https://tech.skbkontur.ru/kontur-ui/?path=/docs/react-ui_button-button--docs). */
    use?: ButtonUse;
    /** Размер раскрывающегося списка.
     * @default small
     */
    size?: SizeProp;
    /** HTML-событие `onfocus`. */
    onFocus?: React.FocusEventHandler<HTMLElement>;
    /** HTML-событие `onblur`. */
    onBlur?: React.FocusEventHandler<HTMLElement>;
    /** Текст заголовка списка в мобильной версии. */
    mobileMenuHeaderText?: string;
}
export interface SelectState<TValue> {
    opened: boolean;
    searchPattern: string;
    value: Nullable<TValue>;
}
type DefaultProps<TValue, TItem> = Required<Pick<SelectProps<TValue, TItem>, 'renderValue' | 'renderItem' | 'areValuesEqual' | 'filterItem' | 'use'>>;
/**
 * Раскрывающийся список позволяет выбрать значение из заранее известного набора вариантов.
 */
export declare class Select<TValue = {}, TItem = {}> extends React.Component<SelectProps<TValue, TItem>, SelectState<TValue>> {
    static __KONTUR_REACT_UI__: string;
    static displayName: string;
    static defaultProps: DefaultProps<unknown, ReactNode | ReactPortal>;
    static Item: typeof Item;
    static SEP: () => React.JSX.Element;
    static staticElement: (element: React.ReactElement | (() => React.ReactElement)) => React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | (() => React.ReactElement);
    state: SelectState<TValue>;
    private theme;
    private size;
    private isMobileLayout;
    private readonly locale;
    private menu;
    private menuId;
    private buttonElement;
    private getProps;
    getRootNode: TGetRootNode;
    private setRootNode;
    componentDidUpdate(_prevProps: SelectProps<TValue, TItem>, prevState: SelectState<TValue>): void;
    render(): React.JSX.Element;
    /** Открывает раскрывающийся список.
     * @public
     */
    open: () => void;
    /** Закрывает раскрывающийся список.
     * @public
     */
    close: () => void;
    /** Программно устанавливает фокус на кнопку.
     * Появляется фокусная рамка, элемент получает клавиатурные события и воспринимается как текущий элемент для чтения скринридерами.
     * @public
     */
    focus: () => void;
    private getMenuRenderer;
    private renderMain;
    private getDefaultButtonParams;
    private renderLabel;
    private getLeftIconClass;
    private renderDefaultButton;
    private getSelectIconGap;
    private renderMenu;
    private getSearch;
    private renderMobileMenu;
    private getMobileSearch;
    private getMenuItems;
    private popupGetParent;
    private focusInput;
    private debouncedFocusInput;
    private refMenu;
    private toggle;
    private handleKey;
    private handleSearch;
    private select;
    private getValue;
    private mapItems;
    private getItemByValue;
    private areValuesEqual;
    private buttonRef;
    private getButton;
}
