@@ -17,6 +17,7 @@ import {
1717 INJECTOR ,
1818 input ,
1919 signal ,
20+ untracked ,
2021 viewChild
2122} from '@angular/core' ;
2223import { RouterLink } from '@angular/router' ;
@@ -29,6 +30,7 @@ import { SiResizeObserverModule } from '@siemens/element-ng/resize-observer';
2930import { SiTabBadgeComponent } from './si-tab-badge.component' ;
3031import { SiTabBaseDirective } from './si-tab-base.directive' ;
3132import { SiTabLinkComponent } from './si-tab-link.component' ;
33+ import { SiTabComponent } from './si-tab.component' ;
3234import { SI_TABSET } from './si-tabs-tokens' ;
3335
3436/**
@@ -94,6 +96,30 @@ export class SiTabsetComponent {
9496 }
9597
9698 constructor ( ) {
99+ // Per the ARIA tabs pattern, at least one tab should be active. If the app
100+ // does not provide an active tab, activate the first non-disabled content
101+ // tab so the tablist stays keyboard reachable.
102+ effect ( ( ) => {
103+ const tabs = this . tabPanels ( ) ;
104+ const hasActiveTab = ! ! this . activeTab ( ) ;
105+ untracked ( ( ) => {
106+ if ( hasActiveTab ) {
107+ return ;
108+ }
109+ const tabToActivate = tabs . find ( tab => {
110+ if ( tab . disabledTab ( ) ) {
111+ return false ;
112+ }
113+ if ( tab instanceof SiTabComponent ) {
114+ const canActivate = tab . canActivate ( ) ;
115+ return canActivate ? canActivate ( ) : true ;
116+ }
117+ return true ;
118+ } ) ;
119+ tabToActivate ?. selectTab ( ) ;
120+ } ) ;
121+ } ) ;
122+
97123 effect ( ( ) => {
98124 if ( this . showMenuButton ( ) && this . activeTab ( ) ) {
99125 // wait for menu button to render on DOM
0 commit comments