-
Notifications
You must be signed in to change notification settings - Fork 6.7k
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(tab-nav-bar): add initial functionality of tab nav bar #1589
Changes from 6 commits
3d221b2
77d7a7d
559989d
4b006b0
907ecdc
42b8ba8
243b349
27bb066
4334bb0
d808c71
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import {Routes} from '@angular/router'; | ||
|
||
import {SunnyTabContent, RainyTabContent, FoggyTabContent} from '../tabs/tabs-demo'; | ||
|
||
export const TABS_DEMO_ROUTES: Routes = [ | ||
{ path: '', redirectTo: 'sunny-tab', pathMatch: 'full' }, | ||
{ path: 'sunny-tab', component: SunnyTabContent }, | ||
{ path: 'rainy-tab', component: RainyTabContent }, | ||
{ path: 'foggy-tab', component: FoggyTabContent }, | ||
]; |
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import {NgModule} from '@angular/core'; | ||
import {MaterialModule} from '@angular/material'; | ||
import {FormsModule} from '@angular/forms'; | ||
import {BrowserModule} from '@angular/platform-browser'; | ||
import {RouterModule} from '@angular/router'; | ||
|
||
import {TabsDemo, SunnyTabContent, RainyTabContent, FoggyTabContent} from './tabs-demo'; | ||
|
||
@NgModule({ | ||
imports: [ | ||
FormsModule, | ||
BrowserModule, | ||
MaterialModule, | ||
RouterModule, | ||
], | ||
declarations: [ | ||
TabsDemo, | ||
SunnyTabContent, | ||
RainyTabContent, | ||
FoggyTabContent, | ||
] | ||
}) | ||
export class TabsDemoModule {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
.demo-nav-bar { | ||
border: 1px solid #e0e0e0; | ||
.md-tab-header { | ||
background: #f9f9f9; | ||
} | ||
sunny-routed-content, | ||
rainy-routed-content, | ||
foggy-routed-content { | ||
display: block; | ||
padding: 12px; | ||
} | ||
} | ||
|
||
.demo-tab-group { | ||
border: 1px solid #e0e0e0; | ||
.md-tab-header { | ||
background: #f9f9f9; | ||
} | ||
.md-tab-body { | ||
padding: 12px; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import {Component, ViewEncapsulation} from '@angular/core'; | ||
import {Router} from '@angular/router'; | ||
import {Observable} from 'rxjs/Observable'; | ||
|
||
@Component({ | ||
moduleId: module.id, | ||
selector: 'tabs-demo', | ||
templateUrl: 'tabs-demo.html', | ||
styleUrls: ['tabs-demo.css'], | ||
encapsulation: ViewEncapsulation.None, | ||
}) | ||
export class TabsDemo { | ||
tabLinks = [ | ||
{ label: 'Sun', link: 'sunny-tab'}, | ||
{ label: 'Rain', link: 'rainy-tab'}, | ||
{ label: 'Fog', link: 'foggy-tab'}, | ||
]; | ||
activeLinkIndex = 0; | ||
|
||
tabs = [ | ||
{ label: 'Tab One', content: 'This is the body of the first tab' }, | ||
{ label: 'Tab Two', content: 'This is the body of the second tab' }, | ||
{ label: 'Tab Three', content: 'This is the body of the third tab' }, | ||
]; | ||
|
||
asyncTabs: Observable<any>; | ||
|
||
constructor(private router: Router) { | ||
this.asyncTabs = Observable.create((observer: any) => { | ||
setTimeout(() => { | ||
observer.next(this.tabs); | ||
}, 1000); | ||
}); | ||
|
||
// Initialize the index by checking if a tab link is contained in the url. | ||
// This is not an ideal check and can be removed if routerLink exposes if it is active. | ||
// https://github.com/angular/angular/pull/12525 | ||
this.activeLinkIndex = | ||
this.tabLinks.findIndex(routedTab => router.url.indexOf(routedTab.link) != -1); | ||
} | ||
} | ||
|
||
|
||
@Component({ | ||
moduleId: module.id, | ||
selector: 'sunny-routed-content', | ||
template: 'This is the routed body of the sunny tab.', | ||
}) | ||
export class SunnyTabContent {} | ||
|
||
|
||
@Component({ | ||
moduleId: module.id, | ||
selector: 'rainy-routed-content', | ||
template: 'This is the routed body of the rainy tab.', | ||
}) | ||
export class RainyTabContent {} | ||
|
||
|
||
@Component({ | ||
moduleId: module.id, | ||
selector: 'foggy-routed-content', | ||
template: 'This is the routed body of the foggy tab.', | ||
}) | ||
export class FoggyTabContent {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './tab-nav-bar'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<div class="md-tab-header"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm thinking that this should probably be a @marcysutton Is it appropriate to always use a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Help me level-set: is the set of anchors visually like tabs, but without the associated tabpanels and ARIA tab semantics/keyboard behavior? The difference between a If you do end up using Edit: I thought I had sent this comment days ago, but I'm still not used to the Review workflow apparently. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the input Marcy. Jeremy and I discussed this and agree that we can move this responsibility to the user by making this a component with an attribute selector. Usage of this component will be written by the user as such: |
||
<ng-content></ng-content> | ||
<md-ink-bar></md-ink-bar> | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
@import '../tabs-common'; | ||
|
||
:host { | ||
display: block; | ||
} | ||
|
||
a[md-tab-link] { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd remove the |
||
@include tab-label; | ||
text-decoration: none; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import {async, ComponentFixture, TestBed} from '@angular/core/testing'; | ||
import {MdTabsModule} from '../tabs'; | ||
import {Component} from '@angular/core'; | ||
import {By} from '@angular/platform-browser'; | ||
|
||
|
||
describe('MdTabNavBar', () => { | ||
|
||
beforeEach(async(() => { | ||
TestBed.configureTestingModule({ | ||
imports: [MdTabsModule.forRoot()], | ||
declarations: [ | ||
SimpleTabNavBarTestApp | ||
], | ||
}); | ||
|
||
TestBed.compileComponents(); | ||
})); | ||
|
||
describe('basic behavior', () => { | ||
let fixture: ComponentFixture<SimpleTabNavBarTestApp>; | ||
|
||
beforeEach(() => { | ||
fixture = TestBed.createComponent(SimpleTabNavBarTestApp); | ||
}); | ||
|
||
it('should change active index on click', () => { | ||
let component = fixture.debugElement.componentInstance; | ||
|
||
// select the second link | ||
let tabLink = fixture.debugElement.queryAll(By.css('a'))[1]; | ||
tabLink.nativeElement.click(); | ||
expect(component.activeIndex).toBe(1); | ||
|
||
// select the third link | ||
tabLink = fixture.debugElement.queryAll(By.css('a'))[2]; | ||
tabLink.nativeElement.click(); | ||
expect(component.activeIndex).toBe(2); | ||
}); | ||
}); | ||
}); | ||
|
||
@Component({ | ||
selector: 'test-app', | ||
template: ` | ||
<md-tab-nav-bar> | ||
<a md-tab-link [active]="activeIndex === 0" (click)="activeIndex = 0">Tab One</a> | ||
<a md-tab-link [active]="activeIndex === 1" (click)="activeIndex = 1">Tab Two</a> | ||
<a md-tab-link [active]="activeIndex === 2" (click)="activeIndex = 2">Tab Three</a> | ||
</md-tab-nav-bar> | ||
` | ||
}) | ||
class SimpleTabNavBarTestApp { | ||
activeIndex = 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the leading/trailing spaces in object literals