import * as i0 from '@angular/core';
import { InjectionToken, Directive, inject, DestroyRef, ElementRef, EventEmitter, signal, booleanAttribute, Component, ChangeDetectionStrategy, ViewEncapsulation, Input, ContentChild, Output, ViewChild, ContentChildren, forwardRef, Inject, Optional, Self, NgModule } from '@angular/core';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import * as i3 from '@angular/forms';
import { hasModifierKey, isSelectAll, ENTER as ENTER$1, TAB as TAB$1, SPACE as SPACE$1, COMMA, SEMICOLON } from '@koobiq/cdk/keycodes';
import * as i3$1 from '@koobiq/components/autocomplete';
import * as i1 from '@koobiq/components/core';
import { KbqFieldSizingContent, KbqColorDirective, KbqComponentColors, isNull, KBQ_TITLE_TEXT_REF, isBoolean } from '@koobiq/components/core';
import * as i1$1 from '@koobiq/components/form-field';
import { KbqFormFieldControl } from '@koobiq/components/form-field';
import { FocusMonitor } from '@angular/cdk/a11y';
import * as i2$1 from '@angular/cdk/bidi';
import * as i2 from '@angular/cdk/drag-drop';
import { CdkDrag, CdkDropList } from '@angular/cdk/drag-drop';
import { DELETE, SPACE, BACKSPACE, ENTER, ESCAPE, F2, LEFT_ARROW, TAB, HOME, END } from '@angular/cdk/keycodes';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FocusKeyManager } from '@koobiq/cdk/a11y';
import { Subject, merge } from 'rxjs';
import { startWith, filter } from 'rxjs/operators';
import { KbqIcon } from '@koobiq/components/icon';
import { PlatformModule } from '@angular/cdk/platform';

/** Injection token to be used to override the default options for the chips module. */
const KBQ_TAGS_DEFAULT_OPTIONS = new InjectionToken('kbq-tags-default-options');

/**
 * Event object emitted by KbqTag when the tag is edited.
 */
class KbqTagEditChange {
    constructor(tag, type, reason) {
        this.tag = tag;
        this.type = type;
        this.reason = reason;
    }
}
/** Event object emitted by KbqTag when selected or deselected. */
class KbqTagSelectionChange {
    constructor(source, selected, isUserInput = false) {
        this.source = source;
        this.selected = selected;
        this.isUserInput = isUserInput;
    }
}
const TAG_ATTRIBUTE_NAMES = ['kbq-basic-tag'];
const getTagEditInputMissingError = () => {
    return Error('Editable kbq-tag must contain a KbqTagEditInput.');
};
/**
 * Dummy directive to add CSS class to tag avatar.
 * @docs-private
 */
class KbqTagAvatar {
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTagAvatar, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: KbqTagAvatar, selector: "kbq-tag-avatar, [kbqTagAvatar]", host: { classAttribute: "kbq-tag-avatar" }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTagAvatar, decorators: [{
            type: Directive,
            args: [{
                    selector: 'kbq-tag-avatar, [kbqTagAvatar]',
                    host: { class: 'kbq-tag-avatar' }
                }]
        }] });
/**
 * Dummy directive to add CSS class to tag trailing icon.
 * @docs-private
 */
class KbqTagTrailingIcon {
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTagTrailingIcon, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: KbqTagTrailingIcon, selector: "kbq-tag-trailing-icon, [kbqTagTrailingIcon]", host: { classAttribute: "kbq-tag-trailing-icon" }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTagTrailingIcon, decorators: [{
            type: Directive,
            args: [{
                    selector: 'kbq-tag-trailing-icon, [kbqTagTrailingIcon]',
                    host: { class: 'kbq-tag-trailing-icon' }
                }]
        }] });
/**
 * Directive to add submit behavior for the editable tag.
 */
class KbqTagEditSubmit {
    constructor() {
        /** @docs-private */
        this.tag = inject(KbqTag);
    }
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTagEditSubmit, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: KbqTagEditSubmit, isStandalone: true, selector: "[kbqTagEditSubmit]", host: { listeners: { "click": "tag.submitEditing(\"click\")" }, properties: { "attr.tabindex": "-1" }, classAttribute: "kbq-tag-edit-submit" }, exportAs: ["kbqTagEditSubmit"], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTagEditSubmit, decorators: [{
            type: Directive,
            args: [{
                    standalone: true,
                    selector: '[kbqTagEditSubmit]',
                    exportAs: 'kbqTagEditSubmit',
                    host: {
                        class: 'kbq-tag-edit-submit',
                        '[attr.tabindex]': '-1',
                        '(click)': 'tag.submitEditing("click")'
                    }
                }]
        }] });
/**
 * Directive to add input behavior for the editable tag.
 */
class KbqTagEditInput {
    constructor() {
        this.tag = inject(KbqTag);
    }
    /** @docs-private */
    handleKeydown(event) {
        switch (event.keyCode) {
            case ESCAPE: {
                event.stopPropagation();
                this.tag.cancelEditing('escape');
                break;
            }
            case ENTER: {
                event.stopPropagation();
                this.tag.submitEditing('enter');
                break;
            }
            // We should prevent KbqTag from receiving these keydown events
            case BACKSPACE:
            case SPACE:
            case DELETE: {
                event.stopPropagation();
                break;
            }
            default:
        }
    }
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTagEditInput, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: KbqTagEditInput, isStandalone: true, selector: "[kbqTagEditInput]", host: { listeners: { "keydown": "handleKeydown($event)" }, classAttribute: "kbq-tag-edit-input" }, exportAs: ["kbqTagEditInput"], hostDirectives: [{ directive: i1.KbqFieldSizingContent }], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTagEditInput, decorators: [{
            type: Directive,
            args: [{
                    standalone: true,
                    selector: '[kbqTagEditInput]',
                    exportAs: 'kbqTagEditInput',
                    host: {
                        class: 'kbq-tag-edit-input',
                        '(keydown)': 'handleKeydown($event)'
                    },
                    hostDirectives: [KbqFieldSizingContent]
                }]
        }] });
class KbqTag extends KbqColorDirective {
    /** Whether the tag is editable. */
    get editable() {
        return this._editable ?? !!this.tagList?.editable;
    }
    set editable(value) {
        this._editable = value;
    }
    /** Whether the tag is selected. */
    get selected() {
        return this._selected;
    }
    set selected(value) {
        this.setSelectedState(value, { emitEvent: true });
    }
    /** The value of the tag. Defaults to the content inside `<kbq-tag>` tags. */
    get value() {
        return this._value ?? this.elementRef.nativeElement.textContent?.trim();
    }
    set value(value) {
        this._value = value;
    }
    /**
     * Whether the tag is selectable.
     */
    get selectable() {
        return this._selectable || !!this.tagList?.selectable;
    }
    set selectable(value) {
        this._selectable = value;
    }
    /**
     * Determines whether the tag is removable.
     */
    get removable() {
        return this._removable && (this.tagList?.removable ?? true);
    }
    set removable(value) {
        this._removable = value;
    }
    get tabindex() {
        return this.disabled ? null : this._tabindex;
    }
    set tabindex(value) {
        this._tabindex = value;
    }
    /**
     * Whether the tag is disabled.
     */
    get disabled() {
        return this._disabled || (this.tagList?.disabled ?? false);
    }
    set disabled(value) {
        this._disabled = value;
        this.syncDragDisabledState();
    }
    /**
     * Whether the tag is draggable.
     *
     * @docs-private
     */
    get draggable() {
        return (this.tagList?.draggable ?? false) && !this.disabled;
    }
    constructor(changeDetectorRef) {
        super();
        this.changeDetectorRef = changeDetectorRef;
        this.focusMonitor = inject(FocusMonitor);
        this.tagList = inject(KbqTagList, { optional: true });
        this.drag = inject(CdkDrag, { host: true });
        this.destroyRef = inject(DestroyRef);
        /** @docs-private */
        this.elementRef = inject(ElementRef);
        /**
         * Emits when the tag is focused.
         *
         * @docs-private
         */
        this.onFocus = new Subject();
        /**
         * Emits when the tag is blurred.
         *
         * @docs-private
         */
        this.onBlur = new Subject();
        /** @docs-private */
        this.nativeElement = this.elementRef.nativeElement;
        /**
         * Whether the tag has focus.
         *
         * @docs-private
         */
        this.hasFocus = false;
        /** Whether the tag edits can't be submitted. */
        this.preventEditSubmit = false;
        /**
         * Emits event when the tag is edited.
         */
        this.editChange = new EventEmitter();
        /**
         * @docs-private
         */
        this.editing = signal(false);
        /** Emitted when the tag is selected or deselected. */
        this.selectionChange = new EventEmitter();
        /** Emitted when the tag is destroyed. */
        this.destroyed = new EventEmitter();
        /** Emitted when a tag is to be removed. */
        this.removed = new EventEmitter();
        this._selected = false;
        this._selectable = false;
        this._removable = true;
        this._tabindex = -1;
        this._disabled = false;
        this.color = KbqComponentColors.ContrastFade;
        this.setDefaultColor(KbqComponentColors.ContrastFade);
        this.addHostClassName();
        this.setupDragInitialProperties();
    }
    ngAfterContentInit() {
        this.addClassModificatorForIcons();
    }
    ngAfterViewInit() {
        this.setupFocusMonitor();
    }
    ngOnDestroy() {
        this.cancelEditing('destroy');
        this.focusMonitor.stopMonitoring(this.elementRef);
        this.destroyed.emit({ tag: this });
    }
    /** @docs-private */
    addClassModificatorForIcons() {
        const icons = this.contentChildren.map((item) => item.elementRef.nativeElement);
        if (icons.length === 1) {
            const iconElement = icons[0];
            if (iconElement.classList.contains('kbq-tag-remove')) {
                iconElement.classList.add('kbq-icon_right');
                this.nativeElement.classList.add('kbq-right-icon');
            }
            else {
                iconElement.classList.add('kbq-icon_left');
                this.nativeElement.classList.add('kbq-left-icon');
            }
        }
        else if (icons.length > 1) {
            const firstIconElement = icons[0];
            const secondIconElement = icons[1];
            firstIconElement.classList.add('kbq-icon_left');
            secondIconElement.classList.add('kbq-icon_right');
        }
    }
    /** @docs-private */
    addHostClassName() {
        // Add class for the different tags
        for (const attr of TAG_ATTRIBUTE_NAMES) {
            if (this.elementRef.nativeElement.hasAttribute(attr) ||
                this.elementRef.nativeElement.tagName.toLowerCase() === attr) {
                this.elementRef.nativeElement.classList.add(attr);
                return;
            }
        }
        this.elementRef.nativeElement.classList.add('kbq-standard-tag');
    }
    /**
     * Selects the tag.
     */
    select() {
        if (this.disabled || !this.selectable)
            return;
        this.setSelectedState(true, { emitEvent: true });
    }
    /**
     * Deselects the tag.
     */
    deselect() {
        if (this.disabled || !this.selectable)
            return;
        this.setSelectedState(false, { emitEvent: true });
    }
    /**
     * Selects the tag and emits event with isUserInput flag.
     *
     * @docs-private
     */
    selectViaInteraction() {
        if (this.disabled || !this.selectable)
            return;
        this.setSelectedState(true, { isUserInput: true, emitEvent: true });
    }
    /**
     * Toggles the current selected state of the tag.
     */
    toggleSelected(isUserInput = false) {
        if (this.disabled || !this.selectable)
            return this.selected;
        this.setSelectedState(!this.selected, { isUserInput, emitEvent: true });
        return this.selected;
    }
    /** Focuses the tag. */
    focus() {
        if (this.disabled)
            return;
        this.elementRef.nativeElement.focus();
    }
    /**
     * Allows for programmatic removal of the tag. Called by the KbqTagList when the DELETE or
     * BACKSPACE keys are pressed.
     *
     * Informs any listeners of the removal request. Does not remove the tag from the DOM.
     */
    remove() {
        if (this.removable) {
            this.removed.emit({ tag: this });
        }
    }
    /** @docs-private */
    handleClick(event) {
        if (this.disabled || this.editing()) {
            event.preventDefault();
            return;
        }
        if (
        // We should toggle selection only if tag inside of a tag list.
        // Single tag can only be toggled on focus or blur.
        this.tagList &&
            this.selectable &&
            hasModifierKey(event, 'metaKey', 'ctrlKey', 'shiftKey')) {
            this.toggleSelected(true);
            // We should stop event propagation to prevent the tag list from handling the click event.
            event.stopPropagation();
            return;
        }
    }
    /** @docs-private */
    handleKeydown(event) {
        if (this.disabled || this.editing())
            return;
        switch (event.keyCode) {
            case DELETE:
            case BACKSPACE: {
                // If there is a tag list and it has selected tags, remove them, otherwise remove focused tag.
                this.tagList?.selected.length ? this.tagList.removeSelected() : this.remove();
                // Always prevent so page navigation does not occur
                event.preventDefault();
                break;
            }
            case SPACE: {
                this.toggleSelected(true);
                this.focusMonitor.focusVia(this.elementRef, 'keyboard');
                // Always prevent space from scrolling the page since the list has focus
                event.preventDefault();
                break;
            }
            case F2:
            case ENTER:
                this.startEditing(event.key);
                break;
            default:
        }
    }
    /** @docs-private */
    blur() {
        this.elementRef.nativeElement.blur();
    }
    /** @docs-private */
    handleDblClick(event) {
        if (this.disabled || !this.editable)
            return;
        event.stopPropagation();
        this.startEditing('dblclick');
    }
    startEditing(reason) {
        if (!this.editable || this.editing())
            return;
        this.editing.set(true);
        this.editChange.emit({ tag: this, type: 'start', reason });
        setTimeout(() => {
            const input = this.editInputElementRef?.nativeElement;
            if (!input)
                throw getTagEditInputMissingError();
            input.select();
        });
    }
    /** @docs-private */
    cancelEditing(reason) {
        if (!this.editing())
            return;
        this.editing.set(false);
        this.editChange.emit({ tag: this, type: 'cancel', reason });
        this.textElement.nativeElement.scrollTo?.({ left: 0, behavior: 'instant' });
    }
    /** @docs-private */
    submitEditing(reason) {
        if (!this.editing() || this.preventEditSubmit)
            return;
        this.editing.set(false);
        this.editChange.emit({ tag: this, type: 'submit', reason });
        this.textElement.nativeElement.scrollTo?.({ left: 0, behavior: 'instant' });
    }
    /**
     * Sets the selected state of the tag.
     *
     * @docs-private
     */
    setSelectedState(selected, options = {}) {
        const { isUserInput = false, emitEvent = false } = options;
        if (selected !== this.selected) {
            this._selected = selected;
            if (emitEvent) {
                this.selectionChange.emit({
                    source: this,
                    isUserInput,
                    selected: this.selected
                });
            }
            this.changeDetectorRef.markForCheck();
        }
    }
    setupDragInitialProperties() {
        this.syncDragDisabledState();
        this.drag.started.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
            this.drag.data = { tag: this };
        });
    }
    syncDragDisabledState() {
        this.drag.disabled = !this.draggable;
    }
    setupFocusMonitor() {
        this.focusMonitor.monitor(this.elementRef, true).subscribe((origin) => {
            if (this.disabled)
                return;
            const hasFocus = !isNull(origin);
            if (hasFocus !== this.hasFocus) {
                this.hasFocus = hasFocus;
                if (this.hasFocus) {
                    this.onFocus.next({ tag: this, origin });
                    if (!this.tagList)
                        this.select();
                }
                else {
                    this.onBlur.next({ tag: this });
                    this.cancelEditing('blur');
                    if (!this.tagList)
                        this.deselect();
                }
                this.changeDetectorRef.markForCheck();
            }
        });
    }
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTag, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
    /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: KbqTag, selector: "kbq-tag, [kbq-tag], kbq-basic-tag, [kbq-basic-tag]", inputs: { editable: ["editable", "editable", booleanAttribute], preventEditSubmit: ["preventEditSubmit", "preventEditSubmit", booleanAttribute], selected: ["selected", "selected", booleanAttribute], value: "value", selectable: ["selectable", "selectable", booleanAttribute], removable: ["removable", "removable", booleanAttribute], tabindex: "tabindex", disabled: ["disabled", "disabled", booleanAttribute] }, outputs: { editChange: "editChange", selectionChange: "selectionChange", destroyed: "destroyed", removed: "removed" }, host: { listeners: { "dblclick": "handleDblClick($event)", "click": "handleClick($event)", "keydown": "handleKeydown($event)" }, properties: { "attr.tabindex": "tabindex", "attr.disabled": "disabled || null", "class.kbq-selected": "selected", "class.kbq-tag-with-avatar": "avatar", "class.kbq-tag-with-icon": "contentChildren", "class.kbq-tag-with-trailing-icon": "trailingIcon || removeIcon", "class.kbq-disabled": "disabled", "class.kbq-tag_editable": "editable", "class.kbq-tag_editing": "editing()", "class.kbq-tag_removable": "removable", "class.kbq-tag_selectable": "selectable", "class.kbq-tag_draggable": "draggable" }, classAttribute: "kbq-tag" }, providers: [{ provide: KBQ_TITLE_TEXT_REF, useExisting: KbqTag }], queries: [{ propertyName: "editInputElementRef", first: true, predicate: KbqTagEditInput, descendants: true, read: ElementRef }, { propertyName: "avatar", first: true, predicate: KbqTagAvatar, descendants: true }, { propertyName: "trailingIcon", first: true, predicate: KbqTagTrailingIcon, descendants: true }, { propertyName: "removeIcon", first: true, predicate: i0.forwardRef(() => KbqTagRemove), descendants: true }, { propertyName: "contentChildren", predicate: KbqIcon }], viewQueries: [{ propertyName: "textElement", first: true, predicate: ["kbqTitleText"], descendants: true }], exportAs: ["kbqTag"], usesInheritance: true, hostDirectives: [{ directive: i2.CdkDrag }], ngImport: i0, template: `
        <div class="kbq-tag__wrapper">
            <ng-content select="[kbq-icon]:not([kbqTagRemove]):not([kbqTagEditSubmit])" />
            <span #kbqTitleText class="kbq-tag__text">
                @if (editing()) {
                    <ng-content select="[kbqTagEditInput]" />
                } @else {
                    <ng-content />
                }
            </span>
            @if (editing()) {
                <ng-content select="[kbqTagEditSubmit]" />
            } @else {
                @if (removable) {
                    <ng-content select="[kbqTagRemove]" />
                }
            }
        </div>
    `, isInline: true, styles: [".kbq-tag{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;display:inline-block;max-width:100%;height:var(--kbq-size-xxl);padding:var(--kbq-tag-size-padding-vertical) var(--kbq-tag-size-padding-horizontal);border-radius:4px;cursor:default;outline:none;box-sizing:border-box}.kbq-tag .kbq-icon.kbq-tag-remove{display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-right:var(--kbq-tag-size-close-button-margin-right)}.kbq-tag .kbq-icon.kbq-tag-remove:hover{cursor:pointer}.kbq-tag.kbq-disabled .kbq-icon.kbq-tag-remove:hover{cursor:default}.kbq-tag .kbq-tag__text{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;margin:0 var(--kbq-tag-size-content-gap-horizontal)}.kbq-tag .kbq-icon_left{margin-left:var(--kbq-tag-size-icon-margin-left)}.kbq-tag .kbq-tag-edit-input{background:transparent;padding:0;margin:0;border:none;outline:none;min-width:var(--kbq-size-xs);max-width:100%}.kbq-tag .kbq-tag-edit-input::-ms-clear{display:none;width:0;height:0}.kbq-tag .kbq-tag-edit-input::-ms-reveal{display:none;width:0;height:0}.kbq-tag .kbq-tag-edit-input::-webkit-search-decoration,.kbq-tag .kbq-tag-edit-input::-webkit-search-cancel-button,.kbq-tag .kbq-tag-edit-input::-webkit-search-results-button,.kbq-tag .kbq-tag-edit-input::-webkit-search-results-decoration{display:none}.kbq-tag .kbq-tag-edit-input.kbq-input{min-height:unset!important;border-radius:unset!important;padding:unset!important}.kbq-tag .kbq-tag-edit-submit{margin-right:var(--kbq-size-3xs)}.kbq-tag.cdk-drag-placeholder{opacity:var(--kbq-opacity-disabled)}.kbq-tag.cdk-drag-animating{transition:transform .3s cubic-bezier(0,0,.2,1)}.kbq-tag__wrapper{display:flex;align-items:center;height:100%;flex:1 1 100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTag, decorators: [{
            type: Component,
            args: [{ selector: 'kbq-tag, [kbq-tag], kbq-basic-tag, [kbq-basic-tag]', exportAs: 'kbqTag', hostDirectives: [CdkDrag], template: `
        <div class="kbq-tag__wrapper">
            <ng-content select="[kbq-icon]:not([kbqTagRemove]):not([kbqTagEditSubmit])" />
            <span #kbqTitleText class="kbq-tag__text">
                @if (editing()) {
                    <ng-content select="[kbqTagEditInput]" />
                } @else {
                    <ng-content />
                }
            </span>
            @if (editing()) {
                <ng-content select="[kbqTagEditSubmit]" />
            } @else {
                @if (removable) {
                    <ng-content select="[kbqTagRemove]" />
                }
            }
        </div>
    `, host: {
                        class: 'kbq-tag',
                        '[attr.tabindex]': 'tabindex',
                        '[attr.disabled]': 'disabled || null',
                        '[class.kbq-selected]': 'selected',
                        '[class.kbq-tag-with-avatar]': 'avatar',
                        '[class.kbq-tag-with-icon]': 'contentChildren',
                        '[class.kbq-tag-with-trailing-icon]': 'trailingIcon || removeIcon',
                        '[class.kbq-disabled]': 'disabled',
                        '[class.kbq-tag_editable]': 'editable',
                        '[class.kbq-tag_editing]': 'editing()',
                        '[class.kbq-tag_removable]': 'removable',
                        '[class.kbq-tag_selectable]': 'selectable',
                        '[class.kbq-tag_draggable]': 'draggable',
                        '(dblclick)': 'handleDblClick($event)',
                        '(click)': 'handleClick($event)',
                        '(keydown)': 'handleKeydown($event)'
                    }, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [{ provide: KBQ_TITLE_TEXT_REF, useExisting: KbqTag }], styles: [".kbq-tag{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;display:inline-block;max-width:100%;height:var(--kbq-size-xxl);padding:var(--kbq-tag-size-padding-vertical) var(--kbq-tag-size-padding-horizontal);border-radius:4px;cursor:default;outline:none;box-sizing:border-box}.kbq-tag .kbq-icon.kbq-tag-remove{display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-right:var(--kbq-tag-size-close-button-margin-right)}.kbq-tag .kbq-icon.kbq-tag-remove:hover{cursor:pointer}.kbq-tag.kbq-disabled .kbq-icon.kbq-tag-remove:hover{cursor:default}.kbq-tag .kbq-tag__text{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;margin:0 var(--kbq-tag-size-content-gap-horizontal)}.kbq-tag .kbq-icon_left{margin-left:var(--kbq-tag-size-icon-margin-left)}.kbq-tag .kbq-tag-edit-input{background:transparent;padding:0;margin:0;border:none;outline:none;min-width:var(--kbq-size-xs);max-width:100%}.kbq-tag .kbq-tag-edit-input::-ms-clear{display:none;width:0;height:0}.kbq-tag .kbq-tag-edit-input::-ms-reveal{display:none;width:0;height:0}.kbq-tag .kbq-tag-edit-input::-webkit-search-decoration,.kbq-tag .kbq-tag-edit-input::-webkit-search-cancel-button,.kbq-tag .kbq-tag-edit-input::-webkit-search-results-button,.kbq-tag .kbq-tag-edit-input::-webkit-search-results-decoration{display:none}.kbq-tag .kbq-tag-edit-input.kbq-input{min-height:unset!important;border-radius:unset!important;padding:unset!important}.kbq-tag .kbq-tag-edit-submit{margin-right:var(--kbq-size-3xs)}.kbq-tag.cdk-drag-placeholder{opacity:var(--kbq-opacity-disabled)}.kbq-tag.cdk-drag-animating{transition:transform .3s cubic-bezier(0,0,.2,1)}.kbq-tag__wrapper{display:flex;align-items:center;height:100%;flex:1 1 100%}\n"] }]
        }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { editable: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], preventEditSubmit: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], editInputElementRef: [{
                type: ContentChild,
                args: [KbqTagEditInput, { read: ElementRef }]
            }], editChange: [{
                type: Output
            }], textElement: [{
                type: ViewChild,
                args: ['kbqTitleText']
            }], contentChildren: [{
                type: ContentChildren,
                args: [KbqIcon]
            }], avatar: [{
                type: ContentChild,
                args: [KbqTagAvatar, { static: false }]
            }], trailingIcon: [{
                type: ContentChild,
                args: [KbqTagTrailingIcon, { static: false }]
            }], removeIcon: [{
                type: ContentChild,
                args: [forwardRef(() => KbqTagRemove), { static: false }]
            }], selectionChange: [{
                type: Output
            }], destroyed: [{
                type: Output
            }], removed: [{
                type: Output
            }], selected: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], value: [{
                type: Input
            }], selectable: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], removable: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], tabindex: [{
                type: Input
            }], disabled: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }] } });
/**
 *
 * Example:
 *
 *     `<kbq-tag>
 *       <kbq-icon kbqTagRemove>cancel</kbq-icon>
 *     </kbq-tag>`
 *
 * You *may* use a custom icon, but you may need to override the `kbq-tag-remove` positioning
 * styles to properly center the icon within the tag.
 */
class KbqTagRemove {
    constructor(parentTag) {
        this.parentTag = parentTag;
    }
    /** @docs-private */
    focus(event) {
        event.stopPropagation();
    }
    /**
     * Calls the parent tag's public `remove()` method if applicable.
     *
     * @docs-private
     */
    handleClick(event) {
        if (this.parentTag.removable) {
            this.parentTag.hasFocus = true;
            this.parentTag.remove();
        }
        // We need to stop event propagation because otherwise the event will bubble up to the
        // form field and cause the `onContainerClick` method to be invoked. This method would then
        // reset the focused tag that has been focused after tag removal. Usually the parent
        // the parent click listener of the `KbqTag` would prevent propagation, but it can happen
        // that the tag is being removed before the event bubbles up.
        event.stopPropagation();
    }
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTagRemove, deps: [{ token: forwardRef(() => KbqTag) }], target: i0.ɵɵFactoryTarget.Directive }); }
    /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: KbqTagRemove, selector: "[kbqTagRemove]", host: { listeners: { "click": "handleClick($event)", "focus": "focus($event)" }, properties: { "attr.tabindex": "-1" }, classAttribute: "kbq-tag-remove kbq-tag-trailing-icon" }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTagRemove, decorators: [{
            type: Directive,
            args: [{
                    selector: '[kbqTagRemove]',
                    host: {
                        class: 'kbq-tag-remove kbq-tag-trailing-icon',
                        '[attr.tabindex]': '-1',
                        '(click)': 'handleClick($event)',
                        '(focus)': 'focus($event)'
                    }
                }]
        }], ctorParameters: () => [{ type: KbqTag, decorators: [{
                    type: Inject,
                    args: [forwardRef(() => KbqTag)]
                }] }] });

// Increasing integer for generating unique ids for tag-list components.
let nextUniqueId$1 = 0;
/** Change event object that is emitted when the tag list value has changed. */
class KbqTagListChange {
    constructor(source, value) {
        this.source = source;
        this.value = value;
    }
}
class KbqTagList {
    /**
     * Combined stream of all of the child tags' selection change events.
     *
     * @docs-private
     */
    get tagSelectionChanges() {
        return merge(...this.tags.map((tag) => tag.selectionChange));
    }
    /**
     * Combined stream of all of the child tags' focus change events.
     *
     * @docs-private
     */
    get tagFocusChanges() {
        return merge(...this.tags.map((tag) => tag.onFocus));
    }
    /**
     * Combined stream of all of the child tags' blur change events.
     *
     * @docs-private
     */
    get tagBlurChanges() {
        return merge(...this.tags.map((tag) => tag.onBlur));
    }
    /**
     * Combined stream of all of the child tags' remove change events.
     *
     * @docs-private
     */
    get tagRemoveChanges() {
        return merge(...this.tags.map((tag) => tag.destroyed));
    }
    /**
     * Combined stream of all of the child tags' edit change events.
     *
     * @docs-private
     */
    get tagEditChanges() {
        return merge(...this.tags.map((tag) => tag.editChange));
    }
    /**
     * The array of selected tags inside tag list.
     *
     * @docs-private
     */
    get selected() {
        return this.tags.filter(({ selected }) => selected);
    }
    /** @docs-private */
    get canShowCleaner() {
        return this.cleaner && this.tags.length > 0;
    }
    /**
     * Implemented as part of KbqFormFieldControl.
     * @docs-private
     */
    get value() {
        return this._value;
    }
    set value(value) {
        this._value = value;
    }
    /**
     * Implemented as part of KbqFormFieldControl.
     * @docs-private
     */
    get id() {
        return this.tagInput ? this.tagInput.id : this.uid;
    }
    /**
     * Implemented as part of KbqFormFieldControl.
     * @docs-private
     */
    get required() {
        return this._required;
    }
    set required(value) {
        this._required = coerceBooleanProperty(value);
        this.stateChanges.next();
    }
    /**
     * Implemented as part of KbqFormFieldControl.
     * @docs-private
     */
    get placeholder() {
        return this.tagInput ? this.tagInput.placeholder : this._placeholder;
    }
    set placeholder(value) {
        this._placeholder = value;
        this.stateChanges.next();
    }
    /** Whether any tags or the kbqTagInput inside of this tag-list has focus. */
    get focused() {
        return (this.tagInput && this.tagInput.focused) || this.hasFocusedTag();
    }
    /**
     * Implemented as part of KbqFormFieldControl.
     * @docs-private
     */
    get empty() {
        return (!this.tagInput || this.tagInput.empty) && this.tags.length === 0;
    }
    /**
     * Implemented as part of KbqFormFieldControl.
     * @docs-private
     */
    get shouldLabelFloat() {
        return !this.empty || this.focused;
    }
    /**
     * Implemented as part of KbqFormFieldControl.
     * @docs-private
     */
    get disabled() {
        return this.ngControl ? !!this.ngControl.disabled : this._disabled;
    }
    set disabled(value) {
        this._disabled = value;
        this.syncDropListDisabledState();
    }
    get draggable() {
        return this._draggable && !this.disabled;
    }
    set draggable(value) {
        this._draggable = value;
        this.syncDropListDisabledState();
    }
    /** Whether the tags in the list are removable. */
    get removable() {
        return this._removable;
    }
    set removable(value) {
        this._removable = value;
        this.syncTagsRemovableState();
    }
    /**
     * Tab index of the tag list. This property is ignored when the tag list contains a tag input or is disabled.
     *
     * @docs-private
     */
    get tabIndex() {
        return this.disabled || this.tagInput ? null : this._tabIndex;
    }
    set tabIndex(value) {
        this.userTabIndex = value;
        this._tabIndex = value;
    }
    constructor(elementRef, changeDetectorRef, defaultErrorStateMatcher, dir, parentForm, parentFormGroup, ngControl) {
        this.elementRef = elementRef;
        this.changeDetectorRef = changeDetectorRef;
        this.defaultErrorStateMatcher = defaultErrorStateMatcher;
        this.dir = dir;
        this.parentForm = parentForm;
        this.parentFormGroup = parentFormGroup;
        this.ngControl = ngControl;
        this.dropList = inject(CdkDropList, { host: true });
        this.destroyRef = inject(DestroyRef);
        this.focusMonitor = inject(FocusMonitor);
        /**
         * Implemented as part of KbqFormFieldControl.
         *
         * @docs-private
         */
        this.controlType = 'tag-list';
        /**
         * Emits whenever the component state changes and should cause the parent
         * form-field to update. Implemented as part of `KbqFormFieldControl`.
         * @docs-private
         */
        this.stateChanges = new Subject();
        /**
         * @deprecated Unused. Will be removed in next major release.
         *
         * @docs-private
         */
        this.multiple = false;
        /**
         * A function to compare the option values with the selected values. The first argument
         * is a value from an option. The second is a value from the selection. A boolean
         * should be returned.
         *
         * @deprecated Unused. Will be removed in next major release.
         */
        this.compareWith = (o1, o2) => o1 === o2;
        this._required = false;
        this._disabled = false;
        this._draggable = false;
        /**
         * Emits when the user drops tag inside tag list container.
         */
        this.dropped = new EventEmitter();
        /**
         * Whether or not this tag list is selectable. When a tag list is not selectable,
         * the selected states for all the tags inside the tag list are always ignored.
         */
        this.selectable = true;
        /** Whether the tags in the list are editable. */
        this.editable = false;
        this._removable = true;
        this._tabIndex = 0;
        /**
         * Event that emits whenever the raw value of the tag-list changes. This is here primarily
         * to facilitate the two-way binding for the `value` input.
         * @docs-private
         */
        this.valueChange = new EventEmitter();
        /** @docs-private */
        this.uid = `kbq-tag-list-${nextUniqueId$1++}`;
        /**
         * User defined tab index.
         * When it is not null, use user defined tab index. Otherwise use tabIndex
         *
         * @docs-private
         */
        this.userTabIndex = null;
        /**
         * @docs-private
         *
         * @deprecated Unused. Will be removed in next major release.
         */
        this.tagChanges = new EventEmitter();
        /**
         * Orientation of the tag list.
         *
         * @deprecated Unused. Will be removed in next major release.
         */
        this.orientation = 'horizontal';
        /** Event emitted when the selected tag list value has been changed by the user. */
        this.change = new EventEmitter();
        /**
         * Whether the component is in an error state.
         *
         * @docs-private
         */
        this.errorState = false;
        /**
         * When a tag is destroyed, we store the index of the destroyed tag until the tags
         * query list notifies about the update. This is necessary because we cannot determine an
         * appropriate tag that should receive focus until the array of tags updated completely.
         */
        this.lastDestroyedTagIndex = null;
        /** @docs-private */
        this.onTouched = () => { };
        /** @docs-private */
        this.onChange = () => { };
        if (this.ngControl) {
            this.ngControl.valueAccessor = this;
        }
        this.setupDropListInitialProperties();
    }
    ngDoCheck() {
        if (this.ngControl) {
            // We need to re-evaluate this on every change detection cycle, because there are some
            // error triggers that we can't subscribe to (e.g. parent form submissions). This means
            // that whatever logic is in here has to be super lean or we risk destroying the performance.
            this.updateErrorState();
        }
    }
    ngAfterContentInit() {
        this.keyManager = new FocusKeyManager(this.tags)
            .withVerticalOrientation()
            .withHorizontalOrientation(this.dir ? this.dir.value : 'ltr')
            .skipPredicate(({ disabled }) => disabled);
        if (this.dir) {
            this.dir.change
                .pipe(takeUntilDestroyed(this.destroyRef))
                .subscribe((dir) => this.keyManager.withHorizontalOrientation(dir));
        }
        // Prevents the tag list from capturing focus and redirecting
        // it back to the first tag when the user tabs out.
        this.keyManager.tabOut.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
            this._tabIndex = -1;
            setTimeout(() => {
                this._tabIndex = this.userTabIndex || 0;
                this.changeDetectorRef.markForCheck();
            });
        });
        // When the list changes, re-subscribe
        this.tags.changes
            .pipe(startWith(null), takeUntilDestroyed(this.destroyRef))
            .subscribe((currentTags) => {
            this.resetTags();
            // Check to see if we need to update our tab index
            this.updateTabIndex();
            // Check to see if we have a destroyed tag and need to refocus
            this.updateFocusForDestroyedTags();
            // Defer setting the value in order to avoid the "Expression
            // has changed after it was checked" errors from Angular.
            Promise.resolve().then(() => {
                this.stateChanges.next();
                // do not call on initial
                if (currentTags) {
                    this.propagateTagsChanges();
                }
            });
        });
    }
    ngAfterViewInit() {
        this.setupFocusMonitor();
    }
    ngOnDestroy() {
        this.stateChanges.complete();
        this.focusMonitor.stopMonitoring(this.elementRef);
        this.dropSubscriptions();
    }
    /** @docs-private */
    updateErrorState() {
        const oldState = this.errorState;
        const parent = this.parentFormGroup || this.parentForm;
        const matcher = this.errorStateMatcher || this.defaultErrorStateMatcher;
        const control = this.ngControl ? this.ngControl.control : null;
        const newState = matcher.isErrorState(control, parent);
        if (newState !== oldState) {
            this.errorState = newState;
            this.stateChanges.next();
        }
    }
    /**
     * Associates an HTML input element with this tag list.
     *
     * @docs-private
     */
    registerInput(inputElement) {
        this.tagInput = inputElement;
        // todo need rethink about it (#DS-3740)
        if (this.ngControl && inputElement.ngControl?.statusChanges) {
            inputElement.ngControl.statusChanges.subscribe(() => this.ngControl.control.setErrors(inputElement.ngControl.errors));
        }
    }
    /**
     * Implemented as part of ControlValueAccessor.
     */
    writeValue(value) {
        this.value = value;
    }
    /**
     * Implemented as part of ControlValueAccessor.
     */
    registerOnChange(fn) {
        this.onChange = fn;
    }
    /**
     * Implemented as part of ControlValueAccessor.
     */
    registerOnTouched(fn) {
        this.onTouched = fn;
    }
    /**
     * Implemented as part of ControlValueAccessor.
     */
    setDisabledState(isDisabled) {
        this.disabled = isDisabled;
        this.stateChanges.next();
    }
    /**
     * Implemented as part of KbqFormFieldControl.
     *
     * @docs-private
     */
    onContainerClick() {
        this.focus();
    }
    /**
     * Focuses the tag list. If there is a tag input, focuses that instead.
     */
    focus() {
        if (this.disabled)
            return;
        if (this.tagInput) {
            this.focusInput();
            this.stateChanges.next();
            return;
        }
        if (this.tags.length > 0) {
            this.keyManager.setFirstItemActive();
            this.stateChanges.next();
            return;
        }
    }
    /**
     * Focuses the tag input inside the tag list.
     *
     * @docs-private
     */
    focusInput() {
        if (this.tagInput) {
            this.tagInput.focus();
        }
    }
    /**
     * Pass events to the keyboard manager. Available here for tests.
     *
     * @docs-private
     */
    keydown(event) {
        const target = event.target;
        if (this.disabled || isNull(target))
            return;
        const shouldSelectAll = this.selectable && isSelectAll(event);
        if (this.isInputEmpty(target)) {
            if (event.keyCode === BACKSPACE ||
                event.keyCode === LEFT_ARROW ||
                (event.keyCode === TAB && event.shiftKey)) {
                this.keyManager.setLastItemActive();
                event.preventDefault();
                return;
            }
            if (shouldSelectAll) {
                this.selectAll();
                this.keyManager.setLastItemActive();
                event.preventDefault();
                return;
            }
        }
        else if (this.isTagElement(target)) {
            if (event.keyCode === HOME) {
                this.keyManager.setFirstItemActive();
                event.preventDefault();
            }
            else if (event.keyCode === END) {
                this.keyManager.setLastItemActive();
                event.preventDefault();
            }
            else if (shouldSelectAll) {
                this.selectAll();
                this.keyManager.setLastItemActive();
                event.preventDefault();
            }
            else {
                this.keyManager.onKeydown(event);
            }
            this.stateChanges.next();
        }
    }
    /**
     * @docs-private
     *
     * @deprecated Unused. Will be removed in next major release.
     */
    setSelectionByValue(_value, _isUserInput = true) { }
    /** When blurred, mark the field as touched when focus moved outside the tag list. */
    blur() {
        if (!this.hasFocusedTag()) {
            this.keyManager.setActiveItem(-1);
        }
        if (!this.disabled) {
            if (this.tagInput) {
                // If there's a tag input, we should check whether the focus moved to tag input.
                // If the focus is not moved to tag input, mark the field as touched. If the focus moved
                // to tag input, do nothing.
                // Timeout is needed to wait for the focus() event trigger on tag input.
                setTimeout(() => {
                    if (!this.focused) {
                        this.markAsTouched();
                        this.revalidate();
                    }
                });
            }
            else {
                // If there's no tag input, then mark the field as touched.
                this.markAsTouched();
                this.revalidate();
            }
        }
    }
    /** Mark the field as touched */
    markAsTouched() {
        this.onTouched();
        this.changeDetectorRef.markForCheck();
        this.stateChanges.next();
    }
    /**
     * Check the tab index as you should not be allowed to focus an empty list.
     *
     * @docs-private
     */
    updateTabIndex() {
        // If we have 0 tags, we should not allow keyboard focus
        this._tabIndex = this.userTabIndex || (this.tags.length === 0 ? -1 : 0);
    }
    /**
     * If the amount of tags changed, we need to update the
     * key manager state and focus the next closest tag.
     *
     * @docs-private
     */
    updateFocusForDestroyedTags() {
        if (this.lastDestroyedTagIndex != null) {
            if (this.tags.length) {
                const newTagIndex = Math.min(this.lastDestroyedTagIndex, this.tags.length - 1);
                this.keyManager.setActiveItem(newTagIndex);
            }
            else {
                this.focusInput();
            }
        }
        this.lastDestroyedTagIndex = null;
    }
    /**
     * Utility to ensure all indexes are valid.
     *
     * @param index The index to be checked.
     * @returns True if the index is valid for our list of tags.
     */
    isValidIndex(index) {
        return index >= 0 && index < this.tags.length;
    }
    isInputElement(element) {
        return element.nodeName.toLowerCase() === 'input';
    }
    isInputEmpty(element) {
        if (!this.isInputElement(element))
            return false;
        return !element.value;
    }
    isTagElement(element) {
        return element.classList.contains('kbq-tag');
    }
    selectAll() {
        this.tags.forEach((tag) => tag.selectViaInteraction());
    }
    /**
     * Unselects all tags in the list.
     *
     * @docs-private
     */
    unselectAll() {
        this.tags.forEach((tag) => tag.setSelectedState(false));
    }
    /**
     * Removes all selected tags from the list.
     *
     * @docs-private
     */
    removeSelected() {
        this.selected.forEach((tag) => tag.remove());
    }
    propagateTagsChanges() {
        const valueToEmit = this.tags.map((tag) => tag.value);
        this._value = valueToEmit;
        this.change.emit(new KbqTagListChange(this, valueToEmit));
        this.valueChange.emit(valueToEmit);
        this.onChange(valueToEmit);
        this.changeDetectorRef.markForCheck();
    }
    resetTags() {
        this.dropSubscriptions();
        this.listenToTagsFocus();
        this.listenToTagsRemoved();
        this.listenToTagsEdit();
    }
    dropSubscriptions() {
        if (this.tagFocusSubscription) {
            this.tagFocusSubscription.unsubscribe();
            this.tagFocusSubscription = null;
        }
        if (this.tagBlurSubscription) {
            this.tagBlurSubscription.unsubscribe();
            this.tagBlurSubscription = null;
        }
        if (this.tagRemoveSubscription) {
            this.tagRemoveSubscription.unsubscribe();
            this.tagRemoveSubscription = null;
        }
        if (this.tagEditSubscription) {
            this.tagEditSubscription.unsubscribe();
            this.tagEditSubscription = null;
        }
    }
    /** Listens to user-generated selection events on each tag. */
    listenToTagsFocus() {
        this.tagFocusSubscription = this.tagFocusChanges.subscribe(({ tag, origin }) => {
            const tagIndex = this.tags.toArray().indexOf(tag);
            if (this.isValidIndex(tagIndex)) {
                this.keyManager.setFocusOrigin(origin);
                this.keyManager.updateActiveItem(tagIndex);
            }
            this.stateChanges.next();
        });
        this.tagBlurSubscription = this.tagBlurChanges.subscribe(() => {
            this.blur();
            this.stateChanges.next();
        });
    }
    listenToTagsRemoved() {
        this.tagRemoveSubscription = this.tagRemoveChanges.subscribe((event) => {
            const tag = event.tag;
            const tagIndex = this.tags.toArray().indexOf(event.tag);
            // In case the tag that will be removed is currently focused, we temporarily store
            // the index in order to be able to determine an appropriate sibling tag that will
            // receive focus.
            if (this.isValidIndex(tagIndex) && tag.hasFocus) {
                this.lastDestroyedTagIndex = tagIndex;
            }
        });
    }
    listenToTagsEdit() {
        this.tagEditSubscription = this.tagEditChanges
            .pipe(filter(({ type }) => type === 'submit'))
            .subscribe(() => this.propagateTagsChanges());
    }
    /** Checks whether any of the tags is focused. */
    hasFocusedTag() {
        return this.tags.some((tag) => tag.hasFocus);
    }
    syncTagsRemovableState() {
        this.tags?.forEach((tag) => (tag.removable = this.removable));
    }
    /** Revalidate control. */
    revalidate() {
        if (this.ngControl?.control) {
            const control = this.ngControl.control;
            control.updateValueAndValidity({ emitEvent: false });
            control.statusChanges.emit(control.status);
        }
    }
    setupDropListInitialProperties() {
        this.syncDropListDisabledState();
        this.dropList.elementContainerSelector = '.kbq-tags-list__list-container';
        this.dropList.orientation = 'mixed';
        this.dropList.dropped
            .pipe(takeUntilDestroyed(this.destroyRef))
            .subscribe(({ currentIndex, previousIndex, event, item }) => {
            const { tag } = item.data;
            this.dropped.emit({ currentIndex, previousIndex, event, tag });
        });
    }
    syncDropListDisabledState() {
        this.dropList.disabled = !this.draggable;
    }
    setupFocusMonitor() {
        this.focusMonitor.monitor(this.elementRef, true).subscribe((origin) => {
            if (!origin)
                this.unselectAll();
        });
    }
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTagList, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1.ErrorStateMatcher }, { token: i2$1.Directionality, optional: true }, { token: i3.NgForm, optional: true }, { token: i3.FormGroupDirective, optional: true }, { token: i3.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component }); }
    /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: KbqTagList, selector: "kbq-tag-list", inputs: { multiple: ["multiple", "multiple", booleanAttribute], compareWith: "compareWith", value: "value", required: "required", placeholder: "placeholder", disabled: ["disabled", "disabled", booleanAttribute], draggable: ["draggable", "draggable", booleanAttribute], selectable: ["selectable", "selectable", booleanAttribute], editable: ["editable", "editable", booleanAttribute], removable: ["removable", "removable", booleanAttribute], tabIndex: "tabIndex", errorStateMatcher: "errorStateMatcher", orientation: "orientation" }, outputs: { dropped: "dropped", valueChange: "valueChange", change: "change" }, host: { listeners: { "focus": "focus()", "blur": "blur()", "keydown": "keydown($event)" }, properties: { "class.kbq-disabled": "disabled", "class.kbq-invalid": "errorState", "class.kbq-tag-list_selectable": "selectable", "class.kbq-tag-list_editable": "editable", "class.kbq-tag-list_removable": "removable", "class.kbq-tag-list_draggable": "draggable", "attr.tabindex": "tabIndex", "id": "uid" }, classAttribute: "kbq-tag-list" }, providers: [{ provide: KbqFormFieldControl, useExisting: KbqTagList }], queries: [{ propertyName: "cleaner", first: true, predicate: ["kbqTagListCleaner"], descendants: true, static: true }, { propertyName: "tags", predicate: KbqTag, descendants: true }], exportAs: ["kbqTagList"], hostDirectives: [{ directive: i2.CdkDropList }], ngImport: i0, template: `
        <div class="kbq-tags-list__list-container">
            <ng-content />
        </div>

        @if (canShowCleaner) {
            <div class="kbq-tags-list__cleaner">
                <ng-content select="kbq-cleaner" />
            </div>
        }
    `, isInline: true, styles: [".kbq-tag-list{display:flex;flex-direction:row;min-height:var(--kbq-size-xxl);box-sizing:border-box}.kbq-tag-list:focus-visible{outline:none}.kbq-tag-list.cdk-drop-list-dragging .cdk-drag{transition:transform .25s cubic-bezier(0,0,.2,1)}.kbq-tag-input{background:transparent;padding:0;margin:0;border:none;outline:none;padding-top:var(--kbq-tag-size-padding-vertical);padding-bottom:var(--kbq-tag-size-padding-vertical);padding-left:var(--kbq-size-xxs);padding-right:unset;min-width:var(--kbq-size-3xl);max-width:100%;flex-grow:1}.kbq-tag-input::-ms-clear{display:none;width:0;height:0}.kbq-tag-input::-ms-reveal{display:none;width:0;height:0}.kbq-tag-input::-webkit-search-decoration,.kbq-tag-input::-webkit-search-cancel-button,.kbq-tag-input::-webkit-search-results-button,.kbq-tag-input::-webkit-search-results-decoration{display:none}.kbq-tag-input.kbq-input{--kbq-input-size-padding-vertical: 0;--kbq-form-field-size-border-radius: 0;padding-left:var(--kbq-size-xxs);min-height:unset!important;width:auto}.kbq-tags-list__list-container{display:flex;flex-wrap:wrap;flex:1 1 100%;box-sizing:border-box;min-width:0;gap:var(--kbq-tag-list-size-content-gap)}.kbq-tags-list__list-container .kbq-tag-input:first-child{padding-left:var(--kbq-size-s)}.kbq-tags-list__cleaner .kbq-cleaner{max-height:24px}.kbq-form-field-type-tag-list .kbq-form-field__container{padding-top:calc(var(--kbq-tag-input-size-padding-vertical) - var(--kbq-form-field-size-border-width));padding-bottom:calc(var(--kbq-tag-input-size-padding-vertical) - var(--kbq-form-field-size-border-width))}body:has(.kbq-tag-list.cdk-drop-list-dragging){cursor:grabbing}\n", ".kbq-tag,.kbq-tag-list,.kbq-tag-input{--kbq-tag-list-size-content-gap: var(--kbq-size-xxs);--kbq-tag-size-padding-horizontal: var(--kbq-size-xxs);--kbq-tag-size-padding-vertical: var(--kbq-size-3xs);--kbq-tag-size-content-gap-horizontal: var(--kbq-size-3xs);--kbq-tag-size-icon-margin-left: var(--kbq-size-3xs);--kbq-tag-size-close-button-margin-right: var(--kbq-size-3xs);--kbq-tag-theme-fade-on-default-background: var(--kbq-background-theme-fade);--kbq-tag-theme-fade-on-default-text: var(--kbq-foreground-theme);--kbq-tag-theme-fade-on-default-icon: var(--kbq-icon-theme);--kbq-tag-theme-fade-on-default-close-button: var(--kbq-icon-theme);--kbq-tag-theme-fade-on-states-hover-background: var(--kbq-states-background-theme-fade-hover);--kbq-tag-theme-fade-on-states-hover-text: var(--kbq-foreground-theme);--kbq-tag-theme-fade-on-states-hover-icon: var(--kbq-icon-theme);--kbq-tag-theme-fade-on-states-hover-close-button: var(--kbq-icon-theme);--kbq-tag-theme-fade-on-states-focus-background: var(--kbq-background-theme-fade);--kbq-tag-theme-fade-on-states-focus-text: var(--kbq-foreground-theme);--kbq-tag-theme-fade-on-states-focus-icon: var(--kbq-icon-theme);--kbq-tag-theme-fade-on-states-focus-close-button: var(--kbq-icon-theme);--kbq-tag-theme-fade-on-states-focus-outline: var(--kbq-states-line-focus-theme);--kbq-tag-theme-fade-on-states-selected-background: var(--kbq-background-theme);--kbq-tag-theme-fade-on-states-selected-text: var(--kbq-foreground-white);--kbq-tag-theme-fade-on-states-selected-icon: var(--kbq-icon-white);--kbq-tag-theme-fade-on-states-selected-close-button: var(--kbq-icon-white);--kbq-tag-theme-fade-on-states-disabled-background: var(--kbq-states-background-disabled);--kbq-tag-theme-fade-on-states-disabled-text: var(--kbq-states-foreground-disabled);--kbq-tag-theme-fade-on-states-disabled-icon: var(--kbq-states-icon-disabled);--kbq-tag-theme-fade-on-states-disabled-close-button: var(--kbq-states-icon-disabled);--kbq-tag-contrast-fade-on-default-background: var(--kbq-background-contrast-fade);--kbq-tag-contrast-fade-on-default-text: var(--kbq-foreground-contrast);--kbq-tag-contrast-fade-on-default-icon: var(--kbq-icon-contrast-fade);--kbq-tag-contrast-fade-on-default-close-button: var(--kbq-icon-contrast-fade);--kbq-tag-contrast-fade-on-states-hover-background: var(--kbq-states-background-contrast-fade-hover);--kbq-tag-contrast-fade-on-states-hover-text: var(--kbq-foreground-contrast);--kbq-tag-contrast-fade-on-states-hover-icon: var(--kbq-icon-contrast-fade);--kbq-tag-contrast-fade-on-states-hover-close-button: var(--kbq-icon-contrast-fade);--kbq-tag-contrast-fade-on-states-focus-background: var(--kbq-background-contrast-fade);--kbq-tag-contrast-fade-on-states-focus-text: var(--kbq-foreground-contrast);--kbq-tag-contrast-fade-on-states-focus-icon: var(--kbq-icon-contrast-fade);--kbq-tag-contrast-fade-on-states-focus-close-button: var(--kbq-icon-contrast-fade);--kbq-tag-contrast-fade-on-states-focus-outline: var(--kbq-states-line-focus-theme);--kbq-tag-contrast-fade-on-states-selected-background: var(--kbq-background-theme);--kbq-tag-contrast-fade-on-states-selected-text: var(--kbq-foreground-white);--kbq-tag-contrast-fade-on-states-selected-icon: var(--kbq-icon-white);--kbq-tag-contrast-fade-on-states-selected-close-button: var(--kbq-icon-white);--kbq-tag-contrast-fade-on-states-disabled-background: var(--kbq-states-background-disabled);--kbq-tag-contrast-fade-on-states-disabled-text: var(--kbq-states-foreground-disabled);--kbq-tag-contrast-fade-on-states-disabled-icon: var(--kbq-states-icon-disabled);--kbq-tag-contrast-fade-on-states-disabled-close-button: var(--kbq-states-icon-disabled);--kbq-tag-error-fade-on-default-background: var(--kbq-background-error-fade);--kbq-tag-error-fade-on-default-text: var(--kbq-foreground-error);--kbq-tag-error-fade-on-default-icon: var(--kbq-icon-error);--kbq-tag-error-fade-on-default-close-button: var(--kbq-icon-error);--kbq-tag-error-fade-on-states-hover-background: var(--kbq-states-background-error-fade-hover);--kbq-tag-error-fade-on-states-hover-text: var(--kbq-foreground-error);--kbq-tag-error-fade-on-states-hover-icon: var(--kbq-icon-error);--kbq-tag-error-fade-on-states-hover-close-button: var(--kbq-icon-error);--kbq-tag-error-fade-on-states-focus-background: var(--kbq-background-error-fade);--kbq-tag-error-fade-on-states-focus-text: var(--kbq-foreground-error);--kbq-tag-error-fade-on-states-focus-icon: var(--kbq-icon-error);--kbq-tag-error-fade-on-states-focus-close-button: var(--kbq-icon-error);--kbq-tag-error-fade-on-states-focus-outline: var(--kbq-states-line-focus-error);--kbq-tag-error-fade-on-states-selected-background: var(--kbq-background-error);--kbq-tag-error-fade-on-states-selected-text: var(--kbq-foreground-white);--kbq-tag-error-fade-on-states-selected-icon: var(--kbq-icon-white);--kbq-tag-error-fade-on-states-selected-close-button: var(--kbq-icon-white);--kbq-tag-error-fade-on-states-disabled-background: var(--kbq-states-background-disabled);--kbq-tag-error-fade-on-states-disabled-text: var(--kbq-states-foreground-disabled);--kbq-tag-error-fade-on-states-disabled-icon: var(--kbq-states-icon-disabled);--kbq-tag-error-fade-on-states-disabled-close-button: var(--kbq-states-icon-disabled);--kbq-tag-warning-fade-default-background: var(--kbq-background-warning-fade);--kbq-tag-warning-fade-default-text: var(--kbq-foreground-warning);--kbq-tag-warning-fade-default-icon: var(--kbq-icon-warning);--kbq-tag-warning-fade-default-close-button: var(--kbq-icon-warning);--kbq-tag-warning-fade-states-hover-background: var(--kbq-states-background-warning-fade-hover);--kbq-tag-warning-fade-states-hover-text: var(--kbq-foreground-warning);--kbq-tag-warning-fade-states-hover-icon: var(--kbq-icon-warning);--kbq-tag-warning-fade-states-hover-close-button: var(--kbq-icon-warning);--kbq-tag-warning-fade-states-focus-background: var(--kbq-background-warning-fade);--kbq-tag-warning-fade-states-focus-text: var(--kbq-foreground-warning);--kbq-tag-warning-fade-states-focus-icon: var(--kbq-icon-warning);--kbq-tag-warning-fade-states-focus-close-button: var(--kbq-icon-warning);--kbq-tag-warning-fade-states-focus-outline: var(--kbq-line-warning);--kbq-tag-warning-fade-states-selected-background: var(--kbq-background-warning);--kbq-tag-warning-fade-states-selected-text: var(--kbq-foreground-white);--kbq-tag-warning-fade-states-selected-icon: var(--kbq-icon-white);--kbq-tag-warning-fade-states-selected-close-button: var(--kbq-icon-white);--kbq-tag-warning-fade-states-disabled-background: var(--kbq-states-background-disabled);--kbq-tag-warning-fade-states-disabled-text: var(--kbq-states-foreground-disabled);--kbq-tag-warning-fade-states-disabled-icon: var(--kbq-states-icon-disabled);--kbq-tag-warning-fade-states-disabled-close-button: var(--kbq-states-icon-disabled)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTagList, decorators: [{
            type: Component,
            args: [{ selector: 'kbq-tag-list', exportAs: 'kbqTagList', template: `
        <div class="kbq-tags-list__list-container">
            <ng-content />
        </div>

        @if (canShowCleaner) {
            <div class="kbq-tags-list__cleaner">
                <ng-content select="kbq-cleaner" />
            </div>
        }
    `, host: {
                        class: 'kbq-tag-list',
                        '[class.kbq-disabled]': 'disabled',
                        '[class.kbq-invalid]': 'errorState',
                        '[class.kbq-tag-list_selectable]': 'selectable',
                        '[class.kbq-tag-list_editable]': 'editable',
                        '[class.kbq-tag-list_removable]': 'removable',
                        '[class.kbq-tag-list_draggable]': 'draggable',
                        '[attr.tabindex]': 'tabIndex',
                        '[id]': 'uid',
                        '(focus)': 'focus()',
                        '(blur)': 'blur()',
                        '(keydown)': 'keydown($event)'
                    }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: KbqFormFieldControl, useExisting: KbqTagList }], hostDirectives: [CdkDropList], styles: [".kbq-tag-list{display:flex;flex-direction:row;min-height:var(--kbq-size-xxl);box-sizing:border-box}.kbq-tag-list:focus-visible{outline:none}.kbq-tag-list.cdk-drop-list-dragging .cdk-drag{transition:transform .25s cubic-bezier(0,0,.2,1)}.kbq-tag-input{background:transparent;padding:0;margin:0;border:none;outline:none;padding-top:var(--kbq-tag-size-padding-vertical);padding-bottom:var(--kbq-tag-size-padding-vertical);padding-left:var(--kbq-size-xxs);padding-right:unset;min-width:var(--kbq-size-3xl);max-width:100%;flex-grow:1}.kbq-tag-input::-ms-clear{display:none;width:0;height:0}.kbq-tag-input::-ms-reveal{display:none;width:0;height:0}.kbq-tag-input::-webkit-search-decoration,.kbq-tag-input::-webkit-search-cancel-button,.kbq-tag-input::-webkit-search-results-button,.kbq-tag-input::-webkit-search-results-decoration{display:none}.kbq-tag-input.kbq-input{--kbq-input-size-padding-vertical: 0;--kbq-form-field-size-border-radius: 0;padding-left:var(--kbq-size-xxs);min-height:unset!important;width:auto}.kbq-tags-list__list-container{display:flex;flex-wrap:wrap;flex:1 1 100%;box-sizing:border-box;min-width:0;gap:var(--kbq-tag-list-size-content-gap)}.kbq-tags-list__list-container .kbq-tag-input:first-child{padding-left:var(--kbq-size-s)}.kbq-tags-list__cleaner .kbq-cleaner{max-height:24px}.kbq-form-field-type-tag-list .kbq-form-field__container{padding-top:calc(var(--kbq-tag-input-size-padding-vertical) - var(--kbq-form-field-size-border-width));padding-bottom:calc(var(--kbq-tag-input-size-padding-vertical) - var(--kbq-form-field-size-border-width))}body:has(.kbq-tag-list.cdk-drop-list-dragging){cursor:grabbing}\n", ".kbq-tag,.kbq-tag-list,.kbq-tag-input{--kbq-tag-list-size-content-gap: var(--kbq-size-xxs);--kbq-tag-size-padding-horizontal: var(--kbq-size-xxs);--kbq-tag-size-padding-vertical: var(--kbq-size-3xs);--kbq-tag-size-content-gap-horizontal: var(--kbq-size-3xs);--kbq-tag-size-icon-margin-left: var(--kbq-size-3xs);--kbq-tag-size-close-button-margin-right: var(--kbq-size-3xs);--kbq-tag-theme-fade-on-default-background: var(--kbq-background-theme-fade);--kbq-tag-theme-fade-on-default-text: var(--kbq-foreground-theme);--kbq-tag-theme-fade-on-default-icon: var(--kbq-icon-theme);--kbq-tag-theme-fade-on-default-close-button: var(--kbq-icon-theme);--kbq-tag-theme-fade-on-states-hover-background: var(--kbq-states-background-theme-fade-hover);--kbq-tag-theme-fade-on-states-hover-text: var(--kbq-foreground-theme);--kbq-tag-theme-fade-on-states-hover-icon: var(--kbq-icon-theme);--kbq-tag-theme-fade-on-states-hover-close-button: var(--kbq-icon-theme);--kbq-tag-theme-fade-on-states-focus-background: var(--kbq-background-theme-fade);--kbq-tag-theme-fade-on-states-focus-text: var(--kbq-foreground-theme);--kbq-tag-theme-fade-on-states-focus-icon: var(--kbq-icon-theme);--kbq-tag-theme-fade-on-states-focus-close-button: var(--kbq-icon-theme);--kbq-tag-theme-fade-on-states-focus-outline: var(--kbq-states-line-focus-theme);--kbq-tag-theme-fade-on-states-selected-background: var(--kbq-background-theme);--kbq-tag-theme-fade-on-states-selected-text: var(--kbq-foreground-white);--kbq-tag-theme-fade-on-states-selected-icon: var(--kbq-icon-white);--kbq-tag-theme-fade-on-states-selected-close-button: var(--kbq-icon-white);--kbq-tag-theme-fade-on-states-disabled-background: var(--kbq-states-background-disabled);--kbq-tag-theme-fade-on-states-disabled-text: var(--kbq-states-foreground-disabled);--kbq-tag-theme-fade-on-states-disabled-icon: var(--kbq-states-icon-disabled);--kbq-tag-theme-fade-on-states-disabled-close-button: var(--kbq-states-icon-disabled);--kbq-tag-contrast-fade-on-default-background: var(--kbq-background-contrast-fade);--kbq-tag-contrast-fade-on-default-text: var(--kbq-foreground-contrast);--kbq-tag-contrast-fade-on-default-icon: var(--kbq-icon-contrast-fade);--kbq-tag-contrast-fade-on-default-close-button: var(--kbq-icon-contrast-fade);--kbq-tag-contrast-fade-on-states-hover-background: var(--kbq-states-background-contrast-fade-hover);--kbq-tag-contrast-fade-on-states-hover-text: var(--kbq-foreground-contrast);--kbq-tag-contrast-fade-on-states-hover-icon: var(--kbq-icon-contrast-fade);--kbq-tag-contrast-fade-on-states-hover-close-button: var(--kbq-icon-contrast-fade);--kbq-tag-contrast-fade-on-states-focus-background: var(--kbq-background-contrast-fade);--kbq-tag-contrast-fade-on-states-focus-text: var(--kbq-foreground-contrast);--kbq-tag-contrast-fade-on-states-focus-icon: var(--kbq-icon-contrast-fade);--kbq-tag-contrast-fade-on-states-focus-close-button: var(--kbq-icon-contrast-fade);--kbq-tag-contrast-fade-on-states-focus-outline: var(--kbq-states-line-focus-theme);--kbq-tag-contrast-fade-on-states-selected-background: var(--kbq-background-theme);--kbq-tag-contrast-fade-on-states-selected-text: var(--kbq-foreground-white);--kbq-tag-contrast-fade-on-states-selected-icon: var(--kbq-icon-white);--kbq-tag-contrast-fade-on-states-selected-close-button: var(--kbq-icon-white);--kbq-tag-contrast-fade-on-states-disabled-background: var(--kbq-states-background-disabled);--kbq-tag-contrast-fade-on-states-disabled-text: var(--kbq-states-foreground-disabled);--kbq-tag-contrast-fade-on-states-disabled-icon: var(--kbq-states-icon-disabled);--kbq-tag-contrast-fade-on-states-disabled-close-button: var(--kbq-states-icon-disabled);--kbq-tag-error-fade-on-default-background: var(--kbq-background-error-fade);--kbq-tag-error-fade-on-default-text: var(--kbq-foreground-error);--kbq-tag-error-fade-on-default-icon: var(--kbq-icon-error);--kbq-tag-error-fade-on-default-close-button: var(--kbq-icon-error);--kbq-tag-error-fade-on-states-hover-background: var(--kbq-states-background-error-fade-hover);--kbq-tag-error-fade-on-states-hover-text: var(--kbq-foreground-error);--kbq-tag-error-fade-on-states-hover-icon: var(--kbq-icon-error);--kbq-tag-error-fade-on-states-hover-close-button: var(--kbq-icon-error);--kbq-tag-error-fade-on-states-focus-background: var(--kbq-background-error-fade);--kbq-tag-error-fade-on-states-focus-text: var(--kbq-foreground-error);--kbq-tag-error-fade-on-states-focus-icon: var(--kbq-icon-error);--kbq-tag-error-fade-on-states-focus-close-button: var(--kbq-icon-error);--kbq-tag-error-fade-on-states-focus-outline: var(--kbq-states-line-focus-error);--kbq-tag-error-fade-on-states-selected-background: var(--kbq-background-error);--kbq-tag-error-fade-on-states-selected-text: var(--kbq-foreground-white);--kbq-tag-error-fade-on-states-selected-icon: var(--kbq-icon-white);--kbq-tag-error-fade-on-states-selected-close-button: var(--kbq-icon-white);--kbq-tag-error-fade-on-states-disabled-background: var(--kbq-states-background-disabled);--kbq-tag-error-fade-on-states-disabled-text: var(--kbq-states-foreground-disabled);--kbq-tag-error-fade-on-states-disabled-icon: var(--kbq-states-icon-disabled);--kbq-tag-error-fade-on-states-disabled-close-button: var(--kbq-states-icon-disabled);--kbq-tag-warning-fade-default-background: var(--kbq-background-warning-fade);--kbq-tag-warning-fade-default-text: var(--kbq-foreground-warning);--kbq-tag-warning-fade-default-icon: var(--kbq-icon-warning);--kbq-tag-warning-fade-default-close-button: var(--kbq-icon-warning);--kbq-tag-warning-fade-states-hover-background: var(--kbq-states-background-warning-fade-hover);--kbq-tag-warning-fade-states-hover-text: var(--kbq-foreground-warning);--kbq-tag-warning-fade-states-hover-icon: var(--kbq-icon-warning);--kbq-tag-warning-fade-states-hover-close-button: var(--kbq-icon-warning);--kbq-tag-warning-fade-states-focus-background: var(--kbq-background-warning-fade);--kbq-tag-warning-fade-states-focus-text: var(--kbq-foreground-warning);--kbq-tag-warning-fade-states-focus-icon: var(--kbq-icon-warning);--kbq-tag-warning-fade-states-focus-close-button: var(--kbq-icon-warning);--kbq-tag-warning-fade-states-focus-outline: var(--kbq-line-warning);--kbq-tag-warning-fade-states-selected-background: var(--kbq-background-warning);--kbq-tag-warning-fade-states-selected-text: var(--kbq-foreground-white);--kbq-tag-warning-fade-states-selected-icon: var(--kbq-icon-white);--kbq-tag-warning-fade-states-selected-close-button: var(--kbq-icon-white);--kbq-tag-warning-fade-states-disabled-background: var(--kbq-states-background-disabled);--kbq-tag-warning-fade-states-disabled-text: var(--kbq-states-foreground-disabled);--kbq-tag-warning-fade-states-disabled-icon: var(--kbq-states-icon-disabled);--kbq-tag-warning-fade-states-disabled-close-button: var(--kbq-states-icon-disabled)}\n"] }]
        }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1.ErrorStateMatcher }, { type: i2$1.Directionality, decorators: [{
                    type: Optional
                }] }, { type: i3.NgForm, decorators: [{
                    type: Optional
                }] }, { type: i3.FormGroupDirective, decorators: [{
                    type: Optional
                }] }, { type: i3.NgControl, decorators: [{
                    type: Optional
                }, {
                    type: Self
                }] }], propDecorators: { multiple: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], compareWith: [{
                type: Input
            }], value: [{
                type: Input
            }], required: [{
                type: Input
            }], placeholder: [{
                type: Input
            }], disabled: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], draggable: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], dropped: [{
                type: Output
            }], selectable: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], editable: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], removable: [{
                type: Input,
                args: [{ transform: booleanAttribute }]
            }], tabIndex: [{
                type: Input
            }], valueChange: [{
                type: Output
            }], errorStateMatcher: [{
                type: Input
            }], orientation: [{
                type: Input
            }], change: [{
                type: Output
            }], cleaner: [{
                type: ContentChild,
                args: ['kbqTagListCleaner', { static: true }]
            }], tags: [{
                type: ContentChildren,
                args: [KbqTag, {
                        // Need to use `descendants: true`,
                        // Ivy will no longer match indirect descendants if it's left as false.
                        descendants: true
                    }]
            }] } });

const KbqTagInputDefaultSeparators = {
    [ENTER$1]: { symbol: /\r?\n/, key: 'Enter' },
    [TAB$1]: { symbol: /\t/, key: 'Tab' },
    [SPACE$1]: { symbol: / /, key: ' ' },
    [COMMA]: { symbol: /,/, key: ',' },
    [SEMICOLON]: { symbol: /;/, key: ';' }
};
// Increasing integer for generating unique ids.
let nextUniqueId = 0;
/**
 * Directive that adds tag-specific behaviors to an input element inside `<kbq-form-field>`.
 * May be placed inside or outside of an `<kbq-tag-list>`.
 */
class KbqTagInput {
    /**
     * The list of key codes that will trigger a tagEnd event.
     *
     * Defaults to `[ENTER]`.
     */
    set separatorKeyCodes(value) {
        this._separatorKeyCodes = value || [];
    }
    get separators() {
        return this._separatorKeyCodes.reduce((acc, key) => {
            const separator = this.getSeparatorByKeyCode(key);
            return separator ? [...acc, separator] : acc;
        }, []);
    }
    /** Register input for tag list */
    set tagList(value) {
        if (value) {
            this._tagList = value;
            this._tagList.registerInput(this);
        }
    }
    /**
     * Whether or not the tagEnd event will be emitted when the input is blurred.
     */
    get addOnBlur() {
        return this._addOnBlur;
    }
    set addOnBlur(value) {
        this._addOnBlur = coerceBooleanProperty(value);
    }
    /**
     * Whether the tagEnd event will be emitted when the text pasted.
     */
    get addOnPaste() {
        return this._addOnPaste;
    }
    set addOnPaste(value) {
        this._addOnPaste = coerceBooleanProperty(value);
    }
    /** Whether the input is disabled. */
    get disabled() {
        return this._disabled || (this._tagList && this._tagList.disabled);
    }
    set disabled(value) {
        this._disabled = coerceBooleanProperty(value);
    }
    /** Whether the input is empty. */
    get empty() {
        return !this.inputElement.value;
    }
    constructor(elementRef, defaultOptions, trimDirective, ngControl, autocompleteTrigger) {
        this.elementRef = elementRef;
        this.defaultOptions = defaultOptions;
        this.trimDirective = trimDirective;
        this.ngControl = ngControl;
        this.autocompleteTrigger = autocompleteTrigger;
        /** Whether the control is focused. */
        this.focused = false;
        this._separatorKeyCodes = this.defaultOptions.separatorKeyCodes;
        /** Emitted when a tag is to be added. */
        this.tagEnd = new EventEmitter();
        /** A value indicating whether allow/prevent tags duplication  */
        this.distinct = false;
        /** The input's placeholder text. */
        this.placeholder = '';
        /** Unique id for the input. */
        this.id = `kbq-tag-list-input-${nextUniqueId++}`;
        this._addOnBlur = true;
        this._disabled = false;
        /**
         * @docs-private
         *
         * @deprecated Unused. Will be removed in next major release.
         */
        this.countOfSymbolsForUpdateWidth = 3;
        this.inputElement = this.elementRef.nativeElement;
        this._separators = this.defaultOptions.separators || KbqTagInputDefaultSeparators;
        this._addOnPaste = isBoolean(this.defaultOptions.addOnPaste) ? this.defaultOptions.addOnPaste : true;
    }
    ngOnChanges() {
        this._tagList.stateChanges.next();
    }
    /** @docs-private */
    onKeydown(event) {
        if (!this.inputElement.value) {
            this._tagList.keydown(event);
            event.stopPropagation();
            return;
        }
        if (this.isSeparatorKey(event) && this.inputElement.value) {
            this.emitTagEnd();
            event.preventDefault();
        }
    }
    /** Checks to see if the blur should emit the (tagEnd) event. */
    blur(event) {
        this.focused = false;
        // Blur the tag list if it is not focused
        if (!this._tagList.focused) {
            this.triggerValidation();
            this._tagList.blur();
        }
        if (this.addOnBlur && (this.autocompleteTrigger?.onInputBlur(event) || true)) {
            this.emitTagEnd();
        }
        this._tagList.stateChanges.next();
    }
    triggerValidation() {
        if (!this.hasControl()) {
            return;
        }
        this.ngControl.statusChanges.emit(this.ngControl.status);
    }
    /** Checks to see if the (tagEnd) event needs to be emitted. */
    emitTagEnd() {
        if (!this.hasControl() || (this.hasControl() && !this.ngControl.invalid)) {
            if (this.distinct && this.hasDuplicates)
                return;
            this.tagEnd.emit({ input: this.inputElement, value: this.trimValue(this.inputElement.value) });
        }
    }
    get hasDuplicates() {
        return this._tagList.tags
            .map(({ value }) => value)
            .some((tagValue) => tagValue === this.trimValue(this.inputElement.value));
    }
    onInput() {
        // Let tag list know whenever the value changes.
        this._tagList.stateChanges.next();
    }
    onPaste($event) {
        if (!$event.clipboardData) {
            return;
        }
        const data = $event.clipboardData.getData('text');
        if ((data && data.length === 0) || !this.addOnPaste) {
            return;
        }
        const separatorsInString = this.getSeparatorsForString(data);
        // prettier-ignore
        const dividedString = separatorsInString.length > 0 ?
            [...data.split(new RegExp(`${separatorsInString.join('|')}`))] :
            [data];
        const items = dividedString.map((item) => this.trimValue(item));
        if (items.length === 0) {
            items.push(data);
        }
        const tagValues = this._tagList.tags.map(({ value }) => value);
        items
            .filter((item) => !tagValues.includes(item))
            .forEach((item) => this.tagEnd.emit({ input: this.inputElement, value: item }));
        $event.preventDefault();
        $event.stopPropagation();
    }
    /**
     * @docs-private
     *
     * @deprecated Unused. Will be removed in next major release.
     */
    updateInputWidth() { }
    /** @docs-private */
    onFocus() {
        this.focused = true;
        this._tagList.unselectAll();
        this._tagList.stateChanges.next();
    }
    /** Focuses the input. */
    focus() {
        this.inputElement.focus();
    }
    getSeparatorsForString(value) {
        return this.separators
            .filter((separator) => value.search(separator.key) > -1)
            .map((separator) => separator.key);
    }
    trimValue(value) {
        return this.trimDirective ? this.trimDirective.trim(value) : value;
    }
    getSeparatorByKeyCode(keyCode) {
        const sep = this._separators[keyCode];
        if (sep) {
            return sep;
        }
        return null;
    }
    hasControl() {
        return !!this.ngControl;
    }
    /** Checks whether a keycode is one of the configured separators. */
    isSeparatorKey(event) {
        return this.separators.some((separator) => separator.key === event.key && !event.shiftKey);
    }
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTagInput, deps: [{ token: i0.ElementRef }, { token: KBQ_TAGS_DEFAULT_OPTIONS }, { token: i1$1.KbqTrim, optional: true, self: true }, { token: i3.NgControl, optional: true, self: true }, { token: i3$1.KbqAutocompleteTrigger, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Directive }); }
    /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: KbqTagInput, selector: "input[kbqTagInputFor]", inputs: { separatorKeyCodes: ["kbqTagInputSeparatorKeyCodes", "separatorKeyCodes"], distinct: "distinct", placeholder: "placeholder", id: "id", tagList: ["kbqTagInputFor", "tagList"], addOnBlur: ["kbqTagInputAddOnBlur", "addOnBlur"], addOnPaste: ["kbqTagInputAddOnPaste", "addOnPaste"], disabled: "disabled" }, outputs: { tagEnd: "kbqTagInputTokenEnd" }, host: { listeners: { "keydown": "onKeydown($event)", "blur": "blur($event)", "focus": "onFocus()", "input": "onInput()", "paste": "onPaste($event)" }, properties: { "id": "id", "attr.disabled": "disabled || null", "attr.placeholder": "placeholder || null" }, classAttribute: "kbq-tag-input" }, exportAs: ["kbqTagInput", "kbqTagInputFor"], usesOnChanges: true, hostDirectives: [{ directive: i1.KbqFieldSizingContent }], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTagInput, decorators: [{
            type: Directive,
            args: [{
                    selector: 'input[kbqTagInputFor]',
                    exportAs: 'kbqTagInput, kbqTagInputFor',
                    host: {
                        class: 'kbq-tag-input',
                        '[id]': 'id',
                        '[attr.disabled]': 'disabled || null',
                        '[attr.placeholder]': 'placeholder || null',
                        '(keydown)': 'onKeydown($event)',
                        '(blur)': 'blur($event)',
                        '(focus)': 'onFocus()',
                        '(input)': 'onInput()',
                        '(paste)': 'onPaste($event)'
                    },
                    hostDirectives: [KbqFieldSizingContent]
                }]
        }], ctorParameters: () => [{ type: i0.ElementRef }, { type: undefined, decorators: [{
                    type: Inject,
                    args: [KBQ_TAGS_DEFAULT_OPTIONS]
                }] }, { type: i1$1.KbqTrim, decorators: [{
                    type: Optional
                }, {
                    type: Self
                }] }, { type: i3.NgControl, decorators: [{
                    type: Optional
                }, {
                    type: Self
                }] }, { type: i3$1.KbqAutocompleteTrigger, decorators: [{
                    type: Optional
                }, {
                    type: Self
                }] }], propDecorators: { separatorKeyCodes: [{
                type: Input,
                args: ['kbqTagInputSeparatorKeyCodes']
            }], tagEnd: [{
                type: Output,
                args: ['kbqTagInputTokenEnd']
            }], distinct: [{
                type: Input
            }], placeholder: [{
                type: Input
            }], id: [{
                type: Input
            }], tagList: [{
                type: Input,
                args: ['kbqTagInputFor']
            }], addOnBlur: [{
                type: Input,
                args: ['kbqTagInputAddOnBlur']
            }], addOnPaste: [{
                type: Input,
                args: ['kbqTagInputAddOnPaste']
            }], disabled: [{
                type: Input
            }] } });

const COMPONENTS = [
    KbqTagEditSubmit,
    KbqTagEditInput
];
class KbqTagsModule {
    /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTagsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    /** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: KbqTagsModule, declarations: [KbqTagList,
            KbqTag,
            KbqTagInput,
            KbqTagTrailingIcon,
            KbqTagAvatar,
            KbqTagRemove], imports: [PlatformModule, KbqTagEditSubmit,
            KbqTagEditInput], exports: [KbqTagList,
            KbqTag,
            KbqTagInput,
            KbqTagTrailingIcon,
            KbqTagAvatar,
            KbqTagRemove, KbqTagEditSubmit,
            KbqTagEditInput] }); }
    /** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTagsModule, providers: [
            {
                provide: KBQ_TAGS_DEFAULT_OPTIONS,
                useValue: { separatorKeyCodes: [ENTER$1] }
            }
        ], imports: [PlatformModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KbqTagsModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [
                        PlatformModule,
                        ...COMPONENTS
                    ],
                    exports: [
                        KbqTagList,
                        KbqTag,
                        KbqTagInput,
                        KbqTagTrailingIcon,
                        KbqTagAvatar,
                        KbqTagRemove,
                        ...COMPONENTS
                    ],
                    declarations: [
                        KbqTagList,
                        KbqTag,
                        KbqTagInput,
                        KbqTagTrailingIcon,
                        KbqTagAvatar,
                        KbqTagRemove
                    ],
                    providers: [
                        {
                            provide: KBQ_TAGS_DEFAULT_OPTIONS,
                            useValue: { separatorKeyCodes: [ENTER$1] }
                        }
                    ]
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { KBQ_TAGS_DEFAULT_OPTIONS, KbqTag, KbqTagAvatar, KbqTagEditChange, KbqTagEditInput, KbqTagEditSubmit, KbqTagInput, KbqTagList, KbqTagListChange, KbqTagRemove, KbqTagSelectionChange, KbqTagTrailingIcon, KbqTagsModule };
//# sourceMappingURL=koobiq-components-tags.mjs.map
