Shadcn Hover Card
Free shadcn/ui hover card for React — a rich preview that opens on hover, built on Radix: a profile card, a user mention, and an inline glossary term.
Installation
{
"registries": {
"@designrevision": "https://registry.designrevision.com/r/{name}.json"
}
}
Add to your existing components.json. Requires shadcn/ui v2.3+.
Packages
Props
No props documented yet.
"use client"
import * as React from "react"
import * as HoverCardPrimitive from "@radix-ui/react-hover-card"
import { cn } from "@/lib/utils"
function HoverCard({
...props
}: React.ComponentProps<typeof HoverCardPrimitive.Root>) {
return <HoverCardPrimitive.Root data-slot="hover-card" {...props} />
}
function HoverCardTrigger({
...props
}: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {
return (
<HoverCardPrimitive.Trigger data-slot="hover-card-trigger" {...props} />
)
}
function HoverCardContent({
className,
align = "center",
sideOffset = 4,
...props
}: React.ComponentProps<typeof HoverCardPrimitive.Content>) {
return (
<HoverCardPrimitive.Portal data-slot="hover-card-portal">
<HoverCardPrimitive.Content
data-slot="hover-card-content"
align={align}
sideOffset={sideOffset}
className={cn(
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden",
className
)}
{...props}
/>
</HoverCardPrimitive.Portal>
)
}
export { HoverCard, HoverCardTrigger, HoverCardContent }
Examples
Basic
The canonical profile-preview hover card.
Packages
Props
No props documented yet.
import { CalendarDays } from "lucide-react"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card"
export default function HoverCardDemo01() {
return (
<HoverCard>
<HoverCardTrigger asChild>
<Button variant="link">@nextjs</Button>
</HoverCardTrigger>
<HoverCardContent className="w-80">
<div className="flex justify-between gap-4">
<Avatar>
<AvatarImage src="https://github.com/vercel.png" />
<AvatarFallback>VC</AvatarFallback>
</Avatar>
<div className="space-y-1">
<h4 className="text-sm font-semibold">@nextjs</h4>
<p className="text-sm">
The React Framework – created and maintained by @vercel.
</p>
<div className="text-muted-foreground flex items-center pt-2 text-xs">
<CalendarDays className="mr-2 size-4" />
Joined December 2021
</div>
</div>
</div>
</HoverCardContent>
</HoverCard>
)
}
User mention
An @mention preview with follower stats and a follow button.
Packages
Props
No props documented yet.
import { Avatar, AvatarFallback } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card"
export default function HoverCardUser01() {
return (
<HoverCard>
<HoverCardTrigger asChild>
<a href="#" className="font-medium underline-offset-4 hover:underline">
@ada
</a>
</HoverCardTrigger>
<HoverCardContent className="w-72">
<div className="flex gap-3">
<Avatar>
<AvatarFallback>AL</AvatarFallback>
</Avatar>
<div className="space-y-1.5">
<div>
<p className="text-sm font-semibold">Ada Lovelace</p>
<p className="text-muted-foreground text-xs">
@ada · Mathematician
</p>
</div>
<div className="flex gap-3 text-xs">
<span>
<span className="text-foreground font-medium">1,204</span>{" "}
<span className="text-muted-foreground">Followers</span>
</span>
<span>
<span className="text-foreground font-medium">180</span>{" "}
<span className="text-muted-foreground">Following</span>
</span>
</div>
<Button size="sm" className="mt-1 h-7 w-full">
Follow
</Button>
</div>
</div>
</HoverCardContent>
</HoverCard>
)
}
Glossary term
An inline term that reveals a definition on hover, with a small open delay.
Packages
Props
No props documented yet.
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card"
export default function HoverCardLink01() {
return (
<p className="max-w-sm text-sm leading-relaxed">
Install components from the{" "}
<HoverCard openDelay={120}>
<HoverCardTrigger asChild>
<span className="cursor-help font-medium underline decoration-dotted underline-offset-4">
CLI
</span>
</HoverCardTrigger>
<HoverCardContent className="w-72">
<p className="text-sm font-medium">Command-line interface</p>
<p className="text-muted-foreground mt-1 text-sm">
A text-based way to run programs by typing commands — here, to add
components to your project.
</p>
</HoverCardContent>
</HoverCard>{" "}
and they're copied straight into your codebase.
</p>
)
}
The Shadcn Hover Card is a rich preview that opens on hover, built on Radix. Unlike a tooltip, it holds real content — avatars, stats, links, a button — and stays open while you move the pointer into it. It's the pattern behind a profile preview on an @mention or a definition on a linked term. The examples below cover a profile card, a user mention, and an inline glossary term.
The shape
<HoverCard>
<HoverCardTrigger asChild>
<a href="https://github.com/vercel">@nextjs</a>
</HoverCardTrigger>
<HoverCardContent className="w-80">
{/* avatar, bio, stats */}
</HoverCardContent>
</HoverCard>
HoverCardTrigger is the element you hover; HoverCardContent is the preview that appears. Pass asChild so the trigger keeps your own tag — an inline link or span stays inline.
Hover Card vs Tooltip
- Tooltip — a short text label that names a control.
- Hover Card — rich, interactive content you can move the pointer into.
Use a tooltip for a one-line hint; use a hover card for a preview the user might read or click inside.
Timing
Tune the delays so the card doesn't flash as the pointer crosses the trigger:
<HoverCard openDelay={200} closeDelay={100}>
A short openDelay waits for intent; a small closeDelay lets the user move into the card without it snapping shut.
Common patterns
- Profile preview — an avatar, bio, and join date on a username (the Basic example).
- User mention — follower stats and a Follow button on an @mention (the User mention example).
- Glossary term — a definition revealed on an inline term (the Glossary term example).
Touch and accessibility
Hover doesn't exist on touch, so a hover card never opens by tap — treat it as progressive enhancement and never hide essential information inside it. It does open on keyboard focus, so keyboard users reach it by tabbing to the trigger. When the content must be reachable everywhere, use a Popover, which opens on click.