redoc/lib/components/SideMenu/side-menu.ts

132 lines
3.9 KiB
TypeScript
Raw Normal View History

2015-10-15 20:06:16 +03:00
'use strict';
2016-08-28 21:46:10 +03:00
import { Component, ElementRef, ChangeDetectorRef, OnInit } from '@angular/core';
2016-09-02 23:18:31 +03:00
//import { global } from '@angular/core/src/facade/lang';
2016-06-19 17:41:04 +03:00
import { trigger, state, animate, transition, style } from '@angular/core';
2016-08-22 12:12:13 +03:00
import { BaseComponent, SpecManager } from '../base';
2016-12-02 12:59:29 +03:00
import { ScrollService, MenuService, OptionsService } from '../../services/index';
2016-08-28 21:46:10 +03:00
import { BrowserDomAdapter as DOM } from '../../utils/browser-adapter';
import { MenuCategory } from '../../services/schema-helper.service';
2016-09-02 23:18:31 +03:00
const global = window;
2016-08-22 12:12:13 +03:00
@Component({
2015-10-15 20:06:16 +03:00
selector: 'side-menu',
templateUrl: './side-menu.html',
styleUrls: ['./side-menu.css'],
2016-06-19 17:41:04 +03:00
animations: [
trigger('itemAnimation', [
state('collapsed, void',
style({ height: '0px' })),
state('expanded',
style({ height: '*' })),
// https://github.com/Rebilly/ReDoc/issues/162
// transition('collapsed <=> expanded', [
// animate('200ms ease')
// ])
2016-06-19 17:41:04 +03:00
])
],
2015-10-15 20:06:16 +03:00
})
2016-08-28 21:46:10 +03:00
export class SideMenu extends BaseComponent implements OnInit {
activeCatCaption: string;
activeItemCaption: string;
categories: Array<MenuCategory>;
private options: any;
private $element: any;
private $mobileNav: any;
private $resourcesNav: any;
private $scrollParent: any;
private firstChange = true;
2016-08-28 21:46:10 +03:00
constructor(specMgr:SpecManager, elementRef:ElementRef,
2016-12-02 12:59:29 +03:00
private scrollService:ScrollService, private menuService:MenuService,
optionsService:OptionsService, private detectorRef:ChangeDetectorRef) {
super(specMgr);
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
2016-05-17 19:38:12 +03:00
this.menuService.changed.subscribe((evt) => this.changed(evt));
}
changed(newItem) {
if (newItem) {
let {cat, item} = newItem;
this.activeCatCaption = cat.name || '';
this.activeItemCaption = item && item.summary || '';
}
2016-05-10 09:44:44 +03:00
//safari doesn't update bindings if not run changeDetector manually :(
this.detectorRef.detectChanges();
if (this.firstChange) {
this.scrollActiveIntoView();
this.firstChange = false;
}
2015-10-15 21:35:05 +03:00
}
scrollActiveIntoView() {
let $item = this.$element.querySelector('li.active, label.active');
if ($item) $item.scrollIntoView();
}
activateAndScroll(catIdx, methodIdx) {
2016-01-21 18:26:54 +03:00
if (this.mobileMode()) {
this.toggleMobileNav();
}
let menu = this.categories;
if (!menu[catIdx].ready) return;
if (menu[catIdx].methods && menu[catIdx].methods.length && (methodIdx >= 0) &&
!menu[catIdx].methods[methodIdx].ready) return;
this.menuService.activate(catIdx, methodIdx);
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() {
this.categories = this.menuService.categories;
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-01-21 18:26:54 +03:00
mobileMode() {
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
: 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;
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() {
this.scrollService.unbind();
}
2016-08-28 21:46:10 +03:00
ngOnInit() {
this.preinit();
}
2015-10-15 20:06:16 +03:00
}