Skip to content

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

  1. Use appropriate message types (info, warning, error)
  2. Provide clear and actionable messages
  3. Support theme colors for consistent appearance
  4. Handle webview lifecycle properly
  5. Dispose of UI elements when no longer needed
  6. Use progress indicators for long-running operations
  7. 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;
    }
  });
}

Your Ultimate AI-Powered IDE Learning Guide