UI API
The UI API provides methods to create and manage user interface elements in Trae IDE, including panels, dialogs, status bar items, and custom views.
Overview
The UI API allows you to:
- Create custom panels and views
- Show dialogs and input boxes
- Add status bar items
- Create tree views and webview panels
- Customize the IDE interface
Basic Usage
Showing Messages
typescript
import { TraeAPI } from '@trae/api';
// Show information message
TraeAPI.window.showInformationMessage('Operation completed successfully!');
// Show warning message
TraeAPI.window.showWarningMessage('This action cannot be undone.');
// Show error message
TraeAPI.window.showErrorMessage('Failed to save file.');
// Show message with actions
const result = await TraeAPI.window.showInformationMessage(
'Do you want to save changes?',
'Save',
'Don\'t Save',
'Cancel'
);
if (result === 'Save') {
// Handle save action
}Input Dialogs
typescript
// Show input box
const input = await TraeAPI.window.showInputBox({
prompt: 'Enter file name',
placeHolder: 'example.txt',
validateInput: (value) => {
if (!value) {
return 'File name cannot be empty';
}
return null;
}
});
// Show quick pick
const selection = await TraeAPI.window.showQuickPick(
['Option 1', 'Option 2', 'Option 3'],
{
placeHolder: 'Select an option',
canPickMany: false
}
);Status Bar
typescript
// Create status bar item
const statusBarItem = TraeAPI.window.createStatusBarItem(
TraeAPI.StatusBarAlignment.Left,
100
);
statusBarItem.text = '$(sync~spin) Processing...';
statusBarItem.tooltip = 'Click to cancel';
statusBarItem.command = 'myExtension.cancelOperation';
statusBarItem.show();
// Update status
statusBarItem.text = '$(check) Complete';
statusBarItem.color = '#00ff00';Custom Panels
Creating a Webview Panel
typescript
const panel = TraeAPI.window.createWebviewPanel(
'myExtension.panel',
'My Custom Panel',
TraeAPI.ViewColumn.One,
{
enableScripts: true,
retainContextWhenHidden: true
}
);
panel.webview.html = `
<!DOCTYPE html>
<html>
<head>
<title>My Panel</title>
<style>
body { font-family: var(--vscode-font-family); }
.container { padding: 20px; }
</style>
</head>
<body>
<div class="container">
<h1>Hello from Webview!</h1>
<button onclick="sendMessage()">Send Message</button>
</div>
<script>
const vscode = acquireVsCodeApi();
function sendMessage() {
vscode.postMessage({ command: 'hello' });
}
</script>
</body>
</html>
`;
// Handle messages from webview
panel.webview.onDidReceiveMessage((message) => {
if (message.command === 'hello') {
TraeAPI.window.showInformationMessage('Hello from webview!');
}
});Tree View Provider
typescript
class MyTreeDataProvider implements TraeAPI.TreeDataProvider<string> {
private _onDidChangeTreeData = new TraeAPI.EventEmitter<string | undefined>();
readonly onDidChangeTreeData = this._onDidChangeTreeData.event;
getTreeItem(element: string): TraeAPI.TreeItem {
return {
label: element,
collapsibleState: TraeAPI.TreeItemCollapsibleState.None,
command: {
command: 'myExtension.selectItem',
title: 'Select',
arguments: [element]
}
};
}
getChildren(element?: string): string[] {
if (!element) {
return ['Item 1', 'Item 2', 'Item 3'];
}
return [];
}
refresh(): void {
this._onDidChangeTreeData.fire(undefined);
}
}
// Register tree view
const treeDataProvider = new MyTreeDataProvider();
const treeView = TraeAPI.window.createTreeView('myExtension.treeView', {
treeDataProvider
});Progress Indicators
Progress with Cancellation
typescript
TraeAPI.window.withProgress({
location: TraeAPI.ProgressLocation.Notification,
title: 'Processing files',
cancellable: true
}, async (progress, token) => {
const files = ['file1.txt', 'file2.txt', 'file3.txt'];
for (let i = 0; i < files.length; i++) {
if (token.isCancellationRequested) {
break;
}
progress.report({
increment: (100 / files.length),
message: `Processing ${files[i]}`
});
// Simulate work
await new Promise(resolve => setTimeout(resolve, 1000));
}
});Window Progress
typescript
TraeAPI.window.withProgress({
location: TraeAPI.ProgressLocation.Window,
title: 'Loading...'
}, async (progress) => {
progress.report({ increment: 0 });
// Do some work
await doSomeWork();
progress.report({ increment: 50, message: 'Half way there...' });
// Do more work
await doMoreWork();
progress.report({ increment: 100, message: 'Complete!' });
});Custom Views
Registering a Custom View
typescript
// In package.json contributes section
{
"views": {
"explorer": [
{
"id": "myExtension.customView",
"name": "My Custom View",
"when": "workspaceFolderCount > 0"
}
]
},
"viewsContainers": {
"activitybar": [
{
"id": "myExtension.container",
"title": "My Extension",
"icon": "$(extensions)"
}
]
}
}Theming Support
Using Theme Colors
typescript
// In CSS/HTML
const html = `
<style>
.error { color: var(--vscode-errorForeground); }
.warning { color: var(--vscode-warningForeground); }
.info { color: var(--vscode-infoForeground); }
.background { background-color: var(--vscode-editor-background); }
</style>
`;
// In TypeScript
const errorColor = new TraeAPI.ThemeColor('errorForeground');
const decoration = TraeAPI.window.createTextEditorDecorationType({
color: errorColor,
backgroundColor: new TraeAPI.ThemeColor('editor.errorBackground')
});API Reference
Window Methods
showInformationMessage()
typescript
showInformationMessage<T extends string>(
message: string,
...items: T[]
): Thenable<T | undefined>;showInputBox()
typescript
showInputBox(options?: InputBoxOptions): Thenable<string | undefined>;createWebviewPanel()
typescript
createWebviewPanel(
viewType: string,
title: string,
showOptions: ViewColumn | { viewColumn: ViewColumn; preserveFocus?: boolean },
options?: WebviewPanelOptions & WebviewOptions
): WebviewPanel;createStatusBarItem()
typescript
createStatusBarItem(
alignment?: StatusBarAlignment,
priority?: number
): StatusBarItem;Best Practices
- Use appropriate message types (info, warning, error)
- Provide clear and actionable messages
- Support theme colors for consistent appearance
- Handle webview lifecycle properly
- Dispose of UI elements when no longer needed
- Use progress indicators for long-running operations
- Follow VS Code UX guidelines
Examples
File Explorer Extension
typescript
class FileExplorerProvider implements TraeAPI.TreeDataProvider<FileItem> {
// Implementation for custom file explorer
}
const provider = new FileExplorerProvider();
TraeAPI.window.registerTreeDataProvider('myExtension.fileExplorer', provider);Settings Panel
typescript
function createSettingsPanel() {
const panel = TraeAPI.window.createWebviewPanel(
'myExtension.settings',
'Extension Settings',
TraeAPI.ViewColumn.One,
{ enableScripts: true }
);
panel.webview.html = getSettingsHtml();
panel.webview.onDidReceiveMessage(async (message) => {
switch (message.command) {
case 'saveSetting':
await saveExtensionSetting(message.key, message.value);
break;
}
});
}Related APIs
- Commands API - For registering UI commands
- Settings API - For managing UI preferences
- Themes API - For creating custom themes