# HoverCard

> Una tarjeta con el adelanto de un link, al pasar el mouse. Nunca contenido crítico.

```tsx
import { HoverCard, HoverCardContent, HoverCardHeader, HoverCardTrigger } from "sebs7n-ui/hover-card"
```

## Ejemplos

### El adelanto de un cliente

El trigger es un `<a>`: se le pasa `href` derecho. Todo lo que está en la tarjeta está también del otro lado del link, porque en un celular la tarjeta no existe.

```tsx
import { Avatar, AvatarFallback } from "sebs7n-ui/avatar"
import { Badge } from "sebs7n-ui/badge"
import { HoverCard, HoverCardContent, HoverCardHeader, HoverCardTrigger } from "sebs7n-ui/hover-card"
import { linkVariants } from "sebs7n-ui/variants/link"

function Basico() {
  return (
    <p className="max-w-sm text-callout text-label">
      La factura 0012 salió a nombre de{" "}
      <HoverCard>
        <HoverCardTrigger className={linkVariants({ variant: "inline" })} href="#">
          Acme S.A.
        </HoverCardTrigger>
        <HoverCardContent>
          <HoverCardHeader>
            <Avatar>
              <AvatarFallback>AC</AvatarFallback>
            </Avatar>
            <div className="flex min-w-0 flex-col">
              <span className="text-headline text-label">Acme S.A.</span>
              <span className="text-callout text-label-secondary">CUIT 30-71234567-8</span>
            </div>
          </HoverCardHeader>
          <div className="flex items-center gap-2">
            <Badge color="green" size="sm">
              Al día
            </Badge>
            <span className="text-callout text-label-secondary">12 facturas · $ 1.284.000</span>
          </div>
        </HoverCardContent>
      </HoverCard>{" "}
      y vence el 30/09.
    </p>
  )
}
```

### Los dos retardos

`delay` evita que se dispare al pasar de largo; `closeDelay` da tiempo a llegar con el mouse hasta la tarjeta. El de abajo abre casi en el acto: se nota la diferencia moviendo el mouse por la línea.

```tsx
import { HoverCard, HoverCardContent, HoverCardTrigger } from "sebs7n-ui/hover-card"
import { linkVariants } from "sebs7n-ui/variants/link"

function Retardos() {
  const ficha = (
    <HoverCardContent side="top">
      <span className="text-headline text-label">Plan Pro</span>
      <span className="text-body text-label-secondary">
        Usuarios ilimitados, facturación electrónica y soporte en 24 h. $ 18.400 por mes.
      </span>
    </HoverCardContent>
  )
  return (
    <div className="flex max-w-sm flex-col gap-3 text-callout text-label">
      <span>
        Por defecto, 600 ms para abrir:{" "}
        <HoverCard>
          <HoverCardTrigger className={linkVariants({ variant: "inline" })} href="#">
            Plan Pro
          </HoverCardTrigger>
          {ficha}
        </HoverCard>
      </span>
      <span>
        Con 100 ms:{" "}
        <HoverCard>
          <HoverCardTrigger className={linkVariants({ variant: "inline" })} closeDelay={100} delay={100} href="#">
            Plan Pro
          </HoverCardTrigger>
          {ficha}
        </HoverCard>
      </span>
    </div>
  )
}
```

## Props

### HoverCard

Hereda las props de `PreviewCard.Root`.

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `actionsRef` | `React.RefObject<PreviewCardRoot.Actions \| null>` | — | **Heredada de Base UI.** Ref con las acciones imperativas de Base UI (`unmount()`), para desmontarlo sin esperar la animación de salida. |
| `defaultOpen` | `boolean` | — | **Heredada de Base UI.** Si arranca abierto. Es la versión no controlada de `open`. |
| `onOpenChange` | `((open: boolean, eventDetails: PreviewCardRoot.ChangeEventDetails) => void)` | — | **Heredada de Base UI.** Se llama con el estado nuevo cada vez que se abre o se cierra. |
| `open` | `boolean` | — | **Heredada de Base UI.** Si está abierto. Pasarla lo vuelve controlado: sin `onOpenChange` ya no se cierra solo. |

### HoverCardContent

Hereda las props de `PreviewCard.Popup` y `PreviewCard.Positioner`.

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `align` | `"center" \| "end" \| "start"` | `"center"` | Cómo se alinea el panel sobre el eje transversal. |
| `alignOffset` | `number \| OffsetFunction` | `0` | Corrimiento en píxeles sobre el eje de alineación. |
| `side` | `"left" \| "right" \| "top" \| "bottom" \| "inline-end" \| "inline-start"` | `"bottom"` | De qué lado del ancla se abre el panel. |
| `sideOffset` | `number \| OffsetFunction` | `8` | Distancia en píxeles entre el ancla y el panel. |
| `className` | `string` | — | Se fusiona con las clases del componente vía `cn()` (tailwind-merge): lo que pongas gana. |

### HoverCardHeader

Hereda las props de `<div>`.

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `className` | `string` | — | Se fusiona con las clases del componente vía `cn()` (tailwind-merge): lo que pongas gana. |

### HoverCardTrigger

Hereda las props de `PreviewCard.Trigger`.

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `closeDelay` | `number` | `300` | Cuánto espera antes de cerrar, en ms. |
| `delay` | `number` | `600` | Cuánto espera antes de abrir, en ms. |
| `className` | `string` | — | Se fusiona con las clases del componente vía `cn()` (tailwind-merge): lo que pongas gana. |

## Teclado

| Tecla | Qué hace |
|---|---|
| Tab | Enfocar el link la abre. |
| Escape | Cierra y deja el foco en el link. |

## Accesibilidad

- **En táctil no existe.** No hay hover y un toque navega: todo lo que esté en la tarjeta tiene que estar también del otro lado del link.
- El trigger es un `<a>`: se le pasa `href`, no `render={<Button />}`.
- Abre también con el foco del teclado, no solo con el mouse.
- El retardo de apertura (600 ms) existe para no dispararla al pasar de largo; el de cierre (300 ms) para poder llegar con el mouse.

## Reglas de uso

- **Un adelanto, nunca la información.** Si el contenido es el dato, va en la página.
- Si hace falta interactuar con algo, es un `Popover`: abre con click y se cierra con Escape en cualquier dispositivo.
- Si es una línea que aclara un control, es un `Tooltip`.
- No la cargues: una ficha, no una pantalla. Mide 256 px (`w-64`): si no entra, sobra algo.

## Relacionados

[popover](/docs/components/popover.md) · [tooltip](/docs/components/tooltip.md) · [avatar](/docs/components/avatar.md)
