Skip to content

Popover

Non-modal overlay with a trigger, positioned surface, title/description, close, and arrow.

Primitive · behaviour

Terminal window
npx shadcn@latest add https://ndigo.dev/r/popover.json

To use the shorter @ndigo/popover form, configure the namespace in components.json.

Source Target Type
registry/ui/popover/nd-popover.ts @ui/nd-popover/nd-popover.ts registry:ui
registry/ui/popover/nd-popover.css @ui/nd-popover/nd-popover.css registry:file

See this component rendered live on the live examples page.

Registry: Ndigo element foundation. Packages: @zag-js/popover@~1.47.0 (installed automatically).

<nd-popover> wraps a trigger and a positioned surface with focus handling, outside-click dismissal, and Escape. It is not modal; the rest of the page stays interactive.

<nd-popover>
<button data-part="trigger">Open settings</button>
<div data-part="positioner">
<div data-part="content">
<h2 data-part="title">Settings</h2>
<p data-part="description">Adjust the workspace.</p>
<button data-part="close-trigger">Close</button>
</div>
</div>
</nd-popover>

A missing trigger is created from trigger-label (or Open popover); missing content and positioner wrappers are created on connect.

Attribute Type Description
open boolean Controlled open state; reflected by the element
trigger-label string Label for the generated trigger
  • nd-open-change — detail: { open: boolean }.
  • show() / hide() — open or close programmatically.

Escape closes and restores focus; clicking outside dismisses. The trigger carries aria-haspopup="dialog", aria-expanded, and aria-controls; the content is a labelled role="dialog". Keep a title or an aria-label.

Import nd-popover.css after the tokens. The surface uses the raised surface, border, radius, and shadow tokens; the arrow is optional.