Preview Card
A floating card that surfaces contextual information when hovering over a trigger, such as user profiles, link previews, or supplementary details.
Overview
The PreviewCard component surfaces glanceable, contextual information when the user hovers over a trigger element. It's designed for supplementary content like user profiles, link destinations, or metadata — information that helps the user decide whether to take further action.
Preview card content is a floating surface. It resolves two surface levels above its parent and uses the matching contextual border and shadow, so it follows the same surface model as Popover.
Usage
import {
PreviewCard,
PreviewCardContent,
PreviewCardTrigger,
} from "@tilt-legal/cubitt-components/preview-card";<PreviewCard>
<PreviewCardTrigger render={<a href="/profile" />}>
Jane Smith
</PreviewCardTrigger>
<PreviewCardContent>
<p>Preview content goes here</p>
</PreviewCardContent>
</PreviewCard>Examples
Basic
Hover over the name to see a preview of user information.
import { Button } from "@tilt-legal/cubitt-components/button";
import {
PreviewCard,
PreviewCardContent,
PreviewCardTrigger,
} from "@tilt-legal/cubitt-components/preview-card";
import { MapPin } from "@tilt-legal/cubitt-icons/ui/outline";
<PreviewCard>
<PreviewCardTrigger render={<Button variant="link" />}>
John Doe
</PreviewCardTrigger>
<PreviewCardContent>
<div className="space-y-2">
<h4 className="font-medium">John Doe</h4>
<p className="text-fg-2 text-sm">
Software Engineer with 5+ years of experience in web development.
</p>
<div className="flex items-center gap-2 text-fg-2 text-xs">
<MapPin className="size-3" />
<span>San Francisco, CA</span>
</div>
</div>
</PreviewCardContent>
</PreviewCard>;Positions
Preview card positioned on physical and writing-direction-aware sides of the trigger.
import { Button } from "@tilt-legal/cubitt-components/button";
import {
PreviewCard,
PreviewCardContent,
PreviewCardTrigger,
} from "@tilt-legal/cubitt-components/preview-card";
<PreviewCard>
<PreviewCardTrigger render={<Button variant="link" />}>
Left
</PreviewCardTrigger>
<PreviewCardContent side="left">
<div className="space-y-1">
<p className="font-medium text-sm">Left Position</p>
<p className="text-fg-2 text-xs">
Preview appears on the left side.
</p>
</div>
</PreviewCardContent>
</PreviewCard>;With Badges
Hover to see a richer profile preview with skills and metadata.
import { Avatar, AvatarFallback } from "@tilt-legal/cubitt-components/avatar";
import { Badge } from "@tilt-legal/cubitt-components/badge";
import { Button } from "@tilt-legal/cubitt-components/button";
import {
PreviewCard,
PreviewCardContent,
PreviewCardTrigger,
} from "@tilt-legal/cubitt-components/preview-card";
import { Calendar, Suitcase } from "@tilt-legal/cubitt-icons/ui/outline";
<PreviewCard>
<PreviewCardTrigger render={<Button variant="link" />}>
Sarah Johnson
</PreviewCardTrigger>
<PreviewCardContent>
<div className="space-y-3">
<div className="flex items-center gap-3">
<Avatar className="size-12">
<AvatarFallback>SJ</AvatarFallback>
</Avatar>
<div>
<h4 className="font-medium">Sarah Johnson</h4>
<p className="text-fg-2 text-xs">Product Designer</p>
</div>
</div>
<div className="flex flex-wrap gap-1.5">
<Badge size="sm">UI/UX</Badge>
<Badge size="sm">Figma</Badge>
<Badge size="sm">Design Systems</Badge>
</div>
<div className="space-y-1.5 text-fg-2 text-xs">
<div className="flex items-center gap-2">
<Suitcase className="size-3" />
<span>Tech Corp</span>
</div>
<div className="flex items-center gap-2">
<Calendar className="size-3" />
<span>Joined March 2023</span>
</div>
</div>
</div>
</PreviewCardContent>
</PreviewCard>;API Reference
PreviewCard
The root component that manages the preview card state.
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Whether the preview card is currently open (controlled). |
defaultOpen | boolean | false | Whether the preview card is initially open (uncontrolled). |
onOpenChange | (open, eventDetails) => void | — | Callback fired when the preview card is opened or closed. |
onOpenChangeComplete | (open: boolean) => void | — | Callback fired after any open/close animations complete. |
actionsRef | RefObject<PreviewCard.Actions> | — | Reference to imperative actions for closing or unmounting the popup. |
handle | PreviewCard.Handle | — | Handle used to associate external triggers with the card. |
triggerId | string | null | — | Active trigger id for controlled preview cards. |
defaultTriggerId | string | null | — | Initial active trigger id for uncontrolled preview cards. |
children | ReactNode | (payload) => ReactNode | — | Child elements or payload-driven render function. |
PreviewCardTrigger
The element that shows the preview card when hovered.
| Prop | Type | Default | Description |
|---|---|---|---|
delay | number | 0 | Delay in milliseconds before showing the preview. |
closeDelay | number | 0 | Delay in milliseconds before hiding the preview. |
children | ReactNode | — | The content of the trigger element. |
className | string | (state) => string | — | CSS classes or function that returns classes based on component state. |
render | ReactElement | (props) => ReactElement | — | Allows composing the trigger with another component. Receives props to spread. |
PreviewCardContent
The container for the preview card content, positioned relative to the trigger.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional CSS classes for the content. |
align | "start" | "center" | "end" | "center" | Alignment relative to the trigger. |
side | "top" | "right" | "bottom" | "left" | "inline-start" | "inline-end" | "bottom" | Which side of the trigger to position. |
sideOffset | number | function | 8 | Distance in pixels from the trigger. |
alignOffset | number | function | 0 | Offset in pixels along the alignment axis. |
anchor | Element | RefObject | function | trigger | Optional custom anchor to position against. |
positionMethod | "absolute" | "fixed" | "absolute" | CSS positioning method for the floating layer. |
children | ReactNode | — | The content to display inside the preview card. |