---
id: "packages/active-ui/list-scroll-area"
title: "ListScrollArea"
description: "The scrolling area of a long option list in a popup, with a visible scrollbar and no extra tab stop."
url: "/packages/active-ui/list-scroll-area"
locale: "en"
revision: "175745c42e37848e"
---

# ListScrollArea

`ListScrollArea` scrolls a long list of options inside a popup, with the same visible scrollbar as
the sidebar, so the reader sees where in the list they are and can drag to its end. The pickers and
the [Calendar](/packages/active-ui/calendar) year list use it; use it for your own long list, such
as a [Command](/packages/active-ui/command) list.

**Example: A long list with a visible scrollbar**

Client: Runs entirely in your browser. Source: `examples/ui/list-scroll-area.tsx`.

```tsx
// apps/docs/examples/ui/list-scroll-area.tsx
'use client';

import {useState} from 'react';

import {ListScrollArea} from '@workspace/active-ui/components/composed/list-scroll-area';
import {
  Command,
  CommandEmpty,
  CommandInput,
  CommandItem,
  CommandList,
} from '@workspace/active-ui/components/primitives/command';

const YEARS = Array.from({length: 120}, (_, index) => String(2026 - index));

/**
 * A long option list with a visible scrollbar. The command list gives up its
 * own height and overflow; the scroll area bounds and scrolls it. The arrow
 * keys keep the active option in view.
 */
export default function ListScrollAreaExample() {
  const [year, setYear] = useState('2026');
  return (
    <div className="grid w-full max-w-xs gap-2">
      <Command className="rounded-md border">
        <CommandInput placeholder="Search a year…" aria-label="Search a year" />
        <ListScrollArea className="max-h-56" viewportClassName="p-1">
          <CommandList className="max-h-none overflow-visible">
            <CommandEmpty>No year found.</CommandEmpty>
            {YEARS.map((value) => (
              <CommandItem key={value} value={value} onSelect={setYear}>
                {value}
              </CommandItem>
            ))}
          </CommandList>
        </ListScrollArea>
      </Command>
      <p className="text-muted-foreground text-sm">Chosen: {year}</p>
    </div>
  );
}
```

## What the composition adds

- **A visible scrollbar** on a list whose own bar is hidden, built from the
  [ScrollArea](/packages/active-ui/scroll-area) scrollbar.
- **The list keeps its keyboard**: moving the active option scrolls this area, and the area itself is
  not a tab stop.
- **No scroll chaining**: at the end of the list the page behind the popup does not scroll.

## Usage

```tsx
import {ListScrollArea} from '@workspace/active-ui/components/composed/list-scroll-area';

<Command>
  <CommandInput aria-label="Search a year" />
  <ListScrollArea className="max-h-56" viewportClassName="p-1">
    <CommandList className="max-h-none overflow-visible">…</CommandList>
  </ListScrollArea>
</Command>;
```

## What your application provides

- The maximum height on `className`, and the list's own height limit and overflow switched off, as
  in the example.

## API

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `children` | `ReactNode` | yes | The option list. |
| `className` | `string` | no | The maximum height, and anything else for the Root. |
| `viewportClassName` | `string` | no | Padding and scroll padding of the scrolling element. |
