[ADF-2859] conditional evaluation of disabled state for content actions (#3450)

* react on [disabled] binding changes

* [disabled] binding updates for context menu items

* evaluating disabled state with a function

* unit test

* restore original description

* remove irrelevant test

* fix tests
This commit is contained in:
Denys Vuika
2018-06-07 23:28:01 +01:00
committed by Eugenio Romano
parent 08fd49c4e3
commit cb88a22a76
10 changed files with 199 additions and 93 deletions

View File

@@ -29,15 +29,12 @@ import { ContextMenuService } from './context-menu.service';
template: `
<button mat-button [matMenuTriggerFor]="contextMenu"></button>
<mat-menu #contextMenu="matMenu" class="context-menu">
<button
*ngFor="let link of links"
<button *ngFor="let link of links"
mat-menu-item
(click)="onMenuItemClick($event, link)"
[attr.disabled]="link.model?.disabled || undefined">
<mat-icon *ngIf="showIcons && link.model?.icon">
{{ link.model?.icon }}
</mat-icon>
{{ (link.title || link.model?.title) | translate}}
[disabled]="link.model?.disabled"
(click)="onMenuItemClick($event, link)">
<mat-icon *ngIf="showIcons && link.model?.icon">{{ link.model.icon }}</mat-icon>
{{ (link.title || link.model?.title) | translate }}
</button>
</mat-menu>
`
@@ -47,9 +44,7 @@ export class ContextMenuHolderComponent implements OnInit, OnDestroy {
private mouseLocation: { left: number, top: number } = {left: 0, top: 0};
private menuElement = null;
private openSubscription: Subscription;
private closeSubscription: Subscription;
private contextSubscription: Subscription;
private subscriptions: Subscription[] = [];
private contextMenuListenerFn: () => void;
@Input()
@@ -68,7 +63,7 @@ export class ContextMenuHolderComponent implements OnInit, OnDestroy {
@HostListener('window:resize', ['$event'])
onResize(event) {
if (this.mdMenuElement) {
this.setPositionAfterCDKrecalculation();
this.updatePosition();
}
}
@@ -80,33 +75,36 @@ export class ContextMenuHolderComponent implements OnInit, OnDestroy {
) {}
ngOnInit() {
this.contextSubscription = this.contextMenuService.show.subscribe(e => this.showMenu(e.event, e.obj));
this.subscriptions.push(
this.contextMenuService.show.subscribe(e => this.showMenu(e.event, e.obj)),
this.openSubscription = this.menuTrigger.onMenuOpen.subscribe(() => {
const container = this.overlayContainer.getContainerElement();
if (container) {
this.contextMenuListenerFn = this.renderer.listen(container, 'contextmenu', (e: Event) => {
e.preventDefault();
});
}
this.menuElement = this.getContextMenuElement();
});
this.menuTrigger.onMenuOpen.subscribe(() => {
const container = this.overlayContainer.getContainerElement();
if (container) {
this.contextMenuListenerFn = this.renderer.listen(container, 'contextmenu', (e: Event) => {
e.preventDefault();
});
}
this.menuElement = this.getContextMenuElement();
}),
this.closeSubscription = this.menuTrigger.onMenuClose.subscribe(() => {
this.menuElement = null;
if (this.contextMenuListenerFn) {
this.contextMenuListenerFn();
}
});
this.menuTrigger.onMenuClose.subscribe(() => {
this.menuElement = null;
if (this.contextMenuListenerFn) {
this.contextMenuListenerFn();
}
})
);
}
ngOnDestroy() {
if (this.contextMenuListenerFn) {
this.contextMenuListenerFn();
}
this.contextSubscription.unsubscribe();
this.openSubscription.unsubscribe();
this.closeSubscription.unsubscribe();
this.subscriptions.forEach(subscription => subscription.unsubscribe());
this.subscriptions = [];
this.menuElement = null;
}
@@ -132,16 +130,10 @@ export class ContextMenuHolderComponent implements OnInit, OnDestroy {
this.menuTrigger.openMenu();
if (this.mdMenuElement) {
this.setPositionAfterCDKrecalculation();
this.updatePosition();
}
}
setPositionAfterCDKrecalculation() {
setTimeout(() => {
this.setPosition();
}, 0);
}
get mdMenuElement() {
return this.menuElement;
}
@@ -153,22 +145,24 @@ export class ContextMenuHolderComponent implements OnInit, OnDestroy {
};
}
private setPosition() {
if (this.mdMenuElement.clientWidth + this.mouseLocation.left > this.viewport.getViewportRect().width) {
this.menuTrigger.menu.xPosition = 'before';
this.mdMenuElement.parentElement.style.left = this.mouseLocation.left - this.mdMenuElement.clientWidth + 'px';
} else {
this.menuTrigger.menu.xPosition = 'after';
this.mdMenuElement.parentElement.style.left = this.locationCss().left;
}
private updatePosition() {
setTimeout(() => {
if (this.mdMenuElement.clientWidth + this.mouseLocation.left > this.viewport.getViewportRect().width) {
this.menuTrigger.menu.xPosition = 'before';
this.mdMenuElement.parentElement.style.left = this.mouseLocation.left - this.mdMenuElement.clientWidth + 'px';
} else {
this.menuTrigger.menu.xPosition = 'after';
this.mdMenuElement.parentElement.style.left = this.locationCss().left;
}
if (this.mdMenuElement.clientHeight + this.mouseLocation.top > this.viewport.getViewportRect().height) {
this.menuTrigger.menu.yPosition = 'above';
this.mdMenuElement.parentElement.style.top = this.mouseLocation.top - this.mdMenuElement.clientHeight + 'px';
} else {
this.menuTrigger.menu.yPosition = 'below';
this.mdMenuElement.parentElement.style.top = this.locationCss().top;
}
if (this.mdMenuElement.clientHeight + this.mouseLocation.top > this.viewport.getViewportRect().height) {
this.menuTrigger.menu.yPosition = 'above';
this.mdMenuElement.parentElement.style.top = this.mouseLocation.top - this.mdMenuElement.clientHeight + 'px';
} else {
this.menuTrigger.menu.yPosition = 'below';
this.mdMenuElement.parentElement.style.top = this.locationCss().top;
}
}, 0);
}
private getContextMenuElement() {