Hover Card

Lightweight preview shown on hover or focus.

Show a lightweight preview for a link or trigger. It opens on hover or focus and closes when you leave.

tsx
import {  Avatar,  AvatarFallback,  AvatarImage,} from "@/components/ui/avatar"import {  HoverCard,  HoverCardContent,  HoverCardTrigger,} from "@/components/ui/hover-card"export function Example() {  return (    <HoverCard>      <HoverCardTrigger asChild>        <a          href="#"          className="text-sm font-medium tracking-wide underline-offset-4 hover:underline"          onClick={(event) => event.preventDefault()}        >          @arctis        </a>      </HoverCardTrigger>      <HoverCardContent className="w-80">        <div className="flex gap-4">          <Avatar>            <AvatarImage src="/assets/brand/demos/avatars/avatar-1.png" alt="Arctis" />            <AvatarFallback>AR</AvatarFallback>          </Avatar>          <div className="flex flex-col gap-1">            <h4 className="text-sm font-medium tracking-wide">@arctis</h4>            <p className="text-sm tracking-wide text-muted-foreground">              A modern component library for building beautiful interfaces.            </p>            <div className="mt-1 text-xs tracking-wide text-muted-foreground">              Joined January 2024            </div>          </div>        </div>      </HoverCardContent>    </HoverCard>  )}

Installation

npx @arctis-sh/@arctis-sh/ui@latest add hover-card

Usage

import {  HoverCard,  HoverCardContent,  HoverCardTrigger,} from "@/components/ui/hover-card"
<HoverCard>  <HoverCardTrigger>Hover</HoverCardTrigger>  <HoverCardContent>    Product designer in Oslo, working on design systems.  </HoverCardContent></HoverCard>

Composition

HoverCard
├── HoverCardTrigger
└── HoverCardContent

Trigger Delays

Set shared delays with openDelay and closeDelay on HoverCard, or override them per trigger with delay and closeDelay.

<HoverCard openDelay={100} closeDelay={200}>  <HoverCardTrigger>Hover</HoverCardTrigger>  <HoverCardContent>Content</HoverCardContent></HoverCard>
<HoverCard>  <HoverCardTrigger delay={100} closeDelay={200}>    Hover  </HoverCardTrigger>  <HoverCardContent>Content</HoverCardContent></HoverCard>

Positioning

Use side and align on HoverCardContent to control placement.

<HoverCard>  <HoverCardTrigger>Hover</HoverCardTrigger>  <HoverCardContent side="top" align="start">    Content  </HoverCardContent></HoverCard>

Basic

Hover the link to preview the profile.

tsx
import {  Avatar,  AvatarFallback,  AvatarImage,} from "@/components/ui/avatar"import {  HoverCard,  HoverCardContent,  HoverCardTrigger,} from "@/components/ui/hover-card"export function Example() {  return (    <HoverCard>      <HoverCardTrigger asChild>        <a          href="#"          className="text-sm font-medium tracking-wide underline-offset-4 hover:underline"          onClick={(event) => event.preventDefault()}        >          @arctis        </a>      </HoverCardTrigger>      <HoverCardContent className="w-80">        <div className="flex gap-4">          <Avatar>            <AvatarImage src="/assets/brand/demos/avatars/avatar-1.png" alt="Arctis" />            <AvatarFallback>AR</AvatarFallback>          </Avatar>          <div className="flex flex-col gap-1">            <h4 className="text-sm font-medium tracking-wide">@arctis</h4>            <p className="text-sm tracking-wide text-muted-foreground">              A modern component library for building beautiful interfaces.            </p>            <div className="mt-1 text-xs tracking-wide text-muted-foreground">              Joined January 2024            </div>          </div>        </div>      </HoverCardContent>    </HoverCard>  )}

Sides

Place the card on whichever side of the trigger fits best.

tsx
import { Button } from "@/components/ui/button"import {  HoverCard,  HoverCardContent,  HoverCardTrigger,} from "@/components/ui/hover-card"export function Example() {  return (    <div className="flex flex-wrap items-center gap-2">      <HoverCard>        <HoverCardTrigger asChild>          <Button variant="outline">Left</Button>        </HoverCardTrigger>        <HoverCardContent side="left">          Opens on the left        </HoverCardContent>      </HoverCard>      <HoverCard>        <HoverCardTrigger asChild>          <Button variant="outline">Top</Button>        </HoverCardTrigger>        <HoverCardContent side="top">Opens on top</HoverCardContent>      </HoverCard>      <HoverCard>        <HoverCardTrigger asChild>          <Button variant="outline">Bottom</Button>        </HoverCardTrigger>        <HoverCardContent side="bottom">Opens below</HoverCardContent>      </HoverCard>      <HoverCard>        <HoverCardTrigger asChild>          <Button variant="outline">Right</Button>        </HoverCardTrigger>        <HoverCardContent side="right">          Opens on the right        </HoverCardContent>      </HoverCard>    </div>  )}

API Reference

HoverCard

PropTypeDefault
openboolean
defaultOpenbooleanfalse
onOpenChange(open: boolean) => void
openDelaynumber700
closeDelaynumber300
<HoverCard>  <HoverCardTrigger>Hover</HoverCardTrigger>  <HoverCardContent>Content</HoverCardContent></HoverCard>

HoverCardTrigger

PropTypeDefault
asChildbooleanfalse
delaynumber
closeDelaynumber

When delay or closeDelay is omitted, the corresponding value from the root is used.

<HoverCardTrigger asChild>  <a href="#">@jordan</a></HoverCardTrigger>

HoverCardContent

PropTypeDefault
side"top" | "bottom" | "left" | "right""bottom"
align"start" | "center" | "end""center"
sideOffsetnumber4
alignOffsetnumber0
classNamestring
<HoverCardContent side="top" align="start">  Content</HoverCardContent>