Skip to main content

Hover Card

Rich preview that opens when a link or trigger is hovered or focused. Delays, sides and alignment.

1'use client';
2
3import { Calendar03Icon } from '@hugeicons/core-free-icons';
4import { HugeiconsIcon } from '@hugeicons/react';
5import { Avatar } from '@/components/ui/avatar';
6import { Button } from '@/components/ui/button';
7import { HoverCard } from '@/components/ui/hover-card';
8
9export function Default() {
10 return (
11 <HoverCard>
12 <HoverCard.Trigger asChild>
13 <Button variant="link">@figueroaignacio</Button>
14 </HoverCard.Trigger>
15 <HoverCard.Content className="w-72">
16 <div className="flex gap-3">
17 <Avatar>
18 <Avatar.Image src="https://github.com/figueroaignacio.png" alt="Ignacio Figueroa" />
19 <Avatar.Fallback>IF</Avatar.Fallback>
20 </Avatar>
21 <div className="flex flex-col gap-1">
22 <p className="text-sm font-semibold">@figueroaignacio</p>
23 <p className="text-muted-foreground text-xs">
24 Building NachUI, a copy-paste component library with zero dependencies.
25 </p>
26 <p className="text-muted-foreground flex items-center gap-1.5 pt-1 text-xs">
27 <HugeiconsIcon icon={Calendar03Icon} size={14} />
28 Joined March 2024
29 </p>
30 </div>
31 </div>
32 </HoverCard.Content>
33 </HoverCard>
34 );
35}

Installation

pnpm dlx nachui add hover-card

Anatomy

1import { HoverCard } from '@/components/ui/hover-card';
1<HoverCard>
2 <HoverCard.Trigger asChild>
3 <a href="/u/nacho">@nacho</a>
4 </HoverCard.Trigger>
5 <HoverCard.Content>Profile preview</HoverCard.Content>
6</HoverCard>
The card opens after openDelay when the pointer enters the trigger and closes after closeDelay when it leaves, unless it moved onto the card. Keyboard focus opens it at once and blur closes it. Escape closes it too. Touch pointers never open it, so on phones the trigger keeps its own behaviour.

Composition

HoverCard
├── HoverCard.Trigger
└── HoverCard.Content

Variants

Default

A profile card on a mention.
1'use client';
2
3import { Calendar03Icon } from '@hugeicons/core-free-icons';
4import { HugeiconsIcon } from '@hugeicons/react';
5import { Avatar } from '@/components/ui/avatar';
6import { Button } from '@/components/ui/button';
7import { HoverCard } from '@/components/ui/hover-card';
8
9export function Default() {
10 return (
11 <HoverCard>
12 <HoverCard.Trigger asChild>
13 <Button variant="link">@figueroaignacio</Button>
14 </HoverCard.Trigger>
15 <HoverCard.Content className="w-72">
16 <div className="flex gap-3">
17 <Avatar>
18 <Avatar.Image src="https://github.com/figueroaignacio.png" alt="Ignacio Figueroa" />
19 <Avatar.Fallback>IF</Avatar.Fallback>
20 </Avatar>
21 <div className="flex flex-col gap-1">
22 <p className="text-sm font-semibold">@figueroaignacio</p>
23 <p className="text-muted-foreground text-xs">
24 Building NachUI, a copy-paste component library with zero dependencies.
25 </p>
26 <p className="text-muted-foreground flex items-center gap-1.5 pt-1 text-xs">
27 <HugeiconsIcon icon={Calendar03Icon} size={14} />
28 Joined March 2024
29 </p>
30 </div>
31 </div>
32 </HoverCard.Content>
33 </HoverCard>
34 );
35}
Inline in a paragraph, opening above and aligned to the start of the link.

The incident started after the

rolled out to the EU region, and was resolved by rolling back the pooling change.

1'use client';
2
3import { HoverCard } from '@/components/ui/hover-card';
4
5export function LinkPreview() {
6 return (
7 <p className="text-muted-foreground max-w-sm text-sm leading-relaxed">
8 The incident started after the{' '}
9 <HoverCard openDelay={200}>
10 <HoverCard.Trigger asChild>
11 <a
12 href="#"
13 className="text-foreground font-medium underline underline-offset-4"
14 onClick={(event) => event.preventDefault()}
15 >
16 v2.24.0 release
17 </a>
18 </HoverCard.Trigger>
19 <HoverCard.Content side="top" align="start" className="w-64 p-0">
20 <div className="bg-muted h-24 rounded-t-md" />
21 <div className="flex flex-col gap-1 p-3">
22 <p className="text-sm font-medium">Release v2.24.0</p>
23 <p className="text-muted-foreground text-xs">
24 Connection pooling for the EU region, new webhook retries, and 14 fixes.
25 </p>
26 <p className="text-muted-foreground text-xs">github.com/northwind/api</p>
27 </div>
28 </HoverCard.Content>
29 </HoverCard>{' '}
30 rolled out to the EU region, and was resolved by rolling back the pooling change.
31 </p>
32 );
33}

API Reference

HoverCard

PropTypeDefaultDescription
openboolean-Controlled open state
defaultOpenbooleanfalseInitial state when uncontrolled
onOpenChange(open: boolean) => void-Called when the state changes
openDelaynumber500Milliseconds of hover before opening
closeDelaynumber200Milliseconds after leaving before closing

HoverCard.Trigger

PropTypeDefaultDescription
asChildbooleanfalseAttach the handlers to the child instead of a span

HoverCard.Content

PropTypeDefaultDescription
side"top" | "bottom" | "left" | "right""bottom"Placement relative to the trigger
align"start" | "center" | "end""center"Alignment along that side
sideOffsetnumber4Gap from the trigger in pixels
classNamestring-Additional CSS classes
Found something to improve?

Notice a bug, typo, or missing detail on this page? Help us make the documentation better by opening a GitHub issue.

Create an Issue
Ctrl+I