> For AI agents: the complete documentation index is available at https://wallarm.github.io/design-system/llms.txt, the full documentation bundle is available at https://wallarm.github.io/design-system/llms-full.txt.

# ScrollArea

A scroll container with the house scrollbar instead of the browser’s: compose `ScrollAreaViewport` › `ScrollAreaContent`, then one `ScrollAreaScrollbar` per axis and a `ScrollAreaCorner` where two of them meet. It can only scroll inside a bounded parent, so give the wrapper a height or a width — with nothing to overflow, the content simply grows.

[Source](https://github.com/wallarm/design-system/tree/main/packages/design-system/src/components/ScrollArea) · [Storybook](https://wallarm.github.io/design-system/storybook/?path=/docs/layout-scrollarea--overview)

```tsx
import { ScrollArea, ScrollAreaContent, ScrollAreaCorner, ScrollAreaScrollbar, ScrollAreaViewport } from '@wallarm-org/design-system/ScrollArea';
import { VStack } from '@wallarm-org/design-system/Stack';

export const Vertical = () => (
  <div className='w-320 h-320 overflow-hidden'>
    <ScrollArea>
      <ScrollAreaViewport>
        <ScrollAreaContent>
          <VStack>
            {new Array(50).fill(null).map((_, index) => {
              const value = `${index + 1}`;

              return (
                <Box key={value} className='h-40 w-full'>
                  {value}
                </Box>
              );
            })}
          </VStack>
        </ScrollAreaContent>
      </ScrollAreaViewport>

      <ScrollAreaScrollbar />

      <ScrollAreaCorner />
    </ScrollArea>
  </div>
);
```

## Usage

```tsx
import { ScrollArea, ScrollAreaContent, ScrollAreaCorner, ScrollAreaScrollbar, ScrollAreaViewport } from '@wallarm-org/design-system/ScrollArea';
import { VStack } from '@wallarm-org/design-system/Stack';
```

## Examples

### Horizontal

`orientation='horizontal'` puts the bar along the bottom edge, for a row that runs past its container rather than a column that runs below it.

```tsx
import { ScrollArea, ScrollAreaContent, ScrollAreaCorner, ScrollAreaScrollbar, ScrollAreaViewport } from '@wallarm-org/design-system/ScrollArea';
import { HStack } from '@wallarm-org/design-system/Stack';

export const Horizontal = () => (
  <div className='w-320 h-320 overflow-hidden'>
    <ScrollArea>
      <ScrollAreaViewport>
        <ScrollAreaContent>
          <HStack>
            {new Array(50).fill(null).map((_, index) => {
              const value = `${index + 1}`;

              return (
                <Box key={value} className='h-320 w-40'>
                  {value}
                </Box>
              );
            })}
          </HStack>
        </ScrollAreaContent>
      </ScrollAreaViewport>

      <ScrollAreaScrollbar orientation='horizontal' />

      <ScrollAreaCorner />
    </ScrollArea>
  </div>
);
```

### Virtualized

`ScrollAreaViewport` forwards its `ref` to the scrolling element itself, so a row
virtualiser such as `@tanstack/react-virtual` can track scroll position inside the
house scrollbar instead of falling back to a bare `overflow-y: auto` div. Ten thousand
rows here, a few dozen in the DOM.

Two things this story is deliberately showing:

- `useVirtualizer` is called in the same component that declares the ref. Called from a
  component rendered _inside_ the viewport, `getScrollElement()` runs once — before React
  has attached the host element's ref — returns `null`, and nothing ever re-runs it, so the
  list stays permanently empty.
- `ScrollAreaContent` gets `h-auto min-h-full` so it grows with the virtual sizer. The
  scrollbar is only rendered while the viewport reports `data-overflow-y`, and that flag is
  recomputed from a `ResizeObserver` watching the content box — which at its default `h-full`
  stays the height of the viewport. A list that grows _after_ mount therefore keeps its
  scrollbar hidden until something else forces a remeasure.

```tsx
import { useRef } from 'react';
import { useVirtualizer } from '@tanstack/react-virtual';
import { ScrollArea, ScrollAreaContent, ScrollAreaCorner, ScrollAreaScrollbar, ScrollAreaViewport } from '@wallarm-org/design-system/ScrollArea';

export const Virtualized = () => {
  const scrollRef = useRef<HTMLDivElement>(null);
  const virtualizer = useVirtualizer({
    count: 10_000,
    getScrollElement: () => scrollRef.current,
    estimateSize: () => 44,
    overscan: 8,
  });

  return (
    <div className='w-320 h-320 overflow-hidden'>
      <ScrollArea>
        <ScrollAreaViewport ref={scrollRef}>
          <ScrollAreaContent className='h-auto min-h-full'>
            <div className='relative w-full' style={{ height: virtualizer.getTotalSize() }}>
              {virtualizer.getVirtualItems().map(item => (
                <div
                  key={item.key}
                  className='absolute top-0 left-0 w-full pb-4'
                  style={{ height: item.size, transform: `translateY(${item.start}px)` }}
                >
                  <Box className='h-full w-full'>{item.index + 1}</Box>
                </div>
              ))}
            </div>
          </ScrollAreaContent>
        </ScrollAreaViewport>

        <ScrollAreaScrollbar />

        <ScrollAreaCorner />
      </ScrollArea>
    </div>
  );
};
```

## Props

| Prop           | Type                                                 | Default | Description                                                                                         |
| -------------- | ---------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------- |
| title          | `string \| undefined`                                |         |                                                                                                     |
| defaultChecked | `boolean \| undefined`                               |         |                                                                                                     |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |                                                                                                     |
| autoFocus      | `boolean \| undefined`                               |         |                                                                                                     |
| id             | `string \| undefined`                                |         |                                                                                                     |
| tabIndex       | `number \| undefined`                                |         |                                                                                                     |
| rel            | `string \| undefined`                                |         |                                                                                                     |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |                                                                                                     |
| ids            | `ElementIds \| undefined`                            |         | The ids of the scroll area elements                                                                 |
| asChild        | `boolean \| undefined`                               |         | Use the provided child element as the default rendered element, combining their props and behavior. |
| data-testid    | `string \| undefined`                                |         |                                                                                                     |

### ScrollAreaContent

| Prop           | Type                                                 | Default | Description                                                                                         |
| -------------- | ---------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------- |
| title          | `string \| undefined`                                |         |                                                                                                     |
| defaultChecked | `boolean \| undefined`                               |         |                                                                                                     |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |                                                                                                     |
| autoFocus      | `boolean \| undefined`                               |         |                                                                                                     |
| id             | `string \| undefined`                                |         |                                                                                                     |
| tabIndex       | `number \| undefined`                                |         |                                                                                                     |
| rel            | `string \| undefined`                                |         |                                                                                                     |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |                                                                                                     |
| asChild        | `boolean \| undefined`                               |         | Use the provided child element as the default rendered element, combining their props and behavior. |
| data-testid    | `string \| undefined`                                |         |                                                                                                     |

### ScrollAreaCorner

| Prop           | Type                                                 | Default | Description                                                                                         |
| -------------- | ---------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------- |
| title          | `string \| undefined`                                |         |                                                                                                     |
| defaultChecked | `boolean \| undefined`                               |         |                                                                                                     |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |                                                                                                     |
| autoFocus      | `boolean \| undefined`                               |         |                                                                                                     |
| id             | `string \| undefined`                                |         |                                                                                                     |
| tabIndex       | `number \| undefined`                                |         |                                                                                                     |
| rel            | `string \| undefined`                                |         |                                                                                                     |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |                                                                                                     |
| asChild        | `boolean \| undefined`                               |         | Use the provided child element as the default rendered element, combining their props and behavior. |
| data-testid    | `string \| undefined`                                |         |                                                                                                     |

### ScrollAreaScrollbar

| Prop           | Type                                                 | Default    | Description                                                                                         |
| -------------- | ---------------------------------------------------- | ---------- | --------------------------------------------------------------------------------------------------- |
| title          | `string \| undefined`                                |            |                                                                                                     |
| defaultChecked | `boolean \| undefined`                               |            |                                                                                                     |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |            |                                                                                                     |
| autoFocus      | `boolean \| undefined`                               |            |                                                                                                     |
| id             | `string \| undefined`                                |            |                                                                                                     |
| tabIndex       | `number \| undefined`                                |            |                                                                                                     |
| rel            | `string \| undefined`                                |            |                                                                                                     |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |            |                                                                                                     |
| asChild        | `boolean \| undefined`                               |            | Use the provided child element as the default rendered element, combining their props and behavior. |
| orientation    | `Orientation \| undefined`                           | `vertical` |                                                                                                     |
| data-testid    | `string \| undefined`                                |            |                                                                                                     |

### ScrollAreaViewport

| Prop           | Type                                                 | Default | Description                                                                                         |
| -------------- | ---------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------- |
| title          | `string \| undefined`                                |         |                                                                                                     |
| defaultChecked | `boolean \| undefined`                               |         |                                                                                                     |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |                                                                                                     |
| autoFocus      | `boolean \| undefined`                               |         |                                                                                                     |
| id             | `string \| undefined`                                |         |                                                                                                     |
| tabIndex       | `number \| undefined`                                |         |                                                                                                     |
| rel            | `string \| undefined`                                |         |                                                                                                     |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |                                                                                                     |
| asChild        | `boolean \| undefined`                               |         | Use the provided child element as the default rendered element, combining their props and behavior. |
| data-testid    | `string \| undefined`                                |         |                                                                                                     |

## Explorer

