/**
 * @license
 * Copyright Endlessjs. All Rights Reserved.
 * Licensed under the MIT License. See License.txt in the project root for license information.
 */
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 { Component, HostBinding, Input, ElementRef } from '@angular/core';
import { takeWhile } from 'rxjs/operators';
import { convertToBoolProperty } from '../helpers';
import { ElThemeService } from '../../services/theme.service';
import { ElSidebarService } from './sidebar.service';
/**
 * Sidebar header container.
 *
 * Placeholder which contains a sidebar header content,
 * placed at the very top of the sidebar outside of the scroll area.
 */
var ElSidebarHeaderComponent = /** @class */ (function () {
    function ElSidebarHeaderComponent() {
    }
    ElSidebarHeaderComponent = __decorate([
        Component({
            selector: 'el-sidebar-header',
            template: "\n    <ng-content></ng-content>\n  "
        })
    ], ElSidebarHeaderComponent);
    return ElSidebarHeaderComponent;
}());
export { ElSidebarHeaderComponent };
/**
 * Sidebar footer container.
 *
 * Placeholder which contains a sidebar footer content,
 * placed at the very bottom of the sidebar outside of the scroll area.
 */
var ElSidebarFooterComponent = /** @class */ (function () {
    function ElSidebarFooterComponent() {
    }
    ElSidebarFooterComponent = __decorate([
        Component({
            selector: 'el-sidebar-footer',
            template: "\n    <ng-content></ng-content>\n  "
        })
    ], ElSidebarFooterComponent);
    return ElSidebarFooterComponent;
}());
export { ElSidebarFooterComponent };
/**
 * Layout sidebar component.
 *
 * @stacked-example(Showcase, sidebar/sidebar-showcase.component)
 *
 * ### Installation
 *
 * Import `ElSidebarModule.forRoot()` to your app module.
 * ```ts
 * @NgModule({
 *   imports: [
 *     // ...
 *     ElSidebarModule.forRoot(),
 *   ],
 * })
 * export class AppModule { }
 * ```
 * and `ElSidebarModule` to your feature module where the component should be shown:
 * ```ts
 * @NgModule({
 *   imports: [
 *     // ...
 *     ElSidebarModule,
 *   ],
 * })
 * export class PageModule { }
 * ```
 * ### Usage
 *
 * Sidebar can be placed on the left or the right side of the layout,
 * or on start/end position of layout (depends on document direction, left to right or right to left)
 * It can be fixed (shown above the content) or can push the layout when opened.
 *
 * There are three states - `expanded`, `collapsed`, `compacted`.
 * By default sidebar content is fixed and saves its position while the page is being scrolled.
 *
 * Compacted sidebar example:
 * @stacked-example(Compacted Sidebar, sidebar/sidebar-compacted.component)
 *
 * Sidebar also supports a `responsive` behavior, listening to window size change and changing its size respectably.
 *
 * In a pair with header it is possible to setup a configuration when header is placed on a side of the sidebar
 * and not on top of it. To achieve this simply put a `subheader` property to the header like this:
 * ```html
 * <el-layout-header subheader></el-layout-header>
 * ```
 * @stacked-example(Subheader, layout/layout-sidebar-subheader.component)
 * Note that in such configuration sidebar shadow is removed and header cannot be make `fixed`.
 *
 * @additional-example(Right Sidebar, sidebar/sidebar-right.component)
 * @additional-example(Fixed Sidebar, sidebar/sidebar-fixed.component)
 *
 * @styles
 *
 * sidebar-background-color:
 * sidebar-text-color:
 * sidebar-text-font-family:
 * sidebar-text-font-size:
 * sidebar-text-font-weight:
 * sidebar-text-line-height:
 * sidebar-height:
 * sidebar-width:
 * sidebar-width-compact:
 * sidebar-padding:
 * sidebar-header-height:
 * sidebar-footer-height:
 * sidebar-shadow:
 * sidebar-menu-item-highlight-color:
 * sidebar-scrollbar-background-color:
 * sidebar-scrollbar-color:
 * sidebar-scrollbar-width:
 */
var ElSidebarComponent = /** @class */ (function () {
    function ElSidebarComponent(sidebarService, themeService, element) {
        this.sidebarService = sidebarService;
        this.themeService = themeService;
        this.element = element;
        this.responsiveValue = false;
        this.alive = true;
        this.containerFixedValue = true;
        this.fixedValue = false;
        this.rightValue = false;
        this.leftValue = true;
        this.startValue = false;
        this.endValue = false;
        // TODO: get width by the key and define only max width for the tablets and mobiles
        /**
         * Controls on which screen sizes sidebar should be switched to compacted state.
         * Works only when responsive mode is on.
         * Default values are `['xs', 'is', 'sm', 'md', 'lg']`.
         *
         * @type string[]
         */
        this.compactedBreakpoints = ['xs', 'is', 'sm', 'md', 'lg'];
        /**
         * Controls on which screen sizes sidebar should be switched to collapsed state.
         * Works only when responsive mode is on.
         * Default values are `['xs', 'is']`.
         *
         * @type string[]
         */
        this.collapsedBreakpoints = ['xs', 'is'];
        this.responsiveState = ElSidebarComponent_1.RESPONSIVE_STATE_PC;
    }
    ElSidebarComponent_1 = ElSidebarComponent;
    Object.defineProperty(ElSidebarComponent.prototype, "expanded", {
        // TODO: rename stateValue to state (take a look to the card component)
        get: function () {
            return this.stateValue === ElSidebarComponent_1.STATE_EXPANDED;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ElSidebarComponent.prototype, "collapsed", {
        get: function () {
            return this.stateValue === ElSidebarComponent_1.STATE_COLLAPSED;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ElSidebarComponent.prototype, "compacted", {
        get: function () {
            return this.stateValue === ElSidebarComponent_1.STATE_COMPACTED;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ElSidebarComponent.prototype, "right", {
        /**
         * Places sidebar on the right side
         * @type {boolean}
         */
        set: function (val) {
            this.rightValue = convertToBoolProperty(val);
            this.leftValue = !this.rightValue;
            this.startValue = false;
            this.endValue = false;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ElSidebarComponent.prototype, "left", {
        /**
         * Places sidebar on the left side
         * @type {boolean}
         */
        set: function (val) {
            this.leftValue = convertToBoolProperty(val);
            this.rightValue = !this.leftValue;
            this.startValue = false;
            this.endValue = false;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ElSidebarComponent.prototype, "start", {
        /**
         * Places sidebar on the start edge of layout
         * @type {boolean}
         */
        set: function (val) {
            this.startValue = convertToBoolProperty(val);
            this.endValue = !this.startValue;
            this.leftValue = false;
            this.rightValue = false;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ElSidebarComponent.prototype, "end", {
        /**
         * Places sidebar on the end edge of layout
         * @type {boolean}
         */
        set: function (val) {
            this.endValue = convertToBoolProperty(val);
            this.startValue = !this.endValue;
            this.leftValue = false;
            this.rightValue = false;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ElSidebarComponent.prototype, "fixed", {
        /**
         * Makes sidebar fixed (shown above the layout content)
         * @type {boolean}
         */
        set: function (val) {
            this.fixedValue = convertToBoolProperty(val);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ElSidebarComponent.prototype, "containerFixed", {
        /**
         * Makes sidebar container fixed
         * @type {boolean}
         */
        set: function (val) {
            this.containerFixedValue = convertToBoolProperty(val);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ElSidebarComponent.prototype, "state", {
        /**
         * Initial sidebar state, `expanded`|`collapsed`|`compacted`
         * @type {string}
         */
        set: function (val) {
            this.stateValue = val;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ElSidebarComponent.prototype, "responsive", {
        /**
         * Makes sidebar listen to media query events and change its behaviour
         * @type {boolean}
         */
        set: function (val) {
            this.responsiveValue = convertToBoolProperty(val);
        },
        enumerable: true,
        configurable: true
    });
    ElSidebarComponent.prototype.toggleResponsive = function (enabled) {
        if (enabled) {
            this.mediaQuerySubscription = this.onMediaQueryChanges();
        }
        else if (this.mediaQuerySubscription) {
            this.mediaQuerySubscription.unsubscribe();
        }
    };
    ElSidebarComponent.prototype.ngOnChanges = function (changes) {
        if (changes.responsive) {
            this.toggleResponsive(this.responsiveValue);
        }
    };
    ElSidebarComponent.prototype.ngOnInit = function () {
        var _this = this;
        this.sidebarService.onToggle()
            .pipe(takeWhile(function () { return _this.alive; }))
            .subscribe(function (data) {
            if (!_this.tag || _this.tag === data.tag) {
                _this.toggle(data.compact);
            }
        });
        this.sidebarService.onExpand()
            .pipe(takeWhile(function () { return _this.alive; }))
            .subscribe(function (data) {
            if (!_this.tag || _this.tag === data.tag) {
                _this.expand();
            }
        });
        this.sidebarService.onCollapse()
            .pipe(takeWhile(function () { return _this.alive; }))
            .subscribe(function (data) {
            if (!_this.tag || _this.tag === data.tag) {
                _this.collapse();
            }
        });
        this.sidebarService.onCompact()
            .pipe(takeWhile(function () { return _this.alive; }))
            .subscribe(function (data) {
            if (!_this.tag || _this.tag === data.tag) {
                _this.compact();
            }
        });
    };
    ElSidebarComponent.prototype.ngOnDestroy = function () {
        this.alive = false;
        if (this.mediaQuerySubscription) {
            this.mediaQuerySubscription.unsubscribe();
        }
    };
    // TODO: this is more of a workaround, should be a better way to make components communicate to each other
    ElSidebarComponent.prototype.onClick = function (event) {
        var menu = this.element.nativeElement.querySelector('el-menu');
        if (menu && menu.contains(event.target)) {
            var link = this.getMenuLink(event.target);
            if (link && link.nextElementSibling && link.nextElementSibling.classList.contains('menu-items')) {
                this.sidebarService.expand(this.tag);
            }
        }
    };
    /**
     * Collapses the sidebar
     */
    ElSidebarComponent.prototype.collapse = function () {
        this.state = ElSidebarComponent_1.STATE_COLLAPSED;
    };
    /**
     * Expands the sidebar
     */
    ElSidebarComponent.prototype.expand = function () {
        this.state = ElSidebarComponent_1.STATE_EXPANDED;
    };
    /**
     * Compacts the sidebar (minimizes)
     */
    ElSidebarComponent.prototype.compact = function () {
        this.state = ElSidebarComponent_1.STATE_COMPACTED;
    };
    /**
     * Toggles sidebar state (expanded|collapsed|compacted)
     * @param {boolean} compact If true, then sidebar state will be changed between expanded & compacted,
     * otherwise - between expanded & collapsed. False by default.
     *
     * Toggle sidebar state
     *
     * ```ts
     * this.sidebar.toggle(true);
     * ```
     */
    ElSidebarComponent.prototype.toggle = function (compact) {
        if (compact === void 0) { compact = false; }
        if (this.responsiveEnabled()) {
            if (this.responsiveState === ElSidebarComponent_1.RESPONSIVE_STATE_MOBILE) {
                compact = false;
            }
        }
        var closedStates = [ElSidebarComponent_1.STATE_COMPACTED, ElSidebarComponent_1.STATE_COLLAPSED];
        if (compact) {
            this.state = closedStates.includes(this.stateValue) ?
                ElSidebarComponent_1.STATE_EXPANDED : ElSidebarComponent_1.STATE_COMPACTED;
        }
        else {
            this.state = closedStates.includes(this.stateValue) ?
                ElSidebarComponent_1.STATE_EXPANDED : ElSidebarComponent_1.STATE_COLLAPSED;
        }
    };
    ElSidebarComponent.prototype.onMediaQueryChanges = function () {
        var _this = this;
        return this.themeService.onMediaQueryChange()
            .subscribe(function (_a) {
            var prev = _a[0], current = _a[1];
            var isCollapsed = _this.collapsedBreakpoints.includes(current.name);
            var isCompacted = _this.compactedBreakpoints.includes(current.name);
            if (isCompacted) {
                _this.fixed = _this.containerFixedValue;
                _this.compact();
                _this.responsiveState = ElSidebarComponent_1.RESPONSIVE_STATE_TABLET;
            }
            if (isCollapsed) {
                _this.fixed = true;
                _this.collapse();
                _this.responsiveState = ElSidebarComponent_1.RESPONSIVE_STATE_MOBILE;
            }
            if (!isCollapsed && !isCompacted && prev.width < current.width) {
                _this.expand();
                _this.fixed = false;
                _this.responsiveState = ElSidebarComponent_1.RESPONSIVE_STATE_PC;
            }
        });
    };
    ElSidebarComponent.prototype.responsiveEnabled = function () {
        return this.responsiveValue;
    };
    ElSidebarComponent.prototype.getMenuLink = function (element) {
        if (!element || element.tagName.toLowerCase() === 'el-menu') {
            return;
        }
        if (element.tagName.toLowerCase() === 'a') {
            return element;
        }
        return this.getMenuLink(element.parentElement);
    };
    var ElSidebarComponent_1;
    ElSidebarComponent.STATE_EXPANDED = 'expanded';
    ElSidebarComponent.STATE_COLLAPSED = 'collapsed';
    ElSidebarComponent.STATE_COMPACTED = 'compacted';
    ElSidebarComponent.RESPONSIVE_STATE_MOBILE = 'mobile';
    ElSidebarComponent.RESPONSIVE_STATE_TABLET = 'tablet';
    ElSidebarComponent.RESPONSIVE_STATE_PC = 'pc';
    __decorate([
        HostBinding('class.fixed'),
        __metadata("design:type", Boolean)
    ], ElSidebarComponent.prototype, "fixedValue", void 0);
    __decorate([
        HostBinding('class.right'),
        __metadata("design:type", Boolean)
    ], ElSidebarComponent.prototype, "rightValue", void 0);
    __decorate([
        HostBinding('class.left'),
        __metadata("design:type", Boolean)
    ], ElSidebarComponent.prototype, "leftValue", void 0);
    __decorate([
        HostBinding('class.start'),
        __metadata("design:type", Boolean)
    ], ElSidebarComponent.prototype, "startValue", void 0);
    __decorate([
        HostBinding('class.end'),
        __metadata("design:type", Boolean)
    ], ElSidebarComponent.prototype, "endValue", void 0);
    __decorate([
        HostBinding('class.expanded'),
        __metadata("design:type", Object),
        __metadata("design:paramtypes", [])
    ], ElSidebarComponent.prototype, "expanded", null);
    __decorate([
        HostBinding('class.collapsed'),
        __metadata("design:type", Object),
        __metadata("design:paramtypes", [])
    ], ElSidebarComponent.prototype, "collapsed", null);
    __decorate([
        HostBinding('class.compacted'),
        __metadata("design:type", Object),
        __metadata("design:paramtypes", [])
    ], ElSidebarComponent.prototype, "compacted", null);
    __decorate([
        Input(),
        __metadata("design:type", Boolean),
        __metadata("design:paramtypes", [Boolean])
    ], ElSidebarComponent.prototype, "right", null);
    __decorate([
        Input(),
        __metadata("design:type", Boolean),
        __metadata("design:paramtypes", [Boolean])
    ], ElSidebarComponent.prototype, "left", null);
    __decorate([
        Input(),
        __metadata("design:type", Boolean),
        __metadata("design:paramtypes", [Boolean])
    ], ElSidebarComponent.prototype, "start", null);
    __decorate([
        Input(),
        __metadata("design:type", Boolean),
        __metadata("design:paramtypes", [Boolean])
    ], ElSidebarComponent.prototype, "end", null);
    __decorate([
        Input(),
        __metadata("design:type", Boolean),
        __metadata("design:paramtypes", [Boolean])
    ], ElSidebarComponent.prototype, "fixed", null);
    __decorate([
        Input(),
        __metadata("design:type", Boolean),
        __metadata("design:paramtypes", [Boolean])
    ], ElSidebarComponent.prototype, "containerFixed", null);
    __decorate([
        Input(),
        __metadata("design:type", String),
        __metadata("design:paramtypes", [String])
    ], ElSidebarComponent.prototype, "state", null);
    __decorate([
        Input(),
        __metadata("design:type", Boolean),
        __metadata("design:paramtypes", [Boolean])
    ], ElSidebarComponent.prototype, "responsive", null);
    __decorate([
        Input(),
        __metadata("design:type", String)
    ], ElSidebarComponent.prototype, "tag", void 0);
    __decorate([
        Input(),
        __metadata("design:type", Array)
    ], ElSidebarComponent.prototype, "compactedBreakpoints", void 0);
    __decorate([
        Input(),
        __metadata("design:type", Array)
    ], ElSidebarComponent.prototype, "collapsedBreakpoints", void 0);
    ElSidebarComponent = ElSidebarComponent_1 = __decorate([
        Component({
            selector: 'el-sidebar',
            template: "\n    <div class=\"main-container\"\n         [class.main-container-fixed]=\"containerFixedValue\">\n      <ng-content select=\"el-sidebar-header\"></ng-content>\n      <div class=\"scrollable\" (click)=\"onClick($event)\">\n        <ng-content></ng-content>\n      </div>\n      <ng-content select=\"el-sidebar-footer\"></ng-content>\n    </div>\n  ",
            styles: [":host{display:flex;flex-direction:column;overflow:hidden;z-index:auto;order:0}:host .scrollable{overflow-y:auto;overflow-x:hidden;flex:1}:host .main-container{transform:translate3d(0, 0, 0);display:flex;flex-direction:column}:host .main-container-fixed{position:fixed}:host.right{margin-right:0;margin-left:auto}[dir=ltr] :host.right{order:4}[dir=rtl] :host.right{order:0}:host.end{order:4}[dir=ltr] :host.end{margin-right:0;margin-left:auto}[dir=rtl] :host.end{margin-left:0;margin-right:auto}:host.fixed{position:fixed;height:100%;z-index:999;top:0;bottom:0;left:0}:host.fixed.right{right:0}[dir=ltr] :host.fixed.start{left:0}[dir=rtl] :host.fixed.start{right:0}[dir=ltr] :host.fixed.end{right:0}[dir=rtl] :host.fixed.end{left:0}:host ::ng-deep el-sidebar-footer{margin-top:auto;display:block}:host ::ng-deep el-sidebar-header{display:block}\n"]
        }),
        __metadata("design:paramtypes", [ElSidebarService,
            ElThemeService,
            ElementRef])
    ], ElSidebarComponent);
    return ElSidebarComponent;
}());
export { ElSidebarComponent };
//# sourceMappingURL=sidebar.component.js.map