# Preview Card Primitive

Preview Card is a Starwind Runtime primitive in the presence-floating-overlay contract family.
Astro and React share one semantic component API. React coordinates reactive state through controlled and default props plus callbacks. Astro renders initial state and coordinates later changes through DOM events and Runtime methods. Raw HTML uses Runtime attributes, DOM events, and imperative methods.
## Anatomy
### Astro
Use the Astro primitive adapter to render PreviewCard anatomy with the Runtime wiring included.
```astro
---
import { PreviewCard } from "@starwind-ui/astro/preview-card";
---

<PreviewCard.Root>
  <PreviewCard.Trigger>Preview profile</PreviewCard.Trigger>
  <PreviewCard.Positioner>
    <PreviewCard.Popup>
      <PreviewCard.Arrow />
    </PreviewCard.Popup>
  </PreviewCard.Positioner>
</PreviewCard.Root>
```

### React
Use the React primitive adapter when PreviewCard state participates in React rendering.
```tsx
import { PreviewCard } from "@starwind-ui/react/preview-card";

export function Example() {
  return (
    <PreviewCard.Root>
      <PreviewCard.Trigger>Preview profile</PreviewCard.Trigger>
      <PreviewCard.Positioner>
        <PreviewCard.Popup>
          <PreviewCard.Arrow />
        </PreviewCard.Popup>
      </PreviewCard.Positioner>
    </PreviewCard.Root>
  );
}
```

### HTML
Render the PreviewCard data-sw-* contract yourself, then initialize createPreviewCard.
```html
<div data-sw-preview-card>
  <button data-sw-preview-card-trigger type="button">Preview profile</button>
  <div data-sw-preview-card-positioner>
    <div data-sw-preview-card-popup role="tooltip" hidden>
      <div data-sw-preview-card-arrow></div>
    </div>
  </div>
</div>

<script type="module">
  import { createPreviewCard } from "@starwind-ui/runtime/preview-card";

  const root = document.querySelector("[data-sw-preview-card]");
  if (root) {
    createPreviewCard(root);
  }
</script>
```

### Vue
Use the Vue 3.5 beta adapter to render PreviewCard anatomy.
```vue
<script setup lang="ts">
import PreviewCard from "@starwind-ui/vue/preview-card";
</script>

<template>
  <PreviewCard.Root>
    <PreviewCard.Trigger>Preview profile</PreviewCard.Trigger>
    <PreviewCard.Positioner>
      <PreviewCard.Popup>
        <PreviewCard.Arrow />
      </PreviewCard.Popup>
    </PreviewCard.Positioner>
  </PreviewCard.Root>
</template>
```
## Floating Behavior
| Fact | Value |
| --- | --- |
| Anchor part | trigger |
| Positioner part | positioner |
| Popup part | popup |
| Portal part | portal |
| Option props | side, align, sideOffset, avoidCollisions |
## API Reference
### Root
The main element that owns the Preview Card Runtime instance.
| Fact | Value |
| --- | --- |
| Default element | `div` |
| Discovery hook | `data-sw-preview-card` |
| Role | - |
#### Props
| Prop | Type | Default | Kind | Description | Framework Behavior |
| --- | --- | --- | --- | --- | --- |
| open | `boolean` | - | control | Controls whether Preview Card is open. | **React:** Use open for controlled state and defaultOpen for default state, and onOpenChange for change proposals.<br>**Astro:** Use open or defaultOpen for initial state, listen for starwind:open-change, and call setOpen for later updates.<br>**Runtime / HTML:** Use data-default-open for initial state, listen for starwind:open-change, and call setOpen for later updates. |
| defaultOpen | `boolean` | false | control | Sets whether Preview Card starts open. | **React:** Use open for controlled state and defaultOpen for default state, and onOpenChange for change proposals.<br>**Astro:** Use open or defaultOpen for initial state, listen for starwind:open-change, and call setOpen for later updates.<br>**Runtime / HTML:** Use data-default-open for initial state, listen for starwind:open-change, and call setOpen for later updates. |
| closeDelay | `number` | 300 | option | Sets how long Preview Card waits before closing. | - |
| closeOnEscape | `boolean` | true | option | Closes Preview Card when Escape is pressed. | - |
| closeOnOutsideInteract | `boolean` | true | option | Closes Preview Card when the user interacts outside it. | - |
| disableHoverableContent | `boolean` | false | option | Configures the disable hoverable content option for the Root part. | - |
| openDelay | `number` | 600 | option | Sets how long Preview Card waits before opening. | - |
| onOpenChange | `(open: boolean, details: PreviewCardOpenChangeDetails) => void` | - | callback | Runs when Preview Card opens or closes. | **React:** Use open for controlled state and defaultOpen for default state, and onOpenChange for change proposals.<br>**Astro:** Use open or defaultOpen for initial state, listen for starwind:open-change, and call setOpen for later updates.<br>**Runtime / HTML:** Use data-default-open for initial state, listen for starwind:open-change, and call setOpen for later updates. |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-preview-card` | runtime | - | Marks the Root part so Starwind Runtime can find it. |
| `data-default-open` | prop | - | Reflects the default open prop on the Root part. |
| `data-close-delay` | prop | - | Reflects the close delay prop on the Root part. |
| `data-close-on-escape` | prop | - | Reflects the close on escape prop on the Root part. |
| `data-close-on-outside-interact` | prop | - | Reflects the close on outside interact prop on the Root part. |
| `data-content-hoverable` | prop | - | Reflects the content hoverable prop on the Root part. |
| `data-open-delay` | prop | - | Reflects the open delay prop on the Root part. |
| `data-state` | state | - | Reflects the current state on the Root part. |
#### State
| State | Value Type | Controlled Prop | Default Prop | Initial Attribute | Runtime Getter | Runtime Setter | Description | State Control Support |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| open | `boolean` | open | defaultOpen | `data-default-open` | `getOpen` | `setOpen` | Tracks whether Preview Card is open. | **React:** Use open for controlled state and defaultOpen for default state, and onOpenChange for change proposals.<br>**Astro:** Use open or defaultOpen for initial state, listen for starwind:open-change, and call setOpen for later updates.<br>**Runtime / HTML:** Use data-default-open for initial state, listen for starwind:open-change, and call setOpen for later updates. |
#### Events
| Event | Callback | DOM Event | Value | Details | Timing | Cancelable | Description | Cancellation Sequence |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| openChange | onOpenChange | starwind:open-change | open: `boolean` | PreviewCardOpenChangeDetails | before-state-commit | Yes | Fires when Preview Card opens or closes. | 1. Check internal eligibility and intent.<br>2. Create one details object for the proposal.<br>3. Call the Runtime callback with the details object when the controller exposes one.<br>4. Dispatch the cancelable DOM event with the same details object, including when the callback canceled it.<br>5. Read details.isCanceled, including cancellation caused by preventDefault().<br>6. Apply the accepted state.<br>7. Notify Runtime subscribers and other accepted-only observers. |
#### Runtime Setters
| Method | Target | Options | Suppresses Emit | Description |
| --- | --- | --- | --- | --- |
| `setOpen` | state: open | emit: false | Yes | Opens or closes Preview Card from Runtime code. |
#### Refs
| Part | Public |
| --- | --- |
| root | Yes |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-preview-card`, `data-default-open`, `data-close-delay`, `data-close-on-escape`, `data-close-on-outside-interact`, `data-content-hoverable`, `data-open-delay`, `data-state` | The preview card root needs timing, dismissal, hoverability, and initial state markers before hydration. |
#### Presence
| Fact | Value |
| --- | --- |
| Initial hidden | No |
| Unmount policy | runtime-owned |
| Keep mounted prop | - |

### Trigger
The control that opens, closes, or targets the Preview Card content.
| Fact | Value |
| --- | --- |
| Default element | `button` |
| Discovery hook | `data-sw-preview-card-trigger` |
| Role | - |
#### Props
| Prop | Type | Default | Kind | Description | Framework Behavior |
| --- | --- | --- | --- | --- | --- |
| asChild | `boolean` | - | rendering | Merges behavior onto your child element instead of rendering the default Trigger element. | - |
| disabled | `boolean` | false | option | Disables the Trigger part. | - |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-preview-card-trigger` | runtime | - | Marks the Trigger part so Starwind Runtime can find it. |
| `data-as-child` | prop | - | Reflects the as child prop on the Trigger part. |
| `data-close-delay` | prop | - | Reflects the close delay prop on the Trigger part. |
| `data-disabled` | prop | - | Reflects the disabled prop on the Trigger part. |
| `data-open-delay` | prop | - | Reflects the open delay prop on the Trigger part. |
| `data-state` | state | - | Reflects the current state on the Trigger part. |
#### Refs
| Part | Public |
| --- | --- |
| trigger | Yes |
#### asChild
| Part | Merged Props |
| --- | --- |
| trigger | aria, className, data, ref |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-preview-card-trigger`, `data-as-child`, `data-close-delay`, `data-disabled`, `data-open-delay`, `aria-disabled`, `data-state`, `disabled`, `type` | Triggers need delay overrides, disabled state, and initial closed state before pointer/focus listeners attach. |

### Portal
Moves Preview Card overlay content to the document body when needed.
| Fact | Value |
| --- | --- |
| Default element | `div` |
| Discovery hook | `data-sw-preview-card-portal` |
| Role | - |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-preview-card-portal` | runtime | - | Marks the Portal part so Starwind Runtime can find it. |
| `data-container` | prop | - | Reflects the container prop on the Portal part. |
| `data-disabled` | prop | - | Reflects the disabled prop on the Portal part. |
| `data-sw-portal-placement` | constant | `runtime` | Identifies Portal metadata for styling and selectors. |
| `data-placement` | runtime | - | Marks the Portal part so Starwind Runtime can find it. |
#### Refs
| Part | Public |
| --- | --- |
| portal | Yes |

### Positioner
Positions the Preview Card content relative to its trigger.
| Fact | Value |
| --- | --- |
| Default element | `div` |
| Discovery hook | `data-sw-preview-card-positioner` |
| Role | - |
#### Props
| Prop | Type | Default | Kind | Description | Framework Behavior |
| --- | --- | --- | --- | --- | --- |
| side | `"top" \| "right" \| "bottom" \| "left"` | "bottom" | option | Sets the preferred side for Preview Card content. | - |
| align | `"start" \| "center" \| "end"` | "center" | option | Sets how Preview Card content aligns to its trigger. | - |
| sideOffset | `number` | 0 | option | Sets the distance between Preview Card content and its trigger. | - |
| avoidCollisions | `boolean` | true | option | Allows Preview Card content to shift or flip to stay visible. | - |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-preview-card-positioner` | runtime | - | Marks the Positioner part so Starwind Runtime can find it. |
| `data-state` | state | - | Reflects the current state on the Positioner part. |
| `data-side` | prop | - | Reflects the side prop on the Positioner part. |
| `data-align` | prop | - | Reflects the align prop on the Positioner part. |
| `data-side-offset` | prop | - | Reflects the side offset prop on the Positioner part. |
| `data-avoid-collisions` | prop | - | Reflects the avoid collisions prop on the Positioner part. |
#### Refs
| Part | Public |
| --- | --- |
| positioner | Yes |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-preview-card-positioner`, `data-state`, `data-side`, `data-align`, `data-side-offset`, `data-avoid-collisions` | The positioner carries initial placement hints used by the shared floating runtime. |

### Popup
The floating content container for Preview Card.
| Fact | Value |
| --- | --- |
| Default element | `div` |
| Discovery hook | `data-sw-preview-card-popup` |
| Role | `tooltip` |
#### Props
| Prop | Type | Default | Kind | Description | Framework Behavior |
| --- | --- | --- | --- | --- | --- |
| side | `"top" \| "right" \| "bottom" \| "left"` | "bottom" | option | Sets the preferred side for Preview Card content. | - |
| align | `"start" \| "center" \| "end"` | "center" | option | Sets how Preview Card content aligns to its trigger. | - |
| sideOffset | `number` | 0 | option | Sets the distance between Preview Card content and its trigger. | - |
| avoidCollisions | `boolean` | true | option | Allows Preview Card content to shift or flip to stay visible. | - |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-preview-card-popup` | runtime | - | Marks the Popup part so Starwind Runtime can find it. |
| `data-state` | state | - | Reflects the current state on the Popup part. |
| `data-side` | prop | - | Reflects the side prop on the Popup part. |
| `data-align` | prop | - | Reflects the align prop on the Popup part. |
| `data-side-offset` | prop | - | Reflects the side offset prop on the Popup part. |
| `data-avoid-collisions` | prop | - | Reflects the avoid collisions prop on the Popup part. |
#### Refs
| Part | Public |
| --- | --- |
| popup | Yes |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-preview-card-popup`, `role`, `data-state`, `data-side`, `data-align`, `data-side-offset`, `data-avoid-collisions`, `hidden` | The preview card popup starts hidden with tooltip semantics and initial placement hints before hydration. |
#### Presence
| Fact | Value |
| --- | --- |
| Initial hidden | Yes |
| Unmount policy | runtime-owned |
| Keep mounted prop | - |

### Arrow
The arrow element that visually points to the trigger.
| Fact | Value |
| --- | --- |
| Default element | `div` |
| Discovery hook | `data-sw-preview-card-arrow` |
| Role | - |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-preview-card-arrow` | runtime | - | Marks the Arrow part so Starwind Runtime can find it. |
| `data-state` | state | - | Reflects the current state on the Arrow part. |
#### Refs
| Part | Public |
| --- | --- |
| arrow | Yes |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-preview-card-arrow`, `data-state` | The optional arrow receives state and placement updates from the floating runtime. |

### Backdrop
The backdrop shown behind the Preview Card overlay.
| Fact | Value |
| --- | --- |
| Default element | `div` |
| Discovery hook | `data-sw-preview-card-backdrop` |
| Role | - |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-preview-card-backdrop` | runtime | - | Marks the Backdrop part so Starwind Runtime can find it. |
| `data-state` | state | - | Reflects the current state on the Backdrop part. |
#### Refs
| Part | Public |
| --- | --- |
| backdrop | Yes |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-preview-card-backdrop`, `data-state`, `hidden` | The optional backdrop starts hidden and receives runtime-owned visibility state. |
#### Presence
| Fact | Value |
| --- | --- |
| Initial hidden | Yes |
| Unmount policy | runtime-owned |
| Keep mounted prop | - |

### Viewport
The visible viewport for Preview Card content.
| Fact | Value |
| --- | --- |
| Default element | `div` |
| Discovery hook | `data-sw-preview-card-viewport` |
| Role | - |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-preview-card-viewport` | runtime | - | Marks the Viewport part so Starwind Runtime can find it. |
| `data-state` | state | - | Reflects the current state on the Viewport part. |
#### Refs
| Part | Public |
| --- | --- |
| viewport | Yes |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-preview-card-viewport`, `data-state` | The optional viewport receives state and placement updates from the floating runtime. |
## Runtime API
| Fact | Value |
| --- | --- |
| Factory | [`createPreviewCard`](/docs/runtime/#create-preview-card) |
| Import | `@starwind-ui/runtime/preview-card` |
| Root part | root |
| Option props | closeDelay, closeOnEscape, closeOnOutsideInteract, defaultOpen, disableHoverableContent, onOpenChange, open, openDelay |
| Option lifecycles | closeDelay: constructor-only, closeOnEscape: constructor-only, closeOnOutsideInteract: constructor-only, defaultOpen: constructor-only, disableHoverableContent: constructor-only, onOpenChange: constructor-only, open: setter-backed, openDelay: constructor-only |
## Related Styled Components
| Component | Relationship |
| --- | --- |
| [Hover Card](/docs/components/hover-card/) | Renamed Primitive |
## Exports
| Group | Import | Exports |
| --- | --- | --- |
| Runtime | `@starwind-ui/runtime/preview-card` | `createPreviewCard` |
| Astro Primitive | `@starwind-ui/astro/preview-card` | `PreviewCard`, `PreviewCardRoot`, `PreviewCardTrigger`, `PreviewCardPortal`, `PreviewCardPositioner`, `PreviewCardPopup`, `PreviewCardArrow`, `PreviewCardBackdrop`, `PreviewCardViewport` |
| React Primitive | `@starwind-ui/react/preview-card` | `PreviewCard`, `PreviewCardRoot`, `PreviewCardTrigger`, `PreviewCardPortal`, `PreviewCardPositioner`, `PreviewCardPopup`, `PreviewCardArrow`, `PreviewCardBackdrop`, `PreviewCardViewport` |
## Canonical Names
| Kind | Name |
| --- | --- |
| namespace | `PreviewCard` |
| runtime-factory | `createPreviewCard` |
| part | `PreviewCard.Root` |
| part | `PreviewCard.Trigger` |
| part | `PreviewCard.Portal` |
| part | `PreviewCard.Positioner` |
| part | `PreviewCard.Popup` |
| part | `PreviewCard.Arrow` |
| part | `PreviewCard.Backdrop` |
| part | `PreviewCard.Viewport` |
## Changelog
### v1.1.1
- Removed obsolete private-release warnings from generated Vue adapters and normalized the resulting blank line in vendored Primitive indexes.
### v1.1.0
- Added portable Portal container and disabled controls, with deterministic framework and Runtime placement reporting for nested floating content.
### v1.0.0
- Promoted this Primitive's vendoring version to the stable 1.0.0 baseline. Its existing API and Runtime behavior carry forward from the previous release.
### v0.1.1
- Marked generated React Primitive files as client modules so vendored installs preserve client boundaries in React server frameworks.
- Kept generated React state-change callbacks and DOM events cancelable until the Runtime accepts the proposed state, then synchronized rendered state.
### v0.1.0
- Introduced hover and focus timing, floating placement, presence, and dismissal for preview content.