Hover card
Preview a person or link on hover or focus without leaving the page.
pnpm dlx shadcn@latest add @uiarc/hover-cardBilling v2 is live for 20% of workspaces. Thanks to for the checkout redesign and for a clean migration. takes the rollout to everyone on Thursday, and is drafting the changelog.
- Previews of people behind mentions, avatars, or author names.
- Link or reference previews where the click must stay free for navigation.
- Dense lists where moving between triggers should open cards almost instantly.
- Use tooltip for a plain text label.
- Use popover when the content has buttons or inputs.
- Use user-menu for the account menu on your own avatar.
Installation
Add Hover card with the shadcn CLI, or copy the source by hand.
pnpm dlx shadcn@latest add @uiarc/hover-cardAdds the component and its local dependencies, and installs @radix-ui/react-popover, motion. First time? Add the @uiarc registry to components.json, or use the full URL:
import { HoverCard, HoverCardProfile } from "@/registry/components/hover-card/hover-card"; export function Mention() { return ( <HoverCard content={<HoverCardProfile name="Maya Chen" role="Product designer, Payments" stats={[{ label: "Projects", value: 12 }]} />} > <button type="button">@maya</button> </HoverCard> );}API reference
2 parts. The first is the root.
HoverCard
A read-only preview that opens after a short hover or keyboard focus and stays open while the pointer travels into it.
childrenRequiredReactElement–The trigger, such as a mention button or link. Must accept a ref and be focusable.contentRequiredReactNode–The preview. HoverCardProfile covers people.side"top" | "bottom" | "left" | "right""bottom"Preferred side of the trigger.align"start" | "center" | "end""start"Alignment against the trigger.openDelaynumber500Milliseconds of hover before the first card opens.closeDelaynumber140Grace in milliseconds after the pointer leaves.classNamestring–Class on the card surface.HoverCardProfile
A person preview: portrait, name, role, bio, stats, and a footer line.
nameRequiredstring–Full name. Initials are derived from it when there is no avatar.rolestring–Role and team.avatarstring | ReactNode–Portrait URL or your own image element such as next/image.biostring–Short bio paragraph.stats{ label: string; value: string | number }[][]Rendered as a definition list.metaReactNode–Footer line such as location and local time.- Tab
- Keyboard focus on the trigger opens the card immediately.
- Enter
- Opens the card without the hover delay.
- Escape
- Closes the card and keeps it closed while the pointer rests on the trigger.
- The card has role="tooltip" and the trigger gets aria-describedby while it is open.
- Focus never moves into the card, so keep its content read only.
- On touch, a tap toggles the card instead of relying on hover.
- Grows from the trigger edge: scale from 0.96 and a 4px offset on a smooth spring, with a separate fade. Mid-exit returns retarget instead of jumping.
- Within 300ms of another card, the next opens after 80ms with a fade only. Profile rows settle in with a small stagger.
- Reduced motion drops scale and travel and keeps a short fade.
- The card is 18.5rem wide, capped at the space Radix reports as available or the viewport minus 24px.
- On touch, a tap toggles the card instead of waiting for hover.
- Long names and roles ellipsize and stats wrap onto new lines.
- Only one hover card is open on the page, and it mounts in a portal only while open.
- Open and close use timers, not pointer tracking loops; the profile avatar decodes async.
Notes for AI
Give your coding assistant the Markdown reference instead of screenshots.
- Use for previews of people, links, or references where the click must stay free for navigation. Use tooltip for plain labels and popover for interactive content.
- Only one hover card is open at a time on the page. Anything actionable belongs behind the trigger itself.
The full library index for assistants is at /llms.txt.