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.json
import { HoverCard } from "@/components/iris/hover-card/hover-card";
Registry item hover-cardBrings in foundationRegistry JSON

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 use Tooltip.

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 gets aria-describedby pointing 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.