Skip to content

Commit 48cef4b

Browse files
committed
feat(tabs): adding routing for tabs (still in progress) #4297
1 parent 08265db commit 48cef4b

File tree

4 files changed

+166
-4
lines changed

4 files changed

+166
-4
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { Component, NgModule } from '@angular/core';
2+
3+
@Component({
4+
template: `This is content in component # 1`
5+
})
6+
export class RoutingView1Component {
7+
}
8+
9+
@Component({
10+
template: `This is content in component # 2`
11+
})
12+
export class RoutingView2Component {
13+
}
14+
15+
@Component({
16+
template: `This is content in component # 3`
17+
})
18+
export class RoutingView3Component {
19+
}
20+
21+
/**
22+
* @hidden
23+
*/
24+
@NgModule({
25+
declarations: [RoutingView1Component, RoutingView2Component, RoutingView3Component],
26+
exports: [RoutingView1Component, RoutingView2Component, RoutingView3Component],
27+
// imports: [CommonModule, IgxBadgeModule, IgxIconModule]
28+
})
29+
export class RoutingViewComponentsModule {
30+
}

Diff for: projects/igniteui-angular/src/lib/tabs/tabs-group.component.ts

+3
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ export class IgxTabsGroupComponent implements IgxTabsGroupBase, AfterContentInit
189189
this._tabs.onTabItemSelected.emit({ tab: this._tabs.tabs.toArray()[this.index], group: this });
190190
}
191191

192+
public _selectAndEmitEvent() {
193+
}
194+
192195
private handleSelection(): void {
193196
const tabElement = this.relatedTab.nativeTabItem.nativeElement;
194197

Diff for: projects/igniteui-angular/src/lib/tabs/tabs.component.spec.ts

+107-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { Component, QueryList, ViewChild } from '@angular/core';
22
import { async, TestBed, fakeAsync, tick } from '@angular/core/testing';
3+
import { Location } from '@angular/common';
4+
import { Router } from '@angular/router';
35
import { RouterTestingModule } from '@angular/router/testing';
46
import { IgxTabItemComponent } from './tab-item.component';
57
import { IgxTabsGroupComponent } from './tabs-group.component';
@@ -12,15 +14,26 @@ import { IgxToggleModule } from '../directives/toggle/toggle.directive';
1214
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
1315
import { By } from '@angular/platform-browser';
1416
import { UIInteractions } from '../test-utils/ui-interactions.spec';
17+
import { RoutingViewComponentsModule,
18+
RoutingView1Component,
19+
RoutingView2Component,
20+
RoutingView3Component } from './routing-view-components';
1521

1622
describe('IgxTabs', () => {
1723
configureTestSuite();
1824
beforeEach(async(() => {
25+
26+
const testRoutes = [
27+
{ path: 'view1', component: RoutingView1Component },
28+
{ path: 'view2', component: RoutingView2Component },
29+
{ path: 'view3', component: RoutingView3Component }
30+
];
31+
1932
TestBed.configureTestingModule({
2033
declarations: [TabsTestComponent, TabsTest2Component, TemplatedTabsTestComponent,
21-
TabsTestSelectedTabComponent, TabsTestCustomStylesComponent, TabsTestBug4420Component],
34+
TabsTestSelectedTabComponent, TabsTestCustomStylesComponent, TabsTestBug4420Component, TabsRoutingTestComponent],
2235
imports: [IgxTabsModule, IgxButtonModule, IgxDropDownModule, IgxToggleModule,
23-
BrowserAnimationsModule, RouterTestingModule]
36+
RoutingViewComponentsModule, BrowserAnimationsModule, RouterTestingModule.withRoutes(testRoutes)]
2437
})
2538
.compileComponents();
2639
}));
@@ -399,6 +412,73 @@ describe('IgxTabs', () => {
399412
const indicator = dom.query(By.css('.igx-tabs__header-menu-item-indicator'));
400413
expect(indicator.nativeElement.style.width).toBe('90px');
401414
}));
415+
416+
fit('should navigate to the correct URL when clicking on tab buttons', fakeAsync(() => {
417+
418+
const router = TestBed.get(Router);
419+
const location = TestBed.get(Location);
420+
const fixture = TestBed.createComponent(TabsRoutingTestComponent);
421+
const tabsComp = fixture.componentInstance.tabsComp;
422+
fixture.detectChanges();
423+
424+
fixture.ngZone.run(() => { router.initialNavigation(); });
425+
426+
tick();
427+
expect(location.path()).toBe('/view1');
428+
429+
fixture.ngZone.run(() => { tabsComp.tabs.toArray()[2].select(); });
430+
tick();
431+
expect(location.path()).toBe('/view3');
432+
433+
fixture.ngZone.run(() => { tabsComp.tabs.toArray()[1].select(); });
434+
tick();
435+
expect(location.path()).toBe('/view2');
436+
437+
fixture.ngZone.run(() => { tabsComp.tabs.toArray()[0].select(); });
438+
tick();
439+
expect(location.path()).toBe('/view1');
440+
}));
441+
442+
fit('should select the correct tab button/panel when navigating an URL', fakeAsync(() => {
443+
444+
const router = TestBed.get(Router);
445+
const location = TestBed.get(Location);
446+
const fixture = TestBed.createComponent(TabsRoutingTestComponent);
447+
const tabsComp = fixture.componentInstance.tabsComp;
448+
fixture.detectChanges();
449+
450+
fixture.ngZone.run(() => { router.initialNavigation(); });
451+
tick();
452+
expect(location.path()).toBe('/view1');
453+
expect(tabsComp.selectedIndex).toBe(0);
454+
expect(tabsComp.groups.toArray()[0].isSelected).toBe(true);
455+
expect(tabsComp.tabs.toArray()[0].isSelected).toBe(true);
456+
457+
fixture.ngZone.run(() => { router.navigate(['/view3']); });
458+
tick();
459+
expect(location.path()).toBe('/view3');
460+
fixture.detectChanges();
461+
expect(tabsComp.selectedIndex).toBe(2);
462+
expect(tabsComp.groups.toArray()[2].isSelected).toBe(true);
463+
expect(tabsComp.tabs.toArray()[2].isSelected).toBe(true);
464+
465+
fixture.ngZone.run(() => { router.navigate(['/view2']); });
466+
tick();
467+
expect(location.path()).toBe('/view2');
468+
fixture.detectChanges();
469+
expect(tabsComp.selectedIndex).toBe(1);
470+
expect(tabsComp.groups.toArray()[1].isSelected).toBe(true);
471+
expect(tabsComp.tabs.toArray()[1].isSelected).toBe(true);
472+
473+
fixture.ngZone.run(() => { router.navigate(['/view1']); });
474+
tick();
475+
expect(location.path()).toBe('/view1');
476+
fixture.detectChanges();
477+
expect(tabsComp.selectedIndex).toBe(0);
478+
expect(tabsComp.groups.toArray()[0].isSelected).toBe(true);
479+
expect(tabsComp.tabs.toArray()[0].isSelected).toBe(true);
480+
481+
}));
402482
});
403483

404484
@Component({
@@ -586,3 +666,28 @@ class TabsTestCustomStylesComponent {
586666
class TabsTestBug4420Component {
587667
@ViewChild(IgxTabsComponent) public tabs: IgxTabsComponent;
588668
}
669+
670+
@Component({
671+
template: `
672+
<div #wrapperDiv>
673+
<igx-tabs>
674+
<igx-tabs-group label="Tab 1" routerLink="/view1">
675+
Content in tab # 1
676+
</igx-tabs-group>
677+
<igx-tabs-group label="Tab 2" routerLink="/view2">
678+
Content in tab # 2
679+
</igx-tabs-group>
680+
<igx-tabs-group label="Tab 3" routerLink="/view3">
681+
Content in tab # 3
682+
</igx-tabs-group>
683+
</igx-tabs>
684+
<div>
685+
<router-outlet></router-outlet>
686+
</div>
687+
</div>
688+
`
689+
})
690+
class TabsRoutingTestComponent {
691+
@ViewChild(IgxTabsComponent)
692+
public tabsComp: IgxTabsComponent;
693+
}

Diff for: projects/igniteui-angular/src/lib/tabs/tabs.component.ts

+26-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ import { IgxTabItemComponent } from './tab-item.component';
2424
import { IgxTabsGroupComponent } from './tabs-group.component';
2525
import { IgxLeftButtonStyleDirective, IgxRightButtonStyleDirective, IgxTabItemTemplateDirective } from './tabs.directives';
2626
import { IgxTabsBase } from './tabs.common';
27-
import { Router } from '@angular/router';
27+
import { NavigationEnd, Router, RouterLink } from '@angular/router';
28+
import { filter } from 'rxjs/operators';
2829

2930
export enum TabsType {
3031
FIXED = 'fixed',
@@ -177,6 +178,10 @@ export class IgxTabsComponent implements IgxTabsBase, AfterViewInit, OnDestroy {
177178
*/
178179
public offset = 0;
179180

181+
/**
182+
* @hidden
183+
*/
184+
private _navigationEndSubscription: Subscription;
180185
private _groupChanges$: Subscription;
181186
private _selectedIndex = 0;
182187

@@ -267,7 +272,7 @@ export class IgxTabsComponent implements IgxTabsBase, AfterViewInit, OnDestroy {
267272
}
268273
}
269274

270-
constructor(private _element: ElementRef, private router: Router) {
275+
constructor(private router: Router) {
271276
}
272277

273278
/**
@@ -279,6 +284,25 @@ export class IgxTabsComponent implements IgxTabsBase, AfterViewInit, OnDestroy {
279284
this._groupChanges$ = this.groups.changes.subscribe(() => {
280285
this.resetSelectionOnCollectionChanged();
281286
});
287+
this._navigationEndSubscription = this.router.events.pipe(
288+
filter(event => event instanceof NavigationEnd)).subscribe(() => {
289+
this.navigationEndHandler(this);
290+
}
291+
);
292+
}
293+
294+
/**
295+
*@hidden
296+
*/
297+
public navigationEndHandler(tabsComponent: IgxTabsComponent) {
298+
const groupsArray = tabsComponent.groups.toArray();
299+
for (let i = 0; i < groupsArray.length; i++) {
300+
if (groupsArray[i].routerLinkDirective &&
301+
tabsComponent.router.url.startsWith(groupsArray[i].routerLinkDirective.urlTree.toString())) {
302+
groupsArray[i]._selectAndEmitEvent();
303+
break;
304+
}
305+
}
282306
}
283307

284308
/**

0 commit comments

Comments
 (0)