Hover Card

A preview that opens when a link or button is hovered or focused.

Overview

HoverCardTrigger clones one child. Hover, or keyboard focus, opens HoverCardContent. Moving onto the card keeps it open. Escape closes it. There is no asChild prop.

Preview

@johndoe

Customize

Open Delay
200
Close Delay
150
Side

Installation

Add the component with the CLI. It copies the files in and installs anything they depend on.

npx vinyaas add hover-card

Usage

import { Avatar, AvatarFallback } from "@/components/ui/avatar"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { HoverCard, HoverCardContent, HoverCardTrigger, } from "@/components/ui/hover-card"; export function ProfileCard() { return ( <HoverCard> <HoverCardTrigger> <Button variant="link" className="underline underline-offset-4"> @johndoe </Button> </HoverCardTrigger> <HoverCardContent> <div className="flex items-start gap-3 text-left"> <Avatar> <AvatarFallback>JD</AvatarFallback> </Avatar> <div className="grid gap-1"> <p className="font-medium">John Doe</p> <p className="text-muted-foreground text-sm">@johndoe</p> <p className="text-sm"> Product designer building accessible UI for design systems. </p> <div className="flex flex-wrap items-center gap-2 pt-1"> <Badge variant="outline">Maintainer</Badge> <span className="text-muted-foreground text-xs">San Francisco</span> </div> </div> </div> </HoverCardContent> </HoverCard> ); }

Examples

Profile

Hover or focus an @username to read a short profile. The card stays open while the pointer is over it.

Alignment

side places the card above, below, or beside the trigger. The grid wraps on small screens so the triggers stay usable.

In practice

An assignment line links @johndoe. Hover or focus the mention to open a profile with Avatar, role, and bio.

Assigned to

API

Other attributes for the underlying element are passed through.

NameTypeDefaultDescription
openDelaynumber200Milliseconds before hover or focus opens the card.
closeDelaynumber150Milliseconds before the pointer leaving closes the card.
openboolean—Controlled open state.
onOpenChange(open: boolean) => void—Called when the card opens or closes.
side"top" | "right" | "bottom" | "left""bottom"Preferred side for HoverCardContent.
classNamestring—Merged onto HoverCardContent with cn.

Accessibility

The trigger exposes aria-expanded, aria-haspopup="dialog", and aria-controls while the card is open. The card is a non-modal dialog. Escape closes it. Focus on the trigger opens it, so keyboard users reach the same content as pointer users.