Documentation Index
Fetch the complete documentation index at: https://anvil.servicetitan.com/llms.txt
Use this file to discover all available pages before exploring further.
Beta FeatureThis feature is currently in beta, and needs to be imported from
@servicetitan/anvil2/beta.While we hope to minimize breaking changes, they may occur due to feedback we receive or other improvements. These will always be documented in the changelog and communicated in Slack.Please reach out in the #ask-designsystem channel with any questions or feedback!- Implementation
Overview
The tree select menu family includes two components for different use cases:TreeSelectMenu— For async data loading with support for lazy branch expansion- Includes automatic debouncing of the search input (configurable via the
debounceMsprop) - Includes automatic LRU caching of search results and loaded children (configurable via the
cacheprop)
- Includes automatic debouncing of the search input (configurable via the
TreeSelectMenuSync— For client-side filtering of static tree option arrays
trigger render prop. They support cascading parent/child selection, keyboard navigation, and adaptive display modes (popover or dialog). Use a tree select menu when you need tree selection behavior outside of a form field context — for example, attaching a dropdown to a button, icon, or custom element.Looking for a form field with a built-in label, error state, and selected chips? Use
TreeSelectField instead.TreeSelectMenuSync (Static Options)
UseTreeSelectMenuSync when you have a static tree of options that can be filtered client-side.Filtering and Sorting
By default,TreeSelectMenuSync uses match-sorter to filter options by their label and searchText fields. The tree structure is preserved: parent nodes of any matching node remain visible so the hierarchy is clear.You can customize this behavior in two ways:Using match-sorter options
Pass a match-sorter options object to customize the default filtering and sorting behavior:Using a custom filter function
Pass a function for full control over both filtering and tree structure. The returned array determines the exact tree shown in the dropdown:TreeSelectMenu (Async Loading)
UseTreeSelectMenu when tree data needs to be fetched from an API or when branches load their children on demand.Basic Async Loading
Lazy Branch Loading
Branches withchildren: null are treated as unloaded. When expanded, loadOptions is called with the parent node to fetch its children:loadOptions should use children: null for branches whose children haven’t been loaded yet:The trigger Render Prop
The trigger render prop receives a set of props that must be spread onto the element that opens the menu. The trigger is responsible for rendering its own visible label.ref— Ref to the trigger element, used for popover positioning and focus restoration when the menu closes.onClick— Toggles the menu open and closed.onKeyDown— Handles keyboard interactions (e.g., opening the menu with Enter or arrow keys).aria-haspopup,aria-controls,aria-expanded— ARIA attributes describing the relationship between the trigger and the tree dropdown.data-state— Either"open"or"close", useful for styling the trigger based on menu state.
Selection Modes
TheselectionMode prop controls how nodes relate to each other during selection:"linked"(default) — Parent-child cascading. Selecting a parent checks all children; selecting all children checks the parent. ThevalueConsistsOfprop controls which nodes appear in the value array."independent"— Each node is selected independently with no cascading."single"— Only one node can be selected at a time. The menu closes after selection.
Value Strategies
In linked selection mode, thevalueConsistsOf prop controls which checked nodes appear in the value array:| Strategy | Selectable Nodes | Value Contains |
|---|---|---|
"ALL" | Any node | All checked nodes |
"BRANCH_PRIORITY" | Any node | Branches replace their leaves when fully checked |
"BRANCH_ONLY" | Branches only | Only branches (leaves are visible but inert) |
"LEAF_PRIORITY" (default) | Leaves + expand branches | Leaves and childless branches |
"LEAF_ONLY" | Leaves only | Strictly leaf nodes |
valueConsistsOf restricts which node types can be selected: "LEAF_ONLY" allows only leaves, "BRANCH_ONLY" allows only branches, and the other strategies allow any node.Display Modes
Control how the options menu is displayed using thedisplayMenuAs prop:Popover Width
UsepopoverWidth to control the popover’s width:Caching
TreeSelectMenu caches loadOptions results by default using two separate LRU caches: one for search results and one for lazy-loaded children. Configure caching behavior:Clearing the Cache
Use a ref to imperatively clear the cache:Invalidating Options
Callinvalidate() to clear the cache and reload options from the data source:TreeSelectMenuSync handles this automatically when its options prop reference changes.Initial Load Behavior
Control when options are first loaded with theinitialLoad prop:Controlled Expansion
By default, expansion state is managed internally. UsedefaultExpandLevel to set the initial depth:expandedIds and onExpandedIdsChange:expandAll() and collapseAll():Disabled Nodes
Individual nodes can be disabled by settingdisabled: true:Virtualization
Passvirtualize to enable windowed rendering for large trees. Only visible rows are mounted to the DOM.Disabling Search
PassdisableSearch to hide the search input:Close Callbacks
Distinguish between an explicit close (Escape, clicking the trigger again) and an implicit close (clicking outside the menu) withonExplicitClose and onImplicitClose:onMenuKeyDown to observe keyboard events that occur while the menu is open.React Accessibility
- The trigger element exposes
aria-haspopup="tree",aria-controls, andaria-expandedto describe its relationship to the dropdown. - The dropdown uses
role="tree"with the appropriaterole="treeitem"rows andaria-expanded/aria-selectedattributes. - The required
labelprop is used as the accessible name for the menu and as the dialog title in dialog mode. - Focus is restored to the trigger element when the menu closes via Escape or by selecting an option in single-select mode.