import { FocusableOption , FocusMonitor } from '@angular/cdk/a11y' ; import { BooleanInput , coerceBooleanProperty } from '@angular/cdk/coercion' ; import { ViewportRuler } from '@angular/cdk/scrolling' ; import { AfterContentChecked , AfterContentInit , AfterViewInit , Attribute , ChangeDetectionStrategy , ChangeDetectorRef , Component , ContentChildren , Directive , ElementRef , forwardRef , Inject , Input , NgZone , OnDestroy , Optional , QueryList , ViewChild , ViewEncapsulation , } from '@angular/core' ; import { ANIMATION_MODULE_TYPE } from '@angular/platform-browser/animations' ; import { CanDisable , HasTabIndex , mixinDisabled , mixinTabIndex } from '@sbb-esta/angular/core' ; import { startWith , takeUntil } from 'rxjs/operators' ; import { SbbPaginatedTabHeader , SbbPaginatedTabHeaderItem } from './paginated-tab-header' ; docs-private @ Directive ( ) export abstract class _SbbTabNavBase extends SbbPaginatedTabHeader implements AfterContentChecked , AfterContentInit , OnDestroy { /** Query list of all tab links of the tab navigation. */ abstract override _items : QueryList < SbbPaginatedTabHeaderItem & { active : boolean ; } > ; constructor ( elementRef , ngZone , changeDetectorRef , viewportRuler , @ Optional ( ) @ Inject ( ANIMATION_MODULE_TYPE ) animationMode ? ) { super ( elementRef , changeDetectorRef , viewportRuler , ngZone , animationMode ) ; } protected _itemSelected ( ) { } override ngAfterContentInit ( ) { this . _items . changes . pipe ( startWith ( null ) , takeUntil ( this . _destroyed ) ) . subscribe ( ( ) => { this . updateActiveLink ( ) ; } ) ; super . ngAfterContentInit ( ) ; } /** Notifies the component that the active link has been changed. */ updateActiveLink ( ) { if ( ! this . _items ) { return ; } const items = this . _items . toArray ( ) ; for ( let i = 0 ; i < items . length ; i ++ ) { if ( items [ i ] . active ) { this . selectedIndex = i ; this . _changeDetectorRef . markForCheck ( ) ; return ; } } this . selectedIndex = - 1 ; } } /**
 * Navigation component matching the styles of the tab group header.
 * Provides anchored navigation with animated ink bar.
 */ @ Component ( { selector : '[sbb-tab-nav-bar]' , exportAs : 'sbbTabNavBar, sbbTabNav' , templateUrl : 'tab-nav-bar.html' , styleUrls : [ 'tab-nav-bar.css' ] , host : { class : 'sbb-tab-nav-bar sbb-tab-header' , } , encapsulation : ViewEncapsulation . None , changeDetection : ChangeDetectionStrategy . Default , } ) export class SbbTabNav extends _SbbTabNavBase { @ ContentChildren ( forwardRef ( ( ) => SbbTabLink ) , { descendants : true } ) _items : QueryList < SbbTabLink > ; @ ViewChild ( 'tabListContainer' , { static : true } ) _tabListContainer : ElementRef ; @ ViewChild ( 'tabList' , { static : true } ) _tabList : ElementRef ; constructor ( elementRef , ngZone , changeDetectorRef , viewportRuler , @ Optional ( ) @ Inject ( ANIMATION_MODULE_TYPE ) animationMode ? ) { super ( elementRef , ngZone , changeDetectorRef , viewportRuler , animationMode ) ; } } const _SbbTabLinkMixinBase = mixinTabIndex ( mixinDisabled ( class { } ) ) ; /** Base class with all of the `SbbTabLink` functionality. */ @ Directive ( ) export class _SbbTabLinkBase extends _SbbTabLinkMixinBase implements AfterViewInit , OnDestroy , CanDisable , HasTabIndex , FocusableOption { /** Whether the tab link is active or not. */ protected _isActive : boolean = false ; /** Whether the link is active. */ @ Input ( ) get active ( ) : boolean { return this . _isActive ; } set active ( value ) { const newValue = coerceBooleanProperty ( value ) ; if ( newValue !== this . _isActive ) { this . _isActive = newValue ; this . _tabNavBar . updateActiveLink ( ) ; } } constructor ( private _tabNavBar , docs-private public elementRef , @ Attribute ( 'tabindex' ) tabIndex , private _focusMonitor ) { super ( ) ; this . tabIndex = parseInt ( tabIndex , 10 ) || 0 ; } /** Focuses the tab link. */ focus ( ) { this . elementRef . nativeElement . focus ( ) ; } ngAfterViewInit ( ) { this . _focusMonitor . monitor ( this . elementRef ) ; } ngOnDestroy ( ) { this . _focusMonitor . stopMonitoring ( this . elementRef ) ; } } /**
 * Link inside of a `sbb-tab-nav-bar`.
 */ @ Directive ( { selector : '[sbb-tab-link], [sbbTabLink]' , exportAs : 'sbbTabLink' , inputs : [ 'disabled' , 'tabIndex' ] , host : { class : 'sbb-tab-link sbb-link-reset sbb-focus-indicator' , '[attr.aria-current]' : 'active ? "page" : null' , '[attr.aria-disabled]' : 'disabled' , '[attr.tabIndex]' : 'tabIndex' , '[class.sbb-tab-disabled]' : 'disabled' , '[class.sbb-tab-label-active]' : 'active' , } , } ) export class SbbTabLink extends _SbbTabLinkBase { constructor ( tabNavBar , elementRef , @ Attribute ( 'tabindex' ) tabIndex , focusMonitor ) { super ( tabNavBar , elementRef , tabIndex , focusMonitor ) ; } }