-
+
${this.branch && !this.open
- ? html``
+ ? html``
: nothing}
${this.branch && this.open
- ? html``
+ ? html``
+ : nothing}
+ ${!this.branch
+ ? html``
: nothing}
- ${!this.branch ? html`` : nothing}
-
-
-
-
-
('vscode-list');
export interface ConfigContext {
- readonly arrows: boolean;
+ readonly hideArrows: boolean;
readonly expandMode: ExpandMode;
readonly indent: number;
- readonly indentGuides: boolean;
+ readonly indentGuides: IndentGuideDisplay;
readonly multiSelect: boolean;
}
diff --git a/src/vscode-tree/vscode-tree.styles.ts b/src/vscode-tree/vscode-tree.styles.ts
index 82d1d35b5..c56d28bad 100644
--- a/src/vscode-tree/vscode-tree.styles.ts
+++ b/src/vscode-tree/vscode-tree.styles.ts
@@ -5,13 +5,49 @@ const styles: CSSResultGroup = [
defaultStyles,
css`
:host {
- --vsc-tree-item-arrow-display: none;
+ --vsc-tree-item-arrow-display: flex;
+ --internal-selectionBackground: var(
+ --vscode-list-inactiveSelectionBackground
+ );
+ --internal-selectionForeground: var(--vscode-foreground);
+ --internal-selectionIconForeground: var(--vscode-icon-foreground);
+ --internal-defaultIndentGuideDisplay: none;
+ --internal-highlightedIndentGuideDisplay: block;
display: block;
}
- :host([arrows]) {
- --vsc-tree-item-arrow-display: flex;
+ :host(:hover) {
+ --internal-defaultIndentGuideDisplay: block;
+ --internal-highlightedIndentGuideDisplay: block;
+ }
+
+ :host(:focus-within) {
+ --internal-selectionBackground: var(
+ --vscode-list-activeSelectionBackground
+ );
+ --internal-selectionForeground: var(
+ --vscode-list-activeSelectionForeground
+ );
+ --internal-selectionIconForeground: var(
+ --vscode-list-activeSelectionIconForeground
+ );
+ }
+
+ :host([hide-arrows]) {
+ --vsc-tree-item-arrow-display: none;
+ }
+
+ :host([indent-guides='none']),
+ :host([indent-guides='none']:hover) {
+ --internal-defaultIndentGuideDisplay: none;
+ --internal-highlightedIndentGuideDisplay: none;
+ }
+
+ :host([indent-guides='always']),
+ :host([indent-guides='always']:hover) {
+ --internal-defaultIndentGuideDisplay: block;
+ --internal-highlightedIndentGuideDisplay: block;
}
`,
];
diff --git a/src/vscode-tree/vscode-tree.ts b/src/vscode-tree/vscode-tree.ts
index c9e38f6a7..0140d33a0 100644
--- a/src/vscode-tree/vscode-tree.ts
+++ b/src/vscode-tree/vscode-tree.ts
@@ -23,12 +23,21 @@ import {
export type VscTreeSelectEvent = CustomEvent<{selectedItems: VscodeTreeItem[]}>;
-export const EXPAND_MODE = {
- SINGLE_CLICK: 'singleClick',
- DOUBLE_CLICK: 'doubleClick',
+export const ExpandMode = {
+ singleClick: 'singleClick',
+ doubleClick: 'doubleClick',
} as const;
-export type ExpandMode = (typeof EXPAND_MODE)[keyof typeof EXPAND_MODE];
+export type ExpandMode = (typeof ExpandMode)[keyof typeof ExpandMode];
+
+export const IndentGuides = {
+ none: 'none',
+ onHover: 'onHover',
+ always: 'always',
+} as const;
+
+export type IndentGuideDisplay =
+ (typeof IndentGuides)[keyof typeof IndentGuides];
type ListenedKey =
| 'ArrowDown'
@@ -50,32 +59,62 @@ const listenedKeys: ListenedKey[] = [
'Escape',
'Shift',
];
-const DEFAULT_ARROWS = false;
+const DEFAULT_HIDE_ARROWS = false;
const DEFAULT_INDENT = 8;
-const DEFAULT_INDENT_GUIDES = false;
const DEFAULT_MULTI_SELECT = false;
-const DEFAULT_EXPAND_MODE = EXPAND_MODE.SINGLE_CLICK;
-
+const DEFAULT_EXPAND_MODE = ExpandMode.singleClick;
+const DEFAULT_INDENT_GUIDE_DISPLAY = IndentGuides.onHover;
+
+/**
+ * @tag vscode-tree
+ *
+ * @prop {'singleClick' | 'doubleClick'} expandMode
+ */
@customElement('vscode-tree')
export class VscodeTree extends VscElement {
static override styles = styles;
//#region properties
- @property({type: Boolean, reflect: true})
- arrows = DEFAULT_ARROWS;
+ /**
+ * Although arrows are always visible in the Tree component by default in VSCode, some icon sets
+ * (e.g., Material Icon Theme) allow disabling them in the file explorer view. This flag makes it
+ * possible to mimic that behavior.
+ */
+ @property({type: Boolean, reflect: true, attribute: 'hide-arrows'})
+ hideArrows = false;
+ /**
+ * Controls how tree folders are expanded when clicked. This property is designed to use
+ * the `workbench.tree.expandMode` setting.
+ */
@property({type: String, attribute: 'expand-mode'})
- expandMode: ExpandMode = DEFAULT_EXPAND_MODE;
+ expandMode: ExpandMode = 'singleClick';
+ /**
+ * Controls the indentation in pixels. This property is designed to use the
+ * `workbench.tree.indent` setting.
+ */
@property({type: Number, reflect: true})
- indent = DEFAULT_INDENT;
+ indent = 8;
- @property({type: Boolean, attribute: 'indent-guides', reflect: true})
- indentGuides = DEFAULT_INDENT_GUIDES;
+ /**
+ * Controls whether the tree should render indent guides. This property is
+ * designed to use the `workbench.tree.renderIndentGuides` setting.
+ */
+ @property({
+ type: String,
+ attribute: 'indent-guides',
+ useDefault: true,
+ reflect: true,
+ })
+ indentGuides: IndentGuideDisplay = 'onHover';
+ /**
+ * Allows selecting multiple items.
+ */
@property({type: Boolean, reflect: true, attribute: 'multi-select'})
- multiSelect = DEFAULT_MULTI_SELECT;
+ multiSelect = false;
//#endregion
@@ -103,10 +142,10 @@ export class VscodeTree extends VscElement {
@provide({context: configContext})
private _configContext: ConfigContext = {
- arrows: DEFAULT_ARROWS,
+ hideArrows: DEFAULT_HIDE_ARROWS,
expandMode: DEFAULT_EXPAND_MODE,
indent: DEFAULT_INDENT,
- indentGuides: DEFAULT_INDENT_GUIDES,
+ indentGuides: DEFAULT_INDENT_GUIDE_DISPLAY,
multiSelect: DEFAULT_MULTI_SELECT,
};
@@ -140,6 +179,9 @@ export class VscodeTree extends VscElement {
//#region public methods
+ /**
+ * Expands all folders.
+ */
expandAll() {
const children = this.querySelectorAll('vscode-tree-item');
@@ -150,6 +192,9 @@ export class VscodeTree extends VscElement {
});
}
+ /**
+ * Collapses all folders.
+ */
collapseAll() {
const children = this.querySelectorAll('vscode-tree-item');
@@ -222,10 +267,10 @@ export class VscodeTree extends VscElement {
}
private _updateConfigContext(changedProperties: PropertyValues) {
- const {arrows, expandMode, indent, indentGuides, multiSelect} = this;
+ const {hideArrows, expandMode, indent, indentGuides, multiSelect} = this;
- if (changedProperties.has('arrows')) {
- this._configContext = {...this._configContext, arrows};
+ if (changedProperties.has('hideArrows')) {
+ this._configContext = {...this._configContext, hideArrows};
}
if (changedProperties.has('expandMode')) {