# ActionSheet

> Folha de ações estilo iOS ancorada na base da tela.

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

# ActionSheet

`ActionSheet` é a folha de ações estilo iOS: um cartão arredondado ancorado na **base da tela** com uma lista de botões de opção e um botão **Cancelar** separado abaixo. Quando há opções demais para caber, elas se distribuem em múltiplas colunas (até `maxColumns`). Atrás da folha há um "scrim" cinza (`fullscreenColor = 0xD0DDDDDD`) que dá o efeito modal.

> 🟢 · **Pacote:** `dev.crossfly.ui` · **Estende:** `Window` · **Estilo:** `ComponentStyle`/`WindowStyle`

## Quando usar
- Menu de ações contextuais sobre um item (compartilhar, renomear, excluir…).
- Quando quiser destacar visualmente uma ação destrutiva (vermelho), como no padrão iOS.

## Quando NÃO usar
- Escolha sim/não simples ou confirmação com mensagem → use [`Alert`](/docs/ui/widgets/alert).
- Feedback passivo/efêmero → use [`Hint`](/docs/ui/widgets/hint).

## Aparência
Cartão inferior de largura ~92% da tela com as opções empilhadas, separadas por linhas finas, e o botão Cancelar totalmente arredondado logo abaixo. O fundo da tela fica coberto por um scrim cinza.

## 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 folha de ações");
      abrir.onAction(c ->
      {
         ActionSheet sheet = new ActionSheet("Cancelar", "Compartilhar", "Renomear", "Excluir");
         sheet.buttonAction(0, origin -> { sheet.hide(); Hint.show("Compartilhar", 2000); });
         sheet.buttonAction(1, origin -> { sheet.hide(); Hint.show("Renomear", 2000); });
         sheet.buttonAction(2, origin -> { sheet.hide(); Hint.show("Excluído", 2000); });
         // Ação destrutiva em vermelho
         sheet.buttonStyle(2, ActionSheet.createDefaultButtonStyle().textColor(0xFFFF0000));
         sheet.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
ActionSheet sheet = new ActionSheet("Cancelar", "Compartilhar", "Renomear", "Excluir");
sheet.buttonAction(0, origin -> { compartilhar(); sheet.hide(); });
sheet.buttonAction(1, origin -> { renomear();     sheet.hide(); });
sheet.buttonAction(2, origin -> { excluir();      sheet.hide(); });
sheet.show();
```

## Construtores
| Construtor | Descrição |
|---|---|
| `ActionSheet(String cancelText, String... buttonTexts)` | `cancelText` (default `"Cancel"`) e os textos das opções (vazio/`null` → `{"OK"}`). |

## Propriedades e personalização
| Propriedade / método | Tipo | Padrão | O que faz |
|---|---|---|---|
| `buttonStyle(ComponentStyle)` | fluente | skin | Estilo default de **todas** as opções. |
| `buttonStyle(int index, ComponentStyle)` | fluente | — | Override de estilo de uma opção específica. |
| `buttonStyle(int index)` | `ComponentStyle` | — | Estilo resolvido da opção. |
| `cancelStyle(ComponentStyle)` | fluente | skin | Estilo do botão Cancelar. |
| `containerStyle(ComponentStyle)` | fluente | skin | Estilo do cartão (raio das bordas). |
| `maxColumns(int)` | fluente | `1` | Máximo de colunas em overflow (>=1). |
| `getButton(int)` / `getCancelButton()` | `Button` | — | Botões após `show()`/`onAdd`. |
| `createDefaultButtonStyle()` / `createDefaultCancelStyle()` / `createDefaultContainerStyle()` | `ComponentStyle` (static) | — | Fábricas dos estilos default. |

## Callbacks e eventos
| Callback | Quando dispara |
|---|---|
| `buttonAction(int index, Component.Action action)` | ao tocar a opção `index` (0-based). |
| `cancelAction(Component.Action action)` | ao tocar o botão Cancelar. |

> Como `ActionSheet` estende `Window` (não `Picker`), **a resposta vem por esses callbacks**, não por `show(onAnswer)`. Não há `getAnswer()`. O lambda de `Component.Action` é `void run(Component origin)` — não retorne valor.

## Estados
- Opção **sem** callback → recebe a ação default `hide()` (fecha a folha).
- Opção **com** callback → executa o callback; se ele não chamar `hide()`, a folha permanece aberta.
- Tap no scrim (fora da folha) ou back → fecha quando `canHide` está ativo (default).

### Destacar a ação destrutiva e permitir 2 colunas
```java
ActionSheet sheet = new ActionSheet("Cancelar", "Compartilhar", "Renomear", "Excluir");

sheet.buttonAction(0, origin -> { compartilhar(); sheet.hide(); });
sheet.buttonAction(1, origin -> { renomear();     sheet.hide(); });
sheet.buttonAction(2, origin -> { excluir();      sheet.hide(); });

// Opção destrutiva em vermelho
sheet.buttonStyle(2, ActionSheet.createDefaultButtonStyle().textColor(0xFFFF0000));

// Permitir até 2 colunas se houver muitas opções
sheet.maxColumns(2);

sheet.show();
```

## Boas práticas
- Use para um conjunto de ações contextuais; para sim/não simples, prefira [`Alert`](/docs/ui/widgets/alert).
- Destaque ações destrutivas com `buttonStyle(index, ...)` em vermelho.
- Em listas longas, configure `maxColumns` para a folha não ultrapassar a tela.

## Erros comuns
- **Callback sem `hide()`** — a folha fica aberta; o `hide()` automático só ocorre quando **não** há callback registrado.
- **Fazer o lambda retornar valor** — `Component.Action.run(...)` é `void`.
- **Acessar `getButton(i)` antes de `show()`** — os botões são criados em `onAdd`.

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