+
+
+
+
diff --git a/src/modules/vertical-tabset/vertical-tab.component.ts b/src/modules/vertical-tabset/vertical-tab.component.ts
index 3ee814a04..1d877452c 100644
--- a/src/modules/vertical-tabset/vertical-tab.component.ts
+++ b/src/modules/vertical-tabset/vertical-tab.component.ts
@@ -21,6 +21,9 @@ import { SkyVerticalTabsetService } from './vertical-tabset.service';
})
export class SkyVerticalTabComponent implements OnInit, OnDestroy {
+ @Input()
+ public tabId: string;
+
@Input()
public active: boolean = false;
@@ -33,6 +36,31 @@ export class SkyVerticalTabComponent implements OnInit, OnDestroy {
@Input()
public disabled: boolean = false;
+ @Input()
+ public get ariaControls(): string {
+ return this.isMobile ? undefined : this._ariaControls;
+ }
+ public set ariaControls(value: string) {
+ this._ariaControls = value;
+ }
+
+ @Input()
+ public get ariaRole(): string {
+ if (this.isMobile) {
+ return undefined;
+ }
+ return this._ariaRole || 'tab';
+ }
+ public set ariaRole(value: string) {
+ this._ariaRole = value;
+ }
+
+ @Input()
+ public ariaInvalid: boolean;
+
+ @Input()
+ public ariaRequired: boolean;
+
@Input()
public get showTabRightArrow() {
return this._showTabRightArrow && this.tabsetService.isMobile();
@@ -47,6 +75,9 @@ export class SkyVerticalTabComponent implements OnInit, OnDestroy {
@ViewChild('tabContentWrapper')
public tabContent: ElementRef;
+ private isMobile = false;
+ private _ariaControls: string;
+ private _ariaRole: string;
private _showTabRightArrow: boolean = false;
private _mobileSubscription = new Subject();
@@ -55,8 +86,14 @@ export class SkyVerticalTabComponent implements OnInit, OnDestroy {
private changeRef: ChangeDetectorRef) {}
public ngOnInit() {
+ this.isMobile = this.tabsetService.isMobile();
+ this.changeRef.detectChanges();
+
this.tabsetService.switchingMobile
- .subscribe((mobile: boolean) => this.changeRef.detectChanges());
+ .subscribe((mobile: boolean) => {
+ this.isMobile = mobile;
+ this.changeRef.detectChanges();
+ });
this.tabsetService.addTab(this);
}
diff --git a/src/modules/vertical-tabset/vertical-tabset.component.html b/src/modules/vertical-tabset/vertical-tabset.component.html
index dbb46804d..225457fc4 100644
--- a/src/modules/vertical-tabset/vertical-tabset.component.html
+++ b/src/modules/vertical-tabset/vertical-tabset.component.html
@@ -1,19 +1,20 @@
diff --git a/src/modules/vertical-tabset/vertical-tabset.component.spec.ts b/src/modules/vertical-tabset/vertical-tabset.component.spec.ts
index 09d618a9c..b13520ec4 100644
--- a/src/modules/vertical-tabset/vertical-tabset.component.spec.ts
+++ b/src/modules/vertical-tabset/vertical-tabset.component.spec.ts
@@ -1,22 +1,34 @@
-import { TestBed } from '@angular/core/testing';
-import { SkyVerticalTabsFixturesModule } from './fixtures/vertical-tabs-fixtures.module';
-import { SkyVerticalTabsetComponent } from '../vertical-tabset/vertical-tabset.component';
-import { VerticalTabsetTestComponent } from './fixtures/vertical-tabset.component.fixture';
+import {
+ TestBed
+} from '@angular/core/testing';
+
+import {
+ SkyVerticalTabsetComponent
+} from '../vertical-tabset/vertical-tabset.component';
+import {
+ SkyMediaQueryService,
+ SkyMediaBreakpoints
+} from '../media-queries';
+import {
+ SkyVerticalTabsFixturesModule
+} from './fixtures/vertical-tabs-fixtures.module';
+import {
+ VerticalTabsetTestComponent
+} from './fixtures/vertical-tabset.component.fixture';
import {
VerticalTabsetNoActiveTestComponent
} from './fixtures/vertical-tabset-no-active.component.fixture';
-
import {
VerticalTabsetEmptyGroupTestComponent
} from './fixtures/vertical-tabset-empty-group.component';
-
import {
VerticalTabsetNoGroupTestComponent
} from './fixtures/vertical-tabset-no-group.component.fixture';
-import { MockSkyMediaQueryService } from './../testing/mocks/mock-media-query.service';
-import { SkyMediaQueryService, SkyMediaBreakpoints } from '../media-queries';
+import {
+ MockSkyMediaQueryService
+} from '../testing/mocks/mock-media-query.service';
let mockQueryService = new MockSkyMediaQueryService();
@@ -97,6 +109,22 @@ describe('Vertical tabset component', () => {
expect(openGroup[0].textContent.trim()).toBe('Group 2');
});
+ it('should pass through aria inputs, id, and set role', () => {
+ mockQueryService.current = SkyMediaBreakpoints.lg;
+ let fixture = createTestComponent();
+ let el = fixture.nativeElement as HTMLElement;
+
+ fixture.detectChanges();
+
+ // check open tab content
+ const tab = el.querySelector('sky-vertical-tab a');
+ expect(tab.id).toBe('some-tab');
+ expect(tab.getAttribute('aria-controls')).toBe('some-div');
+ expect(tab.getAttribute('aria-invalid')).toBe('true');
+ expect(tab.getAttribute('aria-required')).toBe('true');
+ expect(tab.getAttribute('role')).toBe('tab');
+ });
+
it('check closing of group', () => {
mockQueryService.current = SkyMediaBreakpoints.lg;
let fixture = createTestComponent();
@@ -227,6 +255,24 @@ describe('Vertical tabset component', () => {
expect(visibleTabs[0].textContent.trim()).toBe('Group 1 Tab 2 content');
});
+ it('tabs should not have tab aria associations and roles in mobile view', () => {
+ mockQueryService.current = SkyMediaBreakpoints.xs;
+ let fixture = createTestComponent();
+ let el = fixture.nativeElement;
+
+ fixture.detectChanges();
+
+ // click show tabs
+ const showTabsButton = el.querySelector('.sky-vertical-tabset-show-tabs-btn');
+ showTabsButton.click();
+
+ fixture.detectChanges();
+
+ const visibleTab = el.querySelector('.sky-vertical-tab');
+ expect(visibleTab.getAttribute('aria-controls')).toBeFalsy();
+ expect(visibleTab.getAttribute('role')).toBeFalsy();
+ });
+
it('should hide tabs when switching from widescreen to mobile', () => {
mockQueryService.current = SkyMediaBreakpoints.lg;
let fixture = createTestComponent();
diff --git a/src/modules/vertical-tabset/vertical-tabset.component.ts b/src/modules/vertical-tabset/vertical-tabset.component.ts
index f1e3ec628..0d615cfef 100644
--- a/src/modules/vertical-tabset/vertical-tabset.component.ts
+++ b/src/modules/vertical-tabset/vertical-tabset.component.ts
@@ -61,6 +61,17 @@ export class SkyVerticalTabsetComponent implements OnInit, AfterViewChecked, OnD
@Input()
public showTabsText: string = this.resources.getString('vertical_tabs_show_tabs_text');
+ @Input()
+ public get ariaRole(): string {
+ if (this.isMobile) {
+ return undefined;
+ }
+ return this._ariaRole || 'tablist';
+ }
+ public set ariaRole(value: string) {
+ this._ariaRole = value;
+ }
+
@Output()
public activeChange = new EventEmitter
();
@@ -70,7 +81,9 @@ export class SkyVerticalTabsetComponent implements OnInit, AfterViewChecked, OnD
@ViewChild('skySideContent')
public content: ElementRef;
+ private isMobile = false;
private _ngUnsubscribe = new Subject();
+ private _ariaRole: string;
constructor(
public tabService: SkyVerticalTabsetService,
@@ -87,10 +100,15 @@ export class SkyVerticalTabsetComponent implements OnInit, AfterViewChecked, OnD
this.tabService.switchingMobile
.takeUntil(this._ngUnsubscribe)
- .subscribe((mobile: boolean) => this.changeRef.detectChanges());
+ .subscribe((mobile: boolean) => {
+ this.isMobile = mobile;
+ this.changeRef.detectChanges();
+ });
if (this.tabService.isMobile()) {
+ this.isMobile = true;
this.tabService.animationVisibleState = VISIBLE_STATE;
+ this.changeRef.detectChanges();
}
}