Messaging

Popover

Popovers reveal richer, interactive content anchored to a trigger, and stay open until dismissed.

Components · Messaging

A popover is an anchored panel with a title, a divider, and body content — richer than a tooltip and interactive rather than transient. Namirial popovers are built from --nm-popover-* tokens defined in namirial-theme.css, share the same position and pointer system as tooltip, and default to the primary intent.

Filters
Narrow results by status, owner, or date.

Overview

A popover opens on click (not hover) and stays open until the user dismisses it — by clicking its trigger again, clicking outside, or pressing Escape. That persistence is what separates it from a tooltip: a popover can hold interactive content because the user has time to engage with it.

When to use

Use a popover when:

  • The content needs to stay visible while the user reads it or interacts with something inside it (a filter panel, a small form, a list of actions).
  • The trigger should toggle the panel open and closed on click, not just on hover.

Consider another component when:

  • The content is a short, single-idea hint that only needs to appear on hover/focus — use Tooltip.
  • The content is a full task or requires the rest of the page to be inert while it's open — use a Dialog.

Anatomy

A popover is a title, a divider, and a content region, plus the same directional pointer used by tooltip.

Tokens and values that drive each part

PartRoleSource
ContainerFill--nm-popover-bg
ContainerBorder--nm-popover-border
ContainerRadius / padding / gapborder-radius: 8px · padding: 8px · gap: 6px
ContainerSize boundsmin-width: 160px · max-width: 320px
TitleColor / weight--nm-popover-fg, font-weight: 700
DividerColor--nm-popover-fg at opacity: 0.6
ContentColor--nm-popover-fg, font-weight: 400
PointerFill--nm-popover-border (8px triangle, via ::before)

Positions

Popover shares tooltip's 12-position system — four sides, each with a centered default plus -start/-end alignment.

Top
Centered above the trigger.
Bottom
Centered below the trigger.
Left
To the left of the trigger.
Right
To the right of the trigger.

Intent variants

Popover ships seven intents, defaulting to primary.

Primary
Default appearance.
Info
Neutral, explanatory content.
Warning
Flags a caveat before an action.
Negative
Confirms a destructive choice.

Content types

Title + content

Filters
Narrow results by status, owner, or date.

Content only

Drop the title and divider when the popover doesn't need a heading — a short action list or a single line of text stands on its own.

Copied to clipboard.

Light & dark theme

Popover tokens read from the shared --palette-callout-* scale, so no per-component dark override is needed.

Light data-theme="light"
Filters
Narrow by status or owner.
Dark data-theme="dark"
Filters
Narrow by status or owner.

Both previews are locked — they don't follow the page theme switcher.

Do & don't

✓Do
Share
Anyone with the link can view.
Use a popover for a small, focused chunk of interactive content anchored to its trigger.
✕Don't
Settings
A full multi-step settings form doesn't fit a 320px-wide anchored panel — use a dialog or a dedicated page instead.
Don't cram a full workflow into a popover — move to a Dialog or a page.
✓Do
Copied to clipboard.
Let the user click outside or press Escape to close — never trap them inside a popover.
✕Don't
Confirm
Are you sure you want to delete this? This can't be undone.
Don't use a popover for a destructive confirmation that blocks the rest of the page — use a Confirmation Dialog.

Accessibility

Semantics

  • Give the trigger aria-haspopup="true" and aria-expanded, toggled with the panel's open state.
  • Connect trigger and panel with aria-controls pointing at the panel's id.

Keyboard

  • The trigger must open/close the popover on Enter/Space, not only on click.
  • Escape closes the popover and returns focus to the trigger.
  • Tab must be able to reach every interactive element inside the popover before it can reach anything behind it.

Focus

  • On open, move focus into the popover only if it contains interactive content the user is expected to use immediately; otherwise leave focus on the trigger.
  • On close, always return focus to the trigger.

Token reference

TokenRole
--nm-popover-bgContainer fill — recolored per intent
--nm-popover-borderContainer border and pointer fill — recolored per intent
--nm-popover-fgTitle, divider, and content color — recolored per intent

Implementation

Positioning and open/close state need JavaScript; the markup and visuals are pure CSS.

<link rel="stylesheet" href="namirial-theme.css">

<div class="nm-popover nm-popover--bottom" role="dialog" id="pop-1">
  <span class="nm-popover__title">Filters</span>
  <hr class="nm-popover__divider">
  <span class="nm-popover__content">Narrow results by status, owner, or date.</span>
</div>

CSS classes

ClassValuesDefault
nm-popover--{position}top · top-start · top-end · bottom · bottom-start · bottom-end · left · left-start · left-end · right · right-start · right-end—
nm-popover--{intent}primary · secondary · accent · info · positive · negative · warning — omit for primary— (primary)
nm-popover__titleBold heading row—
nm-popover__divider<hr>-style rule between title and content—
nm-popover__contentBody content—