unicorn-components
Version:
<a target="_blank" href="https://getunicorn.io"><img src="https://bitbucket-assetroot.s3.amazonaws.com/c/photos/2017/Jul/07/2615006260-5-nitsnetsstudios-ondemand-UNI_avatar.png" align="left"></a>
105 lines (91 loc) • 3.27 kB
text/typescript
import {
Component,
ContentChild,
Directive,
ElementRef,
EventEmitter,
Host,
HostListener,
Input,
OnDestroy,
Output,
HostBinding,
} from '@angular/core';
import { UniMenuContainerComponent } from './container/container.component';
import { UniPosition } from '../../../models/types';
export class UniMenuComponent {
componentClass = true;
toggle = false;
keepOpen = false;
openedChange = new EventEmitter();
position: UniPosition = null;
calculatedPosition: UniPosition = null;
menuScope: UniMenuContainerComponent;
opened = false;
constructor(private elementRef: ElementRef) { }
open(x = null) {
if (x) {
this.calculatedPosition = x > document.documentElement.clientWidth / 2 ? 'bottom-left' : 'bottom-right';
}
this.opened = true;
this.openedChange.emit(true);
}
close() {
this.opened = false;
this.openedChange.emit(false);
}
isInClosableZone(element: HTMLElement) {
if (!this.menuScope || this.keepOpen === false) { return false; }
return this.menuScope.elementRef.nativeElement.contains(element);
}
}
export class UniMenuTriggerDirective implements OnDestroy {
private openedByFocus = false;
private closeMenuOnOutsideClick = (event: MouseEvent) => this.close(event);
constructor( public menu: UniMenuComponent, private elementRef: ElementRef) { }
openMenu(ev: MouseEvent) {
if (this.openedByFocus) {
this.openedByFocus = false;
return;
}
if (this.menu.opened && this.menu.toggle) {
this.menu.close();
document.removeEventListener('click', this.closeMenuOnOutsideClick);
} else {
this.menu.open(ev.clientX);
document.addEventListener('click', this.closeMenuOnOutsideClick, true);
}
}
onFocus() {
this.openedByFocus = true;
this.menu.open();
document.addEventListener('click', this.closeMenuOnOutsideClick, true);
}
onBlur(event: FocusEvent) {
if (event.relatedTarget &&
!this.menu.isInClosableZone(<HTMLElement>event.relatedTarget) &&
event.relatedTarget !== this.elementRef.nativeElement) {
this.menu.close();
document.removeEventListener('click', this.closeMenuOnOutsideClick);
}
}
ngOnDestroy() {
document.removeEventListener('click', this.closeMenuOnOutsideClick);
}
private close(event: Event) {
if (!this.menu.isInClosableZone(<HTMLElement>event.target)
&& event.target !== this.elementRef.nativeElement
&& !this.elementRef.nativeElement.contains(event.target)) {
this.menu.close();
document.removeEventListener('click', this.closeMenuOnOutsideClick);
}
}
}