Skip to content

Commit 183b275

Browse files
tiagoroldaovalorkin
authored andcommitted
fix(tabs): Use [ngClass] to avoid conflicts with [class.x] bindings (#1651)
* fix(tab.component): Use [ngClass] to avoid conflicts with [class.x] bindings * Added tests, handle undefined customClass
1 parent 62eb22a commit 183b275

File tree

2 files changed

+36
-6
lines changed

2 files changed

+36
-6
lines changed

src/spec/tabset.component.spec.ts

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const html = `
1010
<tab heading="tab0">tab0 content</tab>
1111
<tab *ngFor="let tab of tabs"
1212
[disabled]="tab.disabled"
13+
[customClass]="tab.customClass"
1314
[active]="tab.active"
1415
[removable]="tab.removable"
1516
(select)="_select($event)"
@@ -19,6 +20,10 @@ const html = `
1920
</tabset>
2021
`;
2122

23+
function getTabItems(nativeEl: HTMLElement): NodeListOf<Element> {
24+
return nativeEl.querySelectorAll('.nav-item');
25+
}
26+
2227
function getTabTitles(nativeEl: HTMLElement): NodeListOf<Element> {
2328
return nativeEl.querySelectorAll('.nav-link');
2429
}
@@ -28,18 +33,18 @@ function getTabContent(nativeEl: HTMLElement): NodeListOf<Element> {
2833
}
2934

3035
function expectActiveTabs(nativeEl: HTMLElement, active: boolean[]): void {
31-
const tabTitles = getTabTitles(nativeEl);
36+
const tabItems = getTabItems(nativeEl);
3237
const tabContent = getTabContent(nativeEl);
3338

34-
expect(tabTitles.length).toBe(active.length);
39+
expect(tabItems.length).toBe(active.length);
3540
expect(tabContent.length).toBe(active.length);
3641

3742
for (let i = 0; i < active.length; i++) {
3843
if (active[i]) {
39-
expect(tabTitles[i].classList).toContain('active');
44+
expect(tabItems[i].classList).toContain('active');
4045
expect(tabContent[i].classList).toContain('active');
4146
} else {
42-
expect(tabTitles[i].classList).not.toContain('active');
47+
expect(tabItems[i].classList).not.toContain('active');
4348
expect(tabContent[i].classList).not.toContain('active');
4449
}
4550
}
@@ -175,6 +180,31 @@ describe('Component: Tabs', () => {
175180
heading: 'tab3'
176181
}));
177182
});
183+
184+
it('should set class on a tab item through [customClass]', () => {
185+
const tabItems = getTabItems(element);
186+
187+
expect(tabItems[1].classList).toContain('testCustomClass');
188+
});
189+
190+
it('should prevent interference of [customClass] and state classes', () => {
191+
const tabItems = getTabItems(element);
192+
const tabTitles = getTabTitles(element);
193+
194+
expect(tabItems[1].classList).toContain('testCustomClass');
195+
196+
(tabTitles[1] as HTMLAnchorElement).click();
197+
fixture.detectChanges();
198+
expect(tabItems[1].classList).toContain('testCustomClass');
199+
expectActiveTabs(element, [false, true, false, false]);
200+
201+
context.tabs[0].customClass = 'otherCustomClass';
202+
fixture.detectChanges();
203+
204+
expect(tabItems[1].classList).not.toContain('testCustomClass');
205+
expect(tabItems[1].classList).toContain('otherCustomClass');
206+
expectActiveTabs(element, [false, true, false, false]);
207+
});
178208
});
179209

180210
@Component({
@@ -186,7 +216,7 @@ class TestTabsetComponent {
186216
public isVertical:Boolean = false;
187217
public isJustified:Boolean = false;
188218
public tabs:any[] = [
189-
{title: 'tab1', content: 'tab1 content'},
219+
{title: 'tab1', content: 'tab1 content', customClass:'testCustomClass'},
190220
{title: 'tab2', content: 'tab2 content', disabled: true},
191221
{title: 'tab3', content: 'tab3 content', removable: true}
192222
];

src/tabs/tabset.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { TabsetConfig } from './tabset.config';
88
selector: 'tabset',
99
template: `
1010
<ul class="nav" [ngClass]="classMap" (click)="$event.preventDefault()">
11-
<li *ngFor="let tabz of tabs" class="nav-item {{tabz.customClass}}"
11+
<li *ngFor="let tabz of tabs" [ngClass]="['nav-item', tabz.customClass || '']"
1212
[class.active]="tabz.active" [class.disabled]="tabz.disabled">
1313
<a href="javascript:void(0);" class="nav-link"
1414
[class.active]="tabz.active" [class.disabled]="tabz.disabled"

0 commit comments

Comments
 (0)