Skip to content

Overflow Items

hookoverflowresize-observeritems

Measures how many items fit in a container and tracks the overflow count. Uses ResizeObserver for automatic recalculation. Single ref — no hidden measurement rows needed.

tsx
const tags = ["React", "TypeScript", "Next.js", "Tailwind", "Vite"];const { ref, visibleCount, overflowCount } =  useOverflowItems({ itemCount: tags.length });return (  <div ref={ref} className="relative flex items-center gap-2 overflow-clip">    {tags.map((tag, i) => (      <div key={i} className={cn("shrink-0", i >= visibleCount && "invisible absolute pointer-events-none")}>        <span>{tag}</span>      </div>    ))}    <div className={cn("shrink-0", overflowCount === 0 && "invisible absolute pointer-events-none")}>      <span>+{Math.max(overflowCount, 1)}</span>    </div>  </div>);

Installation

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

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
itemCountrequirednumberNumber of items to lay out. The hook uses this to drive measurement and re-observe on count changes.
onVisibleCountChange(count: number) => voidCalled when the visible count changes. Useful for syncing external state without subscribing to the returned visibleCount in a separate effect.

Returns

{ ref: RefCallback<HTMLDivElement>; visibleCount: number; overflowCount: number }A callback ref to attach to the container and reactive counts.
NameTypeDefaultDescription
refrequiredRefCallback<HTMLDivElement>Attach to the container element. Conditional mounts and replacement containers are remeasured and observed through the callback lifecycle.
visibleCountrequirednumberNumber of items that fit within the container width. Use this to hide overflow items via CSS (invisible absolute pointer-events-none).
overflowCountrequirednumberNumber of items that do not fit (itemCount − visibleCount). Show the overflow indicator when this is greater than zero.

Examples

Basic Overflow Badge

Preview

Notes

Container Contract

The container's children must follow this order: [item0, item1, ..., itemN-1, indicator]. The first itemCount children are measured as items. The child at index itemCount is measured as the overflow indicator. The container must use CSS gap (e.g. Tailwind gap-* or gap-x-*) — the hook reads the resolved column-gap via getComputedStyle, since it measures a single horizontal row.

Hiding Overflow Items

Items where index >= visibleCount should get 'invisible absolute pointer-events-none' classes. This keeps them in the DOM for measurement while hiding them visually. The indicator should always be rendered (hidden when overflowCount === 0) so the hook can measure its width for space reservation.

No Visual Flash

The hook uses useLayoutEffect which fires before the browser paints. On the first render all items are visible in the flex flow, measured synchronously, then visibleCount is set — triggering a re-render before paint. The user never sees the intermediate state.

Source

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