提交 519041e0 编写于 作者: C Christopher Leidigh

SelectBox: constructor, interface refactor. Addresses: #58922

上级 8275b2d7
......@@ -7,7 +7,7 @@ import 'vs/css!./actionbar';
import * as platform from 'vs/base/common/platform';
import * as nls from 'vs/nls';
import { Disposable, dispose } from 'vs/base/common/lifecycle';
import { SelectBox, ISelectBoxOptions } from 'vs/base/browser/ui/selectBox/selectBox';
import { SelectBox, ISelectOptionItem, ISelectBoxOptions } from 'vs/base/browser/ui/selectBox/selectBox';
import { IAction, IActionRunner, Action, IActionChangeEvent, ActionRunner, IRunEvent } from 'vs/base/common/actions';
import * as DOM from 'vs/base/browser/dom';
import * as types from 'vs/base/common/types';
......@@ -784,7 +784,7 @@ export class ActionBar extends Disposable implements IActionRunner {
export class SelectActionItem extends BaseActionItem {
protected selectBox: SelectBox;
constructor(ctx: any, action: IAction, options: string[], selected: number, contextViewProvider: IContextViewProvider, selectBoxOptions?: ISelectBoxOptions) {
constructor(ctx: any, action: IAction, options: ISelectOptionItem[], selected: number, contextViewProvider: IContextViewProvider, selectBoxOptions?: ISelectBoxOptions) {
super(ctx, action);
this.selectBox = new SelectBox(options, selected, contextViewProvider, null, selectBoxOptions);
......@@ -793,8 +793,8 @@ export class SelectActionItem extends BaseActionItem {
this.registerListeners();
}
setOptions(options: string[], selected?: number, disabled?: number): void {
this.selectBox.setOptions(options, selected, disabled);
setOptions(options: ISelectOptionItem[], selected?: number): void {
this.selectBox.setOptions(options, selected);
}
select(index: number): void {
......
......@@ -14,7 +14,7 @@ import { IListStyles } from 'vs/base/browser/ui/list/listWidget';
import { SelectBoxNative } from 'vs/base/browser/ui/selectBox/selectBoxNative';
import { SelectBoxList } from 'vs/base/browser/ui/selectBox/selectBoxCustom';
import { isMacintosh } from 'vs/base/common/platform';
import { IContentActionHandler } from 'vs/base/browser/htmlContentRenderer';
// Public SelectBox interface - Calls routed to appropriate select implementation class
......@@ -22,10 +22,9 @@ export interface ISelectBoxDelegate {
// Public SelectBox Interface
readonly onDidSelect: Event<ISelectData>;
setOptions(options: string[], selected?: number, disabled?: number): void;
setOptions(options: ISelectOptionItem[], selected?: number);
select(index: number): void;
setAriaLabel(label: string);
setDetailsProvider(provider: (index: number) => { details: string, isMarkdown: boolean });
focus(): void;
blur(): void;
dispose(): void;
......@@ -37,10 +36,18 @@ export interface ISelectBoxDelegate {
}
export interface ISelectBoxOptions {
useCustomSelectBox?: boolean;
ariaLabel?: string;
minBottomMargin?: number;
hasDetails?: boolean;
markdownActionHandler?: IContentActionHandler;
}
// Utilize optionItem interface to capture all option parameters
export interface ISelectOptionItem {
optionText: string;
optionDecorationRight?: string;
optionItemDescription?: string;
optionItemDescriptionIsMarkdown?: boolean;
isDisabled?: boolean;
}
export interface ISelectBoxStyles extends IListStyles {
......@@ -67,13 +74,13 @@ export class SelectBox extends Widget implements ISelectBoxDelegate {
private styles: ISelectBoxStyles;
private selectBoxDelegate: ISelectBoxDelegate;
constructor(options: string[], selected: number, contextViewProvider: IContextViewProvider, styles: ISelectBoxStyles = deepClone(defaultStyles), selectBoxOptions?: ISelectBoxOptions) {
constructor(options: ISelectOptionItem[], selected: number, contextViewProvider: IContextViewProvider, styles: ISelectBoxStyles = deepClone(defaultStyles), selectBoxOptions?: ISelectBoxOptions) {
super();
mixin(this.styles, defaultStyles, false);
// Instantiate select implementation based on platform
if (isMacintosh && !(selectBoxOptions && selectBoxOptions.hasDetails)) {
// Default to native SelectBox for OSX unless overridden
if (isMacintosh && !(selectBoxOptions && selectBoxOptions.useCustomSelectBox)) {
this.selectBoxDelegate = new SelectBoxNative(options, selected, styles, selectBoxOptions);
} else {
this.selectBoxDelegate = new SelectBoxList(options, selected, contextViewProvider, styles, selectBoxOptions);
......@@ -88,8 +95,8 @@ export class SelectBox extends Widget implements ISelectBoxDelegate {
return this.selectBoxDelegate.onDidSelect;
}
public setOptions(options: string[], selected?: number, disabled?: number): void {
this.selectBoxDelegate.setOptions(options, selected, disabled);
public setOptions(options: ISelectOptionItem[], selected?: number): void {
this.selectBoxDelegate.setOptions(options, selected);
}
public select(index: number): void {
......@@ -100,10 +107,6 @@ export class SelectBox extends Widget implements ISelectBoxDelegate {
this.selectBoxDelegate.setAriaLabel(label);
}
public setDetailsProvider(provider: (index: number) => { details: string, isMarkdown: boolean }): void {
this.selectBoxDelegate.setDetailsProvider(provider);
}
public focus(): void {
this.selectBoxDelegate.focus();
}
......
......@@ -16,7 +16,7 @@ import { List } from 'vs/base/browser/ui/list/listWidget';
import { IListVirtualDelegate, IListRenderer, IListEvent } from 'vs/base/browser/ui/list/list';
import { domEvent } from 'vs/base/browser/event';
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
import { ISelectBoxDelegate, ISelectBoxOptions, ISelectBoxStyles, ISelectData } from 'vs/base/browser/ui/selectBox/selectBox';
import { ISelectBoxDelegate, ISelectOptionItem, ISelectBoxOptions, ISelectBoxStyles, ISelectData } from 'vs/base/browser/ui/selectBox/selectBox';
import { isMacintosh } from 'vs/base/common/platform';
import { renderMarkdown } from 'vs/base/browser/htmlContentRenderer';
......@@ -24,16 +24,10 @@ const $ = dom.$;
const SELECT_OPTION_ENTRY_TEMPLATE_ID = 'selectOption.entry.template';
export interface ISelectOptionItem {
optionText: string;
optionDescriptionText?: string;
optionDisabled: boolean;
}
interface ISelectListTemplateData {
root: HTMLElement;
optionText: HTMLElement;
optionDescriptionText: HTMLElement;
optionItemDescription: HTMLElement;
disposables: IDisposable[];
}
......@@ -48,8 +42,8 @@ class SelectListRenderer implements IListRenderer<ISelectOptionItem, ISelectList
data.disposables = [];
data.root = container;
data.optionText = dom.append(container, $('.option-text'));
data.optionDescriptionText = dom.append(container, $('.option-text-description'));
dom.addClass(data.optionDescriptionText, 'visually-hidden');
data.optionItemDescription = dom.append(container, $('.option-text-description'));
dom.addClass(data.optionItemDescription, 'visually-hidden');
return data;
}
......@@ -57,19 +51,19 @@ class SelectListRenderer implements IListRenderer<ISelectOptionItem, ISelectList
renderElement(element: ISelectOptionItem, index: number, templateData: ISelectListTemplateData): void {
const data = <ISelectListTemplateData>templateData;
const optionText = (<ISelectOptionItem>element).optionText;
const optionDisabled = (<ISelectOptionItem>element).optionDisabled;
const isDisabled = (<ISelectOptionItem>element).isDisabled;
data.optionText.textContent = optionText;
if (typeof element.optionDescriptionText === 'string') {
const optionDescriptionId = (optionText.replace(/ /g, '_').toLowerCase() + '_description_' + data.root.id);
data.optionText.setAttribute('aria-describedby', optionDescriptionId);
data.optionDescriptionText.id = optionDescriptionId;
data.optionDescriptionText.innerText = element.optionDescriptionText;
if (typeof element.optionItemDescription === 'string') {
const optionItemDescriptionId = (optionText.replace(/ /g, '_').toLowerCase() + '_description_' + data.root.id);
data.optionText.setAttribute('aria-describedby', optionItemDescriptionId);
data.optionItemDescription.id = optionItemDescriptionId;
data.optionItemDescription.innerText = element.optionItemDescription;
}
// pseudo-select disabled option
if (optionDisabled) {
if (isDisabled) {
dom.addClass((<HTMLElement>data.root), 'option-disabled');
} else {
// Make sure we do class removal from prior template rendering
......@@ -95,9 +89,8 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
private _isVisible: boolean;
private selectBoxOptions: ISelectBoxOptions;
private selectElement: HTMLSelectElement;
private options: string[];
private options: ISelectOptionItem[];
private selected: number;
private disabledOptionIndex: number;
private readonly _onDidSelect: Emitter<ISelectData>;
private toDispose: IDisposable[];
private styles: ISelectBoxStyles;
......@@ -110,13 +103,13 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
private widthControlElement: HTMLElement;
private _currentSelection: number;
private _dropDownPosition: AnchorPosition;
private detailsProvider: (index: number) => { details: string, isMarkdown: boolean };
private _hasDetails: boolean = false;
private selectionDetailsPane: HTMLElement;
private _skipLayout: boolean = false;
private _sticky: boolean = true; // for dev purposes only
constructor(options: string[], selected: number, contextViewProvider: IContextViewProvider, styles: ISelectBoxStyles, selectBoxOptions?: ISelectBoxOptions) {
constructor(options: ISelectOptionItem[], selected: number, contextViewProvider: IContextViewProvider, styles: ISelectBoxStyles, selectBoxOptions?: ISelectBoxOptions) {
this.toDispose = [];
this._isVisible = false;
......@@ -251,19 +244,18 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
return this._onDidSelect.event;
}
public setOptions(options: string[], selected?: number, disabled?: number): void {
public setOptions(options: ISelectOptionItem[], selected?: number): void {
if (!this.options || !arrays.equals(this.options, options)) {
this.options = options;
this.selectElement.options.length = 0;
this._hasDetails = false;
let i = 0;
this.options.forEach((option) => {
this.selectElement.add(this.createOption(option, i, disabled === i++));
this.options.map((option, index) => {
this.selectElement.add(this.createOption(option.optionText, index, option.isDisabled));
if (typeof option.optionItemDescription === 'string') {
this._hasDetails = true;
}
});
if (disabled !== undefined) {
this.disabledOptionIndex = disabled;
}
}
if (selected !== undefined) {
......@@ -279,18 +271,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
// Mirror options in drop-down
// Populate select list for non-native select mode
if (this.selectList && !!this.options) {
let listEntries: ISelectOptionItem[];
listEntries = [];
for (let index = 0; index < this.options.length; index++) {
const element = this.options[index];
let optionDisabled: boolean;
index === this.disabledOptionIndex ? optionDisabled = true : optionDisabled = false;
const optionDescription = this.detailsProvider ? this.detailsProvider(index) : { details: undefined, isMarkdown: false };
listEntries.push({ optionText: element, optionDisabled: optionDisabled, optionDescriptionText: optionDescription.details });
}
this.selectList.splice(0, this.selectList.length, listEntries);
this.selectList.splice(0, this.selectList.length, this.options);
}
}
......@@ -314,10 +295,6 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
this.selectElement.setAttribute('aria-label', this.selectBoxOptions.ariaLabel);
}
public setDetailsProvider(provider: (index: number) => { details: string, isMarkdown: boolean }): void {
this.detailsProvider = provider;
}
public focus(): void {
if (this.selectElement) {
this.selectElement.focus();
......@@ -522,23 +499,16 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
// Iterate over detailed descriptions, find max height
private measureMaxDetailsHeight(): number {
if (!this.detailsProvider) {
return 0;
}
let maxDetailsPaneHeight = 0;
let description = { details: '', isMarkdown: false };
this.options.forEach((option, index) => {
this.selectionDetailsPane.innerText = '';
description = this.detailsProvider ? this.detailsProvider(index) : { details: '', isMarkdown: false };
if (description.details) {
if (description.isMarkdown) {
this.selectionDetailsPane.appendChild(this.renderDescriptionMarkdown(description.details));
if (option.optionItemDescription) {
if (option.optionItemDescriptionIsMarkdown) {
this.selectionDetailsPane.appendChild(this.renderDescriptionMarkdown(option.optionItemDescription));
} else {
this.selectionDetailsPane.innerText = description.details;
this.selectionDetailsPane.innerText = option.optionItemDescription;
}
this.selectionDetailsPane.style.display = 'block';
} else {
......@@ -551,18 +521,19 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
});
// Reset description to selected
description = this.detailsProvider ? this.detailsProvider(this.selected) : { details: '', isMarkdown: false };
this.selectionDetailsPane.innerText = '';
const optionItemDescription = this.options[this.selected].optionItemDescription || null;
const optionItemDescriptionIsMarkdown = this.options[this.selected].optionItemDescriptionIsMarkdown || null;
if (description.details) {
if (description.isMarkdown) {
this.selectionDetailsPane.appendChild(this.renderDescriptionMarkdown(description.details));
if (optionItemDescription) {
if (optionItemDescriptionIsMarkdown) {
this.selectionDetailsPane.appendChild(this.renderDescriptionMarkdown(optionItemDescription));
} else {
this.selectionDetailsPane.innerText = description.details;
this.selectionDetailsPane.innerText = optionItemDescription;
}
this.selectionDetailsPane.style.display = 'block';
}
return maxDetailsPaneHeight;
}
......@@ -599,7 +570,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
this.selectList.layout();
let listHeight = this.selectList.contentHeight;
const maxDetailsPaneHeight = this.measureMaxDetailsHeight();
const maxDetailsPaneHeight = this._hasDetails ? this.measureMaxDetailsHeight() : 0;
const minRequiredDropDownHeight = listHeight + verticalPadding + maxDetailsPaneHeight;
const maxVisibleOptionsBelow = ((Math.floor((maxSelectDropDownHeightBelow - verticalPadding - maxDetailsPaneHeight) / this.getHeight())));
......@@ -691,7 +662,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
this.selectList.reveal(this.selectList.getFocus()[0] || 0);
}
if (this.detailsProvider) {
if (this._hasDetails) {
// Leave the selectDropDownContainer to size itself according to children (list + details) - #57447
this.selectList.getHTMLElement().style.height = (listHeight + verticalPadding) + 'px';
} else {
......@@ -718,12 +689,12 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
let longest = 0;
for (let index = 0; index < this.options.length; index++) {
if (this.options[index].length > this.options[longest].length) {
if (this.options[index].optionText.length > this.options[longest].optionText.length) {
longest = index;
}
}
container.innerHTML = this.options[longest];
container.innerHTML = this.options[longest].optionText;
elementWidth = dom.getTotalWidth(container);
}
......@@ -825,7 +796,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
this._onDidSelect.fire({
index: this.selectElement.selectedIndex,
selected: this.options[this.selected]
selected: this.options[this.selected].optionText
});
}
......@@ -859,9 +830,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
}
};
const renderedMarkdown = renderMarkdown({ value: text }, {
actionHandler: this.selectBoxOptions.markdownActionHandler
});
const renderedMarkdown = renderMarkdown({ value: text });
renderedMarkdown.classList.add('select-box-description-markdown');
cleanRenderedMarkdown(renderedMarkdown);
......@@ -872,18 +841,20 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
// List Focus Change - passive - update details pane with newly focused element's data
private onListFocus(e: IListEvent<ISelectOptionItem>) {
// Skip during initial layout
if (!this._isVisible) {
if (!this._isVisible || !this._hasDetails) {
return;
}
this.selectionDetailsPane.innerText = '';
const selectedIndex = e.indexes[0];
let description = this.detailsProvider ? this.detailsProvider(selectedIndex) : { details: '', isMarkdown: false };
if (description.details) {
if (description.isMarkdown) {
this.selectionDetailsPane.appendChild(this.renderDescriptionMarkdown(description.details));
const optionItemDescription = this.options[selectedIndex].optionItemDescription || null;
const optionItemDescriptionIsMarkdown = this.options[selectedIndex].optionItemDescriptionIsMarkdown || null;
if (optionItemDescription) {
if (optionItemDescriptionIsMarkdown) {
this.selectionDetailsPane.appendChild(this.renderDescriptionMarkdown(optionItemDescription));
} else {
this.selectionDetailsPane.innerText = description.details;
this.selectionDetailsPane.innerText = optionItemDescription;
}
this.selectionDetailsPane.style.display = 'block';
} else {
......@@ -917,7 +888,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
this._currentSelection = this.selected;
this._onDidSelect.fire({
index: this.selectElement.selectedIndex,
selected: this.options[this.selected]
selected: this.options[this.selected].optionText
});
}
......@@ -927,14 +898,18 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
// List navigation - have to handle a disabled option (jump over)
private onDownArrow(): void {
if (this.selected < this.options.length - 1) {
// Skip disabled options
if ((this.selected + 1) === this.disabledOptionIndex && this.options.length > this.selected + 2) {
const nextOptionDisabled = this.options[this.selected + 1].isDisabled;
if (nextOptionDisabled && this.options.length > this.selected + 2) {
this.selected += 2;
} else if ((this.selected + 1) === this.disabledOptionIndex) {
} else if (nextOptionDisabled) {
return;
} else {
this.selected++;
}
// Set focus/selection - only fire event when closing drop-down or on blur
this.select(this.selected);
this.selectList.setFocus([this.selected]);
......@@ -945,7 +920,8 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
private onUpArrow(): void {
if (this.selected > 0) {
// Skip disabled options
if ((this.selected - 1) === this.disabledOptionIndex && this.selected > 1) {
const previousOptionDisabled = this.options[this.selected - 1].isDisabled;
if (previousOptionDisabled && this.selected > 1) {
this.selected -= 2;
} else {
this.selected--;
......@@ -967,7 +943,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
this.selected = this.selectList.getFocus()[0];
// Shift selection down if we land on a disabled option
if (this.selected === this.disabledOptionIndex && this.selected < this.options.length - 1) {
if (this.options[this.selected].isDisabled && this.selected < this.options.length - 1) {
this.selected++;
this.selectList.setFocus([this.selected]);
}
......@@ -986,7 +962,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
this.selected = this.selectList.getFocus()[0];
// Shift selection up if we land on a disabled option
if (this.selected === this.disabledOptionIndex && this.selected > 0) {
if (this.options[this.selected].isDisabled && this.selected > 0) {
this.selected--;
this.selectList.setFocus([this.selected]);
}
......@@ -1002,7 +978,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
return;
}
this.selected = 0;
if (this.selected === this.disabledOptionIndex && this.selected > 1) {
if (this.options[this.selected].isDisabled && this.selected > 1) {
this.selected++;
}
this.selectList.setFocus([this.selected]);
......@@ -1017,7 +993,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
return;
}
this.selected = this.options.length - 1;
if (this.selected === this.disabledOptionIndex && this.selected > 1) {
if (this.options[this.selected].isDisabled && this.selected > 1) {
this.selected--;
}
this.selectList.setFocus([this.selected]);
......@@ -1032,7 +1008,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
for (let i = 0; i < this.options.length - 1; i++) {
optionIndex = (i + this.selected + 1) % this.options.length;
if (this.options[optionIndex].charAt(0).toUpperCase() === ch) {
if (this.options[optionIndex].optionText.charAt(0).toUpperCase() === ch && !this.options[optionIndex].isDisabled) {
this.select(optionIndex);
this.selectList.setFocus([optionIndex]);
this.selectList.reveal(this.selectList.getFocus()[0]);
......
......@@ -8,24 +8,25 @@ import { Event, Emitter } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes';
import * as dom from 'vs/base/browser/dom';
import * as arrays from 'vs/base/common/arrays';
import { ISelectBoxDelegate, ISelectBoxOptions, ISelectBoxStyles, ISelectData } from 'vs/base/browser/ui/selectBox/selectBox';
import { ISelectBoxDelegate, ISelectOptionItem, ISelectBoxOptions, ISelectBoxStyles, ISelectData } from 'vs/base/browser/ui/selectBox/selectBox';
import { isMacintosh } from 'vs/base/common/platform';
export class SelectBoxNative implements ISelectBoxDelegate {
private selectElement: HTMLSelectElement;
private selectBoxOptions: ISelectBoxOptions;
private options: string[];
private options: ISelectOptionItem[];
private selected: number;
private readonly _onDidSelect: Emitter<ISelectData>;
private toDispose: IDisposable[];
private styles: ISelectBoxStyles;
constructor(options: string[], selected: number, styles: ISelectBoxStyles, selectBoxOptions?: ISelectBoxOptions) {
constructor(options: ISelectOptionItem[], selected: number, styles: ISelectBoxStyles, selectBoxOptions?: ISelectBoxOptions) {
this.toDispose = [];
this.selectBoxOptions = selectBoxOptions || Object.create(null);
this.options = [];
this.selectElement = document.createElement('select');
// Workaround for Electron 2.x
......@@ -83,15 +84,14 @@ export class SelectBoxNative implements ISelectBoxDelegate {
return this._onDidSelect.event;
}
public setOptions(options: string[], selected?: number, disabled?: number): void {
public setOptions(options: ISelectOptionItem[], selected?: number): void {
if (!this.options || !arrays.equals(this.options, options)) {
this.options = options;
this.selectElement.options.length = 0;
let i = 0;
this.options.forEach((option) => {
this.selectElement.add(this.createOption(option, i, disabled === i++));
this.options.map((option, index) => {
this.selectElement.add(this.createOption(option.optionText, index, option.isDisabled));
});
}
......@@ -102,7 +102,9 @@ export class SelectBoxNative implements ISelectBoxDelegate {
}
public select(index: number): void {
if (index >= 0 && index < this.options.length) {
if (this.options.length === 0) {
this.selected = 0;
} else if (index >= 0 && index < this.options.length) {
this.selected = index;
} else if (index > this.options.length - 1) {
// Adjust index to end of list
......@@ -113,7 +115,11 @@ export class SelectBoxNative implements ISelectBoxDelegate {
}
this.selectElement.selectedIndex = this.selected;
this.selectElement.title = this.options[this.selected];
if (this.options.length && typeof this.options[this.selected].optionText === 'string') {
this.selectElement.title = this.options[this.selected].optionText;
} else {
this.selectElement.title = '';
}
}
public setAriaLabel(label: string): void {
......@@ -121,10 +127,6 @@ export class SelectBoxNative implements ISelectBoxDelegate {
this.selectElement.setAttribute('aria-label', label);
}
public setDetailsProvider(provider: any): void {
console.error('details are not available for native select boxes');
}
public focus(): void {
if (this.selectElement) {
this.selectElement.focus();
......
......@@ -8,7 +8,7 @@ import { IAction, IActionRunner } from 'vs/base/common/actions';
import { KeyCode } from 'vs/base/common/keyCodes';
import * as dom from 'vs/base/browser/dom';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { SelectBox } from 'vs/base/browser/ui/selectBox/selectBox';
import { SelectBox, ISelectOptionItem } from 'vs/base/browser/ui/selectBox/selectBox';
import { SelectActionItem, IActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ICommandService } from 'vs/platform/commands/common/commands';
......@@ -184,7 +184,7 @@ export class StartDebugActionItem implements IActionItem {
});
});
this.selectBox.setOptions(this.options.map(data => data.label), this.selected, disabledIdx);
this.selectBox.setOptions(this.options.map((data, index) => <ISelectOptionItem>{ optionText: data.label, isDisabled: (index === disabledIdx ? true : undefined) }), this.selected);
}
}
......@@ -217,7 +217,7 @@ export class FocusSessionActionItem extends SelectActionItem {
const session = this.debugService.getViewModel().focusedSession;
const sessions = this.getSessions();
const names = sessions.map(s => s.getLabel());
this.setOptions(names, session ? sessions.indexOf(session) : undefined);
this.setOptions(names.map(data => <ISelectOptionItem>{ optionText: data }), session ? sessions.indexOf(session) : undefined);
}
protected getSessions(): ReadonlyArray<IDebugSession> {
......
......@@ -6,7 +6,7 @@
import 'vs/css!../browser/media/breakpointWidget';
import * as nls from 'vs/nls';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { SelectBox } from 'vs/base/browser/ui/selectBox/selectBox';
import { SelectBox, ISelectOptionItem } from 'vs/base/browser/ui/selectBox/selectBox';
import * as lifecycle from 'vs/base/common/lifecycle';
import * as dom from 'vs/base/browser/dom';
import { Position, IPosition } from 'vs/editor/common/core/position';
......@@ -139,7 +139,7 @@ export class BreakpointWidget extends ZoneWidget implements IPrivateBreakpointWi
protected _fillContainer(container: HTMLElement): void {
this.setCssClass('breakpoint-widget');
const selectBox = new SelectBox([nls.localize('expression', "Expression"), nls.localize('hitCount', "Hit Count"), nls.localize('logMessage', "Log Message")], this.context, this.contextViewService, null, { ariaLabel: nls.localize('breakpointType', 'Breakpoint Type') });
const selectBox = new SelectBox(<ISelectOptionItem[]>[{ optionText: nls.localize('expression', "Expression") }, { optionText: nls.localize('hitCount', "Hit Count") }, { optionText: nls.localize('logMessage', "Log Message") }], this.context, this.contextViewService, null, { ariaLabel: nls.localize('breakpointType', 'Breakpoint Type') });
this.toDispose.push(attachSelectBoxStyler(selectBox, this.themeService));
this.selectContainer = $('.breakpoint-select-container');
selectBox.render(dom.append(container, this.selectContainer));
......
......@@ -21,6 +21,7 @@ import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/commo
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { LogViewerInput } from 'vs/workbench/parts/output/browser/logViewer';
import { ISelectOptionItem } from 'vs/base/browser/ui/selectBox/selectBox';
export class ToggleOutputAction extends TogglePanelAction {
......@@ -160,7 +161,7 @@ export class SwitchOutputActionItem extends SelectActionItem {
selected = logChannelIndex !== -1 ? separatorIndex + 1 + logChannelIndex : 0;
}
}
this.setOptions(options, Math.max(0, selected), separatorIndex !== -1 ? separatorIndex : void 0);
this.setOptions(options.map((label, index) => <ISelectOptionItem>{ optionText: label, isDisabled: (index === separatorIndex ? true : undefined) }), Math.max(0, selected));
}
}
......
......@@ -12,7 +12,7 @@ import { alert as ariaAlert } from 'vs/base/browser/ui/aria/aria';
import { Button } from 'vs/base/browser/ui/button/button';
import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox';
import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox';
import { SelectBox } from 'vs/base/browser/ui/selectBox/selectBox';
import { SelectBox, ISelectOptionItem } from 'vs/base/browser/ui/selectBox/selectBox';
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
import { Action, IAction } from 'vs/base/common/actions';
import * as arrays from 'vs/base/common/arrays';
......@@ -841,9 +841,7 @@ export class SettingsRenderer implements ITreeRenderer {
private renderSettingEnumTemplate(tree: ITree, container: HTMLElement): ISettingEnumItemTemplate {
const common = this.renderCommonTemplate(tree, container, 'enum');
const selectBox = new SelectBox([], undefined, this.contextViewService, undefined, {
hasDetails: true
});
const selectBox = new SelectBox([], undefined, this.contextViewService, undefined, { useCustomSelectBox: true });
common.toDispose.push(selectBox);
common.toDispose.push(attachSelectBoxStyler(selectBox, this.themeService, {
......@@ -1165,18 +1163,20 @@ export class SettingsRenderer implements ITreeRenderer {
}
private renderEnum(dataElement: SettingsTreeSettingElement, template: ISettingEnumItemTemplate, onChange: (value: string) => void): void {
const displayOptions = dataElement.setting.enum
.map(String)
.map(escapeInvisibleChars);
template.selectBox.setOptions(displayOptions);
const enumDescriptions = dataElement.setting.enumDescriptions;
const enumDescriptionsAreMarkdown = dataElement.setting.enumDescriptionsAreMarkdown;
template.selectBox.setDetailsProvider(index =>
({
details: enumDescriptions && enumDescriptions[index] && (enumDescriptionsAreMarkdown ? fixSettingLinks(enumDescriptions[index], false) : enumDescriptions[index]),
isMarkdown: enumDescriptionsAreMarkdown
}));
let displayOptions = dataElement.setting.enum
.map(String)
.map(escapeInvisibleChars)
.map((data, index) => <ISelectOptionItem>{
optionText: data,
optionItemDescription: (enumDescriptions && enumDescriptions[index] && (enumDescriptionsAreMarkdown ? fixSettingLinks(enumDescriptions[index], false) : enumDescriptions[index])),
optionItemDescriptionIsMarkdown: enumDescriptionsAreMarkdown
});
template.selectBox.setOptions(displayOptions);
const label = this.setElementAriaLabels(dataElement, SETTINGS_ENUM_TEMPLATE_ID, template);
template.selectBox.setAriaLabel(label);
......
......@@ -29,6 +29,7 @@ import { TERMINAL_COMMAND_ID } from 'vs/workbench/parts/terminal/common/terminal
import { Command } from 'vs/editor/browser/editorExtensions';
import { timeout } from 'vs/base/common/async';
import { FindReplaceState } from 'vs/editor/contrib/find/findState';
import { ISelectOptionItem } from 'vs/base/browser/ui/selectBox/selectBox';
export const TERMINAL_PICKER_PREFIX = 'term ';
......@@ -725,7 +726,7 @@ export class SwitchTerminalActionItem extends SelectActionItem {
@IThemeService themeService: IThemeService,
@IContextViewService contextViewService: IContextViewService
) {
super(null, action, terminalService.getTabLabels(), terminalService.activeTabIndex, contextViewService, { ariaLabel: nls.localize('terminals', 'Open Terminals.') });
super(null, action, terminalService.getTabLabels().map(label => <ISelectOptionItem>{ optionText: label }), terminalService.activeTabIndex, contextViewService, { ariaLabel: nls.localize('terminals', 'Open Terminals.') });
this.toDispose.push(terminalService.onInstancesChanged(this._updateItems, this));
this.toDispose.push(terminalService.onActiveTabChanged(this._updateItems, this));
......@@ -734,7 +735,7 @@ export class SwitchTerminalActionItem extends SelectActionItem {
}
private _updateItems(): void {
this.setOptions(this.terminalService.getTabLabels(), this.terminalService.activeTabIndex);
this.setOptions(this.terminalService.getTabLabels().map(label => <ISelectOptionItem>{ optionText: label }), this.terminalService.activeTabIndex);
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册