UNPKG

@dotglitch/ngx-ctx-menu

Version:

Angular context menu that works with templates

78 lines 10 kB
import { Directive, Input, HostListener } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { calcMenuItemBounds, ContextMenuComponent } from './context-menu/context-menu.component'; import { getPosition } from './utils'; import * as i0 from "@angular/core"; import * as i1 from "@angular/material/dialog"; export class NgxContextMenuDirective { constructor(dialog, viewContainer) { this.dialog = dialog; this.viewContainer = viewContainer; /** * Configuration for opening the app menu */ this.config = {}; } // Needs to be public so we can manually open the dialog async onContextMenu(evt) { const el = this.viewContainer.element.nativeElement; el.classList.add("ngx-app-menu-open"); return openContextMenu(this.dialog, this.menuItems, this.data, evt, this.config) .finally(() => { el.classList.remove("ngx-app-menu-open"); }); } } /** @nocollapse */ NgxContextMenuDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.0", ngImport: i0, type: NgxContextMenuDirective, deps: [{ token: i1.MatDialog }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive }); /** @nocollapse */ NgxContextMenuDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.0", type: NgxContextMenuDirective, isStandalone: true, selector: "[ngx-ctx-menu]", inputs: { data: ["ngx-ctx-menu-context", "data"], menuItems: ["ngx-ctx-menu", "menuItems"], config: ["ngx-ctx-menu-config", "config"] }, host: { listeners: { "contextmenu": "onContextMenu($event)" } }, providers: [ MatDialog ], ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.0", ngImport: i0, type: NgxContextMenuDirective, decorators: [{ type: Directive, args: [{ selector: '[ngx-ctx-menu]', providers: [ MatDialog ], standalone: true }] }], ctorParameters: function () { return [{ type: i1.MatDialog }, { type: i0.ViewContainerRef }]; }, propDecorators: { data: [{ type: Input, args: ["ngx-ctx-menu-context"] }], menuItems: [{ type: Input, args: ["ngx-ctx-menu"] }], config: [{ type: Input, args: ["ngx-ctx-menu-config"] }], onContextMenu: [{ type: HostListener, args: ['contextmenu', ['$event']] }] } }); // Helper to open the context menu without using the directive. export const openContextMenu = async (dialog, menuItems, data, evt, config = {}) => { evt.preventDefault(); evt.stopPropagation(); const cords = getPosition(evt, config, await calcMenuItemBounds(menuItems, data)); const specificId = crypto.randomUUID(); if (!config.alignment) config.alignment = "start"; return new Promise(res => { dialog.open(ContextMenuComponent, { data: { data: data, items: menuItems, config: config, id: specificId }, panelClass: ["ngx-ctx-menu", 'ngx-' + specificId].concat(config?.customClass || []), position: cords, backdropClass: "ngx-ctx-menu-backdrop" }) .afterClosed() .subscribe(s => { res(s); }); }); }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3R4bWVudS5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL2N0eG1lbnUuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBaUMsTUFBTSxlQUFlLENBQUM7QUFDOUYsT0FBTyxFQUFtQixTQUFTLEVBQXVDLE1BQU0sMEJBQTBCLENBQUM7QUFDM0csT0FBTyxFQUFFLGtCQUFrQixFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFJakcsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLFNBQVMsQ0FBQzs7O0FBU3RDLE1BQU0sT0FBTyx1QkFBdUI7SUFpQmhDLFlBQ1ksTUFBaUIsRUFDakIsYUFBK0I7UUFEL0IsV0FBTSxHQUFOLE1BQU0sQ0FBVztRQUNqQixrQkFBYSxHQUFiLGFBQWEsQ0FBa0I7UUFQM0M7O1dBRUc7UUFDMkIsV0FBTSxHQUFzQixFQUFFLENBQUM7SUFLekQsQ0FBQztJQUVMLHdEQUF3RDtJQUVqRCxLQUFLLENBQUMsYUFBYSxDQUFDLEdBQWlCO1FBQ3hDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLGFBQTRCLENBQUM7UUFFbkUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUV0QyxPQUFPLGVBQWUsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQzthQUMzRSxPQUFPLENBQUMsR0FBRyxFQUFFO1lBQ1YsRUFBRSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FBQztJQUNYLENBQUM7O3VJQWpDUSx1QkFBdUI7MkhBQXZCLHVCQUF1Qix1UUFMckI7UUFDUCxTQUFTO0tBQ1o7MkZBR1EsdUJBQXVCO2tCQVBuQyxTQUFTO21CQUFDO29CQUNQLFFBQVEsRUFBRSxnQkFBZ0I7b0JBQzFCLFNBQVMsRUFBRTt3QkFDUCxTQUFTO3FCQUNaO29CQUNELFVBQVUsRUFBRSxJQUFJO2lCQUNuQjsrSEFNa0MsSUFBSTtzQkFBbEMsS0FBSzt1QkFBQyxzQkFBc0I7Z0JBS04sU0FBUztzQkFBL0IsS0FBSzt1QkFBQyxjQUFjO2dCQUtTLE1BQU07c0JBQW5DLEtBQUs7dUJBQUMscUJBQXFCO2dCQVNmLGFBQWE7c0JBRHpCLFlBQVk7dUJBQUMsYUFBYSxFQUFFLENBQUMsUUFBUSxDQUFDOztBQWEzQywrREFBK0Q7QUFDL0QsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFHLEtBQUssRUFBRSxNQUFpQixFQUFFLFNBQTRCLEVBQUUsSUFBUyxFQUFFLEdBQWlCLEVBQUUsU0FBNEIsRUFBRSxFQUFFLEVBQUU7SUFDbkosR0FBRyxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQ3JCLEdBQUcsQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUV0QixNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLGtCQUFrQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ2xGLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUV2QyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVM7UUFBRSxNQUFNLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQztJQUVsRCxPQUFPLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1FBQ3JCLE1BQU0sQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUU7WUFDOUIsSUFBSSxFQUFFO2dCQUNGLElBQUksRUFBRSxJQUFJO2dCQUNWLEtBQUssRUFBRSxTQUFTO2dCQUNoQixNQUFNLEVBQUUsTUFBTTtnQkFDZCxFQUFFLEVBQUUsVUFBVTthQUNqQjtZQUNELFVBQVUsRUFBRSxDQUFDLGNBQWMsRUFBRSxNQUFNLEdBQUcsVUFBVSxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxXQUFXLElBQUksRUFBRSxDQUFDO1lBQ25GLFFBQVEsRUFBRSxLQUFLO1lBQ2YsYUFBYSxFQUFFLHVCQUF1QjtTQUN6QyxDQUFDO2FBQ0QsV0FBVyxFQUFFO2FBQ2IsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ1gsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ1gsQ0FBQyxDQUFDLENBQUE7SUFDTixDQUFDLENBQWlCLENBQUM7QUFDdkIsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlyZWN0aXZlLCBJbnB1dCwgSG9zdExpc3RlbmVyLCBUZW1wbGF0ZVJlZiwgVmlld0NvbnRhaW5lclJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTUFUX0RJQUxPR19EQVRBLCBNYXREaWFsb2csIE1BVF9ESUFMT0dfU0NST0xMX1NUUkFURUdZX1BST1ZJREVSIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IGNhbGNNZW51SXRlbUJvdW5kcywgQ29udGV4dE1lbnVDb21wb25lbnQgfSBmcm9tICcuL2NvbnRleHQtbWVudS9jb250ZXh0LW1lbnUuY29tcG9uZW50JztcbmltcG9ydCB7IENvbnRleHRNZW51SXRlbSB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgTmd4QXBwTWVudU9wdGlvbnMgfSBmcm9tICcuL2FwcG1lbnUuZGlyZWN0aXZlJztcbmltcG9ydCB7IGNyZWF0ZUFwcGxpY2F0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5pbXBvcnQgeyBnZXRQb3NpdGlvbiB9IGZyb20gJy4vdXRpbHMnO1xuXG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ1tuZ3gtY3R4LW1lbnVdJyxcbiAgICBwcm92aWRlcnM6IFtcbiAgICAgICAgTWF0RGlhbG9nXG4gICAgXSxcbiAgICBzdGFuZGFsb25lOiB0cnVlXG59KVxuZXhwb3J0IGNsYXNzIE5neENvbnRleHRNZW51RGlyZWN0aXZlIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBkYXRhIHJlcHJlc2VudGluZyB0aGUgaXRlbSB0aGUgY29udGV4dC1tZW51IHdhcyBvcGVuZWQgZm9yLlxuICAgICAqL1xuICAgIEBJbnB1dChcIm5neC1jdHgtbWVudS1jb250ZXh0XCIpIGRhdGE6IGFueTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBpdGVtcyB0aGF0IHdpbGwgYmUgYm91bmQgdG8gdGhlIGNvbnRleHQgbWVudS5cbiAgICAgKi9cbiAgICBASW5wdXQoXCJuZ3gtY3R4LW1lbnVcIikgbWVudUl0ZW1zOiBDb250ZXh0TWVudUl0ZW1bXTtcblxuICAgIC8qKlxuICAgICAqIENvbmZpZ3VyYXRpb24gZm9yIG9wZW5pbmcgdGhlIGFwcCBtZW51XG4gICAgICovXG4gICAgQElucHV0KFwibmd4LWN0eC1tZW51LWNvbmZpZ1wiKSBjb25maWc6IE5neEFwcE1lbnVPcHRpb25zID0ge307XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBkaWFsb2c6IE1hdERpYWxvZyxcbiAgICAgICAgcHJpdmF0ZSB2aWV3Q29udGFpbmVyOiBWaWV3Q29udGFpbmVyUmVmXG4gICAgKSB7IH1cblxuICAgIC8vIE5lZWRzIHRvIGJlIHB1YmxpYyBzbyB3ZSBjYW4gbWFudWFsbHkgb3BlbiB0aGUgZGlhbG9nXG4gICAgQEhvc3RMaXN0ZW5lcignY29udGV4dG1lbnUnLCBbJyRldmVudCddKVxuICAgIHB1YmxpYyBhc3luYyBvbkNvbnRleHRNZW51KGV2dDogUG9pbnRlckV2ZW50KSB7XG4gICAgICAgIGNvbnN0IGVsID0gdGhpcy52aWV3Q29udGFpbmVyLmVsZW1lbnQubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudDtcblxuICAgICAgICBlbC5jbGFzc0xpc3QuYWRkKFwibmd4LWFwcC1tZW51LW9wZW5cIik7XG5cbiAgICAgICAgcmV0dXJuIG9wZW5Db250ZXh0TWVudSh0aGlzLmRpYWxvZywgdGhpcy5tZW51SXRlbXMsIHRoaXMuZGF0YSwgZXZ0LCB0aGlzLmNvbmZpZylcbiAgICAgICAgICAgIC5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgICAgICAgICBlbC5jbGFzc0xpc3QucmVtb3ZlKFwibmd4LWFwcC1tZW51LW9wZW5cIik7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG59XG5cbi8vIEhlbHBlciB0byBvcGVuIHRoZSBjb250ZXh0IG1lbnUgd2l0aG91dCB1c2luZyB0aGUgZGlyZWN0aXZlLlxuZXhwb3J0IGNvbnN0IG9wZW5Db250ZXh0TWVudSA9IGFzeW5jIChkaWFsb2c6IE1hdERpYWxvZywgbWVudUl0ZW1zOiBDb250ZXh0TWVudUl0ZW1bXSwgZGF0YTogYW55LCBldnQ6IFBvaW50ZXJFdmVudCwgY29uZmlnOiBOZ3hBcHBNZW51T3B0aW9ucyA9IHt9KSA9PiB7XG4gICAgZXZ0LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZ0LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgY29uc3QgY29yZHMgPSBnZXRQb3NpdGlvbihldnQsIGNvbmZpZywgYXdhaXQgY2FsY01lbnVJdGVtQm91bmRzKG1lbnVJdGVtcywgZGF0YSkpO1xuICAgIGNvbnN0IHNwZWNpZmljSWQgPSBjcnlwdG8ucmFuZG9tVVVJRCgpO1xuXG4gICAgaWYgKCFjb25maWcuYWxpZ25tZW50KSBjb25maWcuYWxpZ25tZW50ID0gXCJzdGFydFwiO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlcyA9PiB7XG4gICAgICAgIGRpYWxvZy5vcGVuKENvbnRleHRNZW51Q29tcG9uZW50LCB7XG4gICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgZGF0YTogZGF0YSxcbiAgICAgICAgICAgICAgICBpdGVtczogbWVudUl0ZW1zLFxuICAgICAgICAgICAgICAgIGNvbmZpZzogY29uZmlnLFxuICAgICAgICAgICAgICAgIGlkOiBzcGVjaWZpY0lkXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcGFuZWxDbGFzczogW1wibmd4LWN0eC1tZW51XCIsICduZ3gtJyArIHNwZWNpZmljSWRdLmNvbmNhdChjb25maWc/LmN1c3RvbUNsYXNzIHx8IFtdKSxcbiAgICAgICAgICAgIHBvc2l0aW9uOiBjb3JkcyxcbiAgICAgICAgICAgIGJhY2tkcm9wQ2xhc3M6IFwibmd4LWN0eC1tZW51LWJhY2tkcm9wXCJcbiAgICAgICAgfSlcbiAgICAgICAgLmFmdGVyQ2xvc2VkKClcbiAgICAgICAgLnN1YnNjcmliZShzID0+IHtcbiAgICAgICAgICAgIHJlcyhzKTtcbiAgICAgICAgfSlcbiAgICB9KSBhcyBQcm9taXNlPGFueT47XG59O1xuIl19