import { ReactNode, ChangeEvent, HTMLAttributes, default as React } from 'react';
import { CSSObject } from '@emotion/react';
import { VariableSizeListProps } from 'react-window';
import { InputProps } from '../Input';
import { PropsWithChildren, QA, RequiredQA, getQAAttribute } from '../common';
import { DropdownProps } from '../Dropdown';
import { CheckboxTreeOption } from '../CheckboxTree';
/** Единичное значение - для SingleSelect */
export type SelectSingleValue = string | number;
/** Множественное значение - для Select */
export type SelectMultipleValue = SelectSingleValue[];
/** Option */
export type SelectOption = {
/** Label */
label: string;
/** Иконка
*
*
* Наличие приведет к отключению virtualize
*/
icon?: ReactNode;
/** Дочерние option
*
* Отображаются только при multiple
*
* Наличие приведет к рендеру CheckboxTree
* и отключению virtualize
*/
childs?: SelectOption[];
} & PropsWithChildren & Omit & T;
/** Пропс компонента рендера option */
export type SelectItemProps = {
/** Option */
option: SelectOption;
/** Выбран */
checked: boolean;
} & Pick & Pick, 'style'>;
/** Пропс компонента рендера всех option */
export type SelectItemsProps = {
/** Элементы Option */
options: SelectOption[];
/** Ширина дропдауна в пикселях
*
* используется при virtualize
*/
clientWidth: number | undefined;
} & RequiredQA & Pick & Pick;
/** Пропс компонента рендера контента dropdown */
export type SelectListProps = {
/** Перегружаемые компоненты */
components?: SelectComponents;
};
/** Обработчик изменения значения Select */
export type SelectListOnChange = (
/** Новое значение */
value: SelectMultipleValue,
/** Option на котором произошло событие */
option?: SelectOption,
/** Событие */
event?: ChangeEvent) => void;
/** Обработчик изменения значения SingleSelect */
export type SelectSingleOnChange = (
/** Новое значение */
value: SelectSingleValue,
/** Option на котором произошло событие */
option?: SelectOption,
/** Событие */
event?: ChangeEvent) => void;
/** Последний результат обработчика LoadMore или SelectFilter
*
* Можно расширять другими значениями, например сохраняя номер последней страницы
*/
export type LastResult = {
/** Новые или отфильтрованные option */
options: SelectOption[];
};
/** Обработчик скроллинга в конец списка
*
* Позволяет загружать новые элементы при пагинации
*
* @returns Новые option
*/
export type LoadMore = (
/** Текущие option */
options: SelectOption[],
/** Последний результат вызова функции */
lastResult?: S) => Promise;
/** Обработчик фильтрации option
*
* Используется для поиска значений
* Пример containsFilter
*/
export type SelectFilter = {
/** Обработчик
*
* @returns Отфильтрованные option. Несуществующие option будут добавлены
*/
cb: (
/** Введенный текст */
query: string,
/** Текущие option */
options: SelectOption[],
/** Последний результат вызова функции */
lastResult?: S) => Promise;
/** debounce delay */
delay?: number;
};
/** Состояние Select */
export declare enum SelectState {
/** По умолчанию */
Default = "default",
/** Вызван обработчик filter */
Searching = "searching",
/** Список отфильтрован */
Filtred = "filtred",
/** Вызван обработчик loadMore */
LoadingMore = "loadingMore"
}
/** Перегружаемые компоненты */
type SelectComponents = {
/** Подпись в верхнем баннере */
hint?: ReactNode;
/** Шапка */
header?: ReactNode;
/** Подвал */
footer?: ReactNode;
/** При поиске */
searching?: ReactNode;
/** При отсутствии результатов поиска */
notFound?: ReactNode;
/** Дробдаун (с шапкой, элементами и пр.) */
list?: React.FC;
/** Элементы списка */
items?: React.FC;
/** Элемент списка
*
* Не используется при virtualize
*/
item?: React.FC;
/** Инпут */
input?: React.FC>;
};
type CommonProps = {
/** Значения */
value: SelectMultipleValue;
/** Обработчик изменения значения */
onChange: SelectListOnChange;
/** Множественный выбор */
multiple?: boolean;
/** Количество Chips с label выбранных элементов
*
* Без передачи, будет показано просто кол-во выбранных
*/
showChips?: number;
/** Максимальная длинна label выбранного элемента.
*
* Показывает tooltip при превышении */
maxChipLength?: number;
/** Обработчик длинны label выбранного элемента*/
maxChipLengthFunc?: (label: string) => string;
/** Использовать перенос строк в input */
wrap?: boolean;
/** Фильтр элементов
*
* При передаче будет возможность ввода текста в input
*
* Обработчик может фильтровать текущие элементы, а также возвращать новые
*
* которые будут добавлены (пример: при поиска на backend)
*/
filter?: SelectFilter;
/** Использовать виртуализацию
*
* Использовть при большом количестве элементов > 1000
*
* Виртуализация отключается при передаче options с childs
*
* Виртуализация отключается при количестве элементов < 20
*/
virtualize?: Pick | boolean;
} & Pick & Pick;
export type SelectProps = {
/** Options */
options: SelectOption[];
/** Кастомные свойства Dropdown
*
* Используется в специфических ситуациях
*/
dropdownProps?: Partial;
/** При скроллинге в конец списка
*
* Позволяет загружать новые элементы при пагинации
*/
onLoadMore?: LoadMore;
} & QA & CommonProps & SelectListProps & Omit & Partial>;
export type SingleSelectProps = {
/** Значение */
value: SelectSingleValue | undefined;
/** Обработчик изменения значения */
onChange: SelectSingleOnChange;
} & Omit, 'value' | 'onChange' | 'multiple'>;
export type SelectContextProps = {
options: SelectOption[];
filtred: SelectOption[];
state: SelectState | `${SelectState}`;
setState: (state: SelectState) => void;
getQA: ReturnType;
onClear: () => void;
loadMore: (target: HTMLDivElement | undefined) => void;
filterOptions: (query: string) => void;
} & CommonProps & Pick & Required>;
export {};