Outside Inerting
Headless Outside Inerting; covers Radix overlay inerting, Adobe Spectrum overlay provider.
| Package | @vizejs/ui/inert-outside |
| Maturity | stable |
| Own the source | vize lib pull inert-outside |
| Requires | — |
| Aliases | aria hidden outside, outside inerting, overlay inerting |
| Covers | Radix overlay inerting, Adobe Spectrum overlay provider |
API
createInertOutside
Isolate rendered content outside reactive allowed roots without owning visual styling.
function createInertOutside(options: InertOutsideOptions): InertOutsideController
useInertOutside
Create, mount-activate, and scope-dispose an outside-inerting controller.
function useInertOutside(options: InertOutsideOptions): InertOutsideController
containsComposed
function containsComposed(root: Element, element: Element): boolean
collectOpenShadowRoots
Collect every currently reachable open shadow root for document-level observation.
function collectOpenShadowRoots(root: Document | ShadowRoot): ShadowRoot[]
collectOutside
Find the smallest rendered sibling subtrees outside every allowed root.
function collectOutside(document: Document, allowed: readonly Element[]): Element[]
maskFor
function maskFor(mode: InertOutsideMode): IsolationMask
readRoot
function readRoot(source: unknown): Element | null
readBranches
function readBranches(source: unknown, document: Document | null): readonly Element[]
readEnabled
function readEnabled(source: unknown): boolean
readMode
function readMode(source: unknown): InertOutsideMode
validateOptions
function validateOptions(options: InertOutsideOptions): void
recomputeDocument
function recomputeDocument(state: DocumentState): void
attachToken
function attachToken(token: InertOutsideToken, root: Element): void
detachToken
function detachToken(token: InertOutsideToken): void
refreshToken
function refreshToken(token: InertOutsideToken): void
Behavior
createInertOutside isolates the rendered sibling subtrees outside a modal root. It owns only
inert and aria-hidden; focus movement, roles, visual obscuring, dismissal, and scroll locking
remain separate primitives so applications can compose the correct modal behavior.
| Concern | Contract |
|---|---|
| Masking | The smallest rendered sibling subtrees outside all allowed roots receive inert, aria-hidden, or both. |
| Restoration | Pre-existing attribute values and boolean presence are restored exactly after disablement, deactivation, root migration, or disposal. |
| Nesting | Earlier layers allow later portalled roots; the latest layer may isolate its parent until it closes. |
| Branches | Reactive branches preserve exceptional or portalled content without exposing unrelated siblings. |
| Mutation | One document observer watches the document plus reachable open shadow roots, then batches rendered-tree and owned-attribute repair. |
| Shadow DOM | Open shadow roots and assigned slots follow composed, rendered-tree paths; unrendered light children are ignored. |
| Reactivity | Root, branch, mode, and enablement changes recompute synchronously without replacing the controller. |
| Documents | Root migration restores the old document before acquiring ownership in the new document. |
| Server rendering | Setup performs no global DOM access; a nullable root joins the stack only after hydration mount. |
| Vapor | A public composable fixture must compile without diagnostics in native DOM, SSR, and Vapor lanes. |
| Styling | The primitive emits no CSS; callers must visually obscure content made inert, as required by the HTML Standard. |
| Tree shaking | Root and subpath consumers emit identical JavaScript, retain no unrelated families, and emit zero CSS. |
both is the safe default: native inert blocks focus, selection, editing, and pointer targeting,
while aria-hidden keeps the isolated subtree out of accessibility APIs that do not yet model
inert. The aria-hidden mode is only appropriate when another primitive supplies equivalent
interaction blocking. Attribute ownership deliberately stays separate from backdrop styling.