mirror of
https://github.com/richard-loafle/fuse-angular.git
synced 2025-04-14 12:25:14 +00:00
280 lines
7.4 KiB
TypeScript
280 lines
7.4 KiB
TypeScript
import { Component, ElementRef, HostBinding, HostListener, Input, OnDestroy, OnInit, Renderer2, ViewChild, ViewEncapsulation } from '@angular/core';
|
|
import { Subscription } from 'rxjs/Subscription';
|
|
import { FuseMatchMedia } from '../../../core/services/match-media.service';
|
|
import { FuseNavbarVerticalService } from './navbar-vertical.service';
|
|
import { ObservableMedia } from '@angular/flex-layout';
|
|
import { FuseMainComponent } from '../../main.component';
|
|
import { NavigationEnd, Router } from '@angular/router';
|
|
import { FuseNavigationService } from '../../../core/components/navigation/navigation.service';
|
|
import { FusePerfectScrollbarDirective } from '../../../core/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive';
|
|
import { animate, AnimationBuilder, AnimationPlayer, style } from '@angular/animations';
|
|
|
|
@Component({
|
|
selector : 'fuse-navbar-vertical',
|
|
templateUrl : './navbar-vertical.component.html',
|
|
styleUrls : ['./navbar-vertical.component.scss'],
|
|
encapsulation: ViewEncapsulation.None
|
|
})
|
|
export class FuseNavbarVerticalComponent implements OnInit, OnDestroy
|
|
{
|
|
private _backdropElement: HTMLElement | null = null;
|
|
private _folded = false;
|
|
|
|
@HostBinding('class.close') isClosed: boolean;
|
|
@HostBinding('class.folded') isFoldedActive: boolean;
|
|
@HostBinding('class.folded-open') isFoldedOpen: boolean;
|
|
@HostBinding('class.initialized') initialized: boolean;
|
|
@ViewChild(FusePerfectScrollbarDirective) fusePerfectScrollbarDirective;
|
|
|
|
@Input()
|
|
set folded(value: boolean)
|
|
{
|
|
this._folded = value;
|
|
|
|
if ( this._folded )
|
|
{
|
|
this.activateFolded();
|
|
}
|
|
else
|
|
{
|
|
this.deActivateFolded();
|
|
}
|
|
}
|
|
|
|
get folded(): boolean
|
|
{
|
|
return this._folded;
|
|
}
|
|
|
|
matchMediaWatcher: Subscription;
|
|
navigationServiceWatcher: Subscription;
|
|
fusePerfectScrollbarUpdateTimeout;
|
|
|
|
player: AnimationPlayer;
|
|
|
|
constructor(
|
|
private fuseMainComponent: FuseMainComponent,
|
|
private fuseMatchMedia: FuseMatchMedia,
|
|
private fuseNavigationService: FuseNavigationService,
|
|
private navBarService: FuseNavbarVerticalService,
|
|
public media: ObservableMedia,
|
|
private router: Router,
|
|
private _renderer: Renderer2,
|
|
private _elementRef: ElementRef,
|
|
private animationBuilder: AnimationBuilder
|
|
)
|
|
{
|
|
navBarService.setNavBar(this);
|
|
|
|
this.navigationServiceWatcher =
|
|
this.fuseNavigationService.onNavCollapseToggle.subscribe(() => {
|
|
this.fusePerfectScrollbarUpdateTimeout = setTimeout(() => {
|
|
this.fusePerfectScrollbarDirective.update();
|
|
}, 310);
|
|
});
|
|
|
|
this.matchMediaWatcher =
|
|
this.fuseMatchMedia.onMediaChange
|
|
.subscribe((mediaStep) => {
|
|
setTimeout(() => {
|
|
|
|
if ( this.media.isActive('lt-lg') )
|
|
{
|
|
this.closeBar();
|
|
this.deActivateFolded();
|
|
}
|
|
else
|
|
{
|
|
this.openBar();
|
|
this._detachBackdrop();
|
|
}
|
|
});
|
|
});
|
|
|
|
router.events.subscribe(
|
|
(event) => {
|
|
if ( event instanceof NavigationEnd )
|
|
{
|
|
if ( this.media.isActive('lt-lg') )
|
|
{
|
|
setTimeout(() => {
|
|
this.closeBar();
|
|
});
|
|
}
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
ngOnInit()
|
|
{
|
|
this.isClosed = false;
|
|
this.isFoldedActive = this._folded;
|
|
this.isFoldedOpen = false;
|
|
this.initialized = false;
|
|
this.updateCssClasses();
|
|
|
|
setTimeout(() => {
|
|
this.initialized = true;
|
|
});
|
|
|
|
if ( this.media.isActive('lt-lg') )
|
|
{
|
|
this.closeBar();
|
|
this.deActivateFolded();
|
|
}
|
|
else
|
|
{
|
|
if ( !this._folded )
|
|
{
|
|
this.deActivateFolded();
|
|
}
|
|
else
|
|
{
|
|
this.activateFolded();
|
|
}
|
|
}
|
|
}
|
|
|
|
ngOnDestroy()
|
|
{
|
|
clearTimeout(this.fusePerfectScrollbarUpdateTimeout);
|
|
this.matchMediaWatcher.unsubscribe();
|
|
this.navigationServiceWatcher.unsubscribe();
|
|
}
|
|
|
|
openBar()
|
|
{
|
|
if ( !this.isClosed )
|
|
{
|
|
return;
|
|
}
|
|
|
|
this.isClosed = false;
|
|
this.updateCssClasses();
|
|
if ( this.media.isActive('lt-lg') )
|
|
{
|
|
this._attachBackdrop();
|
|
}
|
|
}
|
|
|
|
closeBar()
|
|
{
|
|
if ( this.isClosed )
|
|
{
|
|
return;
|
|
}
|
|
|
|
this.isClosed = true;
|
|
this.updateCssClasses();
|
|
this._detachBackdrop();
|
|
}
|
|
|
|
toggleBar()
|
|
{
|
|
if ( this.isClosed )
|
|
{
|
|
this.openBar();
|
|
}
|
|
else
|
|
{
|
|
this.closeBar();
|
|
}
|
|
}
|
|
|
|
toggleFold()
|
|
{
|
|
if ( !this.isFoldedActive )
|
|
{
|
|
this.activateFolded();
|
|
}
|
|
else
|
|
{
|
|
this.deActivateFolded();
|
|
}
|
|
}
|
|
|
|
activateFolded()
|
|
{
|
|
this.isFoldedActive = true;
|
|
this.fuseMainComponent.addClass('fuse-nav-bar-folded');
|
|
this.isFoldedOpen = false;
|
|
}
|
|
|
|
deActivateFolded()
|
|
{
|
|
this.isFoldedActive = false;
|
|
this.fuseMainComponent.removeClass('fuse-nav-bar-folded');
|
|
this.isFoldedOpen = false;
|
|
}
|
|
|
|
@HostListener('mouseenter')
|
|
onMouseEnter()
|
|
{
|
|
this.isFoldedOpen = true;
|
|
}
|
|
|
|
@HostListener('mouseleave')
|
|
onMouseLeave()
|
|
{
|
|
this.isFoldedOpen = false;
|
|
}
|
|
|
|
updateCssClasses()
|
|
{
|
|
if ( this.isClosed )
|
|
{
|
|
this.fuseMainComponent.addClass('fuse-nav-bar-opened');
|
|
this.fuseMainComponent.removeClass('fuse-nav-bar-closed');
|
|
}
|
|
else
|
|
{
|
|
this.fuseMainComponent.addClass('fuse-nav-bar-closed');
|
|
this.fuseMainComponent.removeClass('fuse-nav-bar-opened');
|
|
}
|
|
}
|
|
|
|
private _attachBackdrop()
|
|
{
|
|
this._backdropElement = this._renderer.createElement('div');
|
|
this._backdropElement.classList.add('fuse-navbar-backdrop');
|
|
|
|
this._renderer.appendChild(this._elementRef.nativeElement.parentElement, this._backdropElement);
|
|
|
|
this.player =
|
|
this.animationBuilder
|
|
.build([
|
|
animate('400ms ease', style({opacity: 1}))
|
|
]).create(this._backdropElement);
|
|
|
|
this.player.play();
|
|
|
|
this._backdropElement.addEventListener('click', () => {
|
|
this.closeBar();
|
|
}
|
|
);
|
|
}
|
|
|
|
private _detachBackdrop()
|
|
{
|
|
if ( this._backdropElement )
|
|
{
|
|
this.player =
|
|
this.animationBuilder
|
|
.build([
|
|
animate('400ms cubic-bezier(.25,.8,.25,1)', style({opacity: 0}))
|
|
]).create(this._backdropElement);
|
|
|
|
this.player.play();
|
|
|
|
this.player.onDone(() => {
|
|
if ( this._backdropElement )
|
|
{
|
|
this._backdropElement.parentNode.removeChild(this._backdropElement);
|
|
this._backdropElement = null;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|