/**
 *
 * InputTags is an input component that allows entering multiple values as tags with optional autocomplete suggestions.
 *
 * [Live Demo](https://www.primevue.dev/inputtags/)
 *
 * @module inputtags
 *
 */
import type { DefineComponent, DesignToken, EmitFn, HintedString, PassThrough } from '@primevue/core';
import type { ComponentHooks } from '@primevue/core/basecomponent';
import type { AutoCompletePassThroughOptions } from 'primevue/autocomplete';
import type { ChipPassThroughOptions } from 'primevue/chip';
import type { PassThroughOptions } from 'primevue/passthrough';
import { TransitionProps, VNode } from 'vue';

export declare type InputTagsPassThroughOptionType = InputTagsPassThroughAttributes | ((options: InputTagsPassThroughMethodOptions) => InputTagsPassThroughAttributes | string) | string | null | undefined;

export declare type InputTagsPassThroughTransitionType = TransitionProps | ((options: InputTagsPassThroughMethodOptions) => TransitionProps) | undefined;

/**
 * Custom passthrough(pt) option method.
 */
export interface InputTagsPassThroughMethodOptions {
    /**
     * Defines instance.
     */
    instance: any;
    /**
     * Defines valid properties.
     */
    props: InputTagsProps;
    /**
     * Defines current inline state.
     */
    state: InputTagsState;
    /**
     * Defines current options.
     */
    context: InputTagsContext;
    /**
     * Defines valid attributes.
     */
    attrs: any;
    /**
     * Defines parent options.
     */
    parent: any;
    /**
     * Defines passthrough(pt) options in global config.
     */
    global: object | undefined;
}

/**
 * Custom shared passthrough(pt) option method.
 */
export interface InputTagsSharedPassThroughMethodOptions {
    /**
     * Defines valid properties.
     */
    props: InputTagsProps;
    /**
     * Defines current inline state.
     */
    state: InputTagsState;
}

/**
 * Custom add event.
 * @see {@link InputTagsEmitsOptions.add}
 */
export interface InputTagsAddEvent {
    /**
     * Browser event.
     */
    originalEvent: Event;
    /**
     * Added value.
     */
    value: string;
}

/**
 * Custom remove event.
 * @see {@link InputTagsEmitsOptions.remove}
 */
export interface InputTagsRemoveEvent {
    /**
     * Browser event.
     */
    originalEvent: Event;
    /**
     * Removed value.
     */
    value: string;
    /**
     * Index of the removed value.
     */
    index: number;
}

/**
 * Custom option select event.
 * @see {@link InputTagsEmitsOptions['option-select']}
 */
export interface InputTagsOptionSelectEvent {
    /**
     * Browser event.
     */
    originalEvent: Event;
    /**
     * Selected option.
     */
    value: any;
}

/**
 * Custom complete event.
 * @see {@link InputTagsEmitsOptions.complete}
 */
export interface InputTagsCompleteEvent {
    /**
     * Browser event.
     */
    originalEvent: Event;
    /**
     * Value to search with.
     */
    query: string;
}

/**
 * Custom passthrough(pt) options.
 * @see {@link InputTagsProps.pt}
 */
export interface InputTagsPassThroughOptions {
    /**
     * Used to pass attributes to the root's DOM element.
     */
    root?: InputTagsPassThroughOptionType;
    /**
     * Used to pass attributes to the chip item element.
     */
    item?: InputTagsPassThroughOptionType;
    /**
     * Used to pass attributes to the Chip component.
     * @see {@link ChipPassThroughOptions}
     */
    pcChip?: ChipPassThroughOptions<InputTagsSharedPassThroughMethodOptions>;
    /**
     * Used to pass attributes to the AutoComplete component that powers the typeahead suggestion overlay.
     * @see {@link AutoCompletePassThroughOptions}
     */
    pcAutoComplete?: AutoCompletePassThroughOptions;
    /**
     * Used to pass attributes to the hidden form input's DOM element.
     */
    hiddenInput?: InputTagsPassThroughOptionType;
    /**
     * Used to manage all lifecycle hooks.
     * @see {@link BaseComponent.ComponentHooks}
     */
    hooks?: ComponentHooks;
    /**
     * Used to control Vue Transition API.
     */
    transition?: InputTagsPassThroughTransitionType;
}

export interface InputTagsPassThroughAttributes {
    [key: string]: any;
}

/**
 * Defines current inline state in InputTags component.
 */
export interface InputTagsState {
    id: string;
    /**
     * Current focused state as a boolean.
     * @defaultValue false
     */
    focused: boolean;
    /**
     * Current focused tag index as a number.
     * @defaultValue -1
     */
    focusedItemIndex: number;
    /**
     * Current pending input value of the inner AutoComplete.
     * @defaultValue ''
     */
    inputValue: string;
}

/**
 * Defines current chip context in InputTags component.
 */
export interface InputTagsContext {
    /**
     * Current tag value.
     */
    value?: string;
    /**
     * Index of the current tag.
     */
    index: number;
    /**
     * Current focus state of the chip as a boolean.
     * @defaultValue false
     */
    focused: boolean;
}

/**
 * Defines valid properties in InputTags component.
 */
export interface InputTagsProps {
    /**
     * Value of the component (array of tag strings).
     */
    modelValue?: string[];
    /**
     * The default value when not controlled by `modelValue`.
     */
    defaultValue?: string[];
    /**
     * The name attribute used in form submissions.
     */
    name?: string | undefined;
    /**
     * When enabled, an autocomplete dropdown is shown with the values from the {@link suggestions} array.
     * @defaultValue false
     */
    typeahead?: boolean | undefined;
    /**
     * An array of suggestions to display in the dropdown when {@link typeahead} is enabled.
     */
    suggestions?: any[];
    /**
     * Property name or getter function to use as the label of an option.
     */
    optionLabel?: string | ((data: any) => string) | undefined;
    /**
     * Property name or getter function to use as the disabled flag of an option.
     */
    optionDisabled?: string | ((data: any) => boolean) | undefined;
    /**
     * Property name or getter function to use as the label of an option group.
     */
    optionGroupLabel?: string | ((data: any) => string) | undefined;
    /**
     * Property name or getter function that refers to the children options of an option group.
     */
    optionGroupChildren?: string | ((data: any) => any[]) | undefined;
    /**
     * Maximum height of the suggestions overlay.
     * @defaultValue 14rem
     */
    scrollHeight?: string | undefined;
    /**
     * Default placeholder text for the input field.
     */
    placeholder?: string | undefined;
    /**
     * Defines the size of the component.
     */
    size?: HintedString<'small' | 'large'> | undefined;
    /**
     * When present, it specifies that the component should have invalid state style.
     * @defaultValue false
     */
    invalid?: boolean | undefined;
    /**
     * When present, it specifies that the component should be disabled.
     * @defaultValue false
     */
    disabled?: boolean | undefined;
    /**
     * Specifies the input variant of the component.
     * @defaultValue null
     */
    variant?: HintedString<'outlined' | 'filled'> | undefined | null;
    /**
     * Property to uniquely identify an option.
     */
    dataKey?: string | undefined;
    /**
     * Maximum number of tags allowed.
     */
    max?: number | undefined;
    /**
     * Character or pattern to use as a delimiter when typing or pasting tags.
     */
    delimiter?: string | RegExp | undefined;
    /**
     * Whether duplicate tags are allowed.
     * @defaultValue false
     */
    allowDuplicate?: boolean | undefined;
    /**
     * Add the current input value as a tag when the input loses focus.
     * @defaultValue false
     */
    addOnBlur?: boolean | undefined;
    /**
     * Add tags from pasted content (split by delimiter when present).
     * @defaultValue false
     */
    addOnPaste?: boolean | undefined;
    /**
     * Add the current input value as a tag when the Tab key is pressed.
     * @defaultValue false
     */
    addOnTab?: boolean | undefined;
    /**
     * Minimum number of characters required before search is triggered.
     * @defaultValue 1
     */
    minLength?: number | undefined;
    /**
     * Delay in milliseconds before sending a search query.
     * @defaultValue 300
     */
    delay?: number | undefined;
    /**
     * A valid query selector or HTMLElement to specify where the overlay attaches.
     * @defaultValue body
     */
    appendTo?: HintedString<'body' | 'self'> | undefined | HTMLElement;
    /**
     * Identifier of the underlying input element.
     */
    inputId?: string | undefined;
    /**
     * Inline style of the input field.
     */
    inputStyle?: object | undefined;
    /**
     * Style class of the input field.
     */
    inputClass?: string | object | undefined;
    /**
     * Used to pass all properties of the HTMLInputElement to the input element.
     */
    inputProps?: object | undefined;
    /**
     * Inline style of the overlay.
     */
    overlayStyle?: object | undefined;
    /**
     * Style class of the overlay.
     */
    overlayClass?: string | object | undefined;
    /**
     * Whether to focus on the first visible option when the overlay is shown.
     * @defaultValue false
     */
    autoOptionFocus?: boolean | undefined;
    /**
     * When enabled, the focus is placed on the hovered option.
     * @defaultValue true
     */
    focusOnHover?: boolean | undefined;
    /**
     * Text shown in hidden accessible field when filtering returns results. Defaults to PrimeVue locale.
     */
    searchMessage?: string | undefined;
    /**
     * Text shown when filtering returns no results. Defaults to PrimeVue locale.
     */
    emptySearchMessage?: string | undefined;
    /**
     * Text shown when there are no options to display. Defaults to PrimeVue locale.
     */
    emptyMessage?: string | undefined;
    /**
     * When enabled, empty message is rendered when there are no options.
     * @defaultValue true
     */
    showEmptyMessage?: boolean | undefined;
    /**
     * Spans 100% width of the container when enabled.
     * @defaultValue null
     */
    fluid?: boolean | undefined;
    /**
     * Defines a string value that labels an interactive element.
     */
    ariaLabel?: string | undefined;
    /**
     * Identifier of the element that labels the input.
     */
    ariaLabelledby?: string | undefined;
    /**
     * Form control object, typically used for handling validation and form state.
     */
    formControl?: Record<string, any> | undefined;
    /**
     * It generates scoped CSS variables using design tokens for the component.
     */
    dt?: DesignToken<any>;
    /**
     * Used to pass attributes to DOM elements inside the component.
     * @type {InputTagsPassThroughOptions}
     */
    pt?: PassThrough<InputTagsPassThroughOptions>;
    /**
     * Used to configure passthrough(pt) options of the component.
     * @type {PassThroughOptions}
     */
    ptOptions?: PassThroughOptions;
    /**
     * When enabled, it removes component related styles in the core.
     * @defaultValue false
     */
    unstyled?: boolean;
}

/**
 * Defines valid slots in InputTags component.
 */
export interface InputTagsSlots {
    /**
     * Custom chip template.
     */
    chip(scope: {
        /**
         * Style class of the chip.
         */
        class: string | (string | Record<string, boolean>)[];
        /**
         * The tag value.
         */
        value: string;
        /**
         * Index of the tag.
         */
        index: number;
        /**
         * Remove callback.
         */
        removeCallback: (event: Event) => void;
    }): VNode[];
    /**
     * Custom chip remove icon template.
     */
    chipicon(scope: {
        /**
         * Style class of the icon.
         */
        class: string | (string | Record<string, boolean>)[];
        /**
         * Index of the tag.
         */
        index: number;
        /**
         * Remove callback.
         */
        removeCallback: (event: Event) => void;
    }): VNode[];
    /**
     * Custom header template of the overlay panel.
     */
    header(scope: {
        /**
         * Current value of the component.
         */
        value: any;
        /**
         * Displayed options.
         */
        suggestions: any[];
    }): VNode[];
    /**
     * Custom footer template of the overlay panel.
     */
    footer(scope: {
        /**
         * Current value of the component.
         */
        value: any;
        /**
         * Displayed options.
         */
        suggestions: any[];
    }): VNode[];
    /**
     * Custom option template.
     */
    option(scope: {
        /**
         * Option instance.
         */
        option: any;
        /**
         * Index of the option.
         */
        index: number;
    }): VNode[];
    /**
     * Custom option group template.
     */
    optiongroup(scope: { option: any; index: number }): VNode[];
    /**
     * Custom empty template when there are no options.
     */
    empty(): VNode[];
    /**
     * Custom empty template displayed during search.
     */
    emptysearch(): VNode[];
}

/**
 * Defines valid emits in InputTags component.
 */
export interface InputTagsEmitsOptions {
    /**
     * Emitted when the value changes.
     */
    'update:modelValue'(value: string[]): void;
    /**
     * Emitted in uncontrolled mode when the value changes.
     */
    'value-change'(value: string[]): void;
    /**
     * Callback to invoke when the input receives focus.
     */
    focus(event: Event): void;
    /**
     * Callback to invoke when the input loses focus.
     */
    blur(event: Event): void;
    /**
     * Callback to invoke when a tag is added.
     */
    add(event: InputTagsAddEvent): void;
    /**
     * Callback to invoke when a tag is removed.
     */
    remove(event: InputTagsRemoveEvent): void;
    /**
     * Callback to invoke when an option is selected from the dropdown.
     */
    'option-select'(event: InputTagsOptionSelectEvent): void;
    /**
     * Callback to invoke to search for suggestions.
     */
    complete(event: InputTagsCompleteEvent): void;
    /**
     * Callback to invoke before the overlay is shown.
     */
    'before-show'(): void;
    /**
     * Callback to invoke before the overlay is hidden.
     */
    'before-hide'(): void;
    /**
     * Callback to invoke when the overlay is shown.
     */
    show(): void;
    /**
     * Callback to invoke when the overlay is hidden.
     */
    hide(): void;
}

export declare type InputTagsEmits = EmitFn<InputTagsEmitsOptions>;

/**
 * **PrimeVue - InputTags**
 *
 * _InputTags allows entering multiple values as tags with an optional autocomplete dropdown._
 *
 * [Live Demo](https://www.primevue.dev/inputtags/)
 *
 * @group Component
 *
 */
declare const InputTags: DefineComponent<InputTagsProps, InputTagsSlots, InputTagsEmits>;

declare module 'vue' {
    export interface GlobalComponents {
        InputTags: DefineComponent<InputTagsProps, InputTagsSlots, InputTagsEmits>;
    }
}

export default InputTags;
