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.

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.
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.
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
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;
    }
  }
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With