Theia filesystem extension providing comprehensive file operations, tree widgets, dialogs, and file system integration for IDE environments.
—
Interactive file tree widget providing a hierarchical view of the filesystem with lazy loading, drag-and-drop support, context menus, and full integration with Theia's tree framework. Essential for file explorers and file selection interfaces.
Core tree implementation providing filesystem-specific tree behavior with lazy loading and file/directory distinction.
/**
* Tree implementation for file system with lazy loading
*/
@injectable()
class FileTree extends TreeImpl {
/** Resolve child nodes for a parent node with lazy loading */
resolveChildren(parent: CompositeTreeNode): Promise<TreeNode[]>;
/** Resolve file statistics for a file stat node */
protected resolveFileStat(node: FileStatNode): Promise<FileStat | undefined>;
/** Convert file statistics to tree nodes */
protected toNodes(fileStat: FileStat, parent: CompositeTreeNode): Promise<TreeNode[]>;
/** Create individual tree node from file statistics */
protected toNode(fileStat: FileStat, parent: CompositeTreeNode): FileNode | DirNode;
}Model class managing tree state, navigation, file system event handling, and location services.
/**
* Model managing tree state, navigation, and events
*/
@injectable()
interface FileTreeModel extends CompressedTreeModel, LocationService {
/** Current root location of the file tree */
location: URI | undefined;
/** Get available drives/roots for navigation */
drives(): Promise<URI[]>;
/** Get currently selected file stat nodes */
readonly selectedFileStatNodes: Readonly<FileStatNode>[];
/** Find tree nodes by URI */
getNodesByUri(uri: URI): IterableIterator<TreeNode>;
/** Navigate to a specific location */
navigateTo(uri: URI): Promise<TreeNode | undefined>;
/** Copy file or directory to target location */
copy(source: URI, target: Readonly<FileStatNode>): Promise<URI>;
/** Move file or directory between locations */
move(source: TreeNode, target: TreeNode): Promise<URI | undefined>;
/** Handle file system change events */
protected onFilesChanged(changes: FileChangesEvent): void;
/** Check if root directory is affected by changes */
protected isRootAffected(changes: FileChangesEvent): boolean;
/** Get URIs affected by file system changes */
protected getAffectedUris(changes: FileChangesEvent): URI[];
/** Refresh nodes affected by file system changes */
protected refreshAffectedNodes(uris: URI[]): boolean;
/** Get tree nodes affected by URI changes */
protected getAffectedNodes(uris: URI[]): Map<string, CompositeTreeNode>;
/** Check if user should replace existing file */
protected shouldReplace(fileName: string): Promise<boolean>;
/** Refresh the tree or specific node */
refresh(node?: CompositeTreeNode): Promise<void>;
/** Paste from clipboard */
paste(node?: TreeNode): Promise<void>;
}Main widget component providing the complete file tree user interface with context menus, drag-and-drop, and keyboard navigation.
/**
* Tree widget component with drag/drop and context menu support
*/
@injectable()
interface FileTreeWidget extends TreeWidget {
/** File tree model instance */
override readonly model: FileTreeModel;
/** Upload service for drag-and-drop file uploads */
protected readonly uploadService: FileUploadService;
/** Icon theme service for file icons */
protected readonly iconThemeService: IconThemeService;
/** Create custom node CSS class names */
protected createNodeClassNames(node: TreeNode, props: NodeProps): string[];
/** Render icon for tree node */
protected renderIcon(node: TreeNode, props: NodeProps): React.ReactNode;
/** Get tooltip text for node */
protected getNodeTooltip(node: TreeNode): string | undefined;
/** Handle drag start event for file operations */
protected handleDragStartEvent(node: TreeNode, event: React.DragEvent): void;
/** Handle drag over event for drop target validation */
protected handleDragOverEvent(node: TreeNode | undefined, event: React.DragEvent): void;
/** Handle drop event for file operations */
protected handleDropEvent(node: TreeNode | undefined, event: React.DragEvent): Promise<void>;
/** Get drop effect (copy or move) based on modifier keys */
protected getDropEffect(event: React.DragEvent): 'copy' | 'move';
/** Check if explorer arrows should be hidden */
protected get hidesExplorerArrows(): boolean;
/** Serialize node for storage */
protected deflateForStorage(node: TreeNode): object;
/** Deserialize node from storage */
protected inflateFromStorage(node: any, parent?: TreeNode): TreeNode;
}Type definitions for different kinds of tree nodes representing files and directories.
/**
* Base tree node with file statistics
*/
interface FileStatNode extends SelectableTreeNode, Mutable<UriSelection>, FileSelection {
/** File statistics for this node (added at runtime) */
fileStat: FileStat;
}
/**
* Tree node representing a file
*/
type FileNode = FileStatNode;
/**
* Tree node representing a directory
*/
type DirNode = FileStatNode & ExpandableTreeNode;Service providing labels, icons, and decorations for tree nodes.
/**
* Provides labels and icons for file tree nodes
*/
@injectable()
interface FileTreeLabelProvider extends LabelProvider {
/** Get display name for file stat node */
getName(element: FileStatNode): string;
/** Get long name (full path) for file stat node */
getLongName(element: FileStatNode): string;
/** Get icon class for file stat node */
getIcon(element: FileStatNode): string;
/** Get CSS classes for file stat node */
getClassNames(element: FileStatNode): string[];
/** Check if element affects this node's label */
affects(element: FileStatNode, event: DidChangeLabelEvent): boolean;
}Dependency injection container configuration for file tree components.
/**
* Create configured file tree container
*/
function createFileTreeContainer(parent: interfaces.Container): interfaces.Container;
/**
* Create configured file tree widget
*/
function createFileTreeWidget(parent: interfaces.Container): FileTreeWidget;Decoration service for adding badges, colors, and visual indicators to tree nodes.
/**
* Tree decorator for file-specific decorations
*/
@injectable()
interface FileTreeDecoratorAdapter extends TreeDecorator {
/** Unique identifier for this decorator */
readonly id: string;
/** Event fired when decorations change */
readonly onDidChangeDecorations: Event<(tree: Tree) => Map<string, TreeDecoration.Data>>;
/** Get decorations for all nodes in tree */
decorations(tree: Tree): MaybePromise<Map<string, TreeDecoration.Data>>;
/** Merge node and bubbled decorations */
protected mergeDecorations(ownDecoration?: TreeDecoration.Data, bubbledDecoration?: TreeDecoration.Data): TreeDecoration.Data | undefined;
/** Convert decorations to Theia format */
protected toTheiaDecoration(decorations: Decoration[], bubble?: boolean): TreeDecoration.Data;
/** Get URI for tree node */
protected getUriForNode(node: TreeNode): string | undefined;
/** Trigger decoration change event */
fireDidChangeDecorations(): void;
}CSS classes and constants used by file tree components.
/** Main file tree CSS class */
const FILE_TREE_CLASS = 'theia-FileTree';
/** File stat node CSS class */
const FILE_STAT_NODE_CLASS = 'theia-FileStatNode';
/** Directory node CSS class */
const DIR_NODE_CLASS = 'theia-DirNode';
/** File stat icon CSS class */
const FILE_STAT_ICON_CLASS = 'theia-FileStatIcon';
/** File tree container factory with default props */
function createFileTreeContainer(
parent: interfaces.Container,
overrides?: Partial<TreeContainerProps>
): Container;Usage Examples:
import { FileTreeWidget, FileTreeModel } from "@theia/filesystem/lib/browser";
import { URI } from "@theia/core/lib/common/uri";
// Create and configure file tree widget
const container = createFileTreeContainer(parentContainer);
const fileTree = container.get(FileTreeWidget);
// Set root location
fileTree.model.location = URI.parse('file:///workspace');
// Handle selection changes
fileTree.model.onSelectionChanged(selection => {
const selectedNodes = fileTree.model.selectedFileStatNodes;
for (const node of selectedNodes) {
console.log(`Selected: ${node.fileStat.resource.toString()}`);
}
});
// Navigate programmatically
await fileTree.model.navigateTo(URI.parse('file:///workspace/src'));
// Reveal specific file
await fileTree.revealFile(URI.parse('file:///workspace/package.json'));
// Handle file operations
fileTree.model.onDidFileOperation(event => {
console.log(`Operation: ${FileOperation[event.operation]} on ${event.target}`);
});
// Create files and folders
fileTree.createFile(); // Creates in current directory
fileTree.createFolder(); // Creates in current directory
// File upload
fileTree.model.onWillUpload(event => {
console.log(`Uploading to: ${event.parent.fileStat.resource}`);
});
// Custom context menu
fileTree.registerMenuAction({
commandId: 'custom.action',
label: 'Custom Action',
when: 'explorerResourceIsFile'
});import { FileTree } from "@theia/filesystem/lib/browser";
// Custom tree with additional functionality
@injectable()
class CustomFileTree extends FileTree {
// Override node creation for custom behavior
protected toNode(fileStat: FileStat, parent: CompositeTreeNode): FileNode | DirNode {
const node = super.toNode(fileStat, parent);
// Add custom properties
if (node.fileStat.isFile && node.fileStat.name.endsWith('.ts')) {
(node as any).isTypeScript = true;
}
return node;
}
// Custom filtering
protected async toNodes(fileStat: FileStat, parent: CompositeTreeNode): Promise<TreeNode[]> {
const nodes = await super.toNodes(fileStat, parent);
// Filter out hidden files
return nodes.filter(node =>
!node.name.startsWith('.') || this.showHiddenFiles
);
}
}
// Multi-selection operations
const selectedNodes = fileTree.model.selectedFileStatNodes;
if (selectedNodes.length > 1) {
// Bulk operations
await fileTree.delete(selectedNodes);
}Install with Tessl CLI
npx tessl i tessl/npm-theia--filesystem