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