Malevich

Overlays/

Popover

Click-triggered floating panel. Reuses runtime/position helper.

Popover

Click-triggered floating panel anchored to a trigger element. Non-modal — clicks outside dismiss but background remains interactive. Per the answered design question: reuses runtime/position.ts rather than adding @floating-ui/dom as a dependency.

When to use

For modal "full focus" dialogs, use Dialog. For ephemeral hint text on hover, use Tooltip.

Anatomy

<button type="button" class="button -secondary"
        aria-haspopup="dialog"
        aria-expanded="false"
        aria-controls="pop-1">
  More
</button>

<div class="popover" id="pop-1" role="dialog" aria-labelledby="pop-1-title">
  <header class="popover__header">
    <h3 id="pop-1-title" class="popover__title">Quick actions</h3>
  </header>
  <div class="popover__body">
    <button class="button -ghost">Duplicate</button>
    <button class="button -ghost">Archive</button>
    <button class="button -ghost -danger">Delete</button>
  </div>
</div>

The runtime (initPopover, auto-registered for triggers with aria-haspopup="dialog" + aria-controls) handles:

The popover element starts hidden; the runtime toggles hidden, data-state="open", and inline top/left styles. Authors do NOT position the popover manually.

Placement

Default placement is bottom (below the trigger). Override per instance via data-popover-placement on the trigger:

<button aria-haspopup="dialog" aria-controls="p1" data-popover-placement="right">…</button>

Values: top, right, bottom, left. The positioner flips to the opposite edge if the preferred placement does not fit in the viewport.

Tokens used

Component-tier (defined inline)

Accessibility

Edge cases

Do

Don't