Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | 1x 58x 17x 17x 17x 10x 2x 2x 2x 2x 2x 1x 2x 1x 2x 18x 3x | /**
* Copyright (c) Siemens 2016 - 2025
* SPDX-License-Identifier: MIT
*/
import { FocusKeyManager } from '@angular/cdk/a11y';
import { CdkMenuTrigger } from '@angular/cdk/menu';
import { NgTemplateOutlet } from '@angular/common';
import {
ChangeDetectionStrategy,
Component,
computed,
contentChildren,
inject,
INJECTOR,
signal
} from '@angular/core';
import { RouterLink } from '@angular/router';
import { isRTL } from '@siemens/element-ng/common';
import { SiMenuDirective, SiMenuItemComponent } from '@siemens/element-ng/menu';
import { SiResizeObserverModule } from '@siemens/element-ng/resize-observer';
import { SiTabBadgeComponent } from './si-tab-badge.component';
import { SiTabBaseDirective } from './si-tab-base.directive';
import { SiTabLinkComponent } from './si-tab-link.component';
import { SI_TABSET } from './si-tabs-tokens';
/**
* A component to group multiple tabs together.
* Can either be used with {@link SiTabLinkComponent} or {@link SiTabComponent} components.
*/
@Component({
selector: 'si-tabset',
imports: [
SiMenuDirective,
SiMenuItemComponent,
CdkMenuTrigger,
NgTemplateOutlet,
SiResizeObserverModule,
RouterLink,
SiTabBadgeComponent
],
templateUrl: './si-tabset.component.html',
styleUrl: './si-tabset.component.scss',
providers: [
{
provide: SI_TABSET,
useExisting: SiTabsetComponent
}
],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SiTabsetComponent {
/** @internal */
readonly activeTab = computed(() => this.tabPanels().find(tab => tab.active()));
/** @internal */
readonly tabPanels = contentChildren(SiTabBaseDirective);
/** @internal */
focusKeyManager = new FocusKeyManager(this.tabPanels, inject(INJECTOR))
.withHorizontalOrientation(isRTL() ? 'rtl' : 'ltr')
.withWrap(true);
/** @internal */
protected readonly showMenuButton = signal(false);
protected tabIsLink(tab: unknown): tab is SiTabLinkComponent {
return tab instanceof SiTabLinkComponent;
}
/** @internal */
removedTabByUser(index: number, active?: boolean): void {
// The tab was already removed from the tabPanels list when this function is called.
// We need to:
// - focus another tab if the closed one was focused
// - activate another tab if the closed one was active
// If the closed tab was not focussed, there is no need to restore the focus as it could only be closed by mouse.
for (let i = 0; i < this.tabPanels().length; i++) {
// Get the actual index using modulo to wrap around
const checkIndex = (index + i) % this.tabPanels().length;
const checkTab = this.tabPanels()[checkIndex];
if (!checkTab.disabledTab()) {
if (this.focusKeyManager.activeItemIndex === index) {
this.focusKeyManager.setActiveItem(checkIndex);
}
if (active) {
checkTab.selectTab(true);
}
return;
}
}
}
protected resizeContainer(width: number, scrollWidth: number): void {
// 48px is the width of the menu button.
this.showMenuButton.set(scrollWidth > width + (this.showMenuButton() ? 48 : 0));
}
protected keydown(event: KeyboardEvent): void {
this.focusKeyManager.onKeydown(event);
}
}
|