UNPKG

@kreash/ngx-contextmenu

Version:

An Angular component to show a context menu on an arbitrary component

609 lines (597 loc) 31.4 kB
import * as i1$1 from '@angular/cdk/overlay'; import { FullscreenOverlayContainer, OverlayContainer, OverlayModule } from '@angular/cdk/overlay'; import * as i1 from '@angular/common'; import { CommonModule } from '@angular/common'; import * as i0 from '@angular/core'; import { InjectionToken, EventEmitter, QueryList, HostListener, ViewChildren, ViewChild, Output, Input, Optional, Inject, ChangeDetectionStrategy, Component, Directive, ElementRef, Injectable, ContentChildren, ViewEncapsulation, NgModule } from '@angular/core'; import { ActiveDescendantKeyManager } from '@angular/cdk/a11y'; import { Subscription, Subject } from 'rxjs'; import { first } from 'rxjs/operators'; import { ComponentPortal } from '@angular/cdk/portal'; const CONTEXT_MENU_OPTIONS = new InjectionToken('CONTEXT_MENU_OPTIONS'); function evaluateIfFunction(value, item) { return value instanceof Function ? value(item) : value; } const ARROW_LEFT_KEYCODE = 37; class ContextMenuContentComponent { constructor(options) { this.menuItems = []; this.isLeaf = false; this.execute = new EventEmitter(); this.openSubMenu = new EventEmitter(); this.closeLeafMenu = new EventEmitter(); this.closeAllMenus = new EventEmitter(); this.autoFocus = false; this.useBootstrap4 = false; this.subscription = new Subscription(); if (options) { this.autoFocus = options.autoFocus; this.useBootstrap4 = options.useBootstrap4; } } ngOnInit() { this.menuItems.forEach((menuItem) => { menuItem.currentItem = this.item; this.subscription.add(menuItem.execute.subscribe((event) => this.execute.emit({ ...event, menuItem }))); }); const queryList = new QueryList(); queryList.reset(this.menuItems); this._keyManager = new ActiveDescendantKeyManager(queryList).withWrap(); } ngAfterViewInit() { if (this.autoFocus) { setTimeout(() => this.focus()); } this.overlay.updatePosition(); } ngOnDestroy() { this.subscription.unsubscribe(); } focus() { if (this.autoFocus) { this.menuElement.nativeElement.focus(); } } stopEvent($event) { $event.stopPropagation(); } isMenuItemEnabled(menuItem) { return evaluateIfFunction(menuItem?.enabled, this.item); } isMenuItemVisible(menuItem) { return evaluateIfFunction(menuItem?.visible, this.item); } isDisabled(link) { return link.enabled && !link.enabled(this.item); } onKeyEvent(event) { if (!this.isLeaf) { return; } this._keyManager.onKeydown(event); } keyboardOpenSubMenu(event) { if (!this.isLeaf) { return; } this.cancelEvent(event); const menuItem = this.menuItems[this._keyManager.activeItemIndex]; if (menuItem) { this.onOpenSubMenu(menuItem); } } keyboardMenuItemSelect(event) { if (!this.isLeaf) { return; } this.cancelEvent(event); const menuItem = this.menuItems[this._keyManager.activeItemIndex]; if (menuItem) { this.onMenuItemSelect(menuItem, event); } } onCloseLeafMenu(event) { if (!this.isLeaf) { return; } this.cancelEvent(event); this.closeLeafMenu.emit({ exceptRootMenu: event.keyCode === ARROW_LEFT_KEYCODE, event, }); } closeMenu(event) { if (event.type === 'click' && event.button === 2) { return; } this.closeAllMenus.emit({ event }); } onOpenSubMenu(menuItem, event) { const anchorElementRef = this.menuItemElements.toArray()[this._keyManager.activeItemIndex]; const anchorElement = anchorElementRef && anchorElementRef.nativeElement; this.openSubMenu.emit({ anchorElement, contextMenu: menuItem.subMenu, event, item: this.item, parentContextMenu: this, }); } onMenuItemSelect(menuItem, event) { event.preventDefault(); event.stopPropagation(); this.onOpenSubMenu(menuItem, event); if (!menuItem.subMenu) { menuItem.triggerExecute(this.item, event); } } cancelEvent(event) { if (!event) { return; } const target = event.target; if (['INPUT', 'TEXTAREA', 'SELECT'].indexOf(target.tagName) > -1 || target.isContentEditable) { return; } event.preventDefault(); event.stopPropagation(); } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ContextMenuContentComponent, deps: [{ token: CONTEXT_MENU_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Component }); } /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type: ContextMenuContentComponent, isStandalone: false, selector: "context-menu-content", inputs: { menuItems: "menuItems", item: "item", event: "event", parentContextMenu: "parentContextMenu", menuClass: "menuClass", overlay: "overlay", isLeaf: "isLeaf" }, outputs: { execute: "execute", openSubMenu: "openSubMenu", closeLeafMenu: "closeLeafMenu", closeAllMenus: "closeAllMenus" }, host: { listeners: { "window:keydown.ArrowDown": "onKeyEvent($event)", "window:keydown.ArrowUp": "onKeyEvent($event)", "window:keydown.ArrowRight": "keyboardOpenSubMenu($event)", "window:keydown.Enter": "keyboardMenuItemSelect($event)", "window:keydown.Space": "keyboardMenuItemSelect($event)", "window:keydown.Escape": "onCloseLeafMenu($event)", "window:keydown.ArrowLeft": "onCloseLeafMenu($event)", "document:click": "closeMenu($event)", "document:contextmenu": "closeMenu($event)" } }, viewQueries: [{ propertyName: "menuElement", first: true, predicate: ["menu"], descendants: true, static: true }, { propertyName: "menuItemElements", predicate: ["li"], descendants: true }], ngImport: i0, template: "<div class=\"dropdown open show ngx-contextmenu\" [ngClass]=\"menuClass\" tabindex=\"0\">\n <ul #menu class=\"dropdown-menu show\" style=\"position: static; float: none\" tabindex=\"0\">\n @for (menuItem of menuItems; track $index) {\n <li\n #li\n [class.disabled]=\"!isMenuItemEnabled(menuItem)\"\n [class.divider]=\"menuItem.divider\"\n [class.dropdown-divider]=\"useBootstrap4 && menuItem.divider\"\n [class.active]=\"menuItem.isActive && isMenuItemEnabled(menuItem)\"\n [attr.role]=\"menuItem.divider ? 'separator' : undefined\"\n >\n @if (!menuItem.divider && !menuItem.passive) {\n <a\n href\n [class.dropdown-item]=\"useBootstrap4\"\n [class.active]=\"menuItem.isActive && isMenuItemEnabled(menuItem)\"\n [class.disabled]=\"useBootstrap4 && !isMenuItemEnabled(menuItem)\"\n [class.hasSubMenu]=\"!!menuItem.subMenu\"\n (click)=\"onMenuItemSelect(menuItem, $event)\"\n (mouseenter)=\"onOpenSubMenu(menuItem, $event)\"\n >\n <ng-template [ngTemplateOutlet]=\"menuItem.template\" [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-template>\n </a>\n }\n @if (!menuItem.divider && menuItem.passive) {\n @if (!menuItem.divider && menuItem.passive) {\n <span\n (click)=\"stopEvent($event)\"\n (contextmenu)=\"stopEvent($event)\"\n class=\"passive\"\n [class.dropdown-item]=\"useBootstrap4\"\n [class.disabled]=\"useBootstrap4 && !isMenuItemEnabled(menuItem)\"\n >\n <ng-template [ngTemplateOutlet]=\"menuItem.template\" [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-template>\n </span>\n }\n }\n </li>\n }\n </ul>\n</div>\n", styles: ["@charset \"UTF-8\";.passive{display:block;padding:3px 20px;clear:both;font-weight:400;white-space:nowrap}.hasSubMenu:before{content:\"\\25b6\";float:right}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ContextMenuContentComponent, decorators: [{ type: Component, args: [{ selector: 'context-menu-content', changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, template: "<div class=\"dropdown open show ngx-contextmenu\" [ngClass]=\"menuClass\" tabindex=\"0\">\n <ul #menu class=\"dropdown-menu show\" style=\"position: static; float: none\" tabindex=\"0\">\n @for (menuItem of menuItems; track $index) {\n <li\n #li\n [class.disabled]=\"!isMenuItemEnabled(menuItem)\"\n [class.divider]=\"menuItem.divider\"\n [class.dropdown-divider]=\"useBootstrap4 && menuItem.divider\"\n [class.active]=\"menuItem.isActive && isMenuItemEnabled(menuItem)\"\n [attr.role]=\"menuItem.divider ? 'separator' : undefined\"\n >\n @if (!menuItem.divider && !menuItem.passive) {\n <a\n href\n [class.dropdown-item]=\"useBootstrap4\"\n [class.active]=\"menuItem.isActive && isMenuItemEnabled(menuItem)\"\n [class.disabled]=\"useBootstrap4 && !isMenuItemEnabled(menuItem)\"\n [class.hasSubMenu]=\"!!menuItem.subMenu\"\n (click)=\"onMenuItemSelect(menuItem, $event)\"\n (mouseenter)=\"onOpenSubMenu(menuItem, $event)\"\n >\n <ng-template [ngTemplateOutlet]=\"menuItem.template\" [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-template>\n </a>\n }\n @if (!menuItem.divider && menuItem.passive) {\n @if (!menuItem.divider && menuItem.passive) {\n <span\n (click)=\"stopEvent($event)\"\n (contextmenu)=\"stopEvent($event)\"\n class=\"passive\"\n [class.dropdown-item]=\"useBootstrap4\"\n [class.disabled]=\"useBootstrap4 && !isMenuItemEnabled(menuItem)\"\n >\n <ng-template [ngTemplateOutlet]=\"menuItem.template\" [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-template>\n </span>\n }\n }\n </li>\n }\n </ul>\n</div>\n", styles: ["@charset \"UTF-8\";.passive{display:block;padding:3px 20px;clear:both;font-weight:400;white-space:nowrap}.hasSubMenu:before{content:\"\\25b6\";float:right}\n"] }] }], ctorParameters: () => [{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [CONTEXT_MENU_OPTIONS] }] }], propDecorators: { menuItems: [{ type: Input }], item: [{ type: Input }], event: [{ type: Input }], parentContextMenu: [{ type: Input }], menuClass: [{ type: Input }], overlay: [{ type: Input }], isLeaf: [{ type: Input }], execute: [{ type: Output }], openSubMenu: [{ type: Output }], closeLeafMenu: [{ type: Output }], closeAllMenus: [{ type: Output }], menuElement: [{ type: ViewChild, args: ['menu', { static: true }] }], menuItemElements: [{ type: ViewChildren, args: ['li'] }], onKeyEvent: [{ type: HostListener, args: ['window:keydown.ArrowDown', ['$event']] }, { type: HostListener, args: ['window:keydown.ArrowUp', ['$event']] }], keyboardOpenSubMenu: [{ type: HostListener, args: ['window:keydown.ArrowRight', ['$event']] }], keyboardMenuItemSelect: [{ type: HostListener, args: ['window:keydown.Enter', ['$event']] }, { type: HostListener, args: ['window:keydown.Space', ['$event']] }], onCloseLeafMenu: [{ type: HostListener, args: ['window:keydown.Escape', ['$event']] }, { type: HostListener, args: ['window:keydown.ArrowLeft', ['$event']] }], closeMenu: [{ type: HostListener, args: ['document:click', ['$event']] }, { type: HostListener, args: ['document:contextmenu', ['$event']] }] } }); class ContextMenuItemDirective { get disabled() { return this.passive || this.divider || !evaluateIfFunction(this.enabled, this.currentItem); } constructor(template, elementRef) { this.template = template; this.elementRef = elementRef; this.divider = false; this.enabled = true; this.passive = false; this.visible = true; this.execute = new EventEmitter(); this.isActive = false; } setActiveStyles() { this.isActive = true; } setInactiveStyles() { this.isActive = false; } triggerExecute(item, $event) { if (!evaluateIfFunction(this.enabled, item)) { return; } this.execute.emit({ event: $event, item }); } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ContextMenuItemDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); } /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.10", type: ContextMenuItemDirective, isStandalone: false, selector: "[contextMenuItem]", inputs: { subMenu: "subMenu", divider: "divider", enabled: "enabled", passive: "passive", visible: "visible" }, outputs: { execute: "execute" }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ContextMenuItemDirective, decorators: [{ type: Directive, args: [{ selector: '[contextMenuItem]', standalone: false }] }], ctorParameters: () => [{ type: i0.TemplateRef }, { type: i0.ElementRef }], propDecorators: { subMenu: [{ type: Input }], divider: [{ type: Input }], enabled: [{ type: Input }], passive: [{ type: Input }], visible: [{ type: Input }], execute: [{ type: Output }] } }); class ContextMenuService { constructor(overlay, scrollStrategy) { this.overlay = overlay; this.scrollStrategy = scrollStrategy; this.isDestroyingLeafMenu = false; this.show = new Subject(); this.close = new Subject(); this.overlays = []; this.fakeElement = { getBoundingClientRect: () => new DOMRect(0, 0, 0, 0), }; this.rootMenuPositionsFor = [ { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', }, { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', }, { originX: 'end', originY: 'top', overlayX: 'start', overlayY: 'top', }, { originX: 'start', originY: 'top', overlayX: 'end', overlayY: 'top', }, { originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', }, { originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', }, ]; this.subMenuPositions = [ { originX: 'end', originY: 'top', overlayX: 'start', overlayY: 'top', }, { originX: 'start', originY: 'top', overlayX: 'end', overlayY: 'top', }, { originX: 'end', originY: 'bottom', overlayX: 'start', overlayY: 'bottom', }, { originX: 'start', originY: 'bottom', overlayX: 'end', overlayY: 'bottom', }, ]; } openContextMenu(context) { const { anchorElement, event, parentContextMenu } = context; if (!parentContextMenu) { const mouseEvent = event; this.fakeElement.getBoundingClientRect = () => new DOMRect(mouseEvent.clientX, mouseEvent.clientY, 0, 0); this.closeAllContextMenus({ eventType: 'cancel', event }); const positionStrategy = this.overlay .position() .flexibleConnectedTo(new ElementRef(anchorElement ?? this.fakeElement)) .withPositions(this.rootMenuPositionsFor) .withFlexibleDimensions(false); this.overlays = [ this.overlay.create({ positionStrategy, panelClass: 'ngx-contextmenu', scrollStrategy: this.scrollStrategy.close(), }), ]; this.attachContextMenu(this.overlays[0], context); } else { const positionStrategy = this.overlay .position() .flexibleConnectedTo(new ElementRef(event?.target ?? anchorElement)) .withPositions(this.subMenuPositions) .withFlexibleDimensions(false); const newOverlay = this.overlay.create({ positionStrategy, panelClass: 'ngx-contextmenu', scrollStrategy: this.scrollStrategy.close(), }); this.destroySubMenus(parentContextMenu); this.overlays = this.overlays.concat(newOverlay); this.attachContextMenu(newOverlay, context); } } attachContextMenu(overlay, context) { const { event, item, menuItems, menuClass } = context; const contextMenuContent = overlay.attach(new ComponentPortal(ContextMenuContentComponent)); const contentInstance = contextMenuContent.instance; contentInstance.event = event; contentInstance.item = item; contentInstance.menuItems = menuItems; contentInstance.overlay = overlay; contentInstance.isLeaf = true; contentInstance.menuClass = menuClass; overlay.contextMenu = contentInstance; const subscriptions = new Subscription(); subscriptions.add(contentInstance.execute.subscribe((executeEvent) => this.closeAllContextMenus({ eventType: 'execute', ...executeEvent }))); subscriptions.add(contentInstance.closeAllMenus.subscribe((closeAllEvent) => this.closeAllContextMenus({ eventType: 'cancel', ...closeAllEvent }))); subscriptions.add(contentInstance.closeLeafMenu.subscribe((closeLeafMenuEvent) => this.destroyLeafMenu(closeLeafMenuEvent))); subscriptions.add(contentInstance.openSubMenu.subscribe((subMenuEvent) => { this.destroySubMenus(contentInstance); if (!subMenuEvent.contextMenu) { contentInstance.isLeaf = true; return; } contentInstance.isLeaf = false; this.show.next(subMenuEvent); })); contextMenuContent.onDestroy(() => { menuItems.forEach((menuItem) => (menuItem.isActive = false)); subscriptions.unsubscribe(); }); contextMenuContent.changeDetectorRef.detectChanges(); } closeAllContextMenus(closeEvent) { if (this.overlays?.length) { this.close.next(closeEvent); this.overlays.forEach((overlay) => this.destroyOverlay(overlay)); } this.overlays = []; } getLastAttachedOverlay() { let overlay = this.overlays.at(-1); while (this.overlays.length > 1 && overlay && !overlay.hasAttached()) { this.destroyOverlay(overlay); this.overlays = this.overlays.slice(0, -1); overlay = this.overlays.at(-1); } return overlay; } destroyLeafMenu({ exceptRootMenu, event } = {}) { if (this.isDestroyingLeafMenu) { return; } this.isDestroyingLeafMenu = true; setTimeout(() => { const overlay = this.getLastAttachedOverlay(); if (this.overlays.length > 1 && overlay) { this.destroyOverlay(overlay); } if (!exceptRootMenu && this.overlays.length > 0 && overlay) { this.close.next({ eventType: 'cancel', event }); this.destroyOverlay(overlay); } const newLeaf = this.getLastAttachedOverlay(); if (newLeaf) { newLeaf.contextMenu.isLeaf = true; } this.isDestroyingLeafMenu = false; }); } destroySubMenus(contextMenu) { const overlay = contextMenu.overlay; const index = this.overlays.indexOf(overlay); this.overlays.slice(index + 1).forEach((subMenuOverlay) => { this.destroyOverlay(subMenuOverlay); }); } isLeafMenu(contextMenuContent) { const overlay = this.getLastAttachedOverlay(); return contextMenuContent.overlay === overlay; } destroyOverlay(overlay) { overlay.detach(); overlay.dispose(); } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ContextMenuService, deps: [{ token: i1$1.Overlay }, { token: i1$1.ScrollStrategyOptions }], target: i0.ɵɵFactoryTarget.Injectable }); } /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ContextMenuService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ContextMenuService, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i1$1.Overlay }, { type: i1$1.ScrollStrategyOptions }] }); class ContextMenuComponent { constructor(contextMenuService, options) { this.contextMenuService = contextMenuService; this.menuClass = ''; this.autoFocus = false; this.useBootstrap4 = false; this.disabled = false; this.close = new EventEmitter(); this.open = new EventEmitter(); this.visibleMenuItems = []; this.links = []; this.subscription = new Subscription(); if (options) { this.autoFocus = options.autoFocus; this.useBootstrap4 = options.useBootstrap4; } this.subscription.add(contextMenuService.show.subscribe((menuEvent) => { this.onMenuEvent(menuEvent); })); } ngOnDestroy() { this.subscription.unsubscribe(); } onMenuEvent(menuEvent) { if (this.disabled) { return; } const { contextMenu, event, item } = menuEvent; if (contextMenu && contextMenu !== this) { return; } this.event = event; this.item = item; this.setVisibleMenuItems(); this.contextMenuService.openContextMenu({ ...menuEvent, menuItems: this.visibleMenuItems, menuClass: this.menuClass, }); this.contextMenuService.close .pipe(first()) .subscribe((closeEvent) => this.close.emit(closeEvent)); this.open.next(menuEvent); } isMenuItemVisible(menuItem) { return evaluateIfFunction(menuItem.visible, this.item); } setVisibleMenuItems() { this.visibleMenuItems = this.menuItems.filter((menuItem) => this.isMenuItemVisible(menuItem)); } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ContextMenuComponent, deps: [{ token: ContextMenuService }, { token: CONTEXT_MENU_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Component }); } /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.10", type: ContextMenuComponent, isStandalone: false, selector: "context-menu", inputs: { menuClass: "menuClass", autoFocus: "autoFocus", useBootstrap4: "useBootstrap4", disabled: "disabled" }, outputs: { close: "close", open: "open" }, queries: [{ propertyName: "menuItems", predicate: ContextMenuItemDirective }], viewQueries: [{ propertyName: "menuElement", first: true, predicate: ["menu"], descendants: true }], ngImport: i0, template: ``, isInline: true, styles: [".cdk-overlay-container{position:fixed;z-index:1000;pointer-events:none;top:0;left:0;width:100%;height:100%}.ngx-contextmenu.cdk-overlay-pane{position:absolute;pointer-events:auto;box-sizing:border-box}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ContextMenuComponent, decorators: [{ type: Component, args: [{ encapsulation: ViewEncapsulation.None, selector: 'context-menu', template: ``, changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, styles: [".cdk-overlay-container{position:fixed;z-index:1000;pointer-events:none;top:0;left:0;width:100%;height:100%}.ngx-contextmenu.cdk-overlay-pane{position:absolute;pointer-events:auto;box-sizing:border-box}\n"] }] }], ctorParameters: () => [{ type: ContextMenuService }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [CONTEXT_MENU_OPTIONS] }] }], propDecorators: { menuClass: [{ type: Input }], autoFocus: [{ type: Input }], useBootstrap4: [{ type: Input }], disabled: [{ type: Input }], close: [{ type: Output }], open: [{ type: Output }], menuItems: [{ type: ContentChildren, args: [ContextMenuItemDirective] }], menuElement: [{ type: ViewChild, args: ['menu', { static: false }] }] } }); class ContextMenuAttachDirective { constructor(contextMenuService) { this.contextMenuService = contextMenuService; } onContextMenu(event) { if (!this.contextMenu.disabled) { this.contextMenuService.show.next({ contextMenu: this.contextMenu, event, item: this.contextMenuSubject, }); event.preventDefault(); event.stopPropagation(); } } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ContextMenuAttachDirective, deps: [{ token: ContextMenuService }], target: i0.ɵɵFactoryTarget.Directive }); } /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.10", type: ContextMenuAttachDirective, isStandalone: false, selector: "[contextMenu]", inputs: { contextMenuSubject: "contextMenuSubject", contextMenu: "contextMenu" }, host: { listeners: { "contextmenu": "onContextMenu($event)" } }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ContextMenuAttachDirective, decorators: [{ type: Directive, args: [{ selector: '[contextMenu]', standalone: false }] }], ctorParameters: () => [{ type: ContextMenuService }], propDecorators: { contextMenuSubject: [{ type: Input }], contextMenu: [{ type: Input }], onContextMenu: [{ type: HostListener, args: ['contextmenu', ['$event']] }] } }); class ContextMenuModule { static forRoot(options) { return { ngModule: ContextMenuModule, providers: [ ContextMenuService, { provide: CONTEXT_MENU_OPTIONS, useValue: options, }, { provide: OverlayContainer, useClass: FullscreenOverlayContainer }, ], }; } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ContextMenuModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } /** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.10", ngImport: i0, type: ContextMenuModule, declarations: [ContextMenuComponent, ContextMenuContentComponent, ContextMenuAttachDirective, ContextMenuItemDirective], imports: [CommonModule, OverlayModule], exports: [ContextMenuComponent, ContextMenuAttachDirective, ContextMenuItemDirective] }); } /** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ContextMenuModule, imports: [CommonModule, OverlayModule] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ContextMenuModule, decorators: [{ type: NgModule, args: [{ declarations: [ContextMenuComponent, ContextMenuContentComponent, ContextMenuAttachDirective, ContextMenuItemDirective], exports: [ContextMenuComponent, ContextMenuAttachDirective, ContextMenuItemDirective], imports: [CommonModule, OverlayModule], }] }] }); /* Public API Surface of ngx-contextmenu */ /** * Generated bundle index. Do not edit. */ export { ContextMenuAttachDirective, ContextMenuComponent, ContextMenuItemDirective, ContextMenuModule, ContextMenuService }; //# sourceMappingURL=kreash-ngx-contextmenu.mjs.map