Ir al contenido
Superposiciones

HoverCard

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

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.

La factura 0012 salió a nombre de Acme S.A. y vence el 30/09.

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.

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

Generadas del TypeScript del paquete. Las propias del componente, más las heredadas del primitivo que tienen algo que explicar —marcadas «heredada de Base UI»—. El resto está en la línea «hereda de».

HoverCard

Hereda las props de PreviewCard.Root.

PropTipoPor defectoDescripción
actionsRefReact.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.
defaultOpenboolean—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.
openboolean—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.

PropTipoPor defectoDescripción
align"center" | "end" | "start""center"Cómo se alinea el panel sobre el eje transversal.
alignOffsetnumber | OffsetFunction0Corrimiento 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.
sideOffsetnumber | OffsetFunction8Distancia en píxeles entre el ancla y el panel.
classNamestring—Se fusiona con las clases del componente vía cn() (tailwind-merge): lo que pongas gana.

HoverCardHeader

Hereda las props de <div>.

PropTipoPor defectoDescripción
classNamestring—Se fusiona con las clases del componente vía cn() (tailwind-merge): lo que pongas gana.

HoverCardTrigger

Hereda las props de PreviewCard.Trigger.

PropTipoPor defectoDescripción
closeDelaynumber300Cuánto espera antes de cerrar, en ms.
delaynumber600Cuánto espera antes de abrir, en ms.
classNamestring—Se fusiona con las clases del componente vía cn() (tailwind-merge): lo que pongas gana.

Teclado

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