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" />}
>
Hover Here
</HoverCardTrigger>
<HoverCardContent className="flex w-64 flex-col gap-0.5">
<div className="font-semibold">@nextjs</div>
<div>The React Framework – created and maintained by @vercel.</div>
<div className="mt-1 text-xs text-muted-foreground">
Joined December 2021
</div>
</HoverCardContent>
</HoverCard>
)
}Installation
npx shadcn@latest add @fulldev/hover-card
Usage
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card"
<HoverCard>
<HoverCardTrigger>Hover</HoverCardTrigger>
<HoverCardContent>
The React Framework – created and maintained by @vercel.
</HoverCardContent>
</HoverCard>
Composition
Use the following composition to build a HoverCard:
HoverCard
├── HoverCardTrigger
└── HoverCardContent
Trigger Delays
Use 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>
Positioning
Use the side and align props on HoverCardContent to control placement.
<HoverCard>
<HoverCardTrigger>Hover</HoverCardTrigger>
<HoverCardContent side="top" align="start">
Content
</HoverCardContent>
</HoverCard>
Basic
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" />}
>
Hover Here
</HoverCardTrigger>
<HoverCardContent className="flex w-64 flex-col gap-0.5">
<div className="font-semibold">@nextjs</div>
<div>The React Framework – created and maintained by @vercel.</div>
<div className="mt-1 text-xs text-muted-foreground">
Joined December 2021
</div>
</HoverCardContent>
</HoverCard>
)
}Sides
import { Button } from "@/components/ui/button"
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card"
const HOVER_CARD_SIDES = ["left", "top", "bottom", "right"] as const
export function HoverCardSides() {
return (
<div className="flex flex-wrap justify-center gap-2">
{HOVER_CARD_SIDES.map((side) => (
<HoverCard key={side}>
<HoverCardTrigger
delay={100}
closeDelay={100}
render={<Button variant="outline" className="capitalize" />}
>
{side}
</HoverCardTrigger>
<HoverCardContent side={side}>
<div className="flex flex-col gap-1">
<h4 className="font-medium">Hover Card</h4>
<p>This hover card appears on the {side} side of the trigger.</p>
</div>
</HoverCardContent>
</HoverCard>
))}
</div>
)
}RTL
To enable RTL support in shadcn/ui, see the RTL configuration guide.
"use client"
import { Button } from "@/components/ui/button"
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card"
import {
useTranslation,
type Translations,
} from "@/components/language-selector"
const translations: Translations = {
en: {
dir: "ltr",
values: {
trigger: "Wireless Headphones",
name: "Wireless Headphones",
price: "$99.99",
"inline-start": "Inline Start",
left: "Left",
top: "Top",
bottom: "Bottom",
right: "Right",
"inline-end": "Inline End",
},
},
ar: {
dir: "rtl",
values: {
trigger: "سماعات لاسلكية",
name: "سماعات لاسلكية",
price: "٩٩.٩٩ $",
"inline-start": "بداية السطر",
left: "يسار",
top: "أعلى",
bottom: "أسفل",
right: "يمين",
"inline-end": "نهاية السطر",
},
},
he: {
dir: "rtl",
values: {
trigger: "אוזניות אלחוטיות",
name: "אוזניות אלחוטיות",
price: "99.99 $",
"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, t } = useTranslation(translations, "ar")
return (
<div 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="outline" />}
>
{t[side]}
</HoverCardTrigger>
<HoverCardContent
side={side}
className="flex w-64 flex-col gap-1"
dir={dir}
>
<div className="font-semibold">{t.name}</div>
<div className="text-sm text-muted-foreground">{t.price}</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="outline" />}
>
{t[side]}
</HoverCardTrigger>
<HoverCardContent
side={side}
className="flex w-64 flex-col gap-1"
dir={dir}
>
<div className="font-semibold">{t.name}</div>
<div className="text-sm text-muted-foreground">{t.price}</div>
</HoverCardContent>
</HoverCard>
))}
</div>
</div>
)
}API Reference
Source: react/src/components/ui/hover-card.tsx
See the Base UI documentation for more information.