// #region Imports
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Appearanceable } from '../../../Behaviors/Appearanceable';
import { Closeable } from '../../../Behaviors/Closeable';
import { Disableable } from '../../../Behaviors/Disableable';
import { Iconable } from '../../../Behaviors/Iconable';
import { Labelable } from '../../../Behaviors/Labelable';
import { Openable } from '../../../Behaviors/Openable';
import { Slottable } from '../../../Behaviors/Slottable';
import { Themeable } from '../../../Behaviors/Themeable';
import { Variantable } from '../../../Behaviors/Variantable';
import { ClickOutsideController } from '../../../Controllers/ClickOutsideController';
import { addInheritanceProviderController } from '../../../Controllers/InheritanceProviderController';
import { Attribute } from '../../../Decorators/AttributeDecorator';
import { Component } from '../../../Decorators/ComponentDecorator';
import { FabGroupDirection } from '../../../Types/FabGroupDirection';
import { CustomElement } from '../../Abstracts/CustomElement';
import { FloatingActionButtonElement } from './FloatingActionButtonElement';
import { floatingActionButtonGroupElementTemplate } from './FloatingActionButtonGroupElementTemplate';
import { FAB_GROUP_INHERITANCE_CONTEXT } from './FloatingActionButtonGroupInheritanceContext';
import { floatingActionButtonGroupElementCosmopolitanStyle } from './Themes/FloatingActionButtonGroupElement.Cosmopolitan';
import { floatingActionButtonGroupElementJoyStyle } from './Themes/FloatingActionButtonGroupElement.Joy';
import { floatingActionButtonGroupElementMemphisStyle } from './Themes/FloatingActionButtonGroupElement.Memphis';
// #endregion
/**
 * Floating Action Button Group - A group of Floating Action Buttons that trigger primary actions in an application.
 *
 * @description
 * The Floating Action Button Group is a UI component that organizes multiple Floating Action Buttons (FABs) into a
 * cohesive group. This component is designed to provide users with multiple primary actions in a compact and accessible
 * format. Each button within the group can trigger a different action, making it ideal for applications that require
 * multiple high-priority actions to be easily accessible.
 *
 * @name Floating Action Button Group
 * @element mosaik-fab-group
 * @category Buttons
 *
 * @fires opened {OpenedEvent} - Called when the FAB group is opened.
 * @fires closed {ClosedEvent} - Called when the FAB group is closed.
 *
 * @slot trigger - The trigger slot for initiating the FAB group.
 * @slot - The default slot for FABs.
 * @slot overlay - The overlay slot (useful for badges or additional visual elements).
 *
 * @csspart fab - The FAB part within the group.
 * @csspart menu - The menu part of the FAB group.
 *
 * @cssprop {String} --fab-group-font-family - The font family of the FAB group.
 * @cssprop {String} --fab-group-font-size - The font size of the FAB group.
 * @cssprop {String} --fab-group-font-line-height - The font line height of the FAB group.
 * @cssprop {String} --fab-group-font-weight - The font weight of the FAB group.
 * @cssprop {String} --fab-group-font-letter-spacing - The font letter spacing of the FAB group.
 * @cssprop {String} --fab-group-font-text-decoration - The font text decoration of the FAB group.
 * @cssprop {String} --fab-group-font-text-transform - The font text transform of the FAB group.
 * @cssprop {String} --fab-group-transition-duration - The transition duration of the FAB group.
 * @cssprop {String} --fab-group-transition-mode - The transition mode of the FAB group.
 * @cssprop {String} --fab-group-transition-property - The transition property of the FAB group.
 *
 * @dependency {FloatingActionButtonElement} mosaik-fab - The Floating Action Button component.
 *
 * @example
 * ```html
 * <mosaik-fab-group>
 *   <mosaik-fab label="Button 1"></mosaik-fab>
 *   <mosaik-fab label="Button 2"></mosaik-fab>
 *   <mosaik-fab label="Button 3"></mosaik-fab>
 * </mosaik-fab-group>
 * ```
 *
 * @public
 */
let FloatingActionButtonGroupElement = class FloatingActionButtonGroupElement extends Themeable(Openable(Closeable(Disableable(Appearanceable(Variantable(Labelable(Iconable(Slottable(CustomElement))))))))) {
    // #region Fields
    _provider = addInheritanceProviderController(this, {
        context: FAB_GROUP_INHERITANCE_CONTEXT,
        values: () => ({
            disabled: this.disabled,
            appearance: this.appearance,
            variant: this.variant
        })
    });
    _clickOutsideController;
    _isOpen;
    _direction;
    // #endregion
    // #region Ctor
    /**
     * @public
     */
    constructor() {
        super();
        this._isOpen = false;
        this._direction = FabGroupDirection.Top;
        this._clickOutsideController = new ClickOutsideController(this, {
            skipInitial: true,
            callback: () => this.onClickedOutside()
        });
    }
    // #endregion
    // #region Properties
    /**
     * Returns the `{@link is}` property.
     * The `{@link is}` property represents natural name of this element.
     *
     * @public
     * @static
     * @readonly
     */
    static get is() {
        return 'mosaik-fab-group';
    }
    /**
     * Gets or sets the `isOpen` property that allows you to show or hide the `FloatingActionButtonGroupElement` menu.
     *
     * @public
     */
    get isOpen() {
        return this._isOpen;
    }
    set isOpen(value) {
        if (this._isOpen !== value) {
            if (value) {
                void this.open();
            }
            else {
                void this.close();
            }
        }
    }
    /**
     * Gets or sets the `direction` property.
     *
     * @public
     */
    get direction() {
        return this._direction;
    }
    set direction(value) {
        if (this._direction !== value) {
            this._direction = value;
            this.requestUpdate('direction');
        }
    }
    // #endregion
    // #region Methods
    /**
     * @public
     * @override
     */
    onSlotChanges() {
        const elements = this.getSlotAssignments('')
            .filter((x) => x instanceof FloatingActionButtonElement);
        for (const [i, e] of elements.entries()) {
            e.tabIndex = this.isOpen ? 0 : -1;
            e.style.transitionDelay = `${this.isOpen ? i * 25 : 0}ms`;
            e.classList.add('fab-group-button');
            e.classList.toggle('first', i === 0);
            e.classList.toggle('inner', i > 0 && i < elements.length - 1);
            e.classList.toggle('last', i === elements.length - 1);
        }
    }
    /**
     * Opens the FAB group.
     *
     * @public
     * @override
     */
    async open() {
        if (this.disabled) {
            return;
        }
        if (this._isOpen) {
            return;
        }
        return super.open()
            .then(() => {
            this._isOpen = true;
            this.requestUpdate('isOpen');
        })
            .then(() => {
            this._clickOutsideController.observe();
        });
    }
    /**
     * Close the FAB group.
     *
     * @public
     * @override
     */
    async close() {
        if (this.disabled) {
            return false;
        }
        if (!this._isOpen) {
            return false;
        }
        return super.close()
            .then((x) => {
            this._isOpen = false;
            this.requestUpdate('isOpen');
            return x;
        })
            .then((x) => {
            this._clickOutsideController.unobserve();
            return x;
        });
    }
    /**
     * Toggles the FAB group.
     *
     * @public
     */
    async toggle() {
        if (this._isOpen) {
            return this.close().then(() => void 0);
        }
        return this.open();
    }
    /**
     * @private
     */
    onClickedOutside() {
        void this.close();
    }
};
__decorate([
    Attribute({
        type: Boolean,
        useDefault: true
    }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], FloatingActionButtonGroupElement.prototype, "isOpen", null);
__decorate([
    Attribute({ type: FabGroupDirection }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], FloatingActionButtonGroupElement.prototype, "direction", null);
FloatingActionButtonGroupElement = __decorate([
    Component({
        selector: 'mosaik-fab-group',
        template: floatingActionButtonGroupElementTemplate,
        themes: {
            joy: floatingActionButtonGroupElementJoyStyle,
            memphis: floatingActionButtonGroupElementMemphisStyle,
            cosmopolitan: floatingActionButtonGroupElementCosmopolitanStyle
        },
        host: {
            role: 'group'
        },
        imports: [FloatingActionButtonElement]
    }),
    __metadata("design:paramtypes", [])
], FloatingActionButtonGroupElement);
export { FloatingActionButtonGroupElement };
//# sourceMappingURL=FloatingActionButtonGroupElement.js.map