Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tabs): add theming and ability to set background color #5287

Merged
merged 1 commit into from
Jul 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion src/demo-app/tabs/tabs-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ <h1>Tab Nav Bar</h1>
<button md-button (click)="tabLinks.shift()">Remove tab</button>
<button md-button (click)="swapTabLinks()">Swap first two</button>
<button md-button (click)="addToLabel()">Add to labels</button>
<button md-button (click)="toggleBackground()">Toggle background</button>

<div class="demo-nav-bar">
<nav md-tab-nav-bar aria-label="weather navigation links">
<nav md-tab-nav-bar aria-label="weather navigation links" [backgroundColor]="tabNavBackground">
<a md-tab-link
*ngFor="let tabLink of tabLinks; let i = index"
[routerLink]="tabLink.link"
Expand Down Expand Up @@ -248,3 +249,31 @@ <h1>Inverted tabs</h1>
</div>
</md-tab>
</md-tab-group>

<h1>Accent tabs</h1>
<md-tab-group class="demo-tab-group" color="accent">
<md-tab label="Earth">
<div class="tab-content">
This tab is about the Earth!
</div>
</md-tab>
<md-tab label="Fire">
<div class="tab-content">
This tab is about combustion!
</div>
</md-tab>
</md-tab-group>

<h1>Tabs with background color</h1>
<md-tab-group class="demo-tab-group" backgroundColor="primary" color="accent">
<md-tab label="Earth">
<div class="tab-content">
This tab is about the Earth!
</div>
</md-tab>
<md-tab label="Fire">
<div class="tab-content">
This tab is about combustion!
</div>
</md-tab>
</md-tab-group>
6 changes: 6 additions & 0 deletions src/demo-app/tabs/tabs-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export class TabsDemo {
{label: 'Fog', link: 'foggy-tab'},
];

tabNavBackground: any = undefined;

// Standard tabs demo
tabs = [
{
Expand Down Expand Up @@ -93,6 +95,10 @@ export class TabsDemo {
addToLabel() {
this.tabLinks.forEach(link => link.label += 'extracontent');
}

toggleBackground() {
this.tabNavBackground = this.tabNavBackground ? undefined : 'primary';
}
}


Expand Down
83 changes: 78 additions & 5 deletions src/lib/tabs/_tabs-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,94 @@
}
}

.mat-tab-label:focus {
background-color: mat-color($primary, lighter, 0.3);
.mat-tab-label, .mat-tab-link {
color: mat-color($foreground, text);

&.mat-tab-disabled {
color: mat-color($foreground, disabled-text);
}
}

.mat-tab-header-pagination-chevron {
border-color: mat-color($foreground, text);
}

.mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron {
border-color: mat-color($foreground, disabled-text);
}

// Remove header border when there is a background color
.mat-tab-group[class*='mat-background-'] .mat-tab-header,
.mat-tab-nav-bar[class*='mat-background-'] {
border-bottom: none;
border-top: none;
}

.mat-tab-group, .mat-tab-nav-bar {
$theme-colors: (
primary: $primary,
accent: $accent,
warn: $warn
);

@each $name, $color in $theme-colors {
// Set the foreground color of the tabs
&.mat-#{$name} {
@include _mat-tab-label-focus($color);
@include _mat-ink-bar($color);

// Override ink bar when background color is the same
&.mat-background-#{$name} {
@include _mat-ink-bar($color, default-contrast);
}
}
}

@each $name, $color in $theme-colors {
// Set background color of the tabs and override focus color
&.mat-background-#{$name} {
@include _mat-tab-label-focus($color);
@include _mat-tabs-background($color);
}
}
}
}

@mixin _mat-ink-bar($color, $hue: default) {
.mat-ink-bar {
background-color: mat-color($primary);
background-color: mat-color($color, $hue);
}
}

@mixin _mat-tab-label-focus($tab-focus-color) {
.mat-tab-label:focus, .mat-tab-link:focus {
background-color: mat-color($tab-focus-color, lighter, 0.3);
}
}

@mixin _mat-tabs-background($background-color) {
// Set background color for the tab group
.mat-tab-header, .mat-tab-links {
background-color: mat-color($background-color);
}

// Set labels to contrast against background
.mat-tab-label, .mat-tab-link {
color: mat-color($foreground, text);
color: mat-color($background-color, default-contrast);

&.mat-tab-disabled {
color: mat-color($foreground, disabled-text);
color: mat-color($background-color, default-contrast, 0.4);
}
}

// Set pagination chevrons to contrast background
.mat-tab-header-pagination-chevron {
border-color: mat-color($background-color, default-contrast);
}

.mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron {
border-color: mat-color($background-color, default-contrast, 0.4);
}
}

@mixin mat-tabs-typography($config) {
Expand Down
33 changes: 27 additions & 6 deletions src/lib/tabs/tab-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {MdTab} from './tab';
import {map} from '../core/rxjs/index';
import {merge} from 'rxjs/observable/merge';
import {CanDisableRipple, mixinDisableRipple} from '../core/common-behaviors/disable-ripple';
import {CanColor, mixinColor, ThemePalette} from '../core/common-behaviors/color';


/** Used to generate unique ID's for each tab component */
Expand All @@ -46,8 +47,10 @@ export type MdTabHeaderPosition = 'above' | 'below';

// Boilerplate for applying mixins to MdTabGroup.
/** @docs-private */
export class MdTabGroupBase {}
export const _MdTabGroupMixinBase = mixinDisableRipple(MdTabGroupBase);
export class MdTabGroupBase {
constructor(public _renderer: Renderer2, public _elementRef: ElementRef) {}
}
export const _MdTabGroupMixinBase = mixinColor(mixinDisableRipple(MdTabGroupBase), 'primary');

/**
* Material design tab-group component. Supports basic tab pairs (label + content) and includes
Expand All @@ -60,15 +63,15 @@ export const _MdTabGroupMixinBase = mixinDisableRipple(MdTabGroupBase);
templateUrl: 'tab-group.html',
styleUrls: ['tab-group.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
inputs: ['disableRipple'],
inputs: ['color', 'disableRipple'],
host: {
'class': 'mat-tab-group',
'[class.mat-tab-group-dynamic-height]': 'dynamicHeight',
'[class.mat-tab-group-inverted-header]': 'headerPosition === "below"',
}
})
export class MdTabGroup extends _MdTabGroupMixinBase implements AfterContentInit,
AfterContentChecked, AfterViewChecked, OnDestroy, CanDisableRipple {
AfterContentChecked, AfterViewChecked, OnDestroy, CanColor, CanDisableRipple {

@ContentChildren(MdTab) _tabs: QueryList<MdTab>;

Expand Down Expand Up @@ -109,6 +112,22 @@ export class MdTabGroup extends _MdTabGroupMixinBase implements AfterContentInit
/** Position of the tab header. */
@Input() headerPosition: MdTabHeaderPosition = 'above';

/** Background color of the tab group. */
@Input()
get backgroundColor(): ThemePalette { return this._backgroundColor; }
set backgroundColor(value: ThemePalette) {
let nativeElement = this._elementRef.nativeElement;

this._renderer.removeClass(nativeElement, `mat-background-${this.backgroundColor}`);

if (value) {
this._renderer.addClass(nativeElement, `mat-background-${value}`);
}

this._backgroundColor = value;
}
private _backgroundColor: ThemePalette;

/** Output to enable support for two-way binding on `[(selectedIndex)]` */
@Output() get selectedIndexChange(): Observable<number> {
return map.call(this.selectChange, event => event.index);
Expand All @@ -122,8 +141,10 @@ export class MdTabGroup extends _MdTabGroupMixinBase implements AfterContentInit

private _groupId: number;

constructor(private _renderer: Renderer2, private _changeDetectorRef: ChangeDetectorRef) {
super();
constructor(_renderer: Renderer2,
elementRef: ElementRef,
private _changeDetectorRef: ChangeDetectorRef) {
super(_renderer, elementRef);
this._groupId = nextId++;
}

Expand Down
4 changes: 0 additions & 4 deletions src/lib/tabs/tab-header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,6 @@
.mat-tab-header-pagination-disabled {
box-shadow: none;
cursor: default;

.mat-tab-header-pagination-chevron {
border-color: #ccc;
}
}

.mat-tab-label-container {
Expand Down
39 changes: 34 additions & 5 deletions src/lib/tabs/tab-nav-bar/tab-nav-bar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
NgZone,
OnDestroy,
Optional,
Renderer2,
ViewChild,
ViewEncapsulation,
ChangeDetectionStrategy,
Expand All @@ -27,27 +28,36 @@ import {CanDisable, mixinDisabled} from '../../core/common-behaviors/disabled';
import {MdRipple} from '../../core';
import {ViewportRuler} from '../../core/overlay/position/viewport-ruler';
import {Directionality, MD_RIPPLE_GLOBAL_OPTIONS, Platform, RippleGlobalOptions} from '../../core';
import {CanColor, mixinColor, ThemePalette} from '../../core/common-behaviors/color';
import {Subject} from 'rxjs/Subject';
import {Subscription} from 'rxjs/Subscription';
import {takeUntil, auditTime} from '../../core/rxjs/index';
import {of as observableOf} from 'rxjs/observable/of';
import {merge} from 'rxjs/observable/merge';
import {fromEvent} from 'rxjs/observable/fromEvent';

// Boilerplate for applying mixins to MdTabNav.
/** @docs-private */
export class MdTabNavBase {
constructor(public _renderer: Renderer2, public _elementRef: ElementRef) {}
}
export const _MdTabNavMixinBase = mixinColor(MdTabNavBase, 'primary');

/**
* Navigation component matching the styles of the tab group header.
* Provides anchored navigation with animated ink bar.
*/
@Component({
moduleId: module.id,
selector: '[md-tab-nav-bar], [mat-tab-nav-bar]',
inputs: ['color'],
templateUrl: 'tab-nav-bar.html',
styleUrls: ['tab-nav-bar.css'],
host: {'class': 'mat-tab-nav-bar'},
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MdTabNav implements AfterContentInit, OnDestroy {
export class MdTabNav extends _MdTabNavMixinBase implements AfterContentInit, CanColor, OnDestroy {
/** Subject that emits when the component has been destroyed. */
private _onDestroy = new Subject<void>();

Expand All @@ -59,10 +69,29 @@ export class MdTabNav implements AfterContentInit, OnDestroy {
/** Subscription for window.resize event **/
private _resizeSubscription: Subscription;

constructor(
@Optional() private _dir: Directionality,
private _ngZone: NgZone,
private _changeDetectorRef: ChangeDetectorRef) { }
/** Background color of the tab nav. */
@Input()
get backgroundColor(): ThemePalette { return this._backgroundColor; }
set backgroundColor(value: ThemePalette) {
let nativeElement = this._elementRef.nativeElement;

this._renderer.removeClass(nativeElement, `mat-background-${this.backgroundColor}`);

if (value) {
this._renderer.addClass(nativeElement, `mat-background-${value}`);
}

this._backgroundColor = value;
}
private _backgroundColor: ThemePalette;

constructor(renderer: Renderer2,
elementRef: ElementRef,
@Optional() private _dir: Directionality,
private _ngZone: NgZone,
private _changeDetectorRef: ChangeDetectorRef) {
super(renderer, elementRef);
}

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