Skip to content

Floating Indicator

hookindicatormeasurement

Measures the active child inside a container and returns a container-relative rectangle for drawing a floating indicator under or around it.

tsx
const containerRef = useRef<HTMLDivElement>(null);const indicator = useFloatingIndicator(containerRef, activeValue);return (  <div ref={containerRef} className="relative">    {items.map((item) => (      <button key={item.value} data-value={item.value}>        {item.label}      </button>    ))}    {indicator && (      <span        aria-hidden="true"        style={{          left: indicator.left,          top: indicator.top,          width: indicator.width,          height: indicator.height,        }}      />    )}  </div>);

Installation

$pnpm exec dgadd add ui/floating-indicator
[Installs to]src/hooks/use-floating-indicator.ts[Item]ui/floating-indicator

dgadd is not public on npm yet. Until the first release, pack @diffgazer/add from the repository and install that tarball into this app, which is what puts dgadd on pnpm exec.

UI components require Tailwind CSS v4. Local copy mode imports src/styles/styles.css; package mode uses @diffgazer/ui CSS once packages are available.

Parameters

NameTypeDefaultDescription
containerRefrequiredRefObject<HTMLElement | null>Ref for the positioned container that owns selectable descendants marked with data-value.
activeValuerequiredstring | nullActive item value. The hook queries [data-value="..."] inside containerRef and returns null when no matching item is mounted.

Returns

FloatingIndicatorRect | nullContainer-relative rectangle for the active item, or null before measurement / when no active item exists.
NameTypeDefaultDescription
leftrequirednumberLeft offset from the container's bounding box.
toprequirednumberTop offset from the container's bounding box.
widthrequirednumberMeasured active item width.
heightrequirednumberMeasured active item height.

Notes

Measurement

The rectangle is measured with getBoundingClientRect relative to the container. ResizeObserver and MutationObserver keep it current when layout or children change.

Matching Contract

Items must expose data-value matching activeValue. The hook scans the container's [data-value] descendants and compares each attribute to activeValue by exact string equality, so any value is supported without escaping.

Source

Highlighted source loads after this disclosure opens. Browse the source repository.