Skip to content

Commit 4ae1b0f

Browse files
devversionmmalerba
authored andcommitted
feat(tab-nav-bar): allow disabling ripples for links (#6273)
* Adds a possibility to disable ripples for a tab-nav-bar with links. Closes #6245
1 parent c20bcf9 commit 4ae1b0f

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
@@ -21,6 +21,9 @@ import {
2121
ViewEncapsulation,
2222
ChangeDetectionStrategy,
2323
ChangeDetectorRef,
24+
ContentChildren,
25+
QueryList,
26+
forwardRef,
2427
} from '@angular/core';
2528
import {MdInkBar} from '../ink-bar';
2629
import {CanDisable, mixinDisabled} from '../../core/common-behaviors/disabled';
@@ -34,13 +37,15 @@ import {takeUntil, auditTime} from '../../core/rxjs/index';
3437
import {of as observableOf} from 'rxjs/observable/of';
3538
import {merge} from 'rxjs/observable/merge';
3639
import {fromEvent} from 'rxjs/observable/fromEvent';
40+
import {CanDisableRipple, mixinDisableRipple} from '../../core/common-behaviors/disable-ripple';
41+
import {coerceBooleanProperty} from '@angular/cdk/coercion';
3742

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

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

@@ -65,6 +72,10 @@ export class MdTabNav extends _MdTabNavMixinBase implements AfterContentInit, Ca
6572

6673
@ViewChild(MdInkBar) _inkBar: MdInkBar;
6774

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

@@ -84,6 +95,14 @@ export class MdTabNav extends _MdTabNavMixinBase implements AfterContentInit, Ca
8495
}
8596
private _backgroundColor: ThemePalette;
8697

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

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

141168

@@ -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
get tabIndex(): number {
178216
return this.disabled ? -1 : 0;

0 commit comments

Comments
 (0)