# Alert

> Caixa de diálogo modal com título, mensagem e botões de ação.

Source: https://crossfly.dev/pt/docs/ui/widgets/alert — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Alert

`Alert` é a caixa de diálogo modal do CrossFly — o equivalente a um `MessageBox`/`AlertDialog`. Mostra um **título**, uma **mensagem** (com word-wrap automático) e um ou mais **botões de ação** dispostos em linhas. Cada botão pode ter um callback próprio; sem callback, o botão apenas fecha o diálogo. O visual (cores, fontes, layout dos botões) vem do `Skin` ativo.

> 🟢 · **Pacote:** `dev.crossfly.ui` · **Estende:** `Window` · **Estilo:** `AlertStyle` + `WindowStyle`

## Quando usar
- Confirmações que exigem reconhecimento do usuário (excluir? salvar? descartar?).
- Escolhas simples sim/não ou uma mensagem que precisa de um "OK".

## Quando NÃO usar
- Feedback passivo e efêmero (sucesso/erro/status) → use [`Hint`](/docs/ui/widgets/hint).
- Lista de ações contextuais sobre um item (compartilhar/editar/excluir) → use [`ActionSheet`](/docs/ui/widgets/actionsheet).

## Aparência
Cartão centralizado com título no topo, mensagem no meio e uma linha de botões na base. Por padrão o fundo **não** é escurecido — ajuste `WindowStyle.fadeBackground` para o efeito modal clássico.

## Exemplo completo (copiar, colar e rodar)
```java
package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;

/** Tela principal executável. Aponte o launcher (classname) e rode: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      Button abrir = new Button("Abrir alerta");
      abrir.onAction(c ->
      {
         Alert a = new Alert("Excluir item",
            "Tem certeza que deseja excluir este item? Esta ação não pode ser desfeita.",
            "Excluir", "Cancelar");
         // Fundo escurecido para reforçar a modalidade (alpha 0..255)
         WindowStyle ws = a.getStyle();
         ws.fadeBackground(150);
         // Botão 0 = Excluir -> executa, fecha e dá feedback
         a.buttonAction(0, origin ->
         {
            a.hide();
            Hint.show("Item excluído", 2000);
         });
         // Botão 1 = Cancelar: sem callback -> default já chama hide()
         a.show();
      });
      add(LAY_AUTO, abrir);
   }
}
```

> Os trechos abaixo mostram **só o miolo** (o que vai dentro de `onShow()`). Para rodar, coloque-os no esqueleto `MainWindow` acima.

## Uso básico
```java
// buttonTexts é varargs opcional — se vazio/null, vira {"OK"}
Alert a = new Alert("Aviso", "Operação concluída com sucesso.", "OK");
a.show();
```

## Construtores
| Construtor | Descrição |
|---|---|
| `Alert(String title, String message, String... buttonTexts)` | `title` pode ser `""` (oculta visualmente o título). `buttonTexts` opcional; vazio/`null` → `{"OK"}`. |

> ⚠️ **Não existe `Alert.show(...)` estático nem construtor que dispare callback.** Sempre instancie com `new Alert(...)`, registre os callbacks por botão e chame `show()`.

## Propriedades e personalização
| Propriedade / método | Tipo | Padrão | O que faz |
|---|---|---|---|
| `style()` | `AlertStyle` | skin | Retorna o `AlertStyle` atual. |
| `style(AlertStyle)` | fluente | — | Define um `AlertStyle` customizado. |
| `style().buttonLayout(...)` | `IOS`/`FLUTTER`/`MATERIAL` | `MATERIAL` | Estilo de disposição dos botões. |
| `style().maxButtonsPerRow(int)` | `int` | skin | Botões por linha; excedentes quebram em novas linhas. |
| `skin(Skin)` | fluente | — | Troca o skin e reatualiza o `AlertStyle`. |
| `getButton(int index)` | `Button` | — | Botão após `show()` (antes disso, `null`). |
| `getAutoWidth()` / `getAutoHeight()` | `int` | — | Dimensões calculadas. |

## Callbacks e eventos
| Callback | Quando dispara |
|---|---|
| `buttonAction(int index, Component.Action action)` | ao tocar o botão de índice `index` (0-based). |

> ⚠️ **A resposta NÃO vem por `show(onAnswer)`.** `Alert` estende `Window`, não `Picker` — e `Window.hide()` só entrega `onAnswer` quando `this instanceof Picker`. Logo, para reagir a cada botão use `buttonAction(index, action)`. Não há `getAnswer()` no `Alert`.

O tipo do callback é `Component.Action`, cujo método é `void run(Component origin)` — o corpo do lambda **não retorna valor** (nada de `return null;`).

## Estados
- Botão sem callback registrado → recebe a ação default `hide()` (fecha o diálogo).
- Botão com callback → executa o callback; se o callback não fechar, o diálogo continua aberto (chame `a.hide()` você mesmo).
- Gesto "voltar"/back → respeitado se `WindowStyle.canHide` (default `true`).

### Confirmação com fundo escurecido
```java
Alert confirm = new Alert("Excluir item",
   "Tem certeza que deseja excluir este item? Esta ação não pode ser desfeita.",
   "Excluir", "Cancelar");

// Reforça a modalidade escurecendo o fundo (alpha 0..255)
WindowStyle ws = confirm.getStyle();
ws.fadeBackground(150);

// Botão 0 = Excluir -> executa, fecha e dá feedback
confirm.buttonAction(0, origin ->
{
   excluirItem();
   confirm.hide();
   Hint.show("Item excluído", 2000);
});
// Botão 1 = Cancelar: sem callback -> default já chama hide()

confirm.show();
```

### Escolher o layout dos botões
```java
Alert a = new Alert("Salvar", "Deseja salvar as alterações?", "Salvar", "Descartar");
a.style().buttonLayout(AlertStyle.ButtonLayout.IOS)  // IOS / FLUTTER / MATERIAL
         .maxButtonsPerRow(2);
a.show();
```

## Boas práticas
- Use para decisões que exigem reconhecimento. Para feedback passivo, prefira [`Hint`](/docs/ui/widgets/hint).
- Mantenha poucos botões — muitos quebram em linhas e deixam o diálogo alto.
- Combine com `fadeBackground` sempre que quiser o efeito modal clássico.

## Erros comuns
- **Esperar resposta via `show(onAnswer)`** — isso é exclusivo de `Picker`. Registre `buttonAction(...)`.
- **Acessar `getButton(i)` antes de `show()`** — os botões são criados em `onAdd` e retornam `null` antes disso.
- **Fazer o lambda de `buttonAction` retornar valor** — `Action.run(...)` é `void`.

## Veja também
- Guia da área: [`ui/`](/docs/ui) · Receitas: [`cookbook/`](/docs/cookbook)
- Componentes relacionados: [`ActionSheet`](/docs/ui/widgets/actionsheet) · [`Hint`](/docs/ui/widgets/hint)
