import type { Snippet } from 'svelte';
import type { FlipParams } from 'svelte/animate';
import type { HTMLAttributes, HTMLInputAttributes } from 'svelte/elements';
export type Option = string | number | ObjectOption;
export type OptionStyle = string | {
    option?: string;
    selected?: string;
};
export type ObjectOption = {
    label: string | number;
    value?: unknown;
    title?: string;
    disabled?: boolean;
    preselected?: boolean;
    disabledTitle?: string;
    selectedTitle?: string;
    style?: OptionStyle;
    group?: string;
    [key: string]: unknown;
};
export type PlaceholderConfig = {
    text: string;
    persistent?: boolean;
};
export interface MultiSelectEvents<T extends Option = Option> {
    onadd?: (data: {
        option: T;
        selected: T[];
    }) => unknown;
    oncreate?: (data: {
        option: T;
    }) => false | T | undefined | Promise<false | T | undefined>;
    onremove?: (data: {
        option: T;
        selected: T[];
    }) => unknown;
    onremoveAll?: (data: {
        options: T[];
    }) => unknown;
    onselectAll?: (data: {
        options: T[];
    }) => unknown;
    onreorder?: (data: {
        options: T[];
        previous: T[];
    }) => unknown;
    onchange?: (data: {
        option?: T;
        options?: T[];
        type: `add` | `remove` | `removeAll` | `selectAll` | `reorder`;
    }) => unknown;
    onopen?: (data: {
        event: Event;
    }) => unknown;
    onclose?: (data: {
        event: Event;
    }) => unknown;
    ongroupToggle?: (data: {
        group: string;
        collapsed: boolean;
    }) => unknown;
    oncollapseAll?: (data: {
        groups: string[];
    }) => unknown;
    onexpandAll?: (data: {
        groups: string[];
    }) => unknown;
    onsearch?: (data: {
        searchText: string;
        matchingOptions: T[];
    }) => unknown;
    onmaxreached?: (data: {
        selected: T[];
        maxSelect: number;
        attemptedOption: T;
    }) => unknown;
    onduplicate?: (data: {
        option: T;
    }) => unknown;
    onparsed_paste?: (data: {
        added: T[];
        rejected: T[];
        overflow: T[];
        raw_text: string;
    }) => unknown;
    onactivate?: (data: {
        option: T | null;
        index: number | null;
    }) => unknown;
    onundo?: (data: {
        previous: T[];
        current: T[];
    }) => unknown;
    onredo?: (data: {
        previous: T[];
        current: T[];
    }) => unknown;
}
export interface LoadOptionsParams {
    search: string;
    offset: number;
    limit: number;
}
export interface LoadOptionsResult<T extends Option = Option> {
    options: T[];
    hasMore: boolean;
}
export type LoadOptionsFn<T extends Option = Option> = (params: LoadOptionsParams) => Promise<LoadOptionsResult<T>>;
export interface LoadOptionsConfig<T extends Option = Option> {
    fetch: LoadOptionsFn<T>;
    debounceMs?: number;
    batchSize?: number;
    onOpen?: boolean;
}
export type LoadOptions<T extends Option = Option> = LoadOptionsFn<T> | LoadOptionsConfig<T>;
export type FormSerialize<T extends Option = Option> = (selected: T[]) => string | null;
type InputSnippetProps<T extends Option = Option> = Pick<MultiSelectProps<T>, `selected` | `disabled` | `invalid` | `id` | `open` | `required` | `searchText`> & {
    placeholder: string | null;
};
type UserMsgProps = {
    searchText: string;
    msgType: false | `dupe` | `create` | `no-match`;
    msg: null | string;
};
export type GroupHeaderProps<T extends Option = Option> = {
    group: string;
    options: T[];
    collapsed: boolean;
};
export type GroupedOptions<T extends Option = Option> = {
    group: string | null;
    options: T[];
    collapsed: boolean;
};
export interface MultiSelectSnippets<T extends Option = Option> {
    expandIcon?: Snippet<[{
        open: boolean;
        disabled: boolean;
    }]>;
    selectedItem?: Snippet<[{
        option: T;
        idx: number;
    }]>;
    children?: Snippet<[{
        option: T;
        idx: number;
        type: `option` | `selected`;
    }]>;
    removeIcon?: Snippet<[
        {
            option: T;
            isRemoveAll: false;
        } | {
            option?: undefined;
            isRemoveAll: true;
        }
    ]>;
    beforeInput?: Snippet<[InputSnippetProps<T>]>;
    afterInput?: Snippet<[InputSnippetProps<T>]>;
    spinner?: Snippet;
    disabledIcon?: Snippet;
    option?: Snippet<[
        {
            option: T;
            idx: number;
            selected: boolean;
            active: boolean;
            disabled: boolean;
        }
    ]>;
    userMsg?: Snippet<[UserMsgProps]>;
    groupHeader?: Snippet<[GroupHeaderProps<T>]>;
}
export interface PortalParams {
    target_node?: HTMLElement | null;
    active?: boolean;
    placement?: `auto` | `bottom` | `top`;
}
type InputEventProp = Extract<keyof HTMLInputAttributes, `on${string}`>;
export type InputProps = Omit<HTMLInputAttributes, InputEventProp>;
export interface MultiSelectProps<T extends Option = Option> extends MultiSelectEvents<T>, MultiSelectSnippets<T>, Omit<HTMLAttributes<HTMLDivElement>, `children` | `onchange` | `onclose` | `placeholder`> {
    activeIndex?: number | null;
    activeOption?: T | null;
    createOptionMsg?: string | ((state: {
        searchText: string;
        selected: T[];
        options: T[];
        matchingOptions: T[];
    }) => string) | null;
    allowUserOptions?: boolean | `append`;
    allowEmpty?: boolean;
    autocomplete?: HTMLInputAttributes[`autocomplete`];
    autoScroll?: boolean;
    breakpoint?: number;
    defaultDisabledTitle?: string;
    disabled?: boolean;
    disabledInputTitle?: string;
    duplicateOptionMsg?: string;
    duplicates?: boolean | `case-insensitive`;
    expandIconPosition?: `left` | `right` | `none`;
    keepSelectedInDropdown?: false | `plain` | `checkboxes`;
    key?: (opt: T) => unknown;
    filterFunc?: (opt: T, searchText: string) => boolean;
    fuzzy?: boolean;
    closeDropdownOnSelect?: boolean | `if-mobile` | `retain-focus`;
    form_input?: HTMLInputElement | null;
    formSerialize?: FormSerialize<T>;
    highlightMatches?: boolean;
    id?: string | null;
    input?: HTMLInputElement | null;
    inputClass?: string;
    inputProps?: InputProps;
    inputStyle?: string | null;
    inputmode?: HTMLInputAttributes[`inputmode`] | null;
    invalid?: boolean;
    liActiveOptionClass?: string;
    liActiveUserMsgClass?: string;
    liOptionClass?: string;
    liOptionStyle?: string | null;
    liSelectedClass?: string;
    liSelectedStyle?: string | null;
    liUserMsgClass?: string;
    loading?: boolean;
    matchingOptions?: T[];
    maxOptions?: number | undefined;
    virtualList?: boolean | {
        itemHeight?: number;
        overscan?: number;
    };
    maxSelect?: number | null;
    maxSelectMsg?: ((current: number, max: number) => string) | null;
    maxSelectMsgClass?: string;
    maxVisibleChips?: number | null;
    name?: string | null;
    noMatchingOptionsMsg?: string;
    open?: boolean;
    options?: T[];
    outerDiv?: HTMLDivElement | null;
    outerDivClass?: string;
    parseLabelsAsHtml?: boolean;
    pattern?: string | null;
    placeholder?: string | PlaceholderConfig | null;
    removeAllTitle?: string;
    removeBtnTitle?: string;
    minSelect?: number | null;
    required?: boolean | number;
    resetFilterOnAdd?: boolean;
    parse_paste?: (text: string) => T[];
    searchText?: string;
    selected?: T[];
    selectedDisplay?: `chips` | `input`;
    sortSelected?: boolean | ((op1: T, op2: T) => number);
    selectedOptionsDraggable?: boolean;
    style?: string | null;
    ulOptionsClass?: string;
    ulSelectedClass?: string;
    ulSelectedStyle?: string | null;
    ulOptionsStyle?: string | null;
    value?: T | T[] | null;
    portal?: PortalParams;
    selectAllOption?: boolean | string;
    selectAllDisabledTitle?: string | ((state: {
        max_reached: boolean;
        maxSelect: number | null;
        selected_count: number;
    }) => string) | null;
    liSelectAllClass?: string;
    loadOptions?: LoadOptions<T>;
    selectedFlipParams?: FlipParams;
    collapsibleGroups?: boolean;
    collapsedGroups?: Set<string>;
    groupSelectAll?: boolean;
    ungroupedPosition?: `first` | `last`;
    groupSortOrder?: `none` | `asc` | `desc` | ((a: string, b: string) => number);
    searchExpandsCollapsedGroups?: boolean;
    searchMatchesGroups?: boolean;
    keyboardExpandsCollapsedGroups?: boolean;
    stickyGroupHeaders?: boolean;
    liGroupHeaderClass?: string;
    liGroupHeaderStyle?: string | null;
    collapseAllGroups?: () => void;
    expandAllGroups?: () => void;
    shortcuts?: Partial<KeyboardShortcuts>;
    history?: boolean | number;
    undo?: () => boolean;
    redo?: () => boolean;
    canUndo?: boolean;
    canRedo?: boolean;
}
export interface KeyboardShortcuts {
    select_all?: string | null;
    clear_all?: string | null;
    open?: string | null;
    close?: string | null;
    undo?: string | null;
    redo?: string | null;
}
export type NavRouteObject = {
    label?: string;
    children?: string[];
    disabled?: boolean | string;
    separator?: boolean;
    align?: `left` | `right`;
    external?: boolean;
    tooltip?: string;
    class?: string;
    style?: string;
    [key: string]: unknown;
} & ({
    href: string;
} | {
    separator: true;
    href?: string;
});
export type NavRoute = string | [string, string] | [string, string[]] | NavRouteObject;
export {};
