mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
restore focus on escape (#13285)
* restore focus on escape * obtain focus on action click * comment * comment 2 * simplify the implementation * remove the toggle action completely * remove the import * implement aria requirements
This commit is contained in:
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
import 'vs/css!./media/dropdownList';
|
import 'vs/css!./media/dropdownList';
|
||||||
|
|
||||||
import { ToggleDropdownAction } from './actions';
|
|
||||||
import { DropdownDataSource, DropdownFilter, DropdownModel, DropdownRenderer, DropdownController } from './dropdownTree';
|
import { DropdownDataSource, DropdownFilter, DropdownModel, DropdownRenderer, DropdownController } from './dropdownTree';
|
||||||
|
|
||||||
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
|
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
|
||||||
@@ -82,7 +81,6 @@ export class Dropdown extends Disposable {
|
|||||||
private _input: InputBox;
|
private _input: InputBox;
|
||||||
private _tree: ITree;
|
private _tree: ITree;
|
||||||
private _options: IDropdownOptions;
|
private _options: IDropdownOptions;
|
||||||
private _toggleAction: ToggleDropdownAction;
|
|
||||||
private _dataSource = new DropdownDataSource();
|
private _dataSource = new DropdownDataSource();
|
||||||
private _filter = new DropdownFilter();
|
private _filter = new DropdownFilter();
|
||||||
private _renderer = new DropdownRenderer();
|
private _renderer = new DropdownRenderer();
|
||||||
@@ -114,16 +112,10 @@ export class Dropdown extends Disposable {
|
|||||||
this._el = DOM.append(container, DOM.$('.monaco-dropdown'));
|
this._el = DOM.append(container, DOM.$('.monaco-dropdown'));
|
||||||
this._el.style.width = '100%';
|
this._el.style.width = '100%';
|
||||||
|
|
||||||
this._inputContainer = DOM.append(this._el, DOM.$('.dropdown-input'));
|
this._inputContainer = DOM.append(this._el, DOM.$('.dropdown-input.select-container'));
|
||||||
this._inputContainer.style.width = '100%';
|
this._inputContainer.style.width = '100%';
|
||||||
this._treeContainer = DOM.$('.dropdown-tree');
|
this._treeContainer = DOM.$('.dropdown-tree');
|
||||||
|
|
||||||
this._toggleAction = new ToggleDropdownAction(() => {
|
|
||||||
this._showList();
|
|
||||||
this._tree.domFocus();
|
|
||||||
this._tree.focusFirst();
|
|
||||||
}, this._options.actionLabel);
|
|
||||||
|
|
||||||
this._input = new InputBox(this._inputContainer, contextViewService, {
|
this._input = new InputBox(this._inputContainer, contextViewService, {
|
||||||
validationOptions: {
|
validationOptions: {
|
||||||
// @SQLTODO
|
// @SQLTODO
|
||||||
@@ -131,7 +123,6 @@ export class Dropdown extends Disposable {
|
|||||||
validation: v => this._inputValidator(v)
|
validation: v => this._inputValidator(v)
|
||||||
},
|
},
|
||||||
placeholder: this._options.placeholder,
|
placeholder: this._options.placeholder,
|
||||||
actions: [this._toggleAction],
|
|
||||||
ariaLabel: this._options.ariaLabel
|
ariaLabel: this._options.ariaLabel
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -139,6 +130,8 @@ export class Dropdown extends Disposable {
|
|||||||
// in the text box - we already have tooltips for each item in the dropdown itself.
|
// in the text box - we already have tooltips for each item in the dropdown itself.
|
||||||
this._input.inputElement.title = '';
|
this._input.inputElement.title = '';
|
||||||
|
|
||||||
|
this._inputContainer.setAttribute('role', 'combobox');
|
||||||
|
|
||||||
this._register(DOM.addDisposableListener(this._input.inputElement, DOM.EventType.CLICK, () => {
|
this._register(DOM.addDisposableListener(this._input.inputElement, DOM.EventType.CLICK, () => {
|
||||||
this._showList();
|
this._showList();
|
||||||
}));
|
}));
|
||||||
@@ -162,14 +155,14 @@ export class Dropdown extends Disposable {
|
|||||||
if (this._treeContainer.parentElement) {
|
if (this._treeContainer.parentElement) {
|
||||||
this._input.validate();
|
this._input.validate();
|
||||||
this._onBlur.fire();
|
this._onBlur.fire();
|
||||||
this.contextViewService.hideContextView();
|
this._hideList();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KeyCode.Tab:
|
case KeyCode.Tab:
|
||||||
this._input.validate();
|
this._input.validate();
|
||||||
this._onBlur.fire();
|
this._onBlur.fire();
|
||||||
this.contextViewService.hideContextView();
|
this._hideList();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
break;
|
break;
|
||||||
case KeyCode.DownArrow:
|
case KeyCode.DownArrow:
|
||||||
@@ -205,12 +198,15 @@ export class Dropdown extends Disposable {
|
|||||||
this.value = e.value;
|
this.value = e.value;
|
||||||
this._onValueChange.fire(e.value);
|
this._onValueChange.fire(e.value);
|
||||||
this._input.focus();
|
this._input.focus();
|
||||||
this.contextViewService.hideContextView();
|
this._hideList();
|
||||||
});
|
});
|
||||||
|
|
||||||
this._controller.onDropdownEscape(() => {
|
this._controller.onDropdownEscape(() => {
|
||||||
this._input.focus();
|
this._hideList();
|
||||||
this.contextViewService.hideContextView();
|
// have to put this in the setTimeout to make sure the focus can be set properly when the context menu is opened by pressing the DownArrow key
|
||||||
|
setTimeout(() => {
|
||||||
|
this._input.focus();
|
||||||
|
}, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
this._input.onDidChange(e => {
|
this._input.onDidChange(e => {
|
||||||
@@ -225,7 +221,7 @@ export class Dropdown extends Disposable {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.onBlur(() => {
|
this.onBlur(() => {
|
||||||
this.contextViewService.hideContextView();
|
this._hideList();
|
||||||
this._input.validate();
|
this._input.validate();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -235,6 +231,7 @@ export class Dropdown extends Disposable {
|
|||||||
|
|
||||||
private _showList(): void {
|
private _showList(): void {
|
||||||
if (this._input.isEnabled()) {
|
if (this._input.isEnabled()) {
|
||||||
|
this._inputContainer.setAttribute('aria-expanded', 'true');
|
||||||
this._onFocus.fire();
|
this._onFocus.fire();
|
||||||
this._filter.filterString = '';
|
this._filter.filterString = '';
|
||||||
this.contextViewService.showContextView({
|
this.contextViewService.showContextView({
|
||||||
@@ -250,10 +247,15 @@ export class Dropdown extends Disposable {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
}, this._inputContainer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _hideList(): void {
|
||||||
|
this.contextViewService.hideContextView();
|
||||||
|
this._inputContainer.setAttribute('aria-expanded', 'false');
|
||||||
|
}
|
||||||
|
|
||||||
private _layoutTree(): void {
|
private _layoutTree(): void {
|
||||||
if (this._dataSource && this._dataSource.options && this._dataSource.options.length > 0) {
|
if (this._dataSource && this._dataSource.options && this._dataSource.options.length > 0) {
|
||||||
let filteredLength = this._dataSource.options.reduce((p, i) => {
|
let filteredLength = this._dataSource.options.reduce((p, i) => {
|
||||||
@@ -320,7 +322,7 @@ export class Dropdown extends Disposable {
|
|||||||
|
|
||||||
public blur() {
|
public blur() {
|
||||||
this._input.blur();
|
this._input.blur();
|
||||||
this.contextViewService.hideContextView();
|
this._hideList();
|
||||||
}
|
}
|
||||||
|
|
||||||
style(style: IListStyles & IInputBoxStyles & IDropdownStyles) {
|
style(style: IListStyles & IInputBoxStyles & IDropdownStyles) {
|
||||||
@@ -350,7 +352,6 @@ export class Dropdown extends Disposable {
|
|||||||
|
|
||||||
public set enabled(val: boolean) {
|
public set enabled(val: boolean) {
|
||||||
this._input.setEnabled(val);
|
this._input.setEnabled(val);
|
||||||
this._toggleAction.enabled = val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public get enabled(): boolean {
|
public get enabled(): boolean {
|
||||||
|
|||||||
Reference in New Issue
Block a user