Popover
Un panel flotante anclado a un trigger que se redimensiona suavemente con su contenido y sigue la dirección del trigger.
pnpm dlx shadcn@latest add https://hextaui.com/r/popover.jsonAñade el componente, los tokens del tema de HextaUI y los componentes de HextaUI de los que depende.
Añade los tokens del tema a tu CSS global, si aún no lo has hecho.
Instala las dependencias.
pnpm add @base-ui/react cnCopia y pega el siguiente código en tu proyecto.
components/ui/popover.tsx Actualiza las rutas de importación para que coincidan con la configuración de tu proyecto.
Contenido que cambia de tamaño
Cuando el contenido crece o se encoge, el popup anima su altura en lugar de saltar. Los cambios continuos, como escribir, siguen directamente al contenido para que nada se quede atrás.
Controlado
Pasa open y onOpenChange para controlarlo desde tu propio estado. El segundo argumento indica por qué cambió, como trigger-press, outside-press o escape-key.
Posición
side y align definen la posición preferida. Cuando no hay espacio, el popup se voltea al otro lado y se desplaza para seguir en pantalla, manteniendo 8px respecto a los bordes.
Abrir al pasar el cursor
Define openOnHover en el trigger para tarjetas de vista previa. delay y closeDelay evitan el parpadeo cuando el puntero pasa por encima.
Triggers desacoplados
Crea un handle con createPopoverHandle para compartir un popover entre varios triggers en cualquier punto del árbol. Cada trigger pasa un payload, y el popup lo renderiza mediante un hijo función.
Con un calendario
Usa className="w-auto p-0" para ajustar contenido que trae su propio relleno. El popup sigue al calendario cuando cambia de mes.
Anidado
Un popover dentro de otro popover o de un sheet se coloca por encima de su padre. Los clics dentro del hijo mantienen abierto al padre, y Escape cierra solo la capa superior.
Contenido largo
El texto sin espacios se ajusta dentro del popup. Cuando el contenido es más alto que el espacio disponible, el popup hace scroll en su interior en lugar de salirse de la pantalla.
Modal
Con modal, el scroll de la página se bloquea y los clics externos solo descartan el popover. Renderiza un <PopoverClose /> dentro para poder atrapar el foco y dar una salida a los lectores de pantalla táctiles.
Deshabilitado
Un trigger disabled nunca abre su popover.
De derecha a izquierda
El popup toma la dirección del trigger que lo abrió, aunque se renderice en un portal. Los lados lógicos como inline-end se invierten con ella.
| Key | Acción |
|---|---|
| EnterSpace | En el trigger, abre o cierra el popover. El foco se mueve al popup. |
| Tab | Recorre el contenido del popup. Salir con Tab de un popover no modal lo cierra. |
| Esc | Cierra el popover y devuelve el foco al trigger. |
<PopoverTitle />y<PopoverDescription />etiquetan y describen el popup para los lectores de pantalla. Incluye un título siempre que el popup contenga más de una frase.- El foco se mueve al primer elemento enfocable al abrir y vuelve al trigger al cerrar. Cámbialo con
initialFocusyfinalFocus. - Con movimiento reducido activado, el popup se desvanece sin escalar.
Construido sobre el popover de Base UI. Cada parte acepta las props de la primitiva que envuelve.
| Prop | Tipo | Predeterminado |
|---|---|---|
defaultOpen | boolean | false |
open | boolean | – |
onOpenChangedetails.reason indica qué causó el cambio. | (open: boolean, details) => void | – |
onOpenChangeCompleteSe llama cuando termina la animación de apertura o cierre. | (open: boolean) => void | – |
modaltrue bloquea el scroll de la página y la interacción externa. trap-focus solo atrapa el foco. | boolean | "trap-focus" | false |
handleConecta triggers desacoplados. | PopoverHandle<Payload> | – |
children | ReactNode | ({ payload }) => ReactNode | – |
| Prop | Tipo | Predeterminado |
|---|---|---|
openOnHover | boolean | false |
delayMilisegundos antes de abrir al pasar el cursor. | number | 300 |
closeDelayMilisegundos antes de cerrar cuando termina el hover. | number | 0 |
handle | PopoverHandle<Payload> | – |
payloadSe pasa al popup cuando este trigger lo abre. | Payload | – |
disabled | boolean | false |
render | ReactElement | (props, state) => ReactElement | <button> |
| Atributo | Descripción |
|---|---|
data-slot="popover-trigger" | Apunta al trigger en CSS. |
data-popup-open | Presente mientras su popover está abierto. |
data-pressed | Presente mientras el trigger está pulsado. |
data-disabled | Presente cuando el trigger está deshabilitado. |
Renderiza el portal, el positioner y el popup en una sola parte.
| Prop | Tipo | Predeterminado |
|---|---|---|
side | "top" | "right" | "bottom" | "left" | "inline-start" | "inline-end" | "bottom" |
align | "start" | "center" | "end" | "center" |
sideOffsetEspacio entre el trigger y el popup. | number | (data) => number | 6 |
alignOffset | number | (data) => number | 0 |
collisionPaddingEspacio que se mantiene respecto a los bordes del viewport. | number | Rect | 8 |
collisionAvoidanceSi debe voltearse, desplazarse o ninguna de las dos cuando se acaba el espacio. | CollisionAvoidance | – |
collisionBoundary | Boundary | – |
anchorPosiciona respecto a algo distinto del trigger. | Element | RefObject | VirtualElement | () => Element | – |
sticky | boolean | false |
positionMethod | "absolute" | "fixed" | "absolute" |
initialFocusAdónde va el foco cuando el popover se abre. | boolean | RefObject | (type) => HTMLElement | boolean | – |
finalFocusAdónde va el foco cuando el popover se cierra. | boolean | RefObject | (type) => HTMLElement | boolean | – |
portalPropsProps para el portal, como container. | PortalProps | – |
classNameEl popup es w-72 por defecto. | string | (state) => string | – |
render | ReactElement | (props, state) => ReactElement | <div> |
| Atributo | Descripción |
|---|---|
data-slot="popover-content" | El popup. |
data-slot="popover-positioner" | El elemento que posiciona el popup. |
data-open | Presente mientras el popover está abierto. |
data-starting-style | Presente mientras el popup se anima al entrar. |
data-ending-style | Presente mientras el popup se anima al salir. |
data-side | El lado en el que terminó el popup. |
data-align | La alineación con la que terminó el popup. |
data-instant | Presente cuando el cambio no debe animarse. |
--transform-origin | El punto desde el que escala el popup, en el trigger. |
--available-width | Espacio entre el trigger y el borde del viewport. |
--available-height | Espacio entre el trigger y el borde del viewport. La altura máxima del popup. |
--anchor-width | El ancho del trigger. |
--anchor-height | La altura del trigger. |
Un <div> simple que apila el título y la descripción.
| Atributo | Descripción |
|---|---|
data-slot="popover-header" | Apunta al encabezado en CSS. |
| Prop | Tipo | Predeterminado |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <h2> |
| Atributo | Descripción |
|---|---|
data-slot="popover-title" | Etiqueta el popup. |
| Prop | Tipo | Predeterminado |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <p> |
| Atributo | Descripción |
|---|---|
data-slot="popover-description" | Describe el popup. |
| Prop | Tipo | Predeterminado |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <button> |
| Atributo | Descripción |
|---|---|
data-slot="popover-close" | Cierra el popover al pulsarlo. |
createPopoverHandle<Payload>() devuelve un handle que conecta un <Popover /> con triggers renderizados en otro lugar. Créalo una sola vez, fuera de tu componente.
- Alert dialogUn diálogo de confirmación para acciones destructivas o importantes que espera el trabajo asíncrono y se convierte en una hoja inferior en móviles.
- CommandUna lista de acciones con búsqueda, en línea o como paleta ⌘K, con páginas, atajos y coincidencias resaltadas.
- Context menuUn menú de acciones con clic derecho o pulsación larga, con submenús, elementos de casilla y de radio, y respuesta al mantener pulsado en pantallas táctiles.
- DialogUna ventana sobre la página para formularios y tareas concretas, con encabezado y pie fijados, anidamiento y una hoja inferior deslizable en móviles.
- DrawerUn panel que se desliza desde cualquier borde y sigue tu dedo, con puntos de anclaje, un tirador funcional y drawers anidados que se apilan.
- Dropdown menuUn menú de acciones y opciones tras un botón, con grupos, submenús, elementos de casilla y de radio, y atajos.
Usado en bloques
Bloques que se construyen sobre Popover.
- Prompt InputUn compositor de chat que empieza como una línea tranquila, crece hasta convertirse en una tarjeta mientras escribes y baja cuando empieza la conversación. Enter envía, de forma segura con entrada en japonés y chino. Pega, suelta o elige archivos con vistas previas, progreso y reintento. @ añade archivos y / ejecuta comandos desde un menú junto al cursor. Un selector de modelo con teclas numéricas, un control deslizante de esfuerzo que cobra vida en Max, un anillo de contexto, dictado con forma de onda en vivo, chips de herramientas, una cola para los mensajes escritos mientras se transmite una respuesta y borradores que sobreviven a una recarga.
- Agent TodosMuestra el plan de un agente mientras trabaja. Cada paso pasa de pendiente a por hacer, en curso y hecho, con tiempos en vivo, fallos y las llamadas a herramientas detrás. Una píldora de estado para sobre el compositor, cambios del plan que puedes ver y un paso de revisión para editar el plan antes de ejecutarlo.
- Diff ReviewRevisa las ediciones de un agente en todos los archivos antes de que se apliquen. Un árbol de archivos con contadores, aceptar o rechazar cada cambio, cada archivo o todo, comentarios en cualquier línea o rango que vuelven al agente, vistas unificada y dividida, resaltado a nivel de palabra, deshacer, ediciones en streaming y un resumen «Editados 4 archivos» para el chat.
- Voice ModeHabla con tu asistente. Ocho estilos que reaccionan al audio, desde un cielo nublado y una mancha de ferrofluido hasta píxeles con dithering, ASCII, un planeta CRT, puntos de semitono, un solo anillo y un aura suave, más cuatro puntos reactivos. Una sesión a pantalla completa con silencio, interrupción y subtítulos, una píldora de voz en el chat, un selector de voz y un motor del navegador que escucha, espera a que termines y responde.