Skip to content

Commit 9abc786

Browse files
committed
feat(tabs): add theming and ability to set background color
1 parent 2bf7024 commit 9abc786

File tree

7 files changed

+204
-22
lines changed

7 files changed

+204
-22
lines changed

src/demo-app/tabs/tabs-demo.html

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ <h1>Tab Nav Bar</h1>
33
<button md-button (click)="tabLinks.shift()">Remove tab</button>
44
<button md-button (click)="swapTabLinks()">Swap first two</button>
55
<button md-button (click)="addToLabel()">Add to labels</button>
6+
<button md-button (click)="toggleBackground()">Toggle background</button>
67

78
<div class="demo-nav-bar">
8-
<nav md-tab-nav-bar aria-label="weather navigation links">
9+
<nav md-tab-nav-bar aria-label="weather navigation links" [background]="tabNavBackground">
910
<a md-tab-link
1011
*ngFor="let tabLink of tabLinks; let i = index"
1112
[routerLink]="tabLink.link"
@@ -247,3 +248,31 @@ <h1>Inverted tabs</h1>
247248
</div>
248249
</md-tab>
249250
</md-tab-group>
251+
252+
<h1>Accent tabs</h1>
253+
<md-tab-group class="demo-tab-group" color="accent">
254+
<md-tab label="Earth">
255+
<div class="tab-content">
256+
This tab is about the Earth!
257+
</div>
258+
</md-tab>
259+
<md-tab label="Fire">
260+
<div class="tab-content">
261+
This tab is about combustion!
262+
</div>
263+
</md-tab>
264+
</md-tab-group>
265+
266+
<h1>Tabs with background color</h1>
267+
<md-tab-group class="demo-tab-group" background="primary" color="accent">
268+
<md-tab label="Earth">
269+
<div class="tab-content">
270+
This tab is about the Earth!
271+
</div>
272+
</md-tab>
273+
<md-tab label="Fire">
274+
<div class="tab-content">
275+
This tab is about combustion!
276+
</div>
277+
</md-tab>
278+
</md-tab-group>

src/demo-app/tabs/tabs-demo.scss

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
.demo-nav-bar {
22
border: 1px solid #e0e0e0;
33
margin-bottom: 40px;
4-
.mat-tab-nav-bar {
5-
background: #f9f9f9;
6-
}
74
sunny-routed-content,
85
rainy-routed-content,
96
foggy-routed-content {
@@ -16,9 +13,6 @@
1613
border: 1px solid #e0e0e0;
1714
margin-bottom: 40px;
1815
flex-grow: 1;
19-
.mat-tab-header {
20-
background: #f9f9f9;
21-
}
2216
}
2317

2418
tabs-demo .mat-card {

src/demo-app/tabs/tabs-demo.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ export class TabsDemo {
1616
{label: 'Fog', link: 'foggy-tab'},
1717
];
1818

19+
tabNavBackground: any = undefined;
20+
1921
// Standard tabs demo
2022
tabs = [
2123
{
@@ -93,6 +95,10 @@ export class TabsDemo {
9395
addToLabel() {
9496
this.tabLinks.forEach(link => link.label += 'extracontent');
9597
}
98+
99+
toggleBackground() {
100+
this.tabNavBackground = this.tabNavBackground ? undefined : 'primary';
101+
}
96102
}
97103

98104

src/lib/tabs/_tabs-theme.scss

Lines changed: 108 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,120 @@
2323
}
2424
}
2525

26-
.mat-tab-label:focus {
27-
background-color: mat-color($primary, lighter, 0.3);
26+
.mat-tab-label, .mat-tab-link {
27+
color: mat-color($foreground, text);
28+
29+
&.mat-tab-disabled {
30+
color: mat-color($foreground, disabled-text);
31+
}
2832
}
2933

34+
.mat-tab-header-pagination-chevron {
35+
border-color: mat-color($foreground, text);
36+
}
37+
38+
.mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron {
39+
border-color: mat-color($foreground, disabled-text);
40+
}
41+
42+
.mat-tab-group, .mat-tab-nav-bar {
43+
&.mat-primary {
44+
@include _mat-tabs-color($primary);
45+
46+
&.mat-background-primary {
47+
@include _mat-tabs-color($primary, $primary);
48+
}
49+
50+
&.mat-background-accent {
51+
@include _mat-tabs-color($primary, $accent);
52+
}
53+
54+
&.mat-background-warn {
55+
@include _mat-tabs-color($primary, $warn);
56+
}
57+
}
58+
59+
&.mat-accent {
60+
@include _mat-tabs-color($accent);
61+
62+
&.mat-background-primary {
63+
@include _mat-tabs-color($accent, $primary);
64+
}
65+
66+
&.mat-background-accent {
67+
@include _mat-tabs-color($accent, $accent);
68+
}
69+
70+
&.mat-background-warn {
71+
@include _mat-tabs-color($accent, $warn);
72+
}
73+
}
74+
75+
&.mat-warn {
76+
@include _mat-tabs-color($warn);
77+
78+
&.mat-background-primary {
79+
@include _mat-tabs-color($warn, $primary);
80+
}
81+
82+
&.mat-background-accent {
83+
@include _mat-tabs-color($warn, $accent);
84+
}
85+
86+
&.mat-background-warn {
87+
@include _mat-tabs-color($warn, $warn);
88+
}
89+
}
90+
}
91+
}
92+
93+
@mixin _mat-tabs-color($color, $background-color: null) {
94+
95+
$tab-focus-color: if($background-color, $background-color, $color);
96+
97+
// Focus the tab label
98+
.mat-tab-label:focus, .mat-tab-link:focus {
99+
background-color: mat-color($tab-focus-color, lighter, 0.3);
100+
}
101+
102+
// Set the ink bar to the theme color or default-contrast if
103+
// the theme color and background color are the same
30104
.mat-ink-bar {
31-
background-color: mat-color($primary);
105+
background-color: mat-color($color);
106+
107+
@if $background-color == $color {
108+
background-color: mat-color($background-color, default-contrast);
109+
}
32110
}
33111

34-
.mat-tab-label, .mat-tab-link {
35-
color: mat-color($foreground, text);
112+
@if $background-color {
113+
// Set background color for the tab group
114+
.mat-tab-header, .mat-tab-links {
115+
background-color: mat-color($background-color);
116+
}
36117

37-
&.mat-tab-disabled {
38-
color: mat-color($foreground, disabled-text);
118+
// Set labels to contrast against background
119+
.mat-tab-label, .mat-tab-link {
120+
color: mat-color($background-color, default-contrast);
121+
122+
&.mat-tab-disabled {
123+
color: mat-color($background-color, default-contrast, 0.4);
124+
}
125+
}
126+
127+
// Set pagination chevrons to contrast background
128+
.mat-tab-header-pagination-chevron {
129+
border-color: mat-color($background-color, default-contrast);
130+
}
131+
132+
.mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron {
133+
border-color: mat-color($background-color, default-contrast, 0.4);
134+
}
135+
136+
// Remove header border
137+
.mat-tab-header {
138+
border-bottom: none;
139+
border-top: none;
39140
}
40141
}
41142
}

src/lib/tabs/tab-group.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
Renderer2,
1919
} from '@angular/core';
2020
import {coerceBooleanProperty} from '../core';
21+
import {CanColor, mixinColor, ThemePalette} from '../core/common-behaviors/color';
2122
import {Observable} from 'rxjs/Observable';
2223
import {MdTab} from './tab';
2324
import 'rxjs/add/operator/map';
@@ -35,6 +36,12 @@ export class MdTabChangeEvent {
3536
/** Possible positions for the tab header. */
3637
export type MdTabHeaderPosition = 'above' | 'below';
3738

39+
// Boilerplate for applying mixins to MdTabGroup.
40+
export class MdTabGroupBase {
41+
constructor(public _renderer: Renderer2, public _elementRef: ElementRef) {}
42+
}
43+
export const _MdTabGroupMixinBase = mixinColor(MdTabGroupBase, 'primary');
44+
3845
/**
3946
* Material design tab-group component. Supports basic tab pairs (label + content) and includes
4047
* animated ink-bar, keyboard navigation, and screen reader.
@@ -43,6 +50,7 @@ export type MdTabHeaderPosition = 'above' | 'below';
4350
@Component({
4451
moduleId: module.id,
4552
selector: 'md-tab-group, mat-tab-group',
53+
inputs: ['color'],
4654
templateUrl: 'tab-group.html',
4755
styleUrls: ['tab-group.css'],
4856
host: {
@@ -51,7 +59,7 @@ export type MdTabHeaderPosition = 'above' | 'below';
5159
'[class.mat-tab-group-inverted-header]': 'headerPosition === "below"',
5260
}
5361
})
54-
export class MdTabGroup {
62+
export class MdTabGroup extends _MdTabGroupMixinBase implements CanColor {
5563
@ContentChildren(MdTab) _tabs: QueryList<MdTab>;
5664

5765
@ViewChild('tabBodyWrapper') _tabBodyWrapper: ElementRef;
@@ -94,6 +102,22 @@ export class MdTabGroup {
94102
@Input()
95103
headerPosition: MdTabHeaderPosition = 'above';
96104

105+
/** Background color of the tab group. */
106+
@Input()
107+
get background(): ThemePalette { return this._background; }
108+
set background(value: ThemePalette) {
109+
let nativeElement = this._elementRef.nativeElement;
110+
111+
this._renderer.removeClass(nativeElement, `mat-background-${this.background}`);
112+
113+
if (value) {
114+
this._renderer.addClass(nativeElement, `mat-background-${value}`);
115+
}
116+
117+
this._background = value;
118+
}
119+
private _background: ThemePalette;
120+
97121
/** Output to enable support for two-way binding on `[(selectedIndex)]` */
98122
@Output() get selectedIndexChange(): Observable<number> {
99123
return this.selectChange.map(event => event.index);
@@ -107,7 +131,9 @@ export class MdTabGroup {
107131

108132
private _groupId: number;
109133

110-
constructor(private _renderer: Renderer2) {
134+
constructor(_renderer: Renderer2,
135+
elementRef: ElementRef) {
136+
super(_renderer, elementRef);
111137
this._groupId = nextId++;
112138
}
113139

src/lib/tabs/tab-header.scss

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,6 @@
6565
.mat-tab-header-pagination-disabled {
6666
box-shadow: none;
6767
cursor: default;
68-
69-
.mat-tab-header-pagination-chevron {
70-
border-color: #ccc;
71-
}
7268
}
7369

7470
.mat-tab-label-container {

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

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,33 +16,42 @@ import {
1616
NgZone,
1717
OnDestroy,
1818
Optional,
19+
Renderer2,
1920
ViewChild,
2021
ViewEncapsulation
2122
} from '@angular/core';
2223
import {MdInkBar} from '../ink-bar';
2324
import {MdRipple} from '../../core/ripple/index';
2425
import {ViewportRuler} from '../../core/overlay/position/viewport-ruler';
2526
import {Directionality, MD_RIPPLE_GLOBAL_OPTIONS, Platform, RippleGlobalOptions} from '../../core';
27+
import {CanColor, mixinColor, ThemePalette} from '../../core/common-behaviors/color';
2628
import {Observable} from 'rxjs/Observable';
2729
import 'rxjs/add/operator/auditTime';
2830
import 'rxjs/add/operator/takeUntil';
2931
import 'rxjs/add/observable/of';
3032
import 'rxjs/add/observable/merge';
3133
import {Subject} from 'rxjs/Subject';
3234

35+
// Boilerplate for applying mixins to MdTabNav.
36+
export class MdTabNavBase {
37+
constructor(public _renderer: Renderer2, public _elementRef: ElementRef) {}
38+
}
39+
export const _MdTabNavMixinBase = mixinColor(MdTabNavBase, 'primary');
40+
3341
/**
3442
* Navigation component matching the styles of the tab group header.
3543
* Provides anchored navigation with animated ink bar.
3644
*/
3745
@Component({
3846
moduleId: module.id,
3947
selector: '[md-tab-nav-bar], [mat-tab-nav-bar]',
48+
inputs: ['color'],
4049
templateUrl: 'tab-nav-bar.html',
4150
styleUrls: ['tab-nav-bar.css'],
4251
host: {'class': 'mat-tab-nav-bar'},
4352
encapsulation: ViewEncapsulation.None,
4453
})
45-
export class MdTabNav implements AfterContentInit, OnDestroy {
54+
export class MdTabNav extends _MdTabNavMixinBase implements AfterContentInit, CanColor, OnDestroy {
4655
/** Subject that emits when the component has been destroyed. */
4756
private _onDestroy = new Subject<void>();
4857

@@ -51,7 +60,28 @@ export class MdTabNav implements AfterContentInit, OnDestroy {
5160

5261
@ViewChild(MdInkBar) _inkBar: MdInkBar;
5362

54-
constructor(@Optional() private _dir: Directionality, private _ngZone: NgZone) { }
63+
/** Background color of the tab nav. */
64+
@Input()
65+
get background(): ThemePalette { return this._background; }
66+
set background(value: ThemePalette) {
67+
let nativeElement = this._elementRef.nativeElement;
68+
69+
this._renderer.removeClass(nativeElement, `mat-background-${this.background}`);
70+
71+
if (value) {
72+
this._renderer.addClass(nativeElement, `mat-background-${value}`);
73+
}
74+
75+
this._background = value;
76+
}
77+
private _background: ThemePalette;
78+
79+
constructor(renderer: Renderer2,
80+
elementRef: ElementRef,
81+
private _ngZone: NgZone,
82+
@Optional() private _dir: Directionality) {
83+
super(renderer, elementRef);
84+
}
5585

5686
/** Notifies the component that the active link has been changed. */
5787
updateActiveLink(element: ElementRef) {

0 commit comments

Comments
 (0)