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).