useFloating
Anchor a floating element such as a popover, menu or tooltip to a trigger: it places it with flip and shift, renders it through the app's overlay host, registers it in the layer stack for Escape, back, outside press and focus, and returns the ARIA props for both ends. Popover, Menu, Tooltip, HoverCard and Select are built on it.
Spread
getReferenceProps() on the trigger and getFloatingProps() on the panel, then pass the panel to renderFloating(), which opens it in the nearest overlay host and renders nothing in place. placement (default 'bottom', written for LTR and mirrored in RTL) flips when the panel doesn't fit, and the returned placement is the side it actually landed on; offset, matchWidth, modal, role and trigger cover the rest, with 'hover' / 'focus' triggers neither taking focus nor closing on outside press. onDismiss(reason) fires for Escape, Android back, an outside press, or 'closed-externally' when something else closed the overlay. Without an OverlayProvider (PlocksProvider mounts one) the panel renders inline next to the trigger, without flipping.Loading demo…
import { useState } from 'react';
import { Block, Button, Text, useFloating } from '@plocks/ui';
export function Demo() {
const [opened, setOpened] = useState(false);
const floating = useFloating({
opened,
onDismiss: () => setOpened(false),
placement: 'bottom-start',
});
return (
<>
<Button {...floating.getReferenceProps()} onPress={() => setOpened((current) => !current)}>
{opened ? 'Close' : 'Open'}
</Button>
{floating.renderFloating(
<Block {...floating.getFloatingProps()} p="md" radius="md" bg="elevated" shadow="md" maw={260}>
<Text fw="600">Anchored panel</Text>
<Text size="sm" ff="monospace">
{floating.placement}
</Text>
</Block>
)}
</>
);
}React Native design for iOS, Android, and Web.
Quick Links
Resources