OlliHandle
Each entry point (olliVis, olliDiagram, olli) returns an OlliHandle for controlling the tree after it's mounted.
import type { OlliHandle } from 'olli';Focus
focus(navId)
handle.focus(navId: NavNodeId): voidMove focus to a specific node in the tree. The tree scrolls and the screen reader announces the new node's description.
getFocusedNavId()
handle.getFocusedNavId(): NavNodeIdReturns the NavNodeId of the currently focused node.
Selection
setSelection(selection)
handle.setSelection(selection: Selection): voidSet the current selection. For olliVis, this triggers a reactive update: the spec is re-lowered with the new selection, and the tree rebuilds while preserving focus.
getSelection()
handle.getSelection(): SelectionReturns the current Selection.
fullPredicate(navId)
handle.fullPredicate(navId: NavNodeId): SelectionCompose the ancestor predicates along the path to navId into a single Selection describing the subset of the data at that node. This is independent of the selection signal (which is only changed by setSelection).
This is the hook for two-way highlighting: pair it with onFocusChange to feed the resulting Selection into your chart's selection mechanism.
handle.onFocusChange((navId) => {
const sel = handle.fullPredicate(navId);
// Feed `sel` into your chart to highlight matching marks
});Descriptions
getDescription(navId)
handle.getDescription(navId: NavNodeId): stringReturns the assembled description string for a node, reflecting the current customization and preset settings.
Customization
setCustomization(role, customization)
handle.setCustomization(role: string, customization: Customization): voidOverride the description recipe for a specific role. A Customization specifies:
role: which type of node this applies to (e.g.,'root','xAxis','datum')recipe: an ordered list of{ token: string, brevity: 'short' | 'long' }entries
Changes made via setCustomization are automatically persisted to localStorage.
applyPreset(name)
handle.applyPreset(name: string): voidSwitch all role recipes at once by applying a named preset. For olliVis, the built-in presets are 'detailed', 'standard', and 'minimal'.
Subscriptions
onFocusChange(callback)
handle.onFocusChange(cb: (navId: NavNodeId) => void): () => voidSubscribe to focus changes. The callback fires whenever the focused node changes. Returns an unsubscribe function.
onSelectionChange(callback)
handle.onSelectionChange(cb: (selection: Selection) => void): () => voidSubscribe to selection changes. Returns an unsubscribe function.
Lifecycle
destroy()
handle.destroy(): voidTear down the tree: unmount the renderer, clean up the global o hotkey listener, and dispose all reactive subscriptions.
Two-way highlighting recipe
A common pattern is to have Olli's focus drive highlighting in a rendered chart:
const handle = olliVis(spec, treeContainer);
handle.onFocusChange((navId) => {
const selection = handle.fullPredicate(navId);
// Use `selection` to drive your chart's highlight state.
// For Vega-Lite, see the gallery source for the
// withExternalStateParam pattern.
});Next
- Options & Callbacks — configure the tree at mount time.
- Adapters — converting from external visualization formats.