# ScrollArea

Área de rolagem com barra própria.

Serve para quando a barra do sistema atrapalha o desenho: no Windows ela ocupa
largura e empurra o conteúdo, e a diferença entre plataformas aparece na tela.
**Para rolagem comum de página, `overflow-y-auto` continua sendo mais barato.**

```tsx
<ScrollArea className="h-48">
  {notas.map((nota) => (
    <p key={nota.id}>{nota.descricao}</p>
  ))}
</ScrollArea>
```

`horizontal` liga a barra de lado também, para tabela larga e fila de cartoes.

## No React Native

Traduz, e muda de assunto no caminho. No web a peça existe pela **barra**: a do sistema ocupa largura no Windows e desenha diferente em cada plataforma. No celular a barra é do sistema e fica sendo, e o problema de rolagem que dói é outro: **o teclado cobre o campo**. Formulário no fim da tela some debaixo dele, e o botão de enviar fica escondido até alguém fechar o teclado para achá-lo.

Então o `ScrollArea` nativo é a tela de formulário. Por baixo é o `KeyboardAwareScrollView` da `react-native-keyboard-controller`: ao focar um campo, a rolagem anda até ele parar `bottomOffset` pontos acima do teclado (16 por padrão), no mesmo quadro em que o teclado sobe, nos dois sistemas. O toque num item da lista não fecha o teclado (`keyboardShouldPersistTaps="handled"`).

```tsx
<ScrollArea
  contentContainerClassName="gap-4 p-5"
  footer={<Button onPress={emitir}>Emitir nota</Button>}
>
  <Field label="Descrição">…</Field>
</ScrollArea>
```

O `footer` é a ação presa embaixo da rolagem, e ele **sobe junto com o teclado**: o botão de enviar fica sempre à vista. A altura dele entra na conta de onde o campo em foco para, então nenhum campo fica escondido atrás do botão. Com o "reduzir movimento" ligado, o rodapé pula direto para cima do teclado em vez de acompanhá-lo; a rolagem até o campo continua, porque sem ela o campo fica coberto.

Não há `horizontal`: fila de cartões que rola de lado é `ScrollView` puro, e não tem campo para o teclado cobrir. A `react-native-keyboard-controller` é peer do pacote, e o `KeyboardProvider` que ela pede já vem dentro do `RivoProvider`.

## Importação

```tsx
import { ScrollArea } from '@rivocode/ui'
```

## Exemplos

### Lista longa

```tsx
import { ScrollArea } from '@rivocode/ui'

export function LongList() {
  return (
    <ScrollArea className="h-40 w-80 rounded-md border border-border p-3">
      <div className="flex flex-col gap-2 text-base text-fg-muted">
        {Array.from({ length: 14 }, (_, index) => (
          <p key={index}>Nota {4800 + index}, emitida e enviada por email.</p>
        ))}
      </div>
    </ScrollArea>
  )
}
```

## Props

| Prop | Tipo | Obrigatória | Desde | O que faz |
| --- | --- | --- | --- | --- |
| `horizontal` | `boolean` |  | 0.4.0 | Rolagem de lado tambem. |
| `overflowEdgeThreshold` | `number \| Partial<{ xStart: number; xEnd: number; yStart: number; yEnd: number; }>` |  | 0.4.0 | The threshold in pixels that must be passed before the overflow edge attributes are applied. |
| `render` | `ComponentRenderFn<HTMLProps, ScrollAreaRootState> \| ReactElement<unknown, string \| JSXElementConstructor<any>>` |  | 0.4.0 | Allows you to replace the component's HTML element with a different tag, or compose it with another component. |

Além dessas: repassa `className`, `style`, `id` e os demais atributos do elemento raiz.

## Ver também

- [Accordion](/componentes/accordion.md)
- [AspectRatio](/componentes/aspect-ratio.md)
- [Avatar](/componentes/avatar.md)
- [Card](/componentes/card.md)
- [Collapsible](/componentes/collapsible.md)
- [DataTable](/componentes/data-table.md)
- [Convenções da biblioteca](/convencoes.md): Provider, tokens e as regras que valem para toda peça
- [Índice completo](/llms.txt)
