Skip to content
UI

Hover Card

A preview of the record behind a link, shown when the pointer rests on the link.

@zenoxai/ui/components/hover-cardBase UI Markdown

Alert raised on srv-db-01.prod at 14:02.

<p>
  Alert raised on{" "}
  <HoverCard>
    <HoverCardTrigger
      href="#asset-srv-db-01"
      className="font-medium text-link underline-offset-4 hover:underline"
    >
      srv-db-01.prod
    </HoverCardTrigger>
    <HoverCardContent className="flex flex-col gap-3">
      <div className="flex items-center justify-between gap-2">
        <span className="font-medium">srv-db-01.prod</span>
        <Badge variant="soft" tone="success">
          Online
        </Badge>
      </div>
      <dl className="grid grid-cols-[auto_1fr] gap-x-4 gap-y-1">
        <dt className="text-text-secondary">IP address</dt>
        <dd>10.20.4.17</dd>
        <dt className="text-text-secondary">OS</dt>
        <dd>Ubuntu 22.04 LTS</dd>
        <dt className="text-text-secondary">Open alerts</dt>
        <dd>3</dd>
      </dl>
    </HoverCardContent>
  </HoverCard>{" "}
  at 14:02.
</p>

Usage

import {
  HoverCard,
  HoverCardContent,
  HoverCardTrigger,
} from "@zenoxai/ui/components/hover-card"
<HoverCard>
  <HoverCardTrigger href="/assets/srv-db-01">srv-db-01.prod</HoverCardTrigger>
  <HoverCardContent>{/* summary of the asset */}</HoverCardContent>
</HoverCard>

A hover card lets the user peek at an asset, a user or a rule mentioned in running text without following the link. The trigger renders an <a>: give it an href that leads to the full record, because the card is only a shortcut to what that page shows.

  • To label an icon button or explain a control in a few words, use Tooltip.
  • For content the user must be able to reach on touch screens or with a keyboard, or that holds buttons and fields, use Popover. A hover card opens on hover and keyboard focus only, and its content cannot be tabbed into.

HoverCardContent is 16rem wide and opens below the trigger, centered on it. Set side, align and sideOffset to move it, and className to change the width or the layout.

Examples

User card

A card for a person: avatar, name, role and a figure that helps decide whether to open the profile.

Assigned to Marina Santos

<p>
  Assigned to{" "}
  <HoverCard>
    <HoverCardTrigger
      href="#user-msantos"
      className="font-medium text-link underline-offset-4 hover:underline"
    >
      Marina Santos
    </HoverCardTrigger>
    <HoverCardContent side="top" className="flex gap-3">
      <Avatar size="lg">
        <AvatarFallback>MS</AvatarFallback>
      </Avatar>
      <div className="flex flex-col gap-0.5">
        <span className="font-medium">Marina Santos</span>
        <span className="text-text-secondary">
          Tier 2 analyst, Acme Corp
        </span>
        <span className="text-text-muted">12 open investigations</span>
      </div>
    </HoverCardContent>
  </HoverCard>
</p>

Delay

The card opens after the pointer rests on the link for 600ms and closes 300ms after it leaves, so it does not flash while the pointer crosses the page. Set delay and closeDelay on the trigger to change them.

Detected by Impossible travel

<p>
  Detected by{" "}
  <HoverCard>
    <HoverCardTrigger
      href="#rule-impossible-travel"
      delay={200}
      closeDelay={500}
      className="font-medium text-link underline-offset-4 hover:underline"
    >
      Impossible travel
    </HoverCardTrigger>
    <HoverCardContent>
      Two logins from locations more than 1,000 km apart within an hour.
      Enabled in 14 tenants.
    </HoverCardContent>
  </HoverCard>
</p>

Accessibility

  • The card is a visual enhancement for pointer and keyboard users. Screen readers announce the link only, so the card must never hold the only copy of a piece of information.
  • The trigger is a real link. Do not render it as a button or give it an onClick that does something else than navigate.

API reference

Generated from the TypeScript source. className, style and children are accepted everywhere and omitted below.

HoverCard

HoverCard previews what is behind a link, such as a user or a record, when the pointer rests on its HoverCardTrigger. Keep it optional: touch users cannot hover, so the link itself must lead to the same information. For a one-line hint use Tooltip; for interactive content opened on click, Popover.

PropTypeDefault
actionsRefRefObject<PreviewCardRootActions | null>

A ref to imperative actions. - `unmount`: Ends the closing phase of the preview card after an externally controlled closing animation finishes. Call `preventUnmountOnClose()` in `onOpenChange` first, otherwise the preview card completes closing on its own. Whether it leaves the DOM is decided by `keepMounted` on the portal. - `close`: Closes the preview card imperatively when called.

-
defaultOpenboolean

Whether the preview card is initially open.

false
defaultTriggerIdstring | null

ID of the trigger that the preview card is associated with. This is useful in conjunction with the `defaultOpen` prop to create an initially open preview card.

-
handlePreviewCardHandle<unknown>

A handle to associate the preview card with a trigger. If specified, allows external triggers to control the card's open state. Can be created with the PreviewCard.createHandle() method.

-
onOpenChange((open: boolean, eventDetails: PreviewCardRootChangeEventDetails) => void)

Event handler called when the preview card is opened or closed.

-
onOpenChangeComplete((open: boolean) => void)

Event handler called after any animations complete when the preview card is opened or closed.

-
openboolean

Whether the preview card is currently open.

-
triggerIdstring | null

ID of the trigger that the preview card is associated with. This is useful in conjunction with the `open` prop to create a controlled preview card. There's no need to specify this prop when the preview card is uncontrolled (that is, when the `open` prop is not set).

-

HoverCardTrigger

PropTypeDefault
closeDelaynumber

How long to wait before closing the preview card. Specified in milliseconds.

300
delaynumber

How long to wait before the preview card opens. Specified in milliseconds.

600
handlePreviewCardHandle<unknown>

A handle to associate the trigger with a preview card.

-
payloadunknown

A payload to pass to the preview card when it is opened.

-
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<DetailedHTMLProps<AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, PreviewCardTriggerState>

Allows you to replace the component's HTML element with a different tag, or compose it with another component.

-

HoverCardContent

HoverCardContent is the floating card, 256px wide, in a portal below the trigger and centered on it. It enters and exits with the same motion as Popover.

PropTypeDefault
align"center" | "start" | "end"

How to align the popup relative to the specified side.

start
alignOffsetnumber | OffsetFunction

Additional offset along the alignment axis in pixels. Also accepts a function that returns the offset to read the dimensions of the anchor and positioner elements, along with its side and alignment.

0
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, PreviewCardPopupState>

Allows you to replace the component's HTML element with a different tag, or compose it with another component.

-
side"left" | "right" | "top" | "bottom" | "inline-end" | "inline-start"

Which side of the anchor element to align the popup against. May automatically change to avoid collisions.

bottom
sideOffsetnumber | OffsetFunction

Distance between the anchor and the popup in pixels. Also accepts a function that returns the distance to read the dimensions of the anchor and positioner elements, along with its side and alignment.

0