@skyux/tabs 9.21.3 → 9.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/documentation.json +979 -782
- package/esm2022/lib/modules/vertical-tabset/vertical-tab.component.mjs +24 -25
- package/esm2022/lib/modules/vertical-tabset/vertical-tabset-adapter.service.mjs +56 -2
- package/esm2022/lib/modules/vertical-tabset/vertical-tabset-group-message.mjs +2 -0
- package/esm2022/lib/modules/vertical-tabset/vertical-tabset-group.component.mjs +66 -22
- package/esm2022/lib/modules/vertical-tabset/vertical-tabset-group.service.mjs +17 -0
- package/esm2022/lib/modules/vertical-tabset/vertical-tabset.component.mjs +24 -9
- package/esm2022/lib/modules/vertical-tabset/vertical-tabset.service.mjs +33 -2
- package/fesm2022/skyux-tabs.mjs +205 -55
- package/fesm2022/skyux-tabs.mjs.map +1 -1
- package/lib/modules/vertical-tabset/vertical-tab.component.d.ts +6 -2
- package/lib/modules/vertical-tabset/vertical-tabset-adapter.service.d.ts +4 -0
- package/lib/modules/vertical-tabset/vertical-tabset-group-message.d.ts +3 -0
- package/lib/modules/vertical-tabset/vertical-tabset-group.component.d.ts +6 -5
- package/lib/modules/vertical-tabset/vertical-tabset-group.service.d.ts +11 -0
- package/lib/modules/vertical-tabset/vertical-tabset.component.d.ts +7 -0
- package/lib/modules/vertical-tabset/vertical-tabset.service.d.ts +4 -0
- package/package.json +9 -9
package/fesm2022/skyux-tabs.mjs
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import * as i4 from '@angular/common';
|
|
2
|
-
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { DOCUMENT, CommonModule } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { NgModule, Injectable, Component, ChangeDetectionStrategy, Optional, Input, ViewChild, HostListener, ContentChildren, EventEmitter, Output, ViewEncapsulation,
|
|
4
|
+
import { NgModule, Injectable, inject, Component, ChangeDetectionStrategy, Optional, Input, ViewChild, HostListener, ContentChildren, EventEmitter, Output, ViewEncapsulation, HostBinding, Pipe } from '@angular/core';
|
|
5
5
|
import { SkyCheckboxModule } from '@skyux/forms';
|
|
6
6
|
import * as i7 from '@skyux/theme';
|
|
7
7
|
import { SkyThemeModule } from '@skyux/theme';
|
|
8
8
|
import * as i1 from '@skyux/core';
|
|
9
|
-
import { SkyMediaBreakpoints, SkyMediaQueryService, SkyIdModule, SkyResizeObserverMediaQueryService, SkyLayoutHostService } from '@skyux/core';
|
|
9
|
+
import { SkyMediaBreakpoints, SkyMediaQueryService, SkyIdService, SkyIdModule, SkyResizeObserverMediaQueryService, SkyLayoutHostService } from '@skyux/core';
|
|
10
10
|
import * as i6 from '@skyux/indicators';
|
|
11
11
|
import { SkyIconModule, SkyExpansionIndicatorModule, SkyStatusIndicatorModule } from '@skyux/indicators';
|
|
12
12
|
import * as i3 from '@skyux/i18n';
|
|
13
13
|
import { SkyLibResourcesService, getLibStringForLocale, SkyI18nModule, SKY_LIB_RESOURCES_PROVIDERS } from '@skyux/i18n';
|
|
14
|
-
import { ReplaySubject,
|
|
14
|
+
import { ReplaySubject, Subject, BehaviorSubject, combineLatest, race } from 'rxjs';
|
|
15
15
|
import { takeUntil, take, distinctUntilChanged } from 'rxjs/operators';
|
|
16
16
|
import { skyAnimationSlide } from '@skyux/animations';
|
|
17
17
|
import { trigger, transition, style, animate } from '@angular/animations';
|
|
@@ -143,8 +143,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImpor
|
|
|
143
143
|
type: Injectable
|
|
144
144
|
}], ctorParameters: function () { return []; } });
|
|
145
145
|
|
|
146
|
+
/**
|
|
147
|
+
* @internal
|
|
148
|
+
*/
|
|
149
|
+
class SkyVerticalTabsetGroupService {
|
|
150
|
+
constructor() {
|
|
151
|
+
this.messageStream = new Subject();
|
|
152
|
+
}
|
|
153
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: SkyVerticalTabsetGroupService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
154
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: SkyVerticalTabsetGroupService }); }
|
|
155
|
+
}
|
|
156
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: SkyVerticalTabsetGroupService, decorators: [{
|
|
157
|
+
type: Injectable
|
|
158
|
+
}] });
|
|
159
|
+
|
|
160
|
+
const VERTICAL_TABSET_BUTTON_SELECTOR = '.sky-vertical-tabset-button';
|
|
161
|
+
const VERTICAL_TABSET_BUTTON_DISABLED_SELECTOR = `${VERTICAL_TABSET_BUTTON_SELECTOR}-disabled`;
|
|
146
162
|
class SkyVerticalTabsetAdapterService {
|
|
147
163
|
#renderer;
|
|
164
|
+
#document = inject(DOCUMENT);
|
|
148
165
|
constructor(rendererFactory) {
|
|
149
166
|
this.#renderer = rendererFactory.createRenderer(undefined, null);
|
|
150
167
|
}
|
|
@@ -181,6 +198,56 @@ class SkyVerticalTabsetAdapterService {
|
|
|
181
198
|
}
|
|
182
199
|
this.#renderer.addClass(nativeEl, newClass);
|
|
183
200
|
}
|
|
201
|
+
focusButton(elRef) {
|
|
202
|
+
return this.#focusButtonEl(elRef?.nativeElement);
|
|
203
|
+
}
|
|
204
|
+
focusFirstButton(tabGroups) {
|
|
205
|
+
const tabGroupsEl = tabGroups?.nativeElement;
|
|
206
|
+
if (tabGroupsEl) {
|
|
207
|
+
const firstButtonEl = tabGroupsEl.querySelector(VERTICAL_TABSET_BUTTON_SELECTOR);
|
|
208
|
+
if (firstButtonEl) {
|
|
209
|
+
firstButtonEl.focus();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
focusNextButton(tabGroups) {
|
|
214
|
+
this.#focusSiblingButton(tabGroups);
|
|
215
|
+
}
|
|
216
|
+
focusPreviousButton(tabGroups) {
|
|
217
|
+
this.#focusSiblingButton(tabGroups, true);
|
|
218
|
+
}
|
|
219
|
+
#focusSiblingButton(tabGroups, previous) {
|
|
220
|
+
if (tabGroups) {
|
|
221
|
+
const focusedEl = this.#document.activeElement;
|
|
222
|
+
if (focusedEl?.matches(VERTICAL_TABSET_BUTTON_SELECTOR)) {
|
|
223
|
+
const tabGroupsEl = tabGroups.nativeElement;
|
|
224
|
+
const buttonEls = Array.from(tabGroupsEl.querySelectorAll(VERTICAL_TABSET_BUTTON_SELECTOR));
|
|
225
|
+
if (previous) {
|
|
226
|
+
buttonEls.reverse();
|
|
227
|
+
}
|
|
228
|
+
const focusedIndex = buttonEls.indexOf(focusedEl);
|
|
229
|
+
for (let i = 1, n = buttonEls.length; i < n; i++) {
|
|
230
|
+
// Offset the index of the next button from the index of the
|
|
231
|
+
// currently focused button, circling back to the first button
|
|
232
|
+
// when the end of the list is reached.
|
|
233
|
+
const offset = (i + focusedIndex) % n;
|
|
234
|
+
if (this.#focusButtonEl(buttonEls[offset])) {
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
#focusButtonEl(el) {
|
|
242
|
+
if (el && !el.matches(VERTICAL_TABSET_BUTTON_DISABLED_SELECTOR)) {
|
|
243
|
+
el.focus();
|
|
244
|
+
return this.#elHasFocus(el);
|
|
245
|
+
}
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
#elHasFocus(el) {
|
|
249
|
+
return !!el && el === this.#document.activeElement;
|
|
250
|
+
}
|
|
184
251
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: SkyVerticalTabsetAdapterService, deps: [{ token: i0.RendererFactory2 }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
185
252
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: SkyVerticalTabsetAdapterService }); }
|
|
186
253
|
}
|
|
@@ -194,10 +261,12 @@ const HIDDEN_STATE = 'void';
|
|
|
194
261
|
* @internal
|
|
195
262
|
*/
|
|
196
263
|
class SkyVerticalTabsetService {
|
|
264
|
+
#groups;
|
|
197
265
|
#contentAdded;
|
|
198
266
|
#tabsVisible;
|
|
199
267
|
#isMobile;
|
|
200
268
|
#mediaQueryService;
|
|
269
|
+
#adapterSvc;
|
|
201
270
|
constructor(mediaQueryService) {
|
|
202
271
|
this.activeIndex = undefined;
|
|
203
272
|
this.hidingTabs = new BehaviorSubject(false);
|
|
@@ -208,9 +277,11 @@ class SkyVerticalTabsetService {
|
|
|
208
277
|
this.tabs = [];
|
|
209
278
|
this.tabAdded = new Subject();
|
|
210
279
|
this.tabClicked = new ReplaySubject(1);
|
|
280
|
+
this.#groups = [];
|
|
211
281
|
this.#contentAdded = false;
|
|
212
282
|
this.#tabsVisible = false;
|
|
213
283
|
this.#isMobile = false;
|
|
284
|
+
this.#adapterSvc = inject(SkyVerticalTabsetAdapterService);
|
|
214
285
|
this.#mediaQueryService = mediaQueryService;
|
|
215
286
|
this.#mediaQueryService.subscribe((breakpoint) => {
|
|
216
287
|
const nowMobile = breakpoint === SkyMediaBreakpoints.xs;
|
|
@@ -267,6 +338,15 @@ class SkyVerticalTabsetService {
|
|
|
267
338
|
}
|
|
268
339
|
}
|
|
269
340
|
}
|
|
341
|
+
addGroup(group) {
|
|
342
|
+
this.#groups.push(group);
|
|
343
|
+
}
|
|
344
|
+
destroyGroup(group) {
|
|
345
|
+
const groupIndex = this.#groups.indexOf(group);
|
|
346
|
+
if (groupIndex >= 0) {
|
|
347
|
+
this.#groups.splice(groupIndex, 1);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
270
350
|
activateTab(tab) {
|
|
271
351
|
// deactivate active tab
|
|
272
352
|
const activeTab = this.tabs.find((t) => t.index === this.activeIndex);
|
|
@@ -317,6 +397,23 @@ class SkyVerticalTabsetService {
|
|
|
317
397
|
this.animationContentVisibleState = HIDDEN_STATE;
|
|
318
398
|
this.showingTabs.next(true);
|
|
319
399
|
}
|
|
400
|
+
focusActiveTab(tabGroups) {
|
|
401
|
+
let focused = false;
|
|
402
|
+
const activeTab = this.tabs.find((tab) => tab.active);
|
|
403
|
+
if (activeTab) {
|
|
404
|
+
const parentGroup = this.#findParentGroup(activeTab);
|
|
405
|
+
const buttonToFocus = parentGroup && !parentGroup.open
|
|
406
|
+
? parentGroup.groupHeadingButton
|
|
407
|
+
: activeTab.tabButton;
|
|
408
|
+
focused = this.#adapterSvc.focusButton(buttonToFocus);
|
|
409
|
+
}
|
|
410
|
+
if (!focused) {
|
|
411
|
+
this.#adapterSvc.focusFirstButton(tabGroups);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
#findParentGroup(tab) {
|
|
415
|
+
return this.#groups.find((group) => group.tabs?.some((groupTab) => tab === groupTab));
|
|
416
|
+
}
|
|
320
417
|
#destroyContent() {
|
|
321
418
|
if (this.content) {
|
|
322
419
|
this.content.nativeElement.innerHTML = '';
|
|
@@ -469,6 +566,9 @@ class SkyVerticalTabComponent {
|
|
|
469
566
|
*/
|
|
470
567
|
this.errorIndicator = false;
|
|
471
568
|
this.isMobile = false;
|
|
569
|
+
this.groupService = inject(SkyVerticalTabsetGroupService, {
|
|
570
|
+
optional: true,
|
|
571
|
+
});
|
|
472
572
|
this.#_ariaRole = 'tab';
|
|
473
573
|
this.#_contentRendered = false;
|
|
474
574
|
this.#mobileSubscription = new Subject();
|
|
@@ -508,14 +608,6 @@ class SkyVerticalTabComponent {
|
|
|
508
608
|
this.#ngUnsubscribe.complete();
|
|
509
609
|
this.#tabsetService.destroyTab(this);
|
|
510
610
|
}
|
|
511
|
-
tabIndex() {
|
|
512
|
-
if (!this.disabled) {
|
|
513
|
-
return 0;
|
|
514
|
-
}
|
|
515
|
-
else {
|
|
516
|
-
return -1;
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
611
|
activateTab() {
|
|
520
612
|
if (!this.disabled) {
|
|
521
613
|
this.active = true;
|
|
@@ -523,19 +615,19 @@ class SkyVerticalTabComponent {
|
|
|
523
615
|
this.#changeRef.markForCheck();
|
|
524
616
|
}
|
|
525
617
|
}
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
618
|
+
focusButton() {
|
|
619
|
+
this.#adapterService.focusButton(this.tabButton);
|
|
620
|
+
}
|
|
621
|
+
tabButtonActivate(event) {
|
|
622
|
+
this.activateTab();
|
|
623
|
+
event.stopPropagation();
|
|
624
|
+
}
|
|
625
|
+
tabButtonArrowLeft(event) {
|
|
626
|
+
if (this.groupService) {
|
|
627
|
+
this.groupService.messageStream.next({
|
|
628
|
+
messageType: 'focus',
|
|
629
|
+
});
|
|
630
|
+
event.preventDefault();
|
|
539
631
|
}
|
|
540
632
|
}
|
|
541
633
|
onWindowResize() {
|
|
@@ -564,7 +656,7 @@ class SkyVerticalTabComponent {
|
|
|
564
656
|
provide: SkyMediaQueryService,
|
|
565
657
|
useExisting: SkyVerticalTabMediaQueryService,
|
|
566
658
|
},
|
|
567
|
-
], viewQueries: [{ propertyName: "tabContent", first: true, predicate: ["tabContentWrapper"], descendants: true }], ngImport: i0, template: "<a\n class=\"sky-vertical-tab\"\n [attr.aria-controls]=\"isMobile ? null : ariaControls || tabContentPane.id\"\n [attr.aria-selected]=\"active\"\n [attr.id]=\"tabId\"\n [attr.role]=\"isMobile ? undefined : ariaRole\"\n [ngClass]=\"{\n 'sky-vertical-tab-active': active,\n 'sky-vertical-
|
|
659
|
+
], viewQueries: [{ propertyName: "tabButton", first: true, predicate: ["tabButton"], descendants: true }, { propertyName: "tabContent", first: true, predicate: ["tabContentWrapper"], descendants: true }], ngImport: i0, template: "<a\n class=\"sky-vertical-tab sky-vertical-tabset-button\"\n [attr.aria-controls]=\"isMobile ? null : ariaControls || tabContentPane.id\"\n [attr.aria-disabled]=\"disabled || undefined\"\n [attr.aria-selected]=\"active\"\n [attr.id]=\"tabId\"\n [attr.role]=\"isMobile ? undefined : ariaRole\"\n [ngClass]=\"{\n 'sky-vertical-tab-active': active,\n 'sky-vertical-tabset-button-disabled': disabled,\n 'sky-font-deemphasized': disabled,\n 'sky-deemphasized': disabled\n }\"\n [tabIndex]=\"-1\"\n (click)=\"activateTab()\"\n (keyup.arrowleft)=\"tabButtonArrowLeft($event)\"\n (keyup.enter)=\"tabButtonActivate($event)\"\n (keyup.space)=\"tabButtonActivate($event)\"\n #tabButton\n>\n <div class=\"sky-vertical-tab-display\">\n <div class=\"sky-vertical-tab-heading\">\n <span class=\"sky-vertical-tab-heading-value\">{{ tabHeading }}</span>\n <span\n class=\"sky-vertical-tab-count\"\n *ngIf=\"tabHeaderCount || tabHeaderCount === 0\"\n >\n ({{ tabHeaderCount }})\n </span>\n </div>\n <sky-status-indicator\n *ngIf=\"errorIndicator\"\n class=\"sky-vertical-tab-heading-error\"\n descriptionType=\"error\"\n indicatorType=\"danger\"\n ></sky-status-indicator>\n <sky-icon\n *ngIf=\"isMobile && showTabRightArrow\"\n class=\"sky-vertical-tab-right-arrow\"\n icon=\"chevron-right\"\n />\n </div>\n</a>\n\n<div #tabContentWrapper>\n <div\n class=\"sky-vertical-tab-content-pane\"\n role=\"tabpanel\"\n tabindex=\"0\"\n skyId\n [attr.aria-labelledby]=\"tabId\"\n [ngClass]=\"{ 'sky-vertical-tab-hidden': !active }\"\n #tabContentPane\n >\n <ng-content />\n\n <div></div>\n </div>\n</div>\n", styles: [".sky-vertical-tab{cursor:pointer;padding:7px 0 7px 10px;margin:5px 0 5px 10px;display:flex;text-decoration:none}.sky-vertical-tab:not(.sky-deemphasized){color:#212327}.sky-vertical-tab:hover{background-color:#eeeeef}.sky-vertical-tab:focus-visible{outline:thin dotted;outline:-webkit-focus-ring-color auto 5px}.sky-vertical-tab:hover .sky-vertical-tab-right-arrow{color:#979ba2}.sky-vertical-tab-active{background-color:#eeeeef;color:#212327;padding-left:6px;border-left:4px solid #00b4f1}.sky-vertical-tab-hidden{display:none}.sky-vertical-tab-display{display:flex;justify-content:space-between;flex-grow:1}.sky-vertical-tab-heading-error{padding-left:5px}.sky-vertical-tab-count{margin-left:5px}.sky-vertical-tabset-button-disabled{cursor:not-allowed;pointer-events:none}.sky-vertical-tab-right-arrow{padding:3px 10px 0 0;color:#cdcfd2}.sky-vertical-tab-content-pane:focus-visible{outline:none;border:none}:host-context(.sky-theme-modern) .sky-vertical-tab{color:#686c73;cursor:pointer;padding:10px 0 10px 15px;margin:15px 0 15px 10px}:host-context(.sky-theme-modern) .sky-vertical-tab:not(.sky-vertical-tab-active):not(:active):hover{color:#212327;background-color:transparent;padding-left:14px;border-left:1px solid #00b4f1}:host-context(.sky-theme-modern) .sky-vertical-tab:not(:active):focus-visible{outline:solid 2px #1870B8;outline-offset:-2px;box-shadow:0 1px 8px #0000004d}:host-context(.sky-theme-modern) .sky-vertical-tab:focus:active:hover{outline:none;background:none}:host-context(.sky-theme-modern) .sky-vertical-tab:active{border-left:4px solid #00b4f1;color:#212327;padding-left:11px}:host-context(.sky-theme-modern) .sky-vertical-tab .sky-vertical-tab-heading-error{padding-left:10px;position:relative;top:-2px}:host-context(.sky-theme-modern) .sky-vertical-tab-active{background:none;color:#212327;padding-left:11px;border-left:4px solid #1870B8}.sky-theme-modern .sky-vertical-tab{color:#686c73;cursor:pointer;padding:10px 0 10px 15px;margin:15px 0 15px 10px}.sky-theme-modern .sky-vertical-tab:not(.sky-vertical-tab-active):not(:active):hover{color:#212327;background-color:transparent;padding-left:14px;border-left:1px solid #00b4f1}.sky-theme-modern .sky-vertical-tab:not(:active):focus-visible{outline:solid 2px #1870B8;outline-offset:-2px;box-shadow:0 1px 8px #0000004d}.sky-theme-modern .sky-vertical-tab:focus:active:hover{outline:none;background:none}.sky-theme-modern .sky-vertical-tab:active{border-left:4px solid #00b4f1;color:#212327;padding-left:11px}.sky-theme-modern .sky-vertical-tab .sky-vertical-tab-heading-error{padding-left:10px;position:relative;top:-2px}.sky-theme-modern .sky-vertical-tab-active{background:none;color:#212327;padding-left:11px;border-left:4px solid #1870B8}:host-context(.sky-sectioned-form-tabs-only) .sky-vertical-tab{margin-left:0}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.λ4, selector: "sky-icon", inputs: ["icon", "iconType", "size", "fixedWidth", "variant"] }, { kind: "directive", type: i1.λ2, selector: "[skyId]", exportAs: ["skyId"] }, { kind: "component", type: i6.λ10, selector: "sky-status-indicator", inputs: ["indicatorType", "descriptionType", "customDescription"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
568
660
|
}
|
|
569
661
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: SkyVerticalTabComponent, decorators: [{
|
|
570
662
|
type: Component,
|
|
@@ -574,7 +666,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImpor
|
|
|
574
666
|
provide: SkyMediaQueryService,
|
|
575
667
|
useExisting: SkyVerticalTabMediaQueryService,
|
|
576
668
|
},
|
|
577
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<a\n class=\"sky-vertical-tab\"\n [attr.aria-controls]=\"isMobile ? null : ariaControls || tabContentPane.id\"\n [attr.aria-selected]=\"active\"\n [attr.id]=\"tabId\"\n [attr.role]=\"isMobile ? undefined : ariaRole\"\n [ngClass]=\"{\n 'sky-vertical-tab-active': active,\n 'sky-vertical-
|
|
669
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<a\n class=\"sky-vertical-tab sky-vertical-tabset-button\"\n [attr.aria-controls]=\"isMobile ? null : ariaControls || tabContentPane.id\"\n [attr.aria-disabled]=\"disabled || undefined\"\n [attr.aria-selected]=\"active\"\n [attr.id]=\"tabId\"\n [attr.role]=\"isMobile ? undefined : ariaRole\"\n [ngClass]=\"{\n 'sky-vertical-tab-active': active,\n 'sky-vertical-tabset-button-disabled': disabled,\n 'sky-font-deemphasized': disabled,\n 'sky-deemphasized': disabled\n }\"\n [tabIndex]=\"-1\"\n (click)=\"activateTab()\"\n (keyup.arrowleft)=\"tabButtonArrowLeft($event)\"\n (keyup.enter)=\"tabButtonActivate($event)\"\n (keyup.space)=\"tabButtonActivate($event)\"\n #tabButton\n>\n <div class=\"sky-vertical-tab-display\">\n <div class=\"sky-vertical-tab-heading\">\n <span class=\"sky-vertical-tab-heading-value\">{{ tabHeading }}</span>\n <span\n class=\"sky-vertical-tab-count\"\n *ngIf=\"tabHeaderCount || tabHeaderCount === 0\"\n >\n ({{ tabHeaderCount }})\n </span>\n </div>\n <sky-status-indicator\n *ngIf=\"errorIndicator\"\n class=\"sky-vertical-tab-heading-error\"\n descriptionType=\"error\"\n indicatorType=\"danger\"\n ></sky-status-indicator>\n <sky-icon\n *ngIf=\"isMobile && showTabRightArrow\"\n class=\"sky-vertical-tab-right-arrow\"\n icon=\"chevron-right\"\n />\n </div>\n</a>\n\n<div #tabContentWrapper>\n <div\n class=\"sky-vertical-tab-content-pane\"\n role=\"tabpanel\"\n tabindex=\"0\"\n skyId\n [attr.aria-labelledby]=\"tabId\"\n [ngClass]=\"{ 'sky-vertical-tab-hidden': !active }\"\n #tabContentPane\n >\n <ng-content />\n\n <div></div>\n </div>\n</div>\n", styles: [".sky-vertical-tab{cursor:pointer;padding:7px 0 7px 10px;margin:5px 0 5px 10px;display:flex;text-decoration:none}.sky-vertical-tab:not(.sky-deemphasized){color:#212327}.sky-vertical-tab:hover{background-color:#eeeeef}.sky-vertical-tab:focus-visible{outline:thin dotted;outline:-webkit-focus-ring-color auto 5px}.sky-vertical-tab:hover .sky-vertical-tab-right-arrow{color:#979ba2}.sky-vertical-tab-active{background-color:#eeeeef;color:#212327;padding-left:6px;border-left:4px solid #00b4f1}.sky-vertical-tab-hidden{display:none}.sky-vertical-tab-display{display:flex;justify-content:space-between;flex-grow:1}.sky-vertical-tab-heading-error{padding-left:5px}.sky-vertical-tab-count{margin-left:5px}.sky-vertical-tabset-button-disabled{cursor:not-allowed;pointer-events:none}.sky-vertical-tab-right-arrow{padding:3px 10px 0 0;color:#cdcfd2}.sky-vertical-tab-content-pane:focus-visible{outline:none;border:none}:host-context(.sky-theme-modern) .sky-vertical-tab{color:#686c73;cursor:pointer;padding:10px 0 10px 15px;margin:15px 0 15px 10px}:host-context(.sky-theme-modern) .sky-vertical-tab:not(.sky-vertical-tab-active):not(:active):hover{color:#212327;background-color:transparent;padding-left:14px;border-left:1px solid #00b4f1}:host-context(.sky-theme-modern) .sky-vertical-tab:not(:active):focus-visible{outline:solid 2px #1870B8;outline-offset:-2px;box-shadow:0 1px 8px #0000004d}:host-context(.sky-theme-modern) .sky-vertical-tab:focus:active:hover{outline:none;background:none}:host-context(.sky-theme-modern) .sky-vertical-tab:active{border-left:4px solid #00b4f1;color:#212327;padding-left:11px}:host-context(.sky-theme-modern) .sky-vertical-tab .sky-vertical-tab-heading-error{padding-left:10px;position:relative;top:-2px}:host-context(.sky-theme-modern) .sky-vertical-tab-active{background:none;color:#212327;padding-left:11px;border-left:4px solid #1870B8}.sky-theme-modern .sky-vertical-tab{color:#686c73;cursor:pointer;padding:10px 0 10px 15px;margin:15px 0 15px 10px}.sky-theme-modern .sky-vertical-tab:not(.sky-vertical-tab-active):not(:active):hover{color:#212327;background-color:transparent;padding-left:14px;border-left:1px solid #00b4f1}.sky-theme-modern .sky-vertical-tab:not(:active):focus-visible{outline:solid 2px #1870B8;outline-offset:-2px;box-shadow:0 1px 8px #0000004d}.sky-theme-modern .sky-vertical-tab:focus:active:hover{outline:none;background:none}.sky-theme-modern .sky-vertical-tab:active{border-left:4px solid #00b4f1;color:#212327;padding-left:11px}.sky-theme-modern .sky-vertical-tab .sky-vertical-tab-heading-error{padding-left:10px;position:relative;top:-2px}.sky-theme-modern .sky-vertical-tab-active{background:none;color:#212327;padding-left:11px;border-left:4px solid #1870B8}:host-context(.sky-sectioned-form-tabs-only) .sky-vertical-tab{margin-left:0}\n"] }]
|
|
578
670
|
}], ctorParameters: function () { return [{ type: SkyVerticalTabsetAdapterService }, { type: i0.ChangeDetectorRef }, { type: SkyVerticalTabsetService }, { type: SkyVerticalTabMediaQueryService }, { type: SkyTabIdService, decorators: [{
|
|
579
671
|
type: Optional
|
|
580
672
|
}] }]; }, propDecorators: { active: [{
|
|
@@ -595,6 +687,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImpor
|
|
|
595
687
|
type: Input
|
|
596
688
|
}], tabId: [{
|
|
597
689
|
type: Input
|
|
690
|
+
}], tabButton: [{
|
|
691
|
+
type: ViewChild,
|
|
692
|
+
args: ['tabButton']
|
|
598
693
|
}], tabContent: [{
|
|
599
694
|
type: ViewChild,
|
|
600
695
|
args: ['tabContentWrapper']
|
|
@@ -629,43 +724,48 @@ class SkyVerticalTabsetGroupComponent {
|
|
|
629
724
|
#ngUnsubscribe;
|
|
630
725
|
#tabService;
|
|
631
726
|
#changeRef;
|
|
727
|
+
#adapterService;
|
|
728
|
+
#idService;
|
|
729
|
+
#tabIdService;
|
|
730
|
+
#groupService;
|
|
632
731
|
#_disabled;
|
|
633
732
|
#_open;
|
|
634
733
|
constructor(tabService, changeRef) {
|
|
635
734
|
this.animationDisabled = false;
|
|
636
735
|
this.slideDirection = 'up';
|
|
637
736
|
this.#ngUnsubscribe = new Subject();
|
|
638
|
-
this
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
this
|
|
642
|
-
// Angular will sometimes place the animation into the "void" state when tabs are hidden. Update our internal variable to reflect that.
|
|
643
|
-
this.slideDirection = 'void';
|
|
644
|
-
this.#changeRef.markForCheck();
|
|
645
|
-
};
|
|
646
|
-
this.tabsShown = () => {
|
|
647
|
-
// Set the animation back up so that the "void" state is returned to where it was prior to the tabs being hidden.
|
|
648
|
-
// This will be instantaneous due to there not being a "void -> *" state on the slide animation.
|
|
649
|
-
this.#updateSlideDirection(true);
|
|
650
|
-
this.#changeRef.markForCheck();
|
|
651
|
-
};
|
|
737
|
+
this.#adapterService = inject(SkyVerticalTabsetAdapterService);
|
|
738
|
+
this.#idService = inject(SkyIdService);
|
|
739
|
+
this.#tabIdService = inject(SkyTabIdService);
|
|
740
|
+
this.#groupService = inject(SkyVerticalTabsetGroupService);
|
|
652
741
|
this.#tabService = tabService;
|
|
653
742
|
this.#changeRef = changeRef;
|
|
743
|
+
this.groupId = this.#idService.generateId();
|
|
744
|
+
this.#groupService.messageStream.subscribe((message) => {
|
|
745
|
+
switch (message.messageType) {
|
|
746
|
+
case 'focus':
|
|
747
|
+
this.#focusButton();
|
|
748
|
+
}
|
|
749
|
+
});
|
|
654
750
|
}
|
|
655
751
|
ngOnInit() {
|
|
752
|
+
this.#tabIdService.register(this.groupId, this.groupId);
|
|
753
|
+
this.#tabService.addGroup(this);
|
|
656
754
|
this.#tabService.hidingTabs
|
|
657
755
|
.pipe(takeUntil(this.#ngUnsubscribe))
|
|
658
|
-
.subscribe(this
|
|
756
|
+
.subscribe(() => this.#tabsHidden());
|
|
659
757
|
this.#tabService.showingTabs
|
|
660
758
|
.pipe(takeUntil(this.#ngUnsubscribe))
|
|
661
|
-
.subscribe(this
|
|
759
|
+
.subscribe(() => this.#tabsShown());
|
|
662
760
|
this.#tabService.tabClicked
|
|
663
761
|
.pipe(takeUntil(this.#ngUnsubscribe))
|
|
664
|
-
.subscribe(this
|
|
762
|
+
.subscribe(() => this.#tabClicked());
|
|
665
763
|
}
|
|
666
764
|
ngOnDestroy() {
|
|
765
|
+
this.#tabService.destroyGroup(this);
|
|
667
766
|
this.#ngUnsubscribe.next();
|
|
668
767
|
this.#ngUnsubscribe.complete();
|
|
768
|
+
this.#tabIdService.unregister(this.groupId);
|
|
669
769
|
}
|
|
670
770
|
updateSlideDirection(event) {
|
|
671
771
|
this.slideDirection = event.toState;
|
|
@@ -677,19 +777,51 @@ class SkyVerticalTabsetGroupComponent {
|
|
|
677
777
|
this.#updateSlideDirection(true);
|
|
678
778
|
this.#changeRef.markForCheck();
|
|
679
779
|
}
|
|
680
|
-
|
|
780
|
+
groupButtonArrowLeft(event) {
|
|
781
|
+
if (this.open) {
|
|
782
|
+
this.toggleMenuOpen();
|
|
783
|
+
}
|
|
784
|
+
event.preventDefault();
|
|
785
|
+
}
|
|
786
|
+
groupButtonArrowRight(event) {
|
|
787
|
+
if (this.open) {
|
|
788
|
+
this.tabs?.get(0)?.focusButton();
|
|
789
|
+
}
|
|
790
|
+
else {
|
|
791
|
+
this.toggleMenuOpen();
|
|
792
|
+
}
|
|
793
|
+
event.preventDefault();
|
|
794
|
+
}
|
|
795
|
+
isActive() {
|
|
681
796
|
return !!this.tabs && this.tabs.find((t) => !!t.active) !== undefined;
|
|
682
797
|
}
|
|
798
|
+
#tabClicked() {
|
|
799
|
+
this.#changeRef.markForCheck();
|
|
800
|
+
}
|
|
801
|
+
#tabsHidden() {
|
|
802
|
+
// Angular will sometimes place the animation into the "void" state when tabs are hidden. Update our internal variable to reflect that.
|
|
803
|
+
this.slideDirection = 'void';
|
|
804
|
+
this.#changeRef.markForCheck();
|
|
805
|
+
}
|
|
806
|
+
#tabsShown() {
|
|
807
|
+
// Set the animation back up so that the "void" state is returned to where it was prior to the tabs being hidden.
|
|
808
|
+
// This will be instantaneous due to there not being a "void -> *" state on the slide animation.
|
|
809
|
+
this.#updateSlideDirection(true);
|
|
810
|
+
this.#changeRef.markForCheck();
|
|
811
|
+
}
|
|
683
812
|
#updateSlideDirection(animate) {
|
|
684
813
|
this.animationDisabled = !animate;
|
|
685
814
|
this.slideDirection = this.open && !this.disabled ? 'down' : 'up';
|
|
686
815
|
}
|
|
816
|
+
#focusButton() {
|
|
817
|
+
this.#adapterService.focusButton(this.groupHeadingButton);
|
|
818
|
+
}
|
|
687
819
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: SkyVerticalTabsetGroupComponent, deps: [{ token: SkyVerticalTabsetService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
688
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.9", type: SkyVerticalTabsetGroupComponent, selector: "sky-vertical-tabset-group", inputs: { disabled: "disabled", groupHeading: "groupHeading", open: "open" }, queries: [{ propertyName: "tabs", predicate: SkyVerticalTabComponent }], ngImport: i0, template: "<div class=\"sky-vertical-tabset-group\">\n <!-- [ngClass] includes font classes for both modern and default styles -->\n <div\n class=\"sky-vertical-tabset-group-header\"\n [ngClass]=\"{\n 'sky-vertical-tabset-group-header-
|
|
820
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.9", type: SkyVerticalTabsetGroupComponent, selector: "sky-vertical-tabset-group", inputs: { disabled: "disabled", groupHeading: "groupHeading", open: "open" }, providers: [SkyVerticalTabsetGroupService], queries: [{ propertyName: "tabs", predicate: SkyVerticalTabComponent }], viewQueries: [{ propertyName: "groupHeadingButton", first: true, predicate: ["groupHeadingButton"], descendants: true }], ngImport: i0, template: "<div class=\"sky-vertical-tabset-group\">\n <!-- [ngClass] includes font classes for both modern and default styles -->\n <div\n class=\"sky-vertical-tabset-group-header\"\n [ngClass]=\"{\n 'sky-vertical-tabset-group-header-active sky-font-emphasized':\n isActive(),\n 'sky-vertical-tabset-group-header-sub-open': open,\n 'sky-font-deemphasized': disabled,\n 'sky-deemphasized': disabled,\n }\"\n >\n <button\n class=\"sky-padding-even-default sky-vertical-tabset-button\"\n role=\"tab\"\n type=\"button\"\n [attr.aria-controls]=\"groupContent.id\"\n [attr.aria-disabled]=\"disabled || undefined\"\n [attr.aria-expanded]=\"!disabled && open\"\n [id]=\"groupId\"\n [ngClass]=\"{\n 'sky-vertical-tabset-button-disabled': disabled\n }\"\n [tabIndex]=\"-1\"\n (click)=\"toggleMenuOpen()\"\n (keyup.arrowleft)=\"groupButtonArrowLeft($event)\"\n (keyup.arrowright)=\"groupButtonArrowRight($event)\"\n #groupHeadingButton\n >\n {{ groupHeading }}\n <sky-expansion-indicator\n class=\"sky-vertical-tabset-group-expansion-indicator\"\n [direction]=\"!disabled && open ? 'up' : 'down'\"\n >\n </sky-expansion-indicator>\n </button>\n </div>\n <div\n class=\"sky-vertical-tabset-group-content\"\n skyId\n [attr.labelledby]=\"groupId\"\n [@.disabled]=\"animationDisabled\"\n [@skyAnimationSlide]=\"slideDirection\"\n (@skyAnimationSlide.done)=\"updateSlideDirection($event)\"\n #groupContent\n >\n <ng-content />\n </div>\n</div>\n", styles: [".sky-vertical-tabset-group{border-bottom:1px solid #e2e3e4;margin:5px 0 5px 5px}.sky-vertical-tabset-group-header button{cursor:pointer;display:flex;justify-content:space-between;border:none;width:100%;text-align:left;background:none}.sky-vertical-tabset-group-content{overflow:hidden;border-top:1px solid #e2e3e4}:host ::ng-deep .sky-vertical-tabset-group-expansion-indicator>button{font-size:14px!important}.sky-vertical-tabset-button-disabled{cursor:not-allowed;pointer-events:none}:host-context(.sky-theme-modern) .sky-vertical-tabset-group{border:none;margin:15px 0}:host-context(.sky-theme-modern) .sky-vertical-tabset-group-content{border:none;padding-left:10px}:host-context(.sky-theme-modern) .sky-vertical-tabset-group-header{position:relative}:host-context(.sky-theme-modern) .sky-vertical-tabset-group-expansion-indicator{position:absolute;top:6px;right:5px}.sky-theme-modern .sky-vertical-tabset-group{border:none;margin:15px 0}.sky-theme-modern .sky-vertical-tabset-group-content{border:none;padding-left:10px}.sky-theme-modern .sky-vertical-tabset-group-header{position:relative}.sky-theme-modern .sky-vertical-tabset-group-expansion-indicator{position:absolute;top:6px;right:5px}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.λ2, selector: "[skyId]", exportAs: ["skyId"] }, { kind: "component", type: i6.λ15, selector: "sky-expansion-indicator", inputs: ["direction"] }], animations: [skyAnimationSlide], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
689
821
|
}
|
|
690
822
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: SkyVerticalTabsetGroupComponent, decorators: [{
|
|
691
823
|
type: Component,
|
|
692
|
-
args: [{ selector: 'sky-vertical-tabset-group', changeDetection: ChangeDetectionStrategy.OnPush, animations: [skyAnimationSlide], template: "<div class=\"sky-vertical-tabset-group\">\n <!-- [ngClass] includes font classes for both modern and default styles -->\n <div\n class=\"sky-vertical-tabset-group-header\"\n [ngClass]=\"{\n 'sky-vertical-tabset-group-header-
|
|
824
|
+
args: [{ selector: 'sky-vertical-tabset-group', changeDetection: ChangeDetectionStrategy.OnPush, animations: [skyAnimationSlide], providers: [SkyVerticalTabsetGroupService], template: "<div class=\"sky-vertical-tabset-group\">\n <!-- [ngClass] includes font classes for both modern and default styles -->\n <div\n class=\"sky-vertical-tabset-group-header\"\n [ngClass]=\"{\n 'sky-vertical-tabset-group-header-active sky-font-emphasized':\n isActive(),\n 'sky-vertical-tabset-group-header-sub-open': open,\n 'sky-font-deemphasized': disabled,\n 'sky-deemphasized': disabled,\n }\"\n >\n <button\n class=\"sky-padding-even-default sky-vertical-tabset-button\"\n role=\"tab\"\n type=\"button\"\n [attr.aria-controls]=\"groupContent.id\"\n [attr.aria-disabled]=\"disabled || undefined\"\n [attr.aria-expanded]=\"!disabled && open\"\n [id]=\"groupId\"\n [ngClass]=\"{\n 'sky-vertical-tabset-button-disabled': disabled\n }\"\n [tabIndex]=\"-1\"\n (click)=\"toggleMenuOpen()\"\n (keyup.arrowleft)=\"groupButtonArrowLeft($event)\"\n (keyup.arrowright)=\"groupButtonArrowRight($event)\"\n #groupHeadingButton\n >\n {{ groupHeading }}\n <sky-expansion-indicator\n class=\"sky-vertical-tabset-group-expansion-indicator\"\n [direction]=\"!disabled && open ? 'up' : 'down'\"\n >\n </sky-expansion-indicator>\n </button>\n </div>\n <div\n class=\"sky-vertical-tabset-group-content\"\n skyId\n [attr.labelledby]=\"groupId\"\n [@.disabled]=\"animationDisabled\"\n [@skyAnimationSlide]=\"slideDirection\"\n (@skyAnimationSlide.done)=\"updateSlideDirection($event)\"\n #groupContent\n >\n <ng-content />\n </div>\n</div>\n", styles: [".sky-vertical-tabset-group{border-bottom:1px solid #e2e3e4;margin:5px 0 5px 5px}.sky-vertical-tabset-group-header button{cursor:pointer;display:flex;justify-content:space-between;border:none;width:100%;text-align:left;background:none}.sky-vertical-tabset-group-content{overflow:hidden;border-top:1px solid #e2e3e4}:host ::ng-deep .sky-vertical-tabset-group-expansion-indicator>button{font-size:14px!important}.sky-vertical-tabset-button-disabled{cursor:not-allowed;pointer-events:none}:host-context(.sky-theme-modern) .sky-vertical-tabset-group{border:none;margin:15px 0}:host-context(.sky-theme-modern) .sky-vertical-tabset-group-content{border:none;padding-left:10px}:host-context(.sky-theme-modern) .sky-vertical-tabset-group-header{position:relative}:host-context(.sky-theme-modern) .sky-vertical-tabset-group-expansion-indicator{position:absolute;top:6px;right:5px}.sky-theme-modern .sky-vertical-tabset-group{border:none;margin:15px 0}.sky-theme-modern .sky-vertical-tabset-group-content{border:none;padding-left:10px}.sky-theme-modern .sky-vertical-tabset-group-header{position:relative}.sky-theme-modern .sky-vertical-tabset-group-expansion-indicator{position:absolute;top:6px;right:5px}\n"] }]
|
|
693
825
|
}], ctorParameters: function () { return [{ type: SkyVerticalTabsetService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { disabled: [{
|
|
694
826
|
type: Input
|
|
695
827
|
}], groupHeading: [{
|
|
@@ -699,6 +831,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImpor
|
|
|
699
831
|
}], tabs: [{
|
|
700
832
|
type: ContentChildren,
|
|
701
833
|
args: [SkyVerticalTabComponent]
|
|
834
|
+
}], groupHeadingButton: [{
|
|
835
|
+
type: ViewChild,
|
|
836
|
+
args: ['groupHeadingButton']
|
|
702
837
|
}] } });
|
|
703
838
|
|
|
704
839
|
class SkyVerticalTabsetComponent {
|
|
@@ -722,10 +857,10 @@ class SkyVerticalTabsetComponent {
|
|
|
722
857
|
#_ariaRole;
|
|
723
858
|
#resources;
|
|
724
859
|
#changeRef;
|
|
725
|
-
#tabIdSvc;
|
|
726
860
|
constructor(adapterService, tabService, resources, changeRef, tabIdSvc) {
|
|
727
861
|
this.adapterService = adapterService;
|
|
728
862
|
this.tabService = tabService;
|
|
863
|
+
this.tabIdSvc = tabIdSvc;
|
|
729
864
|
/**
|
|
730
865
|
* Whether the vertical tabset loads tab content during initialization so that it
|
|
731
866
|
* displays content without moving around elements in the content container.
|
|
@@ -738,15 +873,11 @@ class SkyVerticalTabsetComponent {
|
|
|
738
873
|
*/
|
|
739
874
|
this.activeChange = new EventEmitter();
|
|
740
875
|
this.isMobile = false;
|
|
876
|
+
this.tablistHasFocus = false;
|
|
741
877
|
this.#ngUnsubscribe = new Subject();
|
|
742
878
|
this.#_ariaRole = 'tablist';
|
|
743
879
|
this.#resources = resources;
|
|
744
880
|
this.#changeRef = changeRef;
|
|
745
|
-
this.#tabIdSvc = tabIdSvc;
|
|
746
|
-
this.#tabIdSvc.ids.pipe(takeUntil(this.#ngUnsubscribe)).subscribe((ids) => {
|
|
747
|
-
this.ariaOwns = ids.join(' ') || undefined;
|
|
748
|
-
this.#changeRef.markForCheck();
|
|
749
|
-
});
|
|
750
881
|
}
|
|
751
882
|
ngOnInit() {
|
|
752
883
|
this.tabService.maintainTabContent = this.maintainTabContent;
|
|
@@ -791,8 +922,27 @@ class SkyVerticalTabsetComponent {
|
|
|
791
922
|
this.#ngUnsubscribe.next();
|
|
792
923
|
this.#ngUnsubscribe.complete();
|
|
793
924
|
}
|
|
925
|
+
tabsetFocus() {
|
|
926
|
+
this.tabService.focusActiveTab(this.tabGroups);
|
|
927
|
+
}
|
|
928
|
+
tabGroupsFocusIn() {
|
|
929
|
+
// This will set the tab index of the the vertical tabset element to -1
|
|
930
|
+
// while focus is inside the tab list, allowing Shift+Tab to move
|
|
931
|
+
// to the next element above the tab list element. Otherwise focus would
|
|
932
|
+
// be trapped on the currently focused tab.
|
|
933
|
+
this.tablistHasFocus = true;
|
|
934
|
+
}
|
|
935
|
+
tabGroupsFocusOut() {
|
|
936
|
+
this.tablistHasFocus = false;
|
|
937
|
+
}
|
|
938
|
+
tabGroupsArrowDown() {
|
|
939
|
+
this.adapterService.focusNextButton(this.tabGroups);
|
|
940
|
+
}
|
|
941
|
+
tabGroupsArrowUp() {
|
|
942
|
+
this.adapterService.focusPreviousButton(this.tabGroups);
|
|
943
|
+
}
|
|
794
944
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: SkyVerticalTabsetComponent, deps: [{ token: SkyVerticalTabsetAdapterService }, { token: SkyVerticalTabsetService }, { token: i3.SkyLibResourcesService }, { token: i0.ChangeDetectorRef }, { token: SkyTabIdService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
795
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.9", type: SkyVerticalTabsetComponent, selector: "sky-vertical-tabset", inputs: { showTabsText: "showTabsText", ariaLabel: "ariaLabel", ariaLabelledBy: "ariaLabelledBy", ariaRole: "ariaRole", maintainTabContent: "maintainTabContent" }, outputs: { activeChange: "activeChange" }, providers: [SkyTabIdService, SkyVerticalTabsetService], viewQueries: [{ propertyName: "tabGroups", first: true, predicate: ["groupContainerWrapper"], descendants: true }, { propertyName: "content", first: true, predicate: ["skySideContent"], descendants: true }, { propertyName: "contentWrapper", first: true, predicate: ["contentContainerWrapper"], descendants: true }], ngImport: i0, template: "<div
|
|
945
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.9", type: SkyVerticalTabsetComponent, selector: "sky-vertical-tabset", inputs: { showTabsText: "showTabsText", ariaLabel: "ariaLabel", ariaLabelledBy: "ariaLabelledBy", ariaRole: "ariaRole", maintainTabContent: "maintainTabContent" }, outputs: { activeChange: "activeChange" }, providers: [SkyTabIdService, SkyVerticalTabsetService], viewQueries: [{ propertyName: "tabGroups", first: true, predicate: ["groupContainerWrapper"], descendants: true }, { propertyName: "content", first: true, predicate: ["skySideContent"], descendants: true }, { propertyName: "contentWrapper", first: true, predicate: ["contentContainerWrapper"], descendants: true }], ngImport: i0, template: "<div\n class=\"sky-vertical-tabset\"\n [tabIndex]=\"tablistHasFocus ? -1 : 0\"\n (focus)=\"tabsetFocus()\"\n>\n <!--\n ARIA rules do not allow tabpanel elements to be children of a tablist element.\n However, the markup for each sky-vertical-tab component includes both the tab button\n and its panel, making the panel element a child of its tablist. Moreover, our\n sky-vertical-tab components can be grouped within collapsible containers, which also\n violates accessibility rules because only tab buttons can be children of a tablist.\n To address this, we create an empty tablist element with an aria-owns attribute,\n pointing to each tab element individually. That way, we don't have to worry about the\n structure for each sky-vertical-tab component in order to satisfy accessibility\n guidelines.\n -->\n <span\n aria-orientation=\"vertical\"\n class=\"sky-vertical-tabset-tablist\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledBy\"\n [attr.aria-owns]=\"(tabIdSvc.ids | async)?.join(' ') || undefined\"\n [attr.role]=\"isMobile ? undefined : ariaRole\"\n ></span>\n <div\n *ngIf=\"maintainTabContent || tabService.tabsVisible()\"\n class=\"sky-vertical-tabset-group-container\"\n [@tabGroupEnter]=\"tabService.animationTabsVisibleState\"\n [ngClass]=\"{ 'sky-vertical-tabset-hidden': !tabService.tabsVisible() }\"\n (keydown.arrowdown)=\"tabGroupsArrowDown(); $event.preventDefault()\"\n (keydown.arrowup)=\"tabGroupsArrowUp(); $event.preventDefault()\"\n (focusin)=\"tabGroupsFocusIn()\"\n (focusout)=\"tabGroupsFocusOut()\"\n #groupContainerWrapper\n >\n <ng-content />\n </div>\n <div\n *ngIf=\"maintainTabContent || tabService.contentVisible()\"\n class=\"sky-vertical-tabset-content\"\n [ngClass]=\"{\n 'sky-vertical-tabset-content-hidden': !tabService.contentVisible()\n }\"\n [@contentEnter]=\"tabService.animationContentVisibleState\"\n #contentContainerWrapper\n >\n <div #skySideContent></div>\n <button\n *ngIf=\"!tabService.tabsVisible()\"\n (click)=\"tabService.showTabs()\"\n class=\"sky-btn sky-btn-primary sky-vertical-tabset-show-tabs-btn\"\n type=\"button\"\n >\n <sky-icon icon=\"chevron-left\" />\n {{ showTabsText }}\n </button>\n </div>\n</div>\n", styles: [":host .sky-vertical-tabset{display:block;height:auto}:host .sky-vertical-tabset-group-container{border-right:none}:host-context(.sky-responsive-container-xs) .sky-vertical-tabset,:host-context(.sky-responsive-container-sm) .sky-vertical-tabset,:host-context(.sky-responsive-container-md) .sky-vertical-tabset,:host-context(.sky-responsive-container-lg) .sky-vertical-tabset{display:block;height:auto}:host-context(.sky-responsive-container-xs) .sky-vertical-tabset-group-container,:host-context(.sky-responsive-container-sm) .sky-vertical-tabset-group-container,:host-context(.sky-responsive-container-md) .sky-vertical-tabset-group-container,:host-context(.sky-responsive-container-lg) .sky-vertical-tabset-group-container{border-right:none}@media (min-width: 768px){:host .sky-vertical-tabset{display:flex;height:100%}:host .sky-vertical-tabset-group-container{border-right:1px solid #cdcfd2}}:host-context(.sky-responsive-container-sm) .sky-vertical-tabset,:host-context(.sky-responsive-container-md) .sky-vertical-tabset,:host-context(.sky-responsive-container-lg) .sky-vertical-tabset{display:flex;height:100%}:host-context(.sky-responsive-container-sm) .sky-vertical-tabset-group-container,:host-context(.sky-responsive-container-md) .sky-vertical-tabset-group-container,:host-context(.sky-responsive-container-lg) .sky-vertical-tabset-group-container{border-right:1px solid #cdcfd2}.sky-vertical-tabset-hidden{display:none}.sky-vertical-tabset-content{margin:10px 0 0 10px;flex-basis:75%;overflow-y:auto}.sky-vertical-tabset-content-hidden{display:none}.sky-vertical-tabset-show-tabs-btn{margin-top:10px}.sky-vertical-tabset-group-container{flex-basis:25%;overflow-y:auto}:host-context(sky-modal-content)>.sky-vertical-tabset{margin:-15px}:host-context(.sky-theme-modern) .sky-vertical-tabset-content{margin:15px}@media (min-width: 768px){:host-context(.sky-theme-modern) :host .sky-vertical-tabset-content{margin:20px 30px}:host-context(.sky-theme-modern) :host .sky-vertical-tabset-group-container{border-right:1px solid #d2d2d2}}:host-context(.sky-theme-modern) :host-context(.sky-responsive-container-sm) .sky-vertical-tabset-content,:host-context(.sky-theme-modern) :host-context(.sky-responsive-container-md) .sky-vertical-tabset-content,:host-context(.sky-theme-modern) :host-context(.sky-responsive-container-lg) .sky-vertical-tabset-content{margin:20px 30px}:host-context(.sky-theme-modern) :host-context(.sky-responsive-container-sm) .sky-vertical-tabset-group-container,:host-context(.sky-theme-modern) :host-context(.sky-responsive-container-md) .sky-vertical-tabset-group-container,:host-context(.sky-theme-modern) :host-context(.sky-responsive-container-lg) .sky-vertical-tabset-group-container{border-right:1px solid #d2d2d2}.sky-theme-modern .sky-vertical-tabset-content{margin:15px}@media (min-width: 768px){.sky-theme-modern :host .sky-vertical-tabset-content{margin:20px 30px}.sky-theme-modern :host .sky-vertical-tabset-group-container{border-right:1px solid #d2d2d2}}.sky-theme-modern :host-context(.sky-responsive-container-sm) .sky-vertical-tabset-content,.sky-theme-modern :host-context(.sky-responsive-container-md) .sky-vertical-tabset-content,.sky-theme-modern :host-context(.sky-responsive-container-lg) .sky-vertical-tabset-content{margin:20px 30px}.sky-theme-modern :host-context(.sky-responsive-container-sm) .sky-vertical-tabset-group-container,.sky-theme-modern :host-context(.sky-responsive-container-md) .sky-vertical-tabset-group-container,.sky-theme-modern :host-context(.sky-responsive-container-lg) .sky-vertical-tabset-group-container{border-right:1px solid #d2d2d2}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.λ4, selector: "sky-icon", inputs: ["icon", "iconType", "size", "fixedWidth", "variant"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }], animations: [
|
|
796
946
|
trigger('tabGroupEnter', [
|
|
797
947
|
transition(`${HIDDEN_STATE} => ${VISIBLE_STATE}`, [
|
|
798
948
|
style({ transform: 'translate(-100%)' }),
|
|
@@ -822,7 +972,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImpor
|
|
|
822
972
|
animate('150ms ease-in'),
|
|
823
973
|
]),
|
|
824
974
|
]),
|
|
825
|
-
], template: "<div
|
|
975
|
+
], template: "<div\n class=\"sky-vertical-tabset\"\n [tabIndex]=\"tablistHasFocus ? -1 : 0\"\n (focus)=\"tabsetFocus()\"\n>\n <!--\n ARIA rules do not allow tabpanel elements to be children of a tablist element.\n However, the markup for each sky-vertical-tab component includes both the tab button\n and its panel, making the panel element a child of its tablist. Moreover, our\n sky-vertical-tab components can be grouped within collapsible containers, which also\n violates accessibility rules because only tab buttons can be children of a tablist.\n To address this, we create an empty tablist element with an aria-owns attribute,\n pointing to each tab element individually. That way, we don't have to worry about the\n structure for each sky-vertical-tab component in order to satisfy accessibility\n guidelines.\n -->\n <span\n aria-orientation=\"vertical\"\n class=\"sky-vertical-tabset-tablist\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledBy\"\n [attr.aria-owns]=\"(tabIdSvc.ids | async)?.join(' ') || undefined\"\n [attr.role]=\"isMobile ? undefined : ariaRole\"\n ></span>\n <div\n *ngIf=\"maintainTabContent || tabService.tabsVisible()\"\n class=\"sky-vertical-tabset-group-container\"\n [@tabGroupEnter]=\"tabService.animationTabsVisibleState\"\n [ngClass]=\"{ 'sky-vertical-tabset-hidden': !tabService.tabsVisible() }\"\n (keydown.arrowdown)=\"tabGroupsArrowDown(); $event.preventDefault()\"\n (keydown.arrowup)=\"tabGroupsArrowUp(); $event.preventDefault()\"\n (focusin)=\"tabGroupsFocusIn()\"\n (focusout)=\"tabGroupsFocusOut()\"\n #groupContainerWrapper\n >\n <ng-content />\n </div>\n <div\n *ngIf=\"maintainTabContent || tabService.contentVisible()\"\n class=\"sky-vertical-tabset-content\"\n [ngClass]=\"{\n 'sky-vertical-tabset-content-hidden': !tabService.contentVisible()\n }\"\n [@contentEnter]=\"tabService.animationContentVisibleState\"\n #contentContainerWrapper\n >\n <div #skySideContent></div>\n <button\n *ngIf=\"!tabService.tabsVisible()\"\n (click)=\"tabService.showTabs()\"\n class=\"sky-btn sky-btn-primary sky-vertical-tabset-show-tabs-btn\"\n type=\"button\"\n >\n <sky-icon icon=\"chevron-left\" />\n {{ showTabsText }}\n </button>\n </div>\n</div>\n", styles: [":host .sky-vertical-tabset{display:block;height:auto}:host .sky-vertical-tabset-group-container{border-right:none}:host-context(.sky-responsive-container-xs) .sky-vertical-tabset,:host-context(.sky-responsive-container-sm) .sky-vertical-tabset,:host-context(.sky-responsive-container-md) .sky-vertical-tabset,:host-context(.sky-responsive-container-lg) .sky-vertical-tabset{display:block;height:auto}:host-context(.sky-responsive-container-xs) .sky-vertical-tabset-group-container,:host-context(.sky-responsive-container-sm) .sky-vertical-tabset-group-container,:host-context(.sky-responsive-container-md) .sky-vertical-tabset-group-container,:host-context(.sky-responsive-container-lg) .sky-vertical-tabset-group-container{border-right:none}@media (min-width: 768px){:host .sky-vertical-tabset{display:flex;height:100%}:host .sky-vertical-tabset-group-container{border-right:1px solid #cdcfd2}}:host-context(.sky-responsive-container-sm) .sky-vertical-tabset,:host-context(.sky-responsive-container-md) .sky-vertical-tabset,:host-context(.sky-responsive-container-lg) .sky-vertical-tabset{display:flex;height:100%}:host-context(.sky-responsive-container-sm) .sky-vertical-tabset-group-container,:host-context(.sky-responsive-container-md) .sky-vertical-tabset-group-container,:host-context(.sky-responsive-container-lg) .sky-vertical-tabset-group-container{border-right:1px solid #cdcfd2}.sky-vertical-tabset-hidden{display:none}.sky-vertical-tabset-content{margin:10px 0 0 10px;flex-basis:75%;overflow-y:auto}.sky-vertical-tabset-content-hidden{display:none}.sky-vertical-tabset-show-tabs-btn{margin-top:10px}.sky-vertical-tabset-group-container{flex-basis:25%;overflow-y:auto}:host-context(sky-modal-content)>.sky-vertical-tabset{margin:-15px}:host-context(.sky-theme-modern) .sky-vertical-tabset-content{margin:15px}@media (min-width: 768px){:host-context(.sky-theme-modern) :host .sky-vertical-tabset-content{margin:20px 30px}:host-context(.sky-theme-modern) :host .sky-vertical-tabset-group-container{border-right:1px solid #d2d2d2}}:host-context(.sky-theme-modern) :host-context(.sky-responsive-container-sm) .sky-vertical-tabset-content,:host-context(.sky-theme-modern) :host-context(.sky-responsive-container-md) .sky-vertical-tabset-content,:host-context(.sky-theme-modern) :host-context(.sky-responsive-container-lg) .sky-vertical-tabset-content{margin:20px 30px}:host-context(.sky-theme-modern) :host-context(.sky-responsive-container-sm) .sky-vertical-tabset-group-container,:host-context(.sky-theme-modern) :host-context(.sky-responsive-container-md) .sky-vertical-tabset-group-container,:host-context(.sky-theme-modern) :host-context(.sky-responsive-container-lg) .sky-vertical-tabset-group-container{border-right:1px solid #d2d2d2}.sky-theme-modern .sky-vertical-tabset-content{margin:15px}@media (min-width: 768px){.sky-theme-modern :host .sky-vertical-tabset-content{margin:20px 30px}.sky-theme-modern :host .sky-vertical-tabset-group-container{border-right:1px solid #d2d2d2}}.sky-theme-modern :host-context(.sky-responsive-container-sm) .sky-vertical-tabset-content,.sky-theme-modern :host-context(.sky-responsive-container-md) .sky-vertical-tabset-content,.sky-theme-modern :host-context(.sky-responsive-container-lg) .sky-vertical-tabset-content{margin:20px 30px}.sky-theme-modern :host-context(.sky-responsive-container-sm) .sky-vertical-tabset-group-container,.sky-theme-modern :host-context(.sky-responsive-container-md) .sky-vertical-tabset-group-container,.sky-theme-modern :host-context(.sky-responsive-container-lg) .sky-vertical-tabset-group-container{border-right:1px solid #d2d2d2}\n"] }]
|
|
826
976
|
}], ctorParameters: function () { return [{ type: SkyVerticalTabsetAdapterService }, { type: SkyVerticalTabsetService }, { type: i3.SkyLibResourcesService }, { type: i0.ChangeDetectorRef }, { type: SkyTabIdService }]; }, propDecorators: { showTabsText: [{
|
|
827
977
|
type: Input
|
|
828
978
|
}], ariaLabel: [{
|