Small interactive content anchored to a trigger: a quick form, a picker, a list. Non-modal, labelled by its title, and the base for Combobox and Date Picker.
Installation
The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";
Usage
import { Popover, PopoverTrigger, PopoverContent, PopoverHeader, PopoverFooter } from "@vamos-ui/react";
<Popover>
<PopoverTrigger asChild><Button>Add tag</Button></PopoverTrigger>
<PopoverContent size="sm">
<PopoverHeader title="Tag contact" />
…
</PopoverContent>
</Popover>Escape closes the popover and returns focus to the trigger.
If the content has nothing interactive, use Tooltip (short label) or Hover Card (rich preview).
Content portals into the nearest ThemeScope, so it keeps a preview's or a dark section's theme.
Examples
Trigger width list
size="trigger" matches the trigger; padded={false} for edge-to-edge lists.
Schedule a post
Controlled open state, a small form and an arrow — a CMS publish box pattern.
Loading on open
Fetch in onOpenChange and show Skeleton until the data arrives.
Nested layers
A popover inside another layer is depth 2: in glass mode it turns opaque instead of adding a second blur.
API
Popover
| Prop | Type | Default |
|---|---|---|
open / defaultOpenControlled / uncontrolled open state. | boolean | — |
onOpenChangeCalled when it opens or closes. | (open: boolean) => void | — |
modalTrap focus and block outside interaction. | boolean | false |
PopoverContent
| Prop | Type | Default |
|---|---|---|
sizeWidth: auto, 256, 320, 416 px, or the trigger width. | "auto" | "sm" | "md" | "lg" | "trigger" | "md" |
paddedInner padding from the --gap token. false for lists. | boolean | true |
arrowPointer arrow towards the trigger. | boolean | false |
sidePreferred side; flips on collision (and in RTL for start/end align). | "top" | "right" | "bottom" | "left" | "bottom" |
alignAlignment against the trigger. | "start" | "center" | "end" | "center" |
sideOffsetGap to the trigger in px. | number | 6 |
collisionPaddingDistance kept from the viewport edge. | number | 12 |
onOpenAutoFocus / onCloseAutoFocuspreventDefault to control focus yourself. | (event) => void | — |
PopoverHeader
| Prop | Type | Default |
|---|---|---|
titleHeading; becomes the popover's accessible name (aria-labelledby). | ReactNode | — |
descriptionOne line under the title. | ReactNode | — |
actionTrailing element, e.g. a close IconButton. | ReactNode | — |
Other parts
| Prop | Type | Default |
|---|---|---|
PopoverTriggerGets aria-expanded and aria-controls. Use asChild with a Button. | Radix Trigger props | — |
PopoverAnchorPosition against another element than the trigger. | Radix Anchor props | — |
PopoverCloseCloses the popover. | Radix Close props | — |
PopoverTitle / PopoverDescriptionUse instead of PopoverHeader for custom layouts. | HTML heading / paragraph props | — |
PopoverFooterAction row with a hairline, bleeding to the panel edge. | HTML div props | — |