Search code examples
angularangular-materialcontextmenu

Angular Material custom context menu (right-click)


Using Angular Material, is it possible to override the default context menu (right-click) with my own MatMenu, on a specified template element?

There is the MatMenuTrigger directive, but it only supports the left-click trigger. Moreover, it only shows the MatMenu in a fixed position relative to the element, and not to the mouse position at the moment of trigger.

I've tried CdkMenu, but I can't get it to work with MatMenu.


Solution

  • You can open your own context menu using below code.

    In your component.html file you need to put this code

    <div (contextmenu)="onRightClick($event)"></div>
    

    You can put below code in end of the html file

    <!-- an hidden div is created to set the position of appearance of the menu-->
    <div style="visibility: hidden; position: fixed;" [style.left]="menuTopLeftPosition.x"
        [style.top]="menuTopLeftPosition.y" [matMenuTriggerFor]="rightMenu"></div>
    
    <!-- standard material menu -->
    <mat-menu #rightMenu="matMenu">
        <ng-template matMenuContent let-item="item" *transloco="let t">
            <button mat-menu-item>Option 1</button>
            <button mat-menu-item>Option 2</button>
            <button mat-menu-item>Option 3</button>
            <button mat-menu-item>Option 4</button>
        </ng-template>
    </mat-menu>
    

    In your component.ts file

    @ViewChild(MatMenuTrigger, { static: true }) matMenuTrigger: MatMenuTrigger;
    
    menuTopLeftPosition = { x: '0', y: '0' }
    
    onRightClick(event) {
          // preventDefault avoids to show the visualization of the right-click menu of the browser 
          event.preventDefault();
    
          // we record the mouse position in our object 
          this.menuTopLeftPosition.x = event.clientX + 'px';
          this.menuTopLeftPosition.y = event.clientY + 'px';
          // we open the menu 
          this.matMenuTrigger.openMenu();
    }