2015-10-15 20:06:16 +03:00
|
|
|
'use strict';
|
|
|
|
|
2017-03-30 15:17:08 +03:00
|
|
|
import { Component,
|
|
|
|
EventEmitter,
|
|
|
|
Input,
|
|
|
|
Output,
|
|
|
|
ElementRef,
|
|
|
|
ChangeDetectorRef,
|
|
|
|
OnInit,
|
|
|
|
OnDestroy
|
|
|
|
} from '@angular/core';
|
2016-07-21 13:35:27 +03:00
|
|
|
|
2016-06-19 17:41:04 +03:00
|
|
|
import { trigger, state, animate, transition, style } from '@angular/core';
|
2017-04-18 16:10:34 +03:00
|
|
|
import { ScrollService, MenuService, OptionsService, MenuItem } from '../../services/';
|
2016-08-28 21:46:10 +03:00
|
|
|
import { BrowserDomAdapter as DOM } from '../../utils/browser-adapter';
|
2016-07-21 13:35:27 +03:00
|
|
|
|
2016-09-02 23:18:31 +03:00
|
|
|
const global = window;
|
|
|
|
|
2016-12-23 01:42:58 +03:00
|
|
|
@Component({
|
|
|
|
selector: 'side-menu-items',
|
|
|
|
templateUrl: './side-menu-items.html',
|
2017-01-06 14:14:47 +03:00
|
|
|
styleUrls: ['./side-menu-items.css'],
|
|
|
|
animations: [
|
|
|
|
trigger('itemAnimation', [
|
|
|
|
state('collapsed, void',
|
|
|
|
style({ height: '0px' })),
|
|
|
|
state('expanded',
|
|
|
|
style({ height: '*' })),
|
|
|
|
transition('collapsed <=> expanded', [
|
|
|
|
animate('200ms ease')
|
|
|
|
])
|
|
|
|
])
|
|
|
|
]
|
2016-12-23 01:42:58 +03:00
|
|
|
})
|
|
|
|
export class SideMenuItems {
|
|
|
|
@Input() items: MenuItem[];
|
|
|
|
@Output() activate = new EventEmitter<MenuItem>();
|
|
|
|
|
|
|
|
activateItem(item) {
|
|
|
|
this.activate.next(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-22 12:12:13 +03:00
|
|
|
@Component({
|
2015-10-15 20:06:16 +03:00
|
|
|
selector: 'side-menu',
|
2016-05-25 18:34:31 +03:00
|
|
|
templateUrl: './side-menu.html',
|
2017-01-06 14:14:47 +03:00
|
|
|
styleUrls: ['./side-menu.css']
|
2015-10-15 20:06:16 +03:00
|
|
|
})
|
2017-04-18 16:10:34 +03:00
|
|
|
export class SideMenu implements OnInit, OnDestroy {
|
2016-05-25 18:34:31 +03:00
|
|
|
activeCatCaption: string;
|
|
|
|
activeItemCaption: string;
|
2016-12-23 01:42:58 +03:00
|
|
|
menuItems: Array<MenuItem>;
|
2016-07-20 11:07:08 +03:00
|
|
|
|
|
|
|
private options: any;
|
|
|
|
private $element: any;
|
|
|
|
private $mobileNav: any;
|
|
|
|
private $resourcesNav: any;
|
|
|
|
private $scrollParent: any;
|
|
|
|
|
2017-04-23 15:43:56 +03:00
|
|
|
private changedActiveSubscription;
|
|
|
|
private changedSubscription;
|
|
|
|
|
2017-03-30 15:17:08 +03:00
|
|
|
constructor(
|
|
|
|
elementRef:ElementRef,
|
|
|
|
private scrollService:ScrollService,
|
|
|
|
private menuService:MenuService,
|
|
|
|
optionsService:OptionsService,
|
|
|
|
private detectorRef:ChangeDetectorRef,
|
|
|
|
) {
|
2016-02-11 14:38:44 +03:00
|
|
|
this.$element = elementRef.nativeElement;
|
2016-01-21 18:26:54 +03:00
|
|
|
|
|
|
|
this.activeCatCaption = '';
|
|
|
|
this.activeItemCaption = '';
|
2015-11-27 01:43:01 +03:00
|
|
|
|
2016-05-07 10:54:44 +03:00
|
|
|
this.options = optionsService.options;
|
2016-05-05 11:05:02 +03:00
|
|
|
|
2017-04-23 15:43:56 +03:00
|
|
|
this.changedActiveSubscription = this.menuService.changedActiveItem.subscribe((evt) => this.changed(evt));
|
|
|
|
this.changedSubscription = this.menuService.changed.subscribe((evt) => {
|
|
|
|
this.detectorRef.detectChanges()
|
|
|
|
});
|
2015-11-29 20:18:01 +03:00
|
|
|
}
|
|
|
|
|
2016-12-23 01:42:58 +03:00
|
|
|
changed(item) {
|
2016-12-25 15:24:58 +03:00
|
|
|
if (!item) {
|
|
|
|
this.activeCatCaption = '';
|
|
|
|
this.activeItemCaption = '';
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (item.parent) {
|
|
|
|
this.activeItemCaption = item.name;
|
|
|
|
this.activeCatCaption = item.parent.name;
|
|
|
|
} else {
|
|
|
|
this.activeCatCaption = item.name;
|
|
|
|
this.activeItemCaption = '';
|
2016-11-24 19:12:43 +03:00
|
|
|
}
|
2016-05-10 09:44:44 +03:00
|
|
|
|
|
|
|
//safari doesn't update bindings if not run changeDetector manually :(
|
|
|
|
this.detectorRef.detectChanges();
|
2017-02-14 15:39:03 +03:00
|
|
|
this.scrollActiveIntoView();
|
2015-10-15 21:35:05 +03:00
|
|
|
}
|
|
|
|
|
2016-11-24 19:12:43 +03:00
|
|
|
scrollActiveIntoView() {
|
|
|
|
let $item = this.$element.querySelector('li.active, label.active');
|
2017-02-14 15:39:03 +03:00
|
|
|
if ($item) $item.scrollIntoViewIfNeeded();
|
2016-11-24 19:12:43 +03:00
|
|
|
}
|
|
|
|
|
2016-12-23 01:42:58 +03:00
|
|
|
activateAndScroll(item) {
|
2016-12-25 15:24:58 +03:00
|
|
|
if (this.mobileMode) {
|
2016-01-21 18:26:54 +03:00
|
|
|
this.toggleMobileNav();
|
|
|
|
}
|
2016-11-24 19:12:43 +03:00
|
|
|
|
2017-04-18 16:37:05 +03:00
|
|
|
this.menuService.activate(item);
|
2016-05-07 10:54:44 +03:00
|
|
|
this.menuService.scrollToActive();
|
2016-02-07 17:10:32 +03:00
|
|
|
}
|
|
|
|
|
2016-05-07 10:54:44 +03:00
|
|
|
init() {
|
2016-12-23 01:42:58 +03:00
|
|
|
this.menuItems = this.menuService.items;
|
2016-07-20 11:07:08 +03:00
|
|
|
|
2016-08-28 21:46:10 +03:00
|
|
|
this.$mobileNav = DOM.querySelector(this.$element, '.mobile-nav');
|
|
|
|
this.$resourcesNav = DOM.querySelector(this.$element, '#resources-nav');
|
2015-11-27 00:30:13 +03:00
|
|
|
|
2016-05-17 19:38:12 +03:00
|
|
|
//decorate scrollYOffset to account mobile nav
|
|
|
|
this.scrollService.scrollYOffset = () => {
|
2016-05-07 10:54:44 +03:00
|
|
|
let mobileNavOffset = this.$mobileNav.clientHeight;
|
2016-05-17 19:38:12 +03:00
|
|
|
return this.options.scrollYOffset() + mobileNavOffset;
|
2016-05-07 10:54:44 +03:00
|
|
|
};
|
2015-10-15 20:06:16 +03:00
|
|
|
}
|
|
|
|
|
2016-12-25 15:24:58 +03:00
|
|
|
get mobileMode() {
|
2016-02-10 16:48:07 +03:00
|
|
|
return this.$mobileNav.clientHeight > 0;
|
2016-01-21 18:26:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
toggleMobileNav() {
|
2016-08-28 21:46:10 +03:00
|
|
|
let $overflowParent = (this.options.$scrollParent === global) ? DOM.defaultDoc().body
|
2016-07-21 13:35:27 +03:00
|
|
|
: this.$scrollParent;
|
2016-08-28 21:46:10 +03:00
|
|
|
if (DOM.hasStyle(this.$resourcesNav, 'height')) {
|
|
|
|
DOM.removeStyle(this.$resourcesNav, 'height');
|
|
|
|
DOM.removeStyle($overflowParent, 'overflow-y');
|
2016-01-21 18:26:54 +03:00
|
|
|
} else {
|
2016-05-17 19:38:12 +03:00
|
|
|
let viewportHeight = this.options.$scrollParent.innerHeight
|
|
|
|
|| this.options.$scrollParent.clientHeight;
|
2016-02-10 16:48:07 +03:00
|
|
|
let height = viewportHeight - this.$mobileNav.getBoundingClientRect().bottom;
|
2016-08-28 21:46:10 +03:00
|
|
|
DOM.setStyle($overflowParent, 'overflow-y', 'hidden');
|
|
|
|
DOM.setStyle(this.$resourcesNav, 'height', height + 'px');
|
2016-01-21 18:26:54 +03:00
|
|
|
}
|
|
|
|
}
|
2016-05-07 10:54:44 +03:00
|
|
|
|
|
|
|
destroy() {
|
2017-04-23 15:43:56 +03:00
|
|
|
this.changedActiveSubscription.unsubscribe();
|
|
|
|
this.changedSubscription.unsubscribe();
|
2016-05-07 10:54:44 +03:00
|
|
|
this.scrollService.unbind();
|
2016-12-19 18:13:39 +03:00
|
|
|
this.menuService.destroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
ngOnDestroy() {
|
|
|
|
this.destroy();
|
2016-05-07 10:54:44 +03:00
|
|
|
}
|
2016-08-28 21:46:10 +03:00
|
|
|
|
|
|
|
ngOnInit() {
|
2017-04-18 16:10:34 +03:00
|
|
|
this.init();
|
2016-08-28 21:46:10 +03:00
|
|
|
}
|
2016-12-29 20:20:29 +03:00
|
|
|
|
|
|
|
ngAfterViewInit() {
|
|
|
|
}
|
2015-10-15 20:06:16 +03:00
|
|
|
}
|