Siteplane UI

Preview Card

Preview a link’s destination without leaving the current page.

Markdown

Assigned to @ben

"use client";

import { Avatar, AvatarFallback } from "@/siteplane/components/avatar";
import {
  PreviewCard,
  PreviewCardPopup,
  PreviewCardTrigger,
} from "@/siteplane/components/preview-card";

export default function Example() {
  return (
    <p className="text-sm">
      Assigned to{" "}
      <PreviewCard>
        <PreviewCardTrigger
          className="font-medium underline underline-offset-4"
          href="#ben-carter"
        >
          @ben
        </PreviewCardTrigger>
        <PreviewCardPopup>
          <div className="flex gap-3">
            <Avatar className="size-10">
              <AvatarFallback>BC</AvatarFallback>
            </Avatar>
            <div className="grid min-w-0 gap-1">
              <p className="font-medium">Ben Carter</p>
              <p className="text-muted-foreground">
                Product designer on the web team.
              </p>
              <p className="text-muted-foreground text-xs">Joined March 2024</p>
            </div>
          </div>
        </PreviewCardPopup>
      </PreviewCard>
    </p>
  );
}

Installation

pnpm dlx shadcn@4.18.0 add @siteplane/preview-card

Complete the one-time setup first. Registry JSON lists source files and dependencies.

For this page’s examples, also install:

pnpm dlx shadcn@4.18.0 add @siteplane/avatar @siteplane/progress

Usage

import {
  PreviewCard,
  PreviewCardTrigger,
  PreviewCardPopup,
} from "@/siteplane/components/preview-card";

<PreviewCard>
  <PreviewCardTrigger href="#website-redesign">
    Website Redesign
  </PreviewCardTrigger>
  <PreviewCardPopup>New marketing site, due October 30.</PreviewCardPopup>
</PreviewCard>;

Composition

PreviewCard
├── PreviewCardTrigger (link)
└── PreviewCardPopup

Show where a link leads, such as a project, so people can decide whether to open it. The popup is 256px wide by default; give PreviewCardPopup a width such as w-80 when the content needs more room. This card pairs a project icon and title with a two-line description, and keeps the details compact with a Progress bar and the due date. The trigger stays a regular link, so it still works for people who don’t hover.

The latest designs are in Website Redesign.

"use client";

import { LayoutTemplateIcon } from "lucide-react";
import {
  PreviewCard,
  PreviewCardPopup,
  PreviewCardTrigger,
} from "@/siteplane/components/preview-card";
import { Progress } from "@/siteplane/components/progress";

export default function Example() {
  return (
    <p className="text-sm">
      The latest designs are in{" "}
      <PreviewCard>
        <PreviewCardTrigger
          className="font-medium underline underline-offset-4"
          href="#website-redesign"
        >
          Website Redesign
        </PreviewCardTrigger>
        <PreviewCardPopup className="w-80">
          <div className="grid w-full min-w-0 gap-3">
            <div className="flex min-w-0 items-start gap-3">
              <LayoutTemplateIcon
                aria-hidden="true"
                className="size-5 shrink-0 text-muted-foreground"
              />
              <div className="grid min-w-0 gap-0.5">
                <p className="font-medium leading-5">Website Redesign</p>
                <p className="line-clamp-2 text-muted-foreground text-xs leading-5">
                  New marketing site with a refreshed homepage and pricing page.
                </p>
              </div>
            </div>
            <div className="grid gap-2">
              <Progress aria-label="Tasks done" max={18} size="sm" value={12} />
              <p className="flex items-center justify-between gap-3 text-muted-foreground text-xs">
                <span>12 of 18 tasks done</span>
                <span>Due October 30</span>
              </p>
            </div>
          </div>
        </PreviewCardPopup>
      </PreviewCard>
      .
    </p>
  );
}

API reference

Component properties
PropTypeDefaultDescription
PreviewCardTrigger.delaynumber600Milliseconds before the card opens.
PreviewCardTrigger.closeDelaynumber300Milliseconds before the card closes.
PreviewCardPopup.sidePositioner sidebottomSide of the anchor the card opens on.
PreviewCardPopup.alignstart | center | endcenterPositioner alignment.
PreviewCardPopup.sideOffsetPositioner sideOffset4Gap from anchor.
PreviewCardPopup.alignOffsetPositioner alignOffset0Shift along the anchor's edge.
PreviewCardPopup.anchorPositioner anchortriggerCustom anchor.
PreviewCardPopup.portalPropsPreviewCardPrimitive.Portal.PropsunsetPortal options.
open / defaultOpenbooleanfalseControlled or initial visibility.
onOpenChange(open, eventDetails) => voidunsetVisibility callback.

PreviewCard is the foundation Root; Trigger preserves link behavior; Popup includes Portal and Positioner and defaults to a padded w-64 surface. Its className is a string. PreviewCardPrimitive exposes Base UI Preview Card. There is no PreviewCardContent alias or complete positioner-props bag; Popup takes the positioner's side, align, sideOffset, alignOffset and anchor directly. Other trigger props, refs and root behavior follow the foundation.

Read the installed source.

Usage notes

Keep the destination understandable without hovering. The card is supplementary and should not contain required actions; use Popover or Dialog for a keyboard-driven interaction.