Skip to content

Commit 2b72ea5

Browse files
committed
feat: support QuickPickItem.iconPath
1 parent d5d4dae commit 2b72ea5

7 files changed

Lines changed: 65 additions & 5 deletions

File tree

packages/core-browser/src/quick-open/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ export interface QuickOpenItemOptions {
125125
* 图标
126126
*/
127127
iconClass?: string;
128+
iconPath?: URI | { light: URI; dark: URI } | ThemeIcon;
128129
/**
129130
* 对应绑定的快捷键
130131
*/
@@ -198,6 +199,9 @@ export class QuickOpenItem {
198199
getIconClass(): string | undefined {
199200
return this.options.iconClass;
200201
}
202+
getIconPath(): URI | { light: URI; dark: URI } | ThemeIcon | undefined {
203+
return this.options.iconPath;
204+
}
201205
getKeybinding(): Keybinding | undefined {
202206
return this.options.keybinding;
203207
}
@@ -401,6 +405,7 @@ export interface QuickPickItem<T> {
401405
value: T;
402406
description?: string;
403407
detail?: string;
408+
iconPath?: URI | { light: URI; dark: URI } | ThemeIcon;
404409
iconClass?: string;
405410
buttons?: QuickInputButton[];
406411
}

packages/extension/src/hosted/api/vscode/ext.host.quickopen.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ export class ExtHostQuickOpen implements IExtHostQuickOpen {
9595
pickItems.push({
9696
label: item.label,
9797
groupLabel,
98+
iconPath: item.iconPath as QuickPickItem<number>['iconPath'],
9899
description: item.description,
99100
detail: item.detail,
100101
value: index, // handle

packages/quick-open/src/browser/quick-open-item.service.ts

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { Autowired, Injectable } from '@opensumi/di';
2+
import { getExternalIcon } from '@opensumi/ide-core-browser';
23
import { IQuickPickItemButtonEvent, QuickInputButton } from '@opensumi/ide-core-browser/lib/quick-open';
34
import { StaticResourceService } from '@opensumi/ide-core-browser/lib/static-resource';
4-
import { Emitter, Event } from '@opensumi/ide-core-common';
5+
import { Emitter, Event, ThemeIcon, URI } from '@opensumi/ide-core-common';
56
import { IIconService, IThemeService, IconType } from '@opensumi/ide-theme';
67

78
import { iconPath2URI } from '../common/icon';
@@ -35,7 +36,18 @@ export class QuickOpenItemService {
3536
return [];
3637
}
3738
return buttons.map((btn, i) => {
38-
const iconUri = iconPath2URI(btn.iconPath, this.themeService.getCurrentThemeSync().type);
39+
if (ThemeIcon.isThemeIcon(btn.iconPath)) {
40+
return {
41+
...btn,
42+
iconClass: getExternalIcon(btn.iconPath.id),
43+
handle: i,
44+
};
45+
}
46+
47+
const iconUri = iconPath2URI(
48+
btn.iconPath as URI | { light: URI; dark: URI },
49+
this.themeService.getCurrentThemeSync().type,
50+
);
3951
const iconPath = iconUri && this.staticResourceService.resolveStaticResource(iconUri).toString();
4052
const iconClass = iconPath && this.iconService.fromIcon('', iconPath, IconType.Background);
4153
return {
@@ -45,4 +57,26 @@ export class QuickOpenItemService {
4557
};
4658
});
4759
}
60+
61+
getIconClass(data: { iconPath?: URI | { light: URI; dark: URI } | ThemeIcon; iconClass?: string }) {
62+
const { iconClass, iconPath } = data;
63+
64+
if (iconClass) {
65+
return iconClass;
66+
}
67+
68+
if (!iconPath) {
69+
return undefined;
70+
}
71+
72+
if (ThemeIcon.isThemeIcon(iconPath)) {
73+
return getExternalIcon(iconPath.id);
74+
}
75+
76+
const iconUri = iconPath2URI(iconPath, this.themeService.getCurrentThemeSync().type);
77+
const iconPathString = iconUri && this.staticResourceService.resolveStaticResource(iconUri).toString();
78+
const iconCls = iconPath && this.iconService.fromIcon('', iconPathString, IconType.Background);
79+
80+
return iconCls;
81+
}
4882
}

packages/quick-open/src/browser/quick-open.view.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,17 @@ const QuickOpenItemView: React.FC<IQuickOpenItemProps> = observer(({ data, index
186186

187187
const showBorder = React.useMemo(() => data.showBorder(), [data]);
188188

189+
const iconPath = React.useMemo(() => data.getIconPath(), [data]);
190+
191+
const finalIconClass = React.useMemo(
192+
() =>
193+
quickOpenItemService.getIconClass({
194+
iconPath,
195+
iconClass,
196+
}),
197+
[iconClass, iconPath],
198+
);
199+
189200
const buttons = React.useMemo(() => quickOpenItemService.getButtons(data.getButtons()), [data]);
190201

191202
const [labelHighlights, descriptionHighlights, detailHighlights] = React.useMemo(() => data.getHighlights(), [data]);
@@ -257,7 +268,7 @@ const QuickOpenItemView: React.FC<IQuickOpenItemProps> = observer(({ data, index
257268
{/* tabIndex is needed here, pls see https://stackoverflow.com/questions/42764494/blur-event-relatedtarget-returns-null */}
258269
<div tabIndex={0} className={styles.item_label_container} onMouseDown={runQuickOpenItem}>
259270
<div className={styles.item_label}>
260-
{iconClass && <span className={cls(styles.item_icon, iconClass)}></span>}
271+
{finalIconClass && <span className={cls(styles.item_icon, finalIconClass)}></span>}
261272
<HighlightLabel
262273
className={styles.item_label_name}
263274
labelClassName={styles.label_icon_container}

packages/quick-open/src/browser/quick-pick.service.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ export class QuickPickServiceImpl implements QuickPickService {
8989
const groupLabel = typeof element === 'string' ? undefined : element.groupLabel;
9090
const showBorder = typeof element === 'string' ? undefined : element.showBorder;
9191
const buttons = typeof element === 'string' ? undefined : element.buttons;
92+
const iconPath = typeof element === 'string' ? undefined : element.iconPath;
9293
const [icon, text] = getIconClass(label);
9394

9495
if (icon) {
@@ -103,6 +104,7 @@ export class QuickPickServiceImpl implements QuickPickService {
103104
groupLabel,
104105
showBorder,
105106
buttons,
107+
iconPath,
106108
run: (mode) => {
107109
if (mode !== Mode.OPEN) {
108110
return false;

packages/quick-open/src/common/icon.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { URI } from '@opensumi/ide-core-common';
22

3-
export function iconPath2URI(iconPath: any, themeType?: string): URI | undefined {
3+
export function iconPath2URI(iconPath: URI | { light: URI; dark: URI }, themeType?: string): URI | undefined {
44
if (URI.isUri(iconPath)) {
5-
return iconPath;
5+
const tmpIconPath = iconPath as URI;
6+
7+
return Object.prototype.hasOwnProperty.call(tmpIconPath, 'codeUri') ? tmpIconPath : new URI(tmpIconPath.toString());
68
}
79

810
if ((iconPath.dark || iconPath.light) && themeType) {

packages/types/vscode/typings/vscode.quickpick.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ declare module 'vscode' {
3131
*/
3232
kind?: QuickPickItemKind;
3333

34+
/**
35+
* The icon path or {@link ThemeIcon} for the QuickPickItem.
36+
*/
37+
iconPath?: Uri | { light: Uri; dark: Uri } | ThemeIcon;
38+
3439
/**
3540
* A human readable string which is rendered less prominent.
3641
*/

0 commit comments

Comments
 (0)