Skip to content

Commit 7387bd8

Browse files
committed
feat(tab-nav-bar): allow disabling ripples for links
* Adds a possibility to disable ripples for a tab-nav-bar with links. Closes #6245
1 parent 0850981 commit 7387bd8

File tree

3 files changed

+73
-6
lines changed

3 files changed

+73
-6
lines changed

src/lib/core/ripple/ripple.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ export class MdRipple implements OnChanges, OnDestroy {
135135
}
136136

137137
/** Updates the ripple renderer with the latest ripple configuration. */
138-
private _updateRippleRenderer() {
138+
_updateRippleRenderer() {
139139
this._rippleRenderer.rippleDisabled = this._globalOptions.disabled || this.disabled;
140140
this._rippleRenderer.rippleConfig = this.rippleConfig;
141141
}

src/lib/tabs/tab-nav-bar/tab-nav-bar.spec.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {async, ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing';
22
import {MdTabsModule} from '../index';
3-
import {MdTabNav} from './tab-nav-bar';
3+
import {MdTabNav, MdTabLink} from './tab-nav-bar';
44
import {Component, ViewChild} from '@angular/core';
55
import {By} from '@angular/platform-browser';
66
import {ViewportRuler} from '../../core/overlay/position/viewport-ruler';
@@ -81,6 +81,20 @@ describe('MdTabNavBar', () => {
8181
.toBe(true, 'Expected aria-disabled to be set to "true" if link is disabled.');
8282
});
8383

84+
it('should update the disableRipple property on each tab link', () => {
85+
const tabLinkElements = fixture.debugElement.queryAll(By.directive(MdTabLink))
86+
.map(tabLinkDebug => tabLinkDebug.componentInstance) as MdTabLink[];
87+
88+
expect(tabLinkElements.every(tabLink => !tabLink.disableRipple))
89+
.toBe(true, 'Expected every tab link to have ripples enabled');
90+
91+
fixture.componentInstance.disableRipple = true;
92+
fixture.detectChanges();
93+
94+
expect(tabLinkElements.every(tabLink => tabLink.disableRipple))
95+
.toBe(true, 'Expected every tab link to have ripples disabled');
96+
});
97+
8498
it('should update the tabindex if links are disabled', () => {
8599
const tabLinkElements = fixture.debugElement.queryAll(By.css('a'))
86100
.map(tabLinkDebugEl => tabLinkDebugEl.nativeElement);
@@ -105,6 +119,20 @@ describe('MdTabNavBar', () => {
105119
.toBe(1, 'Expected one ripple to show up if user clicks on tab link.');
106120
});
107121

122+
it('should be able to disable ripples on a tab link', () => {
123+
const tabLinkDebug = fixture.debugElement.query(By.css('a'));
124+
const tabLinkElement = tabLinkDebug.nativeElement;
125+
const tabLinkInstance = tabLinkDebug.injector.get(MdTabLink);
126+
127+
tabLinkInstance.disableRipple = true;
128+
129+
dispatchMouseEvent(tabLinkElement, 'mousedown');
130+
dispatchMouseEvent(tabLinkElement, 'mouseup');
131+
132+
expect(tabLinkElement.querySelectorAll('.mat-ripple-element').length)
133+
.toBe(0, 'Expected no ripple to show up if ripples are disabled.');
134+
});
135+
108136
it('should re-align the ink bar when the direction changes', () => {
109137
const inkBar = fixture.componentInstance.tabNavBar._inkBar;
110138

@@ -173,7 +201,7 @@ describe('MdTabNavBar', () => {
173201
@Component({
174202
selector: 'test-app',
175203
template: `
176-
<nav md-tab-nav-bar>
204+
<nav md-tab-nav-bar [disableRipple]="disableRipple">
177205
<a md-tab-link
178206
*ngFor="let tab of tabs; let index = index"
179207
[active]="activeIndex === index"
@@ -189,6 +217,7 @@ class SimpleTabNavBarTestApp {
189217

190218
label = '';
191219
disabled: boolean = false;
220+
disableRipple: boolean = false;
192221
tabs = [0, 1, 2];
193222

194223
activeIndex = 0;

src/lib/tabs/tab-nav-bar/tab-nav-bar.ts

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ import {
2222
ViewEncapsulation,
2323
ChangeDetectionStrategy,
2424
ChangeDetectorRef,
25+
ContentChildren,
26+
QueryList,
27+
forwardRef,
2528
} from '@angular/core';
2629
import {MdInkBar} from '../ink-bar';
2730
import {CanDisable, mixinDisabled} from '../../core/common-behaviors/disabled';
@@ -35,13 +38,15 @@ import {takeUntil, auditTime} from '../../core/rxjs/index';
3538
import {of as observableOf} from 'rxjs/observable/of';
3639
import {merge} from 'rxjs/observable/merge';
3740
import {fromEvent} from 'rxjs/observable/fromEvent';
41+
import {CanDisableRipple, mixinDisableRipple} from '../../core/common-behaviors/disable-ripple';
42+
import {coerceBooleanProperty} from '@angular/cdk/coercion';
3843

3944
// Boilerplate for applying mixins to MdTabNav.
4045
/** @docs-private */
4146
export class MdTabNavBase {
4247
constructor(public _renderer: Renderer2, public _elementRef: ElementRef) {}
4348
}
44-
export const _MdTabNavMixinBase = mixinColor(MdTabNavBase, 'primary');
49+
export const _MdTabNavMixinBase = mixinDisableRipple(mixinColor(MdTabNavBase, 'primary'));
4550

4651
/**
4752
* Navigation component matching the styles of the tab group header.
@@ -50,14 +55,16 @@ export const _MdTabNavMixinBase = mixinColor(MdTabNavBase, 'primary');
5055
@Component({
5156
moduleId: module.id,
5257
selector: '[md-tab-nav-bar], [mat-tab-nav-bar]',
53-
inputs: ['color'],
58+
inputs: ['color', 'disableRipple'],
5459
templateUrl: 'tab-nav-bar.html',
5560
styleUrls: ['tab-nav-bar.css'],
5661
host: {'class': 'mat-tab-nav-bar'},
5762
encapsulation: ViewEncapsulation.None,
5863
changeDetection: ChangeDetectionStrategy.OnPush,
5964
})
60-
export class MdTabNav extends _MdTabNavMixinBase implements AfterContentInit, CanColor, OnDestroy {
65+
export class MdTabNav extends _MdTabNavMixinBase implements AfterContentInit, CanColor,
66+
CanDisableRipple, OnDestroy {
67+
6168
/** Subject that emits when the component has been destroyed. */
6269
private _onDestroy = new Subject<void>();
6370

@@ -66,6 +73,10 @@ export class MdTabNav extends _MdTabNavMixinBase implements AfterContentInit, Ca
6673

6774
@ViewChild(MdInkBar) _inkBar: MdInkBar;
6875

76+
/** Query list of all tab links of the tab navigation. */
77+
@ContentChildren(forwardRef(() => MdTabLink), {descendants: true})
78+
_tabLinks: QueryList<MdTabLink>;
79+
6980
/** Subscription for window.resize event **/
7081
private _resizeSubscription: Subscription;
7182

@@ -85,6 +96,14 @@ export class MdTabNav extends _MdTabNavMixinBase implements AfterContentInit, Ca
8596
}
8697
private _backgroundColor: ThemePalette;
8798

99+
/** Whether ripples should be disabled for all links or not. */
100+
get disableRipple() { return this._disableRipple; }
101+
set disableRipple(value: boolean) {
102+
this._disableRipple = coerceBooleanProperty(value);
103+
this._setLinkDisableRipple();
104+
}
105+
private _disableRipple: boolean = false;
106+
88107
constructor(renderer: Renderer2,
89108
elementRef: ElementRef,
90109
@Optional() private _dir: Directionality,
@@ -113,6 +132,7 @@ export class MdTabNav extends _MdTabNavMixinBase implements AfterContentInit, Ca
113132
return takeUntil.call(merge(dirChange, resize), this._onDestroy)
114133
.subscribe(() => this._alignInkBar());
115134
});
135+
this._setLinkDisableRipple();
116136
}
117137

118138
/** Checks if the active link has been changed and, if so, will update the ink bar. */
@@ -137,6 +157,13 @@ export class MdTabNav extends _MdTabNavMixinBase implements AfterContentInit, Ca
137157
this._inkBar.alignToElement(this._activeLinkElement.nativeElement);
138158
}
139159
}
160+
161+
/** Sets the `disableRipple` property on each link of the navigation bar. */
162+
private _setLinkDisableRipple() {
163+
if (this._tabLinks) {
164+
this._tabLinks.forEach(link => link.disableRipple = this.disableRipple);
165+
}
166+
}
140167
}
141168

142169

@@ -160,6 +187,9 @@ export class MdTabLink extends _MdTabLinkMixinBase implements OnDestroy, CanDisa
160187
/** Whether the tab link is active or not. */
161188
private _isActive: boolean = false;
162189

190+
/** Whether the ripples for this tab should be disabled or not. */
191+
private _disableRipple: boolean = false;
192+
163193
/** Reference to the instance of the ripple for the tab link. */
164194
private _tabLinkRipple: MdRipple;
165195

@@ -173,6 +203,14 @@ export class MdTabLink extends _MdTabLinkMixinBase implements OnDestroy, CanDisa
173203
}
174204
}
175205

206+
/** Whether ripples should be disabled or not. */
207+
get disableRipple(): boolean { return this._disableRipple; }
208+
set disableRipple(value: boolean) {
209+
this._disableRipple = value;
210+
this._tabLinkRipple.disabled = this.disableRipple;
211+
this._tabLinkRipple._updateRippleRenderer();
212+
}
213+
176214
/** @docs-private */
177215
@HostBinding('tabIndex')
178216
get tabIndex(): number {

0 commit comments

Comments
 (0)