Skip to content

GroupedVirtuoso

GroupedVirtuoso<ItemData, Context>(props): ReactElement

A virtualized list component for rendering grouped data with sticky group headers. Extends Virtuoso with support for collapsible groups and group-level navigation.

Type ParameterDefault typeDescription
ItemDataanyThe type of data items in the list
ContextanyThe type of additional context passed to callbacks
ParameterTypeDescription
propsGroupedVirtuosoProps<ItemData, Context> & objectGroupedVirtuosoProps

ReactElement

tsx

The props for the GroupedVirtuoso component.

  • Omit<VirtuosoProps<Data, Context>, "itemContent" | "totalCount">
Type ParameterDescription
DataThe type of data items in the list
ContextThe type of additional context passed to callbacks

Setting alignToBottom to true aligns the items to the bottom of the list if the list is shorter than the viewport. Use followOutput property to keep the list aligned when new items are appended.

Omit.alignToBottom


optional atBottomStateChange: (atBottom) => void

Called with true / false when the list has reached the bottom / gets scrolled up. Can be used to load newer items, like tail -f.

ParameterType
atBottomboolean

void

Omit.atBottomStateChange


The property accepts pixel values.

By default 4. Redefine to change how much away from the bottom the scroller can be before the list is not considered not at bottom.

Omit.atBottomThreshold


optional atTopStateChange: (atTop) => void

Called with true / false when the list has reached the top / gets scrolled down.

ParameterType
atTopboolean

void

Omit.atTopStateChange


The property accepts pixel values.

By default 0. Redefine to change how much away from the top the scroller can be before the list is not considered not at top.

Omit.atTopThreshold


Use the components property for advanced customization of the elements rendered by the list.

Omit.components


If specified, the component will use the function to generate the key property for each list item.

Omit.computeItemKey


Additional context available in the custom components and content callbacks

Omit.context


Pass a reference to a scrollable parent element, so that the list won’t wrap in its own.

Omit.customScrollParent


The data items to be rendered. If data is set, the total count will be inferred from the length of the array.

Omit.data


By default, the component assumes the default item height from the first rendered item (rendering it as a “probe”).

If the first item turns out to be an outlier (very short or tall), the rest of the rendering will be slower, as multiple passes of rendering should happen for the list to fill the viewport.

Setting defaultItemHeight causes the component to skip the “probe” rendering and use the property value as default height instead.

Omit.defaultItemHeight


optional endReached: (index) => void

Gets called when the user scrolls to the end of the list. Receives the last item index as an argument. Can be used to implement endless scrolling.

ParameterType
indexnumber

void

Omit.endReached


Use when implementing inverse infinite scrolling, decrease the value this property in combination with a change in groupCounts to prepend groups items to the top of the list. Both new groups and extending the top group is supported.

The delta of the firstItemIndex should equal the amount of new items introduced, without the group themselves. As an example, if you prepend 2 groups with 20 and 30 items each, the firstItemIndex should be decreased with 50.

You can also prepend more items to the first group, for example: { groupCounts: [20, 30], firstItemIndex: 1000 } can become { groupCounts: [10, 30, 30], firstItemIndex: 980 }

Warning: the firstItemIndex should be a positive number, based on the total amount of items to be displayed.

Omit.firstItemIndex


Can be used to improve performance if the rendered group header items are of known size. Setting it causes the component to skip measuring group headers. The value is in pixels. This value has no effect if fixedItemHeight is not set.

VirtuosoProps.fixedGroupHeight


Can be used to improve performance if the rendered items are of known size. Setting it causes the component to skip item measurements.

Omit.fixedItemHeight


If set to true, the list automatically scrolls to bottom if the total count is changed. Set to "smooth" for an animated scrolling.

By default, followOutput scrolls down only if the list is already at the bottom. To implement an arbitrary logic behind that, pass a function:

tsx

Omit.followOutput


Specifies how each each group header gets rendered. The callback receives the zero-based index of the group.


Specifies the amount of items in each group (and, actually, how many groups are there). For example, passing [20, 30] will display 2 groups with 20 and 30 items each.


Set to customize the wrapper tag for the header and footer components (default is div).

Omit.headerFooterTag


Use when you have items with widely varying heights and can estimate each item’s height upfront.

Pass an array of estimated heights for each item (by index). This helps the component calculate a more accurate initial total height for the list, reducing layout shifts during initial scrolling.

The estimates don’t need to be exact - they’re used to build the initial size tree before actual measurements are taken. Once items are rendered and measured, their real heights replace the estimates.

tsx

VirtuosoProps.heightEstimates


When set, turns the scroller into a horizontal list. The items are positioned with inline-block.

Omit.horizontalDirection


increaseViewportBy?: number | { bottom: number; top: number; }

Section titled “increaseViewportBy?: number | { bottom: number; top: number; }”

The property accepts pixel values.

Set the increaseViewportBy property to artificially increase the viewport size, causing items to be rendered before outside of the viewport. The property causes the component to render more items than the necessary, but can help with slow loading content. Using { top?: number, bottom?: number } lets you set the increase for each end separately.

Omit.increaseViewportBy


Use for server-side rendering - if set, the list will render the specified amount of items regardless of the container / item size.

Omit.initialItemCount


Set this value to offset the initial location of the list. Warning: using this property will still run a render cycle at the scrollTop: 0 list window. If possible, avoid using it and stick to initialTopMostItemIndex instead.

Omit.initialScrollTop


Set to a value between 0 and totalCount - 1 to make the list start scrolled to that item. Pass in an object to achieve additional effects similar to scrollToIndex.

Omit.initialTopMostItemIndex


optional isScrolling: (isScrolling) => void

Called when the list starts/stops scrolling.

ParameterType
isScrollingboolean

void

Omit.isScrolling


Specifies how each each item gets rendered.


Allows customizing the height/width calculation of Item elements.

The default implementation reads el.getBoundingClientRect().height and el.getBoundingClientRect().width.

Omit.itemSize


optional itemsRendered: (items) => void

Called with the new set of items each time the list items are rendered due to scrolling.

ParameterType
itemsListItem<Data>[]

void

Omit.itemsRendered


set to LogLevel.DEBUG to enable various diagnostics in the console, the most useful being the item measurement reports.

Ensure that you have “all levels” enabled in the browser console too see the messages.

Omit.logLevel


minOverscanItemCount?: number | { bottom: number; top: number; }

Section titled “minOverscanItemCount?: number | { bottom: number; top: number; }”

Set the minimum number of items to render before and after the visible viewport boundaries. This is useful when rendering items with dynamic or very tall content, where the pixel-based increaseViewportBy may not be sufficient to prevent empty areas during rapid resizing or scrolling. Using { top?: number, bottom?: number } lets you set the count for each end separately.

Omit.minOverscanItemCount


overscan?: number | { main: number; reverse: number; }

Section titled “overscan?: number | { main: number; reverse: number; }”

The property accepts pixel values.

Set the overscan property to make the component “chunk” the rendering of new items on scroll. The property causes the component to render more items than the necessary, but reduces the re-renders on scroll. Setting { main: number, reverse: number } lets you extend the list in both the main and the reverse scrollable directions. See the increaseViewportBy property for a similar behavior (equivalent to the overscan in react-window).

Omit.overscan


optional rangeChanged: (range) => void

Called with the new set of items each time the list items are rendered due to scrolling.

ParameterType
rangeListRange

void

Omit.rangeChanged


pass a state obtained from the getState() method to restore the list state - this includes the previously measured item sizes and the scroll location. Notice that you should still pass the same data and totalCount properties as before, so that the list can match the data with the stored measurements. This is useful when you want to keep the list state when the component is unmounted and remounted, for example when navigating to a different page.

Omit.restoreStateFrom


optional scrollerRef: (ref) => any

Provides access to the root DOM element

ParameterType
refHTMLElement | Window | null

any

Omit.scrollerRef


optional scrollIntoViewOnChange: (params) => false | ScrollIntoViewLocation | null | undefined

Implement this callback if you want to adjust the list position when the list total count changes. Return a ScrollIntoViewLocation object to scroll to a specific item, or falsey value to avoid scrolling. Use the context contents if you need to implement custom logic based on the current state of the list.

ParameterType
params{ context: Context; scrollingInProgress: boolean; totalCount: number; }
params.contextContext
params.scrollingInProgressboolean
params.totalCountnumber

false | ScrollIntoViewLocation | null | undefined

Omit.scrollIntoViewOnChange


Use to display placeholders if the user scrolls fast through the list.

Set components.ScrollSeekPlaceholder to change the placeholder content.

Omit.scrollSeekConfiguration


skipAnimationFrameInResizeObserver?: boolean

Section titled “skipAnimationFrameInResizeObserver?: boolean”

When set, the resize observer used to measure the items will not use requestAnimationFrame to report the size changes. Setting this to true will improve performance and reduce flickering, but will cause benign errors to be reported in the console if the size of the items changes while they are being measured. See https://github.com/petyosi/react-virtuoso/issues/1049 for more information.

Omit.skipAnimationFrameInResizeObserver


optional startReached: (index) => void

Called when the user scrolls to the start of the list.

ParameterType
indexnumber

void

Omit.startReached


Set the amount of items to remain fixed at the top of the list.

For a header that scrolls away when scrolling, check the components.Header property.

Omit.topItemCount


optional totalListHeightChanged: (height) => void

Called when the total list height is changed due to new items or viewport resize.

ParameterType
heightnumber

void

Omit.totalListHeightChanged


Uses the document scroller rather than wrapping the list in its own.

Omit.useWindowScroll


Exposes the GroupedVirtuoso component methods for imperative control. Access via ref on the GroupedVirtuoso component.

autoscrollToBottom(): void

Scrolls to the bottom of the list if follow output is active. Useful when images load in the list.

void


getState(stateCb): void

Obtains the internal size state of the component, so that it can be restored later. This does not include the data items.

ParameterTypeDescription
stateCbStateCallbackCallback that receives the state snapshot

void


scrollBy(location): void

Scrolls the component by the specified amount.

ParameterTypeDescription
locationScrollToOptionsThe scroll offset options

void


scrollIntoView(location): void

Scrolls the specified item into view if it’s not already visible.

ParameterTypeDescription
locationnumber | ScrollIntoViewLocationThe item index or scroll location options

void


scrollTo(location): void

Scrolls the component to the specified position.

ParameterTypeDescription
locationScrollToOptionsThe scroll position options

void


scrollToIndex(location): void

Scrolls the component to the specified item index.

ParameterTypeDescription
locationnumber | IndexLocationWithAlignThe item index or location with alignment options

void


GroupContent<Context> = (index, context) => React.ReactNode

Callback type for rendering group header content in GroupedVirtuoso.

Type ParameterDescription
ContextThe type of context passed from the component
ParameterType
indexnumber
contextContext

React.ReactNode

tsx

GroupedVirtuosoProps.groupContent for usage


How to align the item within the viewport

ScrollIntoViewLocationOptions.align


The scroll behavior - ‘smooth’ for animated scrolling, ‘auto’ for instant

ScrollIntoViewLocationOptions.behavior


Use this function to fine-tune the scrollIntoView behavior. The function receives the item’s top and bottom position in the viewport, and the viewport top/bottom. Return an location object to scroll, or null to prevent scrolling. Here’s the default implementation:

ts

ScrollIntoViewLocationOptions.calculateViewLocation


optional done: () => void

Will be called when the scroll is done, or immediately if no scroll is needed.

void

ScrollIntoViewLocationOptions.done


number

The index of the group to scroll into view


How to position the item in the viewport.

LocationOptions.align


Set ‘smooth’ to have an animated transition to the specified location.

LocationOptions.behavior


number

The group index of the item to scroll to.


The offset to scroll.

LocationOptions.offset


Type Parameter
Data

The data associated with this item

Item.data


number

The index of the item in the list

Item.index


number

The offset position of the item from the start of the list in pixels

Item.offset


The original index before any transformations were applied


number

The measured size of the item in pixels

Item.size


"group"

Identifies this as a group header item


GroupItemContent<Data, Context> = (index, groupIndex, data, context) => React.ReactNode

Callback type for rendering item content in a GroupedVirtuoso list. Similar to ItemContent but includes the group index.

Type ParameterDescription
DataThe type of the data item
ContextThe type of context passed from the component
ParameterType
indexnumber
groupIndexnumber
dataData
contextContext

React.ReactNode

tsx

GroupProps = Pick<React.ComponentProps<"div">, "children" | "style"> & object

Passed to the Components.Group custom component

number

The index of the group

number

The item index within the flattened list

number

The measured size of the group header in pixels