@@ -290,6 +290,110 @@ const generateData = (columns: Array<Column>, count = 300) => {
290
290
)
291
291
}
292
292
293
+ function RowVirtualizerExperimental ( ) {
294
+ const parentRef = React . useRef < HTMLDivElement > ( null )
295
+ const innerRef = React . useRef < HTMLDivElement > ( null )
296
+ const rowRefsMap = React . useRef ( new Map < number , HTMLDivElement > ( ) )
297
+
298
+ const [ enabled , setEnabled ] = React . useState ( true )
299
+
300
+ const count = sentences . length
301
+ const virtualizer = useVirtualizer ( {
302
+ count,
303
+ getScrollElement : ( ) => parentRef . current ,
304
+ estimateSize : ( ) => 45 ,
305
+ enabled,
306
+ onChange : ( instance ) => {
307
+ innerRef . current ! . style . height = `${ instance . getTotalSize ( ) } px`
308
+ instance . getVirtualItems ( ) . forEach ( ( virtualRow ) => {
309
+ const rowRef = rowRefsMap . current . get ( virtualRow . index )
310
+ if ( ! rowRef ) return
311
+ rowRef . style . transform = `translateY(${ virtualRow . start } px)`
312
+ } )
313
+ } ,
314
+ } )
315
+
316
+ const indexes = virtualizer . getVirtualIndexes ( )
317
+
318
+ React . useEffect ( ( ) => {
319
+ virtualizer . measure ( )
320
+ } , [ ] )
321
+
322
+ return (
323
+ < div >
324
+ < button
325
+ onClick = { ( ) => {
326
+ virtualizer . scrollToIndex ( 0 )
327
+ } }
328
+ >
329
+ scroll to the top
330
+ </ button >
331
+ < span style = { { padding : '0 4px' } } />
332
+ < button
333
+ onClick = { ( ) => {
334
+ virtualizer . scrollToIndex ( count / 2 )
335
+ } }
336
+ >
337
+ scroll to the middle
338
+ </ button >
339
+ < span style = { { padding : '0 4px' } } />
340
+ < button
341
+ onClick = { ( ) => {
342
+ virtualizer . scrollToIndex ( count - 1 )
343
+ } }
344
+ >
345
+ scroll to the end
346
+ </ button >
347
+ < span style = { { padding : '0 4px' } } />
348
+ < button
349
+ onClick = { ( ) => {
350
+ setEnabled ( ( prev ) => ! prev )
351
+ } }
352
+ >
353
+ turn { enabled ? 'off' : 'on' } virtualizer
354
+ </ button >
355
+ < hr />
356
+ < div
357
+ ref = { parentRef }
358
+ className = "List"
359
+ style = { {
360
+ height : 400 ,
361
+ width : 400 ,
362
+ overflowY : 'auto' ,
363
+ contain : 'strict' ,
364
+ } }
365
+ >
366
+ < div
367
+ ref = { innerRef }
368
+ style = { {
369
+ width : '100%' ,
370
+ position : 'relative' ,
371
+ } }
372
+ >
373
+ { indexes . map ( ( index ) => (
374
+ < div
375
+ key = { index }
376
+ data-index = { index }
377
+ ref = { ( el ) => {
378
+ if ( el ) {
379
+ virtualizer . measureElement ( el )
380
+ rowRefsMap . current . set ( index , el )
381
+ }
382
+ } }
383
+ className = { index % 2 ? 'ListItemOdd' : 'ListItemEven' }
384
+ >
385
+ < div style = { { padding : '10px 0' } } >
386
+ < div > Row { index } </ div >
387
+ < div > { sentences [ index ] } </ div >
388
+ </ div >
389
+ </ div >
390
+ ) ) }
391
+ </ div >
392
+ </ div >
393
+ </ div >
394
+ )
395
+ }
396
+
293
397
function App ( ) {
294
398
const pathname = location . pathname
295
399
return (
@@ -314,6 +418,9 @@ function App() {
314
418
< li >
315
419
< a href = "/grid" > Grid</ a >
316
420
</ li >
421
+ < li >
422
+ < a href = "/experimental" > Experimental</ a >
423
+ </ li >
317
424
</ ul >
318
425
</ nav >
319
426
{ ( ( ) => {
@@ -327,6 +434,8 @@ function App() {
327
434
const data = generateData ( columns )
328
435
return < GridVirtualizerDynamic columns = { columns } data = { data } />
329
436
}
437
+ case '/experimental' :
438
+ return < RowVirtualizerExperimental />
330
439
default :
331
440
return < div > Not found</ div >
332
441
}
@@ -344,7 +453,6 @@ function App() {
344
453
)
345
454
}
346
455
347
- // eslint-disable-next-line
348
456
const container = document . getElementById ( 'root' ) !
349
457
const root = createRoot ( container )
350
458
const { StrictMode } = React
0 commit comments