Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create collapse menu using Angular Material?

In documentation of Angular Material there is cool feature. Menu with subcategory which can be expanded/collapsed.

Is it possible to create it using some component? Or I have to do it myself from scratch? Or maybe you can suggest me some package that save my time.

enter image description here

like image 441
DiPix Avatar asked Oct 10 '18 10:10

DiPix


People also ask

How is angular material accordion used?

We recommend to set the accordion trigger element as a role="button" while the body container as a role="region" . Furthermore, the trigger should have aria-controls pointing to the body and aria-expanded based on the expanded state, while the body should have an aria-labelledby that points to the header.

Which angular material elements can be used to construct a menu?

Angular Material's menu component consists of two connected parts: the trigger and the pop-up menu. The menu trigger is a standard button element augmented with aria-haspopup , aria-expanded , and aria-controls to create the relationship to the pop-up panel.


2 Answers

I tried to achieve this myself with a side-nav. Maybe it can save you some time.

The nav-items follows a simple interface:

interface NavItem {
displayName: string;
disabled?: boolean;
iconName: string;
route?: string;
children?: NavItem[];}

And then in the component.html the main idea is to add the nav-items recursively (*ngFor). Use mat-accordions for each category and then use another *ngFor to get the children:

<mat-nav-list>
<span *ngFor="let item of menu">
  <span *ngIf="item.children && item.children.length > 0">
    <mat-accordion>
      <mat-expansion-panel>
        <mat-expansion-panel-header>
          <mat-panel-title>
            <!-- Cabeceras del submenu -->
            <div fxLayout="row" fxLayoutAlign="space-between center" > 
              <mat-icon>{{item.iconName}}</mat-icon>
              {{item.displayName}}
            </div>
          </mat-panel-title>
        </mat-expansion-panel-header>
        <span *ngFor="let child of item.children">
          <mat-list-item routerLink="[child.route]">
            <!-- Entradas de cada submenú  -->
            <div fxLayout="row" fxLayoutAlign="space-between center" > 
              <mat-icon>{{child.iconName}}</mat-icon>
              {{child.displayName}}
            </div>
          </mat-list-item>
        </span>
      </mat-expansion-panel>
    </mat-accordion>
  </span>
  <span *ngIf="!item.children || item.children.length === 0">
    <mat-list-item routerLink="[item.route]">
      <!-- Entradas principales -->
      <div fxLayout="row" fxLayoutAlign="space-between center">
        <mat-icon>{{item.iconName}}</mat-icon>
        {{item.displayName}}
      </div>
    </mat-list-item>
  </span>
</span>

Have a look: https://stackblitz.com/edit/angular-side-nav-dynamic-expansive-menu

like image 85
felixosle Avatar answered Sep 19 '22 18:09

felixosle


Place mat-expansion-panel's in a mat-accordion and mat-nav-list's in the expansion panels. Then create a global style for the new navigation accordion.

StackzBlitz

<mat-accordion class="app-nav-accordion">
  <mat-expansion-panel class="mat-elevation-z0">
    <mat-expansion-panel-header>
      <mat-panel-title>Section Two</mat-panel-title>
    </mat-expansion-panel-header>
    <mat-nav-list>
      <a mat-list-item>Item Three</a>
        <a mat-list-item>Item Four</a>
    </mat-nav-list>
  </mat-expansion-panel>
</mat-accordion>
.app-nav-accordion {
  .mat-expansion-panel {
    border-radius: 0px !important;
    box-shadow: none !important;

    &.mat-expansion-panel-spacing {
      margin: 0px;
    }

    .mat-expansion-panel-body {
      padding: 0px;
    }

    .mat-expansion-panel-header {
      height: 40px;
      padding: 0px 24px 0px 16px;
    }

    .mat-expansion-panel-header-title {
      color: rgba(0,0,0,0.54);
      font-size: 14px;
      font-weight: 500;
    }
  }
}
like image 33
Trevor Karjanis Avatar answered Sep 23 '22 18:09

Trevor Karjanis