src/tabs/tab-header.component.ts
Tab header with template for label, optional icon, secondary label, badge, and dismissable close.
Example :<cds-tab-header-group>
<cds-tab-header [paneReference]="c1">Dashboard</cds-tab-header>
<cds-tab-header [paneReference]="c2" [icon]="iconTpl" secondaryLabel="(1/4)">
Monitoring
</cds-tab-header>
</cds-tab-header-group>
<cds-tab #c1>...</cds-tab>
<cds-tab #c2>...</cds-tab>
AfterViewInit
| providers |
{ provide: TabHeaderBase, useExisting: forwardRef(() => TabHeaderComponent) }
|
| selector | cds-tab-header, ibm-tab-header |
| template | |
Properties |
|
Methods |
Inputs |
Outputs |
HostBindings |
Accessors |
| badgeIndicator | |
Type : boolean
|
|
Default value : false
|
|
|
Defined in src/tabs/tab-header.component.ts:141
|
|
|
Preview: Icon-only tabs — show a notification dot on the icon. |
|
| closeButtonAriaLabel | |
Type : string
|
|
Default value : "Press delete to remove tab"
|
|
|
Defined in src/tabs/tab-header.component.ts:149
|
|
|
|
|
| enterDelayMs | |
Type : number
|
|
|
Defined in src/tabs/tab-header.component.ts:153
|
|
|
Icon-only tabs: tooltip show delay (ms). |
|
| iconLabel | |
Type : string
|
|
|
Defined in src/tabs/tab-header.component.ts:137
|
|
|
Icon-only tabs: accessible name ( |
|
| iconOnly | |
Type : boolean
|
|
Default value : false
|
|
|
Defined in src/tabs/tab-header.component.ts:133
|
|
|
Icon-only tab: set |
|
| iconSize | |
Type : "default" | "lg"
|
|
Default value : "default"
|
|
|
Defined in src/tabs/tab-header.component.ts:145
|
|
|
Icon-only tabs: icon size |
|
| isTooltipOpen | |
Type : boolean
|
|
Default value : false
|
|
|
Defined in src/tabs/tab-header.component.ts:161
|
|
|
Icon-only tabs: open the tooltip on first render. |
|
| leaveDelayMs | |
Type : number
|
|
|
Defined in src/tabs/tab-header.component.ts:157
|
|
|
Icon-only tabs: tooltip hide delay (ms). |
|
| active | |
Type : boolean
|
|
Default value : false
|
|
|
Inherited from
TabHeaderBase
|
|
|
Defined in
TabHeaderBase:53
|
|
|
Selected tab; controls whether the linked pane content is shown. |
|
| cacheActive | |
Type : boolean
|
|
|
Inherited from
TabHeaderBase
|
|
|
Defined in
TabHeaderBase:28
|
|
|
Set to 'true' to have pane reference cached and not reloaded on tab switching. |
|
| disabled | |
Type : boolean
|
|
Default value : false
|
|
|
Inherited from
TabHeaderBase
|
|
|
Defined in
TabHeaderBase:58
|
|
|
Indicates whether or not the |
|
| dismissable | |
Type : boolean
|
|
Default value : false
|
|
|
Inherited from
TabHeaderBase
|
|
|
Defined in
TabHeaderBase:74
|
|
|
Set to |
|
| icon | |
Type : TemplateRef<any>
|
|
|
Inherited from
TabHeaderBase
|
|
|
Defined in
TabHeaderBase:63
|
|
|
Icon template; used with |
|
| paneReference | |
Type : Tab
|
|
|
Inherited from
TabHeaderBase
|
|
|
Defined in
TabHeaderBase:79
|
|
|
Reference to the corresponding tab pane. |
|
| paneTabIndex | |
Type : number | null
|
|
|
Inherited from
TabHeaderBase
|
|
|
Defined in
TabHeaderBase:44
|
|
|
Sets |
|
| secondaryLabel | |
Type : string
|
|
|
Inherited from
TabHeaderBase
|
|
|
Defined in
TabHeaderBase:69
|
|
|
Optional secondary label rendered below the primary tab label.
Only displayed when the parent group is using |
|
| title | |
Type : string
|
|
|
Inherited from
TabHeaderBase
|
|
|
Defined in
TabHeaderBase:84
|
|
|
Title attribute used as the tooltip for the tab item. Falls back to the tab item's text content if not provided. |
|
| selected | |
Type : EventEmitter
|
|
|
Inherited from
TabHeaderBase
|
|
|
Defined in
TabHeaderBase:89
|
|
|
Emits when this header becomes selected. |
|
| tabClose | |
Type : EventEmitter
|
|
|
Inherited from
TabHeaderBase
|
|
|
Defined in
TabHeaderBase:94
|
|
|
Emits when this tabs's close button is pressed. |
|
| style.display |
Type : string
|
Default value : "contents"
|
|
Defined in src/tabs/tab-header.component.ts:163
|
| focus |
focus()
|
|
Inherited from
TabHeaderBase
|
|
Defined in
TabHeaderBase:183
|
|
Focus the rendered tab button (not the host).
Returns :
void
|
| ngAfterViewInit |
ngAfterViewInit()
|
|
Defined in src/tabs/tab-header.component.ts:167
|
|
Returns :
void
|
| onClose | ||||||
onClose(event: Event)
|
||||||
|
Defined in src/tabs/tab-header.component.ts:204
|
||||||
|
Close button click; stops propagation so the tab does not activate.
Parameters :
Returns :
void
|
| onTabButtonClick |
onTabButtonClick()
|
|
Defined in src/tabs/tab-header.component.ts:187
|
|
Returns :
void
|
| onTabButtonKeyDown | ||||||
onTabButtonKeyDown(event: KeyboardEvent)
|
||||||
|
Defined in src/tabs/tab-header.component.ts:194
|
||||||
|
Parameters :
Returns :
void
|
| selectTab |
selectTab()
|
|
Inherited from
TabHeaderBase
|
|
Defined in
TabHeaderBase:106
|
|
Activates the linked pane and emits
Returns :
void
|
| displayContents |
Type : string
|
Default value : "contents"
|
Decorators :
@HostBinding('style.display')
|
|
Defined in src/tabs/tab-header.component.ts:163
|
| tabButton |
Type : ElementRef<HTMLButtonElement>
|
Decorators :
@ViewChild('tabButton')
|
|
Defined in src/tabs/tab-header.component.ts:165
|
| Protected _cacheActive |
Default value : false
|
|
Inherited from
TabHeaderBase
|
|
Defined in
TabHeaderBase:96
|
| resolvedTitle |
getresolvedTitle()
|
|
Defined in src/tabs/tab-header.component.ts:212
|
| closeButtonTitle |
getcloseButtonTitle()
|
|
Defined in src/tabs/tab-header.component.ts:219
|
import {
AfterViewInit,
Component,
ElementRef,
forwardRef,
HostBinding,
Input,
ViewChild
} from "@angular/core";
import { TabHeaderBase } from "./tab-header.directive";
/**
* Tab header with template for label, optional icon, secondary label, badge, and dismissable close.
*
* ```html
* <cds-tab-header-group>
* <cds-tab-header [paneReference]="c1">Dashboard</cds-tab-header>
* <cds-tab-header [paneReference]="c2" [icon]="iconTpl" secondaryLabel="(1/4)">
* Monitoring
* </cds-tab-header>
* </cds-tab-header-group>
* <cds-tab #c1>...</cds-tab>
* <cds-tab #c2>...</cds-tab>
* ```
*/
@Component({
selector: "cds-tab-header, ibm-tab-header",
providers: [
// tslint:disable-next-line:no-forward-ref
{ provide: TabHeaderBase, useExisting: forwardRef(() => TabHeaderComponent) }
],
template: `
<cds-tooltip
*ngIf="iconOnly; else plainButton"
align="bottom"
[autoAlign]="true"
class="cds--icon-tooltip"
[description]="iconLabel"
[enterDelayMs]="enterDelayMs"
[leaveDelayMs]="leaveDelayMs"
[isOpen]="isTooltipOpen"
[disabled]="disabled">
<ng-container *ngTemplateOutlet="tabButtonTemplate"></ng-container>
</cds-tooltip>
<ng-template #plainButton>
<ng-container *ngTemplateOutlet="tabButtonTemplate"></ng-container>
</ng-template>
<ng-template #tabButtonTemplate>
<button
#tabButton
type="button"
role="tab"
class="cds--tabs__nav-item cds--tabs__nav-link"
[ngClass]="{
'cds--tabs__nav-item--selected': active,
'cds--tabs__nav-item--disabled': disabled,
'cds--tabs__nav-item--icon-only': iconOnly,
'cds--tabs__nav-item--icon-only__20': iconOnly && iconSize === 'lg'
}"
[attr.aria-selected]="active"
[attr.aria-disabled]="disabled"
[attr.aria-controls]="paneReference?.id || null"
[attr.aria-label]="iconOnly ? iconLabel : null"
[attr.tabindex]="active ? 0 : -1"
[attr.title]="resolvedTitle"
[disabled]="disabled"
(click)="onTabButtonClick()"
(keydown)="onTabButtonKeyDown($event)">
<ng-container *ngIf="iconOnly; else labeledTab">
<ng-container [ngTemplateOutlet]="icon"></ng-container>
<span
*ngIf="!disabled && badgeIndicator"
class="cds--badge-indicator"
aria-hidden="true">
</span>
</ng-container>
<ng-template #labeledTab>
<div class="cds--tabs__nav-item-label-wrapper">
<div *ngIf="dismissable && icon" class="cds--tabs__nav-item--icon-left">
<ng-container [ngTemplateOutlet]="icon"></ng-container>
</div>
<span class="cds--tabs__nav-item-label">
<ng-content></ng-content>
</span>
<div *ngIf="!dismissable && icon" class="cds--tabs__nav-item--icon">
<ng-container [ngTemplateOutlet]="icon"></ng-container>
</div>
</div>
<div
*ngIf="secondaryLabel"
class="cds--tabs__nav-item-secondary-label"
[attr.title]="secondaryLabel">
{{ secondaryLabel }}
</div>
</ng-template>
</button>
</ng-template>
<div *ngIf="dismissable" class="cds--tabs__nav-item--close">
<button
type="button"
class="cds--tabs__nav-item--close-icon"
[attr.tabindex]="-1"
[attr.aria-disabled]="disabled"
[attr.aria-hidden]="!(active && !disabled)"
[ngClass]="{
'cds--tabs__nav-item--close-icon--selected': active,
'cds--tabs__nav-item--close-icon--disabled': disabled
}"
[disabled]="disabled"
[attr.title]="closeButtonTitle"
(click)="onClose($event)">
<svg
focusable="false"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
width="16"
height="16"
viewBox="0 0 32 32"
[attr.aria-label]="closeButtonAriaLabel"
[attr.aria-hidden]="!(active && !disabled)">
<path d="M17.4141 16L24 9.4141 22.5859 8 16 14.5859 9.4143 8 8 9.4141 14.5859 16 8 22.5859 9.4143 24 16 17.4141 22.5859 24 24 22.5859 17.4141 16z"></path>
</svg>
</button>
</div>
`
})
export class TabHeaderComponent extends TabHeaderBase implements AfterViewInit {
/**
* Icon-only tab: set `icon` and `iconLabel`.
*/
@Input() iconOnly = false;
/**
* Icon-only tabs: accessible name (`aria-label` / `title`).
*/
@Input() iconLabel: string;
/**
* **Preview**: Icon-only tabs — show a notification dot on the icon.
*/
@Input() badgeIndicator = false;
/**
* Icon-only tabs: icon size `default` (16px) or `lg` (20px); usually set on the parent group.
*/
@Input() iconSize: "default" | "lg" = "default";
/**
* `aria-label` for the dismissable close button.
*/
@Input() closeButtonAriaLabel = "Press delete to remove tab";
/**
* Icon-only tabs: tooltip show delay (ms).
*/
@Input() enterDelayMs: number;
/**
* Icon-only tabs: tooltip hide delay (ms).
*/
@Input() leaveDelayMs: number;
/**
* Icon-only tabs: open the tooltip on first render.
*/
@Input() isTooltipOpen = false;
@HostBinding("style.display") displayContents = "contents";
@ViewChild("tabButton") tabButton: ElementRef<HTMLButtonElement>;
ngAfterViewInit() {
// Mirror the deprecated directive's title-fallback behavior, but read
// from the inner rendered button rather than the `display: contents` host.
setTimeout(() => {
if (!this.title && this.tabButton?.nativeElement) {
const text = this.tabButton.nativeElement.textContent?.trim();
if (text) {
this.title = text;
}
}
});
}
/**
* Focus the rendered tab button (not the host).
*/
focus() {
this.tabButton?.nativeElement?.focus();
}
onTabButtonClick() {
this.selectTab();
}
/**
* `Delete` closes dismissable tabs when focus is on the tab.
*/
onTabButtonKeyDown(event: KeyboardEvent) {
if (this.dismissable && event.key === "Delete") {
event.stopPropagation();
this.tabClose.emit();
}
}
/**
* Close button click; stops propagation so the tab does not activate.
*/
onClose(event: Event) {
event.stopPropagation();
if (this.disabled) {
return;
}
this.tabClose.emit();
}
get resolvedTitle(): string | null {
if (this.iconOnly) {
return this.iconLabel || null;
}
return this.title || null;
}
get closeButtonTitle(): string {
const label = this.tabButton?.nativeElement?.textContent?.trim();
return label ? `Remove ${label} tab` : "Remove tab";
}
}