/**
 * @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);
};
var ElSidebarComponent_1;
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.
 */
let ElSidebarHeaderComponent = class ElSidebarHeaderComponent {
};
ElSidebarHeaderComponent = __decorate([
    Component({
        selector: 'el-sidebar-header',
        template: `
    <ng-content></ng-content>
  `
    })
], 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.
 */
let ElSidebarFooterComponent = class ElSidebarFooterComponent {
};
ElSidebarFooterComponent = __decorate([
    Component({
        selector: 'el-sidebar-footer',
        template: `
    <ng-content></ng-content>
  `
    })
], 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:
 */
let ElSidebarComponent = ElSidebarComponent_1 = class ElSidebarComponent {
    constructor(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;
    }
    // TODO: rename stateValue to state (take a look to the card component)
    get expanded() {
        return this.stateValue === ElSidebarComponent_1.STATE_EXPANDED;
    }
    get collapsed() {
        return this.stateValue === ElSidebarComponent_1.STATE_COLLAPSED;
    }
    get compacted() {
        return this.stateValue === ElSidebarComponent_1.STATE_COMPACTED;
    }
    /**
     * Places sidebar on the right side
     * @type {boolean}
     */
    set right(val) {
        this.rightValue = convertToBoolProperty(val);
        this.leftValue = !this.rightValue;
        this.startValue = false;
        this.endValue = false;
    }
    /**
     * Places sidebar on the left side
     * @type {boolean}
     */
    set left(val) {
        this.leftValue = convertToBoolProperty(val);
        this.rightValue = !this.leftValue;
        this.startValue = false;
        this.endValue = false;
    }
    /**
     * Places sidebar on the start edge of layout
     * @type {boolean}
     */
    set start(val) {
        this.startValue = convertToBoolProperty(val);
        this.endValue = !this.startValue;
        this.leftValue = false;
        this.rightValue = false;
    }
    /**
     * Places sidebar on the end edge of layout
     * @type {boolean}
     */
    set end(val) {
        this.endValue = convertToBoolProperty(val);
        this.startValue = !this.endValue;
        this.leftValue = false;
        this.rightValue = false;
    }
    /**
     * Makes sidebar fixed (shown above the layout content)
     * @type {boolean}
     */
    set fixed(val) {
        this.fixedValue = convertToBoolProperty(val);
    }
    /**
     * Makes sidebar container fixed
     * @type {boolean}
     */
    set containerFixed(val) {
        this.containerFixedValue = convertToBoolProperty(val);
    }
    /**
     * Initial sidebar state, `expanded`|`collapsed`|`compacted`
     * @type {string}
     */
    set state(val) {
        this.stateValue = val;
    }
    /**
     * Makes sidebar listen to media query events and change its behaviour
     * @type {boolean}
     */
    set responsive(val) {
        this.responsiveValue = convertToBoolProperty(val);
    }
    toggleResponsive(enabled) {
        if (enabled) {
            this.mediaQuerySubscription = this.onMediaQueryChanges();
        }
        else if (this.mediaQuerySubscription) {
            this.mediaQuerySubscription.unsubscribe();
        }
    }
    ngOnChanges(changes) {
        if (changes.responsive) {
            this.toggleResponsive(this.responsiveValue);
        }
    }
    ngOnInit() {
        this.sidebarService.onToggle()
            .pipe(takeWhile(() => this.alive))
            .subscribe((data) => {
            if (!this.tag || this.tag === data.tag) {
                this.toggle(data.compact);
            }
        });
        this.sidebarService.onExpand()
            .pipe(takeWhile(() => this.alive))
            .subscribe((data) => {
            if (!this.tag || this.tag === data.tag) {
                this.expand();
            }
        });
        this.sidebarService.onCollapse()
            .pipe(takeWhile(() => this.alive))
            .subscribe((data) => {
            if (!this.tag || this.tag === data.tag) {
                this.collapse();
            }
        });
        this.sidebarService.onCompact()
            .pipe(takeWhile(() => this.alive))
            .subscribe((data) => {
            if (!this.tag || this.tag === data.tag) {
                this.compact();
            }
        });
    }
    ngOnDestroy() {
        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
    onClick(event) {
        const menu = this.element.nativeElement.querySelector('el-menu');
        if (menu && menu.contains(event.target)) {
            const link = this.getMenuLink(event.target);
            if (link && link.nextElementSibling && link.nextElementSibling.classList.contains('menu-items')) {
                this.sidebarService.expand(this.tag);
            }
        }
    }
    /**
     * Collapses the sidebar
     */
    collapse() {
        this.state = ElSidebarComponent_1.STATE_COLLAPSED;
    }
    /**
     * Expands the sidebar
     */
    expand() {
        this.state = ElSidebarComponent_1.STATE_EXPANDED;
    }
    /**
     * Compacts the sidebar (minimizes)
     */
    compact() {
        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);
     * ```
     */
    toggle(compact = false) {
        if (this.responsiveEnabled()) {
            if (this.responsiveState === ElSidebarComponent_1.RESPONSIVE_STATE_MOBILE) {
                compact = false;
            }
        }
        const 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;
        }
    }
    onMediaQueryChanges() {
        return this.themeService.onMediaQueryChange()
            .subscribe(([prev, current]) => {
            const isCollapsed = this.collapsedBreakpoints.includes(current.name);
            const 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;
            }
        });
    }
    responsiveEnabled() {
        return this.responsiveValue;
    }
    getMenuLink(element) {
        if (!element || element.tagName.toLowerCase() === 'el-menu') {
            return;
        }
        if (element.tagName.toLowerCase() === 'a') {
            return element;
        }
        return this.getMenuLink(element.parentElement);
    }
};
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: `
    <div class="main-container"
         [class.main-container-fixed]="containerFixedValue">
      <ng-content select="el-sidebar-header"></ng-content>
      <div class="scrollable" (click)="onClick($event)">
        <ng-content></ng-content>
      </div>
      <ng-content select="el-sidebar-footer"></ng-content>
    </div>
  `,
        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);
export { ElSidebarComponent };
//# sourceMappingURL=sidebar.component.js.map