diff --git a/src/lib/core/option/option.html b/src/lib/core/option/option.html index fb398f4b3529..205fae26873a 100644 --- a/src/lib/core/option/option.html +++ b/src/lib/core/option/option.html @@ -6,5 +6,7 @@ -
+
diff --git a/src/lib/core/option/option.spec.ts b/src/lib/core/option/option.spec.ts new file mode 100644 index 000000000000..f59519710433 --- /dev/null +++ b/src/lib/core/option/option.spec.ts @@ -0,0 +1,81 @@ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; +import {Component, DebugElement} from '@angular/core'; +import {By} from '@angular/platform-browser'; +import {dispatchFakeEvent} from '@angular/cdk/testing'; +import {MdOption, MdOptionModule} from './index'; + +describe('MdOption component', () => { + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [MdOptionModule], + declarations: [OptionWithDisableRipple] + }).compileComponents(); + })); + + describe('ripples', () => { + let fixture: ComponentFixture; + let optionDebugElement: DebugElement; + let optionNativeElement: HTMLElement; + let optionInstance: MdOption; + + beforeEach(() => { + fixture = TestBed.createComponent(OptionWithDisableRipple); + fixture.detectChanges(); + + optionDebugElement = fixture.debugElement.query(By.directive(MdOption)); + optionNativeElement = optionDebugElement.nativeElement; + optionInstance = optionDebugElement.componentInstance; + }); + + it('should show ripples by default', () => { + expect(optionInstance.disableRipple).toBe(false, 'Expected ripples to be enabled by default'); + expect(optionNativeElement.querySelectorAll('.mat-ripple-element').length) + .toBe(0, 'Expected no ripples to show up initially'); + + dispatchFakeEvent(optionNativeElement, 'mousedown'); + dispatchFakeEvent(optionNativeElement, 'mouseup'); + + expect(optionNativeElement.querySelectorAll('.mat-ripple-element').length) + .toBe(1, 'Expected one ripple to show up after a fake click.'); + }); + + it('should not show ripples if the option is disabled', () => { + expect(optionNativeElement.querySelectorAll('.mat-ripple-element').length) + .toBe(0, 'Expected no ripples to show up initially'); + + fixture.componentInstance.disabled = true; + fixture.detectChanges(); + + dispatchFakeEvent(optionNativeElement, 'mousedown'); + dispatchFakeEvent(optionNativeElement, 'mouseup'); + + expect(optionNativeElement.querySelectorAll('.mat-ripple-element').length) + .toBe(0, 'Expected no ripples to show up after click on a disabled option.'); + }); + + it('should not show ripples if the ripples are disabled using disableRipple', () => { + expect(optionNativeElement.querySelectorAll('.mat-ripple-element').length) + .toBe(0, 'Expected no ripples to show up initially'); + + fixture.componentInstance.disableRipple = true; + fixture.detectChanges(); + + dispatchFakeEvent(optionNativeElement, 'mousedown'); + dispatchFakeEvent(optionNativeElement, 'mouseup'); + + expect(optionNativeElement.querySelectorAll('.mat-ripple-element').length) + .toBe(0, 'Expected no ripples to show up after click when ripples are disabled.'); + }); + + }); + +}); + +@Component({ + template: `` +}) +export class OptionWithDisableRipple { + disableRipple: boolean; + disabled: boolean; +} diff --git a/src/lib/core/option/option.ts b/src/lib/core/option/option.ts index 43c1168b88dc..b801e4e27420 100644 --- a/src/lib/core/option/option.ts +++ b/src/lib/core/option/option.ts @@ -22,6 +22,7 @@ import {ENTER, SPACE} from '../keyboard/keycodes'; import {coerceBooleanProperty} from '@angular/cdk'; import {MATERIAL_COMPATIBILITY_MODE} from '../../core/compatibility/compatibility'; import {MdOptgroup} from './optgroup'; +import {CanDisableRipple, mixinDisableRipple} from '../common-behaviors/disable-ripple'; /** * Option IDs need to be unique across components, so this counter exists outside of @@ -34,6 +35,11 @@ export class MdOptionSelectionChange { constructor(public source: MdOption, public isUserInput = false) { } } +// Boilerplate for applying mixins to MdOption. +/** @docs-private */ +export class MdOptionBase {} +export const _MdOptionMixinBase = mixinDisableRipple(MdOptionBase); + /** * Single option inside of a `` element. @@ -41,6 +47,7 @@ export class MdOptionSelectionChange { @Component({ moduleId: module.id, selector: 'md-option, mat-option', + inputs: ['disableRipple'], host: { 'role': 'option', '[attr.tabindex]': '_getTabIndex()', @@ -59,7 +66,7 @@ export class MdOptionSelectionChange { encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, }) -export class MdOption { +export class MdOption extends _MdOptionMixinBase implements CanDisableRipple { private _selected: boolean = false; private _active: boolean = false; private _multiple: boolean = false; @@ -99,7 +106,10 @@ export class MdOption { private _element: ElementRef, private _changeDetectorRef: ChangeDetectorRef, @Optional() public readonly group: MdOptgroup, - @Optional() @Inject(MATERIAL_COMPATIBILITY_MODE) public _isCompatibilityMode: boolean) {} + @Optional() @Inject(MATERIAL_COMPATIBILITY_MODE) public _isCompatibilityMode: boolean + ) { + super(); + } /** * Whether or not the option is currently active and ready to be selected.