Fixing tabbing logic for tab headers (#19770)

* Fixing tabbing logic for tab headers

* Renaming stuff
Making null checks concise
Adding comments

* Renaming css class and interfaces from active to selected

* Renaming styling classes and objects

* Changing tabbing logic to match w3 behavior

* Fixing focus logic in tab

* Adding helper comment

* Code cleanup
This commit is contained in:
Aasim Khan
2022-06-21 13:13:10 -07:00
committed by GitHub
parent f2c4e23f99
commit 15a611d4a4
9 changed files with 120 additions and 83 deletions

View File

@@ -70,15 +70,15 @@ panel {
font-weight: 600; font-weight: 600;
} }
.tabbedPanel .tabList .tab-header:hover:not(.active) { .tabbedPanel .tabList .tab-header:hover:not(.selected) {
background-color: #dcdcdc; background-color: #dcdcdc;
outline: none; outline: none;
} }
.vs-dark .tabbedPanel .tabList .tab-header:hover:not(.active) { .vs-dark .tabbedPanel .tabList .tab-header:hover:not(.selected) {
background-color: #2a2d2e; background-color: #2a2d2e;
outline: none; outline: none;
} }
.hc-black .tabbedPanel .tabList .tab-header:hover:not(.active) { .hc-black .tabbedPanel .tabList .tab-header:hover:not(.selected) {
background-color: initial; background-color: initial;
outline: 1px dashed #f38518; outline: 1px dashed #f38518;
outline-offset: -3px; outline-offset: -3px;
@@ -135,7 +135,7 @@ panel {
flex: 0 0 auto; flex: 0 0 auto;
} }
.tab > .tabLabel.active { .tab > .tabLabel.selected {
border-bottom: 1px solid; border-bottom: 1px solid;
} }

View File

@@ -13,7 +13,7 @@ tab-header .action-item {
line-height: 1.4em; line-height: 1.4em;
} }
tab-header .tab-header.active .action-label, /* always show it for active tab */ tab-header .tab-header.selected .action-label, /* always show it for selected tab */
tab-header .tab-header:hover .action-label, /* always show it on hover */ tab-header .tab-header:hover .action-label, /* always show it on hover */
tab-header .tab-header:focus .action-label { /* always show it on focus */ tab-header .tab-header:focus .action-label { /* always show it on focus */
opacity: 1; opacity: 1;

View File

@@ -57,10 +57,10 @@ let idPool = 0;
<div *ngIf="_options.layout === NavigationBarLayout.vertical" class="vertical-tab-action-container"> <div *ngIf="_options.layout === NavigationBarLayout.vertical" class="vertical-tab-action-container">
<button [attr.aria-expanded]="_tabExpanded" [title]="toggleTabPanelButtonAriaLabel" [attr.aria-label]="toggleTabPanelButtonAriaLabel" [ngClass]="toggleTabPanelButtonCssClass" tabindex="0" (click)="toggleTabPanel()"></button> <button [attr.aria-expanded]="_tabExpanded" [title]="toggleTabPanelButtonAriaLabel" [attr.aria-label]="toggleTabPanelButtonAriaLabel" [ngClass]="toggleTabPanelButtonCssClass" tabindex="0" (click)="toggleTabPanel()"></button>
</div> </div>
<div [style.display]="_tabExpanded ? 'flex': 'none'" [attr.aria-hidden]="_tabExpanded ? 'false': 'true'" class="tabList" role="tablist" (keydown)="onKey($event)"> <div [style.display]="_tabExpanded ? 'flex': 'none'" [attr.aria-hidden]="_tabExpanded ? 'false': 'true'" class="tabList" role="tablist" (keydown)="onKey($event)" (focusout)="onTabHeaderFocusOut($event)">
<div role="presentation" *ngFor="let tab of _tabs"> <div role="presentation" *ngFor="let tab of _tabs">
<ng-container *ngIf="tab.type!=='group-header'"> <ng-container *ngIf="tab.type!=='group-header'">
<tab-header role="presentation" [active]="_activeTab === tab" [tab]="tab" [showIcon]="_options.showIcon" (onSelectTab)='selectTab($event)' (onCloseTab)='closeTab($event)'></tab-header> <tab-header role="presentation" [selected]="_selectedTab === tab" [tab]="tab" [showIcon]="_options.showIcon" (onSelectTab)='selectTab($event)' (onCloseTab)='closeTab($event)'></tab-header>
</ng-container> </ng-container>
<ng-container *ngIf="tab.type==='group-header' && _options.layout === NavigationBarLayout.vertical"> <ng-container *ngIf="tab.type==='group-header' && _options.layout === NavigationBarLayout.vertical">
<div class="tab-group-header"> <div class="tab-group-header">
@@ -102,7 +102,7 @@ export class PanelComponent extends Disposable implements IThemable {
@Output() public onTabChange = new EventEmitter<TabComponent>(); @Output() public onTabChange = new EventEmitter<TabComponent>();
@Output() public onTabClose = new EventEmitter<TabComponent>(); @Output() public onTabClose = new EventEmitter<TabComponent>();
private _activeTab?: TabComponent; private _selectedTab?: TabComponent;
private _actionbar?: ActionBar; private _actionbar?: ActionBar;
private _mru: TabComponent[] = []; private _mru: TabComponent[] = [];
private _tabExpanded: boolean = true; private _tabExpanded: boolean = true;
@@ -218,39 +218,43 @@ export class PanelComponent extends Disposable implements IThemable {
} }
}); });
if (this._activeTab && tab === this._activeTab) { if (this._selectedTab && tab === this._selectedTab) {
this.onTabChange.emit(tab); this.onTabChange.emit(tab);
return; return;
} }
this._zone.run(() => { this._zone.run(() => {
if (this._activeTab) { if (this._selectedTab) {
this._activeTab.active = false; this._selectedTab.selected = false;
} }
this._activeTab = tab; this._selectedTab = tab;
this.setMostRecentlyUsed(tab); this.setMostRecentlyUsed(tab);
this._activeTab.active = true; this._selectedTab.selected = true;
this.onTabChange.emit(tab); this.onTabChange.emit(tab);
}); });
this._tabHeaders?.forEach(tabHeader => {
tabHeader.tabIndex = tabHeader.tab.identifier === foundTab.identifier ? 0 : -1;
});
} }
} }
} }
/** /**
* Get the id of the active tab * Get the id of the selected tab
*/ */
public get getActiveTab(): string | undefined { public get getSelectedTab(): string | undefined {
return this._activeTab?.identifier; return this._selectedTab?.identifier;
} }
/** /**
* Select on the next tab * Select on the next tab
*/ */
public selectOnNextTab(): void { public selectOnNextTab(): void {
let activeIndex = this._tabs.toArray().findIndex(i => i === this._activeTab); let selectedIndex = this._tabs.toArray().findIndex(i => i === this._selectedTab);
let nextTabIndex = activeIndex + 1; let nextTabIndex = selectedIndex + 1;
if (nextTabIndex === this._tabs.length) { if (nextTabIndex === this._tabs.length) {
nextTabIndex = 0; nextTabIndex = 0;
} }
@@ -315,7 +319,7 @@ export class PanelComponent extends Disposable implements IThemable {
} }
public layout() { public layout() {
this._activeTab?.layout(); this._selectedTab?.layout();
} }
onKey(e: KeyboardEvent): void { onKey(e: KeyboardEvent): void {
@@ -328,15 +332,34 @@ export class PanelComponent extends Disposable implements IThemable {
this.focusPreviousTab(); this.focusPreviousTab();
eventHandled = true; eventHandled = true;
} }
if (eventHandled) { if (eventHandled) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
} }
} }
onTabHeaderFocusOut(e: Event): void {
/**
* Making the selected tab header focusable when the focus leaves the tab header div.
* This fixes an issue when users press up/left arrow in vertical tab header and move up to
* the previous tab header. The next focus was being set to the selected tab and then the tab
* contents. Now, the focus will directly move to tab contents. And, when users press
* shift-tab on the first focusable element of tab content, the focus will move back to
* selected tab header.
*/
if (!(<HTMLElement>e.currentTarget).contains((<any>e).relatedTarget)) {
this._tabHeaders.forEach(th => {
if (th.tab === this._selectedTab) {
th.tabIndex = 0;
}
});
}
}
private focusPreviousTab(): void { private focusPreviousTab(): void {
const currentIndex = this.focusedTabHeaderIndex; const currentIndex = this.focusedTabHeaderIndex;
this._tabHeaders.toArray()[currentIndex].tabIndex = -1;
if (currentIndex !== -1) { if (currentIndex !== -1) {
// Move to the previous tab, if we are at the first tab then move to the last tab. // Move to the previous tab, if we are at the first tab then move to the last tab.
this.focusOnTabHeader(currentIndex === 0 ? this._tabHeaders.length - 1 : currentIndex - 1); this.focusOnTabHeader(currentIndex === 0 ? this._tabHeaders.length - 1 : currentIndex - 1);
@@ -345,6 +368,7 @@ export class PanelComponent extends Disposable implements IThemable {
private focusNextTab(): void { private focusNextTab(): void {
const currentIndex = this.focusedTabHeaderIndex; const currentIndex = this.focusedTabHeaderIndex;
this._tabHeaders.toArray()[currentIndex].tabIndex = -1;
if (currentIndex !== -1) { if (currentIndex !== -1) {
// Move to the next tab, if we are at the last tab then move to the first tab. // Move to the next tab, if we are at the last tab then move to the first tab.
this.focusOnTabHeader(currentIndex === this._tabHeaders.length - 1 ? 0 : currentIndex + 1); this.focusOnTabHeader(currentIndex === this._tabHeaders.length - 1 ? 0 : currentIndex + 1);
@@ -366,32 +390,36 @@ export class PanelComponent extends Disposable implements IThemable {
style(styles: ITabbedPanelStyles) { style(styles: ITabbedPanelStyles) {
if (this._styleElement) { if (this._styleElement) {
const content: string[] = []; const content: string[] = [];
if (styles.titleInactiveForeground) { if (styles.titleUnSelectedForeground) {
content.push(`.tabbedPanel.horizontal > .title .tabList .tab-header { content.push(`.tabbedPanel.horizontal > .title .tabList .tab-header {
color: ${styles.titleInactiveForeground} color: ${styles.titleUnSelectedForeground}
}`); }`);
} }
if (styles.titleActiveBorder && styles.titleActiveForeground) { if (styles.titleSelectedBorder && styles.titleSelectedForeground) {
content.push(`.tabbedPanel.horizontal > .title .tabList .tab-header:focus, content.push(`.tabbedPanel.horizontal > .title .tabList .tab-header.selected {
.tabbedPanel.horizontal > .title .tabList .tab-header.active { border-color: ${styles.titleSelectedBorder};
border-color: ${styles.titleActiveBorder};
border-style: solid; border-style: solid;
color: ${styles.titleActiveForeground} color: ${styles.titleSelectedForeground}
}`); }`);
content.push(`.tabbedPanel.horizontal > .title .tabList .tab-header:focus, content.push(`.tabbedPanel.horizontal > .title .tabList .tab-header.selected {;
.tabbedPanel.horizontal > .title .tabList .tab-header.active {; border-width: 0 0 ${styles.selectedTabContrastBorder ? '0' : '2'}px 0;
border-width: 0 0 ${styles.activeTabContrastBorder ? '0' : '2'}px 0;
}`); }`);
content.push(`.tabbedPanel.horizontal > .title .tabList .tab-header:hover { content.push(`.tabbedPanel.horizontal > .title .tabList .tab-header:hover {
color: ${styles.titleActiveForeground} color: ${styles.titleSelectedForeground}
}`);
content.push(`.tabbedPanel.horizontal > .title .tabList .tab-header:focus {
outline: 1px solid;
outline-offset: 2px;
outline-color: ${styles.titleSelectedBorder};
}`); }`);
} }
if (styles.activeBackgroundForVerticalLayout) { if (styles.selectedBackgroundForVerticalLayout) {
content.push(`.tabbedPanel.vertical > .title .tabList .tab-header.active { content.push(`.tabbedPanel.vertical > .title .tabList .tab-header.selected {
background-color:${styles.activeBackgroundForVerticalLayout} background-color:${styles.selectedBackgroundForVerticalLayout}
}`); }`);
} }
@@ -407,18 +435,14 @@ export class PanelComponent extends Disposable implements IThemable {
}`); }`);
} }
if (styles.activeTabContrastBorder) { if (styles.selectedTabContrastBorder) {
content.push(` content.push(`
.tabbedPanel > .title .tabList .tab-header.active { .tabbedPanel > .title .tabList .tab-header.selected {
outline: 1px solid; outline: 1px solid;
outline-offset: -3px; outline-offset: -3px;
outline-color: ${styles.activeTabContrastBorder}; outline-color: ${styles.selectedTabContrastBorder};
} }
`); `);
} else {
content.push(`.tabbedPanel.horizontal > .title .tabList .tab-header:focus {
outline-width: 0px;
}`);
} }
const newStyles = content.join('\n'); const newStyles = content.join('\n');

View File

@@ -16,14 +16,14 @@ import { Color } from 'vs/base/common/color';
import { isUndefinedOrNull } from 'vs/base/common/types'; import { isUndefinedOrNull } from 'vs/base/common/types';
export interface ITabbedPanelStyles { export interface ITabbedPanelStyles {
titleActiveForeground?: Color; titleSelectedForeground?: Color;
titleActiveBorder?: Color; titleSelectedBorder?: Color;
titleInactiveForeground?: Color; titleUnSelectedForeground?: Color;
focusBorder?: Color; focusBorder?: Color;
outline?: Color; outline?: Color;
activeBackgroundForVerticalLayout?: Color; selectedBackgroundForVerticalLayout?: Color;
border?: Color; border?: Color;
activeTabContrastBorder?: Color; selectedTabContrastBorder?: Color;
} }
export interface IPanelOptions { export interface IPanelOptions {
@@ -108,7 +108,7 @@ export class TabbedPanel extends Disposable {
return this.parent; return this.parent;
} }
public get activeTabId(): string | undefined { public get selectedTabId(): string | undefined {
return this._shownTabId; return this._shownTabId;
} }
@@ -209,8 +209,8 @@ export class TabbedPanel extends Disposable {
if (this._shownTabId) { if (this._shownTabId) {
const shownTab = this._tabMap.get(this._shownTabId); const shownTab = this._tabMap.get(this._shownTabId);
if (shownTab) { if (shownTab) {
shownTab.label.classList.remove('active'); shownTab.label.classList.remove('selected');
shownTab.header.classList.remove('active'); shownTab.header.classList.remove('selected');
shownTab.header.setAttribute('aria-selected', 'false'); shownTab.header.setAttribute('aria-selected', 'false');
shownTab.header.tabIndex = -1; shownTab.header.tabIndex = -1;
if (shownTab.body) { if (shownTab.body) {
@@ -239,8 +239,8 @@ export class TabbedPanel extends Disposable {
} }
this.body.appendChild(tab.body); this.body.appendChild(tab.body);
this.body.setAttribute('aria-labelledby', tab.tab.identifier); this.body.setAttribute('aria-labelledby', tab.tab.identifier);
tab.label.classList.add('active'); tab.label.classList.add('selected');
tab.header.classList.add('active'); tab.header.classList.add('selected');
tab.header.setAttribute('aria-selected', 'true'); tab.header.setAttribute('aria-selected', 'true');
this._onTabChange.fire(id); this._onTabChange.fire(id);
if (tab.tab.view.onShow) { if (tab.tab.view.onShow) {
@@ -329,27 +329,27 @@ export class TabbedPanel extends Disposable {
}`); }`);
} }
if (styles.titleActiveForeground && styles.titleActiveBorder) { if (styles.titleSelectedForeground && styles.titleSelectedBorder) {
content.push(` content.push(`
.tabbedPanel > .title .tabList .tab:hover .tabLabel, .tabbedPanel > .title .tabList .tab:hover .tabLabel,
.tabbedPanel > .title .tabList .tab .tabLabel.active { .tabbedPanel > .title .tabList .tab .tabLabel.selected {
color: ${styles.titleActiveForeground}; color: ${styles.titleSelectedForeground};
border-bottom-color: ${styles.titleActiveBorder}; border-bottom-color: ${styles.titleSelectedBorder};
border-bottom-width: 2px; border-bottom-width: 2px;
}`); }`);
} }
if (styles.titleInactiveForeground) { if (styles.titleUnSelectedForeground) {
content.push(` content.push(`
.tabbedPanel > .title .tabList .tab .tabLabel { .tabbedPanel > .title .tabList .tab .tabLabel {
color: ${styles.titleInactiveForeground}; color: ${styles.titleUnSelectedForeground};
}`); }`);
} }
if (styles.focusBorder && styles.titleActiveForeground) { if (styles.focusBorder && styles.titleSelectedForeground) {
content.push(` content.push(`
.tabbedPanel > .title .tabList .tab .tabLabel:focus { .tabbedPanel > .title .tabList .tab .tabLabel:focus {
color: ${styles.titleActiveForeground}; color: ${styles.titleSelectedForeground};
border-bottom-color: ${styles.focusBorder} !important; border-bottom-color: ${styles.focusBorder} !important;
border-bottom: 1px solid; border-bottom: 1px solid;
outline: none; outline: none;
@@ -358,7 +358,7 @@ export class TabbedPanel extends Disposable {
if (styles.outline) { if (styles.outline) {
content.push(` content.push(`
.tabbedPanel > .title .tabList .tab-header.active, .tabbedPanel > .title .tabList .tab-header.selected,
.tabbedPanel > .title .tabList .tab-header:hover { .tabbedPanel > .title .tabList .tab-header:hover {
outline-color: ${styles.outline}; outline-color: ${styles.outline};
outline-width: 1px; outline-width: 1px;
@@ -367,7 +367,7 @@ export class TabbedPanel extends Disposable {
outline-offset: -5px; outline-offset: -5px;
} }
.tabbedPanel > .title .tabList .tab-header:hover:not(.active) { .tabbedPanel > .title .tabList .tab-header:hover:not(.selected) {
outline-style: dashed; outline-style: dashed;
}`); }`);
} }

View File

@@ -29,7 +29,7 @@ export class TabComponent implements OnDestroy {
@Input() public canClose!: boolean; @Input() public canClose!: boolean;
@Input() public actions?: Array<Action>; @Input() public actions?: Array<Action>;
@Input() public iconClass?: string; @Input() public iconClass?: string;
public _active = false; private _selected = false;
@Input() public identifier!: string; @Input() public identifier!: string;
@Input() public type: TabType = 'tab'; @Input() public type: TabType = 'tab';
@Input() private visibilityType: 'if' | 'visibility' = 'if'; @Input() private visibilityType: 'if' | 'visibility' = 'if';
@@ -38,7 +38,7 @@ export class TabComponent implements OnDestroy {
@ContentChild(TabChild) public set child(tab: TabChild) { @ContentChild(TabChild) public set child(tab: TabChild) {
this._child = tab; this._child = tab;
if (this.active && this._child) { if (this.selected && this._child) {
this._child.layout(); this._child.layout();
} }
} }
@@ -47,21 +47,21 @@ export class TabComponent implements OnDestroy {
@Inject(forwardRef(() => ChangeDetectorRef)) private _cd: ChangeDetectorRef @Inject(forwardRef(() => ChangeDetectorRef)) private _cd: ChangeDetectorRef
) { } ) { }
public set active(val: boolean) { public set selected(val: boolean) {
if (!this.destroyed) { if (!this.destroyed) {
this._active = val; this._selected = val;
if (this.active) { if (this.selected) {
this.rendered = true; this.rendered = true;
} }
this._cd.detectChanges(); this._cd.detectChanges();
if (this.active && this._child) { if (this.selected && this._child) {
this._child.layout(); this._child.layout();
} }
} }
} }
public get active(): boolean { public get selected(): boolean {
return this._active; return this._selected;
} }
ngOnDestroy() { ngOnDestroy() {
@@ -72,7 +72,7 @@ export class TabComponent implements OnDestroy {
} }
shouldBeIfed(): boolean { shouldBeIfed(): boolean {
if (this.active) { if (this.selected) {
return true; return true;
} else if (this.visibilityType === 'visibility' && this.rendered) { } else if (this.visibilityType === 'visibility' && this.rendered) {
return true; return true;
@@ -82,7 +82,7 @@ export class TabComponent implements OnDestroy {
} }
shouldBeHidden(): boolean { shouldBeHidden(): boolean {
if (this.visibilityType === 'visibility' && !this.active) { if (this.visibilityType === 'visibility' && !this.selected) {
return true; return true;
} else { } else {
return false; return false;

View File

@@ -19,10 +19,10 @@ import { CloseTabAction } from 'sql/base/browser/ui/panel/tabActions';
@Component({ @Component({
selector: 'tab-header', selector: 'tab-header',
template: ` template: `
<div #actionHeader role="tab" [attr.aria-selected]="tab.active" [attr.aria-label]="tab.title" class="tab-header" style="flex: 0 0; flex-direction: row;" [class.active]="tab.active" tabindex="0" (click)="selectTab(tab)" (keyup)="onKey($event)"> <div #actionHeader role="tab" [attr.aria-selected]="tab.selected" [attr.aria-label]="tab.title" class="tab-header" style="flex: 0 0; flex-direction: row;" [class.selected]="tab.selected" [attr.tabindex] = "_tabIndex" (click)="selectTab(tab)" (keyup)="onKey($event)">
<div class="tab" role="presentation"> <div class="tab" role="presentation">
<a #tabIcon *ngIf="showIcon && tab.iconClass" class="tabIcon codicon icon {{tab.iconClass}}"></a> <a #tabIcon *ngIf="showIcon && tab.iconClass" class="tabIcon codicon icon {{tab.iconClass}}"></a>
<a class="tabLabel" [class.active]="tab.active" [title]="tab.title" #tabLabel>{{tab.title}}</a> <a class="tabLabel" [class.selected]="tab.selected" [title]="tab.title" #tabLabel>{{tab.title}}</a>
</div> </div>
<div #actionbar style="flex: 0 0 auto; align-self: end; margin-top: auto; margin-bottom: auto;" ></div> <div #actionbar style="flex: 0 0 auto; align-self: end; margin-top: auto; margin-bottom: auto;" ></div>
</div> </div>
@@ -31,12 +31,13 @@ import { CloseTabAction } from 'sql/base/browser/ui/panel/tabActions';
export class TabHeaderComponent extends Disposable implements AfterContentInit, OnDestroy { export class TabHeaderComponent extends Disposable implements AfterContentInit, OnDestroy {
@Input() public tab!: TabComponent; @Input() public tab!: TabComponent;
@Input() public showIcon?: boolean; @Input() public showIcon?: boolean;
@Input() public active?: boolean; @Input() public selected?: boolean;
@Output() public onSelectTab: EventEmitter<TabComponent> = new EventEmitter<TabComponent>(); @Output() public onSelectTab: EventEmitter<TabComponent> = new EventEmitter<TabComponent>();
@Output() public onCloseTab: EventEmitter<TabComponent> = new EventEmitter<TabComponent>(); @Output() public onCloseTab: EventEmitter<TabComponent> = new EventEmitter<TabComponent>();
@Output() public onFocusTab: EventEmitter<TabComponent> = new EventEmitter<TabComponent>(); @Output() public onFocusTab: EventEmitter<TabComponent> = new EventEmitter<TabComponent>();
private _actionbar!: ActionBar; private _actionbar!: ActionBar;
private _tabIndex: number = -1;
@ViewChild('actionHeader', { read: ElementRef }) private _actionHeaderRef!: ElementRef; @ViewChild('actionHeader', { read: ElementRef }) private _actionHeaderRef!: ElementRef;
@ViewChild('actionbar', { read: ElementRef }) private _actionbarRef!: ElementRef; @ViewChild('actionbar', { read: ElementRef }) private _actionbarRef!: ElementRef;
@@ -47,6 +48,15 @@ export class TabHeaderComponent extends Disposable implements AfterContentInit,
super(); super();
} }
public get tabIndex(): number {
return this._tabIndex;
}
public set tabIndex(value: number) {
this._tabIndex = value;
this.refresh();
}
public get nativeElement(): HTMLElement { public get nativeElement(): HTMLElement {
return this._actionHeaderRef.nativeElement; return this._actionHeaderRef.nativeElement;
} }
@@ -66,6 +76,9 @@ export class TabHeaderComponent extends Disposable implements AfterContentInit,
this._actionbar.push(closeAction, { icon: true, label: false }); this._actionbar.push(closeAction, { icon: true, label: false });
} }
} }
if (this.tab.selected) {
this.tabIndex = 0;
}
} }
ngOnDestroy() { ngOnDestroy() {

View File

@@ -1118,8 +1118,8 @@ export class Designer extends Disposable implements IThemable {
private saveUIState(): void { private saveUIState(): void {
if (this._input) { if (this._input) {
this._input.designerUIState = { this._input.designerUIState = {
activeContentTabId: this._contentTabbedPanel.activeTabId, activeContentTabId: this._contentTabbedPanel.selectedTabId,
activeScriptTabId: this._scriptTabbedPannel.activeTabId activeScriptTabId: this._scriptTabbedPannel.selectedTabId
}; };
} }
} }

View File

@@ -45,14 +45,14 @@ export function attachPanelStyler(widget: IThemable, themeService: IThemeService
export function attachTabbedPanelStyler(widget: IThemable, themeService: IThemeService) { export function attachTabbedPanelStyler(widget: IThemable, themeService: IThemeService) {
return attachStyler(themeService, { return attachStyler(themeService, {
titleActiveForeground: PANEL_ACTIVE_TITLE_FOREGROUND, titleSelectedForeground: PANEL_ACTIVE_TITLE_FOREGROUND,
titleActiveBorder: PANEL_ACTIVE_TITLE_BORDER, titleSelectedBorder: PANEL_ACTIVE_TITLE_BORDER,
titleInactiveForeground: PANEL_INACTIVE_TITLE_FOREGROUND, titleUnSelectedForeground: PANEL_INACTIVE_TITLE_FOREGROUND,
focusBorder: cr.focusBorder, focusBorder: cr.focusBorder,
outline: cr.activeContrastBorder, outline: cr.activeContrastBorder,
activeBackgroundForVerticalLayout: VERTICAL_TAB_ACTIVE_BACKGROUND, selectedBackgroundForVerticalLayout: VERTICAL_TAB_ACTIVE_BACKGROUND,
border: DASHBOARD_BORDER, border: DASHBOARD_BORDER,
activeTabContrastBorder: cr.activeContrastBorder selectedTabContrastBorder: cr.activeContrastBorder
}, widget); }, widget);
} }

View File

@@ -149,8 +149,8 @@ export class DashboardNavSection extends DashboardTab implements OnDestroy, OnCh
public layout() { public layout() {
if (this._tabs) { if (this._tabs) {
const activeTabId = this._panel.getActiveTab; const selectedTabId = this._panel.getSelectedTab;
const localtab = this._tabs.find(i => i.id === activeTabId); const localtab = this._tabs.find(i => i.id === selectedTabId);
this._cd.detectChanges(); this._cd.detectChanges();
localtab.layout(); localtab.layout();
} }