diff --git a/libs/components/tabs/src/lib/modules/vertical-tabset/fixtures/vertical-tabs-fixtures.module.ts b/libs/components/tabs/src/lib/modules/vertical-tabset/fixtures/vertical-tabs-fixtures.module.ts index 1d2d6337cd..267ac1c315 100644 --- a/libs/components/tabs/src/lib/modules/vertical-tabset/fixtures/vertical-tabs-fixtures.module.ts +++ b/libs/components/tabs/src/lib/modules/vertical-tabset/fixtures/vertical-tabs-fixtures.module.ts @@ -9,6 +9,7 @@ import { VerticalTabsetEmptyGroupTestComponent } from './vertical-tabset-empty-g import { VerticalTabsetWithNgForTestComponent } from './vertical-tabset-ngfor.component.fixture'; import { VerticalTabsetNoActiveTestComponent } from './vertical-tabset-no-active.component.fixture'; import { VerticalTabsetNoGroupTestComponent } from './vertical-tabset-no-group.component.fixture'; +import { VerticalTabsetProgrammaticTestComponent } from './vertical-tabset-programmatic.component'; import { VerticalTabsetTestComponent } from './vertical-tabset.component.fixture'; @NgModule({ @@ -24,12 +25,14 @@ import { VerticalTabsetTestComponent } from './vertical-tabset.component.fixture FormsModule, NoopAnimationsModule, SkyVerticalTabsetModule, + VerticalTabsetProgrammaticTestComponent, ], exports: [ VerticalTabsetTestComponent, VerticalTabsetEmptyGroupTestComponent, VerticalTabsetNoGroupTestComponent, VerticalTabsetNoActiveTestComponent, + VerticalTabsetProgrammaticTestComponent, VerticalTabsetWithNgForTestComponent, ], }) diff --git a/libs/components/tabs/src/lib/modules/vertical-tabset/fixtures/vertical-tabset-programmatic.component.ts b/libs/components/tabs/src/lib/modules/vertical-tabset/fixtures/vertical-tabset-programmatic.component.ts new file mode 100644 index 0000000000..0991f7567b --- /dev/null +++ b/libs/components/tabs/src/lib/modules/vertical-tabset/fixtures/vertical-tabset-programmatic.component.ts @@ -0,0 +1,22 @@ +import { Component } from '@angular/core'; + +import { SkyVerticalTabsetModule } from '../vertical-tabset.module'; + +@Component({ + standalone: true, + template: ` + + Tab 1 content + + + Tab 2 content + + + Tab 3 content + + `, + imports: [SkyVerticalTabsetModule], +}) +export class VerticalTabsetProgrammaticTestComponent { + public activeIndex = 0; +} diff --git a/libs/components/tabs/src/lib/modules/vertical-tabset/fixtures/vertical-tabset.component.fixture.ts b/libs/components/tabs/src/lib/modules/vertical-tabset/fixtures/vertical-tabset.component.fixture.ts index 174cbd0021..2bbdbaf846 100644 --- a/libs/components/tabs/src/lib/modules/vertical-tabset/fixtures/vertical-tabset.component.fixture.ts +++ b/libs/components/tabs/src/lib/modules/vertical-tabset/fixtures/vertical-tabset.component.fixture.ts @@ -9,7 +9,7 @@ import { SkyVerticalTabsetComponent } from '../vertical-tabset.component'; styleUrls: ['./vertical-tabset.component.fixture.scss'], }) export class VerticalTabsetTestComponent { - public active = true; + public active: boolean | undefined = true; public group1Open = true; public group1Disabled = false; diff --git a/libs/components/tabs/src/lib/modules/vertical-tabset/vertical-tab.component.ts b/libs/components/tabs/src/lib/modules/vertical-tabset/vertical-tab.component.ts index a6dc67d1af..7aaa1f168b 100644 --- a/libs/components/tabs/src/lib/modules/vertical-tabset/vertical-tab.component.ts +++ b/libs/components/tabs/src/lib/modules/vertical-tabset/vertical-tab.component.ts @@ -41,9 +41,21 @@ let nextId = 0; export class SkyVerticalTabComponent implements OnInit, OnDestroy { /** * Whether the tab is active when the tabset loads. + * @default false */ @Input() - public active: boolean | undefined = false; + public set active(value: boolean | undefined) { + if (value !== this.#_active) { + this.#_active = value ?? false; + this.#tabsetService.activateTab(this); + } + } + + public get active(): boolean { + return this.#_active; + } + + #_active = false; /** * The HTML element ID of the element that contains diff --git a/libs/components/tabs/src/lib/modules/vertical-tabset/vertical-tabset.component.spec.ts b/libs/components/tabs/src/lib/modules/vertical-tabset/vertical-tabset.component.spec.ts index b7d0fbc4c7..44d6b51ba7 100644 --- a/libs/components/tabs/src/lib/modules/vertical-tabset/vertical-tabset.component.spec.ts +++ b/libs/components/tabs/src/lib/modules/vertical-tabset/vertical-tabset.component.spec.ts @@ -14,6 +14,7 @@ import { VerticalTabsetEmptyGroupTestComponent } from './fixtures/vertical-tabse import { VerticalTabsetWithNgForTestComponent } from './fixtures/vertical-tabset-ngfor.component.fixture'; import { VerticalTabsetNoActiveTestComponent } from './fixtures/vertical-tabset-no-active.component.fixture'; import { VerticalTabsetNoGroupTestComponent } from './fixtures/vertical-tabset-no-group.component.fixture'; +import { VerticalTabsetProgrammaticTestComponent } from './fixtures/vertical-tabset-programmatic.component'; import { VerticalTabsetTestComponent } from './fixtures/vertical-tabset.component.fixture'; import { SkyVerticalTabMediaQueryService } from './vertical-tab-media-query.service'; import { SkyVerticalTabsetComponent } from './vertical-tabset.component'; @@ -26,7 +27,7 @@ function getVisibleTabContentPane( ): HTMLElement[] { return Array.from( fixture.nativeElement.querySelectorAll( - '.sky-vertical-tab-content-pane:not(.sky-vertical-tab-hidden)', + '.sky-vertical-tabset-content .sky-vertical-tab-content-pane:not(.sky-vertical-tab-hidden)', ), ); } @@ -453,6 +454,37 @@ describe('Vertical tabset component', () => { expect(elementHasFocus(tabButtons[0])).toBeTrue(); }); + it('should set a tab active=false when set to undefined', () => { + const fixture = createTestComponent(); + + fixture.componentInstance.active = undefined; + fixture.detectChanges(); + + const tabButtons = getAllTabButtons(fixture); + expect(elementHasFocus(tabButtons[0])).toBeFalse(); + + const visibleTabs = getVisibleTabContentPane(fixture); + expect(visibleTabs.length).toBe(0); + }); + + it('should programmatically select tabs', () => { + const fixture = TestBed.createComponent( + VerticalTabsetProgrammaticTestComponent, + ); + + // Activate first tab. + fixture.componentInstance.activeIndex = 0; + fixture.detectChanges(); + + // Activate second tab. + fixture.componentInstance.activeIndex = 1; + fixture.detectChanges(); + + const visibleTabs = getVisibleTabContentPane(fixture); + expect(visibleTabs.length).toBe(1); + expect(visibleTabs[0]).toHaveText('Tab 2 content'); + }); + it("should focus the active tab's group when the tabs container is focused and the tab's group is collapsed", fakeAsync(() => { mockQueryService.fire(SkyMediaBreakpoints.lg); const fixture = createTestComponent();