Skip to main content

Overview

@badrinteractive
B
Badr Interactive
@badrinteractive
Designing and building the A’raf Design System. Jakarta, Indonesia 🇮🇩
128 following4.2k followers
Hover Card reveals supplementary content when the user hovers over a trigger element. Unlike Tooltip (text-only, immediate), Hover Card supports rich content and has a short open delay — ideal for user avatars, social handles, and link previews.

Installation

npm install @araf-ds/core

Usage

import {
  HoverCard,
  HoverCardTrigger,
  HoverCardContent,
} from "@araf-ds/core"

export default function Example() {
  return (
    <HoverCard>
      <HoverCardTrigger asChild>
        <a href="#" className="text-primary underline">@badrinteractive</a>
      </HoverCardTrigger>
      <HoverCardContent className="w-64">
        <div className="flex gap-3">
          <Avatar src="/avatar.jpg" fallback="B" />
          <div>
            <h4 className="text-sm font-semibold">Badr Interactive</h4>
            <p className="text-xs text-muted-foreground">@badrinteractive</p>
            <p className="text-sm mt-1">
              Designing A'raf Design System. Jakarta 🇮🇩
            </p>
            <div className="flex gap-4 text-xs text-muted-foreground mt-2">
              <span><strong>128</strong> following</span>
              <span><strong>4.2k</strong> followers</span>
            </div>
          </div>
        </div>
      </HoverCardContent>
    </HoverCard>
  )
}

Variants

User Profile Preview

<HoverCard>
  <HoverCardTrigger asChild>
    <Button variant="link">@badrinteractive</Button>
  </HoverCardTrigger>
  <HoverCardContent side="bottom" align="start" className="w-64">
    <div className="flex gap-3">
      <Avatar src={user.avatar} fallback={user.initials} size="md" />
      <div className="space-y-1">
        <h4 className="text-sm font-semibold">{user.name}</h4>
        <p className="text-xs text-muted-foreground">@{user.handle}</p>
        <p className="text-sm">{user.bio}</p>
        <div className="flex gap-3 text-xs text-muted-foreground pt-1">
          <span><strong>{user.following}</strong> following</span>
          <span><strong>{user.followers}</strong> followers</span>
        </div>
      </div>
    </div>
  </HoverCardContent>
</HoverCard>
<HoverCard openDelay={300}>
  <HoverCardTrigger asChild>
    <a href="https://mintlify.com" target="_blank" className="underline">
      Mintlify docs
    </a>
  </HoverCardTrigger>
  <HoverCardContent className="w-72">
    <div className="space-y-2">
      <div className="aspect-video bg-muted rounded-md overflow-hidden">
        <img src="/og-preview.png" alt="Mintlify" className="w-full h-full object-cover" />
      </div>
      <h4 className="text-sm font-semibold">Mintlify – Beautiful Docs</h4>
      <p className="text-xs text-muted-foreground">
        The documentation platform built for developers.
      </p>
      <p className="text-xs text-muted-foreground">mintlify.com</p>
    </div>
  </HoverCardContent>
</HoverCard>

API Reference

HoverCard

open
boolean
Controlled open state.
onOpenChange
(open: boolean) => void
Callback when open state changes.
openDelay
number
default:"700"
Milliseconds before the card opens after hover starts.
closeDelay
number
default:"300"
Milliseconds before the card closes after hover ends.

HoverCardContent

side
string
default:"bottom"
Which side of the trigger to render on. Values: top · right · bottom · left
align
string
default:"center"
Alignment relative to the trigger. Values: start · center · end
sideOffset
number
default:"4"
Distance in px between trigger and card.

Accessibility

  • Hover Card is purely supplementary — all content inside must also be accessible without hovering
  • It is not keyboard accessible by default (hover only) — consider adding a focus trigger for keyboard users
  • Never put interactive elements (buttons, links) inside a Hover Card — use Popover for that
  • Screen readers ignore Hover Card content — do not put essential information in it

Do’s & Don’ts

Do

  • Use for supplementary previews: user profiles, link previews, tag definitions
  • Set an appropriate openDelay (300–700ms) to avoid accidental triggers
  • Keep content concise — Hover Card is a preview, not a full detail page
  • Use side="bottom" (default) for inline text triggers

Don't

  • Don’t put interactive elements (buttons, forms) inside — use Popover
  • Don’t rely on Hover Card for essential information — hover is not available on touch devices
  • Don’t use on mobile-primary experiences — hover doesn’t exist on touchscreens
  • Don’t set openDelay={0} — it triggers too easily on mouse movement