Skip to content
Alpha

Hololink UI is under active development. Components, APIs and these docs may change without notice.

Holo Popover

The <holo-popover> component is an interactive floating panel (menus, forms) that uses the Popover API (popover="auto") for native light-dismiss on Esc/outside-click. The trigger is provided via a named trigger slot; clicking it toggles the popover open/closed, and the panel content goes in the default slot.

Positioning note: CSS anchor positioning is not yet broadly supported across engines, so positioning falls back to getBoundingClientRect()-based fixed positioning.

Use it for:

  • Small floating panels anchored to a trigger: a filter form, extra detail, a short explanation with controls.
  • Content the user opens on purpose and dismisses by clicking away or pressing Esc.

Don’t use it for:

  • Lists of commands. Use Menu.
  • Hover or focus hints. Use Tooltip.
  • Content that must block the page. Use Dialog.
Popover panel content
<holo-popover placement="bottom">
<button slot="trigger">Open menu</button>
<div>Popover panel content</div>
</holo-popover>

The panel is a <div popover="auto"> shown with the Popover API. The trigger goes in the trigger slot and toggles the popover on click. The panel has no role of its own.

The component sets aria-expanded on the trigger ("false" when closed, "true" when open). When the popover opens, focus moves to the first focusable element in the panel (a link, enabled form control or button, or an element with a non-negative tabindex), or to the panel itself if there is none.

Key Action
Enter, Space On a button trigger, opens or closes the popover (native click). Opening moves focus inside
Tab Moves on in page order. The panel follows the trigger in the tab order
Esc Closes the popover (native light dismiss) and returns focus to the trigger
  • The popover is not modal: focus is not trapped, and the page behind stays interactive.
  • Clicking outside closes the popover. Focus only returns to the trigger if it was inside the popover, so clicking another control keeps focus there.
  • The trigger does not get aria-controls: the panel is in the component’s shadow root, and ID references cannot point into a shadow root. It does not get aria-haspopup either, because the panel is not a menu, listbox or dialog.
  • The open and close transition only runs when prefers-reduced-motion: no-preference.

You provide:

  • A focusable trigger with an accessible name, normally a native <button>. Button does not forward aria-expanded to its inner button, so its state would not be announced.
  • A heading or label inside the panel, and accessible names for the controls in it.

Importing

import '@philbob-sideprojects/hololink-ui/holo-popover';

Properties

PropertyAttributeTypeDefaultDescription
openopenbooleanfalseWhether the popover panel is shown. Setting this to true calls the native showPopover(); setting it to false calls hidePopover().
placementplacement"bottom" | "end" | "start" | "top"'bottom'Which side of the trigger the popover is positioned on.

Events

EventDetailDescription
holoClosevoidEmitted after the popover panel has closed (via Esc, outside click, or open being set to false). If focus was inside the panel, it returns to the element that had focus before opening (normally the trigger).
holoOpenvoidEmitted after the popover panel has opened.

Slots

SlotDescription
(default)The popover panel content.
triggerThe element that toggles the popover when clicked.

CSS custom properties

PropertyDescription
--holo-popover-bgBackground color of the popover panel.
--holo-popover-border-colorBorder color of the popover panel.
--holo-popover-paddingInner padding of the popover panel.
--holo-popover-radiusCorner radius of the popover panel.
--holo-popover-shadowBox shadow of the popover panel.
--holo-popover-text-colorText color of the popover panel.