mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Bug/accessibility 1 (#6774)
* fixing simple name changes * Fixing button color and tabbing on tabs * removing some extra lines of code * Adding some null checks * Updating as per PR comments
This commit is contained in:
@@ -14,7 +14,7 @@
|
|||||||
"textLinkActiveForeground": "#30b4ff",
|
"textLinkActiveForeground": "#30b4ff",
|
||||||
|
|
||||||
//Button control
|
//Button control
|
||||||
"button.background": "#0078d7cc",
|
"button.background": "#0E639C",
|
||||||
"button.foreground": "#ffffff",
|
"button.foreground": "#ffffff",
|
||||||
"button.hoverBackground": "#0078d7",
|
"button.hoverBackground": "#0078d7",
|
||||||
|
|
||||||
@@ -530,4 +530,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
"textLinkActiveForeground": "#3062d6",
|
"textLinkActiveForeground": "#3062d6",
|
||||||
|
|
||||||
//Button control
|
//Button control
|
||||||
"button.background": "#0078d7cc",
|
"button.background": "#007ACC",
|
||||||
"button.foreground": "#ffffff",
|
"button.foreground": "#ffffff",
|
||||||
"button.hoverBackground": "#0078d7",
|
"button.hoverBackground": "#0078d7",
|
||||||
|
|
||||||
@@ -562,4 +562,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import * as DOM from 'vs/base/browser/dom';
|
|||||||
import { IAction } from 'vs/base/common/actions';
|
import { IAction } from 'vs/base/common/actions';
|
||||||
import { IActionOptions, ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
import { IActionOptions, ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||||
import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
|
import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||||
import { Color } from 'vs/base/common/color';
|
import { Color } from 'vs/base/common/color';
|
||||||
import { isUndefinedOrNull } from 'vs/base/common/types';
|
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||||
@@ -77,6 +77,7 @@ export class TabbedPanel extends Disposable {
|
|||||||
public onTabChange: Event<PanelTabIdentifier> = this._onTabChange.event;
|
public onTabChange: Event<PanelTabIdentifier> = this._onTabChange.event;
|
||||||
|
|
||||||
private tabHistory: string[] = [];
|
private tabHistory: string[] = [];
|
||||||
|
private _tabOrder: PanelTabIdentifier[] = [];
|
||||||
|
|
||||||
constructor(container: HTMLElement, private options: IPanelOptions = defaultOptions) {
|
constructor(container: HTMLElement, private options: IPanelOptions = defaultOptions) {
|
||||||
super();
|
super();
|
||||||
@@ -84,9 +85,9 @@ export class TabbedPanel extends Disposable {
|
|||||||
this._styleElement = DOM.createStyleSheet(this.parent);
|
this._styleElement = DOM.createStyleSheet(this.parent);
|
||||||
container.appendChild(this.parent);
|
container.appendChild(this.parent);
|
||||||
this.header = DOM.$('.composite.title');
|
this.header = DOM.$('.composite.title');
|
||||||
|
this.header.setAttribute('tabindex', '0');
|
||||||
this.tabList = DOM.$('.tabList');
|
this.tabList = DOM.$('.tabList');
|
||||||
this.tabList.setAttribute('role', 'tablist');
|
this.tabList.setAttribute('role', 'tablist');
|
||||||
this.tabList.setAttribute('tabindex', '0');
|
|
||||||
this.tabList.style.height = this.headersize + 'px';
|
this.tabList.style.height = this.headersize + 'px';
|
||||||
this.header.appendChild(this.tabList);
|
this.header.appendChild(this.tabList);
|
||||||
let actionbarcontainer = DOM.$('.title-actions');
|
let actionbarcontainer = DOM.$('.title-actions');
|
||||||
@@ -101,6 +102,7 @@ export class TabbedPanel extends Disposable {
|
|||||||
this.body = DOM.$('.tabBody');
|
this.body = DOM.$('.tabBody');
|
||||||
this.body.setAttribute('role', 'tabpanel');
|
this.body.setAttribute('role', 'tabpanel');
|
||||||
this.parent.appendChild(this.body);
|
this.parent.appendChild(this.body);
|
||||||
|
this._register(DOM.addDisposableListener(this.header, DOM.EventType.FOCUS, e => this.focusCurrentTab()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public dispose() {
|
public dispose() {
|
||||||
@@ -142,7 +144,7 @@ export class TabbedPanel extends Disposable {
|
|||||||
|
|
||||||
private _createTab(tab: IInternalPanelTab, index?: number): void {
|
private _createTab(tab: IInternalPanelTab, index?: number): void {
|
||||||
let tabHeaderElement = DOM.$('.tab-header');
|
let tabHeaderElement = DOM.$('.tab-header');
|
||||||
tabHeaderElement.setAttribute('tabindex', '0');
|
tabHeaderElement.setAttribute('tabindex', '-1');
|
||||||
tabHeaderElement.setAttribute('role', 'tab');
|
tabHeaderElement.setAttribute('role', 'tab');
|
||||||
tabHeaderElement.setAttribute('aria-selected', 'false');
|
tabHeaderElement.setAttribute('aria-selected', 'false');
|
||||||
tabHeaderElement.setAttribute('aria-controls', tab.tab.identifier);
|
tabHeaderElement.setAttribute('aria-controls', tab.tab.identifier);
|
||||||
@@ -161,19 +163,40 @@ export class TabbedPanel extends Disposable {
|
|||||||
invokeTabSelectedHandler();
|
invokeTabSelectedHandler();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
tab.disposables.push(DOM.addDisposableListener(tabHeaderElement, DOM.EventType.KEY_UP, (e: KeyboardEvent) => {
|
tab.disposables.push(DOM.addDisposableListener(tabHeaderElement, DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => {
|
||||||
let event = new StandardKeyboardEvent(e);
|
let event = new StandardKeyboardEvent(e);
|
||||||
if (event.equals(KeyCode.Enter)) {
|
if (event.equals(KeyCode.Enter)) {
|
||||||
this.showTab(tab.tab.identifier);
|
this.showTab(tab.tab.identifier);
|
||||||
invokeTabSelectedHandler();
|
invokeTabSelectedHandler();
|
||||||
e.stopImmediatePropagation();
|
e.stopImmediatePropagation();
|
||||||
}
|
}
|
||||||
|
if (event.equals(KeyCode.RightArrow)) {
|
||||||
|
let currentIndex = this._tabOrder.findIndex(x => x === tab.tab.identifier);
|
||||||
|
this.focusNextTab(currentIndex + 1);
|
||||||
|
}
|
||||||
|
if (event.equals(KeyCode.LeftArrow)) {
|
||||||
|
let currentIndex = this._tabOrder.findIndex(x => x === tab.tab.identifier);
|
||||||
|
this.focusNextTab(currentIndex - 1);
|
||||||
|
}
|
||||||
|
if (event.equals(KeyCode.Tab)) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (this._shownTabId) {
|
||||||
|
const shownTab = this._tabMap.get(this._shownTabId);
|
||||||
|
if (shownTab) {
|
||||||
|
shownTab.tab.view.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const insertBefore = !isUndefinedOrNull(index) ? this.tabList.children.item(index) : undefined;
|
const insertBefore = !isUndefinedOrNull(index) ? this.tabList.children.item(index) : undefined;
|
||||||
if (insertBefore) {
|
if (insertBefore && index) {
|
||||||
|
this._tabOrder.copyWithin(index + 1, index);
|
||||||
|
this._tabOrder[index] = tab.tab.identifier;
|
||||||
this.tabList.insertBefore(tabHeaderElement, insertBefore);
|
this.tabList.insertBefore(tabHeaderElement, insertBefore);
|
||||||
} else {
|
} else {
|
||||||
this.tabList.append(tabHeaderElement);
|
this.tabList.append(tabHeaderElement);
|
||||||
|
this._tabOrder.push(tab.tab.identifier);
|
||||||
}
|
}
|
||||||
tab.header = tabHeaderElement;
|
tab.header = tabHeaderElement;
|
||||||
tab.label = tabLabel;
|
tab.label = tabLabel;
|
||||||
@@ -244,6 +267,8 @@ export class TabbedPanel extends Disposable {
|
|||||||
}
|
}
|
||||||
dispose(actualTab.disposables);
|
dispose(actualTab.disposables);
|
||||||
this._tabMap.delete(tab);
|
this._tabMap.delete(tab);
|
||||||
|
let index = this._tabOrder.findIndex(t => t === tab);
|
||||||
|
this._tabOrder.splice(index, 1);
|
||||||
if (this._shownTabId === tab) {
|
if (this._shownTabId === tab) {
|
||||||
this._shownTabId = undefined;
|
this._shownTabId = undefined;
|
||||||
while (this._shownTabId === undefined && this.tabHistory.length > 0) {
|
while (this._shownTabId === undefined && this.tabHistory.length > 0) {
|
||||||
@@ -266,6 +291,25 @@ export class TabbedPanel extends Disposable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private focusNextTab(index: number): void {
|
||||||
|
if (index < 0 || index > this.tabList.children.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let tab = (<HTMLElement>this.tabList.children[index]);
|
||||||
|
if (tab) {
|
||||||
|
tab.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private focusCurrentTab(): void {
|
||||||
|
if (this._shownTabId) {
|
||||||
|
const tab = this._tabMap.get(this._shownTabId);
|
||||||
|
if (tab) {
|
||||||
|
tab.header.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public style(styles: ITabbedPanelStyles): void {
|
public style(styles: ITabbedPanelStyles): void {
|
||||||
const content: string[] = [];
|
const content: string[] = [];
|
||||||
|
|
||||||
|
|||||||
@@ -271,6 +271,7 @@ export class BackupComponent {
|
|||||||
|
|
||||||
// Set backup path list
|
// Set backup path list
|
||||||
this.pathListBox = new ListBox([], this.contextViewService);
|
this.pathListBox = new ListBox([], this.contextViewService);
|
||||||
|
this.pathListBox.setAriaLabel(LocalizedStrings.BACKUP_DEVICE);
|
||||||
this.pathListBox.onKeyDown(e => {
|
this.pathListBox.onKeyDown(e => {
|
||||||
if (this.pathListBox.selectedOptions.length > 0) {
|
if (this.pathListBox.selectedOptions.length > 0) {
|
||||||
const key = e.keyCode;
|
const key = e.keyCode;
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export class RestoreDialog extends Modal {
|
|||||||
private _scriptButton: Button;
|
private _scriptButton: Button;
|
||||||
private _restoreButton: Button;
|
private _restoreButton: Button;
|
||||||
private _closeButton: Button;
|
private _closeButton: Button;
|
||||||
private _optionsMap: { [name: string]: Widget } = {};
|
private _optionsMap: { [name: string]: SelectBox | InputBox | Checkbox } = {};
|
||||||
private _restoreLabel: string;
|
private _restoreLabel: string;
|
||||||
private _restoreTitle: string;
|
private _restoreTitle: string;
|
||||||
private _databaseTitle: string;
|
private _databaseTitle: string;
|
||||||
@@ -250,6 +250,7 @@ export class RestoreDialog extends Modal {
|
|||||||
this._restorePlanData = new TableDataView<Slick.SlickData>();
|
this._restorePlanData = new TableDataView<Slick.SlickData>();
|
||||||
this._restorePlanTable = new Table<Slick.SlickData>(this._restorePlanTableContainer,
|
this._restorePlanTable = new Table<Slick.SlickData>(this._restorePlanTableContainer,
|
||||||
{ dataProvider: this._restorePlanData, columns: this._restorePlanColumn }, { enableColumnReorder: false });
|
{ dataProvider: this._restorePlanData, columns: this._restorePlanColumn }, { enableColumnReorder: false });
|
||||||
|
this._restorePlanTable.setTableTitle(localize('restorePlan', "Restore plan"));
|
||||||
this._restorePlanTable.setSelectionModel(new RowSelectionModel({ selectActiveRow: false }));
|
this._restorePlanTable.setSelectionModel(new RowSelectionModel({ selectActiveRow: false }));
|
||||||
this._restorePlanTable.onSelectedRowsChanged((e, data) => this.backupFileCheckboxChanged(e, data));
|
this._restorePlanTable.onSelectedRowsChanged((e, data) => this.backupFileCheckboxChanged(e, data));
|
||||||
|
|
||||||
@@ -339,7 +340,7 @@ export class RestoreDialog extends Modal {
|
|||||||
DOM.append(c, generalTab);
|
DOM.append(c, generalTab);
|
||||||
},
|
},
|
||||||
layout: () => { },
|
layout: () => { },
|
||||||
focus: () => generalTab.focus()
|
focus: () => this._restoreFromSelectBox ? this._restoreFromSelectBox.focus() : generalTab.focus()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -351,7 +352,7 @@ export class RestoreDialog extends Modal {
|
|||||||
render: c => {
|
render: c => {
|
||||||
c.appendChild(fileContentElement);
|
c.appendChild(fileContentElement);
|
||||||
},
|
},
|
||||||
focus: () => fileContentElement.focus()
|
focus: () => this._optionsMap[this._relocateDatabaseFilesOption] ? this._optionsMap[this._relocateDatabaseFilesOption].focus() : fileContentElement.focus()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -363,7 +364,7 @@ export class RestoreDialog extends Modal {
|
|||||||
render: c => {
|
render: c => {
|
||||||
c.appendChild(optionsContentElement);
|
c.appendChild(optionsContentElement);
|
||||||
},
|
},
|
||||||
focus: () => optionsContentElement.focus()
|
focus: () => this._optionsMap[this._withReplaceDatabaseOption] ? this._optionsMap[this._withReplaceDatabaseOption].focus() : optionsContentElement.focus()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -96,8 +96,9 @@ export class FileBrowserDialog extends Modal {
|
|||||||
ariaLabel: pathLabel
|
ariaLabel: pathLabel
|
||||||
});
|
});
|
||||||
|
|
||||||
this._fileFilterSelectBox = new SelectBox(['*'], '*', this._contextViewService);
|
|
||||||
let filterLabel = localize('fileFilter', "Files of type");
|
let filterLabel = localize('fileFilter', "Files of type");
|
||||||
|
this._fileFilterSelectBox = new SelectBox(['*'], '*', this._contextViewService);
|
||||||
|
this._fileFilterSelectBox.setAriaLabel(filterLabel);
|
||||||
let filterBuilder = DialogHelper.appendRow(tableContainer, filterLabel, 'file-input-label', 'file-input-box');
|
let filterBuilder = DialogHelper.appendRow(tableContainer, filterLabel, 'file-input-label', 'file-input-box');
|
||||||
DialogHelper.appendInputSelectBox(filterBuilder, this._fileFilterSelectBox);
|
DialogHelper.appendInputSelectBox(filterBuilder, this._fileFilterSelectBox);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user