feat(selectBox): add separator option styling and update focus outlines

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
mrleemurray
2026-02-24 17:04:04 +00:00
parent 4b94addae8
commit b834690534
3 changed files with 52 additions and 7 deletions

View File

@@ -51,11 +51,13 @@ export interface ISelectOptionItem {
descriptionIsMarkdown?: boolean;
readonly descriptionMarkdownActionHandler?: MarkdownActionHandler;
isDisabled?: boolean;
isSeparator?: boolean;
}
export const SeparatorSelectOption: Readonly<ISelectOptionItem> = Object.freeze({
text: '\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500',
isDisabled: true,
isSeparator: true,
});
export interface ISelectBoxStyles extends IListStyles {

View File

@@ -6,7 +6,7 @@
.monaco-select-box-dropdown-container {
display: none;
box-sizing: border-box;
border-radius: var(--vscode-cornerRadius-small);
border-radius: var(--vscode-cornerRadius-large);
box-shadow: 0 2px 8px var(--vscode-widget-shadow);
}
@@ -45,6 +45,11 @@
padding: 5px 6px;
}
/* Remove focus ring around the list */
.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list:focus::before {
outline: 0 !important;
}
.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row {
cursor: pointer;
padding-left: 2px;
@@ -76,6 +81,39 @@
}
/* Separator styling */
.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.option-separator {
cursor: default;
border-radius: 0;
padding: 0;
}
.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.option-separator > .option-text {
visibility: hidden;
width: 0;
float: none;
}
.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.option-separator > .option-detail {
display: none;
}
.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.option-separator > .option-decorator-right {
color: var(--vscode-descriptionForeground);
font-size: 12px;
}
.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.option-separator::after {
content: '';
position: absolute;
left: 0;
right: 0;
top: 50%;
height: 1px;
background-color: var(--vscode-menu-separatorBackground);
}
/* Accepted CSS hiding technique for accessibility reader text */
/* https://webaim.org/techniques/css/invisiblecontent/ */

View File

@@ -71,6 +71,13 @@ class SelectListRenderer implements IListRenderer<ISelectOptionItem, ISelectList
// Make sure we do class removal from prior template rendering
data.root.classList.remove('option-disabled');
}
// Separator option - show a CSS border instead of text characters
if (element.isSeparator) {
data.root.classList.add('option-separator');
} else {
data.root.classList.remove('option-separator');
}
}
disposeTemplate(_templateData: ISelectListTemplateData): void {
@@ -395,13 +402,13 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row:not(.option-disabled):not(.focused):hover { background-color: ${this.styles.listHoverBackground} !important; }`);
}
// Match quick input outline styles - ignore for disabled options
// Match action widget outline styles - ignore for disabled options
if (this.styles.listFocusOutline) {
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.focused { outline: 1.6px dotted ${this.styles.listFocusOutline} !important; outline-offset: -1.6px !important; }`);
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.focused { outline: 1px solid ${this.styles.listFocusOutline} !important; outline-offset: -1px !important; }`);
}
if (this.styles.listHoverOutline) {
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row:not(.option-disabled):not(.focused):hover { outline: 1.6px dashed ${this.styles.listHoverOutline} !important; outline-offset: -1.6px !important; }`);
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row:not(.option-disabled):not(.focused):hover { outline: 1px solid ${this.styles.listHoverOutline} !important; outline-offset: -1px !important; }`);
}
// Clear list styles on focus and on hover for disabled options
@@ -425,11 +432,9 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
const background = this.styles.selectBackground ?? '';
const listBackground = cssJs.asCssValueWithDefault(this.styles.selectListBackground, background);
this.selectDropDownContainer.style.backgroundColor = listBackground;
this.selectDropDownListContainer.style.backgroundColor = listBackground;
this.selectionDetailsPane.style.backgroundColor = listBackground;
const optionsBorder = this.styles.focusBorder ?? '';
this.selectDropDownContainer.style.outlineColor = optionsBorder;
this.selectDropDownContainer.style.outlineOffset = '-1px';
this.selectList.style(this.styles);
}