Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions projects/igniteui-angular/src/lib/tabs/tab-header.directive.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

import { Directive, ElementRef, HostBinding, HostListener } from '@angular/core';
import { Directive, ElementRef, HostBinding, HostListener, Optional, inject } from '@angular/core';
import { RouterLink } from '@angular/router';
import { PlatformUtil } from '../core/utils';
import { IgxTabItemDirective } from './tab-item.directive';
import { IgxTabHeaderBase, IgxTabsBase } from './tabs.base';
Expand All @@ -17,7 +18,13 @@ export abstract class IgxTabHeaderDirective implements IgxTabHeaderBase {
public tab: IgxTabItemDirective,
private elementRef: ElementRef<HTMLElement>,
protected platform: PlatformUtil
) { }
) {
// Inject RouterLink directive if present
this.routerLink = inject(RouterLink, { optional: true });
}

/** @hidden */
private routerLink?: RouterLink;

/** @hidden */
@HostBinding('attr.tabindex')
Expand All @@ -40,7 +47,9 @@ export abstract class IgxTabHeaderDirective implements IgxTabHeaderBase {
/** @hidden */
@HostListener('click')
public onClick() {
if (this.tab.panelComponent) {
// For routing tabs, let the RouterLink handle navigation and don't select the tab immediately
// For other tabs (content tabs or action tabs), allow immediate selection
if (!this.routerLink) {
this.tabs.selectTab(this.tab, true);
}
}
Expand Down
30 changes: 30 additions & 0 deletions projects/igniteui-angular/src/lib/tabs/tabs/tabs.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,36 @@ describe('IgxTabs', () => {
fixture.detectChanges();
expect(tabsComp.selectedIndicator.nativeElement.style.visibility).toBe('hidden');
});

it('should allow tab selection by clicking on tabs without content', fakeAsync(() => {
// Initially tab 1 (index 1) is selected
expect(tabsComp.selectedIndex).toBe(1);
expect(tabItems[1].selected).toBe(true);
expect(tabItems[0].selected).toBe(false);
expect(tabItems[2].selected).toBe(false);

// Click on tab 0 (no content)
headerElements[0].dispatchEvent(new Event('click', { bubbles: true }));
tick(200);
fixture.detectChanges();

// Should now be selected
expect(tabsComp.selectedIndex).toBe(0);
expect(tabItems[0].selected).toBe(true);
expect(tabItems[1].selected).toBe(false);
expect(tabItems[2].selected).toBe(false);

// Click on tab 2 (no content)
headerElements[2].dispatchEvent(new Event('click', { bubbles: true }));
tick(200);
fixture.detectChanges();

// Should now be selected
expect(tabsComp.selectedIndex).toBe(2);
expect(tabItems[2].selected).toBe(true);
expect(tabItems[0].selected).toBe(false);
expect(tabItems[1].selected).toBe(false);
}));
});

describe('Tabs-only Mode With Initial Selection Set on Tabs Component Tests', () => {
Expand Down
29 changes: 29 additions & 0 deletions src/app/tabs-showcase/tabs-showcase.sample.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,35 @@
}
</igc-tabs>
</div>

<div class="sample-wrapper">
<strong>Tabs without content (test for fix)</strong>
<p>These tabs have headers but no content - clicking should still allow selection</p>
<igx-tabs>
<igx-tab-item>
<igx-tab-header>
<igx-icon igxTabHeaderIcon>info</igx-icon>
<span igxTabHeaderLabel>View 1</span>
</igx-tab-header>
<!-- No igx-tab-content -->
</igx-tab-item>
<igx-tab-item [selected]="true">
<igx-tab-header>
<igx-icon igxTabHeaderIcon>settings</igx-icon>
<span igxTabHeaderLabel>View 2</span>
</igx-tab-header>
<!-- No igx-tab-content -->
</igx-tab-item>
<igx-tab-item>
<igx-tab-header>
<igx-icon igxTabHeaderIcon>help</igx-icon>
<span igxTabHeaderLabel>View 3</span>
</igx-tab-header>
<!-- No igx-tab-content -->
</igx-tab-item>
</igx-tabs>
<p><small>✅ After the fix, clicking any tab header should select it even without content</small></p>
</div>
</div>

<ng-template #customControlsTemplate>
Expand Down
Loading