@@ -11,6 +11,7 @@ import {
1111 Component ,
1212 Directive ,
1313 ElementRef ,
14+ HostBinding ,
1415 Inject ,
1516 Input ,
1617 NgZone ,
@@ -20,15 +21,16 @@ import {
2021 ViewEncapsulation
2122} from '@angular/core' ;
2223import { MdInkBar } from '../ink-bar' ;
23- import { MdRipple } from '../../core/ripple/index' ;
24+ import { CanDisable , mixinDisabled } from '../../core/common-behaviors/disabled' ;
25+ import { MdRipple } from '../../core' ;
2426import { ViewportRuler } from '../../core/overlay/position/viewport-ruler' ;
2527import { Directionality , MD_RIPPLE_GLOBAL_OPTIONS , Platform , RippleGlobalOptions } from '../../core' ;
2628import { Observable } from 'rxjs/Observable' ;
29+ import { Subject } from 'rxjs/Subject' ;
2730import 'rxjs/add/operator/auditTime' ;
2831import 'rxjs/add/operator/takeUntil' ;
2932import 'rxjs/add/observable/of' ;
3033import 'rxjs/add/observable/merge' ;
31- import { Subject } from 'rxjs/Subject' ;
3234
3335/**
3436 * Navigation component matching the styles of the tab group header.
@@ -92,16 +94,30 @@ export class MdTabNav implements AfterContentInit, OnDestroy {
9294 }
9395}
9496
97+
98+ // Boilerplate for applying mixins to MdTabLink.
99+ export class MdTabLinkBase { }
100+ export const _MdTabLinkMixinBase = mixinDisabled ( MdTabLinkBase ) ;
101+
95102/**
96103 * Link inside of a `md-tab-nav-bar`.
97104 */
98105@Directive ( {
99106 selector : '[md-tab-link], [mat-tab-link], [mdTabLink], [matTabLink]' ,
100- host : { 'class' : 'mat-tab-link' }
107+ inputs : [ 'disabled' ] ,
108+ host : {
109+ 'class' : 'mat-tab-link' ,
110+ '[attr.aria-disabled]' : 'disabled.toString()' ,
111+ '[class.mat-tab-disabled]' : 'disabled'
112+ }
101113} )
102- export class MdTabLink {
114+ export class MdTabLink extends _MdTabLinkMixinBase implements OnDestroy , CanDisable {
115+ /** Whether the tab link is active or not. */
103116 private _isActive : boolean = false ;
104117
118+ /** Reference to the instance of the ripple for the tab link. */
119+ private _tabLinkRipple : MdRipple ;
120+
105121 /** Whether the link is active. */
106122 @Input ( )
107123 get active ( ) : boolean { return this . _isActive ; }
@@ -112,23 +128,28 @@ export class MdTabLink {
112128 }
113129 }
114130
115- constructor ( private _mdTabNavBar : MdTabNav , private _elementRef : ElementRef ) { }
116- }
131+ /** @docs -private */
132+ @HostBinding ( 'tabIndex' )
133+ get tabIndex ( ) : number {
134+ return this . disabled ? - 1 : 0 ;
135+ }
117136
118- /**
119- * Simple directive that extends the ripple and matches the selector of the MdTabLink. This
120- * adds the ripple behavior to nav bar labels.
121- */
122- @Directive ( {
123- selector : '[md-tab-link], [mat-tab-link], [mdTabLink], [matTabLink]' ,
124- } )
125- export class MdTabLinkRipple extends MdRipple {
126- constructor (
127- elementRef : ElementRef ,
128- ngZone : NgZone ,
129- ruler : ViewportRuler ,
130- platform : Platform ,
131- @Optional ( ) @Inject ( MD_RIPPLE_GLOBAL_OPTIONS ) globalOptions : RippleGlobalOptions ) {
132- super ( elementRef , ngZone , ruler , platform , globalOptions ) ;
137+ constructor ( private _mdTabNavBar : MdTabNav ,
138+ private _elementRef : ElementRef ,
139+ ngZone : NgZone ,
140+ ruler : ViewportRuler ,
141+ platform : Platform ,
142+ @Optional ( ) @Inject ( MD_RIPPLE_GLOBAL_OPTIONS ) globalOptions : RippleGlobalOptions ) {
143+ super ( ) ;
144+
145+ // Manually create a ripple instance that uses the tab link element as trigger element.
146+ // Notice that the lifecycle hooks for the ripple config won't be called anymore.
147+ this . _tabLinkRipple = new MdRipple ( _elementRef , ngZone , ruler , platform , globalOptions ) ;
148+ }
149+
150+ ngOnDestroy ( ) {
151+ // Manually call the ngOnDestroy lifecycle hook of the ripple instance because it won't be
152+ // called automatically since its instance is not created by Angular.
153+ this . _tabLinkRipple . ngOnDestroy ( ) ;
133154 }
134155}
0 commit comments