Skip to content

Navigation Runtime ​

The NavigationRuntime is the central stateful object that manages focus, selection, expansion state, and all registered contributions (tokens, keybindings, dialogs, predicate providers). It's built on Solid.js reactivity — all state is reactive and drives the renderer automatically.

ts
interface NavigationRuntime<P> {
  // Reactive state
  hypergraph: Accessor<Hypergraph<P>>;
  navTree: Accessor<NavTree>;
  focusedNavId: Accessor<NavNodeId>;
  selection: Accessor<Selection>;
  expanded: Accessor<ReadonlySet<NavNodeId>>;

  // Lookups
  getNavNode(navId: NavNodeId): NavNode | undefined;
  getHyperedge(id: HyperedgeId): Hyperedge<P> | undefined;
  fullPredicate(navId: NavNodeId): Selection;
  virtualOptionsFor(sourceNavId: NavNodeId): readonly NavNodeId[];
  commitTargetOfVirtual(virtualNavId: NavNodeId): NavNodeId | undefined;
  regroupedSourceOfVirtual(virtualNavId: NavNodeId): NavNodeId | undefined;

  // Actions
  focus(navId: NavNodeId): void;
  moveFocus(direction: MoveDirection): void;
  expand(navId: NavNodeId): void;
  collapse(navId: NavNodeId): void;
  setExpanded(set: ReadonlySet<NavNodeId>): void;
  setSelection(s: Selection): void;
  setHypergraph(g: Hypergraph<P>): void;

  // Registries
  registerKeybinding(binding: KeybindingContribution<P>): void;
  registerDialog(dialog: DialogContribution<P>): void;
  registerPredicateProvider(provider: PredicateProvider<P>): void;
  registerToken(token: DescriptionToken<P>): void;
  keybindings: KeybindingRegistry<P>;
  dialogs: DialogRegistry<P>;
  predicateProviders: PredicateProviderRegistry<P>;
  tokens: TokenRegistry<P>;
  customization: CustomizationStore;

  // Descriptions
  getDescriptionFor(navId: NavNodeId): Accessor<string>;
}

createNavigationRuntime ​

ts
function createNavigationRuntime<P>(initialGraph: Hypergraph<P>): NavigationRuntime<P>

Creates a new runtime with the given hypergraph. The initial focus is set to the first root node.

The runtime automatically:

  • Builds a NavTree from the hypergraph (re-derived reactively when the hypergraph changes).
  • Registers the six built-in description tokens: name, index, level, parent, children, parentContext.
  • Sets up a recipe filter that hides the parent token on roles where no multi-parent edges exist.

Reactive state ​

All state accessors are Solid.js Accessor<T> functions. Call them to read the current value; they track dependencies automatically when called inside reactive contexts (createMemo, createEffect, etc.).

AccessorTypeDescription
hypergraph()Hypergraph<P>The current hypergraph.
navTree()NavTreeThe nav tree derived from the hypergraph.
focusedNavId()NavNodeIdThe currently focused nav node.
selection()SelectionThe current data selection (filter).
expanded()ReadonlySet<NavNodeId>Which nav nodes are expanded in the ARIA tree.

Lookups ​

getNavNode ​

ts
getNavNode(navId: NavNodeId): NavNode | undefined

Returns the nav node for a given ID. Handles both real nodes (from the nav tree) and virtual parent-context nodes (synthesized on demand).

getHyperedge ​

ts
getHyperedge(id: HyperedgeId): Hyperedge<P> | undefined

Returns the hyperedge for a given ID from the current hypergraph.

fullPredicate ​

ts
fullPredicate(navId: NavNodeId): Selection

Composes the predicates from all ancestor edges along the path to produce the full selection for a nav node. This is what determines which data rows a node represents.

virtualOptionsFor / commitTargetOfVirtual / regroupedSourceOfVirtual ​

These methods handle multi-parent navigation:

  • virtualOptionsFor(sourceNavId) — Returns the virtual nav IDs for switching between groupings.
  • commitTargetOfVirtual(virtualNavId) — Given a virtual nav ID, returns the real parent nav ID it would navigate to.
  • regroupedSourceOfVirtual(virtualNavId) — Given a virtual nav ID, returns the nav ID of the source element as a child of the target parent.

Actions ​

focus / moveFocus ​

ts
focus(navId: NavNodeId): void
moveFocus(direction: MoveDirection): void

focus sets the focused node directly. moveFocus moves focus in a direction:

ts
type MoveDirection = 'up' | 'down' | 'left' | 'right' | 'first' | 'last';

Movement semantics:

  • down: First child (or last-visited child if returning).
  • up: Parent. If multi-parent, enters the virtual parent-context layer.
  • left/right: Previous/next sibling.
  • first/last: First/last sibling.

When on a virtual parent-context node, left/right switch between groupings; up commits to the selected parent; down returns to the source.

expand / collapse / setExpanded ​

ts
expand(navId: NavNodeId): void
collapse(navId: NavNodeId): void
setExpanded(set: ReadonlySet<NavNodeId>): void

Manage the ARIA tree expansion state. The renderer uses expanded to determine which subtrees are visible.

setSelection / setHypergraph ​

ts
setSelection(s: Selection): void
setHypergraph(g: Hypergraph<P>): void

setSelection updates the current selection/filter. setHypergraph replaces the entire hypergraph, which reactively rebuilds the nav tree.

Registries ​

The runtime holds four registries for domain contributions. See:

Plus a CustomizationStore for managing description recipes and presets. See Recipes & Customization.

getDescriptionFor ​

ts
getDescriptionFor(navId: NavNodeId): Accessor<string>

Returns a reactive accessor that produces the assembled description string for a nav node. The description is computed from the active recipe and registered tokens. See Tokens for details.

Next ​

Released under the BSD-3-Clause License.