diff --git a/packages/core/src/browser/tree/tree-model.ts b/packages/core/src/browser/tree/tree-model.ts index da808e5b2f0f7..97526a3da4c0d 100644 --- a/packages/core/src/browser/tree/tree-model.ts +++ b/packages/core/src/browser/tree/tree-model.ts @@ -472,6 +472,14 @@ export class TreeModelImpl implements TreeModel, SelectionProvider { + return this.tree.onDidUpdate; + } + + markAsChecked(node: TreeNode, checked: boolean): void { + this.tree.markAsChecked(node, checked); + } + } export namespace TreeModelImpl { export interface State { diff --git a/packages/core/src/browser/tree/tree-widget.tsx b/packages/core/src/browser/tree/tree-widget.tsx index 252e8463b36f5..4b93c4755f26e 100644 --- a/packages/core/src/browser/tree/tree-widget.tsx +++ b/packages/core/src/browser/tree/tree-widget.tsx @@ -252,6 +252,7 @@ export class TreeWidget extends ReactWidget implements StatefulWidget { this.model.onSelectionChanged(() => this.scheduleUpdateScrollToRow({ resize: false })), this.focusService.onDidChangeFocus(() => this.scheduleUpdateScrollToRow({ resize: false })), this.model.onDidChangeBusy(() => this.update()), + this.model.onDidUpdate(() => this.update()), this.model.onNodeRefreshed(() => this.updateDecorations()), this.model.onExpansionChanged(() => this.updateDecorations()), this.decoratorService, @@ -578,6 +579,41 @@ export class TreeWidget extends ReactWidget implements StatefulWidget { ; } + /** + * Render the node expansion toggle. + * @param node the tree node. + * @param props the node properties. + */ + protected renderCheckbox(node: TreeNode, props: NodeProps): React.ReactNode { + if (node.checkboxInfo === undefined) { + // eslint-disable-next-line no-null/no-null + return null; + } + return this.toggleChecked(event)} /> + + } + + protected toggleChecked(event: React.MouseEvent) { + const nodeId = event.currentTarget.getAttribute('data-node-id'); + if (nodeId) { + const node = this.model.getNode(nodeId); + if (node) { + this.model.markAsChecked(node, !node.checkboxInfo!.checked); + } else { + this.handleClickEvent(node, event); + } + } + event.preventDefault(); + event.stopPropagation(); + } /** * Render the tree node caption given the node properties. * @param node the tree node. @@ -905,6 +941,7 @@ export class TreeWidget extends ReactWidget implements StatefulWidget { const attributes = this.createNodeAttributes(node, props); const content =
{this.renderExpansionToggle(node, props)} + {this.renderCheckbox(node, props)} {this.decorateIcon(node, this.renderIcon(node, props))} {this.renderCaptionAffixes(node, props, 'captionPrefixes')} {this.renderCaption(node, props)} diff --git a/packages/core/src/browser/tree/tree.ts b/packages/core/src/browser/tree/tree.ts index 8289639e41fb4..5ef93e9a78529 100644 --- a/packages/core/src/browser/tree/tree.ts +++ b/packages/core/src/browser/tree/tree.ts @@ -20,6 +20,7 @@ import { Disposable, DisposableCollection } from '../../common/disposable'; import { CancellationToken, CancellationTokenSource } from '../../common/cancellation'; import { timeout } from '../../common/promise-util'; import { isObject, Mutable } from '../../common'; +import { AccessibilityInformation } from '../../common/accessibility'; export const Tree = Symbol('Tree'); @@ -70,6 +71,19 @@ export interface Tree extends Disposable { * A token source of the given token should be canceled to unmark. */ markAsBusy(node: Readonly, ms: number, token: CancellationToken): Promise; + + /** + * An update to the tree node occurred, but the tree structure remains unchanged + */ + readonly onDidUpdate: Event; + + markAsChecked(node: TreeNode, checked: boolean): void; +} + +export interface TreeViewItemCheckboxInfo { + checked: boolean; + tooltip?: string; + accessibilityInformation?: AccessibilityInformation } /** @@ -120,6 +134,11 @@ export interface TreeNode { * Whether this node is busy. Greater than 0 then busy; otherwise not. */ readonly busy?: number; + + /** + * Whether this node is checked. + */ + readonly checkboxInfo?: TreeViewItemCheckboxInfo; } export namespace TreeNode { @@ -238,6 +257,8 @@ export class TreeImpl implements Tree { protected readonly onDidChangeBusyEmitter = new Emitter(); readonly onDidChangeBusy = this.onDidChangeBusyEmitter.event; + protected readonly onDidUpdateEmitter = new Emitter(); + readonly onDidUpdate = this.onDidUpdateEmitter.event; protected nodes: { [id: string]: Mutable | undefined @@ -368,6 +389,12 @@ export class TreeImpl implements Tree { await this.doMarkAsBusy(node, ms, token); } } + + markAsChecked(node: Mutable, checked: boolean) { + node.checkboxInfo!.checked = checked; + this.onDidUpdateEmitter.fire([node]); + } + protected async doMarkAsBusy(node: Mutable, ms: number, token: CancellationToken): Promise { try { await timeout(ms, token); diff --git a/packages/plugin-ext/src/common/plugin-api-rpc.ts b/packages/plugin-ext/src/common/plugin-api-rpc.ts index 2857dbb4d106f..20e416dba5721 100644 --- a/packages/plugin-ext/src/common/plugin-api-rpc.ts +++ b/packages/plugin-ext/src/common/plugin-api-rpc.ts @@ -118,6 +118,7 @@ import { isString, isObject, PickOptions, QuickInputButtonHandle } from '@theia/ import { Severity } from '@theia/core/lib/common/severity'; import { DebugConfiguration, DebugSessionOptions } from '@theia/debug/lib/common/debug-configuration'; import { LanguagePackBundle } from './language-pack-service'; +import { AccessibilityInformation } from '@theia/core/lib/common/accessibility'; export interface PreferenceData { [scope: number]: any; @@ -736,6 +737,7 @@ export interface DialogsMain { } export interface RegisterTreeDataProviderOptions { + manageCheckboxStateManually?: boolean; showCollapseAll?: boolean canSelectMany?: boolean dragMimeTypes?: string[] @@ -768,6 +770,7 @@ export class DataTransferFileDTO { } export interface TreeViewsExt { + $checkStateChanged(treeViewId: string, itemIds: { id: string, checked: boolean }[]): unknown; $dragStarted(treeViewId: string, treeItemIds: string[], token: CancellationToken): Promise; $dragEnd(treeViewId: string): Promise; $drop(treeViewId: string, treeItemId: string | undefined, dataTransferItems: [string, string | DataTransferFileDTO][], token: CancellationToken): Promise; @@ -779,6 +782,12 @@ export interface TreeViewsExt { $setVisible(treeViewId: string, visible: boolean): Promise; } +export interface TreeViewItemCheckboxInfo { + checked: boolean; + tooltip?: string; + accessibilityInformation?: AccessibilityInformation +} + export interface TreeViewItem { id: string; @@ -801,6 +810,8 @@ export interface TreeViewItem { collapsibleState?: TreeViewItemCollapsibleState; + checkboxInfo?: TreeViewItemCheckboxInfo; + contextValue?: string; command?: Command; diff --git a/packages/plugin-ext/src/main/browser/view/tree-view-widget.tsx b/packages/plugin-ext/src/main/browser/view/tree-view-widget.tsx index 1d34ac5658dc9..c6ea2fd16a732 100644 --- a/packages/plugin-ext/src/main/browser/view/tree-view-widget.tsx +++ b/packages/plugin-ext/src/main/browser/view/tree-view-widget.tsx @@ -50,7 +50,7 @@ import { AccessibilityInformation } from '@theia/plugin'; import { ColorRegistry } from '@theia/core/lib/browser/color-registry'; import { DecoratedTreeNode } from '@theia/core/lib/browser/tree/tree-decorator'; import { WidgetDecoration } from '@theia/core/lib/browser/widget-decoration'; -import { CancellationTokenSource, CancellationToken } from '@theia/core/lib/common'; +import { CancellationTokenSource, CancellationToken, Mutable } from '@theia/core/lib/common'; import { mixin } from '../../../common/types'; import { Deferred } from '@theia/core/lib/common/promise-util'; import { DnDFileContentStore } from './dnd-file-content-store'; @@ -165,6 +165,7 @@ export namespace CompositeTreeViewNode { @injectable() export class TreeViewWidgetOptions { id: string; + manageCheckboxStateManually: boolean | undefined; showCollapseAll: boolean | undefined; multiSelect: boolean | undefined; dragMimeTypes: string[] | undefined; @@ -272,6 +273,40 @@ export class PluginTree extends TreeImpl { }, update); } + override markAsChecked(node: Mutable, checked: boolean): void { + function findParentsToChange(child: TreeNode, nodes: TreeNode[]): void { + if (child.parent) { + if (child.parent.checkboxInfo !== undefined && child.parent.checkboxInfo.checked !== checked) { + if (!checked || child.parent.children.every(candidate => candidate.checkboxInfo?.checked || candidate.checkboxInfo === undefined || candidate === child)) { + nodes.push(child.parent); + findParentsToChange(child.parent, nodes); + } + } + } + } + + function findChildrenToChange(parent: TreeNode, nodes: TreeNode[]): void { + if (CompositeTreeNode.is(parent)) { + parent.children.forEach(child => { + if (child.checkboxInfo !== undefined && child.checkboxInfo.checked !== checked) { + nodes.push(child); + } + findChildrenToChange(child, nodes); + }); + } + } + + const nodesToChange = [node]; + if (!this.options.manageCheckboxStateManually) { + findParentsToChange(node, nodesToChange); + findChildrenToChange(node, nodesToChange); + + } + nodesToChange.forEach(n => n.checkboxInfo!.checked = checked) + this.onDidUpdateEmitter.fire(nodesToChange); + this.proxy?.$checkStateChanged(this.options.id, [{ id: node.id, checked: checked }]); + } + /** Creates a resolvable tree node. If a node already exists, reset it because the underlying TreeViewItem might have been disposed in the backend. */ protected createResolvableTreeNode(item: TreeViewItem, parent: CompositeTreeNode): TreeNode { const update: Partial = this.createTreeNodeUpdate(item); @@ -328,6 +363,7 @@ export class PluginTree extends TreeImpl { tooltip: item.tooltip, contextValue: item.contextValue, command: item.command, + checkboxInfo: item.checkboxInfo, accessibilityInformation: item.accessibilityInformation, }; } @@ -496,6 +532,7 @@ export class TreeViewWidget extends TreeViewWelcomeWidget { ...attrs, onMouseLeave: () => source?.cancel(), onMouseEnter: async event => { + const target = event.currentTarget; // event.currentTarget will be null after awaiting node resolve() if (configuredTip) { if (MarkdownString.is(node.tooltip)) { this.hoverService.requestHover({ @@ -524,7 +561,7 @@ export class TreeViewWidget extends TreeViewWelcomeWidget { const title = node.tooltip || (node.resourceUri && this.labelProvider.getLongName(new URI(node.resourceUri))) || this.toNodeName(node); - event.currentTarget.title = title; + target.title = title; } configuredTip = true; } diff --git a/packages/plugin-ext/src/main/browser/view/tree-views-main.ts b/packages/plugin-ext/src/main/browser/view/tree-views-main.ts index 9bd9edb22d073..d2bc6b14d2130 100644 --- a/packages/plugin-ext/src/main/browser/view/tree-views-main.ts +++ b/packages/plugin-ext/src/main/browser/view/tree-views-main.ts @@ -63,6 +63,7 @@ export class TreeViewsMainImpl implements TreeViewsMain, Disposable { this.treeViewProviders.set(treeViewId, this.viewRegistry.registerViewDataProvider(treeViewId, async ({ state, viewInfo }) => { const options: TreeViewWidgetOptions = { id: treeViewId, + manageCheckboxStateManually: $options.manageCheckboxStateManually, showCollapseAll: $options.showCollapseAll, multiSelect: $options.canSelectMany, dragMimeTypes: $options.dragMimeTypes, @@ -183,6 +184,15 @@ export class TreeViewsMainImpl implements TreeViewsMain, Disposable { } } + async setChecked(treeViewWidget: TreeViewWidget, changedNodes: TreeViewNode[]) { + this.proxy.$checkStateChanged(treeViewWidget.id, changedNodes.map(node => { + return { + id: node.id, + checked: !!node.checkboxInfo?.checked + } + })); + } + protected handleTreeEvents(treeViewId: string, treeViewWidget: TreeViewWidget): void { this.toDispose.push(treeViewWidget.model.onExpansionChanged(event => { this.proxy.$setExpanded(treeViewId, event.id, event.expanded); diff --git a/packages/plugin-ext/src/plugin/plugin-context.ts b/packages/plugin-ext/src/plugin/plugin-context.ts index 90ca33946d3dc..e29d624f91b79 100644 --- a/packages/plugin-ext/src/plugin/plugin-context.ts +++ b/packages/plugin-ext/src/plugin/plugin-context.ts @@ -98,6 +98,7 @@ import { DataTransfer, TreeItem, TreeItemCollapsibleState, + TreeItemCheckboxState, DocumentSymbol, SymbolTag, WorkspaceEdit, @@ -1291,6 +1292,7 @@ export function createAPIFactory( DataTransfer, TreeItem, TreeItemCollapsibleState, + TreeItemCheckboxState, SymbolKind, SymbolTag, DocumentSymbol, diff --git a/packages/plugin-ext/src/plugin/tree/tree-views.ts b/packages/plugin-ext/src/plugin/tree/tree-views.ts index 6715ee9d6a715..c8188106bf64b 100644 --- a/packages/plugin-ext/src/plugin/tree/tree-views.ts +++ b/packages/plugin-ext/src/plugin/tree/tree-views.ts @@ -18,14 +18,14 @@ import { TreeDataProvider, TreeView, TreeViewExpansionEvent, TreeItem, TreeItemLabel, - TreeViewSelectionChangeEvent, TreeViewVisibilityChangeEvent, CancellationToken, DataTransferFile, TreeViewOptions, ViewBadge + TreeViewSelectionChangeEvent, TreeViewVisibilityChangeEvent, CancellationToken, DataTransferFile, TreeViewOptions, ViewBadge, TreeCheckboxChangeEvent } from '@theia/plugin'; // TODO: extract `@theia/util` for event, disposable, cancellation and common types // don't use @theia/core directly from plugin host import { Emitter } from '@theia/core/lib/common/event'; import { basename } from '@theia/core/lib/common/paths'; import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable'; -import { DataTransfer, DataTransferItem, Disposable as PluginDisposable, ThemeIcon } from '../types-impl'; +import { DataTransfer, DataTransferItem, Disposable as PluginDisposable, ThemeIcon, TreeItemCheckboxState } from '../types-impl'; import { Plugin, PLUGIN_RPC_CONTEXT, TreeViewsExt, TreeViewsMain, TreeViewItem, TreeViewRevealOptions, DataTransferFileDTO } from '../../common/plugin-api-rpc'; import { RPCProtocol } from '../../common/rpc-protocol'; import { CommandRegistryImpl, CommandsConverter } from '../command-registry'; @@ -33,6 +33,7 @@ import { TreeViewItemReference } from '../../common'; import { PluginIconPath } from '../plugin-icon-path'; import { URI } from '@theia/core/shared/vscode-uri'; import { UriComponents } from '@theia/core/lib/common/uri'; +import { isObject } from '@theia/core'; export class TreeViewsExtImpl implements TreeViewsExt { private proxy: TreeViewsMain; @@ -54,6 +55,9 @@ export class TreeViewsExtImpl implements TreeViewsExt { } }); } + $checkStateChanged(treeViewId: string, itemIds: { id: string; checked: boolean; }[]): unknown { + return this.getTreeView(treeViewId).checkStateChanged(itemIds); + } $dragStarted(treeViewId: string, treeItemIds: string[], token: CancellationToken): Promise { return this.getTreeView(treeViewId).onDragStarted(treeItemIds, token); } @@ -107,6 +111,9 @@ export class TreeViewsExtImpl implements TreeViewsExt { get onDidChangeVisibility() { return treeView.onDidChangeVisibility; }, + get onDidChangeCheckboxState() { + return treeView.onDidChangeCheckboxState; + }, get message(): string { return treeView.message; }, @@ -211,6 +218,9 @@ class TreeViewExtImpl implements Disposable { private readonly onDidChangeVisibilityEmitter = new Emitter(); readonly onDidChangeVisibility = this.onDidChangeVisibilityEmitter.event; + private readonly onDidChangeCheckboxStateEmitter = new Emitter>(); + readonly onDidChangeCheckboxState = this.onDidChangeCheckboxStateEmitter.event; + private readonly nodes = new Map>(); private pendingRefresh = Promise.resolve(); @@ -234,7 +244,7 @@ class TreeViewExtImpl implements Disposable { // make copies of optionally provided MIME types: const dragMimeTypes = options.dragAndDropController?.dragMimeTypes?.slice(); const dropMimeTypes = options.dragAndDropController?.dropMimeTypes?.slice(); - proxy.$registerTreeDataProvider(treeViewId, { showCollapseAll: options.showCollapseAll, canSelectMany: options.canSelectMany, dragMimeTypes, dropMimeTypes }); + proxy.$registerTreeDataProvider(treeViewId, { manageCheckboxStateManually: options.manageCheckboxStateManually, showCollapseAll: options.showCollapseAll, canSelectMany: options.canSelectMany, dragMimeTypes, dropMimeTypes }); this.toDispose.push(Disposable.create(() => this.proxy.$unregisterTreeDataProvider(treeViewId))); options.treeDataProvider.onDidChangeTreeData?.(() => { this.pendingRefresh = proxy.$refresh(treeViewId); @@ -399,7 +409,7 @@ class TreeViewExtImpl implements Disposable { const treeItem = await this.options.treeDataProvider.getTreeItem(value); // Convert theia.TreeItem to the TreeViewItem - const label = this.getItemLabel(treeItem); + const label = this.getItemLabel(treeItem) || ''; const highlights = this.getTreeItemLabelHighlights(treeItem); // Generate the ID @@ -433,7 +443,22 @@ class TreeViewExtImpl implements Disposable { iconUrl = PluginIconPath.toUrl(iconPath, this.plugin); } - const treeViewItem = { + let checkboxInfo; + if (treeItem.checkboxState === undefined) { + checkboxInfo = undefined; + } else if (isObject(treeItem.checkboxState)) { + checkboxInfo = { + checked: treeItem.checkboxState.state === TreeItemCheckboxState.Checked, + tooltip: treeItem.checkboxState.tooltip, + accessibilityInformation: treeItem.accessibilityInformation + } + } else { + checkboxInfo = { + checked: treeItem.checkboxState === TreeItemCheckboxState.Checked + } + } + + const treeViewItem: TreeViewItem = { id, label, highlights, @@ -443,11 +468,12 @@ class TreeViewExtImpl implements Disposable { description: treeItem.description, resourceUri: treeItem.resourceUri, tooltip: treeItem.tooltip, - collapsibleState: treeItem.collapsibleState, + collapsibleState: treeItem.collapsibleState?.valueOf(), + checkboxInfo: checkboxInfo, contextValue: treeItem.contextValue, command: this.commandsConverter.toSafeCommand(treeItem.command, toDisposeElement), accessibilityInformation: treeItem.accessibilityInformation - } as TreeViewItem; + }; node.treeViewItem = treeViewItem; return treeViewItem; @@ -511,6 +537,25 @@ class TreeViewExtImpl implements Disposable { } } + checkStateChanged(items: readonly { id: string; checked: boolean; }[]): void { + const transformed: [T, TreeItemCheckboxState][] = []; + items.forEach(item => { + const node = this.nodes.get(item.id); + if (node) { + if (node.value) { + transformed.push([node.value, item.checked ? TreeItemCheckboxState.Checked : TreeItemCheckboxState.Unchecked]); + } + if (node.treeViewItem) { + node.treeViewItem.checkboxInfo!.checked = item.checked; + } + } + }); + + this.onDidChangeCheckboxStateEmitter.fire({ + items: transformed + }); + } + async resolveTreeItem(treeItemId: string, token: CancellationToken): Promise { if (!this.options.treeDataProvider.resolveTreeItem) { return undefined; diff --git a/packages/plugin-ext/src/plugin/types-impl.ts b/packages/plugin-ext/src/plugin/types-impl.ts index 012e8f128e90b..b63f4c4ac5d0d 100644 --- a/packages/plugin-ext/src/plugin/types-impl.ts +++ b/packages/plugin-ext/src/plugin/types-impl.ts @@ -1908,6 +1908,9 @@ export class TreeItem { contextValue?: string; + checkboxState?: theia.TreeItemCheckboxState | { readonly state: theia.TreeItemCheckboxState; readonly tooltip?: string; readonly accessibilityInformation?: AccessibilityInformation }; + + constructor(label: string | theia.TreeItemLabel, collapsibleState?: theia.TreeItemCollapsibleState) constructor(resourceUri: URI, collapsibleState?: theia.TreeItemCollapsibleState) constructor(arg1: string | theia.TreeItemLabel | URI, public collapsibleState: theia.TreeItemCollapsibleState = TreeItemCollapsibleState.None) { @@ -1925,6 +1928,11 @@ export enum TreeItemCollapsibleState { Expanded = 2 } +export enum TreeItemCheckboxState { + Unchecked = 0, + Checked = 1 +} + export enum SymbolTag { Deprecated = 1 } diff --git a/packages/plugin/src/theia.d.ts b/packages/plugin/src/theia.d.ts index 46655c88d1b19..0541277a7e8b7 100644 --- a/packages/plugin/src/theia.d.ts +++ b/packages/plugin/src/theia.d.ts @@ -5944,6 +5944,44 @@ export module '@theia/plugin' { * array containing all selected tree items. */ canSelectMany?: boolean; + + /** + * By default, when the children of a tree item have already been fetched, child checkboxes are automatically managed based on the checked state of the parent tree item. + * If the tree item is collapsed by default (meaning that the children haven't yet been fetched) then child checkboxes will not be updated. + * To override this behavior and manage child and parent checkbox state in the extension, set this to `true`. + * + * Examples where {@link TreeViewOptions.manageCheckboxStateManually} is false, the default behavior: + * + * 1. A tree item is checked, then its children are fetched. The children will be checked. + * + * 2. A tree item's parent is checked. The tree item and all of it's siblings will be checked. + * - [ ] Parent + * - [ ] Child 1 + * - [ ] Child 2 + * When the user checks Parent, the tree will look like this: + * - [x] Parent + * - [x] Child 1 + * - [x] Child 2 + * + * 3. A tree item and all of it's siblings are checked. The parent will be checked. + * - [ ] Parent + * - [ ] Child 1 + * - [ ] Child 2 + * When the user checks Child 1 and Child 2, the tree will look like this: + * - [x] Parent + * - [x] Child 1 + * - [x] Child 2 + * + * 4. A tree item is unchecked. The parent will be unchecked. + * - [x] Parent + * - [x] Child 1 + * - [x] Child 2 + * When the user unchecks Child 1, the tree will look like this: + * - [ ] Parent + * - [ ] Child 1 + * - [x] Child 2 + */ + manageCheckboxStateManually?: boolean; } /** @@ -6157,6 +6195,17 @@ export module '@theia/plugin' { readonly value: number; } + /** + * An event describing the change in a tree item's checkbox state. + */ + export interface TreeCheckboxChangeEvent { + /** + * The items that were checked or unchecked. + */ + readonly items: ReadonlyArray<[T, TreeItemCheckboxState]>; + } + + /** * Represents a Tree view */ @@ -6192,6 +6241,12 @@ export module '@theia/plugin' { */ readonly onDidChangeVisibility: Event; + + /** + * An event to signal that an element or root has either been checked or unchecked. + */ + readonly onDidChangeCheckboxState: Event>; + /** * An optional human-readable message that will be rendered in the view. * Setting the message to null, undefined, or empty string will remove the message from the view. @@ -6364,10 +6419,17 @@ export module '@theia/plugin' { */ accessibilityInformation?: AccessibilityInformation; + /** - * @param label A human-readable string describing this item - * @param collapsibleState {@link TreeItemCollapsibleState TreeItemCollapsibleState} of the tree item. Default is [TreeItemCollapsibleState.None](#TreeItemCollapsibleState.None) + * {@link TreeItemCheckboxState TreeItemCheckboxState} of the tree item. + * {@link TreeDataProvider.onDidChangeTreeData onDidChangeTreeData} should be fired when {@link TreeItem.checkboxState checkboxState} changes. */ + checkboxState?: TreeItemCheckboxState | { readonly state: TreeItemCheckboxState; readonly tooltip?: string; readonly accessibilityInformation?: AccessibilityInformation }; + + /** + * @param label A human-readable string describing this item + * @param collapsibleState {@link TreeItemCollapsibleState TreeItemCollapsibleState} of the tree item. Default is [TreeItemCollapsibleState.None](#TreeItemCollapsibleState.None) + */ constructor(label: string | TreeItemLabel, collapsibleState?: TreeItemCollapsibleState); /** @@ -6412,6 +6474,20 @@ export module '@theia/plugin' { highlights?: [number, number][]; } + /** + * Checkbox state of the tree item + */ + export enum TreeItemCheckboxState { + /** + * Determines an item is unchecked + */ + Unchecked = 0, + /** + * Determines an item is checked + */ + Checked = 1 + } + /** * Represents the configuration. It is a merged view of *