@@ -54,7 +54,7 @@ that override live.
5454## Tree
5555
5656` Tree ` is controlled: ` nodes ` describe the hierarchy, ` expandedIds ` controls
57- branches, and ` selectedItemId ` controls selection. Each
57+ branches, and the single- or multi-selection props control selection. Each
5858visible node renders as a flat ` treeitem ` , while normal keyboard navigation
5959keeps DOM focus on the ` tree ` container and identifies the active row with
6060` aria-activedescendant ` . Focus and selection are independent.
@@ -87,20 +87,46 @@ whose children are still loading. `icon`, `action`, and `className` customize
8787the row. Actions stay live on plain hover, as in the native list, and are
8888isolated from row selection and expansion.
8989
90- Arrow Up/Down, Home, and End move the active row through visible rows. Arrow Right
90+ Arrow Up/Down, Home, End, PageUp/PageDown, and buffered prefix/fuzzy typing
91+ move the active row through visible rows. Arrow Right
9192expands a branch or enters it; Arrow Left collapses it or moves to its parent.
9293
9394` expandMode="singleClick" ` is the default: clicking a branch selects
9495and toggles it, and Enter does the same. With ` expandMode="doubleClick" ` , a
9596single click or Enter only selects and a double click toggles expansion. Space
9697toggles a branch without selecting it, or selects a leaf. A normal-row twistie
9798toggles without changing selection. Alt-click recursively toggles descendant
98- branches.
99+ branches unless Alt is configured as the multi-selection modifier .
99100
100- Escape clears selection, then the active focus mark. Once neither remains,
101- Escape is left to the host. The root ` onKeyDown ` runs first, so a host
101+ Escape clears selection. It also clears the active focus mark when the tree has
102+ at most one selected row; after a larger multi-selection, a second Escape
103+ clears the remaining focus mark. Once neither selection nor a focus mark
104+ remains, Escape is left to the host. The root ` onKeyDown ` runs first, so a host
102105can intercept shortcuts with ` preventDefault() ` .
103106
107+ ` multiSelect ` uses ` selectedItemIds ` and ` onSelectedItemsChange ` and sets
108+ ` aria-multiselectable ` . ` multiSelectModifier ` chooses the toggle modifier:
109+ ` "ctrlCmd" ` (the default) uses Ctrl/Cmd and ` "alt" ` uses Alt. Shift-click and
110+ Shift+Arrow extend from the selection anchor; modifier clicks take precedence
111+ over expansion. Ctrl/Cmd+A selects the visible rows in the active sibling
112+ scope.
113+
114+ ` stickyScroll ` pins ancestors against the nearest scrolling ancestor. ` true `
115+ uses a maximum of seven pinned rows; a number supplies the maximum, and the
116+ widget is also capped at 40% of the viewport. The pinned region is a separate
117+ tab stop: Arrow Up/Down move among pinned ancestors, Arrow Down/Right from the
118+ deepest row enters its first visible child, Enter reveals, focuses, and selects
119+ the real row, Arrow Left reveals and focuses it and collapses an expanded
120+ branch, and Space only reveals and focuses it. A plain pointer click reveals,
121+ focuses, and selects; a pinned twistie additionally toggles the branch.
122+ Selection-modifier clicks update selection without revealing the real row.
123+
124+ Webviews do not receive ` workbench.tree.* ` settings automatically. Consumers
125+ that mirror native sticky-scroll preferences must read
126+ ` workbench.tree.enableStickyScroll ` and
127+ ` workbench.tree.stickyScrollMaxItemCount ` in the extension host and send the
128+ values to the webview.
129+
104130``` mermaid
105131flowchart LR
106132 accTitle: Tree architecture
@@ -113,6 +139,7 @@ flowchart LR
113139 Commands --> Transition
114140 Transition --> Adapter[useTreeAdapter.ts]
115141 Adapter --> Rows[Tree.tsx and TreeRow.tsx]
142+ Adapter --> Sticky[StickyScroll.tsx]
116143```
117144
118145The model, policy, and transitions stay pure. The adapter owns React and DOM
0 commit comments