Skip to content

Commit 7e868f4

Browse files
committed
Tweaks to the list row focus settings list
- Change styling to look like notebooks - Add hover decoration - Add inactive focus styling - Keybindings/interaction tweaks - Make toolbar gear show up when row is focused, and make it tabbable - Revert "custom select box: react on KEY_UP to be aligned with actionBar so appropriate event gets canceled" This reverts commit 1a2a371.
1 parent e8c0b50 commit 7e868f4

5 files changed

Lines changed: 158 additions & 47 deletions

File tree

src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,14 @@
175175

176176
.settings-editor > .settings-body .settings-tree-container .setting-toolbar-container {
177177
position: absolute;
178-
left: -32px;
178+
left: -22px;
179179
top: 11px;
180180
bottom: 0px;
181181
width: 26px;
182182
}
183183

184184
.settings-editor > .settings-body .settings-tree-container .monaco-list-row .mouseover .setting-toolbar-container > .monaco-toolbar .codicon,
185-
.settings-editor > .settings-body .settings-tree-container .monaco-list-row .setting-item-contents.focused .setting-toolbar-container > .monaco-toolbar .codicon,
185+
.settings-editor > .settings-body .settings-tree-container .monaco-list-row.focused .setting-item-contents .setting-toolbar-container > .monaco-toolbar .codicon,
186186
.settings-editor > .settings-body .settings-tree-container .monaco-list-row .setting-toolbar-container:hover > .monaco-toolbar .codicon,
187187
.settings-editor > .settings-body .settings-tree-container .monaco-list-row .setting-toolbar-container > .monaco-toolbar .active .codicon {
188188
opacity: 1;
@@ -283,15 +283,34 @@
283283
max-width: 1000px;
284284
margin: auto;
285285
box-sizing: border-box;
286-
padding-left: 219px;
287-
padding-right: 20px;
286+
padding-left: 204px;
287+
padding-right: 5px;
288288
overflow: visible;
289289
}
290290

291+
.settings-editor > .settings-body > .settings-tree-container .settings-group-title-label::before,
292+
.settings-editor > .settings-body > .settings-tree-container .settings-group-title-label::after,
293+
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents::before,
294+
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents::after {
295+
content: ' ';
296+
position: absolute;
297+
left: 0px;
298+
right: 0px;
299+
}
300+
301+
.settings-editor > .settings-body > .settings-tree-container .settings-group-title-label::before,
302+
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents::before {
303+
top: 0px;
304+
}
305+
306+
.settings-editor > .settings-body > .settings-tree-container .settings-group-title-label::after,
307+
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents::after {
308+
bottom: 0px;
309+
}
310+
291311
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents {
292312
position: relative;
293-
padding-top: 12px;
294-
padding-bottom: 18px;
313+
padding: 12px 15px 18px;
295314
white-space: normal;
296315
}
297316

@@ -300,12 +319,7 @@
300319
overflow: hidden;
301320
text-overflow: ellipsis;
302321
display: inline-block; /* size to contents for hover to show context button */
303-
border-radius: 5px;
304322
}
305-
.settings-editor > .settings-body > .settings-tree-container .monaco-list-row.focused.selected .setting-item-contents .setting-item-title {
306-
padding-left: 7px;
307-
}
308-
309323

310324
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-modified-indicator {
311325
display: none;
@@ -318,7 +332,7 @@
318332
width: 6px;
319333
border-left-width: 2px;
320334
border-left-style: solid;
321-
left: -9px;
335+
left: 5px;
322336
top: 15px;
323337
bottom: 16px;
324338
}
@@ -536,13 +550,10 @@
536550
font-weight: 600;
537551
height: 100%;
538552
box-sizing: border-box;
539-
border-radius: 5px;
540553
padding: 10px;
541-
padding-left: 0;
542-
}
543-
544-
.settings-editor > .settings-body > .settings-tree-container .monaco-list-row.selected .settings-group-title-label {
545-
padding-left: 10px;
554+
padding-left: 15px;
555+
width: 100%;
556+
position: relative;
546557
}
547558

548559
.settings-editor > .settings-body > .settings-tree-container .settings-group-level-1 {

src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import * as nls from 'vs/nls';
1212
import { Action2, MenuId, MenuRegistry, registerAction2 } from 'vs/platform/actions/common/actions';
1313
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
1414
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
15-
import { IsMacNativeContext } from 'vs/platform/contextkey/common/contextkeys';
15+
import { InputFocusedContext, IsMacNativeContext } from 'vs/platform/contextkey/common/contextkeys';
1616
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
1717
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
1818
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
@@ -50,6 +50,8 @@ const SETTINGS_EDITOR_COMMAND_EDIT_FOCUSED_SETTING = 'settings.action.editFocuse
5050
const SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_FROM_SEARCH = 'settings.action.focusSettingsFromSearch';
5151
const SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_LIST = 'settings.action.focusSettingsList';
5252
const SETTINGS_EDITOR_COMMAND_FOCUS_TOC = 'settings.action.focusTOC';
53+
const SETTINGS_EDITOR_COMMAND_FOCUS_TOC2 = 'settings.action.focusTOC2';
54+
const SETTINGS_EDITOR_COMMAND_FOCUS_CONTROL = 'settings.action.focusSettingControl';
5355

5456
const SETTINGS_EDITOR_COMMAND_SWITCH_TO_JSON = 'settings.switchToJSON';
5557
const SETTINGS_EDITOR_COMMAND_FILTER_MODIFIED = 'settings.filterByModified';
@@ -711,20 +713,76 @@ class PreferencesActionsContribution extends Disposable implements IWorkbenchCon
711713
constructor() {
712714
super({
713715
id: SETTINGS_EDITOR_COMMAND_FOCUS_TOC,
716+
keybinding: [
717+
{
718+
primary: KeyCode.Escape,
719+
weight: KeybindingWeight.WorkbenchContrib,
720+
when: ContextKeyExpr.and(CONTEXT_SETTINGS_EDITOR, CONTEXT_TOC_ROW_FOCUS.negate()),
721+
},
722+
{
723+
primary: KeyCode.LeftArrow,
724+
weight: KeybindingWeight.WorkbenchContrib,
725+
when: ContextKeyExpr.and(CONTEXT_SETTINGS_EDITOR, CONTEXT_TOC_ROW_FOCUS.negate(), InputFocusedContext.negate())
726+
}],
727+
title: nls.localize('settings.focusSettingsTOC', "Focus settings TOC tree")
728+
});
729+
}
730+
731+
run(accessor: ServicesAccessor): void {
732+
const preferencesEditor = getPreferencesEditor(accessor);
733+
if (!(preferencesEditor instanceof SettingsEditor2)) {
734+
return;
735+
}
736+
737+
if (document.activeElement?.classList.contains('monaco-list')) {
738+
preferencesEditor.focusTOC();
739+
} else {
740+
preferencesEditor.focusSettings();
741+
}
742+
}
743+
});
744+
745+
registerAction2(class extends Action2 {
746+
constructor() {
747+
super({
748+
id: SETTINGS_EDITOR_COMMAND_FOCUS_CONTROL,
714749
precondition: ContextKeyExpr.and(CONTEXT_SETTINGS_EDITOR, CONTEXT_TOC_ROW_FOCUS.negate()),
715750
keybinding: {
716-
primary: KeyCode.Escape,
751+
primary: KeyCode.Enter,
717752
weight: KeybindingWeight.WorkbenchContrib,
718753
},
754+
title: nls.localize('settings.focusSettingControl', "Focus setting control")
755+
});
756+
}
757+
758+
run(accessor: ServicesAccessor): void {
759+
const preferencesEditor = getPreferencesEditor(accessor);
760+
if (!(preferencesEditor instanceof SettingsEditor2)) {
761+
return;
762+
}
763+
764+
if (document.activeElement?.classList.contains('monaco-list')) {
765+
preferencesEditor.focusSettings(true);
766+
}
767+
}
768+
});
769+
770+
registerAction2(class extends Action2 {
771+
constructor() {
772+
super({
773+
id: SETTINGS_EDITOR_COMMAND_FOCUS_TOC2,
774+
719775
title: nls.localize('settings.focusSettingsTOC', "Focus settings TOC tree")
720776
});
721777
}
722778

723779
run(accessor: ServicesAccessor): void {
724780
const preferencesEditor = getPreferencesEditor(accessor);
725-
if (preferencesEditor instanceof SettingsEditor2) {
726-
preferencesEditor.focusTOC();
781+
if (!(preferencesEditor instanceof SettingsEditor2)) {
782+
return;
727783
}
784+
785+
preferencesEditor.focusTOC();
728786
}
729787
});
730788

src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,8 @@ export class SettingsEditor2 extends BaseEditor {
348348
}
349349
}
350350

351-
focusSettings(): void {
351+
focusSettings(focusSettingInput = false): void {
352+
// TODO@roblourens is this in the right place?
352353
// Update ARIA global labels
353354
const labelElement = this.settingsAriaExtraLabelsContainer.querySelector('#settings_aria_more_actions_shortcut_label');
354355
if (labelElement) {
@@ -358,9 +359,18 @@ export class SettingsEditor2 extends BaseEditor {
358359
}
359360
}
360361

361-
const firstFocusable = this.settingsTree.getHTMLElement().querySelector(AbstractSettingRenderer.CONTROL_SELECTOR);
362-
if (firstFocusable) {
363-
(<HTMLElement>firstFocusable).focus();
362+
const focused = this.settingsTree.getFocus();
363+
if (!focused.length) {
364+
this.settingsTree.focusFirst();
365+
}
366+
367+
this.settingsTree.domFocus();
368+
369+
if (focusSettingInput) {
370+
const controlInFocusedRow = this.settingsTree.getHTMLElement().querySelector(`.focused ${AbstractSettingRenderer.CONTROL_SELECTOR}`);
371+
if (controlInFocusedRow) {
372+
(<HTMLElement>controlInFocusedRow).focus();
373+
}
364374
}
365375
}
366376

src/vs/workbench/contrib/preferences/browser/settingsTree.ts

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ import { IContextMenuService, IContextViewService } from 'vs/platform/contextvie
3636
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
3737
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
3838
import { IOpenerService } from 'vs/platform/opener/common/opener';
39-
import { editorBackground, errorForeground, focusBorder, foreground, inputValidationErrorBackground, inputValidationErrorBorder, inputValidationErrorForeground, listActiveSelectionBackground, listActiveSelectionForeground } from 'vs/platform/theme/common/colorRegistry';
39+
import { editorBackground, errorForeground, focusBorder, foreground, inputValidationErrorBackground, inputValidationErrorBorder, inputValidationErrorForeground } from 'vs/platform/theme/common/colorRegistry';
4040
import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attachStyler } from 'vs/platform/theme/common/styler';
4141
import { ICssStyleCollector, IColorTheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
4242
import { getIgnoredSettings } from 'vs/platform/userDataSync/common/settingsMerge';
4343
import { ITOCEntry } from 'vs/workbench/contrib/preferences/browser/settingsLayout';
4444
import { ISettingsEditorViewState, settingKeyToDisplayFormat, SettingsTreeElement, SettingsTreeGroupChild, SettingsTreeGroupElement, SettingsTreeNewExtensionsElement, SettingsTreeSettingElement } from 'vs/workbench/contrib/preferences/browser/settingsTreeModels';
45-
import { ExcludeSettingWidget, ISettingListChangeEvent, IListDataItem, ListSettingWidget, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsSelectListBorder, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground, ObjectSettingWidget, IObjectDataItem, IObjectEnumOption, ObjectValue, IObjectValueSuggester, IObjectKeySuggester } from 'vs/workbench/contrib/preferences/browser/settingsWidgets';
45+
import { ExcludeSettingWidget, ISettingListChangeEvent, IListDataItem, ListSettingWidget, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsSelectListBorder, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground, ObjectSettingWidget, IObjectDataItem, IObjectEnumOption, ObjectValue, IObjectValueSuggester, IObjectKeySuggester, focusedRowBackground, focusedRowBorder, settingsHeaderForeground, rowHoverBackground } from 'vs/workbench/contrib/preferences/browser/settingsWidgets';
4646
import { SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU } from 'vs/workbench/contrib/preferences/common/preferences';
4747
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
4848
import { ISetting, ISettingsGroup, SettingValueType } from 'vs/workbench/services/preferences/common/preferences';
@@ -650,7 +650,7 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
650650
private fixToolbarIcon(toolbar: ToolBar): void {
651651
const button = toolbar.getElement().querySelector('.codicon-toolbar-more');
652652
if (button) {
653-
(<HTMLElement>button).tabIndex = -1;
653+
(<HTMLElement>button).tabIndex = 0;
654654

655655
// change icon from ellipsis to gear
656656
(<HTMLElement>button).classList.add('codicon-gear');
@@ -1981,6 +1981,26 @@ export class SettingsTree extends WorkbenchObjectTree<SettingsTreeElement> {
19811981
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.invalid-input .setting-item-control .monaco-inputbox.idle { outline-width: 0; border-style:solid; border-width: 1px; border-color: ${invalidInputBorder}; }`);
19821982
}
19831983

1984+
const focusedRowBackgroundColor = theme.getColor(focusedRowBackground);
1985+
if (focusedRowBackgroundColor) {
1986+
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-list-row.focused .setting-item-contents,
1987+
.settings-editor > .settings-body > .settings-tree-container .monaco-list-row.focused .settings-group-title-label { background-color: ${focusedRowBackgroundColor}; }`);
1988+
}
1989+
1990+
const rowHoverBackgroundColor = theme.getColor(rowHoverBackground);
1991+
if (rowHoverBackgroundColor) {
1992+
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-list-row .setting-item-contents:hover,
1993+
.settings-editor > .settings-body > .settings-tree-container .monaco-list-row .settings-group-title-label:hover { background-color: ${rowHoverBackgroundColor}; }`);
1994+
}
1995+
1996+
const focusedRowBorderColor = theme.getColor(focusedRowBorder);
1997+
if (focusedRowBorderColor) {
1998+
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-list:focus-within .monaco-list-row.focused .setting-item-contents::before,
1999+
.settings-editor > .settings-body > .settings-tree-container .monaco-list:focus-within .monaco-list-row.focused .setting-item-contents::after { border-top: 1px solid ${focusedRowBorderColor} }`);
2000+
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-list:focus-within .monaco-list-row.focused .settings-group-title-label::before,
2001+
.settings-editor > .settings-body > .settings-tree-container .monaco-list:focus-within .monaco-list-row.focused .settings-group-title-label::after { border-top: 1px solid ${focusedRowBorderColor} }`);
2002+
}
2003+
19842004
const headerForegroundColor = theme.getColor(settingsHeaderForeground);
19852005
if (headerForegroundColor) {
19862006
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .settings-group-title-label { color: ${headerForegroundColor}; }`);
@@ -1992,18 +2012,11 @@ export class SettingsTree extends WorkbenchObjectTree<SettingsTreeElement> {
19922012
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-markdown a:focus { outline-color: ${focusBorderColor} }`);
19932013
}
19942014

1995-
const listActiveSelectionBackgroundColor = theme.getColor(listActiveSelectionBackground);
1996-
if (listActiveSelectionBackgroundColor) {
1997-
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-list-row.selected .setting-item-contents .setting-item-title { background-color: ${listActiveSelectionBackgroundColor}; }`);
1998-
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-list-row.selected .settings-group-title-label { background-color: ${listActiveSelectionBackgroundColor}; }`);
1999-
}
2000-
2001-
const listActiveSelectionForegroundColor = theme.getColor(listActiveSelectionForeground);
2002-
if (listActiveSelectionForegroundColor) {
2003-
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-list-row.selected .setting-item-contents .setting-item-title { color: ${listActiveSelectionForegroundColor}; }`);
2004-
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-list-row.selected .setting-item-label { color: ${listActiveSelectionForegroundColor}; }`);
2005-
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-list-row.selected .settings-group-title-label { color: ${listActiveSelectionForegroundColor}; }`);
2006-
}
2015+
// const listActiveSelectionBackgroundColor = theme.getColor(listActiveSelectionBackground);
2016+
// if (listActiveSelectionBackgroundColor) {
2017+
// collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-list-row.selected .setting-item-contents .setting-item-title { background-color: ${listActiveSelectionBackgroundColor}; }`);
2018+
// collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-list-row.selected .settings-group-title-label { background-color: ${listActiveSelectionBackgroundColor}; }`);
2019+
// }
20072020
}));
20082021

20092022
this.getHTMLElement().classList.add('settings-editor-tree');

0 commit comments

Comments
 (0)