Floating layer
The primitives that power Tooltip, Menu, Popover, Select dropdowns and the pickers. Use them to build your own anchored floating UI.
useFloating
Positions a floating element (rendered in a portal) against an anchor: fixed positioning, flips to the opposite side when there isn’t room, and clamps to the viewport. Updates on scroll / resize / size changes.
import { useFloating, FloatingPortal } from '@gg-software/ui';
function Dropdown() {
const [open, setOpen] = useState(false);
const { anchorRef, floatingRef, floatingStyle, side } = useFloating<
HTMLButtonElement,
HTMLDivElement
>({ open, placement: 'bottom-start', offset: 4, matchWidth: true });
return (
<>
<button ref={anchorRef} onClick={() => setOpen((o) => !o)}>
Toggle
</button>
{open && (
<FloatingPortal>
<div ref={floatingRef} style={floatingStyle}>
Floating content (resolved side: {side})
</div>
</FloatingPortal>
)}
</>
);
}Options
| Option | Type | Default | Description |
|---|---|---|---|
open | boolean | — (required) | position is only computed while open |
placement | FloatingPlacement | 'bottom' | preferred side/alignment |
offset | number | 4 | gap between anchor and floating element |
matchWidth | boolean | false | make the floating element match the anchor’s width (dropdowns) |
padding | number | 8 | min distance to keep from the viewport edge |
Result
| Field | Type | Description |
|---|---|---|
anchorRef | RefObject<A> | attach to the anchor element |
floatingRef | RefObject<F> | attach to the floating element |
floatingStyle | CSSProperties | apply to the floating element (fixed position) |
side | FloatingSide | resolved side after any flip (useful for arrows) |
update | () => void | recompute the position manually |
Types
type FloatingSide = 'top' | 'bottom' | 'left' | 'right';
type FloatingAlign = 'start' | 'center' | 'end';
type FloatingPlacement =
| FloatingSide
| 'top-start' | 'top-end'
| 'bottom-start' | 'bottom-end';FloatingPortal
Renders children into document.body via a React portal (and renders nothing during SSR).
No props besides children.
<FloatingPortal>
<div ref={floatingRef} style={floatingStyle}>…</div>
</FloatingPortal>