"use client";
import { Avatar, AvatarFallback, AvatarImage,} from "@/components/ui/avatar";import { Button } from "@/components/ui/button";import { HoverCard, HoverCardContent, HoverCardTrigger,} from "@/components/ui/hover-card";
export function HoverCardDemo() { return ( <HoverCard> <HoverCardTrigger delay={10} closeDelay={100} render={<Button variant="link" />} > @nextjs </HoverCardTrigger> <HoverCardContent className="w-64"> <div className="flex items-center gap-3"> <Avatar> <AvatarImage src="https://github.com/vercel.png" /> <AvatarFallback>VC</AvatarFallback> </Avatar> <div className="flex flex-col gap-0.5"> <div className="font-semibold">@nextjs</div> <div className="text-muted-foreground text-xs"> The React Framework </div> </div> </div> <div className="text-muted-foreground text-xs"> Created and maintained by @vercel. </div> <div className="text-muted-foreground text-xs"> Joined December 2021 </div> </HoverCardContent> </HoverCard> );}pnpm dlx shadcn@latest add @herocn/hover-cardimport { HoverCard, HoverCardContent, HoverCardTrigger,} from "@/components/ui/hover-card"<HoverCard> <HoverCardTrigger>Hover</HoverCardTrigger> <HoverCardContent> The React Framework – created and maintained by @vercel. </HoverCardContent></HoverCard>Use the following composition to build a HoverCard:
HoverCard├── HoverCardTrigger└── HoverCardContentUse delay and closeDelay on the trigger to control when the card opens and
closes.
<HoverCard> <HoverCardTrigger delay={100} closeDelay={200}> Hover </HoverCardTrigger> <HoverCardContent>Content</HoverCardContent></HoverCard>Use the side and align props on HoverCardContent to control placement.
<HoverCard> <HoverCardTrigger>Hover</HoverCardTrigger> <HoverCardContent side="top" align="start"> Content </HoverCardContent></HoverCard>Use the side prop to change the position of the hover card.
"use client";
import { Button } from "@/components/ui/button";import { HoverCard, HoverCardContent, HoverCardTrigger,} from "@/components/ui/hover-card";
export function HoverCardSides() { return ( <div className="flex flex-wrap gap-2"> {(["left", "top", "bottom", "right"] as const).map((side) => ( <HoverCard key={side}> <HoverCardTrigger delay={100} closeDelay={100} render={<Button variant="tertiary" className="w-fit capitalize" />} > {side} </HoverCardTrigger> <HoverCardContent side={side}> <div className="flex flex-col gap-1"> <h4 className="font-medium">Hover Card</h4> <p className="text-muted-foreground text-sm"> This hover card appears on the {side} side of the trigger. </p> </div> </HoverCardContent> </HoverCard> ))} </div> );}Use the withArrow prop to add an arrow pointing at the trigger.
"use client";
import { Button } from "@/components/ui/button";import { HoverCard, HoverCardContent, HoverCardTrigger,} from "@/components/ui/hover-card";
export function HoverCardWithArrow() { return ( <div className="flex flex-wrap gap-2"> {(["left", "top", "bottom", "right"] as const).map((side) => ( <HoverCard key={side}> <HoverCardTrigger delay={100} closeDelay={100} render={<Button variant="tertiary" className="w-fit capitalize" />} > {side} </HoverCardTrigger> <HoverCardContent withArrow side={side}> <div className="flex flex-col gap-1"> <h4 className="font-medium">Hover Card</h4> <p className="text-muted-foreground text-sm"> This hover card has an arrow pointing at the trigger. </p> </div> </HoverCardContent> </HoverCard> ))} </div> );}To enable RTL support in shadcn/ui, see the RTL configuration guide.
"use client";
import { type Translations, useTranslation,} from "@/components/language-selector";import { Button } from "@/components/ui/button";import { HoverCard, HoverCardContent, HoverCardTrigger,} from "@/components/ui/hover-card";
const translations: Translations = { en: { dir: "ltr", values: { content: "The React Framework – created and maintained by @vercel.", "inline-start": "Inline Start", left: "Left", top: "Top", bottom: "Bottom", right: "Right", "inline-end": "Inline End", }, }, ar: { dir: "rtl", values: { content: "إطار عمل React - تم إنشاؤه وصيانته بواسطة @vercel.", "inline-start": "بداية السطر", left: "يسار", top: "أعلى", bottom: "أسفل", right: "يمين", "inline-end": "نهاية السطر", }, }, he: { dir: "rtl", values: { content: "React Framework - נוצר ומתוחזק על ידי @vercel.", "inline-start": "תחילת השורה", left: "שמאל", top: "למעלה", bottom: "למטה", right: "ימין", "inline-end": "סוף השורה", }, },};
const physicalSides = ["left", "top", "bottom", "right"] as const;const logicalSides = ["inline-start", "inline-end"] as const;
export function HoverCardRtl() { const { dir, language, t } = useTranslation(translations, "ar");
return ( <div lang={language} dir={dir} className="grid gap-4"> <div className="flex flex-wrap justify-center gap-2"> {physicalSides.map((side) => ( <HoverCard key={side}> <HoverCardTrigger delay={10} closeDelay={100} render={<Button variant="tertiary" />} > {t[side]} </HoverCardTrigger> <HoverCardContent side={side} dir={dir} className="w-64"> <div className="font-semibold">@nextjs</div> <div className="text-muted-foreground text-sm">{t.content}</div> </HoverCardContent> </HoverCard> ))} </div> <div className="flex flex-wrap justify-center gap-2"> {logicalSides.map((side) => ( <HoverCard key={side}> <HoverCardTrigger delay={10} closeDelay={100} render={<Button variant="tertiary" />} > {t[side]} </HoverCardTrigger> <HoverCardContent side={side} dir={dir} className="w-64"> <div className="font-semibold">@nextjs</div> <div className="text-muted-foreground text-sm">{t.content}</div> </HoverCardContent> </HoverCard> ))} </div> </div> );}The hover card is built on Base UI PreviewCard. HoverCardContent sets default positioning and passes the remaining props to the popup.
| Prop | Type | Default |
|---|---|---|
| align | "start" | "center" | "end" | "center" |
Horizontal alignment of the popup relative to the anchor. | ||
| alignOffset | number | 8 |
Offset along the alignment axis. | ||
| side | "top" | "bottom" | "left" | "right" | "inline-start" | "inline-end" | "bottom" |
Which side of the anchor to place the popup on. Logical sides follow the document direction when used with `dir`. | ||
| sideOffset | number | 8 |
Distance between the anchor and the popup. | ||
| withArrow | boolean | false |
Adds an arrow to the HoverCard content | ||
See the Base UI PreviewCard API reference for root, trigger, and other props.