Popover Card

PreviousNext

A premium hover/focus popover for quick previews — users, files and extra details — with blur entrance, an animated arrow and staggered content.

Reviewed by @sofia and attached to the thread.

Installation

pnpm dlx shadcn@latest add https://matos-ui.com/r/popover-card.json

Usage

import {
  PopoverCard,
  PopoverCardTrigger,
  PopoverCardContent,
  PopoverCardHeader,
  PopoverCardTitle,
  PopoverCardDescription,
  PopoverCardBody,
  PopoverCardFooter,
  PopoverCardItem
} from '@/components/matos-ui/popover-card'
<PopoverCard>
  <PopoverCardTrigger underline>@sofia</PopoverCardTrigger>
  <PopoverCardContent side="top">
    <PopoverCardHeader>
      <PopoverCardTitle>Sofia Ramos</PopoverCardTitle>
      <PopoverCardDescription>Product Designer</PopoverCardDescription>
    </PopoverCardHeader>
    <PopoverCardBody>Crafting the design system.</PopoverCardBody>
  </PopoverCardContent>
</PopoverCard>

The card opens on hover and on keyboard focus, so it works for pointer and keyboard users alike. It is built on Base UI's Preview Card, so positioning, collision handling, portalling and focus management come for free.

When to use

Reach for the Popover Card to surface non-essential, contextual information without navigating away:

  • User preview — avatar, name, role and quick actions on a mention.
  • File preview — type, size and metadata on a file chip.
  • Quick details — definitions, specs or a summary behind a link.
  • Extra info — anything that enriches the current view on demand.

For information the user must act on, use a dialog or popover with a click trigger instead.

Examples

Custom trigger

The trigger renders an <a> by default. Use the render prop to turn any element (a button, an avatar) into the trigger.

<PopoverCardTrigger
  render={<button type="button" className="rounded-lg border px-2 py-0.5" />}
>
  report.pdf
</PopoverCardTrigger>

Placement & size

<PopoverCardContent side="right" align="start" size="lg" sideOffset={12}>
  ...
</PopoverCardContent>

Delays

delay and closeDelay live on the trigger (in milliseconds).

<PopoverCardTrigger delay={200} closeDelay={120}>
  Hover me
</PopoverCardTrigger>

Micro-interactions

  • Blur entrance — the popup fades in from a slight scale and blur, and blurs back out on close (driven by Base UI's starting/ending styles).
  • Animated arrow — the arrow rotates with a transition as the card flips to the opposite side on collision, and scales in with the popup.
  • Staggered contentHeader, Body, Footer and Item rise and de-blur one after another via Framer Motion.
  • Trigger lift — the trigger nudges up on hover and while open.
  • Reduced motion — all motion is disabled when the user prefers reduced motion.

Reference

PopoverCard

Wraps Base UI PreviewCard.Root. Accepts open, defaultOpen and onOpenChange for controlled usage.

PopoverCardTrigger

PropTypeDefaultDescription
renderelement<a>Render the trigger as a different element.
underlinebooleanfalseDotted underline styling for inline text triggers.
delaynumber600Time to wait before opening (ms).
closeDelaynumber300Time to wait before closing (ms).

PopoverCardContent

PropTypeDefaultDescription
size"sm" | "md" | "lg""md"Width of the card.
side"top" | "right" | "bottom" | "left""bottom"Preferred side relative to the trigger.
align"start" | "center" | "end""center"Alignment along the side.
sideOffsetnumber10Gap between trigger and card.
alignOffsetnumber0Offset along the alignment axis.
showArrowbooleantrueRender the animated arrow.

Layout subcomponents

ComponentDescription
PopoverCardHeaderStaggered row, ideal for an avatar + title block.
PopoverCardTitlePrimary label.
PopoverCardDescriptionMuted secondary label.
PopoverCardBodyStaggered body text block.
PopoverCardItemGeneric staggered row for custom content.
PopoverCardFooterStaggered footer with a top divider for actions.

Also exported: popoverCardTriggerVariants and popoverCardPopupVariants.

Best practices

  • Keep cards concise — they are a preview, not a full page.
  • Don't hide critical actions behind hover; mirror them elsewhere for touch users.
  • Provide accessible labels on icon-only action buttons inside the card.
  • Prefer side="top" for triggers near the bottom of the viewport.