Skip to content

Popover

In review
Live · web

Click a trigger to float its panel: anchored, with a beak, clamped to the stage

Open with a click or Enter / Space; focus moves into the panel. Tab cycles inside, Esc closes (focus returns to the trigger), click outside dismisses. Non-modal, so the page stays live.

Profile card
Invite

Last action: none yet · 2 filters on · placement auto · pointer + keyboard both work; the island is live.

// Web: React, consuming @dizyx/nockerl-tokens. (Web is the laggard platform;
// this is the canonical API the published @dizyx/nockerl-react package exposes.)
// A popover is a NON-MODAL anchored panel of free-form content: not a menu,
// not a tooltip, not a dialog.
import { NockerlPopover } from '@dizyx/nockerl-react';
export function SessionHeader() {
return (
<NockerlPopover
placement="bottom"
arrow
trigger={<button aria-label="Profile">PM</button>}
>
{({ close }) => (
<>
<h3 className="title">the design lead</h3>
<p className="muted">Owner · dizyx</p>
<button onClick={close}>View full profile</button>
</>
)}
</NockerlPopover>
);
}
PropTypeDefaultDescription
trigger *ReactNodeThe anchor element. Gets aria-haspopup="dialog" + aria-expanded; opens on click / Enter / Space.
children *ReactNode | (ctx: { close }) => ReactNodeThe free-form panel content (title, body, fields, actions). The render-prop form receives close().
placement'top' | 'bottom' | 'left' | 'right''bottom'Preferred side of the trigger. Flips to the opposite side and clamps on-screen if it would overflow.
arrowbooleantrueShow the directional beak. The beak wears the panel surface + hairline and stays centered on the trigger edge.
openbooleanControlled open state. Omit for the uncontrolled (internal) state.
onOpenChange(open: boolean) => voidFires on open / close (trigger, Esc, outside click). Pair with open for controlled use.
offsetnumber12Gap in px between the trigger and the panel (leaves room for the beak).
Popover vs. menu vs. tooltip vs. dialog

Four anchored/floating siblings. Pick by content and modality:

  • Popover (this page) is a non-modal anchored panel of free-form content: a profile card, a small form, a filter panel. Opens on click/focus, points a beak at its trigger, never dims the ground.
  • Menu is the same anchor + beak machinery but holds a list of action items (icons, shortcuts, checks), not arbitrary content.
  • Tooltip is a tiny, non-interactive hover hint (one line, no controls, no focus). When you need a field or a button inside, it’s a popover.
  • Dialog is modal and centered: it dims the ground and traps focus until resolved, and is not anchored to a trigger.
Cross-platform drift (tracked for reconciliation)
  • Android has no shipped popover. NockerlSurface.kt reserves tier-3 elevation for “popovers”, but no NockerlPopover exists yet; the Kotlin sample is the intended API on Material Popup (RichTooltip / TooltipBox are the nearest stock substrate). Drift until built.
  • Beak: web + macOS draw a beak; the intended Android Popup would need a custom one (Material Popup has none).
  • Width: macOS InfoTip fixes width: 250; web sizes per content. Tokenize a shared popover width when Android lands.