Components · Overlays
Popover
BetaRich content anchored to a control.
- Source
components/ui/popover.tsx - shadcn/ui Popover
- Figma: not linked yet (Q13)
When to use
- To show more detail about a value, anchored to it: the macro breakdown behind a day's calories, the sets behind a weekly volume.
- For a small interactive panel tied to one control: share a program link, pick a color for a calendar tag, set a quick reminder.
- When the content has buttons, links or fields, which a Tooltip can't hold.
When not to use
- For a plain text hint on an icon: use a Tooltip.
- For a list of actions: use a dropdown menu, which has menu keyboard behavior.
- For a task with several fields that must be saved: use a Dialog or a Sheet.
- To preview a linked item on hover: use a Hover card.
Anatomy
Open the popover above to see its parts: the trigger (a button that stays visible), and the content panel next to it, with an optional header (title and description) and the body. There is no arrow and no close button; the coach closes it with Escape, by clicking outside, or with the trigger.
Variants
| Variant | Use for |
|---|---|
| Information (macro breakdown) | Read-only detail about the trigger's value |
| Interactive (share link) | One small task: copy, pick, toggle. Results apply right away |
Width is w-72 by default. Pass a wider step, such as w-80, for content with an input and a button.
States
| State | What changes | Token |
|---|---|---|
| Closed | Only the trigger shows, with aria-expanded="false" | none |
| Open | Panel fades and zooms in next to the trigger, on the popover layer | bg-popover, text-popover-foreground, shadow-md, z-(--z-popover) |
| Focus | Moves into the panel on open; returns to the trigger on close | none: the panel itself has no ring (outline-hidden) |
Usage guidelines
- Open on click, never on hover. Hover is a Hover card.
- Keep it small: a title, a few lines or one control, and no scrolling.
- Changes inside a popover apply immediately. If they need a Save button, use a dialog.
- Name the content with
aria-labelledbypointing atPopoverTitle, as in the examples.
Macro breakdown
Edit nutrition plan
Content guidelines
- Title: a noun phrase for what's inside: "Macro breakdown", "Share program". Sentence case.
- The trigger's label says what opens or shows the value it explains: "Tuesday: 1,860 kcal".
- Arabic: units after the number with a space ("140 غ"), Western digits (QUESTIONS Q22).
Accessibility
| Key | Does |
|---|---|
| Enter or Space on the trigger | Opens or closes the popover; focus moves into it |
| Tab / Shift+Tab | Moves through the popover's controls. Focus isn't trapped; tabbing past the end closes it |
| Escape | Closes it and returns focus to the trigger |
- The trigger gets
aria-haspopup="dialog",aria-expandedandaria-controls. The content hasrole="dialog". PopoverTitleis adiv, so it doesn't name the panel on its own. Give it anidand passaria-labelledbytoPopoverContent. A screen reader then announces "Macro breakdown, dialog".- Status messages inside, such as "Link copied", use
role="status".
RTL
The panel is centered under the trigger by default, so it looks the same in both directions. side and align are physical in Radix: align="start" lines up with the left edge in both directions, and side="right" stays right. Pass them from the direction when it matters, as in Sheet. URLs and codes inside keep dir="ltr".
Tokens used
Read from components/ui/popover.tsx at build time, so this list changes when the component does. Opacity modifiers such as /90 are shadcn hover and focus tints on top of the token.
| Token | Utilities | SuperCoach | Coach |
|---|---|---|---|
| --muted-foreground | text-muted-foreground | neutral-600 | neutral-600 |
| --popover | bg-popover | white | white |
| --popover-foreground | text-popover-foreground | neutral-950 | neutral-950 |
- Layer
z-(--z-popover) - Radius
rounded-md - Shadow
shadow-md - Type
font-medium - Type
text-sm
Props
<Popover>
Also takes every prop of Radix Popover.Root
No props of its own.
<PopoverTrigger>
Also takes every prop of Radix Popover.Trigger
No props of its own.
<PopoverContent>
Also takes every prop of Radix Popover.Content
No props of its own.
<PopoverAnchor>
Also takes every prop of Radix Popover.Anchor
No props of its own.
<PopoverHeader>
Also takes every prop of <div>
No props of its own.
<PopoverTitle>
Also takes every prop of <h2>
No props of its own.
<PopoverDescription>
Also takes every prop of <p>
No props of its own.
PopoverContent defaults to align="center" and sideOffset={4}.
Replaces in coach-admin
From the read-only audit of coach-admin: 10 style values, 10 uses.
coach-admin's shared Popover (.popover-anchor) and the billing details popover become this component.
Classes and selectors
.popover-anchor__panel5.billing-details-popover__panel-header1.popover-anchor__panel-title1.billing-details-popover__trigger1.billing-details-popover__download-btn1
Files
src/reusableComponents/Popover/Popover.scss7
The inventory lists the first 12 locations of each value, so file counts are a lower bound.
SCSS variables in these styles
$spacing-smnot a color: spacing, size or layout$overlay-surface-bgnot a color: spacing, size or layout$spacing-mdnot a color: spacing, size or layout$overlay-surface-shadow-softnot a color: spacing, size or layout$z-index-popovernot a color: spacing, size or layout