A rich preview that opens while hovering a link, wrapping the Base UI Preview Card. The trigger is a real anchor, so navigation works everywhere and the card is a bonus for pointer users; for plain text on any control, use the Tooltip.

Playground

Every control maps to a prop. Hover (or focus) the link; the Code tab always shows the markup for exactly what you've configured.

Maintained by Sigurdarson

Variants

Four sides, each flipping when out of room. In running text, top keeps the card off the lines that follow, which is why it's the usual pick for inline links.

Pull request #482 was opened by Ada Byrne, reviewed by Grace Okafor and Linus Berg, and merged by Margaret Chen.

States

Closed and open, both live: hover or focus a link and wait out the delay, 600ms by default so a cursor passing through doesn't open it. While open, the trigger carries data-popup-open and the card data-open, and the card stays open while hovered so anything inside stays clickable.

Assigned to Ada Byrne (default delay) and Grace Okafor (no delay).

Styling states

The trigger carries data-popup-open while the preview shows, and the popup carries data-side plus the data-starting-style/data-ending-style enter and exit hooks:

.ub-preview-card-trigger[data-popup-open] {
  text-decoration-color: var(--ub-accent);
}

Props

The trigger is an anchor and takes every anchor prop; position lives on the content. The essentials, by part:

PropTypeDefaultDescription
PreviewCardRoot.openbooleanโ€“Controlled state. Pair with onOpenChange; defaultOpen for uncontrolled.
PreviewCardRoot.onOpenChange(open: boolean) => voidโ€“Called on every open and close, including pointer leave and Escape.
PreviewCardTrigger.hrefstringโ€“Where the link goes; clicking navigates like any anchor.
PreviewCardTrigger.delaynumber600Milliseconds before opening on hover.
PreviewCardTrigger.closeDelaynumber300Milliseconds before closing once the pointer leaves the link and card.
PreviewCardContent.side"top" | "right" | "bottom" | "left""bottom"Preferred side; flips to the opposite when out of room.
PreviewCardContent.align"start" | "center" | "end""center"Alignment along that side.
PreviewCardContent.sideOffsetnumber8Gap between the link and the card, in pixels.

Agent instructions

Working with a coding agent? Paste this into its context, or point it at llms.txt for the whole library.

PreviewCardRoot, PreviewCardTrigger, PreviewCardContent, from @usebones/react.
- Structure: PreviewCardRoot wraps PreviewCardTrigger (a real anchor; pass href) + PreviewCardContent (the floating preview; put an Avatar, headings, text inside).
- The preview is an enhancement: everything essential must be reachable through the link itself, since touch users never see the card.
- PreviewCardContent: side "bottom" (default) | "top" | "right" | "left", align, sideOffset (8). The card stays open while hovered, so links inside are clickable. Timing on the trigger: delay (600ms), closeDelay (300ms).
- Restyle in CSS via .ub-preview-card-popup, [data-popup-open] on the trigger, [data-open]/[data-side] on the popup, [data-starting-style]/[data-ending-style]. Tokens only.