Components / Overlays & disclosure
HoverCard
Preview a person or link on hover or focus without leaving the page.
Install
npx shadcn@latest add https://irisui.dev/r/hover-card.jsonimport { HoverCard } from "@/components/iris/hover-card/hover-card";Preview
HoverCard
A read-only preview of a person or link that opens after a short hover or keyboard focus, leaving the click free for navigation.
When to use
- @mentions, avatars, and author names where a quick profile helps without leaving the page.
- Link or record references that benefit from a peek (title, status, owner).
- Not for interactive content (buttons, forms): use
Popover. For a one-line label useTooltip.
Usage
import { HoverCard } from "@/components/iris/hover-card/hover-card";
h(
HoverCard,
{
content: h(HoverCardProfile, {
name: "Katerina Vlachou",
role: "Product lead, notdocs",
bio: "Owns the roadmap and the activation experiment.",
stats: [
{ label: "Tasks", value: 12 },
{ label: "Decisions", value: 6 },
],
meta: "Athens · 16:12 local time",
}),
},
h("button", { type: "button" }, "@Katerina Vlachou"),
);
Props
HoverCard
| Prop | Type | Default | Description |
|---|---|---|---|
children |
ReactElement |
— | Required. The trigger; must accept a ref and be focusable (a button or link). |
content |
ReactNode |
— | Required. The preview. Keep it read only. |
side |
"top" | "bottom" | "left" | "right" |
"bottom" |
Preferred side. |
align |
"start" | "center" | "end" |
"start" |
Alignment against the trigger. |
openDelay |
number |
500 |
Hover time in ms before the first card opens. |
closeDelay |
number |
140 |
Grace period in ms so the pointer can travel into the card. |
className |
string |
— | Extra class on the card surface. |
HoverCardProfile
| Prop | Type | Default | Description |
|---|---|---|---|
name |
string |
— | Required. Initials are derived from it when there is no avatar. |
role |
string |
— | Role and team. |
avatar |
string | ReactNode |
— | Portrait URL or your own image element. |
bio |
string |
— | Short description. |
stats |
{ label: string; value: string | number }[] |
[] |
A couple of numbers. |
meta |
ReactNode |
— | Quiet footer line, such as location and local time. |
Notes
- One hover card is open at a time per page. Moving to another trigger within 300 ms opens it almost at once.
- Keyboard focus (
:focus-visible) opens the card immediately; Escape dismisses it. The trigger getsaria-describedbypointing at the card (role="tooltip"). A click or Enter opens without the wait; on touch a tap toggles. - The card grows from the trigger edge on a spring; reduced motion uses a fade only.
- Reads
--surface,--line,--ink,--ink-2,--ink-3, shadow and radius tokens.