diff --git a/src/components/tabs/tab-group.scss b/src/components/tabs/tab-group.scss index ae6b6ef8c5c2..01052b5e30fd 100644 --- a/src/components/tabs/tab-group.scss +++ b/src/components/tabs/tab-group.scss @@ -1,7 +1,6 @@ @import 'variables'; @import 'default-theme'; - -$md-tab-bar-height: 48px !default; +@import './tabs-common'; :host { display: flex; @@ -11,33 +10,13 @@ $md-tab-bar-height: 48px !default; /** The top section of the view; contains the tab labels */ .md-tab-header { - overflow: hidden; - position: relative; - display: flex; - flex-direction: row; + @include tab-header; border-bottom: 1px solid md-color($md-background, status-bar); - flex-shrink: 0; } /** Wraps each tab label */ .md-tab-label { - line-height: $md-tab-bar-height; - height: $md-tab-bar-height; - padding: 0 12px; - font-size: $md-body-font-size-base; - font-family: $md-font-family; - font-weight: 500; - cursor: pointer; - box-sizing: border-box; - color: currentColor; - opacity: 0.6; - min-width: 160px; - text-align: center; - &:focus { - outline: none; - opacity: 1; - background-color: md-color($md-primary, 100, 0.3); - } + @include tab-label; } .md-tab-disabled { @@ -60,16 +39,7 @@ $md-tab-bar-height: 48px !default; box-sizing: border-box; flex-grow: 1; flex-shrink: 1; - &.md-active { + &.md-tab-active { display: block; } } - -/** The colored bar that underlines the active tab */ -md-ink-bar { - position: absolute; - bottom: 0; - height: 2px; - background-color: md-color($md-primary, 500); - transition: 350ms ease-out; -} diff --git a/src/components/tabs/tab-nav-bar/tab-link.scss b/src/components/tabs/tab-nav-bar/tab-link.scss new file mode 100644 index 000000000000..4fbb064c9e32 --- /dev/null +++ b/src/components/tabs/tab-nav-bar/tab-link.scss @@ -0,0 +1,5 @@ +@import '../tabs-common'; + +:host { + @include tab-label; +} diff --git a/src/components/tabs/tab-nav-bar/tab-nav-bar.html b/src/components/tabs/tab-nav-bar/tab-nav-bar.html new file mode 100644 index 000000000000..297bea2fdfaf --- /dev/null +++ b/src/components/tabs/tab-nav-bar/tab-nav-bar.html @@ -0,0 +1,4 @@ +
+ + +
diff --git a/src/components/tabs/tab-nav-bar/tab-nav-bar.scss b/src/components/tabs/tab-nav-bar/tab-nav-bar.scss new file mode 100644 index 000000000000..912c51b3c402 --- /dev/null +++ b/src/components/tabs/tab-nav-bar/tab-nav-bar.scss @@ -0,0 +1,13 @@ +@import '../tabs-common'; + +:host { + display: block; +} + +.md-tab-header { + @include tab-header; +} + +md-ink-bar { + +} diff --git a/src/components/tabs/tab-nav-bar/tab-nav-bar.ts b/src/components/tabs/tab-nav-bar/tab-nav-bar.ts new file mode 100644 index 000000000000..cff20affc038 --- /dev/null +++ b/src/components/tabs/tab-nav-bar/tab-nav-bar.ts @@ -0,0 +1,43 @@ +import {Component, Input, ContentChildren, QueryList, ViewChild, ElementRef, + forwardRef} from '@angular/core'; +import {MdInkBar} from '../ink-bar'; + +@Component({ + moduleId: module.id, + selector: 'md-tab-nav-bar', + templateUrl: 'tab-nav-bar.html', + styleUrls: ['tab-nav-bar.css'], +}) +export class MdTabBar { + @ContentChildren(forwardRef(() => MdTabLink)) private _links: QueryList; + @ViewChild(MdInkBar) private _inkBar: MdInkBar; + + updateActiveLink(element: HTMLElement) { + this._inkBar.alignToElement(element); + } +} + +@Component({ + moduleId: module.id, + selector: '[md-tab-link]', + template: '', + styleUrls: ['tab-link.css'], + host: { + '[class.md-tab-label]': 'true' + } +}) +export class MdTabLink { + private _isSelected: boolean = false; + @Input('selected') + get active(): boolean { + return this._isSelected; + } + set active(value: boolean) { + this._isSelected = value; + if (value) { + this._tabBar.updateActiveLink(this._element.nativeElement); + } + } + + constructor(private _tabBar: MdTabBar, private _element: ElementRef) {} +} diff --git a/src/components/tabs/tabs-common.scss b/src/components/tabs/tabs-common.scss new file mode 100644 index 000000000000..63a150db6f2c --- /dev/null +++ b/src/components/tabs/tabs-common.scss @@ -0,0 +1,42 @@ +@import 'variables'; +@import 'default-theme'; + +$md-tab-bar-height: 48px !default; + +@mixin tab-header { + overflow: hidden; + position: relative; + display: flex; + flex-direction: row; + flex-shrink: 0; +} + +@mixin tab-label { + line-height: $md-tab-bar-height; + height: $md-tab-bar-height; + padding: 0 12px; + font-size: $md-body-font-size-base; + font-family: $md-font-family; + font-weight: 500; + cursor: pointer; + box-sizing: border-box; + color: currentColor; + opacity: 0.6; + min-width: 160px; + text-align: center; + text-decoration: none; + &:focus { + outline: none; + opacity: 1; + background-color: md-color($md-primary, 100, 0.3); + } +} + +/** The colored bar that underlines the active tab */ +md-ink-bar { + position: absolute; + bottom: 0; + height: 2px; + background-color: md-color($md-primary, 500); + transition: 350ms ease-out; +} diff --git a/src/components/tabs/tabs.ts b/src/components/tabs/tabs.ts index 6875066b7c29..f091a90b66d3 100644 --- a/src/components/tabs/tabs.ts +++ b/src/components/tabs/tabs.ts @@ -18,6 +18,7 @@ import {MdTabContent} from './tab-content'; import {MdTabLabelWrapper} from './tab-label-wrapper'; import {MdInkBar} from './ink-bar'; import {Observable} from 'rxjs/Observable'; +import {MdTabBar, MdTabLink} from './tab-nav-bar/tab-nav-bar'; import 'rxjs/add/operator/map'; // Due to a bug in the ChromeDriver, Angular 2 keyboard events are not triggered by `sendKeys` @@ -233,7 +234,7 @@ export class MdTabGroup { } /** @deprecated */ -export const MD_TABS_DIRECTIVES = [MdTabGroup, MdTabLabel, MdTabContent, MdTab]; +export const MD_TABS_DIRECTIVES = [MdTabGroup, MdTabLabel, MdTabContent, MdTab, MdTabBar, MdTabLink]; export const TABS_INTERNAL_DIRECTIVES = [MdInkBar, MdTabLabelWrapper]; @NgModule({ diff --git a/src/demo-app/tabs/tab-group-demo.html b/src/demo-app/tabs/tab-group-demo.html index 3803814796ed..f48030250efc 100644 --- a/src/demo-app/tabs/tab-group-demo.html +++ b/src/demo-app/tabs/tab-group-demo.html @@ -1,7 +1,15 @@ +

Tab Nav Bar

+ + + One + Two + Three + +

Tab Group Demo

- - + +