React Virtual List Component which worked with animation
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Advanced scrolling capabilities including programmatic navigation, scroll event handling, and horizontal scrolling support.
Event handlers for responding to scroll events and virtual scroll changes.
/**
* Native scroll event handler
* @param event - Standard React scroll event
*/
onScroll?: React.UIEventHandler<HTMLElement>;
/**
* Virtual scroll position callback
* @param info - Current virtual scroll position
*/
onVirtualScroll?: (info: ScrollInfo) => void;
/**
* Callback when visible items change during scrolling
* @param visibleList - Currently visible items
* @param fullList - Complete data array
*/
onVisibleChange?: (visibleList: T[], fullList: T[]) => void;
interface ScrollInfo {
/** Horizontal scroll position */
x: number;
/** Vertical scroll position */
y: number;
}Usage Examples:
import React, { useState } from "react";
import List from "rc-virtual-list";
const ScrollTrackingList = () => {
const [scrollInfo, setScrollInfo] = useState({ x: 0, y: 0 });
const [visibleCount, setVisibleCount] = useState(0);
const handleVirtualScroll = (info) => {
setScrollInfo(info);
console.log('Virtual scroll:', info.x, info.y);
};
const handleVisibleChange = (visibleItems, allItems) => {
setVisibleCount(visibleItems.length);
console.log(`Showing ${visibleItems.length} of ${allItems.length} items`);
};
const handleNativeScroll = (e) => {
console.log('Native scroll event:', e.currentTarget.scrollTop);
};
return (
<div>
<div>Position: {scrollInfo.x}, {scrollInfo.y}</div>
<div>Visible items: {visibleCount}</div>
<List
data={data}
height={300}
itemHeight={50}
itemKey="id"
onVirtualScroll={handleVirtualScroll}
onVisibleChange={handleVisibleChange}
onScroll={handleNativeScroll}
>
{(item) => <div>{item.name}</div>}
</List>
</div>
);
};Support for horizontal scrolling with custom scroll width.
/**
* Enable horizontal scrolling with specified scroll width
* When set, enables horizontal scrolling and virtual horizontally
*/
scrollWidth?: number;Usage Example:
import List from "rc-virtual-list";
const HorizontalScrollList = () => {
return (
<List
data={data}
height={300}
itemHeight={50}
itemKey="id"
scrollWidth={1200} // Enable horizontal scrolling
onVirtualScroll={({ x, y }) => {
console.log('Horizontal position:', x, 'Vertical position:', y);
}}
>
{(item, index, { style, offsetX }) => (
<div
style={{
...style,
width: 1200, // Wide content that requires horizontal scrolling
display: 'flex',
alignItems: 'center'
}}
>
<span style={{ minWidth: 200 }}>{item.name}</span>
<span style={{ minWidth: 300 }}>{item.description}</span>
<span style={{ minWidth: 150 }}>{item.category}</span>
<span>Offset: {offsetX}px</span>
</div>
)}
</List>
);
};/**
* Text direction for right-to-left language support
*/
direction?: ScrollBarDirectionType;
type ScrollBarDirectionType = 'ltr' | 'rtl';Usage Example:
import List from "rc-virtual-list";
const RTLList = () => {
return (
<List
data={arabicData}
height={300}
itemHeight={50}
itemKey="id"
direction="rtl" // Right-to-left support
>
{(item) => <div dir="rtl">{item.arabicText}</div>}
</List>
);
};/**
* Custom styles for scrollbar components
*/
styles?: {
horizontalScrollBar?: React.CSSProperties;
horizontalScrollBarThumb?: React.CSSProperties;
verticalScrollBar?: React.CSSProperties;
verticalScrollBarThumb?: React.CSSProperties;
};
/**
* Control scrollbar visibility
* - true: Always show scrollbars
* - false: Never show scrollbars
* - 'optional': Show only when needed (default)
*/
showScrollBar?: boolean | 'optional';Usage Example:
import List from "rc-virtual-list";
const StyledScrollbarList = () => {
const scrollbarStyles = {
verticalScrollBar: {
width: 12,
backgroundColor: '#f0f0f0',
borderRadius: 6,
},
verticalScrollBarThumb: {
backgroundColor: '#666',
borderRadius: 6,
border: '2px solid transparent',
},
horizontalScrollBar: {
height: 12,
backgroundColor: '#f0f0f0',
borderRadius: 6,
},
horizontalScrollBarThumb: {
backgroundColor: '#666',
borderRadius: 6,
},
};
return (
<List
data={data}
height={300}
itemHeight={50}
itemKey="id"
scrollWidth={800}
styles={scrollbarStyles}
showScrollBar={true} // Always show scrollbars
>
{(item) => <div style={{ width: 800 }}>{item.content}</div>}
</List>
);
};/**
* Alignment options for programmatic scrolling
*/
type ScrollAlign = 'top' | 'bottom' | 'auto';'top': Align the target item to the top of the viewport'bottom': Align the target item to the bottom of the viewport'auto': Smart alignment based on current position (minimal scroll distance)/**
* Internal interface for scrollbar control (not directly accessible)
*/
interface ScrollBarRef {
/** Hide scrollbar after delay */
delayHidden: () => void;
}This interface is used internally by the List component for scrollbar management and is not accessible to consumers.
const InfiniteScrollList = () => {
const [data, setData] = useState(initialData);
const [loading, setLoading] = useState(false);
const handleVisibleChange = (visibleItems, allItems) => {
const lastVisible = visibleItems[visibleItems.length - 1];
const lastIndex = allItems.indexOf(lastVisible);
// Load more when approaching end
if (lastIndex > allItems.length - 10 && !loading) {
setLoading(true);
loadMoreData().then(newData => {
setData(prev => [...prev, ...newData]);
setLoading(false);
});
}
};
return (
<List
data={data}
height={300}
itemHeight={50}
itemKey="id"
onVisibleChange={handleVisibleChange}
>
{(item) => <div>{item.name}</div>}
</List>
);
};const PersistentScrollList = () => {
const listRef = useRef<ListRef>(null);
useEffect(() => {
// Restore scroll position on mount
const savedPosition = localStorage.getItem('listScrollPosition');
if (savedPosition) {
listRef.current?.scrollTo(parseInt(savedPosition));
}
}, []);
const handleVirtualScroll = ({ y }) => {
// Save scroll position
localStorage.setItem('listScrollPosition', y.toString());
};
return (
<List
ref={listRef}
data={data}
height={300}
itemHeight={50}
itemKey="id"
onVirtualScroll={handleVirtualScroll}
>
{(item) => <div>{item.name}</div>}
</List>
);
};Install with Tessl CLI
npx tessl i tessl/npm-rc-virtual-list