UNPKG

ng2-tree

Version:

angular2 component for visualizing data that can be naturally represented as a tree

109 lines 12.9 kB
import { Component, EventEmitter, Inject, Input, Output, Renderer2, ViewChild } from '@angular/core'; import { NodeMenuService } from './node-menu.service'; import { NodeMenuAction, NodeMenuItemAction } from './menu.events'; import { isEscapePressed, isLeftButtonClicked } from '../utils/event.utils'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "./node-menu.service"; export class NodeMenuComponent { renderer; nodeMenuService; menuItemSelected = new EventEmitter(); menuItems; menuContainer; availableMenuItems = [ { name: 'New tag', action: NodeMenuItemAction.NewTag, cssClass: 'new-tag' }, { name: 'New folder', action: NodeMenuItemAction.NewFolder, cssClass: 'new-folder' }, { name: 'Rename', action: NodeMenuItemAction.Rename, cssClass: 'rename' }, { name: 'Remove', action: NodeMenuItemAction.Remove, cssClass: 'remove' } ]; disposersForGlobalListeners = []; constructor(renderer, nodeMenuService) { this.renderer = renderer; this.nodeMenuService = nodeMenuService; } ngOnInit() { this.availableMenuItems = this.menuItems || this.availableMenuItems; this.disposersForGlobalListeners.push(this.renderer.listen('document', 'keyup', this.closeMenu.bind(this))); this.disposersForGlobalListeners.push(this.renderer.listen('document', 'mousedown', this.closeMenu.bind(this))); } ngOnDestroy() { this.disposersForGlobalListeners.forEach((dispose) => dispose()); } onMenuItemSelected(e, selectedMenuItem) { if (isLeftButtonClicked(e)) { this.menuItemSelected.emit({ nodeMenuItemAction: selectedMenuItem.action, nodeMenuItemSelected: selectedMenuItem.name }); this.nodeMenuService.fireMenuEvent(e.target, NodeMenuAction.Close); } } closeMenu(e) { const mouseClicked = e instanceof MouseEvent; // Check if the click is fired on an element inside a menu const containingTarget = this.menuContainer.nativeElement !== e.target && this.menuContainer.nativeElement.contains(e.target); if ((mouseClicked && !containingTarget) || isEscapePressed(e)) { this.nodeMenuService.fireMenuEvent(e.target, NodeMenuAction.Close); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeMenuComponent, deps: [{ token: Renderer2 }, { token: NodeMenuService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NodeMenuComponent, selector: "node-menu", inputs: { menuItems: "menuItems" }, outputs: { menuItemSelected: "menuItemSelected" }, viewQueries: [{ propertyName: "menuContainer", first: true, predicate: ["menuContainer"], descendants: true }], ngImport: i0, template: ` <div class="node-menu"> <ul class="node-menu-content" #menuContainer> <li class="node-menu-item" *ngFor="let menuItem of availableMenuItems" (click)="onMenuItemSelected($event, menuItem)"> <div class="node-menu-item-icon {{menuItem.cssClass}}"></div> <span class="node-menu-item-value">{{menuItem.name}}</span> </li> </ul> </div> `, isInline: true, dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeMenuComponent, decorators: [{ type: Component, args: [{ selector: 'node-menu', template: ` <div class="node-menu"> <ul class="node-menu-content" #menuContainer> <li class="node-menu-item" *ngFor="let menuItem of availableMenuItems" (click)="onMenuItemSelected($event, menuItem)"> <div class="node-menu-item-icon {{menuItem.cssClass}}"></div> <span class="node-menu-item-value">{{menuItem.name}}</span> </li> </ul> </div> ` }] }], ctorParameters: function () { return [{ type: i0.Renderer2, decorators: [{ type: Inject, args: [Renderer2] }] }, { type: i2.NodeMenuService, decorators: [{ type: Inject, args: [NodeMenuService] }] }]; }, propDecorators: { menuItemSelected: [{ type: Output }], menuItems: [{ type: Input }], menuContainer: [{ type: ViewChild, args: ['menuContainer', { static: false }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS1tZW51LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9tZW51L25vZGUtbWVudS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBcUIsTUFBTSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDeEgsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxjQUFjLEVBQUUsa0JBQWtCLEVBQTZCLE1BQU0sZUFBZSxDQUFDO0FBQzlGLE9BQU8sRUFBRSxlQUFlLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQzs7OztBQWdCNUUsTUFBTSxPQUFPLGlCQUFpQjtJQW1DQztJQUNNO0lBbEM1QixnQkFBZ0IsR0FBNEMsSUFBSSxZQUFZLEVBQTZCLENBQUM7SUFFakcsU0FBUyxDQUFpQjtJQUduQyxhQUFhLENBQU07SUFFbkIsa0JBQWtCLEdBQW1CO1FBQzFDO1lBQ0UsSUFBSSxFQUFFLFNBQVM7WUFDZixNQUFNLEVBQUUsa0JBQWtCLENBQUMsTUFBTTtZQUNqQyxRQUFRLEVBQUUsU0FBUztTQUNwQjtRQUNEO1lBQ0UsSUFBSSxFQUFFLFlBQVk7WUFDbEIsTUFBTSxFQUFFLGtCQUFrQixDQUFDLFNBQVM7WUFDcEMsUUFBUSxFQUFFLFlBQVk7U0FDdkI7UUFDRDtZQUNFLElBQUksRUFBRSxRQUFRO1lBQ2QsTUFBTSxFQUFFLGtCQUFrQixDQUFDLE1BQU07WUFDakMsUUFBUSxFQUFFLFFBQVE7U0FDbkI7UUFDRDtZQUNFLElBQUksRUFBRSxRQUFRO1lBQ2QsTUFBTSxFQUFFLGtCQUFrQixDQUFDLE1BQU07WUFDakMsUUFBUSxFQUFFLFFBQVE7U0FDbkI7S0FDRixDQUFDO0lBRU0sMkJBQTJCLEdBQW1CLEVBQUUsQ0FBQztJQUV6RCxZQUM2QixRQUFtQixFQUNiLGVBQWdDO1FBRHRDLGFBQVEsR0FBUixRQUFRLENBQVc7UUFDYixvQkFBZSxHQUFmLGVBQWUsQ0FBaUI7SUFDaEUsQ0FBQztJQUVHLFFBQVE7UUFDYixJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUM7UUFDcEUsSUFBSSxDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1RyxJQUFJLENBQUMsMkJBQTJCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2xILENBQUM7SUFFTSxXQUFXO1FBQ2hCLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFtQixFQUFFLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQy9FLENBQUM7SUFFTSxrQkFBa0IsQ0FBQyxDQUFhLEVBQUUsZ0JBQThCO1FBQ3JFLElBQUksbUJBQW1CLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDMUIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQztnQkFDekIsa0JBQWtCLEVBQUUsZ0JBQWdCLENBQUMsTUFBTTtnQkFDM0Msb0JBQW9CLEVBQUUsZ0JBQWdCLENBQUMsSUFBSTthQUM1QyxDQUFDLENBQUM7WUFFSCxJQUFJLENBQUMsZUFBZSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsTUFBcUIsRUFBRSxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDbkY7SUFDSCxDQUFDO0lBRU8sU0FBUyxDQUFDLENBQTZCO1FBQzdDLE1BQU0sWUFBWSxHQUFHLENBQUMsWUFBWSxVQUFVLENBQUM7UUFDN0MsMERBQTBEO1FBQzFELE1BQU0sZ0JBQWdCLEdBQ3BCLElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxLQUFLLENBQUMsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUV2RyxJQUFJLENBQUMsWUFBWSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxlQUFlLENBQUMsQ0FBa0IsQ0FBQyxFQUFFO1lBQzlFLElBQUksQ0FBQyxlQUFlLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxNQUFxQixFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUNuRjtJQUNILENBQUM7d0dBckVVLGlCQUFpQixrQkFtQ2xCLFNBQVMsYUFDVCxlQUFlOzRGQXBDZCxpQkFBaUIsd1BBWmxCOzs7Ozs7Ozs7O0dBVVQ7OzRGQUVVLGlCQUFpQjtrQkFkN0IsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsV0FBVztvQkFDckIsUUFBUSxFQUFFOzs7Ozs7Ozs7O0dBVVQ7aUJBQ0Y7OzBCQW9DSSxNQUFNOzJCQUFDLFNBQVM7OzBCQUNoQixNQUFNOzJCQUFDLGVBQWU7NENBbENsQixnQkFBZ0I7c0JBRHRCLE1BQU07Z0JBR1MsU0FBUztzQkFBeEIsS0FBSztnQkFHQyxhQUFhO3NCQURuQixTQUFTO3VCQUFDLGVBQWUsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5qZWN0LCBJbnB1dCwgT25EZXN0cm95LCBPbkluaXQsIE91dHB1dCwgUmVuZGVyZXIyLCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5vZGVNZW51U2VydmljZSB9IGZyb20gJy4vbm9kZS1tZW51LnNlcnZpY2UnO1xuaW1wb3J0IHsgTm9kZU1lbnVBY3Rpb24sIE5vZGVNZW51SXRlbUFjdGlvbiwgTm9kZU1lbnVJdGVtU2VsZWN0ZWRFdmVudCB9IGZyb20gJy4vbWVudS5ldmVudHMnO1xuaW1wb3J0IHsgaXNFc2NhcGVQcmVzc2VkLCBpc0xlZnRCdXR0b25DbGlja2VkIH0gZnJvbSAnLi4vdXRpbHMvZXZlbnQudXRpbHMnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdub2RlLW1lbnUnLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJub2RlLW1lbnVcIj5cbiAgICAgIDx1bCBjbGFzcz1cIm5vZGUtbWVudS1jb250ZW50XCIgI21lbnVDb250YWluZXI+XG4gICAgICAgIDxsaSBjbGFzcz1cIm5vZGUtbWVudS1pdGVtXCIgKm5nRm9yPVwibGV0IG1lbnVJdGVtIG9mIGF2YWlsYWJsZU1lbnVJdGVtc1wiXG4gICAgICAgICAgKGNsaWNrKT1cIm9uTWVudUl0ZW1TZWxlY3RlZCgkZXZlbnQsIG1lbnVJdGVtKVwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJub2RlLW1lbnUtaXRlbS1pY29uIHt7bWVudUl0ZW0uY3NzQ2xhc3N9fVwiPjwvZGl2PlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwibm9kZS1tZW51LWl0ZW0tdmFsdWVcIj57e21lbnVJdGVtLm5hbWV9fTwvc3Bhbj5cbiAgICAgICAgPC9saT5cbiAgICAgIDwvdWw+XG4gICAgPC9kaXY+XG4gIGBcbn0pXG5leHBvcnQgY2xhc3MgTm9kZU1lbnVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIEBPdXRwdXQoKVxuICBwdWJsaWMgbWVudUl0ZW1TZWxlY3RlZDogRXZlbnRFbWl0dGVyPE5vZGVNZW51SXRlbVNlbGVjdGVkRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxOb2RlTWVudUl0ZW1TZWxlY3RlZEV2ZW50PigpO1xuXG4gIEBJbnB1dCgpIHB1YmxpYyBtZW51SXRlbXM6IE5vZGVNZW51SXRlbVtdO1xuXG4gIEBWaWV3Q2hpbGQoJ21lbnVDb250YWluZXInLCB7IHN0YXRpYzogZmFsc2UgfSlcbiAgcHVibGljIG1lbnVDb250YWluZXI6IGFueTtcblxuICBwdWJsaWMgYXZhaWxhYmxlTWVudUl0ZW1zOiBOb2RlTWVudUl0ZW1bXSA9IFtcbiAgICB7XG4gICAgICBuYW1lOiAnTmV3IHRhZycsXG4gICAgICBhY3Rpb246IE5vZGVNZW51SXRlbUFjdGlvbi5OZXdUYWcsXG4gICAgICBjc3NDbGFzczogJ25ldy10YWcnXG4gICAgfSxcbiAgICB7XG4gICAgICBuYW1lOiAnTmV3IGZvbGRlcicsXG4gICAgICBhY3Rpb246IE5vZGVNZW51SXRlbUFjdGlvbi5OZXdGb2xkZXIsXG4gICAgICBjc3NDbGFzczogJ25ldy1mb2xkZXInXG4gICAgfSxcbiAgICB7XG4gICAgICBuYW1lOiAnUmVuYW1lJyxcbiAgICAgIGFjdGlvbjogTm9kZU1lbnVJdGVtQWN0aW9uLlJlbmFtZSxcbiAgICAgIGNzc0NsYXNzOiAncmVuYW1lJ1xuICAgIH0sXG4gICAge1xuICAgICAgbmFtZTogJ1JlbW92ZScsXG4gICAgICBhY3Rpb246IE5vZGVNZW51SXRlbUFjdGlvbi5SZW1vdmUsXG4gICAgICBjc3NDbGFzczogJ3JlbW92ZSdcbiAgICB9XG4gIF07XG5cbiAgcHJpdmF0ZSBkaXNwb3NlcnNGb3JHbG9iYWxMaXN0ZW5lcnM6ICgoKSA9PiB2b2lkKVtdID0gW107XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoUmVuZGVyZXIyKSBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgQEluamVjdChOb2RlTWVudVNlcnZpY2UpIHByaXZhdGUgbm9kZU1lbnVTZXJ2aWNlOiBOb2RlTWVudVNlcnZpY2VcbiAgKSB7fVxuXG4gIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmF2YWlsYWJsZU1lbnVJdGVtcyA9IHRoaXMubWVudUl0ZW1zIHx8IHRoaXMuYXZhaWxhYmxlTWVudUl0ZW1zO1xuICAgIHRoaXMuZGlzcG9zZXJzRm9yR2xvYmFsTGlzdGVuZXJzLnB1c2godGhpcy5yZW5kZXJlci5saXN0ZW4oJ2RvY3VtZW50JywgJ2tleXVwJywgdGhpcy5jbG9zZU1lbnUuYmluZCh0aGlzKSkpO1xuICAgIHRoaXMuZGlzcG9zZXJzRm9yR2xvYmFsTGlzdGVuZXJzLnB1c2godGhpcy5yZW5kZXJlci5saXN0ZW4oJ2RvY3VtZW50JywgJ21vdXNlZG93bicsIHRoaXMuY2xvc2VNZW51LmJpbmQodGhpcykpKTtcbiAgfVxuXG4gIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRpc3Bvc2Vyc0Zvckdsb2JhbExpc3RlbmVycy5mb3JFYWNoKChkaXNwb3NlOiAoKSA9PiB2b2lkKSA9PiBkaXNwb3NlKCkpO1xuICB9XG5cbiAgcHVibGljIG9uTWVudUl0ZW1TZWxlY3RlZChlOiBNb3VzZUV2ZW50LCBzZWxlY3RlZE1lbnVJdGVtOiBOb2RlTWVudUl0ZW0pOiB2b2lkIHtcbiAgICBpZiAoaXNMZWZ0QnV0dG9uQ2xpY2tlZChlKSkge1xuICAgICAgdGhpcy5tZW51SXRlbVNlbGVjdGVkLmVtaXQoe1xuICAgICAgICBub2RlTWVudUl0ZW1BY3Rpb246IHNlbGVjdGVkTWVudUl0ZW0uYWN0aW9uLFxuICAgICAgICBub2RlTWVudUl0ZW1TZWxlY3RlZDogc2VsZWN0ZWRNZW51SXRlbS5uYW1lXG4gICAgICB9KTtcblxuICAgICAgdGhpcy5ub2RlTWVudVNlcnZpY2UuZmlyZU1lbnVFdmVudChlLnRhcmdldCBhcyBIVE1MRWxlbWVudCwgTm9kZU1lbnVBY3Rpb24uQ2xvc2UpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2xvc2VNZW51KGU6IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgbW91c2VDbGlja2VkID0gZSBpbnN0YW5jZW9mIE1vdXNlRXZlbnQ7XG4gICAgLy8gQ2hlY2sgaWYgdGhlIGNsaWNrIGlzIGZpcmVkIG9uIGFuIGVsZW1lbnQgaW5zaWRlIGEgbWVudVxuICAgIGNvbnN0IGNvbnRhaW5pbmdUYXJnZXQgPVxuICAgICAgdGhpcy5tZW51Q29udGFpbmVyLm5hdGl2ZUVsZW1lbnQgIT09IGUudGFyZ2V0ICYmIHRoaXMubWVudUNvbnRhaW5lci5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKGUudGFyZ2V0KTtcblxuICAgIGlmICgobW91c2VDbGlja2VkICYmICFjb250YWluaW5nVGFyZ2V0KSB8fCBpc0VzY2FwZVByZXNzZWQoZSBhcyBLZXlib2FyZEV2ZW50KSkge1xuICAgICAgdGhpcy5ub2RlTWVudVNlcnZpY2UuZmlyZU1lbnVFdmVudChlLnRhcmdldCBhcyBIVE1MRWxlbWVudCwgTm9kZU1lbnVBY3Rpb24uQ2xvc2UpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIE5vZGVNZW51SXRlbSB7XG4gIG5hbWU6IHN0cmluZztcbiAgYWN0aW9uOiBOb2RlTWVudUl0ZW1BY3Rpb247XG4gIGNzc0NsYXNzPzogc3RyaW5nO1xufVxuIl19