hideOthers
elements man ui/behaviors/hide-othersHides everything but an open modal part from assistive technology. It walks
up from each kept element to <body> and sets aria-hidden="true" on every
sibling along the way that holds no kept element, so a screen reader's
virtual cursor stays in the modal menu or popover. Script, style, template,
link and meta elements are left alone, and so are live regions, so
announcements are still spoken.
Signaturefunction hideOthers(keep: Element | Element[]): () => void;
| Argument | Type | Default | What it does |
|---|---|---|---|
keep |
Element | Element[] |
required | The element or elements to leave readable: the content and its trigger. Elements not in the document are skipped. |
One counter per element is shared by every caller: two overlays that hide
the same sibling each count it, and it is shown again (its own earlier
aria-hidden put back) only when the last of them releases. Releases may
come in any order, and the release function does nothing the second time.
In a template of your own
app/shared/templates/action-menu/index.ehtmlimport { hideOthers, pushLayer, type Layer } from "@elements/ui/behaviors"; interface ActionMenuState { trigger?: HTMLElement; layer?: Layer; unhide?: () => void; } function onOpen(ui: ActionMenuState, content: HTMLElement, close: () => void) { ui.layer = pushLayer(content, { onDismiss: close, inside: () => [ui.trigger], blockOutside: true }); ui.unhide = hideOthers([content, ui.trigger!]); } function onClose(ui: ActionMenuState) { ui.layer?.release(); ui.unhide?.(); } <ActionMenu (open: boolean = false, private ui: ActionMenuState = {})> <button type="button" aria-haspopup="menu" aria-expanded={open ? "true" : "false"} oninsert={(e) => ui.trigger = e.target as HTMLElement} onclick={() => open = !open}><slot name="trigger"/></button> <div e:if={open} role="menu" class="action-menu" oninsert={(e) => onOpen(ui, e.target as HTMLElement, () => open = false)} onremove={() => onClose(ui)}> <slot/> </div> </ActionMenu>
A modal menu: the layer blocks pointer interaction with the page, and
hideOthers hides the page from a screen reader, so both kinds of user stay
in the menu until it closes.
Writes
aria-hidden="true" on every sibling up to <body> that holds no kept
element, counted and put back on the last release.
Used by
DropdownMenu (opens in a new tab), ContextMenu (opens in a new tab), Menubar (opens in a new tab).