CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-theia--filesystem

Theia filesystem extension providing comprehensive file operations, tree widgets, dialogs, and file system integration for IDE environments.

Pending
Overview
Eval results
Files

file-dialog.mddocs/

File Dialog System

Configurable file and folder selection dialogs with filtering, navigation controls, and support for both native (Electron) and web-based implementations. Provides standardized file selection interfaces across different Theia deployment environments.

Capabilities

FileDialogService Interface

High-level service providing convenient methods for showing file dialogs with proper type handling and result processing.

/**
 * High-level service for showing file open/save dialogs
 */
interface FileDialogService {
  /** Show file open dialog for single file selection */
  showOpenDialog(props: OpenFileDialogProps, folder?: FileStat): Promise<URI | undefined>;
  
  /** Show file open dialog for multiple file selection */
  showOpenDialog(props: OpenFileDialogProps & { canSelectMany: true }, folder?: FileStat): Promise<MaybeArray<URI> | undefined>;
  
  /** Show file save dialog */
  showSaveDialog(props: SaveFileDialogProps, folder?: FileStat): Promise<URI | undefined>;
}

type MaybeArray<T> = T | T[];

Dialog Properties and Configuration

Comprehensive configuration options for customizing dialog behavior, appearance, and filtering.

/**
 * Base dialog properties with filters and modal settings
 */
interface FileDialogProps {
  /** Dialog title text */
  title?: string;
  
  /** File type filters */
  filters?: FileFilter[];
  
  /** Default filter to select */
  defaultFilter?: FileFilter;
  
  /** Whether dialog should be modal */
  modal?: boolean;
  
  /** Initial directory to open */
  defaultPath?: string;
  
  /** Custom CSS class names */
  className?: string;
}

/**
 * Properties specific to open file dialogs
 */
interface OpenFileDialogProps extends FileDialogProps {
  /** Allow file selection */
  canSelectFiles?: boolean;
  
  /** Allow folder selection */
  canSelectFolders?: boolean;
  
  /** Allow multiple selection */
  canSelectMany?: boolean;
  
  /** Label for open button */
  openLabel?: string;
}

/**
 * Properties specific to save file dialogs
 */
interface SaveFileDialogProps extends FileDialogProps {
  /** Label for save button */
  saveLabel?: string;
  
  /** Default filename in input field */
  inputValue?: string;
  
  /** Placeholder text for filename input */
  placeholder?: string;
}

/**
 * File type filter definition
 */
interface FileFilter {
  /** Display name for the filter */
  name: string;
  
  /** Array of file extensions (with or without dots) */
  extensions: string[];
}

Dialog Factory Functions

Factory functions for creating dialog instances with proper dependency injection.

/**
 * Factory function for creating open file dialogs
 */
type OpenFileDialogFactory = (props: OpenFileDialogProps) => OpenFileDialog;

/**
 * Factory function for creating save file dialogs
 */
type SaveFileDialogFactory = (props: SaveFileDialogProps) => SaveFileDialog;

Dialog Classes

Core dialog implementations providing the actual user interface and interaction logic.

/**
 * Base file dialog with navigation controls
 */
abstract class FileDialog<T> extends AbstractDialog<T> {
  /** Back navigation button */
  protected readonly back: HTMLSpanElement;
  
  /** Forward navigation button */
  protected readonly forward: HTMLSpanElement;
  
  /** Home directory button */
  protected readonly home: HTMLSpanElement;
  
  /** Parent directory (up) button */
  protected readonly up: HTMLSpanElement;
  
  /** Current location URI */
  protected location: URI | undefined;
  
  /** Navigate to specific location */
  protected navigateTo(location: URI): void;
  
  /** Get available drives for navigation */
  protected getDrives(): Promise<URI[]>;
}

/**
 * File selection dialog implementation
 */
class OpenFileDialog extends FileDialog<URI | URI[]> {
  /** Dialog properties */
  readonly props: OpenFileDialogProps;
  
  /** Currently selected items */
  readonly selectedItems: URI[];
  
  /** Accept the current selection */
  accept(): void;
}

/**
 * File save dialog implementation
 */
class SaveFileDialog extends FileDialog<URI> {
  /** Dialog properties */
  readonly props: SaveFileDialogProps;
  
  /** Filename input element */
  readonly fileNameInput: HTMLInputElement;
  
  /** Get the entered filename */
  readonly fileName: string;
  
  /** Accept the current filename */
  accept(): void;
}

Dialog Model and Tree Integration

Model classes managing dialog state and file tree integration for directory navigation.

/**
 * Dialog model managing state and navigation
 */
interface FileDialogModel extends FileTreeModel {
  /** Available file filters */
  readonly filters: FileFilter[];
  
  /** Currently active filter */
  activeFilter: FileFilter | undefined;
  
  /** Whether to show hidden files */
  showHiddenFiles: boolean;
  
  /** Apply current filter to tree nodes */
  filterTree(): void;
}

/**
 * Tree implementation for file dialogs
 */
interface FileDialogTree extends FileTree {
  /** Dialog-specific tree model */
  readonly model: FileDialogModel;
  
  /** Handle file filter changes */
  applyFileFilter(filter: FileFilter): void;
}

Dialog Widget and Components

Complete widget implementation with all UI components and interaction handlers.

/**
 * Main dialog widget with all components
 */
interface FileDialogWidget extends DialogWidget {
  /** Dialog model instance */
  readonly model: FileDialogModel;
  
  /** File tree component */
  readonly tree: FileDialogTree;
  
  /** Location navigation bar */
  readonly locationBar: HTMLElement;
  
  /** File filter dropdown */
  readonly filterSelect: HTMLSelectElement;
  
  /** Hidden files toggle */
  readonly hiddenFilesToggle: HTMLInputElement;
}

Default Implementation

Default service implementation with support for both web and Electron environments.

/**
 * Default implementation of FileDialogService
 */
@injectable()
class DefaultFileDialogService implements FileDialogService {
  /** Open file dialog factory */
  protected readonly openFileDialogFactory: OpenFileDialogFactory;
  
  /** Save file dialog factory */
  protected readonly saveFileDialogFactory: SaveFileDialogFactory;
  
  async showOpenDialog(props: OpenFileDialogProps, folder?: FileStat): Promise<URI | URI[] | undefined> {
    const dialog = this.openFileDialogFactory(props);
    if (folder) {
      dialog.model.location = folder.resource;
    }
    const result = await dialog.open();
    return result;
  }
  
  async showSaveDialog(props: SaveFileDialogProps, folder?: FileStat): Promise<URI | undefined> {
    const dialog = this.saveFileDialogFactory(props);
    if (folder) {
      dialog.model.location = folder.resource;
    }
    return dialog.open();
  }
}

Usage Examples:

import { FileDialogService, OpenFileDialogProps, SaveFileDialogProps } from "@theia/filesystem/lib/browser";
import { URI } from "@theia/core/lib/common/uri";

// Inject the service
const dialogService = container.get(FileDialogService);

// Open single file
const fileUri = await dialogService.showOpenDialog({
  title: 'Select Configuration File',
  canSelectFiles: true,
  canSelectFolders: false,
  filters: [
    { name: 'JSON Files', extensions: ['json'] },
    { name: 'YAML Files', extensions: ['yml', 'yaml'] },
    { name: 'All Files', extensions: ['*'] }
  ]
});

if (fileUri) {
  console.log(`Selected file: ${fileUri.toString()}`);
}

// Open multiple files
const fileUris = await dialogService.showOpenDialog({
  title: 'Select Source Files',
  canSelectFiles: true,
  canSelectFolders: false,
  canSelectMany: true,
  filters: [
    { name: 'TypeScript Files', extensions: ['ts', 'tsx'] },
    { name: 'JavaScript Files', extensions: ['js', 'jsx'] }
  ]
});

if (Array.isArray(fileUris)) {
  console.log(`Selected ${fileUris.length} files`);
  fileUris.forEach(uri => console.log(uri.toString()));
} else if (fileUris) {
  console.log(`Selected single file: ${fileUris.toString()}`);
}

// Select folder
const folderUri = await dialogService.showOpenDialog({
  title: 'Select Project Folder',
  canSelectFiles: false,
  canSelectFolders: true,
  openLabel: 'Select Folder'
});

// Save file dialog
const saveUri = await dialogService.showSaveDialog({
  title: 'Save Output File',
  saveLabel: 'Save',
  inputValue: 'output.json',
  filters: [
    { name: 'JSON Files', extensions: ['json'] },
    { name: 'Text Files', extensions: ['txt'] }
  ]
});

if (saveUri) {
  console.log(`Save location: ${saveUri.toString()}`);
}

// Advanced dialog with initial location
const workspaceFolder = URI.parse('file:///workspace');
const fileUri2 = await dialogService.showOpenDialog({
  title: 'Select File from Workspace',
  canSelectFiles: true,
  defaultPath: workspaceFolder.fsPath
}, { 
  resource: workspaceFolder,
  isDirectory: true 
} as FileStat);

Electron Native Dialog Integration

For Electron applications, native system dialogs are used when available:

import { ElectronFileDialogService } from "@theia/filesystem/lib/electron-browser";

// Electron-specific service uses native dialogs
@injectable()
class ElectronFileDialogService implements FileDialogService {
  // Uses Electron's dialog.showOpenDialog() and dialog.showSaveDialog()
  // Provides native OS file dialog experience
}

Custom Dialog Implementations

// Custom dialog with additional validation
class ValidatingFileDialog extends OpenFileDialog {
  
  protected accept(): void {
    const selected = this.selectedItems;
    
    // Custom validation logic
    if (!this.validateSelection(selected)) {
      this.setErrorMessage('Invalid file selection');
      return;
    }
    
    super.accept();
  }
  
  private validateSelection(uris: URI[]): boolean {
    // Custom validation logic
    return uris.every(uri => 
      uri.toString().includes('valid-directory')
    );
  }
}

Install with Tessl CLI

npx tessl i tessl/npm-theia--filesystem

docs

file-dialog.md

file-resource.md

file-service.md

file-tree.md

filesystem-core.md

filesystem-preferences.md

index.md

tile.json