HoverCard
A preview card shown after a short delay when a link is hovered or focused: a profile, a repository, a page summary.
Reviewed by @ada two hours ago.
import { Avatar, HoverCard, Link, Text } from "@meridui/react";
export function Example() {
return (
<Text>
Reviewed by{" "}
<HoverCard.Root>
<HoverCard.Trigger asChild>
<Link href="/people/ada">@ada</Link>
</HoverCard.Trigger>
<HoverCard.Content>
<Avatar name="Ada Lovelace" />
<strong>Ada Lovelace</strong>
<span>Analytical Engine team · joined March 2021</span>
</HoverCard.Content>
</HoverCard.Root>{" "}
two hours ago.
</Text>
);
}Import
import { HoverCard } from "@meridui/react";Anatomy
<HoverCard.Root>
<HoverCard.Trigger />
<HoverCard.Content />
</HoverCard.Root>- Root holds the open state and the delays. It renders no element.
- Trigger is an
<a>; withasChildit merges onto your own Link or router link. - Content is the portalled card, positioned against the trigger. It only mounts while open.
Examples
Delays and placement
openDelay (default 500ms) avoids flashing cards while the pointer passes by; closeDelay (default 300ms) lets the pointer travel from the link onto the card, which stays open while hovered.
<HoverCard.Root openDelay={150} closeDelay={100}>
<HoverCard.Trigger asChild>
<Link href="/projects/northwind-web">northwind-web</Link>
</HoverCard.Trigger>
<HoverCard.Content placement="top">
Next.js storefront · 42 open pull requests · deployed 5 minutes ago
</HoverCard.Content>
</HoverCard.Root>API reference
Root
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | – | Controlled open state. |
defaultOpen | boolean | false | Initial open state when uncontrolled. |
onOpenChange | (open: boolean) => void | – | Called when the open state should change. |
openDelay | number | 500 | Delay before opening on hover or focus, in ms. |
closeDelay | number | 300 | Delay before closing after the pointer leaves, in ms. |
Trigger
Accepts every <a> attribute.
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | Render the single child element (e.g. your own Link) instead of an <a>, merging props, ref and handlers. |
ref | Ref<HTMLAnchorElement> | – | Forwarded ref. |
Content
Accepts every <div> attribute.
| Prop | Type | Default | Description |
|---|---|---|---|
placement | Placement | "bottom" | Preferred placement relative to the trigger. |
sideOffset | number | 8 | Distance from the trigger in px. |
container | Element | null | document.body | Portal target. |
ref | Ref<HTMLDivElement> | – | Forwarded ref to the card. |
Styling
| Class | Element |
|---|---|
.mrd-hover-card | Content |
| Attribute | On | Values |
|---|---|---|
data-state | Trigger | open, closed |
data-state | Content | open |
Accessibility
A hover card is supplementary: it opens on hover and on keyboard focus, but screen readers are not told about it and its content is not in the Tab order. The trigger must make sense on its own (the link goes to the full profile), and nothing essential or interactive should live only in the card. Touch hover is ignored. For interactive content, use a Popover.
| Key | Action |
|---|---|
| Tab | Focusing the trigger opens the card after openDelay; leaving closes it. |
| Escape | Close the card. |
Guidelines
Do
Preview something the link points to: who a person is, what a repository contains.
Avoid
Put buttons, forms or the only copy of information in a hover card.