Experience System
Components

Hover Card

A popover preview anchored to a trigger, shown on pointer hover—profiles, link previews, and lightweight context.

Installation

Hover Card is exported from @by/experience-system. Add the package with your package manager:

pnpm add @by/experience-system

In this monorepo, depend on the workspace package (for example via workspace:* or your catalog) so imports resolve to packages/experience-system.

Composition

Use HoverCard as the root with HoverCardTrigger and HoverCardContent:

HoverCard
├── HoverCardTrigger
└── HoverCardContent

Hover Card is for richer previews than a Tooltip (short text). The panel can include short structured content; avoid long forms or critical-only actions here. Behavior follows Radix UI Hover Card.

Usage

import { Button, HoverCard, HoverCardContent, HoverCardTrigger } from '@by/experience-system';

Hover Card primitives (HoverCard, HoverCardTrigger, HoverCardContent) are client components ('use client'). Wrap your tree in ThemeProvider so HoverCardContent can resolve the portal container. Use it inside a Client Component or a dynamic import when using the Next.js App Router.

<HoverCard openDelay={10} closeDelay={100}>
  <HoverCardTrigger asChild>
    <Button variant="ghost">Hover here</Button>
  </HoverCardTrigger>
  <HoverCardContent className="flex flex-col gap-scaled-2">
    <div className="font-medium">Title</div>
    <div>Supporting text.</div>
  </HoverCardContent>
</HoverCard>

When to use

  • Optional contextual detail that helps understanding but is not required to complete the task.
  • Dense UIs where in-place detail would add noise (tables, dashboards, feeds).
  • Helpful, non-critical metadata (summaries, definitions).
  • Desktop-first experiences where cursor hover is common.

When not to use

  • Critical information or actions that must not depend on hover alone.
  • Touch-first layouts without a reliable hover affordance—prefer tap targets, popovers, or sheets.
  • High-frequency actions that should stay visible or one click away.
  • Large or complex content—use a page, Dialog, or Drawer instead.

Examples

The live preview at the top of this page uses hover-card-overview. Shorter openDelay / closeDelay values feel responsive in demos; increase them in dense UIs to reduce accidental activation.

API Reference

Subsection titles name @by/experience-system exports and the Radix part they wrap. Full primitive reference: Radix Hover Card.

HoverCard

PropTypeDefault
openboolean
defaultOpenboolean
onOpenChange(open: boolean) => void
openDelaynumber
closeDelaynumber

Also accepts other HoverCard.Root props from Radix.

HoverCardTrigger

The anchor that opens the card on hover or focus; supports asChild.

PropTypeDefault
asChildbooleanfalse

HoverCardContent

Floating panel; portaled with useContainerElement. Default align="center", sideOffset={4} in this experience system; merges className with card, border, shadow, and motion utilities.

PropTypeDefault
asChildbooleanfalse
forceMountboolean

Also accepts Radix content positioning props (side, align, sideOffset, collisionPadding, …). See Radix — Content.

Accessibility

The trigger should be a real control (for example Button or Link) so keyboard users can move focus to it and open the card per Radix — accessibility. Keep preview content concise; if users must operate controls inside the panel, consider Popover or Dialog instead.

Source in the repo: packages/experience-system/src/components/HoverCard/HoverCard.tsx. Agent-oriented contracts: packages/experience-system/src/components/HoverCard/HoverCard.instructions.md.