Non-modal panel anchored to a trigger, for extra controls or details. Open it with DialogTrigger.
import { Button, Checkbox, Popover, PopoverTrigger } from "@rdloom/react";
export default function PopoverBasicExample() {
return (
<PopoverTrigger>
<Button variant="secondary">Filters</Button>
<Popover label="Filters">
<div className="flex w-56 flex-col gap-3">
<Checkbox defaultSelected>Active</Checkbox>
<Checkbox>Archived</Checkbox>
</div>
</Popover>
</PopoverTrigger>
);
}Installation
npx rdloom add popoverCopies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes. It needs react-aria-components; add --install to install them.
Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/popover.jsonWorks, but without upgrade tracking.
Usage
import { Button, Checkbox, Popover, PopoverTrigger } from "@rdloom/react";
<PopoverTrigger>
<Button variant="secondary">Filters</Button>
<Popover label="Filters">
<div className="flex w-56 flex-col gap-3">
<Checkbox defaultSelected>Active</Checkbox>
<Checkbox>Archived</Checkbox>
</div>
</Popover>
</PopoverTrigger>With arrow
import { Button, Popover, PopoverTrigger } from "@rdloom/react";
export default function PopoverWithArrowExample() {
return (
<PopoverTrigger>
<Button variant="secondary">What's new</Button>
<Popover label="What's new" showArrow>
<p className="w-60 text-sm">Data grids now support inline editing and pagination.</p>
</Popover>
</PopoverTrigger>
);
}Placements
import { Button, Popover, PopoverTrigger } from "@rdloom/react";
export default function PopoverPlacementsExample() {
return (
<div className="flex flex-wrap gap-3">
{(["top", "bottom", "start", "end"] as const).map((placement) => (
<PopoverTrigger key={placement}>
<Button variant="secondary">{placement}</Button>
<Popover label={`Placed ${placement}`} placement={placement} showArrow>
<p className="text-sm">Placed {placement}</p>
</Popover>
</PopoverTrigger>
))}
</div>
);
}API Reference
Defined by the spec. Components also accept the props of the React Aria component they wrap.
| Prop | Type | Default |
|---|---|---|
labelrequiredAccessible name for the popover content. | string | none |
placementPreferred side of the trigger. Flips when there isn't room. | "top" | "bottom" | "start" | "end" | "bottom" |
showArrowShows an arrow pointing at the trigger. | boolean | false |
childrenPopover content. A function receives close(). | ReactNode | ((opts: { close: () => void }) => ReactNode) | none |
Accessibility
Role dialog, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.
Keyboard
- Esc closes and returns focus to the trigger
Screen readers announce
- Opening announces a dialog named by its label (Filters)
- Its controls are reachable with Tab; Esc announces the trigger again
What your code must do
- Has an accessible name
- Focus moves into the popover on open
Guidelines
Use it when
- Filters, quick settings or details related to a control
Avoid it when
- Plain hints: use Tooltip
- Blocking tasks: use Dialog
Don't
- Opening on hover
- Very long scrolling content
Design tokens
The semantic tokens this component uses. Change them once and every component follows; see Design tokens.
--rd-color-surface-raised--rd-color-border-default--rd-color-text-default--rd-radius-overlay