clr-angular-static-fix
Version:
1. Install Clarity Icons package through npm:
172 lines (148 loc) • 6 kB
text/typescript
/*
* Copyright (c) 2016-2018 VMware, Inc. All Rights Reserved.
* This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project.
*/
import { animate, AnimationEvent, state, style, transition, trigger } from '@angular/animations';
import { AfterContentInit, Component, EventEmitter, HostBinding, Input, OnDestroy, Output } from '@angular/core';
import { Subscription } from 'rxjs';
import { Expand } from '../../utils/expand/providers/expand';
import { VerticalNavGroupRegistrationService } from './providers/vertical-nav-group-registration.service';
import { VerticalNavGroupService } from './providers/vertical-nav-group.service';
import { VerticalNavService } from './providers/vertical-nav.service';
const EXPANDED_STATE: string = 'expanded';
const COLLAPSED_STATE: string = 'collapsed';
export class ClrVerticalNavGroup implements AfterContentInit, OnDestroy {
constructor(
private _itemExpand: Expand,
private _navGroupRegistrationService: VerticalNavGroupRegistrationService,
private _navGroupService: VerticalNavGroupService,
private _navService: VerticalNavService
) {
this._navGroupRegistrationService.registerNavGroup();
// FIXME: This subscription handles a corner case
// Vertical Nav collapse requires the animation to run first and then
// remove the nodes from the DOM. If the user directly sets the input
// on the clrIfExpanded directive, we have no chance to run the animation
// and wait for it to complete. This subscription makes sure that the
// animation states are correct for that edge case.
this._subscriptions.push(
this._itemExpand.expandChange.subscribe(value => {
if (value && this.expandAnimationState === COLLAPSED_STATE) {
if (this._navService.collapsed) {
this._navService.collapsed = false;
}
this.expandAnimationState = EXPANDED_STATE;
} else if (!value && this.expandAnimationState === EXPANDED_STATE) {
this.expandAnimationState = COLLAPSED_STATE;
}
})
);
// 1. If the nav is collapsing, close the open nav group + save its state
// 2. If the nav is expanding, expand the nav group if the previous state was expanded
this._subscriptions.push(
this._navService.animateOnCollapsed.subscribe((goingToCollapse: boolean) => {
if (goingToCollapse && this.expanded) {
this.wasExpanded = true;
this.expandAnimationState = COLLAPSED_STATE;
} else if (!goingToCollapse && this.wasExpanded) {
this.expandGroup();
this.wasExpanded = false;
}
})
);
// If a link is clicked, expand the nav group
this._subscriptions.push(
this._navGroupService.expandChange.subscribe((expand: boolean) => {
if (expand && !this.expanded) {
this.expandGroup();
}
})
);
}
private wasExpanded: boolean = false;
get expanded(): boolean {
return this._itemExpand.expanded;
}
set expanded(value: boolean) {
if (this._itemExpand.expanded !== value) {
this._itemExpand.expanded = value;
this.expandedChange.emit(value);
}
}
set userExpandedInput(value: boolean) {
value = !!value;
if (this.expanded !== value) {
// We have to call toggleExpand because some cases require animations to occur first
// Directly setting the Expand service value skips the animation and can result in
// nodes in the DOM but the nav group still being collapsed
this.toggleExpand();
}
}
expandedChange: EventEmitter<boolean> = new EventEmitter<boolean>(true);
private _subscriptions: Subscription[] = [];
private _expandAnimationState: string = COLLAPSED_STATE;
expandGroup(): void {
this.expanded = true;
// Expanded animation occurs after Expand.expand is set to true
this.expandAnimationState = EXPANDED_STATE;
}
collapseGroup(): void {
// If a Vertical Nav Group toggle button is clicked while the Vertical Nav is in Collapsed state,
// the Vertical Nav should be expanded first.
this.expandAnimationState = COLLAPSED_STATE;
}
// closes a group after the collapse animation
expandAnimationDone($event: AnimationEvent) {
if ($event.toState === COLLAPSED_STATE) {
this.expanded = false;
}
}
get expandAnimationState(): string {
return this._expandAnimationState;
}
set expandAnimationState(value: string) {
if (value !== this._expandAnimationState) {
this._expandAnimationState = value;
}
}
toggleExpand(): void {
if (this.expanded) {
this.collapseGroup();
} else {
// If nav is collasped, first open the nav
if (this._navService.collapsed) {
this._navService.collapsed = false;
}
// then expand the nav group
this.expandGroup();
}
}
ngAfterContentInit() {
// This makes sure that if someone marks a nav group expanded in a collapsed nav
// the expanded property is switched back to collapsed state.
if (this._navService.collapsed && this.expanded) {
this.wasExpanded = true;
this.expandAnimationState = COLLAPSED_STATE;
}
}
ngOnDestroy() {
this._subscriptions.forEach((sub: Subscription) => sub.unsubscribe());
this._navGroupRegistrationService.unregisterNavGroup();
}
}