shadcn.io is an independent project built on shadcn/ui
Files and Preview sit side by side, with a drag handle between them. Files lists file-1.tsx onward. Preview is titled File Content and holds several paragraphs. Each side scrolls.
Use two scrolling panes for a list and a preview, such as a file browser. A Resizable pair is enough when each side is short. Base UI in React does not read the files.
Installation
Anatomy

Usage
<Resizable
className="max-w-4xl rounded-lg border bg-background"
orientation="horizontal"
>
<ResizablePanel defaultSize="50%" minSize="30%">
<div className="flex h-[400px] flex-col">
<div className="border-b p-4">
<h3 className="font-semibold">Files</h3>
</div>
<ScrollArea className="min-h-0 flex-1">
<div className="flex flex-col gap-1 p-2">
{files.map((file) => (
<button
className="w-full rounded-md px-3 py-2 text-start text-sm transition-colors hover:bg-accent"
key={file.name}
type="button"
>
<div className="font-medium">{file.name}</div>
<div className="text-muted-foreground text-xs">
{file.updated}
</div>
</button>
))}
</div>
</ScrollArea>
</div>
</ResizablePanel>
<ResizableResizeTrigger withHandle />
<ResizablePanel defaultSize="50%" minSize="30%">
<div className="flex h-[400px] flex-col">
<div className="border-b p-4">
{/* The rest of the file is under Installation. */}FAQ
How are the two panels sized?
Files and Preview sit side by side. Each one starts at half the group.
Each ResizablePanel has defaultSize "50%" and minSize "30%". orientation is horizontal on Resizable, so those values are widths. For minSize, a number is pixels and a percentage is a string.
What does withHandle do?
ResizableResizeTrigger sets withHandle, which shows the grip between Files and Preview. The trigger's accessible name is Resize. Focus it and the arrow keys change the sizes. Home and End jump toward the ends of the range.
Why do the scroll areas use min-h-0 and flex-1?
Each panel's body is a h-[400px] column, flex flex-col. The header is a border-b row. ScrollArea has min-h-0 flex-1, so it takes the height left under that header and scrolls inside it.
What is in the Files list?
Thirty buttons, type button, labeled file-1.tsx through file-30.tsx, each with "Updated N days ago" in text-xs text-muted-foreground. The button is w-full with px-3 py-2 and hover:bg-accent. The list wrapper is gap-1 p-2.
API Reference
Resizable
Sets orientation="horizontal", defaultSize="50%", minSize="30%" and withHandle. The rest is on the Resizable page.
Scroll Area
No extra props in this demo. The rest is on the Scroll Area page.






