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