Skip to content

Commit 6b391eb

Browse files
connor4312aeschli
andauthored
theme: fix unthemable icons in several areas (microsoft#209131)
* theme: fix unthemable icons in several areas We manually used icon characters in several areas. These are/were entire unthemable. Fixing this required people to manually listen to the theme service and apply rules to their elements when icons change. This PRs adds theme variables that people can use instead. Fixes microsoft#208343 * implement review comments * fix font-family variable --------- Co-authored-by: Martin Aeschlimann <[email protected]>
1 parent 49c1a3e commit 6b391eb

File tree

16 files changed

+68
-40
lines changed

16 files changed

+68
-40
lines changed

build/lib/stylelint/validateVariableNames.js

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/lib/stylelint/validateVariableNames.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ function getKnownVariableNames() {
1818
return knownVariables;
1919
}
2020

21+
const iconVariable = /^--vscode-icon-.+-(content|font-family)$/;
22+
2123
export interface IValidator {
2224
(value: string, report: (message: string) => void): void;
2325
}
@@ -29,7 +31,7 @@ export function getVariableNameValidator(): IValidator {
2931
let match;
3032
while (match = RE_VAR_PROP.exec(value)) {
3133
const variableName = match[1];
32-
if (variableName && !allVariables.has(variableName)) {
34+
if (variableName && !allVariables.has(variableName) && !iconVariable.test(variableName)) {
3335
report(variableName);
3436
}
3537
}

src/vs/base/browser/ui/codicons/codicon/codicon.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
src: url("./codicon.ttf?5d4d76ab2ce5108968ad644d591a16a6") format("truetype");
1010
}
1111

12-
.codicon[class*='codicon-'] {
12+
.codicon {
1313
font: normal normal normal 16px/1 codicon;
1414
display: inline-block;
1515
text-decoration: none;

src/vs/base/browser/ui/menu/menubar.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@
9999

100100
.menubar:not(.compact) .menubar-menu-button:first-child .toolbar-toggle-more::before,
101101
.menubar.compact .toolbar-toggle-more::before {
102-
content: "\eb94" !important;
102+
content: var(--vscode-icon-menu-content) !important;
103+
font-family: var(--vscode-icon-menu-font-family) !important;
103104
}
104105

105106
/* Match behavior of outline for activity bar icons */

src/vs/editor/contrib/inlineProgress/browser/inlineProgressWidget.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@
2525
}
2626

2727
.inline-progress-widget:hover .icon::before {
28-
content: "\ea76"; /* codicon-x */
28+
content: var(--vscode-icon-x-content);
29+
font-family: var(--vscode-icon-x-font-family);
2930
}

src/vs/platform/theme/browser/iconsStyleSheet.ts

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,34 +31,41 @@ export function getIconsStyleSheet(themeService: IThemeService | undefined): IIc
3131
getCSS() {
3232
const productIconTheme = themeService ? themeService.getProductIconTheme() : new UnthemedProductIconTheme();
3333
const usedFontIds: { [id: string]: IconFontDefinition } = {};
34-
const formatIconRule = (contribution: IconContribution): string | undefined => {
34+
35+
const rules: string[] = [];
36+
const rootAttribs: string[] = [];
37+
for (const contribution of iconRegistry.getIcons()) {
3538
const definition = productIconTheme.getIcon(contribution);
3639
if (!definition) {
37-
return undefined;
40+
continue;
3841
}
42+
3943
const fontContribution = definition.font;
44+
const fontFamilyVar = `--vscode-icon-${contribution.id}-font-family`;
45+
const contentVar = `--vscode-icon-${contribution.id}-content`;
4046
if (fontContribution) {
4147
usedFontIds[fontContribution.id] = fontContribution.definition;
42-
return `.codicon-${contribution.id}:before { content: '${definition.fontCharacter}'; font-family: ${asCSSPropertyValue(fontContribution.id)}; }`;
43-
}
44-
// default font (codicon)
45-
return `.codicon-${contribution.id}:before { content: '${definition.fontCharacter}'; }`;
46-
};
47-
48-
const rules = [];
49-
for (const contribution of iconRegistry.getIcons()) {
50-
const rule = formatIconRule(contribution);
51-
if (rule) {
52-
rules.push(rule);
48+
rootAttribs.push(
49+
`${fontFamilyVar}: ${asCSSPropertyValue(fontContribution.id)};`,
50+
`${contentVar}: '${definition.fontCharacter}';`,
51+
);
52+
rules.push(`.codicon-${contribution.id}:before { content: '${definition.fontCharacter}'; font-family: ${asCSSPropertyValue(fontContribution.id)}; }`);
53+
} else {
54+
rootAttribs.push(`${contentVar}: '${definition.fontCharacter}'; ${fontFamilyVar}: 'codicon';`);
55+
rules.push(`.codicon-${contribution.id}:before { content: '${definition.fontCharacter}'; }`);
5356
}
5457
}
58+
5559
for (const id in usedFontIds) {
5660
const definition = usedFontIds[id];
5761
const fontWeight = definition.weight ? `font-weight: ${definition.weight};` : '';
5862
const fontStyle = definition.style ? `font-style: ${definition.style};` : '';
5963
const src = definition.src.map(l => `${asCSSUrl(l.location)} format('${l.format}')`).join(', ');
6064
rules.push(`@font-face { src: ${src}; font-family: ${asCSSPropertyValue(id)};${fontWeight}${fontStyle} font-display: block; }`);
6165
}
66+
67+
rules.push(`:root { ${rootAttribs.join(' ')} }`);
68+
6269
return rules.join('\n');
6370
}
6471
};

src/vs/workbench/browser/actions/media/actions.css

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
.monaco-workbench .quick-input-list .quick-input-list-entry.has-actions:hover .quick-input-list-entry-action-bar .action-label.dirty-workspace::before {
7-
content: "\ea76"; /* Close icon flips between black dot and "X" for dirty workspaces */
7+
/* Close icon flips between black dot and "X" for dirty workspaces */
8+
content: var(--vscode-icon-x-content);
9+
font-family: var(--vscode-icon-x-font-family);
810
}
911

1012
.monaco-workbench .screencast-mouse {

src/vs/workbench/browser/media/style.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,8 @@ body.web {
196196
}
197197

198198
.monaco-workbench .select-container:after {
199-
content: "\eab4";
199+
content: var(--vscode-icon-chevron-down-content);
200+
font-family: var(--vscode-icon-chevron-down-font-family);
200201
font-family: codicon;
201202
font-size: 16px;
202203
width: 16px;

src/vs/workbench/browser/parts/editor/media/editorquickaccess.css

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
.quick-input-list .quick-input-list-entry.has-actions:hover .quick-input-list-entry-action-bar .action-label.dirty-editor::before {
7-
content: "\ea76"; /* Close icon flips between black dot and "X" for dirty open editors */
7+
/* Close icon flips between black dot and "X" for dirty open editors */
8+
content: var(--vscode-icon-x-content);
9+
font-family: var(--vscode-icon-x-font-family);
810
}

src/vs/workbench/browser/parts/editor/media/multieditortabscontrol.css

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -420,14 +420,16 @@
420420

421421
.monaco-workbench .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab.sticky.dirty > .tab-actions .action-label:not(:hover)::before,
422422
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sticky.dirty > .tab-actions .action-label:not(:hover)::before {
423-
content: "\ebb2"; /* use `pinned-dirty` icon unicode for sticky-dirty indication */
424-
font-family: 'codicon';
423+
/* use `pinned-dirty` icon unicode for sticky-dirty indication */
424+
content: var(--vscode-icon-pinned-dirty-content);
425+
font-family: var(--vscode-icon-pinned-dirty-font-family);
425426
}
426427

427428
.monaco-workbench .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab.dirty > .tab-actions .action-label:not(:hover)::before,
428429
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty > .tab-actions .action-label:not(:hover)::before {
429-
content: "\ea71"; /* use `circle-filled` icon unicode for dirty indication */
430-
font-family: 'codicon';
430+
/* use `circle-filled` icon unicode for dirty indication */
431+
content: var(--vscode-icon-circle-filled-content);
432+
font-family: var(--vscode-icon-circle-filled-font-family);
431433
}
432434

433435
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active > .tab-actions .action-label,

0 commit comments

Comments
 (0)