diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8096b896b3c06..0b5f0caa03e38 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@
## v1.27.0 - Unreleased
- [plugin] moved `WebviewViewResolveContext` from `window` to `root` namespace [#11216](https://github.com/eclipse-theia/theia/pull/11216) - Contributed on behalf of STMicroelectronics
+- [plugin] Add support for property `color` of `ThemeIcon`. [#11243](https://github.com/eclipse-theia/theia/pull/11243) - Contributed on behalf of STMicroelectronics
[Breaking Changes:](#breaking_changes_1.27.0)
diff --git a/packages/plugin-ext/src/common/plugin-api-rpc.ts b/packages/plugin-ext/src/common/plugin-api-rpc.ts
index 40670441412c3..be6f6d66e4c01 100644
--- a/packages/plugin-ext/src/common/plugin-api-rpc.ts
+++ b/packages/plugin-ext/src/common/plugin-api-rpc.ts
@@ -709,7 +709,7 @@ export interface TreeViewItem {
icon?: string;
iconUrl?: IconUrl;
- themeIconId?: string;
+ themeIcon?: ThemeIcon;
resourceUri?: UriComponents;
@@ -1077,6 +1077,11 @@ export interface ThemeColor {
id: string;
}
+export interface ThemeIcon {
+ id: string;
+ color?: ThemeColor;
+}
+
/**
* Describes the behavior of decorations when typing/editing near their edges.
*/
diff --git a/packages/plugin-ext/src/main/browser/view/plugin-tree-view-node-label-provider.ts b/packages/plugin-ext/src/main/browser/view/plugin-tree-view-node-label-provider.ts
index 0ecd1b9310f77..1090f48501596 100644
--- a/packages/plugin-ext/src/main/browser/view/plugin-tree-view-node-label-provider.ts
+++ b/packages/plugin-ext/src/main/browser/view/plugin-tree-view-node-label-provider.ts
@@ -33,7 +33,7 @@ export class PluginTreeViewNodeLabelProvider implements LabelProviderContributio
// eslint-disable-next-line @typescript-eslint/no-explicit-any
canHandle(element: TreeViewNode | any): number {
- if (TreeNode.is(element) && ('resourceUri' in element || 'themeIconId' in element)) {
+ if (TreeNode.is(element) && ('resourceUri' in element || 'themeIcon' in element)) {
return this.treeLabelProvider.canHandle(element) + 1;
}
return 0;
@@ -43,12 +43,14 @@ export class PluginTreeViewNodeLabelProvider implements LabelProviderContributio
if (node.icon) {
return node.icon;
}
- if (node.themeIconId) {
- if (node.themeIconId === 'file' || node.themeIconId === 'folder') {
+ if (node.themeIcon) {
+ if (node.themeIcon.id === 'file' || node.themeIcon.id === 'folder') {
const uri = node.resourceUri && new URI(node.resourceUri) || undefined;
- return this.labelProvider.getIcon(URIIconReference.create(node.themeIconId, uri));
+ if (uri) {
+ return this.labelProvider.getIcon(URIIconReference.create(node.themeIcon.id, uri));
+ }
}
- return ThemeIcon.asClassName({ id: node.themeIconId });
+ return ThemeIcon.asClassName(node.themeIcon);
}
if (node.resourceUri) {
return this.labelProvider.getIcon(new URI(node.resourceUri));
diff --git a/packages/plugin-ext/src/main/browser/view/tree-view-widget.tsx b/packages/plugin-ext/src/main/browser/view/tree-view-widget.tsx
index fe3b749a20bd7..d1f7fa522edce 100644
--- a/packages/plugin-ext/src/main/browser/view/tree-view-widget.tsx
+++ b/packages/plugin-ext/src/main/browser/view/tree-view-widget.tsx
@@ -16,7 +16,7 @@
import { URI } from '@theia/core/shared/vscode-uri';
import { injectable, inject, postConstruct } from '@theia/core/shared/inversify';
-import { TreeViewsExt, TreeViewItemCollapsibleState, TreeViewItem, TreeViewSelection } from '../../../common/plugin-api-rpc';
+import { TreeViewsExt, TreeViewItemCollapsibleState, TreeViewItem, TreeViewSelection, ThemeIcon } from '../../../common/plugin-api-rpc';
import { Command } from '../../../common/plugin-api-rpc-model';
import {
TreeNode,
@@ -46,6 +46,7 @@ import * as markdownit from '@theia/core/shared/markdown-it';
import { MarkdownString } from '@theia/core/lib/common/markdown-rendering';
import { LabelParser } from '@theia/core/lib/browser/label-parser';
import { AccessibilityInformation } from '@theia/plugin';
+import { ColorRegistry } from '@theia/core/lib/browser/color-registry';
export const TREE_NODE_HYPERLINK = 'theia-TreeNodeHyperlink';
export const VIEW_ITEM_CONTEXT_MENU: MenuPath = ['view-item-context-menu'];
@@ -60,7 +61,7 @@ export interface TreeViewNode extends SelectableTreeNode {
contextValue?: string;
command?: Command;
resourceUri?: string;
- themeIconId?: string | 'folder' | 'file';
+ themeIcon?: ThemeIcon;
tooltip?: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
description?: string | boolean | any;
@@ -68,7 +69,7 @@ export interface TreeViewNode extends SelectableTreeNode {
}
export namespace TreeViewNode {
export function is(arg: TreeNode | undefined): arg is TreeViewNode {
- return !!arg && SelectableTreeNode.is(arg) && !ExpandableTreeNode.is(arg) && !CompositeTreeNode.is(arg);
+ return !!arg && SelectableTreeNode.is(arg);
}
}
@@ -151,12 +152,12 @@ export class PluginTree extends TreeImpl {
protected createTreeNode(item: TreeViewItem, parent: CompositeTreeNode): TreeNode {
const icon = this.toIconClass(item);
const resourceUri = item.resourceUri && URI.revive(item.resourceUri).toString();
- const themeIconId = item.themeIconId ? item.themeIconId : item.collapsibleState !== TreeViewItemCollapsibleState.None ? 'folder' : 'file';
+ const themeIcon = item.themeIcon ? item.themeIcon : item.collapsibleState !== TreeViewItemCollapsibleState.None ? { id: 'folder' } : { id: 'file' };
const update: Partial = {
name: item.label,
icon,
description: item.description,
- themeIconId,
+ themeIcon,
resourceUri,
tooltip: item.tooltip,
contextValue: item.contextValue,
@@ -178,7 +179,7 @@ export class PluginTree extends TreeImpl {
command: item.command
}, update);
}
- if (TreeViewNode.is(node)) {
+ if (TreeViewNode.is(node) && !ExpandableTreeNode.is(node)) {
return Object.assign(node, update, { command: item.command });
}
return Object.assign({
@@ -257,6 +258,9 @@ export class TreeViewWidget extends TreeViewWelcomeWidget {
@inject(LabelParser)
protected readonly labelParser: LabelParser;
+ @inject(ColorRegistry)
+ protected readonly colorRegistry: ColorRegistry;
+
protected readonly markdownIt = markdownit();
@postConstruct()
@@ -286,7 +290,14 @@ export class TreeViewWidget extends TreeViewWelcomeWidget {
protected override renderIcon(node: TreeNode, props: NodeProps): React.ReactNode {
const icon = this.toNodeIcon(node);
if (icon) {
- return ;
+ let style: React.CSSProperties | undefined;
+ if (TreeViewNode.is(node) && node.themeIcon?.color) {
+ const color = this.colorRegistry.getCurrentColor(node.themeIcon.color.id);
+ if (color) {
+ style = { color };
+ }
+ }
+ return ;
}
return undefined;
}
diff --git a/packages/plugin-ext/src/plugin/tree/tree-views.ts b/packages/plugin-ext/src/plugin/tree/tree-views.ts
index 700b3dc3cd4ab..325492fc8019f 100644
--- a/packages/plugin-ext/src/plugin/tree/tree-views.ts
+++ b/packages/plugin-ext/src/plugin/tree/tree-views.ts
@@ -366,12 +366,12 @@ class TreeViewExtImpl implements Disposable {
let icon;
let iconUrl;
- let themeIconId;
+ let themeIcon;
const { iconPath } = treeItem;
if (typeof iconPath === 'string' && iconPath.indexOf('fa-') !== -1) {
icon = iconPath;
} else if (ThemeIcon.is(iconPath)) {
- themeIconId = iconPath.id;
+ themeIcon = iconPath;
} else {
iconUrl = PluginIconPath.toUrl(iconPath, this.plugin);
}
@@ -381,7 +381,7 @@ class TreeViewExtImpl implements Disposable {
label,
icon,
iconUrl,
- themeIconId,
+ themeIcon,
description: treeItem.description,
resourceUri: treeItem.resourceUri,
tooltip: treeItem.tooltip,
diff --git a/packages/plugin-ext/src/plugin/types-impl.ts b/packages/plugin-ext/src/plugin/types-impl.ts
index b4cdab5090ad4..6108ebf44c982 100644
--- a/packages/plugin-ext/src/plugin/types-impl.ts
+++ b/packages/plugin-ext/src/plugin/types-impl.ts
@@ -732,7 +732,7 @@ export class ThemeIcon {
static readonly Folder: ThemeIcon = new ThemeIcon('folder');
- private constructor(public id: string) {
+ private constructor(public id: string, public color?: ThemeColor) {
}
}
diff --git a/packages/plugin/src/theia.d.ts b/packages/plugin/src/theia.d.ts
index 802364d6bfc79..28a1c2fcd8786 100644
--- a/packages/plugin/src/theia.d.ts
+++ b/packages/plugin/src/theia.d.ts
@@ -2652,7 +2652,22 @@ export module '@theia/plugin' {
*/
static readonly Folder: ThemeIcon;
- private constructor(public id: string);
+ /**
+ * The id of the icon. The available icons are listed in https://code.visualstudio.com/api/references/icons-in-labels#icon-listing.
+ */
+ readonly id: string;
+
+ /**
+ * The optional ThemeColor of the icon. The color is currently only used in {@link TreeItem}.
+ */
+ readonly color?: ThemeColor | undefined;
+
+ /**
+ * Creates a reference to a theme icon.
+ * @param id id of the icon. The available icons are listed in https://code.visualstudio.com/api/references/icons-in-labels#icon-listing.
+ * @param color optional `ThemeColor` for the icon. The color is currently only used in {@link TreeItem}.
+ */
+ private constructor(public id: string, public color?: ThemeColor);
}
/**