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