Skip to main content

Hover Card

A card that appears on hover to show a preview or additional information.

import * as HoverCard from '@gentleduck/primitives/hover-card'
import * as HoverCard from '@gentleduck/primitives/hover-card'

Anatomy

<HoverCard.Root>
  <HoverCard.Trigger />
  <HoverCard.Portal>
    <HoverCard.Content>
      <HoverCard.Arrow />
    </HoverCard.Content>
  </HoverCard.Portal>
</HoverCard.Root>
<HoverCard.Root>
  <HoverCard.Trigger />
  <HoverCard.Portal>
    <HoverCard.Content>
      <HoverCard.Arrow />
    </HoverCard.Content>
  </HoverCard.Portal>
</HoverCard.Root>

Example

<HoverCard.Root openDelay={200} closeDelay={300}>
  <HoverCard.Trigger asChild>
    <a href="/user/ahmed" className="text-blue-600 underline">@ahmed</a>
  </HoverCard.Trigger>
  <HoverCard.Portal>
    <HoverCard.Content className="bg-white shadow-lg rounded-lg p-4 w-72 border" sideOffset={5}>
      <div className="flex gap-3">
        <div className="w-12 h-12 bg-gray-200 rounded-full" />
        <div>
          <p className="font-semibold">Ahmed</p>
          <p className="text-sm text-gray-500">Software Engineer</p>
        </div>
      </div>
      <HoverCard.Arrow className="fill-white" />
    </HoverCard.Content>
  </HoverCard.Portal>
</HoverCard.Root>
<HoverCard.Root openDelay={200} closeDelay={300}>
  <HoverCard.Trigger asChild>
    <a href="/user/ahmed" className="text-blue-600 underline">@ahmed</a>
  </HoverCard.Trigger>
  <HoverCard.Portal>
    <HoverCard.Content className="bg-white shadow-lg rounded-lg p-4 w-72 border" sideOffset={5}>
      <div className="flex gap-3">
        <div className="w-12 h-12 bg-gray-200 rounded-full" />
        <div>
          <p className="font-semibold">Ahmed</p>
          <p className="text-sm text-gray-500">Software Engineer</p>
        </div>
      </div>
      <HoverCard.Arrow className="fill-white" />
    </HoverCard.Content>
  </HoverCard.Portal>
</HoverCard.Root>

API

HoverCard.Root

PropTypeDefaultDescription
openboolean--Controlled state
defaultOpenbooleanfalseInitial state
onOpenChange(open: boolean) => void--State change callback
openDelaynumber700Delay before opening (ms)
closeDelaynumber300Delay before closing (ms)

HoverCard.Trigger

The element that activates the card on hover. Renders an <a> by default.

PropTypeDescription
asChildbooleanRender as child element

HoverCard.Portal

Portals content to document.body.

PropTypeDefaultDescription
containerElement | nulldocument.bodyPortal target
forceMounttrue--Force mount content

HoverCard.Content

Positioned floating content. Positioned by the Popper engine.

PropTypeDefaultDescription
side'top' | 'right' | 'bottom' | 'left''bottom'Preferred side
sideOffsetnumber0Distance from anchor in pixels
align'start' | 'center' | 'end''center'Alignment along the side
alignOffsetnumber0Alignment offset in pixels
forceMounttrue--Keep mounted always
onEscapeKeyDown(event) => void--Called on Escape press
onPointerDownOutside(event) => void--Called on outside click
onFocusOutside(event) => void--Called when focus moves outside
onInteractOutside(event) => void--Called for any outside interaction

HoverCard.Arrow

Optional visual arrow pointing toward the trigger.