Virtual scroll
Lista virtualizada — 10 mil filas, ~25 nodos del DOM.
- Navegadores
- Chrome 123+Firefox 121+Safari 17.5+
- Nivel
- 2
- Tamaño comprimido
- 4.16 kB
- Presupuesto de diseño forzado
- 0 ms
- Presupuesto de axe
- 0
- Compatible con SSR
- Sí
- Contrato publicado
- Entorno de pruebas
Zona de pruebas
Virtual scroll
10,000 team members with checkbox, avatar, and dropdown actions. Only visible rows (+ buffer) mount in the DOM — open DevTools and count [data-uiify-virtual-scroll] [data-part="row"] nodes while scrolling.
Horizontal
The same users as a horizontal strip with orientation="horizontal". rowHeight sets each card's width; the window follows the viewport width.
API
VirtualScroll
| Prop | Tipo | Predeterminado | Descripción |
|---|---|---|---|
items* | T[] | — | Lista completa de elementos, cada uno con un id estable; solo se renderizan las filas del rango actual. |
renderRow* | (item: T, index: number) => ReactNode | — | Renderiza el contenido de una fila a partir de su elemento y su índice absoluto. |
height | number | — | Altura explícita en píxeles. Omítela y pasa style={{ blockSize: '100%' }} para ocupar una altura definida del elemento padre; si no se proporciona ninguna, el valor predeterminado es 600px. |
rowHeight | number | 64 | Tamaño fijo en píxeles de cada fila sobre el eje de desplazamiento (altura en vertical, ancho en horizontal); se usa para calcular el tamaño desplazable y las filas visibles. |
orientation | "vertical" | "horizontal" | "vertical" | Eje de desplazamiento. Las listas horizontales se desplazan sobre el eje en línea, calculan la ventana a partir del ancho medido del área visible, se reflejan correctamente en diseños de derecha a izquierda y reflejan el valor en data-orientation. |
overscan | number | 5 | Número de filas adicionales renderizadas antes y después del rango visible para que el desplazamiento rápido no muestre espacios vacíos. |
estimateRowHeight | (index: number) => number | — | Estimación de altura por índice que cambia la lista a una distribución dinámica, donde se miden las filas renderizadas y se corrige la estimación. |
role | "list" | "grid" | "list" | Rol ARIA aplicado al contenedor de desplazamiento. |
anchor | "start" | "end" | "start" | Extremo de la lista al que permanece fijada la posición de desplazamiento al añadir o quitar elementos. |
followAppend | boolean | "smooth" | false | Se desplaza hasta los elementos recién añadidos cuando la lista ya está al final, opcionalmente con desplazamiento suave. |
scrollRef | Ref<VirtualScrollHandle> | — | Recibe el manejador imperativo que expone scrollToIndex, scrollToOffset y scrollToEnd. |
onRangeChange | (range: VirtualScrollRangeChange) => void | — | Se llama con los rangos de índices visibles y adicionales cada vez que se mueve la ventana renderizada. |
onScrollStateChange | (state: VirtualScrollScrollState) => void | — | Se llama cuando comienza el desplazamiento y cuando se detiene. |
isScrollingResetDelay | number | 150 | Milisegundos sin movimiento para considerar terminado el desplazamiento en navegadores sin el evento scrollend. |
className | string | — | Clase aplicada al contenedor de desplazamiento. |
testId | string | — | Valor del atributo data-testid del contenedor de desplazamiento. |
Teclado
| Tecla | Acción |
|---|---|
| Scroll | La rueda, el panel táctil o la barra de desplazamiento mueven la ventana |
| Tab | Mover el foco entre controles de fila (casilla de verificación, activador de menú) |
| Arrow keys | Recorrer los elementos de un menú desplegable abierto |
| Escape | Cerrar un menú desplegable abierto |
Accesibilidad
Un espaciador de altura completa mantiene precisa la barra de desplazamiento nativa mientras solo se monta un conjunto fijo de espacios de fila y algunas filas adicionales; las claves estables de los espacios reciclan nodos del DOM. Las filas exponen role="listitem" con aria-posinset y aria-setsize dentro de un área de desplazamiento role="list". La sincronización del desplazamiento es pasiva y los saltos grandes, como los de la barra de desplazamiento, Home/End o Cmd+Arrow, actualizan el rango de forma síncrona.
Puntos de estilo
data-uiify-virtual-scrolldata-part="spacer"data-part="row"