# Hover Card

<div class="not-content sl-bejamas-component-preview flex justify-center px-4 md:px-10 py-12 border border-border rounded-t-lg min-h-72 items-center">
<HoverCard delay={10} closeDelay={100}> <HoverCardTrigger asChild> <Button variant="link">{"@data-slot"}</Button> </HoverCardTrigger> <HoverCardContent class="flex w-64 flex-col gap-0.5"> <div class="font-semibold">{"@data-slot"}</div> <div>{"Headless UI components for vanilla JavaScript."}</div> <div class="text-muted-foreground mt-1 text-xs">{" Created by Bejamas in 2026 "}</div> </HoverCardContent> </HoverCard>
</div>

```astro
---
---

<HoverCard delay={10} closeDelay={100}>
  <HoverCardTrigger asChild>
    <Button variant="link">@data-slot</Button>
  </HoverCardTrigger>
  <HoverCardContent class="flex w-64 flex-col gap-0.5">
    <div class="font-semibold">@data-slot</div>
    <div>Headless UI components for vanilla JavaScript.</div>
    <div class="text-muted-foreground mt-1 text-xs">
      Created by Bejamas in 2026
    </div>
  </HoverCardContent>
</HoverCard>
```

## Installation

<DocsTabs syncKey="pkg">
  <DocsTabItem label="bun">
  ```bash
  bunx bejamas add hover-card
  ```
  </DocsTabItem>
  <DocsTabItem label="npm">
  ```bash
  npx bejamas add hover-card
  ```
  </DocsTabItem>
  <DocsTabItem label="pnpm">
  ```bash
  pnpm dlx bejamas add hover-card
  ```
  </DocsTabItem>
  <DocsTabItem label="yarn">
  ```bash
  yarn dlx bejamas add hover-card
  ```
  </DocsTabItem>
</DocsTabs>

## Usage

```astro nocollapse
---
---

<HoverCard>
  <HoverCardTrigger asChild>
    <Button variant="link">Hover Here</Button>
  </HoverCardTrigger>
  <HoverCardContent>
    <div class="font-semibold">@nextjs</div>
    <div>The React Framework - created and maintained by @vercel.</div>
  </HoverCardContent>
</HoverCard>
```

## Props

| Prop | Type | Default |
|---|---|---|
| <code>class</code> | `string` | `""` |
| <code>defaultOpen</code> | `boolean` | `false` |
| <code>delay</code> | `number` | `700` |
| <code>skipDelayDuration</code> | `number` | `300` |
| <code>closeDelay</code> | `number` | `300` |
| <code>closeOnClickOutside</code> | `boolean` | `true` |
| <code>closeOnEscape</code> | `boolean` | `true` |

## Examples

### With Avatar

<div class="not-content sl-bejamas-component-preview flex justify-center px-4 md:px-10 py-12 border border-border rounded-t-lg min-h-72 items-center">
<HoverCard> <HoverCardTrigger asChild> <Button variant="link">@thom</Button> </HoverCardTrigger> <HoverCardContent class="flex w-72 gap-3 p-3"> <Avatar class="size-10 rounded-full"> <AvatarImage> <img src="https://github.com/thomkrupa.png" alt="@thom" /> </AvatarImage> <AvatarFallback>TK</AvatarFallback> </Avatar> <div class="space-y-1"> <div class="text-sm font-semibold leading-none">@thom</div> <p class="text-muted-foreground text-sm"> Building design systems and UI tooling. </p> </div> </HoverCardContent> </HoverCard>
</div>

```astro
---
---

<HoverCard>
  <HoverCardTrigger asChild>
    <Button variant="link">@thom</Button>
  </HoverCardTrigger>
  <HoverCardContent class="flex w-72 gap-3 p-3">
    <Avatar class="size-10 rounded-full">
      <AvatarImage>
        <img src="https://github.com/thomkrupa.png" alt="@thom" />
      </AvatarImage>
      <AvatarFallback>TK</AvatarFallback>
    </Avatar>
    <div class="space-y-1">
      <div class="text-sm font-semibold leading-none">@thom</div>
      <p class="text-muted-foreground text-sm">
        Building design systems and UI tooling.
      </p>
    </div>
  </HoverCardContent>
</HoverCard>
```

### Different sides

<div class="not-content sl-bejamas-component-preview flex justify-center px-4 md:px-10 py-12 border border-border rounded-t-lg min-h-72 items-center">
<div class="flex flex-wrap items-center gap-3 py-8"> <HoverCard delay={10} closeDelay={80} skipDelayDuration={0}> <HoverCardTrigger asChild> <Button variant="outline">{"Left"}</Button> </HoverCardTrigger> <HoverCardContent side="left">{"Appears on left."}</HoverCardContent> </HoverCard> <HoverCard delay={10} closeDelay={80} skipDelayDuration={0}> <HoverCardTrigger asChild> <Button variant="outline">{"Top"}</Button> </HoverCardTrigger> <HoverCardContent side="top">{"Appears on top."}</HoverCardContent> </HoverCard> <HoverCard delay={10} closeDelay={80} skipDelayDuration={0}> <HoverCardTrigger asChild> <Button variant="outline">{"Bottom"}</Button> </HoverCardTrigger> <HoverCardContent side="bottom">{"Appears on bottom."}</HoverCardContent> </HoverCard> <HoverCard delay={10} closeDelay={80} skipDelayDuration={0}> <HoverCardTrigger asChild> <Button variant="outline">{"Right"}</Button> </HoverCardTrigger> <HoverCardContent side="right">{"Appears on right."}</HoverCardContent> </HoverCard> </div>
</div>

```astro
---
---

<div class="flex flex-wrap items-center gap-3 py-8">
  <HoverCard delay={10} closeDelay={80} skipDelayDuration={0}>
    <HoverCardTrigger asChild>
      <Button variant="outline">Left</Button>
    </HoverCardTrigger>
    <HoverCardContent side="left">Appears on left.</HoverCardContent>
  </HoverCard>
  <HoverCard delay={10} closeDelay={80} skipDelayDuration={0}>
    <HoverCardTrigger asChild>
      <Button variant="outline">Top</Button>
    </HoverCardTrigger>
    <HoverCardContent side="top">Appears on top.</HoverCardContent>
  </HoverCard>
  <HoverCard delay={10} closeDelay={80} skipDelayDuration={0}>
    <HoverCardTrigger asChild>
      <Button variant="outline">Bottom</Button>
    </HoverCardTrigger>
    <HoverCardContent side="bottom">Appears on bottom.</HoverCardContent>
  </HoverCard>
  <HoverCard delay={10} closeDelay={80} skipDelayDuration={0}>
    <HoverCardTrigger asChild>
      <Button variant="outline">Right</Button>
    </HoverCardTrigger>
    <HoverCardContent side="right">Appears on right.</HoverCardContent>
  </HoverCard>
</div>
```

### Positioning options

Configure placement options on `HoverCardContent`:

<div class="not-content sl-bejamas-component-preview flex justify-center px-4 md:px-10 py-12 border border-border rounded-t-lg min-h-72 items-center">
<HoverCard> <HoverCardTrigger asChild> <Button variant="outline">{"Custom positioning"}</Button> </HoverCardTrigger> <HoverCardContent side="top" sideOffset={8} align="start" >{" Uses content-level positioning options. "}</HoverCardContent> </HoverCard>
</div>

```astro
---
---

<HoverCard>
  <HoverCardTrigger asChild>
    <Button variant="outline">Custom positioning</Button>
  </HoverCardTrigger>
  <HoverCardContent
    side="top"
    sideOffset={8}
    align="start"
  >
    Uses content-level positioning options.
  </HoverCardContent>
</HoverCard>
```

### Custom timing

<div class="not-content sl-bejamas-component-preview flex justify-center px-4 md:px-10 py-12 border border-border rounded-t-lg min-h-72 items-center">
<HoverCard delay={600} closeDelay={200} skipDelayDuration={300}> <HoverCardTrigger asChild> <Button variant="outline">{"Hover with delay"}</Button> </HoverCardTrigger> <HoverCardContent>{" Opens after 600ms, closes after 200ms. "}</HoverCardContent> </HoverCard>
</div>

```astro
---
---

<HoverCard delay={600} closeDelay={200} skipDelayDuration={300}>
  <HoverCardTrigger asChild>
    <Button variant="outline">Hover with delay</Button>
  </HoverCardTrigger>
  <HoverCardContent>
    Opens after 600ms, closes after 200ms.
  </HoverCardContent>
</HoverCard>
```

## API Reference

### Events

The hover card emits custom events that you can listen to:

| Event | Detail | Description |
|-------|--------|-------------|
| `hover-card:change` | `{ open: boolean, reason: string, trigger: HTMLElement, content: HTMLElement }` | Fired when visibility changes |

```astro nocollapse console
<HoverCard id="my-hover-card">
  <HoverCardTrigger asChild>
    <Button variant="outline">Hover me</Button>
  </HoverCardTrigger>
  <HoverCardContent>
    Hover card content
  </HoverCardContent>
</HoverCard>

<script>
  const hoverCard = document.getElementById('my-hover-card');

  hoverCard.addEventListener('hover-card:change', (e) => {
    console.log('Is open:', e.detail.open);
    console.log('Reason:', e.detail.reason);
  });
</script>
```

### Programmatic Control

You can control the hover card programmatically by dispatching a `hover-card:set` event:

```js nocollapse
const hoverCard = document.getElementById('my-hover-card');

// Open the hover card
hoverCard.dispatchEvent(new CustomEvent('hover-card:set', {
  detail: { open: true }
}));

// Close the hover card
hoverCard.dispatchEvent(new CustomEvent('hover-card:set', {
  detail: { open: false }
}));
```

### Data Attributes

The hover card sets these data attributes that you can use for styling or querying state:

| Attribute | Element | Description |
|-----------|---------|-------------|
| `data-state` | hover-card, hover-card-content | Current state (`open` or `closed`) |
| `data-open` | hover-card, hover-card-content | Present while open |
| `data-closed` | hover-card, hover-card-content | Present while closed |
| `data-side` | hover-card-content | Position relative to trigger (`top`, `right`, `bottom`, or `left`) |
| `data-align` | hover-card-content | Alignment (`start`, `center`, or `end`) |
| `data-side-offset` | hover-card-content | Distance from trigger in pixels (default `4`) |
| `data-align-offset` | hover-card-content | Alignment-axis offset in pixels (default `0`) |