@kreash/ngx-contextmenu
Version:
An Angular component to show a context menu on an arbitrary component
609 lines (597 loc) • 31.4 kB
JavaScript
import * as i1$1 from '@angular/cdk/overlay';
import { OverlayContainer, FullscreenOverlayContainer, 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, Component, ChangeDetectionStrategy, Optional, Inject, Input, Output, ViewChild, ViewChildren, HostListener, Directive, ElementRef, Injectable, ViewEncapsulation, ContentChildren, 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: "19.1.7", 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: "19.1.7", 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 <span\n (click)=\"stopEvent($event)\"\n (contextmenu)=\"stopEvent($event)\"\n class=\"passive\"\n *ngIf=\"!menuItem.divider && menuItem.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 </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.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", 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 <span\n (click)=\"stopEvent($event)\"\n (contextmenu)=\"stopEvent($event)\"\n class=\"passive\"\n *ngIf=\"!menuItem.divider && menuItem.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 </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: "19.1.7", 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: "19.1.7", 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: "19.1.7", 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: "19.1.7", 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: "19.1.7", ngImport: i0, type: ContextMenuService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", 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: "19.1.7", 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: "19.1.7", 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: "19.1.7", 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: "19.1.7", ngImport: i0, type: ContextMenuAttachDirective, deps: [{ token: ContextMenuService }], target: i0.ɵɵFactoryTarget.Directive }); }
/** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.7", 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: "19.1.7", 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: "19.1.7", ngImport: i0, type: ContextMenuModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
/** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.7", 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: "19.1.7", ngImport: i0, type: ContextMenuModule, imports: [CommonModule, OverlayModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.7", 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