@biem/ui

Scroll Area

A container that lets users scroll through content that is larger than the space available.

A scroll area holds content that is larger than the space it has and lets users scroll through it. It hides the scrollbars of the browser and draws its own, which look the same on every platform and appear only in a direction in which the content overflows. The vertical scrollbar is built in, and a ScrollBar with a horizontal orientation adds the second one. The scroll area takes the width of its parent and the height of its content. To scroll vertically, it needs a parent that stretches it to a fixed height, such as the grid with a single row in the examples.

Usage

scroll-area-default.tsx
import { ScrollArea } from "@biem/ui/components/ui/scroll-area";

const products = [
	{ name: "Sparkling water", cases: 12 },
	{ name: "Orange juice", cases: 8 },
	{ name: "Oat milk", cases: 6 },
	{ name: "Ground coffee", cases: 4 },
	{ name: "Green tea", cases: 3 },
	{ name: "Dark chocolate", cases: 5 },
	{ name: "Olive oil", cases: 2 },
	{ name: "Tomato sauce", cases: 9 },
	{ name: "Whole milk", cases: 10 },
	{ name: "Butter", cases: 4 },
	{ name: "Rolled oats", cases: 6 },
	{ name: "Basmati rice", cases: 7 },
	{ name: "Spaghetti", cases: 11 },
	{ name: "Sea salt", cases: 2 },
	{ name: "Apple juice", cases: 8 },
	{ name: "Honey", cases: 3 },
];

export function ScrollAreaDefault() {
	return (
		<div className="grid h-72 w-full max-w-sm grid-rows-1 rounded-lg border">
			<ScrollArea>
				<ul className="grid gap-2 p-4 text-sm">
					{products.map((product) => (
						<li key={product.name} className="flex justify-between">
							<span>{product.name}</span>
							<span className="text-muted-foreground">{product.cases} cases</span>
						</li>
					))}
				</ul>
			</ScrollArea>
		</div>
	);
}

Examples

Horizontal

Some content runs sideways rather than downward, such as the delivery slots of a full week or the key figures of every store in a region. With orientation set to "horizontal", a ScrollBar lets users scroll along that content while the page around it keeps its width. No fixed height is needed in this direction, because the scroll area takes the height of its content.

Vertical and Horizontal

Large overviews often outgrow their container in both directions, such as a price comparison of every product across all stores. Next to the vertical scrollbar that the scroll area brings, a ScrollBar with orientation set to "horizontal" lets users reach every part of the overview while the rest of the page stays in place. For the vertical direction to scroll as well, the scroll area needs a parent that gives it a fixed height.

API Reference

ScrollArea

PropoverflowEdgeThreshold
Typenumber | Partial<{ xStart: number; xEnd: number; yStart: number; yEnd: number }>
Default0
DescriptionSets the number of pixels that the hidden content beyond an edge must exceed before the scroll area sets the data attribute of that edge on itself, its viewport and its scrollbars: data-overflow-x-start, data-overflow-x-end, data-overflow-y-start or data-overflow-y-end. A number applies to all four edges, and an object sets each edge on its own.
Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the scroll area with another component.

ScrollBar

Proporientation
Type"vertical" | "horizontal"
Default"vertical"
DescriptionSets the direction in which the scrollbar scrolls the content. ScrollArea renders the vertical scrollbar itself, so a ScrollBar inside it needs "horizontal".
PropkeepMounted
Typeboolean
Defaultfalse
DescriptionKeeps the scrollbar in the DOM while the content doesn't overflow in its direction. Without it, the scroll area renders the scrollbar only while there is content to scroll.
Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the scrollbar with another component.