Popover
since v8.3.0Popover root — pairs with PopoverTrigger and PopoverContent.
Wraps @radix-ui/react-popover (per ADR-0001) — Radix owns positioning,
collision handling, focus management, dismiss (ESC / outside-click), and
portal semantics; we own class output and the public API. First consumer is
DatePicker's desktop calendar surface.
Install
Add the package and import the component.
pnpm add @hey-mike/tungstenpnpm add @hey-mike/tungstenimport { Popover } from '@hey-mike/tungsten';import { Popover } from '@hey-mike/tungsten';Preview
Same fixtures used by the visual-regression suite.
Usage
apps/docs/app/snapshots/popover/page.tsx
import { Popover, PopoverTrigger, PopoverContent, Button } from '@hey-mike/tungsten';
import { VariantGrid } from '../_components/VariantGrid';
import { HeroSpecimen } from '../_components/HeroSpecimen';
export default function PopoverSnapshot() {
return (
<VariantGrid
title="Popover"
// Gallery thumbnail: a static, non-portaled mock of the open popover (the
// real PopoverContent portals to document.body and would leak onto the
// detail page from the hidden hero wrapper). The variant below stays closed
// — the interactive preview opens the real popover on click.
hero={
<HeroSpecimen className="max-w-[200px]">
<div className="flex flex-col items-center gap-2">
<span className="bg-button-primary-bg text-button-primary-text rounded-md px-3 py-1.5 text-sm font-medium">
Open popover
</span>
<div className="border-stroke bg-surface shadow-overlay w-full rounded-lg border p-2.5 text-left">
<p className="text-ink-1 text-sm font-semibold">Floating panel</p>
<p className="text-ink-2 text-xs">Surface, stroke, overlay shadow.</p>
</div>
</div>
</HeroSpecimen>
}
variants={[
{
label: 'trigger',
node: (
<Popover>
<PopoverTrigger asChild>
<Button>Open popover</Button>
</PopoverTrigger>
<PopoverContent>
<div className="flex flex-col gap-2 p-1 text-sm">
<p className="text-ink-1 font-semibold">Floating panel</p>
<p className="text-ink-2">Tokens: surface, stroke, overlay shadow.</p>
</div>
</PopoverContent>
</Popover>
),
},
]}
/>
);
}
import { Popover, PopoverTrigger, PopoverContent, Button } from '@hey-mike/tungsten';
import { VariantGrid } from '../_components/VariantGrid';
import { HeroSpecimen } from '../_components/HeroSpecimen';
export default function PopoverSnapshot() {
return (
<VariantGrid
title="Popover"
// Gallery thumbnail: a static, non-portaled mock of the open popover (the
// real PopoverContent portals to document.body and would leak onto the
// detail page from the hidden hero wrapper). The variant below stays closed
// — the interactive preview opens the real popover on click.
hero={
<HeroSpecimen className="max-w-[200px]">
<div className="flex flex-col items-center gap-2">
<span className="bg-button-primary-bg text-button-primary-text rounded-md px-3 py-1.5 text-sm font-medium">
Open popover
</span>
<div className="border-stroke bg-surface shadow-overlay w-full rounded-lg border p-2.5 text-left">
<p className="text-ink-1 text-sm font-semibold">Floating panel</p>
<p className="text-ink-2 text-xs">Surface, stroke, overlay shadow.</p>
</div>
</div>
</HeroSpecimen>
}
variants={[
{
label: 'trigger',
node: (
<Popover>
<PopoverTrigger asChild>
<Button>Open popover</Button>
</PopoverTrigger>
<PopoverContent>
<div className="flex flex-col gap-2 p-1 text-sm">
<p className="text-ink-1 font-semibold">Floating panel</p>
<p className="text-ink-2">Tokens: surface, stroke, overlay shadow.</p>
</div>
</PopoverContent>
</Popover>
),
},
]}
/>
);
}
Props
Surface specific to <Popover />.
| Prop | Type | Default | Description |
|---|---|---|---|
| defaultOpen | boolean | — | Render the content open on mount. Useful for visual snapshots. Uncontrolled mode. |
| open | boolean | — | Controlled open state. Pair with onOpenChange. |
| onOpenChange | ((open: boolean) => void) | — | Fires whenever Radix wants to open or close the popover. |
| modal | boolean | — | Position the content relative to a PopoverAnchor instead of the trigger. |
Sub-components
Composition slots re-exported from the same module.
PopoverTrigger
No library-specific props. Pass through standard HTML attributes for the underlying element.
PopoverAnchor
No library-specific props. Pass through standard HTML attributes for the underlying element.
PopoverContent
No library-specific props. Pass through standard HTML attributes for the underlying element.
PopoverClose
No library-specific props. Pass through standard HTML attributes for the underlying element.