Scroll area
Scroll nativo con una barra de desplazamiento mínima, bordes que se desvanecen solo donde hay más por ver y un vistazo opcional que corta el último elemento por la mitad.
pnpm dlx shadcn@latest add https://hextaui.com/r/scroll-area.jsonAñade el componente, los tokens del tema de HextaUI y los componentes de HextaUI de los que depende.
Añade los tokens del tema a tu CSS global, si aún no lo has hecho.
Instala las dependencias.
pnpm add @base-ui/react class-variance-authority cnCopia y pega el siguiente código en tu proyecto.
components/ui/scroll-area.tsx Actualiza las rutas de importación para que coincidan con la configuración de tu proyecto.
Dale al scroll area una altura o un ancho fijos. El contenido que excede ese tamaño se desplaza con el comportamiento de scroll nativo, y aparece una barra fina mientras pasas el cursor o haces scroll.
Peek
Ambas listas tienen la misma altura. Con peek, a la derecha, la caja se recorta para que el último elemento visible quede cortado a medias, lo que muestra que hay más por desplazar antes de que nadie lo intente. Nunca recorta la caja por debajo de la mitad de su altura.
Texto
Los bordes se desvanecen solo donde hay más contenido por desplazar. Arriba solo se desvanece el borde inferior, y el degradado crece a medida que te alejas de un borde.
Empezar abajo
viewportRef te da el elemento que se desplaza. Define su scrollTop para iniciar un chat en el último mensaje, de modo que solo se desvanece el borde superior.
Horizontal
Define scrollbars="horizontal" y dale al contenido w-max para que pueda crecer más allá de la caja.
Ambos ejes
scrollbars="both" muestra ambas barras y una esquina donde se encuentran, y desvanece los cuatro bordes.
Contenido dinámico
El peek y los degradados se actualizan al añadir o quitar elementos. Con muy pocos elementos para desplazar, la caja mantiene su altura y nada se desvanece.
Sobre una superficie de color
El degradado es una máscara sobre el contenido, no un color superpuesto, así que funciona sobre cualquier fondo.
Dentro de una hoja
Dentro de una columna flex, envuélvelo en un elemento con min-h-0 flex-1 y dale al scroll area h-full para que ocupe el espacio restante.
Sin fade
Desactiva los degradados de los bordes con fade={false}.
De derecha a izquierda
El contenido empieza en el borde derecho, la barra de scroll y los degradados siguen la dirección de lectura, y la dirección se toma de la página.
El viewport entra en el orden de tabulación solo cuando tiene algo que desplazar. Una vez enfocado, se desplaza con las teclas nativas del navegador.
| Key | Acción |
|---|---|
| Tab | Enfoca el viewport cuando su contenido se desborda. |
| ↑↓ | Se desplaza verticalmente. |
| ←→ | Se desplaza horizontalmente. |
| Page UpPage DownSpace | Se desplaza una página. |
| HomeEnd | Salta al inicio o al final. |
- Dale al scroll area un
aria-labelcuando su propósito no quede claro por el contenido que lo rodea, como la etiqueta “Messages” en el ejemplo del chat. - El anillo de foco se dibuja en el propio scroll area, así que sigue visible por encima de los bordes desvanecidos.
Construido sobre el scroll area de Base UI. ScrollArea renderiza juntos la raíz, el viewport, el contenido y las barras de scroll.
| Prop | Tipo | Predeterminado |
|---|---|---|
scrollbars | "vertical" | "horizontal" | "both" | "vertical" |
fadeDesvanece los bordes que tienen más contenido. | boolean | true |
peekRecorta la altura para que el último elemento visible quede cortado a medias. Marca los elementos con data-scroll-area-item para elegir cuáles cuentan. | boolean | false |
viewportRefEl elemento que se desplaza. | Ref<HTMLDivElement> | – |
overflowEdgeThresholdPíxeles que hay que desplazar para que un borde cuente como desbordado. | number | { xStart, xEnd, yStart, yEnd } | 0 |
className | string | (state) => string | – |
render | ReactElement | (props, state) => ReactElement | <div> |
| Atributo | Descripción |
|---|---|
data-slot="scroll-area" | La raíz. |
data-slot="scroll-area-viewport" | El elemento que se desplaza. |
data-slot="scroll-area-content" | Envuelve tu contenido dentro del viewport. |
data-peek | Presente cuando peek está activado. |
data-peeking | Presente mientras peek recorta la altura. |
data-scrolling | Presente mientras el usuario hace scroll. |
data-has-overflow-x | Presente cuando el contenido es más ancho que el viewport. |
data-has-overflow-y | Presente cuando el contenido es más alto que el viewport. |
data-overflow-y-start | Presente cuando hay más contenido arriba. Existen atributos equivalentes -y-end, -x-start y -x-end para los otros bordes. |
--scroll-area-fade | Tamaño del degradado del borde. Por defecto es 2.5rem. |
--scroll-area-overflow-y-start | Distancia desde el borde superior en píxeles. Existen variables equivalentes -y-end, -x-start y -x-end. |
Lo renderiza ScrollArea por ti. Expórtalo solo si compones tú mismo las partes de Base UI.
| Prop | Tipo | Predeterminado |
|---|---|---|
orientation | "vertical" | "horizontal" | "vertical" |
render | ReactElement | (props, state) => ReactElement | <div> |
| Atributo | Descripción |
|---|---|
data-slot="scroll-area-scrollbar" | La pista de la barra de scroll. |
data-slot="scroll-area-thumb" | El thumb arrastrable. |
data-orientation | vertical u horizontal. |
data-hovering | Presente mientras el puntero está sobre el área. |
data-scrolling | Presente mientras el usuario hace scroll. |
--scroll-area-thumb-height | La altura del thumb. |
--scroll-area-thumb-width | El ancho del thumb. |
- AccordionEncabezados apilados que revelan cada uno un panel, con un movimiento de altura que puedes invertir a mitad de camino y paneles que siguen siendo buscables mientras están cerrados.
- Aspect ratioUn contenedor que mantiene su forma antes de que cargue el contenido multimedia, muestra un brillo mientras carga, hace aparecer el contenido con un fundido y muestra una alternativa si falla.
- CarouselDiapositivas nativas con scroll-snap, con inercia en pantallas táctiles, arrastre con el ratón, teclas de flecha, puntos, miniaturas y una reproducción automática que se pausa cuando debe.
- CollapsibleUn panel que se muestra y se oculta con un movimiento de altura que puedes invertir a mitad de camino, sin saltos en el diseño.
- ResizablePaneles que puedes separar arrastrando, con un divisor discreto que despierta al pasar el cursor, tamaños que se deslizan al restablecer o colapsar, y diseños que persisten.
- SeparatorUna línea fina que divide el contenido horizontal o verticalmente, con una etiqueta opcional y un modo decorativo para líneas puramente visuales.