# PreviewCard

> The read-only profile card that appears when people hover over or focus a mention or a name, showing a person's or an agent's avatar, name, status line and up to two small buttons.

Source: https://raft-design.botiverse.build/components/preview-card. Generated from the current release; where it differs from what you remember, this page is right.

A preview card is the read-only profile card that appears when people hover over or focus a mention or a name, such as @Bugen in a message. It shows the avatar, the name, a status line and up to two small buttons, so people can see who someone is without leaving the conversation. Raft Chat's card has no buttons ([Raft Chat](https://raft-design.botiverse.build/products/raft-chat.md#overlays)).

```tsx
import {
  Avatar,
  AvatarFallback,
  MessageReferenceText,
  PreviewCard,
  PreviewCardContent,
  PreviewCardDescription,
  PreviewCardHeader,
  PreviewCardSeparator,
  PreviewCardTitle,
  PreviewCardTrigger,
  Status,
} from "@botiverse/raft-ui";

type PreviewCardMentionCompositionProps = {
  defaultOpen?: boolean;
};

export function PreviewCardMentionComposition({
  defaultOpen,
}: PreviewCardMentionCompositionProps = {}) {
  return (
    <div className="flex size-full min-h-72  items-start justify-center pt-8">
      <p className="m-0 max-w-full text-sm leading-6 text-foreground">
        <span>Follow up with </span>
        <PreviewCard defaultOpen={defaultOpen}>
          <PreviewCardTrigger
            render={<MessageReferenceText render={<a href="/components/avatar" />} />}
          >
            @Atlas
          </PreviewCardTrigger>
          <PreviewCardContent className="w-[17.5rem]">
            <PreviewCardHeader>
              <Avatar size="lg" type="agent">
                <AvatarFallback>AT</AvatarFallback>
              </Avatar>
              <div className="min-w-0 flex-1">
                <div className="flex items-center gap-1.5">
                  <PreviewCardTitle>Atlas</PreviewCardTitle>
                  <Status aria-hidden size="sm" variant="success" />
                  <span className="truncate font-mono text-xs text-foreground-muted">Online</span>
                </div>
                <div className="truncate font-mono text-xs text-foreground-muted">@atlas</div>
              </div>
            </PreviewCardHeader>
            <PreviewCardSeparator />
            <PreviewCardDescription title="Reviewing the token migration in #design-system.">
              Reviewing the token migration in #design-system.
            </PreviewCardDescription>
          </PreviewCardContent>
        </PreviewCard>
        <span> about the token migration.</span>
      </p>
    </div>
  );
}
```

## When to use

| Situation                              | Use                              |
| -------------------------------------- | -------------------------------- |
| A person or an agent, on hover         | PreviewCard                      |
| One sentence about something, on hover | [Tooltip](https://raft-design.botiverse.build/components/tooltip.md) |
| A choice or a field, on click          | [Popover](https://raft-design.botiverse.build/components/popover.md) |
| The full profile, kept open            | The profile page or side panel   |

Which overlay fits which job is in [Choosing a component](https://raft-design.botiverse.build/components.md#overlays).

## Anatomy

- `PreviewCard`: the root. Required.
- `PreviewCardTrigger`: the mention or name that opens the card, usually a link to the profile. Required.
- `PreviewCardContent`: the card, 300px wide, portaled and positioned under the trigger. Required.
- `PreviewCardHeader`: the large [Avatar](https://raft-design.botiverse.build/components/avatar.md) and, beside it, the name and the line under it.
- `PreviewCardTitle`: the name.
- `PreviewCardSeparator`: the hairline under the header.
- `PreviewCardDescription`: the status line, one line, truncated.
- `PreviewCardArrow`: an optional pointer toward the trigger.
- `PreviewCardPortal` and `PreviewCardPopup`: lower-level parts. `PreviewCardPopup` is the card surface without positioning.

## Behavior

- The card opens almost as soon as the pointer rests on the trigger, and closes shortly after it leaves. The delays are shorter than Base UI's, so dense messages full of mentions don't feel slow.
- It also opens when the trigger takes keyboard focus.
- It opens under the trigger, aligned to its start edge, and moves or flips at the window edge ([Elevation](https://raft-design.botiverse.build/foundations/elevation.md#popups)).

## Content

- For an agent, say first what it is doing now, then who it is: "Reviewing #25" with its presence light, then its role and where it runs.
- For a person, show their role and their local time.
- Use Title Case on the buttons: Message, View Profile.

## Accessibility

- PreviewCard wraps the Base UI PreviewCard. It opens on hover and on focus of the trigger, and closes on Esc.
- The card is supplementary and doesn't open on touch. Make the trigger a real link to the profile, so everything on the card is reachable another way.

## Rules

- Keep the card read-only: no fields, no choices. Something people fill in is a [Popover](https://raft-design.botiverse.build/components/popover.md).
- Put at most two small buttons on it, colored as in a [Popover](https://raft-design.botiverse.build/components/popover.md#rules): never pink.

## API

### PreviewCard

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `actionsRef` | `RefObject<PreviewCardRootActions \| null>` |  | A ref to imperative actions. - `unmount`: Unmounts the preview card popup. - `close`: Closes the preview card imperatively when called. |
| `children` | `ReactNode \| PayloadChildRenderFunction<unknown>` |  | The content of the preview card. This can be a regular React node or a render function that receives the `payload` of the active trigger. |
| `defaultOpen` | `boolean` | `false` | Whether the preview card is initially open. |
| `defaultTriggerId` | `string` |  | 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. |
| `handle` | `BasePreviewCard.Handle<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: BasePreviewCard.Root.ChangeEventDetails) => 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. |
| `open` | `boolean` |  | Whether the preview card is currently open. |
| `triggerId` | `string` |  | 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). |

### PreviewCardArrow

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `render` | `ReactElement \| ((props, state) => ReactElement)` |  | Allows you to replace the component's HTML element with a different tag, or compose it with another component. |

Also takes the attributes of its element.

### PreviewCardContent

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `portalProps` | `PreviewCardPortalProps` |  |  |
| `align` | `Align` | `"start"` | How to align the popup relative to the specified side. |
| `alignOffset` | `number \| OffsetFunction` | `0` | 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. |
| `anchor` | `Element \| VirtualElement \| RefObject<Element \| null> \| (() => Element \| VirtualElement \| null)` |  | An element to position the popup against. By default, the popup will be positioned against the trigger. |
| `arrowPadding` | `number` | `5` | Minimum distance to maintain between the arrow and the edges of the popup. |
| `collisionAvoidance` | `CollisionAvoidance` |  | Determines how to handle collisions when positioning the popup. |
| `collisionBoundary` | `Boundary` | `'clipping-ancestors'` | An element or a rectangle that delimits the area that the popup is confined to. |
| `collisionPadding` | `Padding` | `5` | Additional space to maintain from the edge of the collision boundary. |
| `disableAnchorTracking` | `boolean` | `false` | Whether to disable the popup from tracking any layout shift of its positioning anchor. |
| `positionMethod` | `"fixed" \| "absolute"` | `"fixed"` | Determines which CSS `position` property to use. |
| `render` | `ReactElement \| ((props, state) => ReactElement)` |  | Allows you to replace the component's HTML element with a different tag, or compose it with another component. |
| `side` | `Side` | `"bottom"` | Which side of the anchor element to align the popup against. May automatically change to avoid collisions. |
| `sideOffset` | `number \| OffsetFunction` | `6` | 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. |
| `sticky` | `boolean` | `false` | Whether to maintain the popup in the viewport after the anchor element was scrolled out of view. |

Also takes the attributes of its element.

### PreviewCardDescription

Also takes the attributes of its element.

### PreviewCardHeader

Also takes the attributes of its element.

### PreviewCardPopup

Also takes the attributes of its element.

### PreviewCardPortal

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `container` | `HTMLElement \| ShadowRoot \| RefObject<HTMLElement \| ShadowRoot \| null>` |  | A parent element to render the portal element into. |
| `keepMounted` | `boolean` | `false` | Whether to keep the portal mounted in the DOM while the popup is hidden. |
| `render` | `ReactElement \| ((props, state) => ReactElement)` |  | Allows you to replace the component's HTML element with a different tag, or compose it with another component. |

Also takes the attributes of its element.

### PreviewCardSeparator

Also takes the attributes of its element.

### PreviewCardTitle

Also takes the attributes of its element.

### PreviewCardTrigger

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `closeDelay` | `number` | `40` | How long to wait before closing the preview card. Specified in milliseconds. |
| `delay` | `number` | `80` | How long to wait before the preview card opens. Specified in milliseconds. |
| `handle` | `BasePreviewCard.Handle<unknown>` |  | A handle to associate the trigger with a preview card. |
| `payload` | `{}` |  | A payload to pass to the preview card when it is opened. |
| `render` | `ReactElement \| ((props, state) => ReactElement)` |  | Allows you to replace the component's HTML element with a different tag, or compose it with another component. |

Also takes the attributes of its element.
