UNPKG

@progress/kendo-angular-buttons

Version:
5,811 lines 221 kB
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import * as i0 from '@angular/core';
import { Injectable, isDevMode, EventEmitter, Component, Optional, Input, Output, HostBinding, HostListener, ContentChildren, Directive, InjectionToken, Inject, ElementRef, ViewContainerRef, ViewChild, ContentChild, forwardRef, NgModule } from '@angular/core';
import { Subject, Subscription, fromEvent, merge } from 'rxjs';
import * as i12 from '@progress/kendo-angular-common';
import { isDocumentAvailable, isFirefox, isSafari, isChanged, hasObservers, Keys, TemplateContextDirective, MultiTabStop, guid, isPresent as isPresent$1, EventsOutsideAngularDirective, anyChanged, ToggleButtonTabStopDirective, ResizeBatchService, KENDO_TOGGLEBUTTONTABSTOP } from '@progress/kendo-angular-common';
export { ToggleButtonTabStopDirective } from '@progress/kendo-angular-common';
import { caretAltDownIcon, xCircleIcon, moreVerticalIcon } from '@progress/kendo-svg-icons';
import * as i1 from '@progress/kendo-angular-l10n';
import { LocalizationService, L10N_PREFIX, ComponentMessages } from '@progress/kendo-angular-l10n';
import { validatePackage } from '@progress/kendo-licensing';
import { IconWrapperComponent, IconsService } from '@progress/kendo-angular-icons';
import { NgIf, NgClass, NgStyle, NgFor, NgTemplateOutlet } from '@angular/common';
import { filter, tap, take } from 'rxjs/operators';
import * as i3 from '@progress/kendo-angular-popup';
import { PopupService } from '@progress/kendo-angular-popup';
import * as i4 from '@angular/animations';
import { sequence, query, style, stagger, animate } from '@angular/animations';

/**
 * @hidden
 */
class KendoButtonService {
    buttonClicked = new Subject();
    buttonClicked$ = this.buttonClicked.asObservable();
    click(button) {
        this.buttonClicked.next(button);
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: KendoButtonService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: KendoButtonService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: KendoButtonService, decorators: [{
            type: Injectable
        }] });

/**
 * @hidden
 */
const packageMetadata = {
    name: '@progress/kendo-angular-buttons',
    productName: 'Kendo UI for Angular',
    productCode: 'KENDOUIANGULAR',
    productCodes: ['KENDOUIANGULAR'],
    publishDate: 1745303781,
    version: '18.5.2',
    licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
};

/**
 * @hidden
 */
const resolvedPromise = Promise.resolve(null);
/**
 * @hidden
 */
const isPresent = (value) => value !== null && value !== undefined;
/**
 * @hidden
 */
const tick = (f) => (resolvedPromise.then(f));
/**
 * @hidden
 */
function isDocumentNode(container) {
    return container.nodeType === 9;
}
/**
 * @hidden
 */
function closest(element, selector) {
    if (element.closest) {
        return element.closest(selector);
    }
    const matches = Element.prototype.matches ?
        (el, sel) => el.matches(sel)
        : (el, sel) => el.msMatchesSelector(sel);
    let node = element;
    while (node && !isDocumentNode(node)) {
        if (matches(node, selector)) {
            return node;
        }
        node = node.parentNode;
    }
}
/**
 * @hidden
 */
const replaceMessagePlaceholder = (message, name, value) => message.replace(new RegExp(`\{\\s*${name}\\s*\}`, 'g'), value);
/**
 * @hidden
 */
const SIZES = {
    small: 'sm',
    medium: 'md',
    large: 'lg'
};
const ROUNDNESS = {
    small: 'sm',
    medium: 'md',
    large: 'lg',
    full: 'full'
};
/**
 * @hidden
 *
 * Returns the styling classes to be added and removed
 */
const getStylingClasses = (componentType, stylingOption, previousValue, newValue) => {
    switch (stylingOption) {
        case 'size':
            return {
                toRemove: `k-${componentType}-${SIZES[previousValue]}`,
                toAdd: newValue !== 'none' ? `k-${componentType}-${SIZES[newValue]}` : ''
            };
        case 'rounded':
            return {
                toRemove: `k-rounded-${ROUNDNESS[previousValue]}`,
                toAdd: newValue !== 'none' ? `k-rounded-${ROUNDNESS[newValue]}` : ''
            };
        case 'fillMode':
            return {
                toRemove: `k-${componentType}-${previousValue}`,
                toAdd: newValue !== 'none' ? `k-${componentType}-${newValue}` : ''
            };
        default:
            break;
    }
};
/**
 * @hidden
 *
 * Returns the themeColor classes to be added and removed
 */
const getThemeColorClasses = (componentType, prevFillMode, fillMode, previousValue, newValue) => {
    return {
        toRemove: `k-${componentType}-${prevFillMode}-${previousValue}`,
        toAdd: newValue !== 'none' ? `k-${componentType}-${fillMode}-${newValue}` : ''
    };
};
/**
 * @hidden
 *
 * Checks for an empty object - {}
 */
const isObjectEmpty = (obj) => obj && Object.keys(obj).length === 0 && obj.constructor === Object;

const DEFAULT_ROUNDED$3 = 'medium';
const DEFAULT_SIZE$2 = 'medium';
const DEFAULT_THEME_COLOR$2 = 'base';
const DEFAULT_FILL_MODE$3 = 'solid';
/**
 * Represents the Kendo UI Button component for Angular.
 *
 * As of package v17, the `span[kendoButton]` and `kendo-button` selectors are removed.
 * Please use the `button[kendoButton]` selector only.
 */
class ButtonComponent {
    renderer;
    service;
    ngZone;
    /**
     * @hidden
     * @default false
     * required for DropDownButton arrow icon.
     */
    arrowIcon = false;
    /**
     * Provides visual styling that indicates if the Button is active.
     *
     * @default false
     */
    toggleable = false;
    /**
     * Backwards-compatible alias
     *
     * @hidden
     */
    get togglable() {
        return this.toggleable;
    }
    /**
     * @hidden
     */
    set togglable(value) {
        this.toggleable = value;
    }
    /**
     * Sets the selected state of the Button.
     *
     * @default false
     */
    get selected() {
        return this._selected || false;
    }
    set selected(value) {
        this._selected = value;
    }
    /**
     * @hidden
     */
    set tabIndex(index) {
        this.element.tabIndex = index;
    }
    get tabIndex() {
        return this.element.tabIndex;
    }
    /**
     * Defines a URL which is used for an `img` element inside the Button.
     * The URL can be relative or absolute. If relative, it is evaluated with relation to the web page URL.
     */
    imageUrl;
    /**
     * Defines a CSS class—or multiple classes separated by spaces—
     * which are applied to a `span` element inside the Button. Allows the usage of custom icons.
     */
    set iconClass(value) {
        if (isDevMode() && value && (this.icon || this.svgIcon)) {
            throw new Error('Setting both icon/svgIcon and iconClass options at the same time is not supported.');
        }
        this._iconClass = value;
    }
    get iconClass() {
        return this._iconClass;
    }
    /**
     * Defines the name for an existing font icon in the Kendo UI theme.
     */
    set icon(name) {
        if (isDevMode() && name && this.iconClass) {
            throw new Error('Setting both icon/svgIcon and iconClass options at the same time is not supported.');
        }
        this._icon = name;
    }
    get icon() {
        return this._icon;
    }
    /**
     * If set to `true`, it disables the Button.
     *
     * @default false
     */
    set disabled(disabled) {
        //Required, because in FF focused buttons are not blurred on disabled
        if (disabled && isDocumentAvailable() && isFirefox(navigator.userAgent)) {
            this.blur();
        }
        this.isDisabled = disabled;
        this.renderer.setProperty(this.element, 'disabled', disabled);
    }
    get disabled() {
        return this.isDisabled;
    }
    /**
     * The size property specifies the padding of the Button
     * ([see example]({% slug appearance_button %}#toc-size)).
     *
     * @default 'medium'
     */
    set size(size) {
        const newSize = size ? size : DEFAULT_SIZE$2;
        this.handleClasses(newSize, 'size');
        this._size = newSize;
    }
    get size() {
        return this._size;
    }
    /**
     * The rounded property specifies the border radius of the Button
     * ([see example](slug:appearance_button#toc-roundness)).
     *
     * @default 'medium'
     */
    set rounded(rounded) {
        const newRounded = rounded ? rounded : DEFAULT_ROUNDED$3;
        this.handleClasses(newRounded, 'rounded');
        this._rounded = newRounded;
    }
    get rounded() {
        return this._rounded;
    }
    /**
     * The fillMode property specifies the background and border styles of the Button
     * ([see example](slug:appearance_button#toc-fill-mode)).
     *
     * @default 'solid'
     */
    set fillMode(fillMode) {
        const newFillMode = fillMode ? fillMode : DEFAULT_FILL_MODE$3;
        this.handleClasses(newFillMode, 'fillMode');
        this._fillMode = newFillMode;
    }
    get fillMode() {
        return this._fillMode;
    }
    /**
     * The Button allows you to specify predefined theme colors.
     * The theme color will be applied as a background and border color while also amending the text color accordingly
     * ([see example](slug:appearance_button#toc-theme-colors)).
     *
     * @default 'base'
     */
    set themeColor(themeColor) {
        const newThemeColor = themeColor ? themeColor : DEFAULT_THEME_COLOR$2;
        this.handleThemeColor(newThemeColor);
        this._themeColor = newThemeColor;
    }
    get themeColor() {
        return this._themeColor;
    }
    /**
     * Defines an SVGIcon to be rendered within the button.
     */
    set svgIcon(icon) {
        if (isDevMode() && icon && this.iconClass) {
            throw new Error('Setting both icon/svgIcon and iconClass options at the same time is not supported.');
        }
        this._svgIcon = icon;
    }
    get svgIcon() {
        return this._svgIcon;
    }
    /**
     * Fires each time the selected state of a toggleable button is changed.
     *
     * The event argument is the new selected state (boolean).
     */
    selectedChange = new EventEmitter();
    /**
     * Fires each time the user clicks the button.
     */
    click = new EventEmitter();
    element;
    isDisabled = false;
    caretAltDownIcon = caretAltDownIcon;
    _size = DEFAULT_SIZE$2;
    _rounded = DEFAULT_ROUNDED$3;
    _fillMode = DEFAULT_FILL_MODE$3;
    _themeColor = DEFAULT_THEME_COLOR$2;
    _focused = false;
    direction;
    _selected;
    subs = new Subscription();
    _iconClass;
    _icon;
    _svgIcon;
    set isFocused(isFocused) {
        this.toggleClass('k-focus', isFocused);
        this._focused = isFocused;
    }
    get isFocused() {
        return this._focused;
    }
    get classButton() {
        return true;
    }
    get isToggleable() {
        return this.toggleable;
    }
    get iconButtonClass() {
        const hasIcon = this.icon || this.iconClass || this.imageUrl || this.svgIcon;
        return hasIcon && !this.hasText;
    }
    get classDisabled() {
        return this.isDisabled;
    }
    get classActive() {
        return this.selected;
    }
    get getDirection() {
        return this.direction;
    }
    /**
     * @hidden
     */
    onFocus() {
        this.isFocused = true;
    }
    /**
     * @hidden
     */
    onBlur() {
        this.isFocused = false;
    }
    /**
     * @hidden
     */
    set primary(value) {
        this.themeColor = value ? 'primary' : 'base';
    }
    /**
     * @hidden
     */
    set look(value) {
        switch (value) {
            case 'default':
                this.fillMode = 'solid';
                break;
            default:
                this.fillMode = value;
                break;
        }
    }
    /**
     * Alias for ElementRef.nativeElement to workaround
     * ViewChild() selectors that used to return the host element before v11.
     *
     * @hidden
     */
    get nativeElement() {
        return this.element;
    }
    constructor(element, renderer, service, localization, ngZone) {
        this.renderer = renderer;
        this.service = service;
        this.ngZone = ngZone;
        validatePackage(packageMetadata);
        this.direction = localization.rtl ? 'rtl' : 'ltr';
        this.subs.add(localization.changes.subscribe(({ rtl }) => (this.direction = rtl ? 'rtl' : 'ltr')));
        this.element = element.nativeElement;
    }
    ngOnInit() {
        if (!this.element.hasAttribute('role') && this.togglable) {
            this.toggleAriaPressed(this.toggleable);
        }
        this.ngZone.runOutsideAngular(() => {
            this.subs.add(this.renderer.listen(this.element, 'click', this._onButtonClick.bind(this)));
            this.subs.add(this.renderer.listen(this.element, 'mousedown', (event) => {
                const isBrowserSafari = isDocumentAvailable() && isSafari(navigator.userAgent);
                if (!this.isDisabled && isBrowserSafari) {
                    event.preventDefault();
                    this.element.focus();
                }
            }));
        });
    }
    ngOnChanges(change) {
        if (isChanged('togglable', change) || isChanged('toggleable', change)) {
            this.toggleAriaPressed(this.toggleable);
        }
    }
    ngAfterViewInit() {
        const stylingOptions = ['size', 'rounded', 'fillMode'];
        stylingOptions.forEach(input => {
            this.handleClasses(this[input], input);
        });
    }
    ngOnDestroy() {
        this.subs.unsubscribe();
    }
    /**
     * @hidden
     */
    get hasText() {
        return isDocumentAvailable() && this.element.textContent.trim().length > 0;
    }
    /**
     * Focuses the Button component.
     */
    focus() {
        if (isDocumentAvailable()) {
            this.element.focus();
            this.isFocused = true;
        }
    }
    /**
     * Blurs the Button component.
     */
    blur() {
        if (isDocumentAvailable()) {
            this.element.blur();
            this.isFocused = false;
        }
    }
    /**
     * @hidden
     */
    setAttribute(attribute, value) {
        this.renderer.setAttribute(this.element, attribute, value);
    }
    /**
     * @hidden
     */
    removeAttribute(attribute) {
        this.renderer.removeAttribute(this.element, attribute);
    }
    /**
     * @hidden
     *
     * Internal setter that triggers selectedChange
     */
    setSelected(value) {
        const changed = this.selected !== value;
        this.selected = value;
        this.setAttribute('aria-pressed', this.selected.toString());
        this.toggleClass('k-selected', this.selected);
        if (changed && hasObservers(this.selectedChange)) {
            this.ngZone.run(() => {
                this.selectedChange.emit(value);
            });
        }
    }
    toggleAriaPressed(shouldSet) {
        if (!isDocumentAvailable()) {
            return;
        }
        if (shouldSet) {
            this.setAttribute('aria-pressed', this.selected.toString());
        }
        else {
            this.removeAttribute('aria-pressed');
        }
    }
    toggleClass(className, add) {
        if (add) {
            this.renderer.addClass(this.element, className);
        }
        else {
            this.renderer.removeClass(this.element, className);
        }
    }
    _onButtonClick() {
        if (!this.disabled && this.service) {
            this.ngZone.run(() => {
                this.service.click(this);
            });
        }
        if (this.togglable && !this.service) {
            this.setSelected(!this.selected);
        }
    }
    handleClasses(value, input) {
        const elem = this.element;
        const classes = getStylingClasses('button', input, this[input], value);
        if (input === 'fillMode') {
            this.handleThemeColor(this.themeColor, this[input], value);
        }
        if (classes.toRemove) {
            this.renderer.removeClass(elem, classes.toRemove);
        }
        if (classes.toAdd) {
            this.renderer.addClass(elem, classes.toAdd);
        }
    }
    handleThemeColor(value, prevFillMode, fillMode) {
        const elem = this.element;
        const removeFillMode = prevFillMode ? prevFillMode : this.fillMode;
        const addFillMode = fillMode ? fillMode : this.fillMode;
        const themeColorClass = getThemeColorClasses('button', removeFillMode, addFillMode, this.themeColor, value);
        this.renderer.removeClass(elem, themeColorClass.toRemove);
        if (addFillMode !== 'none' && fillMode !== 'none') {
            if (themeColorClass.toAdd) {
                this.renderer.addClass(elem, themeColorClass.toAdd);
            }
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ButtonComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: KendoButtonService, optional: true }, { token: i1.LocalizationService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ButtonComponent, isStandalone: true, selector: "button[kendoButton]", inputs: { arrowIcon: "arrowIcon", toggleable: "toggleable", togglable: "togglable", selected: "selected", tabIndex: "tabIndex", imageUrl: "imageUrl", iconClass: "iconClass", icon: "icon", disabled: "disabled", size: "size", rounded: "rounded", fillMode: "fillMode", themeColor: "themeColor", svgIcon: "svgIcon", primary: "primary", look: "look" }, outputs: { selectedChange: "selectedChange", click: "click" }, host: { listeners: { "focus": "onFocus()", "blur": "onBlur()" }, properties: { "class.k-button": "this.classButton", "class.k-toggle-button": "this.isToggleable", "class.k-icon-button": "this.iconButtonClass", "class.k-disabled": "this.classDisabled", "class.k-selected": "this.classActive", "attr.dir": "this.getDirection" } }, providers: [
            LocalizationService,
            {
                provide: L10N_PREFIX,
                useValue: 'kendo.button'
            }
        ], exportAs: ["kendoButton"], usesOnChanges: true, ngImport: i0, template: `
        <kendo-icon-wrapper
            *ngIf="icon || svgIcon"
            innerCssClass="k-button-icon"
            [name]="icon"
            [svgIcon]="svgIcon"></kendo-icon-wrapper>
        <span *ngIf="imageUrl" class="k-button-icon k-icon">
            <img [src]="imageUrl" class="k-image" role="presentation" />
        </span>
        <span *ngIf="iconClass" class="k-button-icon" [ngClass]="iconClass"></span>
        <span class="k-button-text"><ng-content></ng-content></span>
        <span *ngIf="$any(arrowIcon).iconClass" class="k-button-icon" [ngClass]="$any(arrowIcon).iconClass"></span>
        <span *ngIf="arrowIcon && !$any(arrowIcon).iconClass" class="k-button-arrow">
            <kendo-icon-wrapper
                [name]="$any(arrowIcon).icon || 'caret-alt-down'"
                [svgIcon]="$any(arrowIcon).svgIcon || caretAltDownIcon"></kendo-icon-wrapper>
        </span>
        
    `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ButtonComponent, decorators: [{
            type: Component,
            args: [{
                    exportAs: 'kendoButton',
                    providers: [
                        LocalizationService,
                        {
                            provide: L10N_PREFIX,
                            useValue: 'kendo.button'
                        }
                    ],
                    selector: 'button[kendoButton]',
                    template: `
        <kendo-icon-wrapper
            *ngIf="icon || svgIcon"
            innerCssClass="k-button-icon"
            [name]="icon"
            [svgIcon]="svgIcon"></kendo-icon-wrapper>
        <span *ngIf="imageUrl" class="k-button-icon k-icon">
            <img [src]="imageUrl" class="k-image" role="presentation" />
        </span>
        <span *ngIf="iconClass" class="k-button-icon" [ngClass]="iconClass"></span>
        <span class="k-button-text"><ng-content></ng-content></span>
        <span *ngIf="$any(arrowIcon).iconClass" class="k-button-icon" [ngClass]="$any(arrowIcon).iconClass"></span>
        <span *ngIf="arrowIcon && !$any(arrowIcon).iconClass" class="k-button-arrow">
            <kendo-icon-wrapper
                [name]="$any(arrowIcon).icon || 'caret-alt-down'"
                [svgIcon]="$any(arrowIcon).svgIcon || caretAltDownIcon"></kendo-icon-wrapper>
        </span>
        
    `,
                    standalone: true,
                    imports: [NgIf, IconWrapperComponent, NgClass]
                }]
        }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: KendoButtonService, decorators: [{
                    type: Optional
                }] }, { type: i1.LocalizationService }, { type: i0.NgZone }]; }, propDecorators: { arrowIcon: [{
                type: Input
            }], toggleable: [{
                type: Input
            }], togglable: [{
                type: Input
            }], selected: [{
                type: Input
            }], tabIndex: [{
                type: Input
            }], imageUrl: [{
                type: Input
            }], iconClass: [{
                type: Input
            }], icon: [{
                type: Input
            }], disabled: [{
                type: Input
            }], size: [{
                type: Input
            }], rounded: [{
                type: Input
            }], fillMode: [{
                type: Input
            }], themeColor: [{
                type: Input
            }], svgIcon: [{
                type: Input
            }], selectedChange: [{
                type: Output
            }], click: [{
                type: Output
            }], classButton: [{
                type: HostBinding,
                args: ['class.k-button']
            }], isToggleable: [{
                type: HostBinding,
                args: ['class.k-toggle-button']
            }], iconButtonClass: [{
                type: HostBinding,
                args: ['class.k-icon-button']
            }], classDisabled: [{
                type: HostBinding,
                args: ['class.k-disabled']
            }], classActive: [{
                type: HostBinding,
                args: ['class.k-selected']
            }], getDirection: [{
                type: HostBinding,
                args: ['attr.dir']
            }], onFocus: [{
                type: HostListener,
                args: ['focus']
            }], onBlur: [{
                type: HostListener,
                args: ['blur']
            }], primary: [{
                type: Input
            }], look: [{
                type: Input
            }] } });

/**
 * @hidden
 */
class PreventableEvent {
    prevented = false;
    /**
     * Prevents the default action for a specified event.
     * In this way, the source component suppresses the built-in behavior that follows the event.
     */
    preventDefault() {
        this.prevented = true;
    }
    /**
     * If the event is prevented by any of its subscribers, returns `true`.
     *
     * @returns `true` if the default action was prevented. Otherwise, returns `false`.
     */
    isDefaultPrevented() {
        return this.prevented;
    }
}

/**
 * @hidden
 */
const tabindex = 'tabindex';
/**
 * Represents the Kendo UI ButtonGroup component for Angular.
 */
class ButtonGroupComponent {
    service;
    renderer;
    element;
    /**
     * By default, the ButtonGroup is enabled.
     * To disable the whole group of buttons, set its `disabled` attribute to `true`.
     *
     * To disable a specific button, set its own `disabled` attribute to `true`
     * and leave the `disabled` attribute of the ButtonGroup undefined.
     * If you define the `disabled` attribute of the ButtonGroup, it will take
     * precedence over the `disabled` attributes of the underlying buttons and they will be ignored.
     *
     * For more information on how to configure the Button, refer to
     * its [API documentation]({% slug api_buttons_buttoncomponent %}).
     */
    disabled;
    /**
     * The selection mode of the ButtonGroup.
     * @default 'multiple'
     */
    selection = 'multiple';
    /**
     * Sets the width of the ButtonGroup.
     * If the width of the ButtonGroup is set:
     * - The buttons resize automatically to fill the full width of the group wrapper.
     * - The buttons acquire the same width.
     */
    width;
    /**
     * Specifies the [`tabIndex`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) of the component.
     */
    set tabIndex(value) {
        this._tabIndex = value;
        this.currentTabIndex = value;
    }
    get tabIndex() {
        return this._tabIndex;
    }
    /**
     * When this option is set to `true` (default), the component is a single tab-stop,
     * and focus is moved through the inner buttons via the arrow keys.
     *
     * When the option is set to `false`, the inner buttons are part of the natural tab sequence of the page.
     *
     * @default true
     */
    navigable = true;
    /**
     * Fires every time keyboard navigation occurs.
     */
    navigate = new EventEmitter();
    buttons;
    _tabIndex = 0;
    currentTabIndex = 0;
    lastFocusedIndex = -1;
    direction;
    subs = new Subscription();
    wrapperClasses = true;
    get disabledClass() {
        return this.disabled;
    }
    get stretchedClass() {
        return !!this.width;
    }
    role = 'group';
    get dir() {
        return this.direction;
    }
    get ariaDisabled() {
        return this.disabled;
    }
    get wrapperWidth() {
        return this.width;
    }
    get wrapperTabIndex() {
        return this.disabled ? undefined : this.navigable ? this.currentTabIndex : undefined;
    }
    constructor(service, localization, renderer, element) {
        this.service = service;
        this.renderer = renderer;
        this.element = element;
        validatePackage(packageMetadata);
        this.subs.add(localization.changes.subscribe(({ rtl }) => this.direction = rtl ? 'rtl' : 'ltr'));
    }
    ngOnInit() {
        this.subs.add(this.service.buttonClicked$.subscribe((button) => {
            let newSelectionValue;
            if (this.isSelectionSingle()) {
                newSelectionValue = true;
                this.deactivate(this.buttons.filter(current => current !== button));
            }
            else {
                if (this.navigable) {
                    this.defocus(this.buttons.toArray());
                }
                newSelectionValue = !button.selected;
            }
            if (button.togglable) {
                button.setSelected(newSelectionValue);
            }
            if (this.navigable) {
                this.currentTabIndex = -1;
                this.renderer.setAttribute(button, tabindex, '0');
            }
        }));
        this.handleSubs('focus', () => this.navigable, this.focusHandler);
        this.handleSubs('keydown', () => this.navigable && !this.disabled, (event) => this.navigateFocus(event));
        this.handleSubs('focusout', (event) => this.navigable && event.relatedTarget && event.relatedTarget.parentNode !== this.element.nativeElement, () => {
            this.lastFocusedIndex = this.buttons.toArray().findIndex(button => button.tabIndex !== -1);
            this.defocus(this.buttons.toArray());
            this.currentTabIndex = this.tabIndex;
        });
        this.subs.add(fromEvent(this.element.nativeElement, 'focusout')
            .pipe(filter((event) => this.navigable && event.relatedTarget && event.relatedTarget.parentNode !== this.element.nativeElement))
            .subscribe(() => {
            this.defocus(this.buttons.toArray());
            this.currentTabIndex = this.tabIndex;
        }));
    }
    ngOnChanges(changes) {
        if (isChanged('disabled', changes)) {
            this.buttons.forEach((button) => {
                if (isPresent(this.disabled)) {
                    button.disabled = this.disabled;
                }
            });
        }
        if (isChanged('navigable', changes)) {
            if (changes['navigable'].currentValue) {
                this.defocus(this.buttons.toArray());
                this.currentTabIndex = 0;
            }
            else {
                this.currentTabIndex = -1;
                this.buttons.forEach((button) => this.renderer.setAttribute(button, tabindex, '0'));
            }
        }
    }
    ngAfterContentInit() {
        if (!this.navigable) {
            return;
        }
        this.defocus(this.buttons.toArray());
    }
    ngAfterViewChecked() {
        if (this.buttons.length) {
            this.renderer.addClass(this.buttons.first.element, 'k-group-start');
            this.renderer.addClass(this.buttons.last.element, 'k-group-end');
        }
    }
    ngOnDestroy() {
        this.subs.unsubscribe();
    }
    ngAfterContentChecked() {
        this.verifySettings();
    }
    navigateFocus(event) {
        const navigationButtons = this.buttons.toArray().filter(button => !button.disabled);
        const focusedIndex = navigationButtons.findIndex(current => current.element.tabIndex !== -1);
        const firstIndex = 0;
        const lastIndex = navigationButtons.length - 1;
        const eventArgs = new PreventableEvent();
        if (event.keyCode === Keys.ArrowRight && focusedIndex < lastIndex) {
            this.navigate.emit(eventArgs);
            if (!eventArgs.isDefaultPrevented()) {
                this.defocus(navigationButtons);
                this.focus(navigationButtons.filter((_current, index) => {
                    return index === focusedIndex + 1;
                }));
            }
        }
        if (event.keyCode === Keys.ArrowLeft && focusedIndex > firstIndex) {
            this.navigate.emit(eventArgs);
            if (!eventArgs.isDefaultPrevented()) {
                this.defocus(navigationButtons);
                this.focus(navigationButtons.filter((_current, index) => {
                    return index === focusedIndex - 1;
                }));
            }
        }
    }
    deactivate(buttons) {
        buttons.forEach((button) => {
            button.setSelected(false);
            if (this.navigable) {
                this.renderer.setAttribute(button, tabindex, '-1');
            }
        });
    }
    activate(buttons) {
        buttons.forEach((button) => {
            button.setSelected(true);
            if (this.navigable) {
                this.renderer.setAttribute(button, tabindex, '0');
            }
            button.focus();
        });
    }
    defocus(buttons) {
        buttons.forEach((button) => {
            this.renderer.setAttribute(button, tabindex, '-1');
        });
    }
    focus(buttons) {
        buttons.forEach((button) => {
            this.renderer.setAttribute(button, tabindex, '0');
            button.focus();
        });
    }
    verifySettings() {
        if (isDevMode()) {
            if (this.isSelectionSingle() && this.buttons.filter(button => button.selected).length > 1) {
                throw new Error('Having multiple selected buttons with single selection mode is not supported');
            }
        }
    }
    isSelectionSingle() {
        return this.selection === 'single';
    }
    handleSubs(eventName, predicate, handler) {
        this.subs.add(fromEvent(this.element.nativeElement, eventName)
            .pipe(filter(predicate))
            .subscribe(handler));
    }
    focusHandler = () => {
        this.currentTabIndex = -1;
        this.defocus(this.buttons.toArray());
        const firstFocusableIndex = this.buttons.toArray().findIndex(current => !current.disabled);
        const index = this.lastFocusedIndex === -1 ? firstFocusableIndex : this.lastFocusedIndex;
        this.focus(this.buttons.filter((_current, i) => {
            return i === index;
        }));
    };
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ButtonGroupComponent, deps: [{ token: KendoButtonService }, { token: i1.LocalizationService }, { token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ButtonGroupComponent, isStandalone: true, selector: "kendo-buttongroup", inputs: { disabled: "disabled", selection: "selection", width: "width", tabIndex: "tabIndex", navigable: "navigable" }, outputs: { navigate: "navigate" }, host: { properties: { "class.k-button-group": "this.wrapperClasses", "class.k-disabled": "this.disabledClass", "class.k-button-group-stretched": "this.stretchedClass", "attr.role": "this.role", "attr.dir": "this.dir", "attr.aria-disabled": "this.ariaDisabled", "style.width": "this.wrapperWidth", "attr.tabindex": "this.wrapperTabIndex" } }, providers: [
            KendoButtonService,
            LocalizationService,
            {
                provide: L10N_PREFIX,
                useValue: 'kendo.buttongroup'
            }
        ], queries: [{ propertyName: "buttons", predicate: ButtonComponent }], exportAs: ["kendoButtonGroup"], usesOnChanges: true, ngImport: i0, template: `
        <ng-content select="[kendoButton]"></ng-content>
    `, isInline: true });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ButtonGroupComponent, decorators: [{
            type: Component,
            args: [{
                    exportAs: 'kendoButtonGroup',
                    providers: [
                        KendoButtonService,
                        LocalizationService,
                        {
                            provide: L10N_PREFIX,
                            useValue: 'kendo.buttongroup'
                        }
                    ],
                    selector: 'kendo-buttongroup',
                    template: `
        <ng-content select="[kendoButton]"></ng-content>
    `,
                    standalone: true
                }]
        }], ctorParameters: function () { return [{ type: KendoButtonService }, { type: i1.LocalizationService }, { type: i0.Renderer2 }, { type: i0.ElementRef }]; }, propDecorators: { disabled: [{
                type: Input,
                args: ['disabled']
            }], selection: [{
                type: Input,
                args: ['selection']
            }], width: [{
                type: Input,
                args: ['width']
            }], tabIndex: [{
                type: Input
            }], navigable: [{
                type: Input
            }], navigate: [{
                type: Output
            }], buttons: [{
                type: ContentChildren,
                args: [ButtonComponent]
            }], wrapperClasses: [{
                type: HostBinding,
                args: ['class.k-button-group']
            }], disabledClass: [{
                type: HostBinding,
                args: ['class.k-disabled']
            }], stretchedClass: [{
                type: HostBinding,
                args: ['class.k-button-group-stretched']
            }], role: [{
                type: HostBinding,
                args: ['attr.role']
            }], dir: [{
                type: HostBinding,
                args: ['attr.dir']
            }], ariaDisabled: [{
                type: HostBinding,
                args: ['attr.aria-disabled']
            }], wrapperWidth: [{
                type: HostBinding,
                args: ['style.width']
            }], wrapperTabIndex: [{
                type: HostBinding,
                args: ['attr.tabindex']
            }] } });

const DEFAULT_SIZE$1 = 'medium';
const DEFAULT_ROUNDED$2 = 'medium';
const DEFAULT_THEME_COLOR$1 = 'base';
const DEFAULT_FILL_MODE$2 = 'solid';
/**
 * Displays a Chip that represents an input, attribute or an action.
 */
class ChipComponent {
    element;
    renderer;
    ngZone;
    localizationService;
    /**
     * Sets the label text of the Chip.
     */
    label;
    /**
     * Defines the name for an existing icon in a Kendo UI theme.
     * The icon is rendered inside the Chip by a `span.k-icon` element.
     */
    icon;
    /**
     * Defines an [`SVGIcon`](slug:api_icons_svgicon) icon to be rendered inside the Chip using
     * a [`KendoSVGIcon`](slug:api_icons_svgiconcomponent) component.
     */
    svgIcon;
    /**
     * Defines a CSS class — or multiple classes separated by spaces —
     * which are applied to a span element.
     * Allows the usage of custom icons.
     */
    iconClass;
    /**
     * Use these settings to render an avatar within the Chip.
     */
    avatarSettings;
    /**
     * Specifies the selected state of the Chip.
     * @default false
     */
    selected = false;
    /**
     * Specifies if the Chip will be removable or not.
     * If the property is set to `true`, the Chip renders a remove icon.
     * @default false
     */
    removable = false;
    /**
     * Specifies a custom remove font icon class that will be rendered when the Chip is removable.
     * [see example]({% slug icons %})
     */
    removeIcon;
    /**
     * Specifies a custom remove SVG icon that will be rendered when the Chip is removable.
     */
    removeSvgIcon;
    /**
     * @hidden
     *
     * Determines whether the Chip has a menu.
     */
    hasMenu = false;
    /**
     * @hidden
     *
     * Specifies a custom menu font icon class that will be rendered when the Chip has menu.
     */
    menuIcon;
    /**
     * @hidden
     *
     * Specifies a custom menu SVG icon that will be rendered when the Chip has menu.
     */
    menuSvgIcon;
    /**
     * If set to `true`, the Chip will be disabled.
     * @default false
     */
    disabled = false;
    /**
     * The size property specifies the padding of the Chip
     * ([see example]({% slug appearance_chip %}#toc-size)).
     *
     * The possible values are:
     * * `small`
     * * `medium` (default)
     * * `large`
     * * `none`
     */
    set size(size) {
        const newSize = size ? size : DEFAULT_SIZE$1;
        !this.sizeIsSet && (this.sizeIsSet = true);
        this.handleClasses(newSize, 'size');
        this._size = newSize;
    }
    get size() {
        return this._size;
    }
    /**
     * The rounded property specifies the border radius of the Chip
     * ([see example](slug:appearance_chip#toc-roundness)).
     *
     * The possible values are:
     * * `small`
     * * `medium` (default)
     * * `large`
     * * `full`
     * * `none`
     */
    set rounded(rounded) {
        const newRounded = rounded ? rounded : DEFAULT_ROUNDED$2;
        this.handleClasses(newRounded, 'rounded');
        this._rounded = newRounded;
    }
    get rounded() {
        return this._rounded;
    }
    /**
     * The fillMode property specifies the background and border styles of the Chip
     * ([see example](slug:appearance_chip#toc-fill-mode)).
     *
     * The possible values are:
     * * `solid` (default)
     * * `outline`
     * * `none`
     */
    set fillMode(fillMode) {
        const newFillMode = fillMode ? fillMode : DEFAULT_FILL_MODE$2;
        this.handleClasses(newFillMode, 'fillMode');
        this._fillMode = newFillMode;
    }
    get fillMode() {
        return this._fillMode;
    }
    /**
     * The Chip allows you to specify predefined theme colors.
     * The theme color will be applied as a background and border color while also amending the text color accordingly
     * ([see example](slug:appearance_chip#toc-theme-colors)).
     *
     * The possible values are:
     * * `base` (default)
     * * `info`
     * * `success`
     * * `warning`
     * * `error`
     * * `none`
     */
    set themeColor(themeColor) {
        const newThemeColor = themeColor ? themeColor : DEFAULT_THEME_COLOR$1;
        this.handleThemeColor(newThemeColor);
        this._themeColor = newThemeColor;
    }
    get themeColor() {
        return this._themeColor;
    }
    /**
     * Fires each time the user clicks the remove icon of the Chip.
     */
    remove = new EventEmitter();
    /**
     * @hidden
     *
     * Fires each time the user clicks the menu icon of the Chip.
     */
    menuToggle = new EventEmitter();
    /**
     * Fires each time the user clicks the content of the Chip.
     */
    contentClick = new EventEmitter();
    tabIndex = 0;
    hostClass = true;
    get hasIconClass() {
        return Boolean(this.icon || this.iconClass || (this.avatarSettings && !isObjectEmpty(this.avatarSettings)));
    }
    get disabledClass() {
        return this.disabled;
    }
    get selectedClass() {
        return this.selected;
    }
    get focusedClass() {
        return this.focused;
    }
    /**
     * @hidden
     */
    direction;
    /**
     * @hidden
     */
    defaultRemoveIcon = xCircleIcon;
    /**
     * @hidden
     */
    defaultMenuIcon = moreVerticalIcon;
    /**
     * @hidden
     */
    sizeIsSet = false;
    _size = 'medium';
    _rounded = 'medium';
    _fillMode = 'solid';
    _themeColor = 'base';
    focused = false;
    subs = new Subscription();
    constructor(element, renderer, ngZone, localizationService) {
        this.element = element;
        this.renderer = renderer;
        this.ngZone = ngZone;
        this.localizationService = localizationService;
        validatePackage(packageMetadata);
        this.direction = localizationService.rtl ? 'rtl' : 'ltr';
    }
    ngOnInit() {
        this.subs.add(this.localizationService.changes
            .subscribe(({ rtl }) => this.direction = rtl ? 'rtl' : 'ltr'));
        this.renderer.setAttribute(this.element.nativeElement, 'role', 'button');
    }
    ngOnDestroy() {
        this.subs.unsubscribe();
    }
    ngOnChanges(changes) {
        if (changes && changes['selected']) {
            const hasAriaSelected = this.element.nativeElement.hasAttribute('aria-selected');
            if (!hasAriaSelected) {
                this.renderer.setAttribute(this.element.nativeElement, 'aria-pressed', `${this.selected}`);
            }
        }
    }
    ngAfterViewInit() {
        const chip = this.element.nativeElement;
        const stylingOptions = ['size', 'rounded', 'fillMode'];
        stylingOptions.forEach(input => {
            this.handleClasses(this[input], input);
        });
        this.attachElementEventHandlers(chip);
    }
    /**
     * @hidden
     */
    get kendoIconClass() {
        this.verifyIconSettings([this.iconClass]);
        return `k-i-${this.icon}`;
    }
    /**
     * @hidden
     */
    get customIconClass() {
        this.verifyIconSettings([this.icon]);
        return this.iconClass;
    }
    /**
     * @hidden
     */
    get removeIconClass() {
        return this.removeIcon ? this.removeIcon : 'k-i-x-circle';
    }
    /**
     * Focuses the Chip component.
     */
    focus() {
        if (isDocumentAvailable()) {
            this.element.nativeElement.focus();
        }
    }
    /**
     * Blurs the Chip component.
     */
    blur() {
        if (isDocumentAvailable()) {
            this.element.nativeElement.blur();
        }
    }
    /**
     * @hidden
     */
    onRemoveClick(e) {
        if (this.removable) {
            this.remove.emit({ sender: this, originalEvent: e });
        }
    }
    /**
     * @hidden
     */
    onMenuClick(e) {
        if (this.hasMenu) {
            this.menuToggle.emit({ sender: this, originalEvent: e });
        }
    }
    attachElementEventHandlers(chip) {
        this.ngZone.runOutsideAngular(() => {
            this.subs.add(this.renderer.listen(chip, 'focus', () => {
                this.renderer.addClass(chip, 'k-focus');
            }));
            this.subs.add(this.renderer.listen(chip, 'blur', () => {
                this.renderer.removeClass(chip, 'k-focus');
            }));
            this.subs.add(this.renderer.listen(chip, 'click', (e) => {
                const isActionClicked = closest(e.target, '.k-chip-action');
                if (!isActionClicked) {
                    this.ngZone.run(() => {
                        this.contentClick.emit({ sender: this, originalEvent: e });
                    });
                }
            }));
            this.subs.add(this.renderer.listen(chip, 'keydown', this.keyDownHandler.bind(this)));
        });
    }
    /**
     * @hidden
     */
    verifyIconSettings(iconsToCheck) {
        if (isDevMode()) {
            if (iconsToCheck.filter(icon => icon !== null && icon !== undefined).length > 0) {
                this.renderer.removeClass(this.element.nativeElement, 'k-chip-has-icon');
                throw new Error('Invalid configuration: Having multiple icons is not supported. Only a single icon on a chip can be displayed.');
            }
        }
    }
    handleClasses(value, input) {
        const elem = this.element.nativeElement;
        const classes = getStylingClasses('chip', input, this[input], value);
        if (input === 'fillMode') {
            this.handleThemeColor(this.themeColor, this[input], value);
        }
        if (classes.toRemove) {
            this.renderer.removeClass(elem, classes.toRemove);
        }
        if (classes.toAdd) {
            this.renderer.addClass(elem, classes.toAdd);
        }
    }
    handleThemeColor(value, prevFillMode, fillMode) {
        const elem = this.element.nativeElement;
        const removeFillMode = prevFillMode ? prevFillMode : this.fillMode;
        const addFillMode = fillMode ? fillMode : this.fillMode;
        const themeColorClass = getThemeColorClasses('chip', removeFillMode, addFillMode, this.themeColor, value);
        this.renderer.removeClass(elem, themeColorClass.toRemove);
        if (addFillMode !== 'none' && fillMode !== 'none') {
            if (themeColorClass.toAdd) {
                this.renderer.addClass(elem, themeColorClass.toAdd);
            }
        }
    }
    keyDownHandler(e) {
        const isEnterOrSpace = e.keyCode === Keys.Enter || e.keyCode === Keys.Space;
        const isDeleteOrBackspace = e.keyCode === Keys.Delete || e.keyCode === Keys.Backspace;
        if (this.disabled) {
            return;
        }
        if (isEnterOrSpace) {
            this.ngZone.run(() => {
                this.contentClick.emit({ sender: this, originalEvent: e });
            });
        }
        else if (isDeleteOrBackspace && this.removable) {
            this.ngZone.run(() => {
                this.remove.emit({ sender: this, originalEvent: e });
            });
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ChipComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }, { token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ChipComponent, isStandalone: true, selector: "kendo-chip", inputs: { label: "label", icon: "icon", svgIcon: "svgIcon", iconClass: "iconClass", avatarSettings: "avatarSettings", selected: "selected", removable: "removable", removeIcon: "removeIcon", removeSvgIcon: "removeSvgIcon", hasMenu: "hasMenu", menuIcon: "menuIcon", menuSvgIcon: "menuSvgIcon", disabled: "disabled", size: "size", rounded: "rounded", fillMode: "fillMode", themeColor: "themeColor" }, outputs: { remove: "remove", menuToggle: "menuToggle", contentClick: "contentClick" }, host: { properties: { "attr.tabindex": "this.tabIndex", "class.k-chip": "this.hostClass", "class.k-chip-has-icon": "this.hasIconClass", "attr.aria-disabled": "this.disabledClass", "class.k-disabled": "this.disabledClass", "class.k-selected": "this.selectedClass", "class.k-focus": "this.focusedClass", "attr.dir": "this.direction" } }, providers: [
            LocalizationService,
            {
                provide: L10N_PREFIX,
                useValue: 'kendo.chip'
            }
        ], usesOnChanges: true, ngImport: i0, template: `
        <kendo-icon-wrapper
            *ngIf="icon || svgIcon"
            size="small"
            innerCssClass="k-chip-icon"
            [name]="icon"
            [svgIcon]="svgIcon"></kendo-icon-wrapper>

        <kendo-icon-wrapper
            *ngIf="iconClass"
            size="small"
            innerCssClass="k-chip-icon"
            [customFontClass]="customIconClass"></kendo-icon-wrapper>
        <span
            *ngIf="avatarSettings"
            class="k-chip-avatar k-avatar k-avatar-sm k-avatar-solid k-avatar-solid-primary k-rounded-full"
            [ngStyle]="avatarSettings.cssStyle">
            <ng-container *ngIf="avatarSettings?.imageSrc">
                <span class="k-avatar-image">
                    <img src="{{ avatarSettings.imageSrc }}" [ngStyle]="avatarSettings.imageCssStyle" [attr.alt]="avatarSettings.imageAltText" />
                </span>
            </ng-container>
    
            <ng-container *ngIf="avatarSettings?.initials">
                <span class="k-avatar-text" [ngStyle]="avatarSettings.initialsCssStyle">{{ avatarSettings.initials.substring(0, 2) }}</span>
            </ng-container>
        </span>

        <span class="k-chip-content">
            <span class="k-chip-label" *ngIf="label">
                {{ label }}
            </span>
            <ng-content *ngIf="!label"></ng-content>
        </span>

        <span class="k-chip-actions" *ngIf="hasMenu || removable">
            <span class="k-chip-action k-chip-more-action"
                *ngIf="hasMenu"
                (click)="onMenuClick($event)">
                <kendo-icon-wrapper
                    name="more-vertical"
                    size="small"
                    [svgIcon]="defaultMenuIcon || menuSvgIcon"
                    [customFontClass]="menuIcon"></kendo-icon-wrapper>
            </span>
            <span class="k-chip-action k-chip-remove-action"
                *ngIf="removable"
                (click)="onRemoveClick($event)">
                <kendo-icon-wrapper
                    name="x-circle"
                    size="small"
                    [svgIcon]="removeSvgIcon || defaultRemoveIcon"
                    [customFontClass]="removeIcon"></kendo-icon-wrapper>
            </span>
        </span>
    `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ChipComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'kendo-chip',
                    template: `
        <kendo-icon-wrapper
            *ngIf="icon || svgIcon"
            size="small"
            innerCssClass="k-chip-icon"
            [name]="icon"
            [svgIcon]="svgIcon"></kendo-icon-wrapper>

        <kendo-icon-wrapper
            *ngIf="iconClass"
            size="small"
            innerCssClass="k-chip-icon"
            [customFontClass]="customIconClass"></kendo-icon-wrapper>
        <span
            *ngIf="avatarSettings"
            class="k-chip-avatar k-avatar k-avatar-sm k-avatar-solid k-avatar-solid-primary k-rounded-full"
            [ngStyle]="avatarSettings.cssStyle">
            <ng-container *ngIf="avatarSettings?.imageSrc">
                <span class="k-avatar-image">
                    <img src="{{ avatarSettings.imageSrc }}" [ngStyle]="avatarSettings.imageCssStyle" [attr.alt]="avatarSettings.imageAltText" />
                </span>
            </ng-container>
    
            <ng-container *ngIf="avatarSettings?.initials">
                <span class="k-avatar-text" [ngStyle]="avatarSettings.initialsCssStyle">{{ avatarSettings.initials.substring(0, 2) }}</span>
            </ng-container>
        </span>

        <span class="k-chip-content">
            <span class="k-chip-label" *ngIf="label">
                {{ label }}
            </span>
            <ng-content *ngIf="!label"></ng-content>
        </span>

        <span class="k-chip-actions" *ngIf="hasMenu || removable">
            <span class="k-chip-action k-chip-more-action"
                *ngIf="hasMenu"
                (click)="onMenuClick($event)">
                <kendo-icon-wrapper
                    name="more-vertical"
                    size="small"
                    [svgIcon]="defaultMenuIcon || menuSvgIcon"
                    [customFontClass]="menuIcon"></kendo-icon-wrapper>
            </span>
            <span class="k-chip-action k-chip-remove-action"
                *ngIf="removable"
                (click)="onRemoveClick($event)">
                <kendo-icon-wrapper
                    name="x-circle"
                    size="small"
                    [svgIcon]="removeSvgIcon || defaultRemoveIcon"
                    [customFontClass]="removeIcon"></kendo-icon-wrapper>
            </span>
        </span>
    `,
                    providers: [
                        LocalizationService,
                        {
                            provide: L10N_PREFIX,
                            useValue: 'kendo.chip'
                        }
                    ],
                    standalone: true,
                    imports: [NgIf, NgStyle, IconWrapperComponent, NgClass]
                }]
        }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: i1.LocalizationService }]; }, propDecorators: { label: [{
                type: Input
            }], icon: [{
                type: Input
            }], svgIcon: [{
                type: Input
            }], iconClass: [{
                type: Input
            }], avatarSettings: [{
                type: Input
            }], selected: [{
                type: Input
            }], removable: [{
                type: Input
            }], removeIcon: [{
                type: Input
            }], removeSvgIcon: [{
                type: Input
            }], hasMenu: [{
                type: Input
            }], menuIcon: [{
                type: Input
            }], menuSvgIcon: [{
                type: Input
            }], disabled: [{
                type: Input
            }], size: [{
                type: Input
            }], rounded: [{
                type: Input
            }], fillMode: [{
                type: Input
            }], themeColor: [{
                type: Input
            }], remove: [{
                type: Output
            }], menuToggle: [{
                type: Output
            }], contentClick: [{
                type: Output
            }], tabIndex: [{
                type: HostBinding,
                args: ['attr.tabindex']
            }], hostClass: [{
                type: HostBinding,
                args: ['class.k-chip']
            }], hasIconClass: [{
                type: HostBinding,
                args: ['class.k-chip-has-icon']
            }], disabledClass: [{
                type: HostBinding,
                args: ['attr.aria-disabled']
            }, {
                type: HostBinding,
                args: ['class.k-disabled']
            }], selectedClass: [{
                type: HostBinding,
                args: ['class.k-selected']
            }], focusedClass: [{
                type: HostBinding,
                args: ['class.k-focus']
            }], direction: [{
                type: HostBinding,
                args: ['attr.dir']
            }] } });

class ChipListComponent {
    localizationService;
    renderer;
    element;
    ngZone;
    hostClass = true;
    orientation = 'horizontal';
    /**
     * @hidden
     */
    direction;
    /**
     * Sets the selection mode of the ChipList.
     *
     * The available values are:
     * * `none` (default)
     * * `single`
     * * `multiple`
     */
    selection = 'none';
    /**
     * The size property specifies the gap between the Chips in the ChipList
     * ([see example]({% slug appearance_chiplist %}#toc-size)).
     *
     * The possible values are:
     * * `'small'`
     * * `'medium'` (default)
     * * `'large'`
     * * `none`
     */
    set size(size) {
        const sizeValue = size ? size : 'medium';
        this.handleClasses(sizeValue, 'size');
        this.chips?.forEach(chip => this.setChipSize(chip, sizeValue));
        this._size = sizeValue;
    }
    get size() {
        return this._size;
    }
    /**
     * Fires each time when the ChipList selection is changed.
     */
    selectedChange = new EventEmitter();
    /**
     * Fires each time the user clicks on the remove icon of the Chip.
     */
    remove = new EventEmitter();
    chips;
    get single() {
        return this.selection === 'single';
    }
    get multiple() {
        return this.selection === 'multiple';
    }
    /**
     * @hidden
     */
    role = 'listbox';
    dynamicRTLSubscription;
    _size = 'medium';
    subs = new Subscription();
    _navigable = true;
    /**
     * @hidden
     */
    onClick($event) {
        const target = $event.target;
        const isRemoveClicked = closest(target, '.k-chip-remove-action');
        const clickedChip = closest(target, '.k-chip');
        const chip = this.chips.find((chip) => clickedChip === chip.element.nativeElement);
        this.currentActiveIndex = this.chips.toArray().indexOf(chip);
        chip && chip.focus();
        if (chip && this.navigable) {
            this.chips.forEach((c) => {
                this.renderer.setAttribute(c.element.nativeElement, 'tabindex', '-1');
            });
            this.renderer.setAttribute(chip.element.nativeElement, 'tabindex', '0');
        }
        if (isRemoveClicked && clickedChip) {
            const removeEventArgs = { sender: this, originalEvent: $event, removedChip: chip };
            this.remove.emit(removeEventArgs);
        }
        if (this.selection !== 'none' && clickedChip && !isRemoveClicked) {
            this.setSelection(chip);
        }
    }
    /**
     * By default, keyboard navigation is available through arrow keys and roving tabindex.
     * When set to `false`, all chips are part of the default tabbing sequence of the page.
     *
     * @default true
     */
    set navigable(value) {
        this._navigable = value;
        this.chips?.forEach(c => this.renderer.setAttribute(c.element.nativeElement, 'tabindex', value ? '-1' : '0'));
        this.chips?.first && this.renderer.setAttribute(this.chips.first.element.nativeElement, 'tabindex', '0');
    }
    get navigable() {
        return this._navigable;
    }
    currentActiveIndex = 0;
    constructor(localizationService, renderer, element, ngZone) {
        this.localizationService = localizationService;
        this.renderer = renderer;
        this.element = element;
        this.ngZone = ngZone;
        validatePackage(packageMetadata);
        this.direction = localizationService.rtl ? 'rtl' : 'ltr';
    }
    ngOnInit() {
        this.dynamicRTLSubscription = this.localizationService.changes
            .subscribe(({ rtl }) => this.direction = rtl ? 'rtl' : 'ltr');
    }
    ngAfterViewInit() {
        const stylingInputs = ['size'];
        stylingInputs.forEach(input => {
            this.handleClasses(this[input], input);
        });
        this.attachElementEventHandlers();
        this.updateChips();
    }
    ngAfterContentInit() {
        this.subs.add(this.chips?.changes.subscribe(() => this.updateChips()));
    }
    ngOnDestroy() {
        if (this.dynamicRTLSubscription) {
            this.dynamicRTLSubscription.unsubscribe();
        }
        this.subs.unsubscribe();
    }
    selectedChips() {
        return this.chips.reduce((acc, cur, idx) => { return cur.selected ? acc.concat(idx) : acc; }, []);
    }
    /**
     * Updates the selection on click of a Chip. Emits events.
     */
    setSelection(chip) {
        if (this.selection === 'single') {
            this.clearSelection(chip);
        }
        chip.selected = !chip.selected;
        const chipEl = chip.element.nativeElement;
        this.renderer.setAttribute(chipEl, 'aria-selected', `${chip.selected}`);
        this.selectedChange.emit(this.selectedChips());
    }
    clearSelection(chip) {
        this.chips.forEach((c) => {
            if (chip !== c) {
                c.selected = false;
                this.renderer.setAttribute(c.element.nativeElement, 'aria-selected', 'false');
            }
        });
    }
    handleClasses(value, input) {
        const elem = this.element.nativeElement;
        const classes = getStylingClasses('chip-list', input, this[input], value);
        if (classes.toRemove) {
            this.renderer.removeClass(elem, classes.toRemove);
        }
        if (classes.toAdd) {
            this.renderer.addClass(elem, classes.toAdd);
        }
    }
    attachElementEventHandlers() {
        const chiplist = this.element.nativeElement;
        this.ngZone.runOutsideAngular(() => {
            this.subs.add(this.renderer.listen(chiplist, 'keydown', this.keyDownHandler.bind(this)));
        });
    }
    keyDownHandler(e) {
        const isEnterOrSpace = e.keyCode === Keys.Enter || e.keyCode === Keys.Space;
        const isDeleteOrBackspace = e.keyCode === Keys.Delete || e.keyCode === Keys.Backspace;
        const isLeftArrow = e.keyCode === Keys.ArrowLeft;
        const isRightArrow = e.keyCode === Keys.ArrowRight;
        if (isEnterOrSpace) {
            const target = e.target;
            const clickedChip = closest(target, '.k-chip');
            const chip = this.chips.find((chip) => clickedChip === chip.element.nativeElement);
            this.currentActiveIndex = this.chips.toArray().findIndex((chip) => clickedChip === chip.element.nativeElement);
            if (this.selection !== 'none' && clickedChip) {
                this.ngZone.run(() => {
                    this.setSelection(chip);
                });
            }
        }
        else if (isDeleteOrBackspace) {
            const target = e.target;
            const clickedChip = closest(target, '.k-chip');
            const chip = this.chips.find((chip) => clickedChip === chip.element.nativeElement);
            if (clickedChip) {
                const removeEventArgs = { sender: this, originalEvent: e, removedChip: chip };
                this.ngZone.run(() => {
                    this.remove.emit(removeEventArgs);
                });
            }
        }
        else if (isLeftArrow) {
            this.handleArrowKeys('left');
        }
        else if (isRightArrow) {
            this.handleArrowKeys('right');
        }
    }
    handleArrowKeys(direction) {
        if (!this.navigable) {
            return;
        }
        const directionDelta = direction === 'left' ? -1 : 1;
        this.currentActiveIndex = this.currentActiveIndex + directionDelta;
        if (this.currentActiveIndex >= this.chips.length) {
            this.currentActiveIndex = 0;
        }
        else if (this.currentActiveIndex < 0) {
            this.currentActiveIndex = this.chips.length - 1;
        }
        this.chips.forEach((chip, idx) => {
            this.renderer.setAttribute(chip.element.nativeElement, 'tabindex', '-1');
            if (idx === this.currentActiveIndex) {
                this.renderer.setAttribute(chip.element.nativeElement, 'tabindex', '0');
                chip.focus();
            }
        });
    }
    updateChips() {
        this.normalizeActiveIndex();
        this.chips.forEach((chip, idx) => {
            const chipEl = chip.element.nativeElement;
            this.renderer.removeAttribute(chipEl, 'aria-pressed');
            this.renderer.setAttribute(chipEl, 'aria-selected', `${chip.selected}`);
            this.role === 'listbox' && this.renderer.setAttribute(chipEl, 'role', 'option');
            if (!this.navigable) {
                return;
            }
            this.renderer.setAttribute(chipEl, 'tabindex', '-1');
            if (idx === this.currentActiveIndex) {
                this.renderer.setAttribute(chipEl, 'tabindex', '0');
                if (isDocumentAvailable() && document.activeElement.closest('.k-chip-list')) {
                    chip.focus();
                }
            }
            if (chip.removable) {
                this.renderer.setAttribute(chipEl, 'aria-keyshortcuts', 'Enter Delete');
            }
            this.setChipSize(chip, this.size);
        });
    }
    normalizeActiveIndex() {
        if (this.currentActiveIndex >= this.chips.length) {
            this.currentActiveIndex = Math.max(this.chips.length - 1, 0);
        }
    }
    setChipSize(chip, size) {
        const hasSize = chip.sizeIsSet;
        !hasSize && chip.size !== size && (chip.size = size);
        !hasSize && (chip.sizeIsSet = false);
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ChipListComponent, deps: [{ token: i1.LocalizationService }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ChipListComponent, isStandalone: true, selector: "kendo-chiplist, kendo-chip-list", inputs: { selection: "selection", size: "size", role: "role", navigable: "navigable" }, outputs: { selectedChange: "selectedChange", remove: "remove" }, host: { listeners: { "click": "onClick($event)" }, properties: { "class.k-chip-list": "this.hostClass", "attr.aria-orientation": "this.orientation", "attr.dir": "this.direction", "class.k-selection-single": "this.single", "attr.aria-multiselectable": "this.multiple", "class.k-selection-multiple": "this.multiple", "attr.role": "this.role" } }, providers: [
            LocalizationService,
            {
                provide: L10N_PREFIX,
                useValue: 'kendo.chiplist'
            }
        ], queries: [{ propertyName: "chips", predicate: ChipComponent }], ngImport: i0, template: `
        <ng-content></ng-content>
    `, isInline: true });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ChipListComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'kendo-chiplist, kendo-chip-list',
                    template: `
        <ng-content></ng-content>
    `,
                    providers: [
                        LocalizationService,
                        {
                            provide: L10N_PREFIX,
                            useValue: 'kendo.chiplist'
                        }
                    ],
                    standalone: true
                }]
        }], ctorParameters: function () { return [{ type: i1.LocalizationService }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { hostClass: [{
                type: HostBinding,
                args: ['class.k-chip-list']
            }], orientation: [{
                type: HostBinding,
                args: ['attr.aria-orientation']
            }], direction: [{
                type: HostBinding,
                args: ['attr.dir']
            }], selection: [{
                type: Input
            }], size: [{
                type: Input
            }], selectedChange: [{
                type: Output
            }], remove: [{
                type: Output
            }], chips: [{
                type: ContentChildren,
                args: [ChipComponent]
            }], single: [{
                type: HostBinding,
                args: ['class.k-selection-single']
            }], multiple: [{
                type: HostBinding,
                args: ['attr.aria-multiselectable']
            }, {
                type: HostBinding,
                args: ['class.k-selection-multiple']
            }], role: [{
                type: HostBinding,
                args: ['attr.role']
            }, {
                type: Input
            }], onClick: [{
                type: HostListener,
                args: ['click', ['$event']]
            }], navigable: [{
                type: Input
            }] } });

/**
 * Used for rendering the list item content.
 *
 * To define the item template, nest a `<ng-template>` tag with the `kendo<ComponentName>ItemTemplate` directive inside the component tag.
 *
 * For the DropDownButton, use the `kendoDropDownButtonItemTemplate` directive.
 * For the SplitButton, use the `kendoSplitButtonItemTemplate` directive.
 *
 * The template context is set to the current component. To get a reference to the current data item, use the `let-dataItem` directive.
 *
 * @example
 * ```ts
 * _@Component({
 * selector: 'my-app',
 * template: `
 *  <kendo-splitbutton [data]="listItems">
 *    <ng-template kendoSplitButtonItemTemplate let-dataItem>
 *      <span>{{dataItem}} option</span>
 *    </ng-template>
 *  </kendo-splitbutton>
 *  <kendo-dropdownbutton [data]="listItems">
 *    <ng-template kendoDropDownButtonItemTemplate let-dataItem>
 *      <span>{{dataItem}} option</span>
 *    </ng-template>
 *  </kendo-dropdownbutton>
 * `
 * })
 * class AppComponent {
 *   public listItems: Array<any> = [{
 *      text: 'item1',
 *      icon: 'arrow-rotate-cw',
 *      disabled: false,
 *      click: (dataItem: any) => {
 *          //action
 *      }
 *  }, {
 *      text: 'item2',
 *      icon: 'arrow-rotate-cw',
 *      disabled: false,
 *      click: (dataItem: any) => {
 *          //action
 *      }
 *  }]
 * }
 * ```
 *
 * For more examples, refer to the article on the [DropDownButton templates](slug:itemstemplates_dropdownbutton).
 */
class ButtonItemTemplateDirective {
    templateRef;
    constructor(templateRef) {
        this.templateRef = templateRef;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ButtonItemTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ButtonItemTemplateDirective, isStandalone: true, selector: "[kendoDropDownButtonItemTemplate],[kendoSplitButtonItemTemplate]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ButtonItemTemplateDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[kendoDropDownButtonItemTemplate],[kendoSplitButtonItemTemplate]',
                    standalone: true
                }]
        }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });

/**
 * @hidden
 */
class FocusService {
    onFocus = new EventEmitter();
    focusedIndex;
    isFocused(index) {
        return index === this.focused;
    }
    focus(index) {
        if (this.isFocused(index)) {
            return;
        }
        this.focused = index;
        this.onFocus.emit(index);
    }
    resetFocus() {
        this.focused = -1;
    }
    get focused() {
        return this.focusedIndex;
    }
    set focused(index) {
        this.focusedIndex = index;
        this.onFocus.emit(index);
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FocusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FocusService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FocusService, decorators: [{
            type: Injectable
        }] });

/**
 * @hidden
 */
var KeyEvents;
(function (KeyEvents) {
    KeyEvents[KeyEvents["keydown"] = 0] = "keydown";
    KeyEvents[KeyEvents["keypress"] = 1] = "keypress";
    KeyEvents[KeyEvents["keyup"] = 2] = "keyup";
})(KeyEvents || (KeyEvents = {}));

/**
 * @hidden
 */
var NavigationAction;
(function (NavigationAction) {
    // eslint-disable-next-line id-denylist
    NavigationAction[NavigationAction["Undefined"] = 0] = "Undefined";
    NavigationAction[NavigationAction["Open"] = 1] = "Open";
    NavigationAction[NavigationAction["Close"] = 2] = "Close";
    NavigationAction[NavigationAction["Enter"] = 3] = "Enter";
    NavigationAction[NavigationAction["EnterPress"] = 4] = "EnterPress";
    NavigationAction[NavigationAction["EnterUp"] = 5] = "EnterUp";
    NavigationAction[NavigationAction["Tab"] = 6] = "Tab";
    NavigationAction[NavigationAction["Esc"] = 7] = "Esc";
    NavigationAction[NavigationAction["Navigate"] = 8] = "Navigate";
})(NavigationAction || (NavigationAction = {}));

/**
 * @hidden
 */
const NAVIGATION_CONFIG = new InjectionToken('navigation.config');

/**
 * @hidden
 */
class NavigationService {
    navigate = new EventEmitter();
    open = new EventEmitter();
    close = new EventEmitter();
    enter = new EventEmitter();
    enterpress = new EventEmitter();
    enterup = new EventEmitter();
    tab = new EventEmitter();
    esc = new EventEmitter();
    useLeftRightArrows;
    constructor(config) {
        this.useLeftRightArrows = config.useLeftRightArrows;
    }
    process(args) {
        const keyCode = args.keyCode;
        const keyEvent = args.keyEvent;
        let index;
        let action = NavigationAction.Undefined;
        if (keyEvent === KeyEvents.keyup) {
            if (this.isEnterOrSpace(keyCode)) {
                action = NavigationAction.EnterUp;
            }
        }
        else {
            if (args.altKey && keyCode === Keys.ArrowDown) {
                action = NavigationAction.Open;
            }
            else if (args.altKey && keyCode === Keys.ArrowUp) {
                action = NavigationAction.Close;
            }
            else if (this.isEnterOrSpace(keyCode)) {
                action = NavigationAction.Enter;
            }
            else if (keyCode === Keys.Escape) {
                action = NavigationAction.Esc;
            }
            else if (keyCode === Keys.Tab) {
                action = NavigationAction.Tab;
            }
            else if (keyCode === Keys.ArrowUp || (this.useLeftRightArrows && keyCode === Keys.ArrowLeft)) {
                const step = args.flipNavigation ? 1 : -1;
                const start = args.flipNavigation ? args.min : args.max;
                const end = args.flipNavigation ? args.max : args.min;
                index = this.next({
                    current: args.current,
                    start: start,
                    end: end,
                    step: step
                });
                action = NavigationAction.Navigate;
            }
            else if (keyCode === Keys.ArrowDown || (this.useLeftRightArrows && keyCode === Keys.ArrowRight)) {
                const step = args.flipNavigation ? -1 : 1;
                const start = args.flipNavigation ? args.max : args.min;
                const end = args.flipNavigation ? args.min : args.max;
                index = this.next({
                    current: args.current,
                    start: start,
                    end: end,
                    step: step
                });
                action = NavigationAction.Navigate;
            }
            else if (keyCode === Keys.Home) {
                index = args.min;
                action = NavigationAction.Navigate;
            }
            else if (keyCode === Keys.End) {
                index = args.max;
                action = NavigationAction.Navigate;
            }
        }
        if (action !== NavigationAction.Undefined) {
            this[NavigationAction[action].toLowerCase()].emit({ index, target: args.target, esc: action === NavigationAction.Esc });
        }
        return action;
    }
    isEnterOrSpace(keyCode) {
        return keyCode === Keys.Enter || keyCode === Keys.Space;
    }
    next(args) {
        if (!isPresent(args.current)) {
            return args.start;
        }
        else {
            return args.current !== args.end ? args.current + args.step : args.end;
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NavigationService, deps: [{ token: NAVIGATION_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NavigationService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NavigationService, decorators: [{
            type: Injectable
        }], ctorParameters: function () { return [{ type: undefined, decorators: [{
                    type: Inject,
                    args: [NAVIGATION_CONFIG]
                }] }]; } });

/**
 * @hidden
 */
class PopupContainerService {
    container;
    template;
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: PopupContainerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: PopupContainerService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: PopupContainerService, decorators: [{
            type: Injectable
        }] });

/**
 * @hidden
 */
class FocusableDirective {
    focusService;
    renderer;
    index;
    element;
    subs = new Subscription();
    constructor(focusService, elementRef, renderer) {
        this.focusService = focusService;
        this.renderer = renderer;
        this.element = elementRef.nativeElement;
        this.subscribeEvents();
    }
    ngOnInit() {
        if (this.index === this.focusService.focused) {
            this.renderer.addClass(this.element, 'k-focus');
        }
        else {
            this.renderer.removeClass(this.element, 'k-focus');
        }
    }
    /**
     * @hidden
     */
    ngOnDestroy() {
        this.subs.unsubscribe();
    }
    subscribeEvents() {
        if (!isDocumentAvailable()) {
            return;
        }
        this.subs.add(this.focusService.onFocus.subscribe((index) => {
            if (this.index === index) {
                this.renderer.addClass(this.element, 'k-focus');
                this.renderer.setAttribute(this.element, 'tabindex', '0');
                this.element.focus();
            }
            else {
                this.renderer.setAttribute(this.element, 'tabindex', '-1');
                this.renderer.removeClass(this.element, 'k-focus');
            }
        }));
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FocusableDirective, deps: [{ token: FocusService }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: FocusableDirective, isStandalone: true, selector: "[kendoButtonFocusable]", inputs: { index: "index" }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FocusableDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[kendoButtonFocusable]',
                    standalone: true
                }]
        }], ctorParameters: function () { return [{ type: FocusService }, { type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { index: [{
                type: Input
            }] } });

/**
 * @hidden
 */
class ListComponent {
    data;
    textField;
    itemTemplate;
    onItemClick = new EventEmitter();
    onItemBlur = new EventEmitter();
    set size(size) {
        if (size) {
            this.sizeClass = `k-menu-group-${SIZES[size]}`;
        }
        else {
            this.sizeClass = '';
        }
    }
    sizeClass = '';
    constructor() {
        validatePackage(packageMetadata);
    }
    getText(dataItem) {
        if (dataItem) {
            return this.textField ? dataItem[this.textField] : dataItem.text || dataItem;
        }
        return undefined;
    }
    getIconClasses(dataItem) {
        const icon = dataItem.icon ? 'k-icon k-i-' + dataItem.icon : undefined;
        const classes = {};
        classes[icon || dataItem.iconClass] = true;
        return classes;
    }
    onClick(index) {
        this.onItemClick.emit(index);
    }
    onBlur() {
        this.onItemBlur.emit();
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ListComponent, isStandalone: true, selector: "kendo-button-list", inputs: { data: "data", textField: "textField", itemTemplate: "itemTemplate", size: "size" }, outputs: { onItemClick: "onItemClick", onItemBlur: "onItemBlur" }, ngImport: i0, template: `
        <ul class="k-group k-menu-group k-reset" role="list" [ngClass]="sizeClass">
            <li kendoButtonFocusable
                *ngFor="let dataItem of data; let index = index;"
                [index]="index"
                tabindex="-1"
                class="k-item k-menu-item"
                role="listitem"
                [attr.aria-disabled]="dataItem.disabled ? true : false"
                (click)="$event.stopImmediatePropagation(); onClick(index);"
                (blur)="onBlur()">
                <ng-template [ngIf]="itemTemplate?.templateRef">
                    <span
                        class="k-link k-menu-link"
                        [class.k-disabled]="dataItem.disabled"
                        [ngClass]="dataItem.cssClass">
                        <ng-template
                            [templateContext]="{ templateRef: itemTemplate?.templateRef, $implicit: dataItem }"
                        ></ng-template>
                    </span>
                </ng-template>
                <ng-template [ngIf]="!itemTemplate?.templateRef">
                    <span
                        class="k-link k-menu-link"
                        [class.k-disabled]="dataItem.disabled"
                        [ngClass]="dataItem.cssClass">
                        <kendo-icon-wrapper
                            *ngIf="dataItem.icon || dataItem.iconClass || dataItem.svgIcon"
                            [name]="dataItem.icon"
                            [svgIcon]="dataItem.svgIcon"
                            [customFontClass]="dataItem.iconClass"
                        ></kendo-icon-wrapper>
                        <img
                            *ngIf="dataItem.imageUrl"
                            class="k-image"
                            [src]="dataItem.imageUrl"
                            [alt]="dataItem.imageAlt"
                        >
                        <span *ngIf="getText(dataItem)" class="k-menu-link-text">
                            {{ getText(dataItem) }}
                        </span>
                    </span>
                </ng-template>
            </li>
        </ul>
    `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: FocusableDirective, selector: "[kendoButtonFocusable]", inputs: ["index"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: TemplateContextDirective, selector: "[templateContext]", inputs: ["templateContext"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ListComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'kendo-button-list',
                    template: `
        <ul class="k-group k-menu-group k-reset" role="list" [ngClass]="sizeClass">
            <li kendoButtonFocusable
                *ngFor="let dataItem of data; let index = index;"
                [index]="index"
                tabindex="-1"
                class="k-item k-menu-item"
                role="listitem"
                [attr.aria-disabled]="dataItem.disabled ? true : false"
                (click)="$event.stopImmediatePropagation(); onClick(index);"
                (blur)="onBlur()">
                <ng-template [ngIf]="itemTemplate?.templateRef">
                    <span
                        class="k-link k-menu-link"
                        [class.k-disabled]="dataItem.disabled"
                        [ngClass]="dataItem.cssClass">
                        <ng-template
                            [templateContext]="{ templateRef: itemTemplate?.templateRef, $implicit: dataItem }"
                        ></ng-template>
                    </span>
                </ng-template>
                <ng-template [ngIf]="!itemTemplate?.templateRef">
                    <span
                        class="k-link k-menu-link"
                        [class.k-disabled]="dataItem.disabled"
                        [ngClass]="dataItem.cssClass">
                        <kendo-icon-wrapper
                            *ngIf="dataItem.icon || dataItem.iconClass || dataItem.svgIcon"
                            [name]="dataItem.icon"
                            [svgIcon]="dataItem.svgIcon"
                            [customFontClass]="dataItem.iconClass"
                        ></kendo-icon-wrapper>
                        <img
                            *ngIf="dataItem.imageUrl"
                            class="k-image"
                            [src]="dataItem.imageUrl"
                            [alt]="dataItem.imageAlt"
                        >
                        <span *ngIf="getText(dataItem)" class="k-menu-link-text">
                            {{ getText(dataItem) }}
                        </span>
                    </span>
                </ng-template>
            </li>
        </ul>
    `,
                    standalone: true,
                    imports: [NgClass, NgFor, FocusableDirective, NgIf, TemplateContextDirective, IconWrapperComponent]
                }]
        }], ctorParameters: function () { return []; }, propDecorators: { data: [{
                type: Input
            }], textField: [{
                type: Input
            }], itemTemplate: [{
                type: Input
            }], onItemClick: [{
                type: Output
            }], onItemBlur: [{
                type: Output
            }], size: [{
                type: Input
            }] } });

/**
 * @hidden
 */
class ListButton extends MultiTabStop {
    focusService;
    navigationService;
    wrapperRef;
    _zone;
    popupService;
    elRef;
    cdr;
    containerService;
    listId = guid();
    buttonId = guid();
    _data;
    _open = false;
    _disabled = false;
    _active = false;
    _popupSettings = { animate: true, popupClass: '' };
    _isFocused = false;
    _itemClick;
    _blur;
    wrapper;
    subs = new Subscription();
    direction;
    popupRef;
    popupSubs = new Subscription();
    button;
    buttonList;
    popupTemplate;
    container;
    /**
     * Sets the disabled state of the DropDownButton.
     */
    set disabled(value) {
        if (value && this.openState) {
            this.openState = false;
        }
        this._disabled = value;
    }
    get disabled() {
        return this._disabled;
    }
    /**
     * Specifies the [`tabIndex`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) of the component.
     */
    tabIndex = 0;
    /**
     * The CSS classes that will be rendered on the main button.
     * Supports the type of values that are supported by [`ngClass`](link:site.data.urls.angular['ngclassapi']).
     */
    buttonClass;
    /**
     * Fires each time the popup is about to open.
     * This event is preventable. If you cancel the event, the popup will remain closed.
     */
    open = new EventEmitter();
    /**
     * Fires each time the popup is about to close.
     * This event is preventable. If you cancel the event, the popup will remain open.
     */
    close = new EventEmitter();
    /**
     * Needed by the kendoToggleButtonTabStop directive
     *
     * @hidden
     */
    escape = new EventEmitter();
    /**
     * @hidden
     */
    get componentTabIndex() {
        return this.disabled ? (-1) : this.tabIndex;
    }
    get appendTo() {
        const { appendTo } = this.popupSettings;
        if (!appendTo || appendTo === 'root') {
            return undefined;
        }
        return appendTo === 'component' ? this.containerService.container : appendTo;
    }
    /**
     * Configures the popup of the DropDownButton.
     *
     * The available options are:
     * - `animate: Boolean`&mdash;Controls the popup animation. By default, the open and close animations are enabled.
     * - `popupClass: String`&mdash;Specifies a list of CSS classes that are used to style the popup.
     * - `appendTo: "root" | "component" | ViewContainerRef`&mdash;Specifies the component to which the popup will be appended.
     * - `align: "left" | "center" | "right"`&mdash;Specifies the alignment of the popup.
     */
    set popupSettings(settings) {
        this._popupSettings = Object.assign({ animate: true, popupClass: '' }, settings);
    }
    get popupSettings() {
        return this._popupSettings;
    }
    /**
     * @hidden
     */
    get anchorAlign() {
        const align = { horizontal: this.popupSettings.align || 'left', vertical: 'bottom' };
        if (this.direction === 'rtl' && !isPresent(this.popupSettings.align)) {
            align.horizontal = 'right';
        }
        return align;
    }
    /**
     * @hidden
     */
    get popupAlign() {
        const align = { horizontal: this.popupSettings.align || 'left', vertical: 'top' };
        if (this.direction === 'rtl' && !isPresent(this.popupSettings.align)) {
            align.horizontal = 'right';
        }
        return align;
    }
    isClosePrevented = false;
    constructor(focusService, navigationService, wrapperRef, _zone, popupService, elRef, localization, cdr, containerService) {
        super();
        this.focusService = focusService;
        this.navigationService = navigationService;
        this.wrapperRef = wrapperRef;
        this._zone = _zone;
        this.popupService = popupService;
        this.elRef = elRef;
        this.cdr = cdr;
        this.containerService = containerService;
        validatePackage(packageMetadata);
        this.focusService = focusService;
        this.navigationService = navigationService;
        this.wrapper = wrapperRef.nativeElement;
        this.subs.add(localization.changes.subscribe(({ rtl }) => (this.direction = rtl ? 'rtl' : 'ltr')));
        this.subscribeEvents();
    }
    ngOnChanges(changes) {
        if (isChanged("popupSettings", changes) && isPresent(this.popupRef)) {
            const popup = this.popupRef.popup.instance;
            const newSettings = changes['popupSettings'].currentValue;
            popup.popupClass = newSettings.popupClass;
            popup.animate = newSettings.animate;
            popup.popupAlign = this.popupAlign;
        }
    }
    get popupClasses() {
        const popupClasses = ['k-menu-popup'];
        if (this._popupSettings.popupClass) {
            popupClasses.push(this._popupSettings.popupClass);
        }
        return popupClasses.join(' ');
    }
    get openState() {
        return this._open;
    }
    /**
     * @hidden
     */
    set openState(open) {
        if (this.disabled) {
            return;
        }
        this._open = open;
    }
    /**
     * Returns the current open state of the popup.
     */
    get isOpen() {
        return this._open;
    }
    /**
     * @hidden
     */
    togglePopupVisibility() {
        if (this._disabled) {
            return;
        }
        this._toggle(!this.openState, true);
        if (!this.isClosePrevented) {
            this.focusService.focus(this.openState ? 0 : -1);
        }
    }
    /**
     * @hidden
     */
    onItemClick(index) {
        this.emitItemClickHandler(index);
        this.togglePopupVisibility();
        if (isDocumentAvailable() && !this.isClosePrevented) {
            this.focusButton();
        }
    }
    ngOnDestroy() {
        this.openState = false;
        this.subs.unsubscribe();
        this.destroyPopup();
    }
    subscribeEvents() {
        if (!isDocumentAvailable()) {
            return;
        }
        this.subscribeListItemFocusEvent();
        this.subscribeComponentBlurredEvent();
        this.subscribeNavigationEvents();
    }
    subscribeListItemFocusEvent() {
        this.subs.add(this.focusService.onFocus.subscribe(() => {
            this._isFocused = true;
        }));
    }
    subscribeComponentBlurredEvent() {
        this._zone.runOutsideAngular(() => {
            this.subs.add(this.navigationService.tab.pipe(filter(() => this._isFocused), tap(() => this.focusButton())).subscribe(this.handleTab.bind(this)));
            this.subs.add(fromEvent(document, 'click')
                .pipe(filter((event) => !this.wrapperContains(event.target)), filter(() => this._isFocused))
                .subscribe(() => this._zone.run(() => this.blurWrapper())));
        });
    }
    subscribeNavigationEvents() {
        this.subs.add(this.navigationService.navigate
            .subscribe(this.onArrowKeyNavigate.bind(this)));
        this.subs.add(this.navigationService.enterup.subscribe(this.onNavigationEnterUp.bind(this)));
        this.subs.add(this.navigationService.open.subscribe(this.onNavigationOpen.bind(this)));
        this.subs.add(merge(this.navigationService.close, this.navigationService.esc).subscribe(this.onNavigationClose.bind(this)));
    }
    /**
     * Toggles the visibility of the popup.
     * If the `toggle` method is used to open or close the popup, the `open` and `close` events will not be fired.
     *
     * @param open - The state of the popup.
     */
    toggle(open) {
        if (this.disabled) {
            return;
        }
        const value = open === undefined ? !this.openState : open;
        this._toggle(value, false);
    }
    /**
     * @hidden
     */
    keyDownHandler(event, isHost) {
        this.keyHandler(event, null, isHost);
    }
    /**
     * @hidden
     */
    keyUpHandler(event) {
        this.keyHandler(event, KeyEvents.keyup);
    }
    /**
     * @hidden
     */
    keyHandler(event, keyEvent, isHost) {
        if (this._disabled) {
            return;
        }
        const eventData = event;
        if (!isHost) {
            eventData.stopImmediatePropagation();
        }
        const focused = this.focusService.focused || 0;
        const action = this.navigationService.process({
            altKey: eventData.altKey,
            current: focused,
            keyCode: eventData.keyCode,
            keyEvent: keyEvent,
            max: this._data ? this._data.length - 1 : 0,
            min: 0,
            target: event.target
        });
        if (action !== NavigationAction.Undefined &&
            action !== NavigationAction.Tab &&
            (action !== NavigationAction.Enter || (action === NavigationAction.Enter && this.openState))) {
            if (!(event.keyCode === Keys.Space && action === NavigationAction.EnterUp)) {
                eventData.preventDefault();
            }
        }
    }
    emitItemClickHandler(index) {
        const dataItem = this._data[index];
        if (this._itemClick && !dataItem.disabled) {
            this._itemClick.emit(dataItem);
        }
        if (dataItem && dataItem.click && !dataItem.disabled) {
            dataItem.click(dataItem);
        }
        this.focusService.focus(index);
    }
    focusWrapper() {
        if (this.openState) {
            this.togglePopupVisibility();
            this.focusButton();
        }
    }
    wrapperContains(element) {
        return this.wrapper === element || this.wrapper.contains(element);
    }
    blurWrapper(emit = true) {
        if (!this._isFocused) {
            return;
        }
        if (this.openState) {
            this.togglePopupVisibility();
        }
        this._isFocused = false;
        if (emit) {
            this._blur.emit();
            this.cdr.markForCheck();
        }
    }
    focusButton() {
        if (this.button) {
            this.button.nativeElement.focus();
        }
    }
    handleTab() {
        this.blurWrapper();
    }
    onNavigationEnterUp(_args) {
        if (!this._disabled && !this.openState) {
            this._active = false;
        }
        if (this.openState) {
            const focused = this.focusService.focused;
            if (isPresent(focused) && focused !== -1) {
                this.emitItemClickHandler(focused);
            }
        }
        this.togglePopupVisibility();
        if (!this.openState && isDocumentAvailable()) {
            this.button.nativeElement.focus();
        }
    }
    onNavigationOpen() {
        if (!this._disabled && !this.openState) {
            this.togglePopupVisibility();
        }
    }
    onNavigationClose(e) {
        if (this.openState && !this.isClosePrevented) {
            this.togglePopupVisibility();
            if (isDocumentAvailable()) {
                e?.esc && hasObservers(this.escape) && this.escape.emit();
                this.button.nativeElement.focus();
            }
        }
    }
    onArrowKeyNavigate({ index }) {
        this.focusService.focus(index);
    }
    _toggle(open, emitEvent) {
        if (this.openState === open) {
            return;
        }
        const eventArgs = new PreventableEvent();
        if (emitEvent) {
            if (open && !this.openState) {
                this.open.emit(eventArgs);
            }
            else if (!open && this.openState) {
                this.close.emit(eventArgs);
            }
            if (eventArgs.isDefaultPrevented()) {
                this.isClosePrevented = true;
                return;
            }
        }
        this.openState = open;
        this.destroyPopup();
        if (this.openState) {
            this.createPopup();
        }
    }
    createPopup() {
        this.popupRef = this.popupService.open({
            anchor: this.elRef,
            anchorAlign: this.anchorAlign,
            animate: this.popupSettings.animate,
            appendTo: this.appendTo,
            content: this.containerService.template,
            popupAlign: this.popupAlign,
            popupClass: this.popupClasses
        });
        this.popupSubs = this.popupRef.popupAnchorViewportLeave.subscribe(() => {
            this.togglePopupVisibility();
        });
    }
    destroyPopup() {
        if (this.popupRef) {
            this.popupRef.close();
            this.popupRef = null;
            this.popupSubs.unsubscribe();
            this.isClosePrevented = false;
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ListButton, deps: [{ token: FocusService }, { token: NavigationService }, { token: i0.ElementRef }, { token: i0.NgZone }, { token: i3.PopupService }, { token: i0.ElementRef }, { token: i1.LocalizationService }, { token: i0.ChangeDetectorRef }, { token: PopupContainerService }], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ListButton, selector: "ng-component", inputs: { disabled: "disabled", tabIndex: "tabIndex", buttonClass: "buttonClass", popupSettings: "popupSettings" }, outputs: { open: "open", close: "close", escape: "escape" }, viewQueries: [{ propertyName: "button", first: true, predicate: ["button"], descendants: true, read: ElementRef }, { propertyName: "buttonList", first: true, predicate: ["buttonList"], descendants: true }, { propertyName: "popupTemplate", first: true, predicate: ["popupTemplate"], descendants: true }, { propertyName: "container", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: '', isInline: true });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ListButton, decorators: [{
            type: Component,
            args: [{
                    template: ''
                }]
        }], ctorParameters: function () { return [{ type: FocusService }, { type: NavigationService }, { type: i0.ElementRef }, { type: i0.NgZone }, { type: i3.PopupService }, { type: i0.ElementRef }, { type: i1.LocalizationService }, { type: i0.ChangeDetectorRef }, { type: PopupContainerService }]; }, propDecorators: { button: [{
                type: ViewChild,
                args: ['button', { read: ElementRef }]
            }], buttonList: [{
                type: ViewChild,
                args: ['buttonList']
            }], popupTemplate: [{
                type: ViewChild,
                args: ['popupTemplate']
            }], container: [{
                type: ViewChild,
                args: ['container', { read: ViewContainerRef }]
            }], disabled: [{
                type: Input
            }], tabIndex: [{
                type: Input
            }], buttonClass: [{
                type: Input
            }], open: [{
                type: Output
            }], close: [{
                type: Output
            }], escape: [{
                type: Output
            }], popupSettings: [{
                type: Input
            }] } });

const NAVIGATION_SETTINGS$2 = {
    useLeftRightArrows: true
};
const NAVIGATION_SETTINGS_PROVIDER$2 = {
    provide: NAVIGATION_CONFIG,
    useValue: NAVIGATION_SETTINGS$2
};
const DEFAULT_FILL_MODE$1 = 'solid';
/**
 * Represents the Kendo UI DropDownButton component for Angular.
 *
 * @example
 * ```ts
 * _@Component({
 * selector: 'my-app',
 * template: `
 *  <kendo-dropdownbutton [data]="data">
 *    User Settings
 *  </kendo-dropdownbutton>
 * `
 * })
 * class AppComponent {
 *   public data: Array<any> = [{
 *       text: 'My Profile'
 *   }, {
 *       text: 'Friend Requests'
 *   }, {
 *       text: 'Account Settings'
 *   }, {
 *       text: 'Support'
 *   }, {
 *       text: 'Log Out'
 *   }];
 * }
 * ```
 */
class DropDownButtonComponent extends ListButton {
    containerService;
    renderer;
    /**
     * Allows showing the default arrow icon or providing alternative one instead.
     * @default false
     */
    arrowIcon = false;
    /**
     * Defines the name of an existing icon in the Kendo UI theme.
     */
    icon = '';
    /**
     * Defines an [`SVGIcon`](slug:api_icons_svgicon) to be rendered within the button.
     */
    svgIcon;
    /**
     * Defines the list of CSS classes which are used for styling the Button with custom icons.
     */
    iconClass = '';
    /**
     * Defines a URL for styling the button with a custom image.
     */
    imageUrl = '';
    /**
     * Sets the data item field that represents the item text.
     * If the data contains only primitive values, do not define it.
     */
    textField;
    /**
     * Sets or gets the data of the DropDownButton.
     *
     * > The data has to be provided in an array-like list.
     */
    set data(data) {
        this._data = data || [];
    }
    get data() {
        return this._data;
    }
    /**
     * The size property specifies the padding of the DropDownButton
     * ([see example]({% slug api_buttons_dropdownbuttoncomponent %}#toc-size)).
     *
     * The possible values are:
     * * `small`
     * * `medium` (default)
     * * `large`
     * * `none`
     */
    size = 'medium';
    /**
     * The rounded property specifies the border radius of the DropDownButton
     * ([see example]({% slug api_buttons_dropdownbuttoncomponent %}#toc-rounded)).
     *
     * The possible values are:
     * * `small`
     * * `medium` (default)
     * * `large`
     * * `full`
     * * `none`
     */
    rounded = 'medium';
    /**
     * The fillMode property specifies the background and border styles of the DropDownButton
     * ([see example]({% slug api_buttons_dropdownbuttoncomponent %}#toc-fillMode)).
     *
     * The available values are:
     * * `solid` (default)
     * * `flat`
     * * `outline`
     * * `link`
     * * `none`
     */
    set fillMode(fillMode) {
        this._fillMode = fillMode === 'clear' ? 'flat' : fillMode;
    }
    get fillMode() {
        return this._fillMode;
    }
    /**
     * The DropDownButton allows you to specify predefined theme colors.
     * The theme color will be applied as a background and border color while also amending the text color accordingly
     * ([see example]({% slug api_buttons_dropdownbuttoncomponent %}#toc-themeColor)).
     *
     * The possible values are:
     * * `base` &mdash;Applies coloring based on the `base` theme color. (default)
     * * `primary` &mdash;Applies coloring based on the `primary` theme color.
     * * `secondary`&mdash;Applies coloring based on the `secondary` theme color.
     * * `tertiary`&mdash; Applies coloring based on the `tertiary` theme color.
     * * `info`&mdash;Applies coloring based on the `info` theme color.
     * * `success`&mdash; Applies coloring based on the `success` theme color.
     * * `warning`&mdash; Applies coloring based on the `warning` theme color.
     * * `error`&mdash; Applies coloring based on the `error` theme color.
     * * `dark`&mdash; Applies coloring based on the `dark` theme color.
     * * `light`&mdash; Applies coloring based on the `light` theme color.
     * * `inverse`&mdash; Applies coloring based on the `inverse` theme color.
     * * `none` &mdash;Removes the default CSS class (no class would be rendered).
     */
    themeColor = 'base';
    /**
     * Sets attributes to the main button.
     */
    set buttonAttributes(buttonAttributes) {
        const newButtonAttributes = buttonAttributes ? buttonAttributes : null;
        this.handleButtonAttributes(newButtonAttributes);
        this._buttonAttributes = newButtonAttributes;
    }
    get buttonAttributes() {
        return this._buttonAttributes;
    }
    /**
     * Fires each time the user clicks on a drop-down list item. The event data contains the data item bound to the clicked list item.
     */
    itemClick = new EventEmitter();
    /**
     * Fires each time the DropDownButton gets focused.
     */
    onFocus = new EventEmitter();
    /**
     * Fires each time the DropDownButton gets blurred.
     */
    onBlur = new EventEmitter();
    get focused() {
        return this._isFocused && !this._disabled;
    }
    hostDisplayStyle = 'inline-flex';
    get dir() {
        return this.direction;
    }
    /**
     * @hidden
     */
    get active() {
        return this._active;
    }
    itemTemplate;
    _fillMode = DEFAULT_FILL_MODE$1;
    _buttonAttributes = null;
    documentMouseUpSub;
    /**
     * @hidden
     */
    keydown(event) {
        this.keyDownHandler(event, true);
        if (event.keyCode === Keys.Space || event.keyCode === Keys.Enter) {
            this._active = true;
        }
        if (event.keyCode === Keys.Enter) {
            event.preventDefault();
        }
    }
    /**
     * @hidden
     */
    keyup(event) {
        this.keyUpHandler(event);
        this._active = false;
    }
    /**
     * @hidden
     */
    mousedown(event) {
        if (this._disabled) {
            event.preventDefault();
        }
        else {
            this._active = true;
        }
    }
    /**
     * @hidden
     */
    mouseup(event) {
        if (this._disabled) {
            event.preventDefault();
        }
        this._active = false;
    }
    /**
     * @hidden
     */
    openPopup() {
        this._isFocused = true;
        this.togglePopupVisibility();
    }
    /**
     * @hidden
     */
    onButtonBlur() {
        if (!this.openState) {
            this.blurWrapper();
        }
    }
    /**
     * Focuses the DropDownButton component.
     */
    focus() {
        if (isDocumentAvailable()) {
            this.button.nativeElement.focus();
        }
    }
    /**
     * Blurs the DropDownButton component.
     */
    blur() {
        if (isDocumentAvailable()) {
            this.button.nativeElement.blur();
            this.blurWrapper();
        }
    }
    constructor(focusService, navigationService, wrapperRef, zone, popupService, elRef, localization, cdr, containerService, renderer) {
        super(focusService, navigationService, wrapperRef, zone, popupService, elRef, localization, cdr, containerService);
        this.containerService = containerService;
        this.renderer = renderer;
        this._itemClick = this.itemClick;
        this._blur = this.onBlur;
        zone.runOutsideAngular(() => {
            this.documentMouseUpSub = this.renderer.listen('document', 'mouseup', () => {
                if (this.active) {
                    zone.run(() => this._active = false);
                }
            });
        });
    }
    ngAfterViewInit() {
        this.containerService.container = this.container;
        this.containerService.template = this.popupTemplate;
        this.handleButtonAttributes(this.buttonAttributes);
        const arrowWrapper = this.button.nativeElement.querySelector('.k-button-arrow');
        if (arrowWrapper) {
            this.renderer.addClass(arrowWrapper, 'k-menu-button-arrow');
        }
    }
    /**
     * @hidden
     */
    handleFocus(event) {
        if (!this._disabled) {
            // eslint-disable-next-line no-unused-expressions
            !this._isFocused && this.onFocus.emit();
            this._isFocused = true;
            this.focusService.resetFocus();
            const relatedTargetInList = event.relatedTarget && closest(event.relatedTarget, '.k-popup kendo-button-list');
            if (this.openState && !relatedTargetInList) {
                this.focusService.focus(0);
            }
        }
    }
    /**
     * @hidden
     */
    wrapperContains(element) {
        return this.wrapper === element
            || this.wrapper.contains(element)
            || (this.popupRef && this.popupRef.popupElement.contains(element));
    }
    handleButtonAttributes(newButtonAttributes) {
        const mainButton = this.button?.nativeElement;
        if (isPresent$1(this.buttonAttributes) && isPresent$1(mainButton)) {
            for (const attr in this.buttonAttributes) {
                this.renderer.removeAttribute(mainButton, attr, this.buttonAttributes[attr]);
            }
        }
        if (isPresent$1(newButtonAttributes) && isPresent$1(mainButton)) {
            for (const attr in newButtonAttributes) {
                this.renderer.setAttribute(mainButton, attr, newButtonAttributes[attr]);
            }
        }
    }
    /**
     * @hidden
     */
    ngOnDestroy() {
        if (this.documentMouseUpSub) {
            this.documentMouseUpSub();
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DropDownButtonComponent, deps: [{ token: FocusService }, { token: NavigationService }, { token: i0.ElementRef }, { token: i0.NgZone }, { token: i3.PopupService }, { token: i0.ElementRef }, { token: i1.LocalizationService }, { token: i0.ChangeDetectorRef }, { token: PopupContainerService }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DropDownButtonComponent, isStandalone: true, selector: "kendo-dropdownbutton", inputs: { arrowIcon: "arrowIcon", icon: "icon", svgIcon: "svgIcon", iconClass: "iconClass", imageUrl: "imageUrl", textField: "textField", data: "data", size: "size", rounded: "rounded", fillMode: "fillMode", themeColor: "themeColor", buttonAttributes: "buttonAttributes" }, outputs: { itemClick: "itemClick", onFocus: "focus", onBlur: "blur" }, host: { listeners: { "keydown": "keydown($event)", "keyup": "keyup($event)", "mousedown": "mousedown($event)", "mouseup": "mouseup($event)" }, properties: { "class.k-focus": "this.focused", "style.display": "this.hostDisplayStyle", "attr.dir": "this.dir" } }, providers: [
            FocusService,
            NavigationService,
            NAVIGATION_SETTINGS_PROVIDER$2,
            LocalizationService,
            {
                provide: L10N_PREFIX,
                useValue: 'kendo.dropdownbutton'
            },
            PopupContainerService
        ], queries: [{ propertyName: "itemTemplate", first: true, predicate: ButtonItemTemplateDirective, descendants: true }], exportAs: ["kendoDropDownButton"], usesInheritance: true, ngImport: i0, template: `
        <button kendoButton #button
            type="button"
            [id]="buttonId"
            [tabindex]="componentTabIndex"
            class="k-menu-button"
            [class.k-active]="active"
            [disabled]="disabled"
            [icon]="icon"
            [svgIcon]="svgIcon"
            [arrowIcon]="arrowIcon"
            [iconClass]="iconClass"
            [imageUrl]="imageUrl"
            [ngClass]="buttonClass"
            [size]="size"
            [rounded]="rounded"
            [fillMode]="fillMode"
            [themeColor]="fillMode ? themeColor : null"
            (click)="openPopup()"
            (focus)="handleFocus($event)"
            (blur)="onButtonBlur()"
            [attr.aria-disabled]="disabled"
            [attr.aria-expanded]="openState"
            [attr.aria-controls]="listId"
        >
            <ng-content></ng-content>
        </button>
        <ng-template #popupTemplate>
            <kendo-button-list
                #buttonList
                [id]="listId"
                [data]="data"
                [textField]="textField"
                [itemTemplate]="itemTemplate"
                (onItemClick)="onItemClick($event)"
                (keydown)="keyDownHandler($event)"
                (keyup)="keyUpHandler($event)"
                [attr.dir]="dir"
                [attr.aria-labelledby]="buttonId"
                [size]="size"
            >
            </kendo-button-list>
        </ng-template>
        <ng-container #container></ng-container>
    `, isInline: true, dependencies: [{ kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ListComponent, selector: "kendo-button-list", inputs: ["data", "textField", "itemTemplate", "size"], outputs: ["onItemClick", "onItemBlur"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DropDownButtonComponent, decorators: [{
            type: Component,
            args: [{
                    exportAs: 'kendoDropDownButton',
                    providers: [
                        FocusService,
                        NavigationService,
                        NAVIGATION_SETTINGS_PROVIDER$2,
                        LocalizationService,
                        {
                            provide: L10N_PREFIX,
                            useValue: 'kendo.dropdownbutton'
                        },
                        PopupContainerService
                    ],
                    selector: 'kendo-dropdownbutton',
                    template: `
        <button kendoButton #button
            type="button"
            [id]="buttonId"
            [tabindex]="componentTabIndex"
            class="k-menu-button"
            [class.k-active]="active"
            [disabled]="disabled"
            [icon]="icon"
            [svgIcon]="svgIcon"
            [arrowIcon]="arrowIcon"
            [iconClass]="iconClass"
            [imageUrl]="imageUrl"
            [ngClass]="buttonClass"
            [size]="size"
            [rounded]="rounded"
            [fillMode]="fillMode"
            [themeColor]="fillMode ? themeColor : null"
            (click)="openPopup()"
            (focus)="handleFocus($event)"
            (blur)="onButtonBlur()"
            [attr.aria-disabled]="disabled"
            [attr.aria-expanded]="openState"
            [attr.aria-controls]="listId"
        >
            <ng-content></ng-content>
        </button>
        <ng-template #popupTemplate>
            <kendo-button-list
                #buttonList
                [id]="listId"
                [data]="data"
                [textField]="textField"
                [itemTemplate]="itemTemplate"
                (onItemClick)="onItemClick($event)"
                (keydown)="keyDownHandler($event)"
                (keyup)="keyUpHandler($event)"
                [attr.dir]="dir"
                [attr.aria-labelledby]="buttonId"
                [size]="size"
            >
            </kendo-button-list>
        </ng-template>
        <ng-container #container></ng-container>
    `,
                    standalone: true,
                    imports: [ButtonComponent, NgClass, ListComponent]
                }]
        }], ctorParameters: function () { return [{ type: FocusService }, { type: NavigationService }, { type: i0.ElementRef }, { type: i0.NgZone }, { type: i3.PopupService }, { type: i0.ElementRef }, { type: i1.LocalizationService }, { type: i0.ChangeDetectorRef }, { type: PopupContainerService }, { type: i0.Renderer2 }]; }, propDecorators: { arrowIcon: [{
                type: Input
            }], icon: [{
                type: Input
            }], svgIcon: [{
                type: Input
            }], iconClass: [{
                type: Input
            }], imageUrl: [{
                type: Input
            }], textField: [{
                type: Input
            }], data: [{
                type: Input
            }], size: [{
                type: Input
            }], rounded: [{
                type: Input
            }], fillMode: [{
                type: Input
            }], themeColor: [{
                type: Input
            }], buttonAttributes: [{
                type: Input
            }], itemClick: [{
                type: Output
            }], onFocus: [{
                type: Output,
                args: ['focus']
            }], onBlur: [{
                type: Output,
                args: ['blur']
            }], focused: [{
                type: HostBinding,
                args: ['class.k-focus']
            }], hostDisplayStyle: [{
                type: HostBinding,
                args: ['style.display']
            }], dir: [{
                type: HostBinding,
                args: ['attr.dir']
            }], itemTemplate: [{
                type: ContentChild,
                args: [ButtonItemTemplateDirective]
            }], keydown: [{
                type: HostListener,
                args: ['keydown', ['$event']]
            }], keyup: [{
                type: HostListener,
                args: ['keyup', ['$event']]
            }], mousedown: [{
                type: HostListener,
                args: ['mousedown', ['$event']]
            }], mouseup: [{
                type: HostListener,
                args: ['mouseup', ['$event']]
            }] } });

/**
 * @hidden
 */
function getAnchorAlign(fabAlign, rtl) {
    const align = { horizontal: (rtl ? 'right' : 'left'), vertical: 'bottom' };
    if (fabAlign.horizontal === 'end') {
        align.horizontal = rtl ? 'left' : 'right';
    }
    if (fabAlign.vertical === 'bottom') {
        align.vertical = 'top';
    }
    if (fabAlign.vertical === 'bottom' && fabAlign.horizontal === 'end') {
        align.horizontal = rtl ? 'left' : 'right';
        align.vertical = 'top';
    }
    return align;
}
/**
 * @hidden
 */
function getPopupAlign(fabAlign, rtl) {
    const align = { horizontal: (rtl ? 'right' : 'left'), vertical: 'top' };
    if (fabAlign.horizontal === 'end') {
        align.horizontal = rtl ? 'left' : 'right';
    }
    if (fabAlign.vertical === 'bottom') {
        align.vertical = 'bottom';
    }
    if (fabAlign.vertical === 'bottom' && fabAlign.horizontal === 'end') {
        align.horizontal = rtl ? 'left' : 'right';
        align.vertical = 'bottom';
    }
    return align;
}

/**
 * @hidden
 */
function openAnimation(animationSettings) {
    const isBottom = animationSettings.align.vertical === 'bottom';
    const duration = animationSettings.duration;
    const gap = animationSettings.gap;
    return sequence([
        query(`.k-fab-item`, [
            style({ opacity: 0, transform: `translateY(${isBottom ? '8px' : '-8px'})` }),
            stagger(gap, [animate(`${duration}ms ease-in`, style({ opacity: '*', transform: 'translateY(0)' }))])
        ], { optional: true })
    ]);
}
/**
 * @hidden
 */
function closeAnimation(animationSettings) {
    const isBottom = animationSettings.align.vertical === 'bottom';
    const duration = animationSettings.duration;
    const gap = animationSettings.gap;
    return sequence([
        query(`.k-fab-item`, [
            style({ opacity: '*', transform: 'translateY(0)' }),
            stagger(-gap, [animate(`${duration}ms ease-in`, style({ opacity: 0, transform: `translateY(${isBottom ? '8px' : '-8px'})` }))])
        ], { optional: true })
    ]);
}

/**
 * Represents a template that defines the content of the whole dial item.
 * To define the template, nest an `<ng-template>` tag
 * with the `kendoDialItemTemplate` directive inside the `<kendo-floatingactionbutton>` tag
 * ([see example]({% slug templates_floatingactionbutton %}#toc-dial-item-template)).
 */
class DialItemTemplateDirective {
    templateRef;
    constructor(templateRef) {
        this.templateRef = templateRef;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DialItemTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: DialItemTemplateDirective, isStandalone: true, selector: "[kendoDialItemTemplate]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DialItemTemplateDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[kendoDialItemTemplate]',
                    standalone: true
                }]
        }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
                    type: Optional
                }] }]; } });

/**
 * Represents a template that defines the content of the FloatingActionButton.
 * To define the template, nest an `<ng-template>` tag
 * with the `kendoFloatingActionButtonTemplate` directive inside the `<kendo-floatingactionbutton>` tag
 * ([see example]({% slug templates_floatingactionbutton %}#toc-floatingactionbutton-template)).
 */
class FloatingActionButtonTemplateDirective {
    templateRef;
    constructor(templateRef) {
        this.templateRef = templateRef;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FloatingActionButtonTemplateDirective, deps: [{ token: i0.TemplateRef, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: FloatingActionButtonTemplateDirective, isStandalone: true, selector: "[kendoFloatingActionButtonTemplate]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FloatingActionButtonTemplateDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[kendoFloatingActionButtonTemplate]',
                    standalone: true
                }]
        }], ctorParameters: function () { return [{ type: i0.TemplateRef, decorators: [{
                    type: Optional
                }] }]; } });

/**
 * @hidden
 */
class DialItemComponent {
    element;
    renderer;
    localisationService;
    hostClass = true;
    role = 'menuitem';
    get disabledClass() {
        return this.item.disabled;
    }
    get title() {
        const label = this.item.label;
        return label || this.itemTitle;
    }
    get indexAttr() {
        return this.index;
    }
    cssClass;
    cssStyle;
    isFocused;
    index;
    item;
    dialItemTemplate;
    align;
    constructor(element, renderer, localisationService) {
        this.element = element;
        this.renderer = renderer;
        this.localisationService = localisationService;
    }
    get iconClasses() {
        const classes = [];
        if (this.item.iconClass) {
            classes.push(`${this.item.iconClass}`);
        }
        if (this.item.icon) {
            classes.push(`k-fab-item-icon k-icon k-i-${this.item.icon}`);
        }
        return classes;
    }
    get itemTitle() {
        const icon = this.item.icon;
        const itemTitle = this.item.itemTitle;
        return (icon && itemTitle) ? itemTitle : icon;
    }
    ngAfterViewInit() {
        const element = this.element.nativeElement;
        const rtl = this.localisationService.rtl;
        const hAlign = this.align.horizontal;
        this.renderer.addClass(element, this.getTextDirectionClass(rtl, hAlign));
    }
    getTextDirectionClass(rtl, hAlign) {
        const dir = rtl ? 'rtl' : 'ltr';
        const align = hAlign === 'end' ? 'end' : 'start';
        const directions = {
            rtl: { end: 'k-text-left', start: 'k-text-right' },
            ltr: { start: 'k-text-left', end: 'k-text-right' }
        };
        return directions[dir][align];
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DialItemComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DialItemComponent, isStandalone: true, selector: "[kendoDialItem]", inputs: { cssClass: "cssClass", cssStyle: "cssStyle", isFocused: "isFocused", index: "index", item: "item", dialItemTemplate: "dialItemTemplate", align: "align" }, host: { properties: { "class.k-fab-item": "this.hostClass", "attr.role": "this.role", "attr.aria-disabled": "this.disabledClass", "class.k-disabled": "this.disabledClass", "attr.title": "this.title", "attr.aria-label": "this.title", "attr.data-fab-item-index": "this.indexAttr" } }, ngImport: i0, template: `
        <ng-template *ngIf="dialItemTemplate"
            [ngTemplateOutlet]="dialItemTemplate"
            [ngTemplateOutletContext]="{ $implicit: item, index: index, isFocused: isFocused }"
        >
        </ng-template>

        <ng-container *ngIf="!dialItemTemplate">
            <span *ngIf="item.label" class="k-fab-item-text">{{ item.label }}</span>
            <kendo-icon-wrapper
                *ngIf="item.icon || item.iconClass || item.svgIcon"
                [name]="item.icon"
                innerCssClass="k-fab-item-icon"
                [customFontClass]="item.iconClass"
                [svgIcon]="item.svgIcon"></kendo-icon-wrapper>
        </ng-container>
    `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DialItemComponent, decorators: [{
            type: Component,
            args: [{
                    // eslint-disable-next-line @angular-eslint/component-selector
                    selector: '[kendoDialItem]',
                    template: `
        <ng-template *ngIf="dialItemTemplate"
            [ngTemplateOutlet]="dialItemTemplate"
            [ngTemplateOutletContext]="{ $implicit: item, index: index, isFocused: isFocused }"
        >
        </ng-template>

        <ng-container *ngIf="!dialItemTemplate">
            <span *ngIf="item.label" class="k-fab-item-text">{{ item.label }}</span>
            <kendo-icon-wrapper
                *ngIf="item.icon || item.iconClass || item.svgIcon"
                [name]="item.icon"
                innerCssClass="k-fab-item-icon"
                [customFontClass]="item.iconClass"
                [svgIcon]="item.svgIcon"></kendo-icon-wrapper>
        </ng-container>
    `,
                    standalone: true,
                    imports: [NgIf, NgTemplateOutlet, IconWrapperComponent]
                }]
        }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1.LocalizationService }]; }, propDecorators: { hostClass: [{
                type: HostBinding,
                args: ['class.k-fab-item']
            }], role: [{
                type: HostBinding,
                args: ['attr.role']
            }], disabledClass: [{
                type: HostBinding,
                args: ['attr.aria-disabled']
            }, {
                type: HostBinding,
                args: ['class.k-disabled']
            }], title: [{
                type: HostBinding,
                args: ['attr.title']
            }, {
                type: HostBinding,
                args: ['attr.aria-label']
            }], indexAttr: [{
                type: HostBinding,
                args: ['attr.data-fab-item-index']
            }], cssClass: [{
                type: Input
            }], cssStyle: [{
                type: Input
            }], isFocused: [{
                type: Input
            }], index: [{
                type: Input
            }], item: [{
                type: Input
            }], dialItemTemplate: [{
                type: Input
            }], align: [{
                type: Input
            }] } });

/**
 * @hidden
 */
class DialListComponent {
    focusService;
    cdr;
    hostClass = true;
    get bottomClass() {
        return this.align.vertical === 'top' || this.align.vertical === 'middle';
    }
    get topClass() {
        return this.align.vertical === 'bottom';
    }
    dialItems;
    dialItemTemplate;
    align;
    subscriptions = new Subscription();
    constructor(focusService, cdr) {
        this.focusService = focusService;
        this.cdr = cdr;
        this.subscriptions.add(this.focusService.onFocus.subscribe(() => this.cdr.detectChanges()));
    }
    isFocused(index) {
        return this.focusService.isFocused(index);
    }
    ngOnDestroy() {
        this.subscriptions.unsubscribe();
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DialListComponent, deps: [{ token: FocusService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DialListComponent, isStandalone: true, selector: "[kendoDialList]", inputs: { dialItems: "dialItems", dialItemTemplate: "dialItemTemplate", align: "align" }, host: { properties: { "class.k-fab-items": "this.hostClass", "class.k-fab-items-bottom": "this.bottomClass", "class.k-fab-items-top": "this.topClass" } }, ngImport: i0, template: `
        <ng-container *ngFor='let item of dialItems; let idx = index'>
            <li
                kendoButtonFocusable
                kendoDialItem
                [item]="dialItems[idx]"
                [index]="idx"
                [dialItemTemplate]="dialItemTemplate"
                [isFocused]="isFocused(idx)"
                [ngClass]='item.cssClass'
                [ngStyle]='item.cssStyle'
                [align]="align"
            >
            </li>
        </ng-container>
    `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: FocusableDirective, selector: "[kendoButtonFocusable]", inputs: ["index"] }, { kind: "component", type: DialItemComponent, selector: "[kendoDialItem]", inputs: ["cssClass", "cssStyle", "isFocused", "index", "item", "dialItemTemplate", "align"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DialListComponent, decorators: [{
            type: Component,
            args: [{
                    // eslint-disable-next-line @angular-eslint/component-selector
                    selector: '[kendoDialList]',
                    template: `
        <ng-container *ngFor='let item of dialItems; let idx = index'>
            <li
                kendoButtonFocusable
                kendoDialItem
                [item]="dialItems[idx]"
                [index]="idx"
                [dialItemTemplate]="dialItemTemplate"
                [isFocused]="isFocused(idx)"
                [ngClass]='item.cssClass'
                [ngStyle]='item.cssStyle'
                [align]="align"
            >
            </li>
        </ng-container>
    `,
                    standalone: true,
                    imports: [NgFor, FocusableDirective, DialItemComponent, NgClass, NgStyle]
                }]
        }], ctorParameters: function () { return [{ type: FocusService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { hostClass: [{
                type: HostBinding,
                args: ['class.k-fab-items']
            }], bottomClass: [{
                type: HostBinding,
                args: ['class.k-fab-items-bottom']
            }], topClass: [{
                type: HostBinding,
                args: ['class.k-fab-items-top']
            }], dialItems: [{
                type: Input
            }], dialItemTemplate: [{
                type: Input
            }], align: [{
                type: Input
            }] } });

const NAVIGATION_SETTINGS$1 = {
    useLeftRightArrows: false
};
const NAVIGATION_SETTINGS_PROVIDER$1 = {
    provide: NAVIGATION_CONFIG,
    useValue: NAVIGATION_SETTINGS$1
};
const SIZE_CLASSES = {
    small: 'k-fab-sm',
    medium: 'k-fab-md',
    large: 'k-fab-lg'
};
const ROUNDED_CLASSES = {
    small: 'k-rounded-sm',
    medium: 'k-rounded-md',
    large: 'k-rounded-lg',
    full: 'k-rounded-full'
};
const FILLMODE_CLASS = 'k-fab-solid';
const DEFAULT_DURATION = 180;
const DEFAULT_ITEM_GAP = 90;
const DEFAULT_OFFSET = '16px';
const DEFAULT_ROUNDED$1 = 'full';
const DEFAULT_SIZE = 'medium';
const DEFAULT_THEME_COLOR = 'primary';
/**
 *
 * Represents the [Kendo UI FloatingActionButton component for Angular]({% slug overview_floatingactionbutton %}).
 * Used to specify the primary or the most common action in an application.
 *
 */
class FloatingActionButtonComponent {
    renderer;
    element;
    focusService;
    navigationService;
    ngZone;
    popupService;
    builder;
    localizationService;
    get fixedClass() {
        return this.positionMode === 'fixed';
    }
    get absoluteClass() {
        return this.positionMode === 'absolute';
    }
    direction;
    button;
    popupTemplate;
    dialItemTemplate;
    fabTemplate;
    /**
     * Specifies the theme color of the FloatingActionButton
     * ([see example](slug:appearance_floatingactionbutton#toc-theme-colors)).
     * The theme color will be applied as background color of the component.
     *
     * The possible values are:
     * * `primary` (Default)&mdash;Applies coloring based on the `primary` theme color.
     * * `secondary`&mdash;Applies coloring based on the `secondary` theme color.
     * * `tertiary`&mdash; Applies coloring based on the `tertiary` theme color.
     * * `info`&mdash;Applies coloring based on the `info` theme color.
     * * `success`&mdash; Applies coloring based on the `success` theme color.
     * * `warning`&mdash; Applies coloring based on the `warning` theme color.
     * * `error`&mdash; Applies coloring based on the `error` theme color.
     * * `dark`&mdash; Applies coloring based on the `dark` theme color.
     * * `light`&mdash; Applies coloring based on the `light` theme color.
     * * `inverse`&mdash; Applies coloring based on the `inverse` theme color.
     * * `none`&mdash; Removes the built in theme color.
     */
    set themeColor(themeColor) {
        const newThemeColor = themeColor ? themeColor : DEFAULT_THEME_COLOR;
        this.handleClasses(newThemeColor, 'themeColor');
        this._themeColor = newThemeColor;
    }
    get themeColor() {
        return this._themeColor;
    }
    /**
     * Specifies the size of the FloatingActionButton
     * ([see example]({% slug appearance_floatingactionbutton %}#toc-size)).
     *
     * The possible values are:
     * * `small`
     * * `medium` (Default)
     * * `large`
     * * `none`
     */
    set size(size) {
        const newSize = size ? size : DEFAULT_SIZE;
        this.handleClasses(newSize, 'size');
        this._size = newSize;
    }
    get size() {
        return this._size;
    }
    /**
     * The rounded property specifies the border radius of the FloatingActionButton.
     *
     * The possible values are:
     * * `small`
     * * `medium`
     * * `large`
     * * `full` (default)
     * * `none`
     */
    set rounded(rounded) {
        const newRounded = rounded ? rounded : DEFAULT_ROUNDED$1;
        this.handleClasses(newRounded, 'rounded');
        this._rounded = newRounded;
    }
    get rounded() {
        return this._rounded;
    }
    /**
     * Specifies whether the FloatingActionButton is disabled.
     */
    set disabled(disabled) {
        this._disabled = disabled;
    }
    get disabled() {
        return this._disabled;
    }
    /**
     * Specifies the horizontal and vertical alignment of the FloatingActionButton
     * ([see example](slug:positioning_floatingactionbutton#toc-alignment)).
     *
     * The possible values are:
     * * `{ horizontal: 'start'|'center'|'end', vertical: 'top'|'middle'|'bottom' }`
     *
     * The default value is:
     * * `{ horizontal: 'end', vertical: 'bottom' }`
     *
     */
    set align(align) {
        this._align = Object.assign(this._align, align);
    }
    get align() {
        return this._align;
    }
    /**
     * Specifies the horizontal and vertical offset position of the FloatingActionButton
     * ([see example]({% slug positioning_floatingactionbutton %}#toc-offset)).
     *
     * * The default value is:
     * * `{ x: '16px', y: '16px' }`
     */
    set offset(offset) {
        this._offset = Object.assign(this._offset, offset);
        this.offsetStyles();
    }
    get offset() {
        return this._offset;
    }
    /**
     * Specifies the positionMode of the FloatingActionButton
     * ([see example](slug:positioning_floatingactionbutton#toc-position-mode)).
     *
     * * The possible values are:
     * * `absolute`&mdash;Positions the FloatingActionButton absolutely to its first positioned parent element.
     * * `fixed` (Default)&mdash;Positions the FloatingActionButton relative to the viewport. It always stays in the same place even if the page is scrolled.
     */
    positionMode = 'fixed';
    /**
     * Defines the name of an existing icon in a Kendo UI theme.
     * If provided, the icon will be rendered inside the FloatingActionButton by a `span.k-icon` element.
     */
    icon;
    /**
     * Defines an [`SVGIcon`](slug:api_icons_svgicon) to be rendered within the FloatingActionButton.
     */
    svgIcon;
    /**
     * Defines a CSS class or multiple classes separated by spaces which are applied to a `span` element.
     * Allows the usage of custom icons, rendered inside the FloatingActionButton by a `span` element.
     */
    iconClass;
    /**
     * The CSS classes that will be rendered on the main button.
     * Supports the type of values that are supported by [`ngClass`](link:site.data.urls.angular['ngclassapi']).
     */
    buttonClass;
    /**
     * The CSS classes that will be rendered on the dial items `ul` element.
     * Supports the type of values that are supported by [`ngClass`](link:site.data.urls.angular['ngclassapi']).
     */
    dialClass;
    /**
     * Specifies the text content of the FloatingActionButton.
     */
    text;
    /**
     * Specifies the animation settings of the FloatingActionButton dial items.
     * ([see example]({% slug dialitems_floatingactionbutton %}#toc-animation)).
     *
     * The possible values are:
     * * Boolean
     *    * (Default) `true`&mdash;Applies the default [`DialItemAnimation`]({% slug api_buttons_dialitemanimation %}) settings.
     *    * `false`
     * * `DialItemAnimation`
     *    * `duration`&mdash;Specifies the animation duration in milliseconds for each dial item. Defaults to `180ms`.
     *    * `gap`&mdash;Specifies the animation duration gap in milliseconds after each dial item is animated. Defaults to `90ms`.
     */
    dialItemAnimation = true;
    /**
     * Specifies the [`tabIndex`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) of the FloatingActionButton.
     */
    tabIndex = 0;
    /**
     * Specifies the collection of the dial items that will be rendered in the FloatingActionButton popup.
     */
    dialItems = [];
    /**
     * Fires each time the FloatingActionButton gets blurred.
     */
    onBlur = new EventEmitter();
    /**
     * Fires each time the FloatingActionButton gets focused.
     */
    onFocus = new EventEmitter();
    /**
     * Fires each time a dial item is clicked.
     */
    dialItemClick = new EventEmitter();
    /**
     * Fires each time the popup is about to open.
     * This event is preventable. If you cancel the event, the popup will remain closed
     * ([more information and example](slug:events_floatingactionbutton)).
     */
    open = new EventEmitter();
    /**
     * Fires each time the popup is about to close.
     * This event is preventable. If you cancel the event, the popup will remain open
     * ([more information and example](slug:events_floatingactionbutton)).
     */
    close = new EventEmitter();
    /**
     * @hidden
     */
    get componentTabIndex() {
        return this.disabled ? (-1) : this.tabIndex;
    }
    /**
     * @hidden
     */
    id = `k-${guid()}`;
    /**
     * @hidden
     */
    dialListId = `k-dial-list-${guid()}`;
    _themeColor = DEFAULT_THEME_COLOR;
    _size = DEFAULT_SIZE;
    _rounded = DEFAULT_ROUNDED$1;
    _disabled = false;
    _align = { horizontal: 'end', vertical: 'bottom' };
    _offset = { x: DEFAULT_OFFSET, y: DEFAULT_OFFSET };
    subscriptions = new Subscription();
    popupMouseDownListener;
    rtl = false;
    animationEnd = new EventEmitter();
    popupRef;
    initialSetup = true;
    focusChangedProgrammatically = false;
    constructor(renderer, element, focusService, navigationService, ngZone, popupService, builder, localizationService) {
        this.renderer = renderer;
        this.element = element;
        this.focusService = focusService;
        this.navigationService = navigationService;
        this.ngZone = ngZone;
        this.popupService = popupService;
        this.builder = builder;
        this.localizationService = localizationService;
        validatePackage(packageMetadata);
        this.subscribeNavigationEvents();
        this.subscriptions.add(this.localizationService.changes.subscribe(({ rtl }) => {
            this.rtl = rtl;
            this.direction = this.rtl ? 'rtl' : 'ltr';
        }));
    }
    ngAfterViewInit() {
        ['size', 'rounded', 'themeColor'].forEach(option => this.handleClasses(this[option], option));
        this.renderer.addClass(this.element.nativeElement, this.alignClass());
        this.offsetStyles();
        this.initialSetup = false;
    }
    ngOnDestroy() {
        this.subscriptions.unsubscribe();
        this.isOpen && this.toggleDial(false);
    }
    /**
     * Indicates whether the FloatingActionButton is currently open.
     */
    get isOpen() { return isPresent(this.popupRef); }
    /**
     * Focuses the FloatingActionButton.
     */
    focus() {
        if (isDocumentAvailable()) {
            this.focusChangedProgrammatically = true;
            this.button.nativeElement.focus();
            this.focusChangedProgrammatically = false;
        }
    }
    /**
     * Blurs the FloatingActionButton.
     */
    blur() {
        if (isDocumentAvailable()) {
            this.focusChangedProgrammatically = true;
            this.button.nativeElement.blur();
            this.focusChangedProgrammatically = false;
        }
    }
    /**
     * Toggles the visibility of the FloatingActionButton dial items popup.
     *
     * If you use the `toggleDial` method to open or close the dial items,
     * the `open` and `close` events do not fire ([more information and examples](slug:openstate_floatingactionbutton)).
     *
     * @param open - The state of dial items popup.
     */
    toggleDial(open) {
        if (this.disabled || !this.hasDialItems) {
            return;
        }
        const shouldOpen = isPresent(open) ? open : !this.isOpen;
        if (this.disabled || shouldOpen === this.isOpen) {
            return;
        }
        if (shouldOpen) {
            setTimeout(() => this.openDial());
        }
        else {
            this.closeDial();
        }
    }
    /**
     * @hidden
     */
    get ariaExpanded() {
        return this.hasDialItems ? this.isOpen : undefined;
    }
    /**
     * @hidden
     */
    get ariaHasPopup() {
        return this.hasDialItems ? 'menu' : undefined;
    }
    /**
     * @hidden
     */
    get ariaControls() {
        return this.hasDialItems ? this.isOpen ? this.dialListId : undefined : undefined;
    }
    /**
     * @hidden
     */
    get iconClasses() {
        const classes = [];
        if (this.iconClass) {
            classes.push(`${this.iconClass}`);
        }
        if (this.icon) {
            classes.push(`k-fab-icon k-icon k-i-${this.icon}`);
        }
        return classes;
    }
    /**
     * @hidden
     */
    clickHandler() {
        if (this.disabled || !this.hasDialItems) {
            return;
        }
        this.ngZone.run(() => {
            const shouldOpen = !this.isOpen;
            this.toggleDialWithEvents(shouldOpen);
        });
    }
    /**
     * @hidden
     */
    pointerdownHandler(e) {
        if (this.isOpen) {
            e.preventDefault();
            this.focus();
        }
    }
    /**
     * @hidden
     */
    keyDownHandler(event) {
        if (this.disabled) {
            return;
        }
        const focused = this.focusService.focused || 0;
        const keyCode = event.keyCode;
        const action = this.navigationService.process({
            altKey: event.altKey,
            current: focused,
            keyCode,
            max: this.dialItems ? this.dialItems.length - 1 : 0,
            min: 0,
            flipNavigation: this.align.vertical === 'bottom'
        });
        if (action !== NavigationAction.Undefined && action !== NavigationAction.Tab) {
            event.preventDefault();
        }
        if (action === NavigationAction.Tab && event.target.closest(`#${this.dialListId}`)) {
            this.focus();
        }
        if (action === NavigationAction.EnterUp && !this.hasDialItems) {
            this.button.nativeElement.click();
        }
        else if (action === NavigationAction.Open || action === NavigationAction.Close) {
            const toggleDial = action === NavigationAction.Open;
            this.ngZone.run(() => {
                this.toggleDialWithEvents(toggleDial);
            });
        }
    }
    /**
     * @hidden
     */
    onItemClick(event) {
        const item = closest(event.target, '.k-fab-item');
        if (!item) {
            return;
        }
        const index = parseInt(item.getAttribute('data-fab-item-index'));
        this.emitItemClick(index);
    }
    /**
     * @hidden
     */
    focusHandler() {
        if (!this.disabled && !this.focusChangedProgrammatically) {
            this.onFocus.emit();
        }
    }
    /**
     * @hidden
     */
    blurHandler(e) {
        const focusInList = e.relatedTarget && (e.relatedTarget.closest(`#${this.dialListId}`));
        if (focusInList) {
            return;
        }
        !this.focusChangedProgrammatically && this.onBlur.emit();
        this.toggleDialWithEvents(false);
    }
    /**
     * @hidden
     */
    focusOutHandler(e) {
        const focusInList = e.relatedTarget && (e.relatedTarget.closest(`#${this.dialListId}`));
        const focusOnButton = e.relatedTarget === this.button.nativeElement;
        const shouldClose = !focusInList && !focusOnButton;
        if (shouldClose) {
            this.toggleDialWithEvents(false);
            !this.focusChangedProgrammatically && this.onBlur.emit();
        }
    }
    /**
     * @hidden
     */
    onNavigationEnterPress() {
        this.ngZone.run(() => {
            if (this.isOpen) {
                const focusedIndex = this.focusService.focused;
                const focusedItem = this.dialItems[focusedIndex];
                if (focusedItem && focusedItem.disabled) {
                    return;
                }
                if (isPresent(focusedIndex) && focusedIndex !== -1) {
                    this.onEnterPressed();
                    return;
                }
            }
            if (!this.isOpen && isDocumentAvailable()) {
                this.toggleDialWithEvents(true);
                this.focus();
            }
        });
    }
    /**
     * @hidden
     */
    onNavigationClose() {
        if (this.isOpen) {
            this.ngZone.run(() => {
                this.toggleDialWithEvents(false);
                this.focus();
            });
        }
    }
    handleClasses(inputValue, input) {
        if (isPresent(this.button) && (this[input] !== inputValue || this.initialSetup)) {
            const button = this.button.nativeElement;
            const classesToRemove = {
                themeColor: `${FILLMODE_CLASS}-${this.themeColor}`,
                size: SIZE_CLASSES[this.size],
                rounded: ROUNDED_CLASSES[this.rounded]
            };
            const classesToAdd = {
                themeColor: inputValue !== 'none' ? `${FILLMODE_CLASS}-${inputValue}` : '',
                size: SIZE_CLASSES[inputValue],
                rounded: ROUNDED_CLASSES[inputValue]
            };
            this.renderer.removeClass(button, classesToRemove[input]);
            if (classesToAdd[input]) {
                this.renderer.addClass(button, classesToAdd[input]);
            }
        }
    }
    onEnterPressed() {
        const index = this.focusService.focused;
        this.emitItemClick(index);
    }
    emitItemClick(index) {
        const item = this.dialItems[index];
        if (item && !item.disabled) {
            const clickEventArgs = { item: item, index: index };
            this.dialItemClick.emit(clickEventArgs);
            this.toggleDialWithEvents(false);
            this.focusService.focused = index;
        }
        this.focus();
    }
    subscribeNavigationEvents() {
        this.subscriptions.add(this.navigationService.navigate.subscribe(this.onArrowKeyNavigate.bind(this)));
        this.subscriptions.add(this.navigationService.enter.subscribe(this.onNavigationEnterPress.bind(this)));
        this.subscriptions.add(merge(this.navigationService.close, this.navigationService.esc).subscribe(this.onNavigationClose.bind(this)));
    }
    onArrowKeyNavigate({ index }) {
        this.focusService.focus(index);
    }
    alignClass() {
        return `k-pos-${this.align.vertical}-${this.align.horizontal}`;
    }
    toggleDialWithEvents(open) {
        if (open === this.isOpen) {
            return;
        }
        const event = new PreventableEvent();
        if (open) {
            this.open.emit(event);
        }
        else {
            this.close.emit(event);
        }
        if (event.isDefaultPrevented()) {
            return;
        }
        if (open) {
            this.openDial();
        }
        else {
            this.closeDial();
        }
    }
    openPopup() {
        if (this.isOpen) {
            return;
        }
        const isIconFab = this.icon && !this.text;
        const rtl = this.rtl;
        const align = this.align;
        this.popupRef = this.popupService.open({
            anchor: this.element.nativeElement,
            animate: false,
            content: this.popupTemplate,
            anchorAlign: getAnchorAlign(align, rtl),
            popupAlign: getPopupAlign(align, rtl),
            popupClass: 'k-fab-popup k-popup-transparent'
        });
        const popupElement = this.popupRef.popupElement;
        this.renderer.setStyle(popupElement, 'box-shadow', 'none');
        if (isIconFab) {
            this.subscriptions.add(this.popupRef.popupOpen.subscribe(() => this.positionPopup()));
        }
        this.ngZone.runOutsideAngular(() => {
            this.popupMouseDownListener = this.renderer.listen(popupElement, 'mousedown', (event) => {
                event.preventDefault();
            });
        });
        this.popupRef.popupAnchorViewportLeave.subscribe(() => this.toggleDialWithEvents(false));
    }
    closePopup() {
        if (this.isOpen) {
            if (this.popupMouseDownListener) {
                this.popupMouseDownListener();
            }
            this.popupRef.close();
            this.popupRef = null;
        }
    }
    openDial() {
        this.openPopup();
        this.focusService.focus(0);
        if (this.dialItemAnimation && this.isValidAnimation()) {
            this.playAnimation(true);
        }
        this.renderer.setAttribute(this.button.nativeElement, 'aria-expanded', 'true');
    }
    closeDial() {
        if (this.dialItemAnimation && this.isValidAnimation()) {
            this.playAnimation(false);
            this.animationEnd.pipe(take(1)).subscribe(() => this.closePopup());
        }
        else {
            this.closePopup();
        }
        this.renderer.setAttribute(this.button.nativeElement, 'aria-expanded', 'false');
        this.focusService.resetFocus();
    }
    isValidAnimation() {
        const animation = this.dialItemAnimation;
        if (typeof animation !== 'boolean') {
            return animation.duration !== 0;
        }
        return true;
    }
    positionPopup() {
        if (this.dialItemTemplate) {
            return;
        }
        if (!this.popupRef) {
            return;
        }
        const fab = this.element.nativeElement;
        const fabWidth = fab.getBoundingClientRect().width;
        const popupEl = this.popupRef.popupElement;
        const icon = popupEl.querySelector('.k-fab-item-icon');
        if (!icon) {
            return;
        }
        const iconWidth = icon.getBoundingClientRect().width;
        const left = (fabWidth / 2) - (iconWidth / 2);
        const popupLeft = popupEl.getBoundingClientRect().left;
        const isEndAlign = this.align.horizontal === 'end';
        const leftValue = isEndAlign ? (popupLeft - left) : (left + popupLeft);
        const rtlLeftValue = isEndAlign ? (left + popupLeft) : (popupLeft - left);
        popupEl.style.left = this.rtl ? `${rtlLeftValue}px` : `${leftValue}px`;
    }
    offsetStyles() {
        const hostElement = this.element.nativeElement;
        this.renderer.setStyle(hostElement, this.horizontalPosition, this.horizontalOffset);
        this.renderer.setStyle(hostElement, this.verticalPosition, this.verticalOffset);
    }
    get hasDialItems() {
        return isPresent(this.dialItems) && this.dialItems.length !== 0;
    }
    /**
     * Gets the CSS prop name of the selected vertical position (`top`/`bottom`);
     */
    get verticalPosition() {
        return {
            top: 'top',
            middle: 'top',
            bottom: 'bottom'
        }[this.align.vertical];
    }
    /**
     * Gets the offset according to the selected vertical position.
     */
    get verticalOffset() {
        if (this.align.vertical === 'middle') {
            return this.offset.y === DEFAULT_OFFSET ? '50%' : `calc(50% + ${this.offset.y})`;
        }
        return this.offset.y;
    }
    /**
     * Gets the CSS prop name of the selected horizontal position (`left`/`right`);
     */
    get horizontalPosition() {
        const { horizontal } = this.align;
        return {
            end: this.rtl ? 'left' : 'right',
            center: 'left',
            start: this.rtl ? 'right' : 'left'
        }[horizontal];
    }
    /**
     * Gets the offset according to the selected horizontal position.
     */
    get horizontalOffset() {
        if (this.align.horizontal === 'center') {
            return this.offset.x === DEFAULT_OFFSET ? '50%' : `calc(50% + ${this.offset.x})`;
        }
        return this.offset.x;
    }
    playerFor(element, animation) {
        const factory = this.builder.build(animation);
        return factory.create(element);
    }
    playAnimation(open) {
        const durationSettings = this.durationSettings();
        const animationSettings = {
            duration: durationSettings.duration,
            gap: durationSettings.gap,
            align: this.align
        };
        const animation = open ? openAnimation(animationSettings) : closeAnimation(animationSettings);
        let player = this.playerFor(this.popupRef.popupElement, animation);
        player.play();
        player.onDone(() => {
            if (player) {
                this.animationEnd.emit();
                player.destroy();
                player = null;
            }
        });
    }
    durationSettings() {
        return {
            duration: this.animationDuration(),
            gap: this.animationGap()
        };
    }
    animationGap() {
        const animation = this.dialItemAnimation;
        if (typeof animation !== 'boolean' && isPresent(animation.gap)) {
            return animation.gap;
        }
        return DEFAULT_ITEM_GAP;
    }
    animationDuration() {
        const animation = this.dialItemAnimation;
        if (typeof animation !== 'boolean' && isPresent(animation.duration)) {
            return animation.duration;
        }
        return DEFAULT_DURATION;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FloatingActionButtonComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: FocusService }, { token: NavigationService }, { token: i0.NgZone }, { token: i3.PopupService }, { token: i4.AnimationBuilder }, { token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: FloatingActionButtonComponent, isStandalone: true, selector: "kendo-floatingactionbutton", inputs: { themeColor: "themeColor", size: "size", rounded: "rounded", disabled: "disabled", align: "align", offset: "offset", positionMode: "positionMode", icon: "icon", svgIcon: "svgIcon", iconClass: "iconClass", buttonClass: "buttonClass", dialClass: "dialClass", text: "text", dialItemAnimation: "dialItemAnimation", tabIndex: "tabIndex", dialItems: "dialItems" }, outputs: { onBlur: "blur", onFocus: "focus", dialItemClick: "dialItemClick", open: "open", close: "close" }, host: { properties: { "class.k-pos-fixed": "this.fixedClass", "class.k-pos-absolute": "this.absoluteClass", "attr.dir": "this.direction" } }, providers: [
            FocusService,
            NavigationService,
            NAVIGATION_SETTINGS_PROVIDER$1,
            LocalizationService,
            {
                provide: L10N_PREFIX,
                useValue: 'kendo.floatingactionbutton'
            }
        ], queries: [{ propertyName: "dialItemTemplate", first: true, predicate: DialItemTemplateDirective, descendants: true }, { propertyName: "fabTemplate", first: true, predicate: FloatingActionButtonTemplateDirective, descendants: true }], viewQueries: [{ propertyName: "button", first: true, predicate: ["button"], descendants: true, static: true }, { propertyName: "popupTemplate", first: true, predicate: ["popupTemplate"], descendants: true, static: true }], ngImport: i0, template: `
        <button
            #button
            [attr.id]="id"
            [tabIndex]="componentTabIndex"
            type="button"
            class="k-fab k-fab-solid"
            [class.k-disabled]="disabled"
            [ngClass]="buttonClass"
            [disabled]="disabled"
            [attr.aria-disabled]="disabled"
            [attr.aria-expanded]="ariaExpanded"
            [attr.aria-haspopup]="ariaHasPopup"
            [attr.aria-controls]="ariaControls"
            (focus)="focusHandler()"
            (blur)="blurHandler($event)"
            [kendoEventsOutsideAngular]="{
                keydown: keyDownHandler,
                click: clickHandler,
                pointerdown: pointerdownHandler
            }"
            [scope]="this"
        >
            <ng-template *ngIf="fabTemplate"
                [ngTemplateOutlet]="fabTemplate?.templateRef"
            >
            </ng-template>

            <ng-container *ngIf="!fabTemplate">
                <kendo-icon-wrapper
                    *ngIf="icon || iconClass || svgIcon"
                    [name]="icon"
                    innerCssClass="k-fab-icon"
                    [customFontClass]="iconClass"
                    [svgIcon]="svgIcon"></kendo-icon-wrapper>
                <span *ngIf="text" class="k-fab-text">{{ text }}</span>
            </ng-container>
        </button>

        <ng-template #popupTemplate>
            <ul
                kendoDialList
                role="menu"
                [id]="dialListId"
                [ngClass]="dialClass"
                [dialItems]="dialItems"
                [dialItemTemplate]='dialItemTemplate?.templateRef'
                [align]="align"
                [attr.aria-labelledby]="id"
                (click)="onItemClick($event)"
                [kendoEventsOutsideAngular]="{
                    keydown: keyDownHandler.bind(this),
                    focusout: focusOutHandler.bind(this)
                }"
            >
            </ul>
        </ng-template>
    `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: EventsOutsideAngularDirective, selector: "[kendoEventsOutsideAngular]", inputs: ["kendoEventsOutsideAngular", "scope"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: DialListComponent, selector: "[kendoDialList]", inputs: ["dialItems", "dialItemTemplate", "align"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FloatingActionButtonComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'kendo-floatingactionbutton',
                    providers: [
                        FocusService,
                        NavigationService,
                        NAVIGATION_SETTINGS_PROVIDER$1,
                        LocalizationService,
                        {
                            provide: L10N_PREFIX,
                            useValue: 'kendo.floatingactionbutton'
                        }
                    ],
                    template: `
        <button
            #button
            [attr.id]="id"
            [tabIndex]="componentTabIndex"
            type="button"
            class="k-fab k-fab-solid"
            [class.k-disabled]="disabled"
            [ngClass]="buttonClass"
            [disabled]="disabled"
            [attr.aria-disabled]="disabled"
            [attr.aria-expanded]="ariaExpanded"
            [attr.aria-haspopup]="ariaHasPopup"
            [attr.aria-controls]="ariaControls"
            (focus)="focusHandler()"
            (blur)="blurHandler($event)"
            [kendoEventsOutsideAngular]="{
                keydown: keyDownHandler,
                click: clickHandler,
                pointerdown: pointerdownHandler
            }"
            [scope]="this"
        >
            <ng-template *ngIf="fabTemplate"
                [ngTemplateOutlet]="fabTemplate?.templateRef"
            >
            </ng-template>

            <ng-container *ngIf="!fabTemplate">
                <kendo-icon-wrapper
                    *ngIf="icon || iconClass || svgIcon"
                    [name]="icon"
                    innerCssClass="k-fab-icon"
                    [customFontClass]="iconClass"
                    [svgIcon]="svgIcon"></kendo-icon-wrapper>
                <span *ngIf="text" class="k-fab-text">{{ text }}</span>
            </ng-container>
        </button>

        <ng-template #popupTemplate>
            <ul
                kendoDialList
                role="menu"
                [id]="dialListId"
                [ngClass]="dialClass"
                [dialItems]="dialItems"
                [dialItemTemplate]='dialItemTemplate?.templateRef'
                [align]="align"
                [attr.aria-labelledby]="id"
                (click)="onItemClick($event)"
                [kendoEventsOutsideAngular]="{
                    keydown: keyDownHandler.bind(this),
                    focusout: focusOutHandler.bind(this)
                }"
            >
            </ul>
        </ng-template>
    `,
                    standalone: true,
                    imports: [NgClass, EventsOutsideAngularDirective, NgIf, NgTemplateOutlet, IconWrapperComponent, DialListComponent]
                }]
        }], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: FocusService }, { type: NavigationService }, { type: i0.NgZone }, { type: i3.PopupService }, { type: i4.AnimationBuilder }, { type: i1.LocalizationService }]; }, propDecorators: { fixedClass: [{
                type: HostBinding,
                args: ['class.k-pos-fixed']
            }], absoluteClass: [{
                type: HostBinding,
                args: ['class.k-pos-absolute']
            }], direction: [{
                type: HostBinding,
                args: ['attr.dir']
            }], button: [{
                type: ViewChild,
                args: ['button', { static: true }]
            }], popupTemplate: [{
                type: ViewChild,
                args: ['popupTemplate', { static: true }]
            }], dialItemTemplate: [{
                type: ContentChild,
                args: [DialItemTemplateDirective, { static: false }]
            }], fabTemplate: [{
                type: ContentChild,
                args: [FloatingActionButtonTemplateDirective, { static: false }]
            }], themeColor: [{
                type: Input
            }], size: [{
                type: Input
            }], rounded: [{
                type: Input
            }], disabled: [{
                type: Input
            }], align: [{
                type: Input
            }], offset: [{
                type: Input
            }], positionMode: [{
                type: Input
            }], icon: [{
                type: Input
            }], svgIcon: [{
                type: Input
            }], iconClass: [{
                type: Input
            }], buttonClass: [{
                type: Input
            }], dialClass: [{
                type: Input
            }], text: [{
                type: Input
            }], dialItemAnimation: [{
                type: Input
            }], tabIndex: [{
                type: Input
            }], dialItems: [{
                type: Input
            }], onBlur: [{
                type: Output,
                args: ['blur']
            }], onFocus: [{
                type: Output,
                args: ['focus']
            }], dialItemClick: [{
                type: Output,
                args: ['dialItemClick']
            }], open: [{
                type: Output
            }], close: [{
                type: Output
            }] } });

/**
 * @hidden
 */
class Messages extends ComponentMessages {
    /**
     * The text for the SplitButton aria-label.
     *
     * The text for the aria-label consists of a two-part message - the text of the SplitButton and a localizable string.
     * For a SplitButton with text 'Reply', the default aria-label will be 'Reply splitbutton'.
     *
     * To allow reordering of the SplitButton text and the localizable part, the splitButtonLabel accepts a string with a
     * placeholder for the button text - e.g. 'splitbutton for {buttonText}'. The '{buttonText}' placeholder will be replaced
     * internally with the current SplitButton text, and the resulting aria-label will be rendered as 'splitbutton for Reply'.
     *
     * @example
     *
     * ```ts-no-run
     *      <kendo-splitbutton>
     *          <kendo-splitbutton-messages
     *              splitButtonLabel="splitbutton for {buttonText}"
     *          >
     *          </kendo-splitbutton-messages>
     *      </kendo-splitbutton>
     *  ```
     */
    splitButtonLabel;
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: Messages, deps: null, target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: Messages, selector: "kendo-splitbutton-messages-base", inputs: { splitButtonLabel: "splitButtonLabel" }, usesInheritance: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: Messages, decorators: [{
            type: Directive,
            args: [{
                    // eslint-disable-next-line @angular-eslint/directive-selector
                    selector: 'kendo-splitbutton-messages-base'
                }]
        }], propDecorators: { splitButtonLabel: [{
                type: Input
            }] } });

/**
 * Custom component messages override default component messages
 * ([see example]({% slug rtl_buttons %}).
 */
class SplitButtonCustomMessagesComponent extends Messages {
    service;
    constructor(service) {
        super();
        this.service = service;
    }
    get override() {
        return true;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SplitButtonCustomMessagesComponent, deps: [{ token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SplitButtonCustomMessagesComponent, isStandalone: true, selector: "kendo-splitbutton-messages", providers: [{
                provide: Messages,
                useExisting: forwardRef(() => SplitButtonCustomMessagesComponent)
            }], usesInheritance: true, ngImport: i0, template: ``, isInline: true });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SplitButtonCustomMessagesComponent, decorators: [{
            type: Component,
            args: [{
                    providers: [{
                            provide: Messages,
                            useExisting: forwardRef(() => SplitButtonCustomMessagesComponent)
                        }],
                    selector: 'kendo-splitbutton-messages',
                    template: ``,
                    standalone: true
                }]
        }], ctorParameters: function () { return [{ type: i1.LocalizationService }]; } });

/**
 * @hidden
 */
class LocalizedSplitButtonMessagesDirective extends Messages {
    service;
    constructor(service) {
        super();
        this.service = service;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LocalizedSplitButtonMessagesDirective, deps: [{ token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: LocalizedSplitButtonMessagesDirective, isStandalone: true, selector: "[kendoSplitButtonLocalizedMessages]", providers: [
            {
                provide: Messages,
                useExisting: forwardRef(() => LocalizedSplitButtonMessagesDirective)
            }
        ], usesInheritance: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LocalizedSplitButtonMessagesDirective, decorators: [{
            type: Directive,
            args: [{
                    providers: [
                        {
                            provide: Messages,
                            useExisting: forwardRef(() => LocalizedSplitButtonMessagesDirective)
                        }
                    ],
                    selector: '[kendoSplitButtonLocalizedMessages]',
                    standalone: true
                }]
        }], ctorParameters: function () { return [{ type: i1.LocalizationService }]; } });

const NAVIGATION_SETTINGS = {
    useLeftRightArrows: true
};
const NAVIGATION_SETTINGS_PROVIDER = {
    provide: NAVIGATION_CONFIG,
    useValue: NAVIGATION_SETTINGS
};
const DEFAULT_ROUNDED = 'medium';
const DEFAULT_FILL_MODE = 'solid';
/**
 * Represents the Kendo UI SplitButton component for Angular.
 *
 * @example
 * ```ts
 * _@Component({
 * selector: 'my-app',
 * template: `
 *  <kendo-splitbutton [data]="data" icon="clipboard"
 *      (itemClick)="onSplitButtonItemClick($event)"
 *      (buttonClick)="onSplitButtonClick()">Paste</kendo-splitbutton>
 * `
 * })
 *
 * class AppComponent {
 *   public data: Array<any> = [{
 *       text: 'Keep Text Only',
 *       icon: 'clipboard-text',
 *       click: () => { console.log('Keep Text Only click handler'); }
 *   }, {
 *       text: 'Paste as HTML',
 *       icon: 'clipboard-code'
 *   }, {
 *       text: 'Paste Markdown',
 *       icon: 'clipboard-markdown'
 *   }, {
 *       text: 'Set Default Paste'
 *   }];
 *
 *   public onSplitButtonClick(dataItem: any): void {
 *       console.log('Paste');
 *   }
 *
 *   public onSplitButtonItemClick(dataItem: any): void {
 *       if (dataItem) {
 *           console.log(dataItem.text);
 *       }
 *   }
 * }
 * ```
 */
class SplitButtonComponent extends ListButton {
    localization;
    renderer;
    /**
     * Sets the text of the SplitButton.
     */
    text = '';
    /**
     * Defines an icon to be rendered next to the button text.
     * ([see example]({% slug databinding_splitbutton %}#toc-arrays-of-complex-data)).
     */
    icon = '';
    /**
     * Defines an SVGIcon to be rendered next to the button text.
     */
    svgIcon;
    /**
     * Defines an icon with a custom CSS class to be rendered next to the button text
     * ([see example]({% slug databinding_splitbutton %}#toc-arrays-of-complex-data)).
     */
    iconClass;
    /**
     * Defines the type attribute of the main button
     */
    type = 'button';
    /**
     * Defines the location of an image to be displayed next to the button text
     * ([see example]({% slug databinding_splitbutton %}#toc-arrays-of-complex-data)).
     */
    imageUrl = '';
    /**
     * The size property specifies the padding of the SplitButton
     * ([see example]({% slug api_buttons_splitbuttoncomponent %}#toc-size)).
     *
     * The possible values are:
     * * `small`
     * * `medium` (default)
     * * `large`
     * * `none`
     */
    size = 'medium';
    /**
     * The rounded property specifies the border radius of the SplitButton
     * ([see example]({% slug api_buttons_splitbuttoncomponent %}#toc-rounded)).
     *
     * The possible values are:
     * * `small`
     * * `medium` (default)
     * * `large`
     * * `full`
     * * `none`
     */
    set rounded(rounded) {
        const newRounded = rounded ? rounded : DEFAULT_ROUNDED;
        this.handleClasses(newRounded, 'rounded');
        this._rounded = newRounded;
    }
    get rounded() {
        return this._rounded;
    }
    /**
     * The fillMode property specifies the background and border styles of the SplitButton
     * ([see example]({% slug api_buttons_splitbuttoncomponent %}#toc-fillMode)).
     *
     * The available values are:
     * * `solid` (default)
     * * `flat`
     * * `outline`
     * * `link`
     */
    set fillMode(fillMode) {
        const newFillMode = fillMode ? fillMode : DEFAULT_FILL_MODE;
        this._fillMode = fillMode === 'clear' ? 'flat' : newFillMode;
    }
    get fillMode() {
        return this._fillMode;
    }
    /**
     * The SplitButton allows you to specify predefined theme colors.
     * The theme color will be applied as a background and border color while also amending the text color accordingly
     * ([see example]({% slug api_buttons_splitbuttoncomponent %}#toc-themeColor)).
     *
     * The possible values are:
     * * `base` &mdash;Applies coloring based on the `base` theme color. (default)
     * * `primary` &mdash;Applies coloring based on the `primary` theme color.
     * * `secondary`&mdash;Applies coloring based on the `secondary` theme color.
     * * `tertiary`&mdash; Applies coloring based on the `tertiary` theme color.
     * * `info`&mdash;Applies coloring based on the `info` theme color.
     * * `success`&mdash; Applies coloring based on the `success` theme color.
     * * `warning`&mdash; Applies coloring based on the `warning` theme color.
     * * `error`&mdash; Applies coloring based on the `error` theme color.
     * * `dark`&mdash; Applies coloring based on the `dark` theme color.
     * * `light`&mdash; Applies coloring based on the `light` theme color.
     * * `inverse`&mdash; Applies coloring based on the `inverse` theme color.
     * * `none`&mdash; Removes the built in theme color.
     */
    themeColor = 'base';
    /**
     * When set to `true`, disables a SplitButton item
     * ([see example]({% slug databinding_splitbutton %}#toc-arrays-of-complex-data)).
     */
    set disabled(value) {
        if (this.isOpen) {
            this.toggle(false);
        }
        this._disabled = value;
    }
    get disabled() {
        return this._disabled;
    }
    /**
     * Configures the popup of the SplitButton.
     *
     * The available options are:
     * - `animate: Boolean`&mdash;Controls the popup animation. By default, the open and close animations are enabled.
     * - `popupClass: String`&mdash;Specifies a list of CSS classes that are used to style the popup.
     * - `appendTo: "root" | "component" | ViewContainerRef`&mdash;Specifies the component to which the popup will be appended.
     * - `align: "left" | "center" | "right"`&mdash;Specifies the alignment of the popup.
     */
    set popupSettings(settings) {
        this._popupSettings = Object.assign({ animate: true, popupClass: '' }, settings);
    }
    get popupSettings() {
        return this._popupSettings;
    }
    /**
     * Specifies the [`tabIndex`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) of the component.
     */
    tabIndex = 0;
    /**
     * Configures the text field of the button-list popup.
     */
    textField;
    /**
     * Sets the data of the SplitButton.
     *
     * > The data has to be provided in an array-like list.
     */
    set data(data) {
        this._data = data || [];
    }
    get data() {
        if (!this._data) {
            this.data = [];
        }
        return this._data;
    }
    /**
     * The CSS classes that will be rendered on the button which opens the popup.
     * Supports the type of values that are supported by [`ngClass`](link:site.data.urls.angular['ngclassapi']).
     */
    arrowButtonClass;
    /**
     * Specifies the name of the [font icon](slug:icons#icons-list) that will
     * be rendered for the button which opens the popup.
     */
    arrowButtonIcon = 'caret-alt-down';
    /**
     * Specifies the [`SVGIcon`](slug:api_icons_svgicon) that will
     * be rendered for the button which opens the popup.
     */
    arrowButtonSvgIcon = caretAltDownIcon;
    /**
     * Sets attributes to the main button.
     */
    set buttonAttributes(buttonAttributes) {
        const newButtonAttributes = buttonAttributes ? buttonAttributes : null;
        this.handleButtonAttributes(newButtonAttributes);
        this._buttonAttributes = newButtonAttributes;
    }
    get buttonAttributes() {
        return this._buttonAttributes;
    }
    /**
     * Fires each time the user clicks the main button.
     *
     * @example
     * ```ts
     * _@Component({
     *    selector: 'my-app',
     *    template: `
     *        <kendo-splitbutton (buttonClick)="onSplitButtonClick()" [data]="data">
     *            Reply
     *        </kendo-splitbutton>
     *    `
     * })
     * class AppComponent {
     *    public data: Array<any> = ['Reply All', 'Forward', 'Reply & Delete'];
     *
     *    public onSplitButtonClick(): void {
     *      console.log('SplitButton click');
     *    }
     * }
     * ```
     *
     */
    buttonClick = new EventEmitter();
    /**
     * Fires each time the user clicks on the drop-down list. The event data contains the data item bound to the clicked list item.
     *
     * @example
     * ```ts
     * _@Component({
     *     selector: 'my-app',
     *    template: `
     *        <kendo-splitbutton (itemClick)="onSplitButtonItemClick($event)" [data]="data">
     *          Reply
     *      </kendo-splitbutton>
     *    `
     * })
     * class AppComponent {
     *    public data: Array<any> = ['Reply All', 'Forward', 'Reply & Delete'];
     *
     *   public onSplitButtonItemClick(dataItem?: string): void {
     *        if (dataItem) {
     *            console.log(dataItem);
     *       }
     *    }
     * }
     * ```
     *
     */
    itemClick = new EventEmitter();
    /**
     * Fires each time the SplitButton gets focused.
     */
    onFocus = new EventEmitter();
    /**
     * Fires each time the SplitButton gets blurred.
     */
    onBlur = new EventEmitter();
    /**
     * Fires each time the popup is about to open.
     * This event is preventable. If you cancel the event, the popup will remain closed.
     */
    open = new EventEmitter();
    /**
     * Fires each time the popup is about to close.
     * This event is preventable. If you cancel the event, the popup will remain open.
     */
    close = new EventEmitter();
    /**
     * An item template that helps to customize the item content.
     */
    itemTemplate;
    activeArrow = false;
    listId = guid();
    /**
     * @hidden
     */
    get hasContent() {
        return this.button?.nativeElement.childElementCount > 0;
    }
    /**
     * @hidden
     */
    get active() {
        return this._active;
    }
    /**
     * @hidden
     */
    get componentTabIndex() {
        return this.disabled ? -1 : this.tabIndex;
    }
    buttonText = '';
    arrowButtonClicked = false;
    _rounded = DEFAULT_ROUNDED;
    _fillMode = DEFAULT_FILL_MODE;
    _buttonAttributes = null;
    documentMouseUpSub;
    set isFocused(value) {
        this._isFocused = value;
    }
    get isFocused() {
        return this._isFocused && !this._disabled && isDocumentAvailable() && this.wrapperContains(document.activeElement);
    }
    get widgetClasses() {
        return true;
    }
    get dir() {
        return this.direction;
    }
    /**
     * @hidden
     */
    get ariaLabel() {
        const localizationMsg = this.localization.get('splitButtonLabel') || '';
        return replaceMessagePlaceholder(localizationMsg, 'buttonText', this.buttonText);
    }
    /**
     * @hidden
     */
    onButtonFocus(event) {
        if (!this._disabled) {
            // eslint-disable-next-line no-unused-expressions
            !this._isFocused && this.onFocus.emit();
            this._isFocused = true;
            this.focusService.resetFocus();
            const relatedTargetInList = event.relatedTarget && closest(event.relatedTarget, '.k-popup kendo-button-list');
            if (this.openState && !relatedTargetInList) {
                this.focusService.focus(0);
            }
        }
    }
    /**
     * @hidden
     */
    onArrowButtonClick() {
        this.togglePopupVisibility();
        this.arrowButtonClicked = false;
        if (!this.isOpen) {
            this.focus();
        }
    }
    /**
     * @hidden
     */
    toggleButtonActiveState(enable) {
        this._active = enable;
    }
    /**
     * @hidden
     */
    toggleArrowButtonActiveState(enable) {
        this.arrowButtonClicked = true;
        this.activeArrow = enable;
    }
    /**
     * @hidden
     */
    onButtonClick() {
        this.buttonClick.emit();
    }
    /**
     * @hidden
     */
    onButtonBlur() {
        if (!this.isOpen && !this.arrowButtonClicked) {
            this.blurWrapper();
        }
    }
    /**
     * @hidden
     */
    keydown(event) {
        this.keyDownHandler(event, true);
        if (event.keyCode === Keys.Space) {
            this._active = true;
        }
    }
    /**
     * @hidden
     */
    keyup(event) {
        this._active = false;
        if (event.keyCode !== Keys.Space) {
            this.keyUpHandler(event);
        }
    }
    /**
     * @hidden
     */
    ngAfterViewInit() {
        this.containerService.container = this.container;
        this.containerService.template = this.popupTemplate;
        this.updateButtonText();
        this.handleClasses(this.rounded, 'rounded');
        this.handleButtonAttributes(this.buttonAttributes);
    }
    /**
     * @hidden
     */
    ngOnChanges(changes) {
        if (changes.hasOwnProperty('text')) {
            this.updateButtonText();
        }
        if (anyChanged(['text', 'icon', 'svgIcon', 'iconClass', 'imageUrl'], changes)) {
            this.toggleButtonIconClass();
        }
        if (isChanged('popupSettings', changes) && isPresent(this.popupRef)) {
            const popup = this.popupRef.popup.instance;
            const newSettings = changes['popupSettings'].currentValue;
            popup.popupClass = newSettings.popupClass;
            popup.animate = newSettings.animate;
            popup.popupAlign = this.popupAlign;
        }
    }
    /**
     * @hidden
     */
    ngOnDestroy() {
        if (this.documentMouseUpSub) {
            this.documentMouseUpSub();
        }
    }
    /**
     * @hidden
     */
    onNavigationEnterUp(args) {
        if (args.target !== this.button.nativeElement) {
            super.onNavigationEnterUp(args);
        }
    }
    /**
     * @hidden
     */
    togglePopupVisibility() {
        if (isDocumentAvailable() && this.wrapperContains(document.activeElement) && this.arrowButtonClicked) {
            this.button.nativeElement.focus();
        }
        super.togglePopupVisibility();
    }
    /**
     * @hidden
     */
    wrapperContains(element) {
        return (this.wrapper === element || this.wrapper.contains(element));
    }
    /**
     * @hidden
     */
    get anchorAlign() {
        const align = { horizontal: this.popupSettings.align || 'left', vertical: 'bottom' };
        if (this.direction === 'rtl' && !isPresent(this.popupSettings.align)) {
            align.horizontal = 'right';
        }
        return align;
    }
    /**
     * @hidden
     */
    get popupAlign() {
        const align = { horizontal: this.popupSettings.align || 'left', vertical: 'top' };
        if (this.direction === 'rtl' && !isPresent(this.popupSettings.align)) {
            align.horizontal = 'right';
        }
        return align;
    }
    /**
     * @hidden
     */
    get isIconButton() {
        const hasIcon = this.icon || this.svgIcon || this.iconClass || this.imageUrl;
        const hasTextContent = isDocumentAvailable() && this.button?.nativeElement.textContent.trim().length > 0;
        return hasIcon && !hasTextContent;
    }
    /**
     * Focuses the SplitButton component.
     */
    focus() {
        if (isDocumentAvailable()) {
            this.button.nativeElement.focus();
        }
    }
    /**
     * Blurs the SplitButton component.
     */
    blur() {
        if (isDocumentAvailable()) {
            this.button.nativeElement.blur();
            this.blurWrapper();
        }
    }
    constructor(focusService, navigationService, wrapperRef, zone, popupService, elRef, localization, cdr, renderer, containerService) {
        super(focusService, navigationService, wrapperRef, zone, popupService, elRef, localization, cdr, containerService);
        this.localization = localization;
        this.renderer = renderer;
        this._itemClick = this.itemClick;
        this._blur = this.onBlur;
        zone.runOutsideAngular(() => {
            this.documentMouseUpSub = this.renderer.listen('document', 'mouseup', () => {
                if (this.active) {
                    zone.run(() => this._active = false);
                }
                if (this.activeArrow) {
                    zone.run(() => this.activeArrow = false);
                }
            });
        });
    }
    /**
     * Returns the current open state of the popup.
     */
    get isOpen() {
        return this.openState;
    }
    updateButtonText() {
        if (isDocumentAvailable()) {
            const innerText = this.wrapper.innerText
                .split('\n')
                .join('')
                .trim();
            //setTimeout is needed because of `Expression has changed after it was checked.` error;
            setTimeout(() => (this.buttonText = innerText), 0);
        }
    }
    handleClasses(value, input) {
        const elem = this.wrapperRef.nativeElement;
        const classes = getStylingClasses('button', input, this[input], value);
        if (classes.toRemove) {
            this.renderer.removeClass(elem, classes.toRemove);
        }
        if (classes.toAdd) {
            this.renderer.addClass(elem, classes.toAdd);
        }
    }
    toggleButtonIconClass() {
        this.button.nativeElement.classList[this.isIconButton ? 'add' : 'remove']('k-button-icon');
    }
    handleButtonAttributes(newButtonAttributes) {
        const mainButton = this.button.nativeElement;
        if (isPresent(this.buttonAttributes) && isPresent(mainButton)) {
            for (const attr in this.buttonAttributes) {
                this.renderer.removeAttribute(mainButton, attr, this.buttonAttributes[attr]);
            }
        }
        if (isPresent(newButtonAttributes) && isPresent(mainButton)) {
            for (const attr in newButtonAttributes) {
                this.renderer.setAttribute(mainButton, attr, newButtonAttributes[attr]);
            }
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SplitButtonComponent, deps: [{ token: FocusService }, { token: NavigationService }, { token: i0.ElementRef }, { token: i0.NgZone }, { token: i3.PopupService }, { token: i0.ElementRef }, { token: i1.LocalizationService }, { token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }, { token: PopupContainerService }], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SplitButtonComponent, isStandalone: true, selector: "kendo-splitbutton", inputs: { text: "text", icon: "icon", svgIcon: "svgIcon", iconClass: "iconClass", type: "type", imageUrl: "imageUrl", size: "size", rounded: "rounded", fillMode: "fillMode", themeColor: "themeColor", disabled: "disabled", popupSettings: "popupSettings", tabIndex: "tabIndex", textField: "textField", data: "data", arrowButtonClass: "arrowButtonClass", arrowButtonIcon: "arrowButtonIcon", arrowButtonSvgIcon: "arrowButtonSvgIcon", buttonAttributes: "buttonAttributes" }, outputs: { buttonClick: "buttonClick", itemClick: "itemClick", onFocus: "focus", onBlur: "blur", open: "open", close: "close" }, host: { listeners: { "keydown": "keydown($event)", "keyup": "keyup($event)" }, properties: { "class.k-focus": "this.isFocused", "class.k-split-button": "this.widgetClasses", "class.k-button-group": "this.widgetClasses", "attr.dir": "this.dir" } }, providers: [
            FocusService,
            NavigationService,
            NAVIGATION_SETTINGS_PROVIDER,
            LocalizationService,
            {
                provide: L10N_PREFIX,
                useValue: 'kendo.splitbutton'
            },
            PopupContainerService,
            {
                provide: MultiTabStop,
                useExisting: forwardRef(() => SplitButtonComponent)
            }
        ], queries: [{ propertyName: "itemTemplate", first: true, predicate: ButtonItemTemplateDirective, descendants: true }], exportAs: ["kendoSplitButton"], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: `
        <ng-container kendoSplitButtonLocalizedMessages
            i18n-splitButtonLabel="kendo.splitbutton.splitButtonLabel|The text for the SplitButton aria-label"
            splitButtonLabel="{{ '{buttonText} splitbutton' }}"
        >
        </ng-container>
        <button
            kendoButton
            #button
            [type]="type"
            [tabindex]="componentTabIndex"
            [disabled]="disabled"
            [size]="size"
            [rounded]="rounded"
            [fillMode]="fillMode"
            [themeColor]="themeColor"
            [icon]="icon"
            [svgIcon]="svgIcon"
            [class.k-active]="active"
            [iconClass]="iconClass"
            [imageUrl]="imageUrl"
            [ngClass]="buttonClass"
            (focus)="onButtonFocus($event)"
            (click)="onButtonClick()"
            (blur)="onButtonBlur()"
            (mousedown)="toggleButtonActiveState(true)"
            (mouseup)="toggleButtonActiveState(false)"
            [attr.aria-expanded]="openState"
            [attr.aria-controls]="listId"
            [attr.aria-label]="ariaLabel"
        >
            <span *ngIf="text" class="k-button-text">
                {{ text }} </span><ng-content></ng-content>
        </button>
        <button kendoButton #arrowButton type="button"
            class="k-split-button-arrow"
            [class.k-active]="activeArrow"
            [ngClass]="arrowButtonClass"
            [disabled]="disabled"
            [icon]="arrowButtonIcon"
            [svgIcon]="arrowButtonSvgIcon"
            [size]="size"
            [rounded]="rounded"
            [fillMode]="fillMode"
            [themeColor]="themeColor"
            [tabindex]="-1"
            aria-hidden="true"
            (click)="onArrowButtonClick()"
            (mousedown)="toggleArrowButtonActiveState(true)"
            (mouseup)="toggleArrowButtonActiveState(false)"
            (keydown.enter)="$event.stopImmediatePropagation(); $event.preventDefault();"
        ></button>
        <ng-template #popupTemplate>
            <kendo-button-list
                [id]="listId"
                [data]="data"
                [textField]="textField"
                [itemTemplate]="itemTemplate"
                (onItemClick)="onItemClick($event)"
                (keydown)="keyDownHandler($event)"
                (keyup)="keyUpHandler($event)"
                [attr.dir]="dir"
                [size]="size"
            >
            </kendo-button-list>
        </ng-template>
        <ng-container #container></ng-container>
    `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedSplitButtonMessagesDirective, selector: "[kendoSplitButtonLocalizedMessages]" }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ListComponent, selector: "kendo-button-list", inputs: ["data", "textField", "itemTemplate", "size"], outputs: ["onItemClick", "onItemBlur"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SplitButtonComponent, decorators: [{
            type: Component,
            args: [{
                    exportAs: 'kendoSplitButton',
                    providers: [
                        FocusService,
                        NavigationService,
                        NAVIGATION_SETTINGS_PROVIDER,
                        LocalizationService,
                        {
                            provide: L10N_PREFIX,
                            useValue: 'kendo.splitbutton'
                        },
                        PopupContainerService,
                        {
                            provide: MultiTabStop,
                            useExisting: forwardRef(() => SplitButtonComponent)
                        }
                    ],
                    selector: 'kendo-splitbutton',
                    template: `
        <ng-container kendoSplitButtonLocalizedMessages
            i18n-splitButtonLabel="kendo.splitbutton.splitButtonLabel|The text for the SplitButton aria-label"
            splitButtonLabel="{{ '{buttonText} splitbutton' }}"
        >
        </ng-container>
        <button
            kendoButton
            #button
            [type]="type"
            [tabindex]="componentTabIndex"
            [disabled]="disabled"
            [size]="size"
            [rounded]="rounded"
            [fillMode]="fillMode"
            [themeColor]="themeColor"
            [icon]="icon"
            [svgIcon]="svgIcon"
            [class.k-active]="active"
            [iconClass]="iconClass"
            [imageUrl]="imageUrl"
            [ngClass]="buttonClass"
            (focus)="onButtonFocus($event)"
            (click)="onButtonClick()"
            (blur)="onButtonBlur()"
            (mousedown)="toggleButtonActiveState(true)"
            (mouseup)="toggleButtonActiveState(false)"
            [attr.aria-expanded]="openState"
            [attr.aria-controls]="listId"
            [attr.aria-label]="ariaLabel"
        >
            <span *ngIf="text" class="k-button-text">
                {{ text }} </span><ng-content></ng-content>
        </button>
        <button kendoButton #arrowButton type="button"
            class="k-split-button-arrow"
            [class.k-active]="activeArrow"
            [ngClass]="arrowButtonClass"
            [disabled]="disabled"
            [icon]="arrowButtonIcon"
            [svgIcon]="arrowButtonSvgIcon"
            [size]="size"
            [rounded]="rounded"
            [fillMode]="fillMode"
            [themeColor]="themeColor"
            [tabindex]="-1"
            aria-hidden="true"
            (click)="onArrowButtonClick()"
            (mousedown)="toggleArrowButtonActiveState(true)"
            (mouseup)="toggleArrowButtonActiveState(false)"
            (keydown.enter)="$event.stopImmediatePropagation(); $event.preventDefault();"
        ></button>
        <ng-template #popupTemplate>
            <kendo-button-list
                [id]="listId"
                [data]="data"
                [textField]="textField"
                [itemTemplate]="itemTemplate"
                (onItemClick)="onItemClick($event)"
                (keydown)="keyDownHandler($event)"
                (keyup)="keyUpHandler($event)"
                [attr.dir]="dir"
                [size]="size"
            >
            </kendo-button-list>
        </ng-template>
        <ng-container #container></ng-container>
    `,
                    standalone: true,
                    imports: [LocalizedSplitButtonMessagesDirective, ButtonComponent, NgClass, NgIf, ListComponent]
                }]
        }], ctorParameters: function () { return [{ type: FocusService }, { type: NavigationService }, { type: i0.ElementRef }, { type: i0.NgZone }, { type: i3.PopupService }, { type: i0.ElementRef }, { type: i1.LocalizationService }, { type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }, { type: PopupContainerService }]; }, propDecorators: { text: [{
                type: Input
            }], icon: [{
                type: Input
            }], svgIcon: [{
                type: Input
            }], iconClass: [{
                type: Input
            }], type: [{
                type: Input
            }], imageUrl: [{
                type: Input
            }], size: [{
                type: Input
            }], rounded: [{
                type: Input
            }], fillMode: [{
                type: Input
            }], themeColor: [{
                type: Input
            }], disabled: [{
                type: Input
            }], popupSettings: [{
                type: Input
            }], tabIndex: [{
                type: Input
            }], textField: [{
                type: Input
            }], data: [{
                type: Input
            }], arrowButtonClass: [{
                type: Input
            }], arrowButtonIcon: [{
                type: Input
            }], arrowButtonSvgIcon: [{
                type: Input
            }], buttonAttributes: [{
                type: Input
            }], buttonClick: [{
                type: Output
            }], itemClick: [{
                type: Output
            }], onFocus: [{
                type: Output,
                args: ['focus']
            }], onBlur: [{
                type: Output,
                args: ['blur']
            }], open: [{
                type: Output
            }], close: [{
                type: Output
            }], itemTemplate: [{
                type: ContentChild,
                args: [ButtonItemTemplateDirective]
            }], isFocused: [{
                type: HostBinding,
                args: ['class.k-focus']
            }], widgetClasses: [{
                type: HostBinding,
                args: ['class.k-split-button']
            }, {
                type: HostBinding,
                args: ['class.k-button-group']
            }], dir: [{
                type: HostBinding,
                args: ['attr.dir']
            }], keydown: [{
                type: HostListener,
                args: ['keydown', ['$event']]
            }], keyup: [{
                type: HostListener,
                args: ['keyup', ['$event']]
            }] } });

/**
 * Utility array that contains all `Button` related components and directives
 */
const KENDO_BUTTON = [
    ButtonComponent
];
/**
 * Utility array that contains all `ButtonGroup` related components and directives
 */
const KENDO_BUTTONGROUP = [
    ButtonComponent,
    ButtonGroupComponent
];
/**
 * Utility array that contains all `DropDownButton` related components and directives
 */
const KENDO_DROPDOWNBUTTON = [
    DropDownButtonComponent,
    ButtonItemTemplateDirective
];
/**
 * Utility array that contains all `Chip` related components and directives
 */
const KENDO_CHIP = [
    ChipComponent
];
/**
 * Utility array that contains all `ChipList` related components and directives
 */
const KENDO_CHIPLIST = [
    ChipComponent,
    ChipListComponent
];
/**
 * Utility array that contains all `FloatingActionButton` related components and directives
 */
const KENDO_FLOATINGACTIONBUTTON = [
    FloatingActionButtonComponent,
    DialItemTemplateDirective,
    FloatingActionButtonTemplateDirective
];
/**
 * Utility array that contains all `SplitButton` related components and directives
 */
const KENDO_SPLITBUTTON = [
    SplitButtonComponent,
    SplitButtonCustomMessagesComponent,
    ToggleButtonTabStopDirective,
    ButtonItemTemplateDirective
];
/**
 * Utility array that contains all `@progress/kendo-angular-buttons` related components and directives
 */
const KENDO_BUTTONS = [
    ...KENDO_BUTTON,
    ...KENDO_BUTTONGROUP,
    ...KENDO_DROPDOWNBUTTON,
    ...KENDO_CHIP,
    ...KENDO_CHIPLIST,
    ...KENDO_FLOATINGACTIONBUTTON,
    ...KENDO_SPLITBUTTON
];

//IMPORTANT: NgModule export kept for backwards compatibility
/**
 *
 * The exported package module.
 *
 * The package exports:
 * - `ButtonGroupComponent`&mdash;The ButtonGroup component class.
 * - `ButtonComponent`&mdash;The Button component class.
 */
class ButtonGroupModule {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ButtonGroupModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: ButtonGroupModule, imports: [ButtonComponent, ButtonGroupComponent], exports: [ButtonComponent, ButtonGroupComponent] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ButtonGroupModule, providers: [IconsService], imports: [ButtonComponent] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ButtonGroupModule, decorators: [{
            type: NgModule,
            args: [{
                    exports: [...KENDO_BUTTONGROUP],
                    imports: [...KENDO_BUTTONGROUP],
                    providers: [IconsService]
                }]
        }] });

//IMPORTANT: NgModule export kept for backwards compatibility
/**
 * Represents the [NgModule](link:site.data.urls.angular['ngmodules'])
 * definition for the Button directive.
 *
 * @example
 *
 * ```ts-no-run
 * // Import the Button module
 * import { ButtonModule } from '@progress/kendo-angular-buttons';
 *
 * // The browser platform with a compiler
 * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
 *
 * import { NgModule } from '@angular/core';
 *
 * // Import the app component
 * import { AppComponent } from './app.component';
 *
 * // Define the app module
 * _@NgModule({
 *     declarations: [AppComponent], // declare app component
 *     imports:      [BrowserModule, ButtonModule], // import Button module
 *     bootstrap:    [AppComponent]
 * })
 * export class AppModule {}
 *
 * // Compile and launch the module
 * platformBrowserDynamic().bootstrapModule(AppModule);
 *
 * ```
 */
class ButtonModule {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ButtonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: ButtonModule, imports: [ButtonComponent], exports: [ButtonComponent] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ButtonModule, providers: [IconsService], imports: [ButtonComponent] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ButtonModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [ButtonComponent],
                    exports: [ButtonComponent],
                    providers: [IconsService]
                }]
        }] });

//IMPORTANT: NgModule export kept for backwards compatibility
/**
 * Represents the [NgModule](link:site.data.urls.angular['ngmodules'])
 * definition for the Buttons components.
 *
 * @example
 *
 * ```ts-no-run
 * // Import the Buttons module
 * import { ButtonsModule } from '@progress/kendo-angular-buttons';
 *
 * // The browser platform with a compiler
 * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
 *
 * import { NgModule } from '@angular/core';
 *
 * // Import the app component
 * import { AppComponent } from './app.component';
 *
 * // Define the app module
 * _@NgModule({
 *     declarations: [AppComponent], // declare app component
 *     imports:      [BrowserModule, ButtonsModule], // import Buttons module
 *     bootstrap:    [AppComponent]
 * })
 * export class AppModule {}
 *
 * // Compile and launch the module
 * platformBrowserDynamic().bootstrapModule(AppModule);
 *
 * ```
 */
class ButtonsModule {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ButtonsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: ButtonsModule, imports: [ButtonComponent, ButtonComponent, ButtonGroupComponent, DropDownButtonComponent, ButtonItemTemplateDirective, ChipComponent, ChipComponent, ChipListComponent, FloatingActionButtonComponent, DialItemTemplateDirective, FloatingActionButtonTemplateDirective, SplitButtonComponent, SplitButtonCustomMessagesComponent, i12.ToggleButtonTabStopDirective, ButtonItemTemplateDirective, i12.ToggleButtonTabStopDirective], exports: [ButtonComponent, ButtonComponent, ButtonGroupComponent, DropDownButtonComponent, ButtonItemTemplateDirective, ChipComponent, ChipComponent, ChipListComponent, FloatingActionButtonComponent, DialItemTemplateDirective, FloatingActionButtonTemplateDirective, SplitButtonComponent, SplitButtonCustomMessagesComponent, i12.ToggleButtonTabStopDirective, ButtonItemTemplateDirective, i12.ToggleButtonTabStopDirective] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ButtonsModule, providers: [IconsService, PopupService, ResizeBatchService], imports: [ButtonComponent, ButtonComponent, DropDownButtonComponent, ChipComponent, ChipComponent, FloatingActionButtonComponent, SplitButtonComponent] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ButtonsModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [...KENDO_BUTTONS, ...KENDO_TOGGLEBUTTONTABSTOP],
                    exports: [...KENDO_BUTTONS, ...KENDO_TOGGLEBUTTONTABSTOP],
                    providers: [IconsService, PopupService, ResizeBatchService]
                }]
        }] });

//IMPORTANT: NgModule export kept for backwards compatibility
/**
 *
 * The exported package module.
 *
 * The package exports:
 * - `SplitButtonComponent`&mdash;The SplitButton component class.
 * - `SplitButtonCustomMessagesComponent`&mdash;The SplitButton custom messages component class.
 */
class SplitButtonModule {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SplitButtonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: SplitButtonModule, imports: [SplitButtonComponent, SplitButtonCustomMessagesComponent, i12.ToggleButtonTabStopDirective, ButtonItemTemplateDirective, i12.ToggleButtonTabStopDirective], exports: [SplitButtonComponent, SplitButtonCustomMessagesComponent, i12.ToggleButtonTabStopDirective, ButtonItemTemplateDirective, i12.ToggleButtonTabStopDirective] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SplitButtonModule, providers: [IconsService, PopupService, ResizeBatchService], imports: [SplitButtonComponent] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SplitButtonModule, decorators: [{
            type: NgModule,
            args: [{
                    exports: [...KENDO_SPLITBUTTON, ...KENDO_TOGGLEBUTTONTABSTOP],
                    imports: [...KENDO_SPLITBUTTON, ...KENDO_TOGGLEBUTTONTABSTOP],
                    providers: [IconsService, PopupService, ResizeBatchService]
                }]
        }] });

//IMPORTANT: NgModule export kept for backwards compatibility
/**
 *
 * The exported package module.
 *
 * The package exports:
 * - `DropDownButtonComponent`&mdash;The DropDownButtonComponent component class.
 * - `ButtonItemTemplateDirective`&mdash;The Button item template directive.
 */
class DropDownButtonModule {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DropDownButtonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: DropDownButtonModule, imports: [DropDownButtonComponent, ButtonItemTemplateDirective], exports: [DropDownButtonComponent, ButtonItemTemplateDirective] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DropDownButtonModule, providers: [IconsService, PopupService, ResizeBatchService], imports: [DropDownButtonComponent] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DropDownButtonModule, decorators: [{
            type: NgModule,
            args: [{
                    exports: [...KENDO_DROPDOWNBUTTON],
                    imports: [...KENDO_DROPDOWNBUTTON],
                    providers: [IconsService, PopupService, ResizeBatchService]
                }]
        }] });

//IMPORTANT: NgModule export kept for backwards compatibility
/**
 * Represents the [NgModule](link:site.data.urls.angular['ngmoduleapi'])
 * definition for the Chip and ChipList components.
 *
 * @example
 *
 * ```ts-no-run
 * // Import the Chip module
 * import { ChipModule } from '@progress/kendo-angular-buttons';
 *
 * // The browser platform with a compiler
 * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
 *
 * import { NgModule } from '@angular/core';
 *
 * // Import the app component
 * import { AppComponent } from './app.component';
 *
 * // Define the app module
 * _@NgModule({
 *     declarations: [AppComponent], // declare app component
 *     imports:      [BrowserModule, ChipModule], // import Chip module
 *     bootstrap:    [AppComponent]
 * })
 * export class AppModule {}
 *
 * ```
 */
class ChipModule {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ChipModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: ChipModule, imports: [ChipComponent, ChipListComponent], exports: [ChipComponent, ChipListComponent] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ChipModule, providers: [IconsService], imports: [ChipComponent] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ChipModule, decorators: [{
            type: NgModule,
            args: [{
                    exports: [...KENDO_CHIPLIST],
                    imports: [...KENDO_CHIPLIST],
                    providers: [IconsService]
                }]
        }] });

//IMPORTANT: NgModule export kept for backwards compatibility
/**
 * Represents the [NgModule](link:site.data.urls.angular['ngmoduleapi'])
 * definition for the FloatingActionButton component.
 *
 * @example
 *
 * ```ts-no-run
 * // Import the FloatingActionButton module
 * import { FloatingActionButtonModule } from '@progress/kendo-angular-buttons';
 *
 * // The browser platform with a compiler
 * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
 *
 * import { NgModule } from '@angular/core';
 *
 * // Import the app component
 * import { AppComponent } from './app.component';
 *
 * // Define the app module
 * _@NgModule({
 *     declarations: [AppComponent], // declare app component
 *     imports:      [BrowserModule, FloatingActionButtonModule], // import FloatingActionButton module
 *     bootstrap:    [AppComponent]
 * })
 * export class AppModule {}
 *
 * ```
 */
class FloatingActionButtonModule {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FloatingActionButtonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: FloatingActionButtonModule, imports: [FloatingActionButtonComponent, DialItemTemplateDirective, FloatingActionButtonTemplateDirective], exports: [FloatingActionButtonComponent, DialItemTemplateDirective, FloatingActionButtonTemplateDirective] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FloatingActionButtonModule, providers: [IconsService, PopupService, ResizeBatchService], imports: [FloatingActionButtonComponent] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FloatingActionButtonModule, decorators: [{
            type: NgModule,
            args: [{
                    exports: [...KENDO_FLOATINGACTIONBUTTON],
                    imports: [...KENDO_FLOATINGACTIONBUTTON],
                    providers: [IconsService, PopupService, ResizeBatchService]
                }]
        }] });

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

export { ButtonComponent as Button, ButtonComponent, ButtonComponent as ButtonDirective, ButtonGroupComponent as ButtonGroup, ButtonGroupComponent, ButtonGroupModule, ButtonItemTemplateDirective, ButtonModule, ButtonsModule, ChipComponent, ChipListComponent, ChipModule, DialItemTemplateDirective, DropDownButtonComponent as DropDownButton, DropDownButtonComponent, DropDownButtonModule, FloatingActionButtonComponent, FloatingActionButtonModule, FloatingActionButtonTemplateDirective, FocusableDirective, KENDO_BUTTON, KENDO_BUTTONGROUP, KENDO_BUTTONS, KENDO_CHIP, KENDO_CHIPLIST, KENDO_DROPDOWNBUTTON, KENDO_FLOATINGACTIONBUTTON, KENDO_SPLITBUTTON, ListComponent, LocalizedSplitButtonMessagesDirective, PreventableEvent, SplitButtonComponent as SplitButton, SplitButtonComponent, SplitButtonCustomMessagesComponent, SplitButtonModule };