import * as i0 from '@angular/core';
import { InjectionToken, EventEmitter, OnInit, TemplateRef, OnChanges, AfterViewInit, OnDestroy, ElementRef, SimpleChanges } from '@angular/core';
import { Nullable, NestedKeyOf, ObjectPathType, CssClassBuilder, FocusEscapeDirection } from '@fundamental-ngx/cdk/utils';
import { MobileMode, MobileModeBase, MobileModeConfig } from '@fundamental-ngx/core/mobile-mode';
import { ControlValueAccessor, FormControl } from '@angular/forms';
import { BehaviorSubject, Observable } from 'rxjs';
import { FormItemControl } from '@fundamental-ngx/core/form';
import { ListComponent } from '@fundamental-ngx/core/list';
import { PopoverComponent } from '@fundamental-ngx/core/popover';
import { PopoverFillMode } from '@fundamental-ngx/core/shared';
import { TokenizerComponent } from '@fundamental-ngx/core/token';
import { FormStates } from '@fundamental-ngx/cdk/forms';
import * as i1 from '@fundamental-ngx/core/content-density';
import { ContentDensityObserver } from '@fundamental-ngx/core/content-density';
import { IconFont } from '@fundamental-ngx/core/icon';

declare const MULTI_INPUT_COMPONENT: InjectionToken<string[]>;
/**
 * Multi Input Interface to have typing and avoid circular dependency between
 * MultiInputComponent <==> MultiInputMobileComponent
 */
interface MultiInputInterface extends MobileMode {
    selected: any[];
    openChange: EventEmitter<boolean>;
    allItemsSelectedChange: EventEmitter<boolean>;
    dialogApprove(): void;
    selectAllItems(selectAll: boolean): void;
    dialogDismiss(selectedBackup: any[]): void;
}

declare class MultiInputMobileComponent extends MobileModeBase<MultiInputInterface> implements OnInit {
    /** @hidden */
    dialogTemplate: TemplateRef<any>;
    /** @hidden */
    allItemsSelected: boolean;
    /** @hidden
     * For internal usage
     * Control element, which will be rendered inside dialog.
     * List element, which will be rendered inside dialog.
     */
    childContent: Nullable<{
        listTemplate: TemplateRef<any>;
        controlTemplate: TemplateRef<any>;
    }>;
    /** @hidden */
    private _selectedBackup;
    /** @hidden */
    constructor(multiInputComponent: MultiInputInterface);
    /** @hidden */
    ngOnInit(): void;
    /** Throw select all event, it's handled by multi input component */
    selectAll(selectAll: boolean): void;
    /** @hidden */
    handleDismiss(): void;
    /** @hidden */
    handleApprove(): void;
    /** @hidden */
    private _toggleDialog;
    /** @hidden */
    private _listenOnMultiInputOpenChange;
    /** @hidden */
    private _open;
    static ɵfac: i0.ɵɵFactoryDeclaration<MultiInputMobileComponent, never>;
    static ɵcmp: i0.ɵɵComponentDeclaration<MultiInputMobileComponent, "fd-multi-input-mobile", never, {}, {}, never, never, true, never>;
}

/**
 * @deprecated
 * Use direct imports of components and directives.
 */
declare class MultiInputMobileModule {
    static ɵfac: i0.ɵɵFactoryDeclaration<MultiInputMobileModule, never>;
    static ɵmod: i0.ɵɵNgModuleDeclaration<MultiInputMobileModule, never, [typeof MultiInputMobileComponent], [typeof MultiInputMobileComponent]>;
    static ɵinj: i0.ɵɵInjectorDeclaration<MultiInputMobileModule>;
}

declare class PairSelectionModel<KeyType, ValueType> {
    /** @hidden */
    _selected: Map<KeyType, ValueType>;
    /** Event emitted when the selection has changed. */
    selectionChanged: EventEmitter<[KeyType, ValueType][]>;
    /** Array of selected items */
    get selected(): ValueType[];
    /** Whether the given key exists in the record */
    isSelected(key: KeyType): boolean;
    /** Selects the given key-value pair */
    select(values: [KeyType, ValueType][]): void;
    /** Selects the given key-value pair */
    select(key: KeyType, value: ValueType): void;
    /** Deselects the given key */
    deselect(key: KeyType): void;
    /** Clears the selection information */
    clear(): void;
}

/**
 * Input field with multiple selection enabled. Should be used when a user can select between a
 * limited number of pre-defined options with a filter-enabled context.
 *
 * Supports Angular Forms.
 */
declare class MultiInputComponent<ItemType = any, ValueType = any> implements MultiInputInterface, ControlValueAccessor, CssClassBuilder, OnInit, OnChanges, AfterViewInit, OnDestroy, FormItemControl {
    /** Placeholder for the input field. */
    placeholder: string;
    /** Whether the input is disabled. */
    disabled: boolean;
    /** If it is mandatory field */
    required: boolean;
    /** Whether to use cozy visuals but compact collapsing behavior. */
    compactCollapse: boolean;
    /** Max height of the popover. Any overflowing elements will be accessible through scrolling. */
    maxHeight: string;
    /** Icon of the button on the right of the input field. */
    glyph: string;
    /** Glyph font family */
    glyphFont: IconFont;
    /** Values to be displayed in the unfiltered dropdown. */
    dropdownValues: Array<ItemType | _OptionItem<ItemType, ValueType>>;
    /** Whether to open the dropdown when the addon button is clicked. */
    openDropdownOnAddOnClicked: boolean;
    /** Title text for the add-on icon button. */
    addonIconTitle: string;
    /** Search term, or more specifically the value of the inner input field. */
    set searchTerm(value: string);
    get searchTerm(): string;
    /** Id attribute for input element inside MultiInput component */
    inputId: string;
    /** Whether the search term should be highlighted in results. */
    highlight: boolean;
    /** Selected dropdown items. */
    set selected(values: ValueType[]);
    get selected(): ValueType[];
    /** user's custom classes */
    class: string;
    /**
     * Filter function. Accepts an array and a string as arguments, and outputs an array.
     * An arrow function can be used to access the *this* keyword in the calling component.
     * See multi input examples for details.
     */
    filterFn: (contentArray: this['dropdownValues'], searchTerm: string) => this['dropdownValues'];
    /**
     * Value function. Accepts an object of the same type as the
     * items passed to dropdownValues as argument, and outputs any property, that should be used as value.
     * An arrow function can be used to access the *this* keyword in the calling component.
     * See multi input examples for details.
     */
    valueFn: (item: ItemType) => ValueType;
    /**
     * Display function. Accepts an object of the same type as the
     * items passed to dropdownValues as argument, and outputs a string.
     * An arrow function can be used to access the *this* keyword in the calling component.
     * See multi input examples for details.
     */
    displayFn: (item: ItemType) => string;
    /**
     * Parse function. Used for submitting new tokens. Accepts a string by default.
     * An arrow function can be used to access the *this* keyword in the calling component.
     * See multi input examples for details.
     */
    newTokenParseFn: (searchTerm: string) => any;
    /**
     * Identifier function or path to an identifier property.
     */
    optionItemIdentifier: OptionItemIdentifierInput<ItemType>;
    /**
     * Validate function. Used to check if new token can be added into list.
     * Works only, when `allowNewTokens` option is enabled.
     */
    newTokenValidateFn: (str: string) => boolean;
    /** aria-label attribute binding. */
    ariaLabel: Nullable<string>;
    /** aria-labelledby attribute binding. */
    ariaLabelledBy: Nullable<string>;
    /**
     * Preset options for the Select body width, whatever is chosen, the body has a 600px limit.
     * * `at-least` will apply a minimum width to the body equivalent to the width of the control. - Default
     * * `equal` will apply a width to the body equivalent to the width of the control.
     * * 'fit-content' will apply width needed to properly display items inside, independent of control.
     */
    fillControlMode: PopoverFillMode;
    /**
     *  The state of the form control - applies css classes.
     *  Can be `success`, `error`, `warning`, `information` or blank for default.
     */
    state?: FormStates;
    /**
     * Whether AddOn Button should be focusable
     * @default true
     */
    buttonFocusable: boolean;
    /** Whether the multi-input allows the creation of new tokens. */
    allowNewTokens: boolean;
    /** Whether the multi-input should be built on mobile mode */
    mobile: boolean;
    /** Whether the multi-input should have show all button. */
    showAllButton: boolean;
    /**
     * Max width of multi input body.
     * `none` will not limit width of the dropdown.
     * `container` will limit width of the dropdown to the width of the multi-input itself.
     * `number` will limit width of the dropdown by provided number in pixels.
     */
    bodyMaxWidth: 'none' | 'container' | number;
    /** @hidden */
    get _popoverMaxWidth(): number | null;
    /** Multi Input Mobile Configuration, it's applied only, when mobile is enabled */
    mobileConfig: MobileModeConfig;
    /**
     * Whether to return results where the input matches the entire string. By default, only results that start
     * with the input search term will be returned.
     */
    includes: boolean;
    /**
     * The template with which to display the individual listed items.
     * Use it by passing an ng-template with implicit content. See examples for more info.
     */
    itemTemplate: TemplateRef<any>;
    /**
     * The tooltip for the multi-input icon.
     */
    title: string;
    /** Whether list item options should be rendered as byline. */
    byline: boolean;
    /** Whether the autocomplete should be enabled; Enabled by default */
    autoComplete: boolean;
    /** Event emitted when the search term changes. Use *$event* to access the new term. */
    readonly searchTermChange: EventEmitter<string>;
    /** Event emitted when the selected items change. Use *$event* to access the new selected array. */
    readonly selectedChange: EventEmitter<ValueType[]>;
    /** Whether multi input popover body should be opened */
    open: boolean;
    /** Whether to display the addon button. */
    displayAddonButton: boolean;
    /** Aria-label for the addon button. */
    addOnButtonAriaLabel: Nullable<string>;
    /** Event emitted, when the multi input's popover body is opened or closed */
    readonly openChange: EventEmitter<boolean>;
    /** Emits event when the addon button is clicked. */
    readonly addOnButtonClicked: EventEmitter<Event>;
    /** Event emitted, when the multi input's all item checked or not */
    readonly allItemsSelectedChange: EventEmitter<boolean>;
    /** @hidden */
    popoverRef: PopoverComponent;
    /** @hidden */
    controlTemplate: TemplateRef<{
        displayAddonButton: boolean;
    }>;
    /** @hidden */
    listTemplate: TemplateRef<any>;
    /** @hidden */
    listComponent: ListComponent;
    /** @hidden */
    searchInputElement: ElementRef<HTMLInputElement>;
    /** @hidden */
    tokenizer: TokenizerComponent;
    /**
     * Maximum number of selected tokens to render when the input is not focused.
     * When the selection exceeds this limit, the remaining count is shown as a
     * "+N more" indicator. Defaults to 12.
     */
    readonly maxVisibleTokens: i0.InputSignal<number>;
    /** @hidden */
    get _optionItems(): _OptionItem<ItemType, ValueType>[];
    /** @hidden */
    readonly optionItems$: BehaviorSubject<_OptionItem<ItemType, ValueType>[]>;
    /** @hidden */
    readonly _onlySelected$: BehaviorSubject<boolean>;
    /** @hidden */
    readonly _searchTermCtrl: FormControl<string | null>;
    /** @hidden */
    readonly _selectionModel: PairSelectionModel<OptionItemIdentifier, OptionItem<ItemType, ValueType>>;
    /** @hidden */
    readonly _viewModel$: Observable<ViewModel<ItemType, ValueType>>;
    /** @hidden */
    readonly contentDensityObserver: ContentDensityObserver;
    /** @hidden */
    readonly elementRef: ElementRef<HTMLElement>;
    /** @hidden — slice (or full list) of options rendered into <fd-tokenizer>. */
    protected readonly renderedTokens: i0.Signal<_OptionItem<ItemType, ValueType>[]>;
    /** @hidden — count of selected tokens not currently rendered. Fed into tokenizer's externalHiddenCount input. */
    protected readonly hiddenCount: i0.Signal<number>;
    /** @hidden — the selected option list as a signal, derived from the view model. */
    private readonly _selectedOptionsSignal;
    /** @hidden — true while the input has focus. Renders the full token list. */
    private readonly _renderAllTokens;
    /** typeahead matcher function */
    get typeAheadMatcher(): (item: string, searchTerm: string) => boolean;
    /** @hidden */
    private readonly _dir;
    /** @hidden */
    private _subscriptions;
    /** @hidden */
    private readonly _rangeSelector;
    /** @hidden */
    private readonly _changeDetRef;
    /** @hidden */
    private readonly _dynamicComponentService;
    /** @hidden */
    private readonly _injector;
    /** @hidden */
    private readonly _viewContainerRef;
    /** @hidden */
    private readonly _rtlService;
    /** @hidden */
    private readonly _focusTrapService;
    /** @hidden */
    constructor();
    /** @hidden CssClassBuilder interface implementation
     * function must return single string
     * function is responsible for order which css classes are applied
     */
    buildComponentCssClass(): string[];
    /** @hidden Called on input focus — render all tokens, then expand the tokenizer. */
    _onInputFocus(): void;
    /** @hidden */
    onChange: (value: any) => void;
    /** @hidden */
    onTouched: () => void;
    /** @hidden */
    ngOnInit(): void;
    /** @hidden */
    ngOnChanges(changes: SimpleChanges): void;
    /** @hidden */
    ngAfterViewInit(): void;
    /** @hidden */
    ngOnDestroy(): void;
    /** @hidden */
    registerOnChange(fn: (selected: any[]) => void): void;
    /** @hidden */
    registerOnTouched(fn: () => void): void;
    /** @hidden */
    setDisabledState(isDisabled: boolean): void;
    /** @hidden */
    writeValue(selected: ValueType[]): void;
    /** Method passed to list component */
    handleListFocusEscape(direction: FocusEscapeDirection): void;
    /** @hidden */
    openChangeHandle(open: boolean): void;
    /** Method that selects all possible options. */
    selectAllItems(selectAll: boolean): void;
    /** @hidden */
    _onCheckboxKeyup(option: _OptionItem<ItemType, ValueType>, event: KeyboardEvent, index: number, isListItem?: boolean): void;
    /** @hidden */
    _onCheckboxClick(option: _OptionItem<ItemType, ValueType>, event: MouseEvent | KeyboardEvent, index: number, _isListItem?: boolean): Promise<void>;
    /** @hidden */
    _onTokenCloseClick(option: _OptionItem<ItemType, ValueType>, resetSearch: boolean, event?: MouseEvent): void;
    /** @hidden */
    _tokenElementClicked(event: MouseEvent): void;
    /** @hidden */
    _handleSelect(checked: any, option: _OptionItem<ItemType, ValueType>, resetSearch?: boolean, fromTokenCloseClick?: boolean): void;
    /** @hidden */
    _handleInputKeydown(event: KeyboardEvent): void;
    /** @hidden */
    _showAllClicked(event: Event): void;
    /** @hidden */
    _showAllKeyDown(event: KeyboardEvent): void;
    /** @hidden */
    _onSubmit(): void;
    /** @hidden */
    _handleComplete({ term }: {
        term: any;
    }): void;
    /**
     * Handle dialog dismissing, closes popover and sets backup data.
     */
    dialogDismiss(selectedBackup: any[]): void;
    /**
     * Handle dialog approval, closes popover and propagates data changes.
     */
    dialogApprove(): void;
    /** @hidden */
    _moreClicked(): void;
    /** @hidden Click handler for the "+N more" indicator owned by multi-input. */
    _onMoreClicked(): void;
    /** @hidden */
    _addOnButtonClicked(event: Event): void;
    /** @hidden */
    disableParentFocusTrap(): void;
    /** @hidden */
    enableParentFocusTrap(): void;
    /** @hidden */
    _close(): void;
    /** @hidden */
    protected _focusOut(event: FocusEvent): void;
    /** @hidden */
    private _addNewTokenToDropDownValues;
    /** @hidden */
    private _selectFirstFiltered;
    /** @hidden */
    private _defaultFilter;
    /** @hidden */
    private _defaultValueFn;
    /** @hidden */
    private _defaultDisplay;
    /** @hidden */
    private _defaultParse;
    /** @hidden */
    private _defaultTokenValidate;
    /** @hidden */
    private _popoverOpenHandle;
    /** @hidden */
    private _propagateChange;
    /** @hidden */
    private _shouldPopoverBeUpdated;
    /** @hidden */
    private _setUpMobileMode;
    /** @hidden */
    private _getItemIdentifier;
    /** @hidden */
    private _resetSearchTerm;
    /** @hidden */
    private _getOptionItem;
    /** @hidden */
    private _getValueAndLabelOfItem;
    /** @hidden */
    private _getViewModel;
    static ɵfac: i0.ɵɵFactoryDeclaration<MultiInputComponent<any, any>, never>;
    static ɵcmp: i0.ɵɵComponentDeclaration<MultiInputComponent<any, any>, "fd-multi-input", never, { "placeholder": { "alias": "placeholder"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "required": { "alias": "required"; "required": false; }; "compactCollapse": { "alias": "compactCollapse"; "required": false; }; "maxHeight": { "alias": "maxHeight"; "required": false; }; "glyph": { "alias": "glyph"; "required": false; }; "glyphFont": { "alias": "glyphFont"; "required": false; }; "dropdownValues": { "alias": "dropdownValues"; "required": false; }; "openDropdownOnAddOnClicked": { "alias": "openDropdownOnAddOnClicked"; "required": false; }; "addonIconTitle": { "alias": "addonIconTitle"; "required": false; }; "searchTerm": { "alias": "searchTerm"; "required": false; }; "inputId": { "alias": "inputId"; "required": false; }; "highlight": { "alias": "highlight"; "required": false; }; "selected": { "alias": "selected"; "required": false; }; "class": { "alias": "class"; "required": false; }; "filterFn": { "alias": "filterFn"; "required": false; }; "valueFn": { "alias": "valueFn"; "required": false; }; "displayFn": { "alias": "displayFn"; "required": false; }; "newTokenParseFn": { "alias": "newTokenParseFn"; "required": false; }; "optionItemIdentifier": { "alias": "optionItemIdentifier"; "required": false; }; "newTokenValidateFn": { "alias": "newTokenValidateFn"; "required": false; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; }; "ariaLabelledBy": { "alias": "ariaLabelledBy"; "required": false; }; "fillControlMode": { "alias": "fillControlMode"; "required": false; }; "state": { "alias": "state"; "required": false; }; "buttonFocusable": { "alias": "buttonFocusable"; "required": false; }; "allowNewTokens": { "alias": "allowNewTokens"; "required": false; }; "mobile": { "alias": "mobile"; "required": false; }; "showAllButton": { "alias": "showAllButton"; "required": false; }; "bodyMaxWidth": { "alias": "bodyMaxWidth"; "required": false; }; "mobileConfig": { "alias": "mobileConfig"; "required": false; }; "includes": { "alias": "includes"; "required": false; }; "itemTemplate": { "alias": "itemTemplate"; "required": false; }; "title": { "alias": "title"; "required": false; }; "byline": { "alias": "byline"; "required": false; }; "autoComplete": { "alias": "autoComplete"; "required": false; }; "open": { "alias": "open"; "required": false; }; "displayAddonButton": { "alias": "displayAddonButton"; "required": false; }; "addOnButtonAriaLabel": { "alias": "addOnButtonAriaLabel"; "required": false; }; "maxVisibleTokens": { "alias": "maxVisibleTokens"; "required": false; "isSignal": true; }; }, { "searchTermChange": "searchTermChange"; "selectedChange": "selectedChange"; "openChange": "openChange"; "addOnButtonClicked": "addOnButtonClicked"; "allItemsSelectedChange": "allItemsSelectedChange"; }, never, ["*"], true, never>;
}
interface _OptionItem<ItemType = any, ValueType = any> extends OptionItemBase<ValueType> {
    id: OptionItemIdentifier;
    item: ItemType;
    isSelected?: boolean;
}
type OptionItemWithItemIdentifierValues<ItemType extends object, AllTheKeys extends (string | keyof ItemType)[] = NestedKeyOf<ItemType>[]> = {
    [Key in AllTheKeys[number]]: ObjectPathType<ItemType, Key> extends OptionItemIdentifier ? Key : never;
}[AllTheKeys[number]];
type AcceptableKeysOf<ItemType = any> = ItemType extends object ? OptionItemWithItemIdentifierValues<ItemType> : never;
type OptionItemIdentifierInput<ItemType = any> = ((item: ItemType) => OptionItemIdentifier) | AcceptableKeysOf<ItemType>;
type OptionItemIdentifier = string | number | symbol;
type OptionItem<ItemType = any, ValueType = any> = Omit<_OptionItem<ItemType, ValueType>, 'isSelected'>;
interface OptionItemBase<ValueType = any> {
    label: string;
    value: ValueType;
}
interface ViewModel<ItemType = any, ValueType = any> {
    selectedOptions: _OptionItem<ItemType, ValueType>[];
    displayedOptions: _OptionItem<ItemType, ValueType>[];
}

/**
 * @deprecated
 * Use direct imports of components and directives.
 */
declare class MultiInputModule {
    static ɵfac: i0.ɵɵFactoryDeclaration<MultiInputModule, never>;
    static ɵmod: i0.ɵɵNgModuleDeclaration<MultiInputModule, never, [typeof i1.ContentDensityModule, typeof MultiInputComponent], [typeof MultiInputComponent, typeof i1.ContentDensityModule]>;
    static ɵinj: i0.ɵɵInjectorDeclaration<MultiInputModule>;
}

export { MULTI_INPUT_COMPONENT, MultiInputComponent, MultiInputMobileComponent, MultiInputMobileModule, MultiInputModule };
export type { AcceptableKeysOf, MultiInputInterface, OptionItem, OptionItemBase, OptionItemIdentifier, OptionItemIdentifierInput, OptionItemWithItemIdentifierValues };
