# HoverCard

A preview card that opens on hover or keyboard focus of a link (a user, a repository, an item) and shows more about the target. Sighted mouse users get a preview; the link still works alone. Use Tooltip for a short label, Popover for content opened by a click that holds controls.

## Usage

### When to use

- Show read-only details about a linked person or item when a mouse user hovers or a keyboard user focuses it.
- Keep the link useful on touch, where tapping follows the destination without opening the preview.

### When not to use

- A short label for a control. Use Tooltip.
- A panel with buttons, fields or other controls. Use Popover.

## Variants

### side

On HoverCardContent: preferred side; flips when there is no room.

Values: `top`, `right`, `bottom`, `left`. Default: `bottom`.

### align

On HoverCardContent: alignment along the trigger.

Values: `start`, `center`, `end`. Default: `center`.

## Examples

### User preview

```tsx
<HoverCard>
  <HoverCardTrigger asChild>
    <Link href="#khanh">Khanh Nguyen</Link>
  </HoverCardTrigger>
  <HoverCardContent>
    <div className="flex items-start gap-md">
      <Avatar alt="" size="lg">KN</Avatar>
      <div className="flex flex-col gap-xs">
        <p className="text-sm font-medium">Khanh Nguyen</p>
        <p className="text-sm text-text-secondary">Product designer</p>
      </div>
    </div>
  </HoverCardContent>
</HoverCard>
```

### Project preview

```tsx
<HoverCard>
  <HoverCardTrigger asChild>
    <Link href="#workspace">Workspace</Link>
  </HoverCardTrigger>
  <HoverCardContent side="right" align="start">
    <p className="text-sm font-medium">Workspace</p>
    <p className="text-sm text-text-secondary">Shared files and project notes for your team.</p>
    <Badge>Private</Badge>
  </HoverCardContent>
</HoverCard>
```

### Short delay

The card opens after 200ms and closes after 100ms. A touch tap still follows the link.

```tsx
<HoverCard openDelay={200} closeDelay={100}>
  <HoverCardTrigger asChild>
    <Link href="#report">Quarterly report</Link>
  </HoverCardTrigger>
  <HoverCardContent side="top" align="end" sideOffset={8}>
    <p className="text-sm font-medium">Quarterly report</p>
    <p className="text-sm text-text-secondary">Review the latest project updates before opening the document.</p>
  </HoverCardContent>
</HoverCard>
```

## Do and don't

### Do

- Keep the content read-only.
- Grow from the trigger side (origin by side), exit with animate-exit-scale.

### Don't

- Do not put buttons or forms inside; use Popover.
- Do not use on buttons; only links.

## Props

| Name | Type | Values | Default | Description |
| --- | --- | --- | --- | --- |
| `open` | `boolean` |  |  | Open state when controlled. |
| `defaultOpen` | `boolean` |  | `false` | Initial open state. |
| `onOpenChange` | `(open: boolean) => void` |  |  | Called when it opens or closes. |
| `openDelay` | `number` |  | `600` | Milliseconds before opening. |
| `closeDelay` | `number` |  | `300` | Milliseconds before closing. |
| `side` | `enum` | `top`, `right`, `bottom`, `left` | `bottom` | On HoverCardContent: preferred side; flips when there is no room. |
| `align` | `enum` | `start`, `center`, `end` | `center` | On HoverCardContent: alignment along the trigger. |
| `sideOffset` | `number` |  | `4` | On HoverCardContent: distance from the trigger in px. |
| `asChild` | `boolean` |  | `false` | On HoverCardTrigger: apply hover and focus behavior to one real link child. Use true for Link or a. |
| `alignOffset` | `number` |  | `0` | On HoverCardContent: offset along the alignment axis in px. |
| `avoidCollisions` | `boolean` |  | `true` | On HoverCardContent: shift or flip the preview to keep it in the viewport. |
| `collisionPadding` | `number \| Partial<Record<"top" \| "right" \| "bottom" \| "left", number>>` |  | `8` | On HoverCardContent: minimum distance from viewport edges in px. |

### Slots

| Name | Required | Description |
| --- | --- | --- |
| `trigger` | yes | The link that opens the card. |
| `content` | yes | Preview content: Avatar, name, short text, Metadata. |

## Anatomy

| Part | Description |
| --- | --- |
| `root` | HoverCard: holds open state, renders nothing. |
| `trigger` | HoverCardTrigger: a link, usually Link with asChild. |
| `content` | HoverCardContent: read-only floating card, 320px wide by default, on the popover stacking layer. |

## Accessibility

Role: `none`

| Keys | Action |
| --- | --- |
| `Tab` | Focus on the trigger opens the card after openDelay; leaving focus closes it after closeDelay. |
| `Escape` | Closes the card; focus stays on the trigger. |

- The content is supplementary: it is not in the tab order and must not hold the only path to an action.
- The trigger is a real link; the card does not change its name. Put the essential info in the link text.
- On touch there is no hover: a tap follows the link and the card does not open.
- The card stays open while the pointer moves from the trigger into it.

## Install

```bash
npx werewolf-ui add hover-card
```

Run `npx werewolf-ui init` once in your app before adding components. Init sets up tokens, their CSS import and agent rules. Add installs this component and its dependencies while preserving your theme. See [Installation](https://werewolf-ui.vercel.app/docs/installation.md) for requirements and the alternative registry setup.
