Skip to content

Commit

Permalink
feat(menu): allow disabling ripples on items (#8388)
Browse files Browse the repository at this point in the history
Closes #8261
  • Loading branch information
devversion authored and jelbourn committed Nov 20, 2017
1 parent 131272a commit ce23395
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 15 deletions.
4 changes: 3 additions & 1 deletion src/lib/menu/menu-item.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<ng-content></ng-content>
<div class="mat-menu-ripple" *ngIf="!disabled" mat-ripple [matRippleTrigger]="_getHostElement()">
<div class="mat-menu-ripple" matRipple
[matRippleDisabled]="disableRipple || disabled"
[matRippleTrigger]="_getHostElement()">
</div>
15 changes: 10 additions & 5 deletions src/lib/menu/menu-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,18 @@ import {
OnDestroy,
ViewEncapsulation,
} from '@angular/core';
import {CanDisable, mixinDisabled} from '@angular/material/core';
import {
CanDisable,
CanDisableRipple,
mixinDisabled,
mixinDisableRipple
} from '@angular/material/core';
import {Subject} from 'rxjs/Subject';

// Boilerplate for applying mixins to MatMenuItem.
/** @docs-private */
export class MatMenuItemBase {}
export const _MatMenuItemMixinBase = mixinDisabled(MatMenuItemBase);
export const _MatMenuItemMixinBase = mixinDisableRipple(mixinDisabled(MatMenuItemBase));

/**
* This directive is intended to be used inside an mat-menu tag.
Expand All @@ -30,7 +35,7 @@ export const _MatMenuItemMixinBase = mixinDisabled(MatMenuItemBase);
moduleId: module.id,
selector: '[mat-menu-item]',
exportAs: 'matMenuItem',
inputs: ['disabled'],
inputs: ['disabled', 'disableRipple'],
host: {
'role': 'menuitem',
'class': 'mat-menu-item',
Expand All @@ -47,8 +52,8 @@ export const _MatMenuItemMixinBase = mixinDisabled(MatMenuItemBase);
preserveWhitespaces: false,
templateUrl: 'menu-item.html',
})
export class MatMenuItem extends _MatMenuItemMixinBase implements FocusableOption, CanDisable,
OnDestroy {
export class MatMenuItem extends _MatMenuItemMixinBase
implements FocusableOption, CanDisable, CanDisableRipple, OnDestroy {

/** Stream that emits when the menu item is hovered. */
_hovered: Subject<MatMenuItem> = new Subject();
Expand Down
6 changes: 6 additions & 0 deletions src/lib/menu/menu.scss
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,10 @@ button.mat-menu-item {

.mat-menu-ripple {
@include mat-fill;

// Prevent any pointer events on the ripple container for a menu item. The ripple container is
// not the trigger element for the ripples and can be therefore disabled like that. Disabling
// the pointer events ensures that there is no `click` event that can bubble up and cause
// the menu panel to close.
pointer-events: none;
}
32 changes: 23 additions & 9 deletions src/lib/menu/menu.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
MatMenuItem,
} from './index';
import {MENU_PANEL_TOP_PADDING} from './menu-trigger';
import {extendObject} from '@angular/material/core';
import {extendObject, MatRipple} from '@angular/material/core';
import {
dispatchKeyboardEvent,
dispatchMouseEvent,
Expand Down Expand Up @@ -490,29 +490,43 @@ describe('MatMenu', () => {
});

describe('animations', () => {
it('should include the ripple on items by default', () => {
it('should enable ripples on items by default', () => {
const fixture = TestBed.createComponent(SimpleMenu);
fixture.detectChanges();

fixture.componentInstance.trigger.openMenu();

const item = fixture.debugElement.query(By.css('.mat-menu-item'));
const ripple = item.query(By.css('.mat-ripple'));
const ripple = item.query(By.css('.mat-ripple')).injector.get<MatRipple>(MatRipple);

expect(ripple).not.toBeNull();
expect(ripple.disabled).toBe(false);
});

it('should remove the ripple on disabled items', () => {
it('should disable ripples on disabled items', () => {
const fixture = TestBed.createComponent(SimpleMenu);
fixture.detectChanges();

fixture.componentInstance.trigger.openMenu();

// The second menu item in the `SimpleMenu` component is disabled.
const items = fixture.debugElement.queryAll(By.css('.mat-menu-item'));
const ripple = items[1].query(By.css('.mat-ripple')).injector.get<MatRipple>(MatRipple);

// items[1] is disabled, so the ripple should not be present
const ripple = items[1].query(By.css('.mat-ripple'));
expect(ripple).toBeNull();
expect(ripple.disabled).toBe(true);
});

it('should disable ripples if disableRipple is set', () => {
const fixture = TestBed.createComponent(SimpleMenu);
fixture.detectChanges();

fixture.componentInstance.trigger.openMenu();

// The third menu item in the `SimpleMenu` component has ripples disabled.
const items = fixture.debugElement.queryAll(By.css('.mat-menu-item'));
const ripple = items[2].query(By.css('.mat-ripple')).injector.get<MatRipple>(MatRipple);

expect(ripple.disabled).toBe(true);
});
});

describe('close event', () => {
Expand Down Expand Up @@ -1115,7 +1129,7 @@ describe('MatMenu default overrides', () => {
<mat-menu class="custom-one custom-two" #menu="matMenu" (closed)="closeCallback($event)">
<button mat-menu-item> Item </button>
<button mat-menu-item disabled> Disabled </button>
<button mat-menu-item>
<button mat-menu-item disableRipple>
<fake-icon>unicorn</fake-icon>
Item with an icon
</button>
Expand Down

0 comments on commit ce23395

Please sign in to comment.