# Hover Card

A preview card that appears when hovering a link.

Source: [hover-card.tsx](https://github.com/jakejarvis/jarvis-ui/blob/main/src/components/ui/hover-card.tsx)

```tsx
import { CalendarDaysIcon } from "lucide-react";

import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/ui/hover-card";
import { people, preventNavigation } from "@/examples/data";

export default function HoverCardBasic() {
  return (
    <p className="text-sm text-muted-foreground">
      Assigned to{" "}
      <HoverCard>
        <HoverCardTrigger
          href="#"
          onClick={preventNavigation}
          className="font-medium text-link underline-offset-2 hover:underline"
        >
          @adapark
        </HoverCardTrigger>
        <HoverCardContent align="start">
          <div className="flex gap-3">
            <Avatar size="lg">
              <AvatarImage src={people[0].image} alt="" />
              <AvatarFallback>AP</AvatarFallback>
            </Avatar>
            <div className="flex min-w-0 flex-col gap-1">
              <p className="text-sm font-medium">Ada Park</p>
              <p className="text-sm text-muted-foreground">
                Product designer working on the website redesign.
              </p>
              <p className="flex items-center gap-1.5 pt-1 text-xs text-faint">
                <CalendarDaysIcon className="size-3.5" />
                Joined March 2024
              </p>
            </div>
          </div>
        </HoverCardContent>
      </HoverCard>{" "}
      and due Friday.
    </p>
  );
}
```

## Installation

Add the registry, once per project:

```bash
npx shadcn@latest registry add @jarvis=https://ui.jarv.is/r/{name}.json
```

Then add the component:

```bash
npx shadcn@latest add @jarvis/hover-card
```

## Usage

```tsx
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/ui/hover-card";

export function ProjectLink() {
  return (
    <HoverCard>
      <HoverCardTrigger href="/projects/website-redesign">Website redesign</HoverCardTrigger>
      <HoverCardContent>
        <p className="font-medium">Website redesign</p>
        <p className="text-muted-foreground">18 of 28 tasks done.</p>
      </HoverCardContent>
    </HoverCard>
  );
}
```

`HoverCardTrigger` renders a link. Keyboard, touch and screen reader users can't reach the card, so
don't put anything in it that isn't also on the linked page.

## Composition

- `HoverCard`
  - `HoverCardTrigger`
  - `HoverCardContent`

## Examples

### Delay and placement

`delay` and `closeDelay` on `HoverCardTrigger` set the timing. `side` and `align` on
`HoverCardContent` set its position.

```tsx
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/ui/hover-card";
import { preventNavigation } from "@/examples/data";

export default function HoverCardDelay() {
  return (
    <p className="text-sm text-muted-foreground">
      Part of{" "}
      <HoverCard>
        <HoverCardTrigger
          href="#"
          onClick={preventNavigation}
          delay={150}
          closeDelay={100}
          className="font-medium text-link underline-offset-2 hover:underline"
        >
          Website redesign
        </HoverCardTrigger>
        <HoverCardContent side="top">
          <p className="font-medium">Website redesign</p>
          <p className="text-muted-foreground">
            Refresh the marketing site with the new brand. 18 of 28 tasks done.
          </p>
        </HoverCardContent>
      </HoverCard>
      .
    </p>
  );
}
```

## Props

| Part | Extends |
| --- | --- |
| `HoverCard` | [`PreviewCard.Root`](https://base-ui.com/react/components/preview-card#root) |
| `HoverCardTrigger` | [`PreviewCard.Trigger`](https://base-ui.com/react/components/preview-card#trigger) |
| `HoverCardContent` | [`PreviewCard.Popup`](https://base-ui.com/react/components/preview-card#popup) |

The tables leave out `className`, `style` and `render`. Parts built on Base UI take them as its [styling](https://base-ui.com/react/handbook/styling) and [composition](https://base-ui.com/react/handbook/composition) guides describe.

### HoverCard

| Prop                    | Type                                                                           | Description                                                                                                                                                                                                                                                                                                                                                                                        |
| ----------------------- | ------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `defaultOpen?`          | `boolean`                                                                      | Whether the preview card is initially open. To render a controlled preview card, use the `open` prop instead. Default: `false`                                                                                                                                                                                                                                                                     |
| `open?`                 | `boolean`                                                                      | Whether the preview card is currently open.                                                                                                                                                                                                                                                                                                                                                        |
| `onOpenChange?`         | `((open: boolean, eventDetails: PreviewCard.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.                                                                                                                                                                                                                                                                                                      |
| `actionsRef?`           | `React.RefObject<PreviewCardRootActions \| null>`                              | A ref to imperative actions. - `unmount`: Ends the closing phase of the preview card after an externally controlled closing animation finishes. Call `preventUnmountOnClose()` in `onOpenChange` first, otherwise the preview card completes closing on its own. Whether it leaves the DOM is decided by `keepMounted` on the portal. - `close`: Closes the preview card imperatively when called. |
| `handle?`               | `PreviewCard.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.                                                                                                                                                                                                         |
| `children?`             | `PayloadChildRenderFunction<unknown> \| React.ReactNode`                       | 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.                                                                                                                                                                                                                                                          |
| `triggerId?`            | `string \| null`                                                               | 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).                                                                                                                         |
| `defaultTriggerId?`     | `string \| null`                                                               | 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.                                                                                                                                                                                                                                    |

### HoverCardTrigger

| Prop          | Type                          | Description                                                                                 |
| ------------- | ----------------------------- | ------------------------------------------------------------------------------------------- |
| `handle?`     | `PreviewCard.Handle<unknown>` | A handle to associate the trigger with a preview card.                                      |
| `payload?`    | `unknown`                     | A payload to pass to the preview card when it is opened.                                    |
| `delay?`      | `number`                      | How long to wait before the preview card opens. Specified in milliseconds. Default: `600`   |
| `closeDelay?` | `number`                      | How long to wait before closing the preview card. Specified in milliseconds. Default: `300` |

### HoverCardContent

| Prop           | Type                                                                       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| -------------- | -------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `side?`        | `"bottom" \| "inline-end" \| "inline-start" \| "left" \| "right" \| "top"` | Which side of the anchor element to align the popup against. May automatically change to avoid collisions. Default: `"bottom"`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `sideOffset?`  | `number \| OffsetFunction`                                                 | 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. The function takes a `data` object parameter with the following properties: - `data.anchor`: the dimensions of the anchor element with properties `width` and `height`. - `data.positioner`: the dimensions of the positioner element with properties `width` and `height`. - `data.side`: which side of the anchor element the positioner is aligned against. - `data.align`: how the positioner is aligned relative to the specified side. Default: `4` |
| `align?`       | `"center" \| "end" \| "start"`                                             | How to align the popup relative to the specified side. Default: `"center"`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `alignOffset?` | `number \| OffsetFunction`                                                 | 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. The function takes a `data` object parameter with the following properties: - `data.anchor`: the dimensions of the anchor element with properties `width` and `height`. - `data.positioner`: the dimensions of the positioner element with properties `width` and `height`. - `data.side`: which side of the anchor element the positioner is aligned against. - `data.align`: how the positioner is aligned relative to the specified side. Default: `0`  |
