Pickers and overlays
Preview
A rich card revealed by pausing on a link.
When to use it: Use it to show what a link leads to, such as a profile or package card.
Example
import { Preview, PreviewPopover, PreviewTrigger } from "@comp0/react";
export function Example() {
return (
<Preview>
<PreviewTrigger
href="https://www.npmjs.com/package/@comp0/react"
className="text-base text-zinc-800 underline decoration-zinc-400 underline-offset-4 hover:decoration-zinc-800 sm:text-sm dark:text-zinc-100 dark:decoration-zinc-500 dark:hover:decoration-zinc-200"
>
@comp0/react on npm
</PreviewTrigger>
<PreviewPopover
placement="bottom start"
offset={8}
className="flex w-64 flex-col gap-2 rounded border-0 bg-white p-3 opacity-100 shadow-lg ring-1 ring-zinc-950/10 transition-opacity duration-150 ease-out starting:opacity-0 motion-reduce:transition-none dark:bg-zinc-900 dark:shadow-none dark:ring-white/10"
>
<p className="text-base font-medium text-zinc-900 sm:text-sm dark:text-zinc-100">
@comp0/react
</p>
<p className="text-base text-zinc-600 sm:text-sm dark:text-zinc-400">
Headless React components with native-first behavior and styling hooks.
</p>
<dl className="flex gap-4 text-base text-zinc-600 sm:text-sm dark:text-zinc-400">
<div className="flex gap-1">
<dt>Version</dt>
<dd className="font-medium text-zinc-900 dark:text-zinc-100">0.1.0</dd>
</div>
<div className="flex gap-1">
<dt>Weekly</dt>
<dd className="font-medium text-zinc-900 dark:text-zinc-100">12k</dd>
</div>
</dl>
</PreviewPopover>
</Preview>
);
}Anatomy
Dashed frames are invisible state providers; shaded shapes own real DOM. Numbered pins match the list below.
A wireframe sketch of the assembled component. Each numbered marker matches a part in the list that follows.
Preview
Open-state provider with hover-intent timing. Does not add a DOM element.
PreviewTrigger
Link that reveals the card on hover intent or focus. Owns a DOM element.
PreviewPopover
Rich card that may hold interactive content. Owns a DOM element.
Step by step
- 1
Add the main part
Start Preview around the link people already follow.
- 2
Add the supporting parts
Give PreviewTrigger the real href and put the card in PreviewPopover with a placement.
- 3
Make the behavior clear
Keep the link useful on its own; the card is a bonus, not the destination.
Exampletsx <Preview> <PreviewTrigger href="/users/ada">@ada</PreviewTrigger> <PreviewPopover placement="bottom start" offset={8}> Ada Lovelace, first programmer </PreviewPopover> </Preview>;
Keyboard
- ⇥
- Focus reveals the card on its trigger.
- Esc
- Closes the card.
Forms and accessibility
Previews never hold form values; they only describe what a link leads to.
Accessibility checklist
- Keep the trigger a real link with a clear name; the card must stay optional.
- Do not put content in the card that is not reachable another way.
- Escape closes the card from anywhere, and it stays open while hovered or focused (WCAG 1.4.13).
API reference
import { Preview, PreviewPopover, PreviewTrigger } from "@comp0/react";Preview
Context onlyOpen-state provider with hover-intent timing.
| Prop | Type | Description |
|---|---|---|
open | boolean | Controlled open state. |
defaultOpen | boolean | Initial open state. |
onToggle | (open: boolean) => void | Receives the next open state. |
openDelay | number | Milliseconds the pointer must rest before opening; 600 by default. Focus opens immediately. |
closeDelay | number | Milliseconds after the pointer or focus leaves before closing; 300 by default. |
PreviewTrigger
DOM elementLink that reveals the card on hover intent or focus.
| Prop | Type | Description |
|---|---|---|
href | string | Real destination; the preview never replaces it. |
as | ElementType | Fragment | Fragment merges the trigger onto your own element child. |
PreviewPopover
DOM elementRich card that may hold interactive content.
| Prop | Type | Description |
|---|---|---|
placement | PopoverPlacement | Trigger side to open on, such as "bottom start"; flips when there is no room. |
offset | number | Pixel gap between the trigger and the card. |
Style hooks
Attributes that appear while a state is true. Target them with Tailwind data variants such as data-open:bg-zinc-100, or with any CSS selector.
PreviewTrigger
| Style hook | Meaning |
|---|---|
[data-open] | The card is visible. |
PreviewPopover
| Style hook | Meaning |
|---|---|
[data-open] | The card is visible. |