A responsive React component that shows as many items as can fit within constraints, hiding overflow items behind a configurable overflow renderer
npm install react-responsive-overflow-listResponsive list for React that shows only items that fit and groups the rest into a customizable overflow element. Recalculates on resize.




đź”— Live demo: https://eliav2.github.io/react-responsive-overflow-list/

!Screen Recording 2025-09-27 at 15 49 03
---
- Accurate & responsive: measures real layout after paint (ResizeObserver), not guessed widths
- Two usage modes: children (simple) or items + renderItem (structured)
- Customizable overflow element; ships with a lightweight default
- Multi-row support (via maxRows)
- Handles uneven widths, including a single ultra-wide item
- TypeScript types; zero runtime deps (React as peer)
- SSR-friendly: measurement runs on the client
- No implicit wrappers around your items. (layout behaves as you expect)
``bash`
npm i react-responsive-overflow-list
> In real apps, you’ll typically wrap OverflowList in your own component—design tokens, accessible menus, virtualization, or search. See 'Wrap & extend' below and the demo for a full wrapper example.
Minimal usage with an items array and render function.
`tsx
import { OverflowList } from "react-responsive-overflow-list";
const items = ["One", "Two", "Three", "Four", "Five"];
export default function Example() {
return (
renderItem={(item) => {item}}
style={{ gap: 8 }} // root is display:flex; flex-wrap:wrap
maxRows={1}
/>
);
}
`
Use children instead of items + renderItem.
`tsx`
Provide your own overflow UI (button, menu, details/summary, etc.).
`tsx`
renderItem={(item) => {item}}
renderOverflow={(hidden) => }
/>
Render using a different HTML element via as.
Trade visual smoothness vs peak performance during rapid resize.
`tsx`
renderItem={(item) => {item}}
flushImmediately={false} // uses rAF; faster under rapid resize, may flicker briefly
/>
See the Flush Immediately example in the live demo.
---
| Prop | Type | Default | Notes |
| ---------------------- | ---------------------------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------- |
| items | T[] | — | Use with renderItem. Omit when using children. |renderItem
| | (item: T, index: number) => ReactNode | — | How to render each item. |children
| | ReactNode | — | Alternative to items + renderItem. |as
| | React.ElementType | "div" | Polymorphic root element. |maxRows
| | number | 1 | Visible rows before overflow. |maxVisibleItems
| | number | 100 | Hard cap on visible items. |renderOverflow
| | (hidden: T[]) => ReactNode | default chip | Custom overflow UI. |renderOverflowItem
| | (item: T, i: number) => ReactNode | renderItem | For expanded lists/menus. |renderOverflowProps
| | Partial | — | Props for default overflow. |flushImmediately
| | boolean | true | true (flushSync, no flicker) vs false (rAF, faster under resize). |renderItemVisibility
| | (node: ReactNode, meta: RenderItemVisibilityMeta) => ReactNode | internal | Control visibility of hidden items (defaults to React.Activity if available, otherwise simply return null). |
Styles: Root uses display:flex; flex-wrap:wrap; align-items:center;. Override via style/className.
Default overflow element: A tiny chip that renders +{count} more. Replace via renderOverflow.
---
It’s expected you’ll wrap OverflowList for product needs (design system styling, a11y menus, virtualization, search). for example:
- Radix UI + Virtualization wrapper (search, large datasets, a11y, perf):
- Demo: see Radix UI + Virtualization in the live site
- Source
- Uses @tanstack/react-virtual and the helper createLimitedRangeExtractor(...).
---
1. Measure all items and compute how many fit within maxRows.
2. Re-test with the overflow indicator; if it would create a new row, hide one more item.
3. Render the stable “normal” state until container size changes.
flushImmediately=true → immediate, flicker-free (uses flushSync).flushImmediately=false → defer with rAF; smoother under rapid resize, may flicker.
- Single wide item exceeding container width
- maxRows / maxVisibleItems respected
- Varying item widths, responsive content
- Multi-row overflow detection
- In React 19.2+, hidden items use React.Activity so overflowed children stay mounted while toggling visibility.renderItemVisibility
- In React 16–18, overflowed nodes unmount during measurement; pass if you need to keep custom
elements or skeletons mounted and control visibility yourself.
---
- React ≥ 16.8 (hooks)
- Modern browsers with ResizeObserver`
MIT