Skip to content

Commit 2e47c97

Browse files
authored
keybindingLabel: switch theming to css variables (microsoft#165426)
1 parent 0a6c728 commit 2e47c97

File tree

10 files changed

+81
-102
lines changed

10 files changed

+81
-102
lines changed

src/vs/base/browser/ui/keybindingLabel/keybindingLabel.ts

Lines changed: 31 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import * as dom from 'vs/base/browser/dom';
7-
import { Color } from 'vs/base/common/color';
87
import { UILabelProvider } from 'vs/base/common/keybindingLabels';
98
import { ResolvedKeybinding, ResolvedKeybindingPart } from 'vs/base/common/keybindings';
109
import { equals } from 'vs/base/common/objects';
1110
import { OperatingSystem } from 'vs/base/common/platform';
12-
import { IThemable } from 'vs/base/common/styler';
1311
import 'vs/css!./keybindingLabel';
1412
import { localize } from 'vs/nls';
1513

@@ -32,15 +30,17 @@ export interface KeybindingLabelOptions extends IKeybindingLabelStyles {
3230
renderUnboundKeybindings?: boolean;
3331
}
3432

33+
export type CSSValueString = string;
34+
3535
export interface IKeybindingLabelStyles {
36-
keybindingLabelBackground?: Color;
37-
keybindingLabelForeground?: Color;
38-
keybindingLabelBorder?: Color;
39-
keybindingLabelBottomBorder?: Color;
40-
keybindingLabelShadow?: Color;
36+
keybindingLabelBackground?: CSSValueString;
37+
keybindingLabelForeground?: CSSValueString;
38+
keybindingLabelBorder?: CSSValueString;
39+
keybindingLabelBottomBorder?: CSSValueString;
40+
keybindingLabelShadow?: CSSValueString;
4141
}
4242

43-
export class KeybindingLabel implements IThemable {
43+
export class KeybindingLabel {
4444

4545
private domNode: HTMLElement;
4646
private options: KeybindingLabelOptions;
@@ -51,22 +51,26 @@ export class KeybindingLabel implements IThemable {
5151
private matches: Matches | undefined;
5252
private didEverRender: boolean;
5353

54-
private labelBackground: Color | undefined;
55-
private labelForeground: Color | undefined;
56-
private labelBorder: Color | undefined;
57-
private labelBottomBorder: Color | undefined;
58-
private labelShadow: Color | undefined;
54+
private labelBackground: CSSValueString | undefined;
55+
private labelBorder: CSSValueString | undefined;
56+
private labelBottomBorder: CSSValueString | undefined;
57+
private labelShadow: CSSValueString | undefined;
5958

6059
constructor(container: HTMLElement, private os: OperatingSystem, options?: KeybindingLabelOptions) {
6160
this.options = options || Object.create(null);
6261

6362
this.labelBackground = this.options.keybindingLabelBackground;
64-
this.labelForeground = this.options.keybindingLabelForeground;
6563
this.labelBorder = this.options.keybindingLabelBorder;
6664
this.labelBottomBorder = this.options.keybindingLabelBottomBorder;
6765
this.labelShadow = this.options.keybindingLabelShadow;
6866

67+
const labelForeground = this.options.keybindingLabelForeground;
68+
6969
this.domNode = dom.append(container, $('.monaco-keybinding'));
70+
if (labelForeground) {
71+
this.domNode.style.color = labelForeground;
72+
}
73+
7074
this.didEverRender = false;
7175
container.appendChild(this.domNode);
7276
}
@@ -102,8 +106,6 @@ export class KeybindingLabel implements IThemable {
102106
this.renderUnbound(this.domNode);
103107
}
104108

105-
this.applyStyles();
106-
107109
this.didEverRender = true;
108110
}
109111

@@ -147,40 +149,20 @@ export class KeybindingLabel implements IThemable {
147149
const keyElement = $('span.monaco-keybinding-key' + extraClass, undefined, label);
148150
this.keyElements.add(keyElement);
149151

150-
return keyElement;
151-
}
152-
153-
style(styles: IKeybindingLabelStyles): void {
154-
this.labelBackground = styles.keybindingLabelBackground;
155-
this.labelForeground = styles.keybindingLabelForeground;
156-
this.labelBorder = styles.keybindingLabelBorder;
157-
this.labelBottomBorder = styles.keybindingLabelBottomBorder;
158-
this.labelShadow = styles.keybindingLabelShadow;
159-
160-
this.applyStyles();
161-
}
162-
163-
private applyStyles() {
164-
if (this.element) {
165-
for (const keyElement of this.keyElements) {
166-
if (this.labelBackground) {
167-
keyElement.style.backgroundColor = this.labelBackground?.toString();
168-
}
169-
if (this.labelBorder) {
170-
keyElement.style.borderColor = this.labelBorder.toString();
171-
}
172-
if (this.labelBottomBorder) {
173-
keyElement.style.borderBottomColor = this.labelBottomBorder.toString();
174-
}
175-
if (this.labelShadow) {
176-
keyElement.style.boxShadow = `inset 0 -1px 0 ${this.labelShadow}`;
177-
}
178-
}
179-
180-
if (this.labelForeground) {
181-
this.element.style.color = this.labelForeground.toString();
182-
}
152+
if (this.labelBackground) {
153+
keyElement.style.backgroundColor = this.labelBackground;
154+
}
155+
if (this.labelBorder) {
156+
keyElement.style.borderColor = this.labelBorder;
183157
}
158+
if (this.labelBottomBorder) {
159+
keyElement.style.borderBottomColor = this.labelBottomBorder;
160+
}
161+
if (this.labelShadow) {
162+
keyElement.style.boxShadow = `inset 0 -1px 0 ${this.labelShadow}`;
163+
}
164+
165+
return keyElement;
184166
}
185167

186168
private static areSame(a: Matches | undefined, b: Matches | undefined): boolean {

src/vs/editor/browser/editorDom.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
99
import { RunOnceScheduler } from 'vs/base/common/async';
1010
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
1111
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
12-
import { asCssVariableName } from 'vs/platform/theme/common/colorRegistry';
12+
import { asCssValue } from 'vs/platform/theme/common/colorRegistry';
1313
import { ThemeColor } from 'vs/platform/theme/common/themeService';
1414

1515
/**
@@ -378,7 +378,7 @@ class RefCountedCssRule {
378378
const value = (properties as any)[prop] as string | ThemeColor;
379379
let cssValue;
380380
if (typeof value === 'object') {
381-
cssValue = `var(${asCssVariableName(value.id)})`;
381+
cssValue = asCssValue(value.id);
382382
} else {
383383
cssValue = value;
384384
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
import { IKeybindingLabelStyles } from 'vs/base/browser/ui/keybindingLabel/keybindingLabel';
6+
import { ColorIdentifier, keybindingLabelBackground, keybindingLabelBorder, keybindingLabelBottomBorder, keybindingLabelForeground, asCssValue, widgetShadow } from 'vs/platform/theme/common/colorRegistry';
7+
import { IStyleOverrides } from 'vs/platform/theme/common/styler';
8+
9+
10+
export interface IKeybindingLabelStyleOverrides extends IStyleOverrides {
11+
keybindingLabelBackground?: ColorIdentifier;
12+
keybindingLabelForeground?: ColorIdentifier;
13+
keybindingLabelBorder?: ColorIdentifier;
14+
keybindingLabelBottomBorder?: ColorIdentifier;
15+
keybindingLabelShadow?: ColorIdentifier;
16+
}
17+
18+
export function getKeybindingLabelStyles(style?: IKeybindingLabelStyleOverrides): IKeybindingLabelStyles {
19+
return {
20+
keybindingLabelBackground: asCssValue(style?.keybindingLabelBackground || keybindingLabelBackground),
21+
keybindingLabelForeground: asCssValue(style?.keybindingLabelForeground || keybindingLabelForeground),
22+
keybindingLabelBorder: asCssValue(style?.keybindingLabelBorder || keybindingLabelBorder),
23+
keybindingLabelBottomBorder: asCssValue(style?.keybindingLabelBottomBorder || keybindingLabelBottomBorder),
24+
keybindingLabelShadow: asCssValue(style?.keybindingLabelShadow || widgetShadow)
25+
};
26+
}

src/vs/platform/theme/common/colorRegistry.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ export function asCssVariableName(colorIdent: ColorIdentifier): string {
3535
return `--vscode-${colorIdent.replace(/\./g, '-')}`;
3636
}
3737

38+
export function asCssValue(color: ColorIdentifier): string {
39+
return `var(${asCssVariableName(color)})`;
40+
}
41+
3842
export const enum ColorTransformType {
3943
Darken,
4044
Lighten,

src/vs/platform/theme/common/styler.ts

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import { Color } from 'vs/base/common/color';
77
import { IDisposable } from 'vs/base/common/lifecycle';
88
import { IThemable, styleFn } from 'vs/base/common/styler';
9-
import { activeContrastBorder, badgeBackground, badgeForeground, breadcrumbsActiveSelectionForeground, breadcrumbsBackground, breadcrumbsFocusForeground, breadcrumbsForeground, buttonBackground, buttonBorder, buttonForeground, buttonHoverBackground, buttonSecondaryBackground, buttonSecondaryForeground, buttonSecondaryHoverBackground, ColorIdentifier, ColorTransform, ColorValue, contrastBorder, editorWidgetBackground, editorWidgetBorder, editorWidgetForeground, focusBorder, inputActiveOptionBackground, inputActiveOptionBorder, inputActiveOptionForeground, inputBackground, inputBorder, inputForeground, inputValidationErrorBackground, inputValidationErrorBorder, inputValidationErrorForeground, inputValidationInfoBackground, inputValidationInfoBorder, inputValidationInfoForeground, inputValidationWarningBackground, inputValidationWarningBorder, inputValidationWarningForeground, keybindingLabelBackground, keybindingLabelBorder, keybindingLabelBottomBorder, keybindingLabelForeground, listActiveSelectionBackground, listActiveSelectionForeground, listActiveSelectionIconForeground, listDropBackground, listFilterWidgetBackground, listFilterWidgetNoMatchesOutline, listFilterWidgetOutline, listFocusBackground, listFocusForeground, listFocusOutline, listHoverBackground, listHoverForeground, listInactiveFocusBackground, listInactiveFocusOutline, listInactiveSelectionBackground, listInactiveSelectionForeground, listInactiveSelectionIconForeground, menuBackground, menuBorder, menuForeground, menuSelectionBackground, menuSelectionBorder, menuSelectionForeground, menuSeparatorBackground, pickerGroupForeground, problemsErrorIconForeground, problemsInfoIconForeground, problemsWarningIconForeground, progressBarBackground, quickInputListFocusBackground, quickInputListFocusForeground, quickInputListFocusIconForeground, resolveColorValue, scrollbarShadow, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground, selectBackground, selectBorder, selectForeground, selectListBackground, checkboxBackground, checkboxBorder, checkboxForeground, tableColumnsBorder, tableOddRowsBackgroundColor, textLinkForeground, treeIndentGuidesStroke, widgetShadow, listFocusAndSelectionOutline, listFilterWidgetShadow, buttonSeparator } from 'vs/platform/theme/common/colorRegistry';
9+
import { activeContrastBorder, badgeBackground, badgeForeground, breadcrumbsActiveSelectionForeground, breadcrumbsBackground, breadcrumbsFocusForeground, breadcrumbsForeground, buttonBackground, buttonBorder, buttonForeground, buttonHoverBackground, buttonSecondaryBackground, buttonSecondaryForeground, buttonSecondaryHoverBackground, ColorIdentifier, ColorTransform, ColorValue, contrastBorder, editorWidgetBackground, editorWidgetBorder, editorWidgetForeground, focusBorder, inputActiveOptionBackground, inputActiveOptionBorder, inputActiveOptionForeground, inputBackground, inputBorder, inputForeground, inputValidationErrorBackground, inputValidationErrorBorder, inputValidationErrorForeground, inputValidationInfoBackground, inputValidationInfoBorder, inputValidationInfoForeground, inputValidationWarningBackground, inputValidationWarningBorder, inputValidationWarningForeground, listActiveSelectionBackground, listActiveSelectionForeground, listActiveSelectionIconForeground, listDropBackground, listFilterWidgetBackground, listFilterWidgetNoMatchesOutline, listFilterWidgetOutline, listFocusBackground, listFocusForeground, listFocusOutline, listHoverBackground, listHoverForeground, listInactiveFocusBackground, listInactiveFocusOutline, listInactiveSelectionBackground, listInactiveSelectionForeground, listInactiveSelectionIconForeground, menuBackground, menuBorder, menuForeground, menuSelectionBackground, menuSelectionBorder, menuSelectionForeground, menuSeparatorBackground, pickerGroupForeground, problemsErrorIconForeground, problemsInfoIconForeground, problemsWarningIconForeground, progressBarBackground, quickInputListFocusBackground, quickInputListFocusForeground, quickInputListFocusIconForeground, resolveColorValue, scrollbarShadow, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground, selectBackground, selectBorder, selectForeground, selectListBackground, checkboxBackground, checkboxBorder, checkboxForeground, tableColumnsBorder, tableOddRowsBackgroundColor, textLinkForeground, treeIndentGuidesStroke, widgetShadow, listFocusAndSelectionOutline, listFilterWidgetShadow, buttonSeparator } from 'vs/platform/theme/common/colorRegistry';
1010
import { isHighContrast } from 'vs/platform/theme/common/theme';
1111
import { IColorTheme, IThemeService } from 'vs/platform/theme/common/themeService';
1212

@@ -261,25 +261,6 @@ export function attachButtonStyler(widget: IThemable, themeService: IThemeServic
261261
buttonBorder: style?.buttonBorder || buttonBorder,
262262
} as IButtonStyleOverrides, widget);
263263
}
264-
265-
export interface IKeybindingLabelStyleOverrides extends IStyleOverrides {
266-
keybindingLabelBackground?: ColorIdentifier;
267-
keybindingLabelForeground?: ColorIdentifier;
268-
keybindingLabelBorder?: ColorIdentifier;
269-
keybindingLabelBottomBorder?: ColorIdentifier;
270-
keybindingLabelShadow?: ColorIdentifier;
271-
}
272-
273-
export function attachKeybindingLabelStyler(widget: IThemable, themeService: IThemeService, style?: IKeybindingLabelStyleOverrides): IDisposable {
274-
return attachStyler(themeService, {
275-
keybindingLabelBackground: (style && style.keybindingLabelBackground) || keybindingLabelBackground,
276-
keybindingLabelForeground: (style && style.keybindingLabelForeground) || keybindingLabelForeground,
277-
keybindingLabelBorder: (style && style.keybindingLabelBorder) || keybindingLabelBorder,
278-
keybindingLabelBottomBorder: (style && style.keybindingLabelBottomBorder) || keybindingLabelBottomBorder,
279-
keybindingLabelShadow: (style && style.keybindingLabelShadow) || widgetShadow
280-
} as IKeybindingLabelStyleOverrides, widget);
281-
}
282-
283264
export interface IProgressBarStyleOverrides extends IStyleOverrides {
284265
progressBarBackground?: ColorIdentifier;
285266
}

src/vs/workbench/contrib/extensions/browser/extensionEditor.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
6363
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
6464
import { Delegate } from 'vs/workbench/contrib/extensions/browser/extensionsList';
6565
import { renderMarkdown } from 'vs/base/browser/markdownRenderer';
66-
import { attachKeybindingLabelStyler } from 'vs/platform/theme/common/styler';
6766
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
6867
import { errorIcon, infoIcon, preReleaseIcon, verifiedPublisherIcon as verifiedPublisherThemeIcon, warningIcon } from 'vs/workbench/contrib/extensions/browser/extensionsIcons';
6968
import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite';
7069
import { ViewContainerLocation } from 'vs/workbench/common/views';
7170
import { IExtensionGalleryService, IGalleryExtension } from 'vs/platform/extensionManagement/common/extensionManagement';
7271
import * as semver from 'vs/base/common/semver/semver';
72+
import { getKeybindingLabelStyles } from 'vs/platform/theme/browser/defaultStyles';
7373

7474
class NavBar extends Disposable {
7575

@@ -1556,9 +1556,8 @@ export class ExtensionEditor extends EditorPane {
15561556

15571557
const renderKeybinding = (keybinding: ResolvedKeybinding): HTMLElement => {
15581558
const element = $('');
1559-
const kbl = new KeybindingLabel(element, OS);
1559+
const kbl = new KeybindingLabel(element, OS, getKeybindingLabelStyles());
15601560
kbl.set(keybinding);
1561-
this.contentDisposables.add(attachKeybindingLabelStyler(kbl, this.themeService));
15621561
return element;
15631562
};
15641563

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

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
2020
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
2121
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
2222
import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition } from 'vs/editor/browser/editorBrowser';
23-
import { attachInputBoxStyler, attachKeybindingLabelStyler, attachStylerCallback } from 'vs/platform/theme/common/styler';
23+
import { attachInputBoxStyler, attachStylerCallback } from 'vs/platform/theme/common/styler';
2424
import { IThemeService } from 'vs/platform/theme/common/themeService';
2525
import { editorWidgetBackground, editorWidgetForeground, widgetShadow } from 'vs/platform/theme/common/colorRegistry';
2626
import { ScrollType } from 'vs/editor/common/editorCommon';
2727
import { SearchWidget, SearchOptions } from 'vs/workbench/contrib/preferences/browser/preferencesWidgets';
2828
import { withNullAsUndefined } from 'vs/base/common/types';
2929
import { Promises, timeout } from 'vs/base/common/async';
3030
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
31+
import { getKeybindingLabelStyles } from 'vs/platform/theme/browser/defaultStyles';
3132

3233
export interface KeybindingsSearchOptions extends SearchOptions {
3334
recordEnter?: boolean;
@@ -168,9 +169,6 @@ export class DefineKeybindingWidget extends Widget {
168169
private _onShowExistingKeybindings = this._register(new Emitter<string | null>());
169170
readonly onShowExistingKeybidings: Event<string | null> = this._onShowExistingKeybindings.event;
170171

171-
private disposables = this._register(new DisposableStore());
172-
private keybindingLabelStylers = this.disposables.add(new DisposableStore());
173-
174172
constructor(
175173
parent: HTMLElement | null,
176174
@IInstantiationService private readonly instantiationService: IInstantiationService,
@@ -279,17 +277,13 @@ export class DefineKeybindingWidget extends Widget {
279277
dom.clearNode(this._outputNode);
280278
dom.clearNode(this._showExistingKeybindingsNode);
281279

282-
this.keybindingLabelStylers.clear();
283-
284-
const firstLabel = new KeybindingLabel(this._outputNode, OS);
280+
const firstLabel = new KeybindingLabel(this._outputNode, OS, getKeybindingLabelStyles());
285281
firstLabel.set(withNullAsUndefined(this._firstPart));
286-
this.keybindingLabelStylers.add(attachKeybindingLabelStyler(firstLabel, this.themeService));
287282

288283
if (this._chordPart) {
289284
this._outputNode.appendChild(document.createTextNode(nls.localize('defineKeybinding.chordsTo', "chord to")));
290-
const chordLabel = new KeybindingLabel(this._outputNode, OS);
285+
const chordLabel = new KeybindingLabel(this._outputNode, OS, getKeybindingLabelStyles());
291286
chordLabel.set(this._chordPart);
292-
this.keybindingLabelStylers.add(attachKeybindingLabelStyler(chordLabel, this.themeService));
293287
}
294288

295289
const label = this.getUserSettingsLabel();

0 commit comments

Comments
 (0)