0
# Scrolling
1
2
Advanced scrolling capabilities including programmatic navigation, scroll event handling, and horizontal scrolling support.
3
4
## Capabilities
5
6
### Scroll Event Handling
7
8
Event handlers for responding to scroll events and virtual scroll changes.
9
10
```typescript { .api }
11
/**
12
* Native scroll event handler
13
* @param event - Standard React scroll event
14
*/
15
onScroll?: React.UIEventHandler<HTMLElement>;
16
17
/**
18
* Virtual scroll position callback
19
* @param info - Current virtual scroll position
20
*/
21
onVirtualScroll?: (info: ScrollInfo) => void;
22
23
/**
24
* Callback when visible items change during scrolling
25
* @param visibleList - Currently visible items
26
* @param fullList - Complete data array
27
*/
28
onVisibleChange?: (visibleList: T[], fullList: T[]) => void;
29
30
interface ScrollInfo {
31
/** Horizontal scroll position */
32
x: number;
33
/** Vertical scroll position */
34
y: number;
35
}
36
```
37
38
**Usage Examples:**
39
40
```typescript
41
import React, { useState } from "react";
42
import List from "rc-virtual-list";
43
44
const ScrollTrackingList = () => {
45
const [scrollInfo, setScrollInfo] = useState({ x: 0, y: 0 });
46
const [visibleCount, setVisibleCount] = useState(0);
47
48
const handleVirtualScroll = (info) => {
49
setScrollInfo(info);
50
console.log('Virtual scroll:', info.x, info.y);
51
};
52
53
const handleVisibleChange = (visibleItems, allItems) => {
54
setVisibleCount(visibleItems.length);
55
console.log(`Showing ${visibleItems.length} of ${allItems.length} items`);
56
};
57
58
const handleNativeScroll = (e) => {
59
console.log('Native scroll event:', e.currentTarget.scrollTop);
60
};
61
62
return (
63
<div>
64
<div>Position: {scrollInfo.x}, {scrollInfo.y}</div>
65
<div>Visible items: {visibleCount}</div>
66
67
<List
68
data={data}
69
height={300}
70
itemHeight={50}
71
itemKey="id"
72
onVirtualScroll={handleVirtualScroll}
73
onVisibleChange={handleVisibleChange}
74
onScroll={handleNativeScroll}
75
>
76
{(item) => <div>{item.name}</div>}
77
</List>
78
</div>
79
);
80
};
81
```
82
83
### Horizontal Scrolling
84
85
Support for horizontal scrolling with custom scroll width.
86
87
```typescript { .api }
88
/**
89
* Enable horizontal scrolling with specified scroll width
90
* When set, enables horizontal scrolling and virtual horizontally
91
*/
92
scrollWidth?: number;
93
```
94
95
**Usage Example:**
96
97
```typescript
98
import List from "rc-virtual-list";
99
100
const HorizontalScrollList = () => {
101
return (
102
<List
103
data={data}
104
height={300}
105
itemHeight={50}
106
itemKey="id"
107
scrollWidth={1200} // Enable horizontal scrolling
108
onVirtualScroll={({ x, y }) => {
109
console.log('Horizontal position:', x, 'Vertical position:', y);
110
}}
111
>
112
{(item, index, { style, offsetX }) => (
113
<div
114
style={{
115
...style,
116
width: 1200, // Wide content that requires horizontal scrolling
117
display: 'flex',
118
alignItems: 'center'
119
}}
120
>
121
<span style={{ minWidth: 200 }}>{item.name}</span>
122
<span style={{ minWidth: 300 }}>{item.description}</span>
123
<span style={{ minWidth: 150 }}>{item.category}</span>
124
<span>Offset: {offsetX}px</span>
125
</div>
126
)}
127
</List>
128
);
129
};
130
```
131
132
### Scroll Direction & RTL Support
133
134
```typescript { .api }
135
/**
136
* Text direction for right-to-left language support
137
*/
138
direction?: ScrollBarDirectionType;
139
140
type ScrollBarDirectionType = 'ltr' | 'rtl';
141
```
142
143
**Usage Example:**
144
145
```typescript
146
import List from "rc-virtual-list";
147
148
const RTLList = () => {
149
return (
150
<List
151
data={arabicData}
152
height={300}
153
itemHeight={50}
154
itemKey="id"
155
direction="rtl" // Right-to-left support
156
>
157
{(item) => <div dir="rtl">{item.arabicText}</div>}
158
</List>
159
);
160
};
161
```
162
163
### Custom Scrollbar Styling
164
165
```typescript { .api }
166
/**
167
* Custom styles for scrollbar components
168
*/
169
styles?: {
170
horizontalScrollBar?: React.CSSProperties;
171
horizontalScrollBarThumb?: React.CSSProperties;
172
verticalScrollBar?: React.CSSProperties;
173
verticalScrollBarThumb?: React.CSSProperties;
174
};
175
176
/**
177
* Control scrollbar visibility
178
* - true: Always show scrollbars
179
* - false: Never show scrollbars
180
* - 'optional': Show only when needed (default)
181
*/
182
showScrollBar?: boolean | 'optional';
183
```
184
185
**Usage Example:**
186
187
```typescript
188
import List from "rc-virtual-list";
189
190
const StyledScrollbarList = () => {
191
const scrollbarStyles = {
192
verticalScrollBar: {
193
width: 12,
194
backgroundColor: '#f0f0f0',
195
borderRadius: 6,
196
},
197
verticalScrollBarThumb: {
198
backgroundColor: '#666',
199
borderRadius: 6,
200
border: '2px solid transparent',
201
},
202
horizontalScrollBar: {
203
height: 12,
204
backgroundColor: '#f0f0f0',
205
borderRadius: 6,
206
},
207
horizontalScrollBarThumb: {
208
backgroundColor: '#666',
209
borderRadius: 6,
210
},
211
};
212
213
return (
214
<List
215
data={data}
216
height={300}
217
itemHeight={50}
218
itemKey="id"
219
scrollWidth={800}
220
styles={scrollbarStyles}
221
showScrollBar={true} // Always show scrollbars
222
>
223
{(item) => <div style={{ width: 800 }}>{item.content}</div>}
224
</List>
225
);
226
};
227
```
228
229
### Scroll Alignment Options
230
231
```typescript { .api }
232
/**
233
* Alignment options for programmatic scrolling
234
*/
235
type ScrollAlign = 'top' | 'bottom' | 'auto';
236
```
237
238
- **`'top'`**: Align the target item to the top of the viewport
239
- **`'bottom'`**: Align the target item to the bottom of the viewport
240
- **`'auto'`**: Smart alignment based on current position (minimal scroll distance)
241
242
### Internal ScrollBar Interface
243
244
```typescript { .api }
245
/**
246
* Internal interface for scrollbar control (not directly accessible)
247
*/
248
interface ScrollBarRef {
249
/** Hide scrollbar after delay */
250
delayHidden: () => void;
251
}
252
```
253
254
This interface is used internally by the List component for scrollbar management and is not accessible to consumers.
255
256
### Advanced Scroll Scenarios
257
258
#### Infinite Scrolling
259
```typescript
260
const InfiniteScrollList = () => {
261
const [data, setData] = useState(initialData);
262
const [loading, setLoading] = useState(false);
263
264
const handleVisibleChange = (visibleItems, allItems) => {
265
const lastVisible = visibleItems[visibleItems.length - 1];
266
const lastIndex = allItems.indexOf(lastVisible);
267
268
// Load more when approaching end
269
if (lastIndex > allItems.length - 10 && !loading) {
270
setLoading(true);
271
loadMoreData().then(newData => {
272
setData(prev => [...prev, ...newData]);
273
setLoading(false);
274
});
275
}
276
};
277
278
return (
279
<List
280
data={data}
281
height={300}
282
itemHeight={50}
283
itemKey="id"
284
onVisibleChange={handleVisibleChange}
285
>
286
{(item) => <div>{item.name}</div>}
287
</List>
288
);
289
};
290
```
291
292
#### Scroll Position Persistence
293
```typescript
294
const PersistentScrollList = () => {
295
const listRef = useRef<ListRef>(null);
296
297
useEffect(() => {
298
// Restore scroll position on mount
299
const savedPosition = localStorage.getItem('listScrollPosition');
300
if (savedPosition) {
301
listRef.current?.scrollTo(parseInt(savedPosition));
302
}
303
}, []);
304
305
const handleVirtualScroll = ({ y }) => {
306
// Save scroll position
307
localStorage.setItem('listScrollPosition', y.toString());
308
};
309
310
return (
311
<List
312
ref={listRef}
313
data={data}
314
height={300}
315
itemHeight={50}
316
itemKey="id"
317
onVirtualScroll={handleVirtualScroll}
318
>
319
{(item) => <div>{item.name}</div>}
320
</List>
321
);
322
};
323
```