projects/i-components/src/lib/components/mat-menu/mat-menu.component.ts
This component represents material menu calls recursively in case of deeper node levels
selector | wm-mat-menu |
styleUrls | ./mat-menu.component.scss |
templateUrl | ./mat-menu.component.html |
Properties |
|
Methods |
Inputs |
constructor(injector: Injector)
|
||||||
Creates an instance of MatMenuComponent.
Parameters :
|
items | |
Type : any[]
|
|
Items RadMenuItemComponents array |
itemsToRender | |
Type : any
|
|
Set of dynamic items to render |
childMenuDynamicModels | ||||||
childMenuDynamicModels(child: any)
|
||||||
Returns set of sub dynamic components if applies.
Parameters :
Returns :
any
|
ngAfterViewInit |
ngAfterViewInit()
|
AfterViewInit
Returns :
void
|
processItemsToRender | ||||
processItemsToRender(child)
|
||||
Process dynamic items.
Parameters :
Returns :
any
{*} |
trackByFn | ||||||||||||
trackByFn(index: any, item: any)
|
||||||||||||
Function used by Angular to track elements in the ngFor directive. We use the GUID property to compare elements.
Parameters :
Returns :
any
{*} -return the model or object itself |
validateRendering |
validateRendering()
|
Validate internal mat menu view child to be ready.
Returns :
boolean
{boolean} |
Public childMenu |
Type : any
|
Decorators :
@ViewChild('childMenu', {static: true})
|
Child menu material menu |
items |
Type : any[]
|
Decorators :
@Input()
|
Items RadMenuItemComponents array |
itemsToRender |
Decorators :
@Input()
|
Set of dynamic items to render |
Public menu |
Type : any
|
Decorators :
@ViewChild('menu')
|
Sub material menu |
renderingFlag |
Default value : false
|
RenderingFlag |
import {
AfterViewInit,
Component,
Injector,
Input,
ViewChild,
} from '@angular/core';
import { Utils } from '../../utils/utilities';
/**
* This component represents material menu calls recursively in case of deeper node levels
*
* @export
* @class MatMenuComponent
* @implements {OnInit}
* @implements {AfterViewInit}
*/
@Component({
selector: 'wm-mat-menu',
templateUrl: './mat-menu.component.html',
styleUrls: ['./mat-menu.component.scss'],
})
export class MatMenuComponent implements AfterViewInit {
/**
* Items RadMenuItemComponents array
*
* @type {any[]}
* @memberof MatMenuComponent
*/
@Input() items: any[];
/**
* Set of dynamic items to render
*
* @memberof MatMenuComponent
*/
@Input() itemsToRender;
/**
* Child menu material menu
*
* @memberof MatMenuComponent
*/
@ViewChild('childMenu', { static: true }) public childMenu: any;
/**
* Sub material menu
*
* @memberof MatMenuComponent
*/
@ViewChild('menu') public menu: any;
/**
* RenderingFlag
*
* @memberof MatMenuComponent
*/
renderingFlag = false;
/**
* Creates an instance of MatMenuComponent.
*
* @memberof MatMenuComponent
*/
constructor(private injector: Injector) {}
/**
* AfterViewInit
*
* @memberof MatMenuComponent
*/
ngAfterViewInit(): void {
setTimeout(() => {
this.renderingFlag = true;
}, 0);
}
/**
* Validate internal mat menu view child to be ready.
*
* @return {*} {boolean}
* @memberof MatMenuComponent
*/
validateRendering(): boolean {
return this.menu?.renderingFlag === true;
}
/**
* Returns set of sub dynamic components if applies.
*
* @param {*} child
* @return {*}
* @memberof MatMenuComponent
*/
childMenuDynamicModels(child: any) {
return child.itemsToRender;
}
/**
* Process dynamic items.
*
* @param {*} child
* @return {*} {*}
* @memberof MatMenuComponent
*/
processItemsToRender(child): any {
return Utils.getDynamicUIElements(
child.item.items.internalArray,
[],
true,
this.injector
);
}
/**
* Function used by Angular to track elements in the ngFor directive.
* We use the GUID property to compare elements.
*
* @param {*} index - index of the array
* @param {*} item - item of the array
* @return {*} {*} -return the model or object itself
* @memberof BaseComponent
*/
trackByFn(index: any, item: any): any {
return item.model ?? item.item ?? item;
}
}
<mat-menu #childMenu="matMenu" [overlapTrigger]="false">
<!-- Static Rendering -->
<ng-container *ngIf="items && items.length > 0">
<span *ngFor="let child of items; let i = index; trackBy: trackByFn">
<!-- Handle branch node menu items -->
<span
*ngIf="
child.menuItems &&
child.renderingFlag &&
child.menuItems.toArray().length > 0 &&
child.visibility
"
>
<wm-mat-menu
#menu
[items]="child.menuItems"
[itemsToRender]="child.itemsToRender"
></wm-mat-menu>
<ng-container *ngIf="validateRendering()">
<button
mat-menu-item
color="primary"
[matMenuTriggerFor]="menu.childMenu"
>
<ng-container *ngIf="child.renderingFlag">
<ng-container
[ngTemplateOutlet]="child.itemTemplate"
[ngTemplateOutletContext]="{ context: { child: child } }"
>
</ng-container>
</ng-container>
</button>
</ng-container>
</span>
<!-- Handle leaf node menu items -->
<span
*ngIf="
child.menuItems &&
child.renderingFlag &&
child.menuItems.toArray().length === 0 &&
child.visibility
"
>
<ng-container *ngIf="child.renderingFlag">
<button mat-menu-item>
<ng-container
[ngTemplateOutlet]="child.itemTemplate"
[ngTemplateOutletContext]="{ context: { child: child } }"
>
</ng-container>
</button>
</ng-container>
</span>
</span>
</ng-container>
<ng-container
*ngIf="itemsToRender && itemsToRender.length > 0 && renderingFlag"
>
<span *ngFor="let child of itemsToRender; trackBy: trackByFn">
<!-- Handle branch node menu items -->
<span
*ngIf="
child.item && child.item.items.count > 0 && child.item.Visibility
"
>
<wm-mat-menu
#menu
[itemsToRender]="processItemsToRender(child)"
></wm-mat-menu>
<ng-container *ngIf="validateRendering() && menu.childMenu">
<button
mat-menu-item
color="primary"
[matMenuTriggerFor]="menu.childMenu"
>
<ng-container *ngIf="child.customInjector && child.component">
<ng-container
*ngComponentOutlet="
child.component;
injector: child.customInjector
"
></ng-container>
</ng-container>
</button>
</ng-container>
</span>
<!-- Handle leaf node menu items -->
<span
*ngIf="
child.item && child.item.items.count === 0 && child.item.Visibility
"
>
<button mat-menu-item>
<ng-container *ngIf="child.customInjector && child.component">
<ng-container
*ngComponentOutlet="
child.component;
injector: child.customInjector
"
></ng-container>
</ng-container>
</button>
</span>
</span>
</ng-container>
</mat-menu>
./mat-menu.component.scss
.mat-menu-item {
height: auto;
padding: 0px;
line-height: 1;
border: 1px solid transparent;
border-radius: 2px;
cursor: default;
&:hover {
background: rgb(255, 251, 218);
background: linear-gradient(
180deg,
rgba(255, 251, 218, 1) 0%,
rgba(255, 251, 163, 1) 100%
);
border-color: #ffc92b;
}
}