Search code examples
angulartypescriptsassprimengmenubar

Keeping PrimeNG p-menubar to stay within viewport


I have been playing around with PrimeNG's p-menubar, but I am having an issue where if you have the bellow code:

<p-panel>
<div class="d-flex">
    <div class="flex-grow-1">
        <p-menubar [model]="menuItems" 
            styleClass="border border-0 rounded-0 pt-0 pb-0">
        </p-menubar>
    </div>
    <div>
        <p-menubar [model]="endMenuItems"
            styleClass="border border-0 rounded-0 pt-0 pb-0">
        </p-menubar>
    </div>
</div>

Let's fill these items with dummy content in my OnInit() function

this.menuItems = [
  {
    label: "Label 1",
    icon: "",
    items: [
      { label: "Dummy Item 1" },
      { label: "Dummy Item 2" }
    ],
  },
  {
    label: "Label 2",
    icon: "",
    items: [
      { label: "Dummy Item 1" },
      { label: "Dummy Item 2" }
    ],
  },
];

this.endMenuItems = [
  {
    label: "Label 1",
    icon: "",
    items: [
      { label: "Dummy Item 1" },
      { label: "Dummy Item 2", items: [
          { label: "Dummy Item 1" },
          { label: "Dummy Item 2" }
        ]
      }
    ]
  }
];

With this the p-menubar with endMenuItems has a submenu nested within it under Label 2 as you can see. The issue here is that this then pushes my viewport to extend and overflow with horizontal scrollbars. I would like it to instead open left wards so that the menu stays within the viewport.

I have tried referencing the different classes relative to the the submenu and using custom css for this right: 100% important but this was still overridden by PrimeNG even if I used ::ng-deep

::ng-deep .p-tieredmenu {
    .p-menuitem-active {
        .p-tieredmenusub {
            .p-submenu-list {
                right: 100% !important;
            }
        }
    }
}

Any help would be appreciated!

Here's a link to the stackblitz


Solution

  • If you want to style primeng components more in depth, you will have to reference the item you want to style with the styleClass attribute.

    For example :
    The p-card body is subdivided like this p-card > p-card-body > p-card-content.
    You can easily modify the p-card-body by adding the corresponding :

    <p-card>
        <ng-template pTemplate="body">card body</ng-template>
    </p-card>
    

    Sometimes primeng allow you to overload the template by using the corresponding pTemplate attribute, sometimes it doesn't work because of internal css overload.

    You can then use the styleClass attribute to specify what element you want to modify:

    <p-card styleClass="main-card">main card content</p-card>
    
    .main-card .p-card-body .p-card-content {
        padding: 0;
    }
    

    Of course, cou can also just style what's inside your ng-tamplate tag with a simple class attribute.