Tags
import { ScrollArea } from "@/components/ui/scroll-area"
import { Separator } from "@/components/ui/separator"
const tags = Array.from({ length: 50 }).map((_, i, a) => `v1.2.0-beta.${a.length - i}`)
export default function ScrollAreaDemo() {
return (
<ScrollArea className="h-72 w-48 rounded-md border">
<div className="p-4">
<h4 className="mb-4 text-sm font-medium leading-none">Tags</h4>
{tags.map((tag) => (
<div key={tag}>
<div className="text-sm">{tag}</div>
<Separator className="my-2" />
</div>
))}
</div>
</ScrollArea>
)
}Installation
npx logic2b@latest add scroll-areaWorking with an AI assistant? Copy this prompt into Claude Code, Cursor or Copilot — it carries the install steps, a no-CLI fallback and a verification checklist.
Add the "scroll-area" item from the logic2b ui registry (https://ui.logic2b.com) to this project. Follow every step and verify at the end. ## Steps 1. If the project has no `components.json` yet, set up logic2b ui first: ```bash npx logic2b@latest init ``` 2. Install the item (the CLI resolves registry dependencies automatically): ```bash npx logic2b@latest add scroll-area ``` 3. Install any npm dependencies the command prints. ## If the CLI is not available Do it manually from the registry payload: 1. Fetch https://ui.logic2b.com/r/scroll-area.json. 2. Write every entry in `files[]` to its mapped project path (see below). 3. Repeat (recursively) for each name in `registryDependencies`. 4. Install every package listed in `dependencies` across those payloads. ## Registry reference - Index of every item: https://ui.logic2b.com/r/index.json - Item payload (full source): https://ui.logic2b.com/r/<name>.json - Usage examples per item: https://ui.logic2b.com/r/demos/index.json → https://ui.logic2b.com/r/demos/<demo>.json - Docs index for agents: https://ui.logic2b.com/llms.txt (full docs: https://ui.logic2b.com/llms-full.txt) - Every docs page is Markdown when you append `.md` to its URL. Registry file paths map to project paths like this: - `ui/*` → `@/components/ui/*` - `blocks/<name>/*` → `@/components/*` - `charts/*` → `@/components/charts/*` - `hooks/*` → `@/hooks/*` - `lib/utils.ts` → `@/lib/utils.ts` - `theme.css` → next to the project's Tailwind entry stylesheet ## Conventions (do not break these) - Tailwind CSS v4 (CSS-first config; no tailwind.config.js needed) and React 19. - All colors go through semantic tokens (`bg-primary`, `text-muted-foreground`, `border-border`, …). Never hardcode hex/oklch values in components. - Dark mode is class-based: toggle `.dark` on `<html>`. - Icons come from lucide-react. ## Verify before finishing 1. The dev server starts and the app renders without console errors. 2. TypeScript compiles (`tsc --noEmit` or the framework's check). 3. Components use the theme: a `<Button>` shows the primary token color, and toggling `.dark` on `<html>` switches the palette.
Install the dependencies:
npm install radix-uiCopy into ui/scroll-area.tsx:
"use client"
import * as React from "react"
import { ScrollArea as ScrollAreaPrimitive } from "radix-ui"
import { cn } from "@/lib/utils"
function ScrollArea({
className,
children,
...props
}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
return (
<ScrollAreaPrimitive.Root
data-slot="scroll-area"
className={cn("relative", className)}
{...props}
>
<ScrollAreaPrimitive.Viewport
data-slot="scroll-area-viewport"
className="focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
>
{children}
</ScrollAreaPrimitive.Viewport>
<ScrollBar />
<ScrollAreaPrimitive.Corner />
</ScrollAreaPrimitive.Root>
)
}
function ScrollBar({
className,
orientation = "vertical",
...props
}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
return (
<ScrollAreaPrimitive.ScrollAreaScrollbar
data-slot="scroll-area-scrollbar"
orientation={orientation}
className={cn(
"flex touch-none p-px transition-colors select-none",
orientation === "vertical" &&
"h-full w-2.5 border-l border-l-transparent",
orientation === "horizontal" &&
"h-2.5 flex-col border-t border-t-transparent",
className
)}
{...props}
>
<ScrollAreaPrimitive.ScrollAreaThumb
data-slot="scroll-area-thumb"
className="bg-border relative flex-1 rounded-full"
/>
</ScrollAreaPrimitive.ScrollAreaScrollbar>
)
}
export { ScrollArea, ScrollBar }Usage
import { ScrollArea } from "@/components/ui/scroll-area"
<ScrollArea className="h-72 w-48 rounded-md border">
Jokester began sneaking into the castle in the middle of the night...
</ScrollArea>
Set the viewport size with className (height/width) — the content scrolls
inside it. For horizontal scrolling, render a ScrollBar with
orientation="horizontal" inside the ScrollArea.
API
| Prop | Type | Default |
|---|---|---|
type (ScrollArea) |
auto | always | scroll | hover |
hover |
scrollHideDelay (ScrollArea) |
number (ms) |
600 |
orientation (ScrollBar) |
vertical | horizontal |
vertical |
Examples
Horizontal
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area"
const figures = Array.from({ length: 12 }).map((_, i) => `Figure ${i + 1}`)
export default function ScrollAreaHorizontalDemo() {
return (
<ScrollArea className="w-96 rounded-md border whitespace-nowrap">
<div className="flex w-max gap-4 p-4">
{figures.map((figure) => (
<div
key={figure}
className="bg-muted flex size-28 shrink-0 items-center justify-center rounded-md text-sm font-medium"
>
{figure}
</div>
))}
</div>
<ScrollBar orientation="horizontal" />
</ScrollArea>
)
}Long text
Terms of Service
By accessing this registry you agree to copy, adapt, and ship these components in your own projects without attribution.
Components are provided as-is. You own the code once it lands in your repository and are free to modify every token, variant, and style.
Updates are opt-in: re-run the installer whenever you want the latest version of a component, then reconcile any local changes.
Accessibility primitives are inherited from the underlying libraries. Test your own compositions before shipping to production.
import { ScrollArea } from "@/components/ui/scroll-area"
export default function ScrollAreaProseDemo() {
return (
<ScrollArea className="h-52 w-80 rounded-md border p-4">
<h4 className="mb-3 text-sm font-medium">Terms of Service</h4>
<div className="text-muted-foreground space-y-3 text-sm">
<p>
By accessing this registry you agree to copy, adapt, and ship these
components in your own projects without attribution.
</p>
<p>
Components are provided as-is. You own the code once it lands in your
repository and are free to modify every token, variant, and style.
</p>
<p>
Updates are opt-in: re-run the installer whenever you want the latest
version of a component, then reconcile any local changes.
</p>
<p>
Accessibility primitives are inherited from the underlying libraries.
Test your own compositions before shipping to production.
</p>
</div>
</ScrollArea>
)
}