Skip to content

computePlacement

Coloca un panel flotante (desplegable, popover, información sobre herramienta) respecto al rectángulo de un ancla: si al lado preferido le falta sitio y al contrario le sobra, se pasa al contrario, y luego se desplaza por el eje transversal para no salirse de un límite. Hace lo mismo que los middleware flip y shift de Floating UI, sin la dependencia.

Geometría pura: nunca toca el DOM. Le pasas resultados de getBoundingClientRect() y te devuelve las coordenadas que hay que escribir.

Uso

ts
import { computePlacement } from 'ranuts/utils';

const anchorRect = trigger.getBoundingClientRect();
const { top, left, placement } = computePlacement({
  anchor: anchorRect,
  floating: { width: panel.offsetWidth, height: panel.offsetHeight },
  placement: 'bottom',
  offset: 4,
});

panel.style.position = 'absolute';
panel.style.top = `${top + window.scrollY}px`;
panel.style.left = `${left + window.scrollX}px`;
// `placement` es el lado que se acabó usando, ya con el volteo aplicado; úsalo para
// elegir la clase de animación de entrada o la dirección de la flecha.

API

computePlacement

Parámetros

ParámetroDescripciónTipoPor defecto
options.anchorRectángulo del ancla (el disparador), en coordenadas del viewport (por ejemplo, getBoundingClientRect()){ top, left, width, height }Obligatorio
options.floatingEl tamaño del propio panel flotante{ width, height }Obligatorio
options.placementLado preferido. Se pasa al contrario cuando le falta sitio y al contrario le sobra'top' | 'bottom' | 'left' | 'right'Obligatorio
options.offsetHueco que se deja entre el ancla y el panel flotante, en pxnumber0
options.boundaryRegión dentro de la cual debe quedarse el panel, en coordenadas del viewport{ top, left, width, height }El viewport de la ventana
options.paddingHueco mínimo que se deja entre el panel y el borde del límite al desplazarlo, en pxnumber8

Devuelve

ArgumentoDescripciónTipo
topEl top resuelto, en el mismo espacio de coordenadas que anchornumber
leftEl left resuelto, en el mismo espacio de coordenadas que anchornumber
placementEl lado que se acabó usando, ya con el volteo'top' | 'bottom' | 'left' | 'right'

Notas

  1. Las coordenadas son siempre relativas al viewport, el mismo espacio que anchor. Si colocas el panel con position: absolute respecto al documento, súmale tú scrollX y scrollY al escribir el estilo (véase el ejemplo de arriba).
  2. Sin maquetación real, ni volteo ni desplazamiento. Cuando anchor o floating tiene ancho o alto cero (jsdom, que nunca maqueta de verdad, o un panel leído antes de que su contenido se asiente), los cálculos de espacio «detectarían» una colisión falsa en cada llamada. Por eso computePlacement se salta el volteo y el desplazamiento por completo y devuelve tal cual el placement que le pidieron.
  3. El desplazamiento se omite cuando el panel es más grande que el propio límite: ceñirlo solo lo empujaría fuera de la pantalla por el otro lado.
  4. Lo usan por dentro el r-popover y el r-select de ranui para que un desplegable portado al body no se salga de la pantalla.

Publicado bajo la licencia MIT.