How it works
The behaviour that makes components accessible (focus, positioning, dismissal) runs in a small JavaScript engine driven from C#, because Blazor can't do it synchronously. This page is authored in markdown and rendered with Markdig.
The constraint
Blazor cannot synchronously manipulate the DOM: WebAssembly has no DOM, and Server marshals interop asynchronously over SignalR. So a correct focus trap, scroll lock, anchored positioning, roving tabindex, content teleport, or pointer drag must be JavaScript, driven from C#.
The engine
Navius keeps that behaviour in one engine (navius-interop.js) with C# wrappers. It is dependency-free: the anchored positioner is hand-rolled rather than pulling in a positioning library. Each primitive stays declarative and drives the engine over interop.
- focus trap, scroll lock, anchored positioning (flip / clamp / arrow)
- dismissable layers, roving focus with a nested-submenu guard
- teleport-to-body (focus-preserving), size observation, drag tracking
- constraint-validation readout, toast swipe / pause / hotkey
From brain to helm
Primitives expose ARIA, keyboard, and a data-* state contract, and forward every unmatched attribute. The helm is Tailwind on that seam: it merges its classes with yours and reproduces the state contract in CSS (data-[open], data-[checked]). Behaviour is solved once; styling is yours.