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
-
-
+
+
{{tab.label}}
{{tab.content}}
diff --git a/src/demo-app/tabs/tab-group-demo.ts b/src/demo-app/tabs/tab-group-demo.ts
index 12765490200a..832d847a126e 100644
--- a/src/demo-app/tabs/tab-group-demo.ts
+++ b/src/demo-app/tabs/tab-group-demo.ts
@@ -18,6 +18,7 @@ export class TabsDemo {
{ label: 'Tab Three', content: 'This is the body of the third tab' },
];
asyncTabs: Observable;
+ selectedIndex = 0;
constructor() {
this.asyncTabs = Observable.create((observer: any) => {
setTimeout(() => {