# Button

Ação. Sai como `<button>` nativo, e vira `<a>` com `render={<a href="..." />}`.

**Quando usar cada variante.** `primary` para a ação principal da tela, uma só por
área. `secondary` para a alternativa. `outline` para chamada secundária de página
de marketing. `ghost` para ação discreta em tabela ou cabeçalho. `destructive`
para o que apaga, e só para isso.

**Tamanho.** `sm`, `md` e `lg` leem a altura do token de densidade, então encolhem
sozinhos no modo compacto. `icon` e `iconSm` sao quadrados, para botão sem texto,
que sempre precisa de `aria-label`. `cta` e de marketing: maior, em negrito, com
medida própria.

**Forma.** O padrão do produto e o canto de 8px. `shape="pill"` e assinatura de
marketing, não de formulário.

`loading` desabilita e anuncia ocupado.

## No React Native

Traduz: o `@rivocode/ui-native` exporta `Button` - contrato controlado; `hitSlop` no `sm`, porque 32px de alvo não se toca sem ajuda. Afunda de leve no toque, e não afunda quando o sistema pede para reduzir movimento. A API não é a mesma do web (no nativo tudo é controlado), e a [tabela de paridade](/react-native) diz o que muda peça a peça.

## Importação

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

## Exemplos

### Variantes

```tsx
import { Download, MessageCircle, Trash2 } from 'lucide-react'
import { Button } from '@rivocode/ui'

export function Variants() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <Button>Salvar alterações</Button>
      <Button variant="secondary">Cancelar</Button>
      <Button variant="outline">Quero um diagnóstico</Button>
      <Button variant="ghost">Ver detalhes</Button>
      <Button variant="destructive">Excluir projeto</Button>
    </div>
  )
}
```

### Tamanhos

```tsx
import { Download, MessageCircle, Trash2 } from 'lucide-react'
import { Button } from '@rivocode/ui'

export function Sizes() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <Button size="sm">Pequeno</Button>
      <Button size="md">Médio</Button>
      <Button size="lg">Grande</Button>
      <Button size="cta" shape="pill">
        <MessageCircle size={18} aria-hidden="true" />
        Falar no WhatsApp
      </Button>
    </div>
  )
}
```

### Estados

```tsx
import { Download, MessageCircle, Trash2 } from 'lucide-react'
import { Button } from '@rivocode/ui'

export function States() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <Button loading>Emitindo nota</Button>
      <Button disabled>Indisponível</Button>
      <Button size="icon" variant="secondary" aria-label="Baixar">
        <Download size={16} aria-hidden="true" />
      </Button>
      <Button size="icon" variant="ghost" aria-label="Excluir">
        <Trash2 size={16} aria-hidden="true" />
      </Button>
    </div>
  )
}
```

### Como link

```tsx
import { Download, MessageCircle, Trash2 } from 'lucide-react'
import { Button } from '@rivocode/ui'

export function AsLink() {
  return (
    <Button render={<a href="https://rivocode.com" />} size="cta" shape="pill">
      Ver o site da RivoCode
    </Button>
  )
}
```

## Props

| Prop | Tipo | Obrigatória | Desde | O que faz |
| --- | --- | --- | --- | --- |
| `loading` | `boolean` |  | 0.4.0 | Desabilita e anuncia ocupado enquanto uma acao esta em andamento. |
| `ref` | `Ref<HTMLButtonElement>` |  | 0.4.0 |  |
| `render` | `ReactElement<unknown, string \| JSXElementConstructor<any>>` |  | 0.4.0 | Troca o elemento renderizado mantendo a aparencia. |
| `shape` | `"default" \| "pill" \| null` |  | 0.4.0 |  |
| `size` | `"cta" \| "icon" \| "iconSm" \| "lg" \| "md" \| "sm" \| null` |  | 0.4.0 |  |
| `variant` | `"destructive" \| "ghost" \| "outline" \| "primary" \| "secondary" \| null` |  | 0.4.0 |  |

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

## Ver também

- [ButtonGroup](/componentes/button-group.md)
- [Clipboard](/componentes/clipboard.md)
- [Toggle](/componentes/toggle.md)
- [ToggleGroup](/componentes/toggle-group.md)
- [Toolbar](/componentes/toolbar.md)
- [Convenções da biblioteca](/convencoes.md): Provider, tokens e as regras que valem para toda peça
- [Índice completo](/llms.txt)
