# Diálogos y modales

> Alert, ActionSheet y Hint — cómo abrir, obtener la respuesta y configurar la apariencia.

Source: https://crossfly.dev/es/docs/ui/navigation/dialogs-and-modals — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Diálogos y modales

Los diálogos son **ventanas emergentes** apiladas sobre la pantalla actual. En CrossFly los tres principales son
`Alert` (confirmación), `ActionSheet` (lista de acciones) y `Hint` (aviso efímero, el antiguo "Toast").

## ⚠️ `Alert`/`ActionSheet` responden por los BOTONES, no por `onAnswer`
Extienden `Window` (no `Picker`), por lo que **`show(callback)` no devuelve valor**. La elección del
usuario llega por el **callback del botón** (`buttonAction`). (Ver [Devolver valores](/docs/ui/navigation/returning-results).)

## Ejemplo completo (copiar, pegar y ejecutar)
```java
package com.exemplo;

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

/** Pantalla principal ejecutable. Apunta el launcher (classname) y corre: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // Alert — botones en el constructor (0 = Cancelar, 1 = Excluir); acción por índice.
      Button excluir = new Button("Excluir item");
      excluir.onAction(c -> {
         Alert a = new Alert("Excluir", "Confirma a exclusão deste item?", "Cancelar", "Excluir");
         a.buttonAction(1, x -> Hint.show("Item excluído", 2000));   // Cancelar (0) solo cierra
         // popup: dimensiona y oscurece el fondo vía WindowStyle fluido
         a.getStyle().widthRatio(0.85f).fadeBackground(128).transition(UIConstants.Transition.FADE);
         a.show();
      });
      add(LAY_AUTO, excluir);

      // ActionSheet — el 1º argumento es el texto de cancelar.
      Button compartilhar = new Button("Compartilhar");
      compartilhar.onAction(c -> {
         ActionSheet sheet = new ActionSheet("Cancelar", "E-mail", "Mensagem");
         sheet.buttonAction(0, x -> Hint.show("Enviado por e-mail", 2000));   // índice 0 = E-mail
         sheet.buttonAction(1, x -> Hint.show("Enviado por SMS", 2000));      // índice 1 = Mensaje
         sheet.show();
      });
      add(LAY_AUTO, compartilhar);

      // Hint — aviso efímero (delay en ms).
      Button avisar = new Button("Mostrar aviso");
      avisar.onAction(c -> Hint.show("Salvo com sucesso", 2000));
      add(LAY_AUTO, avisar);
   }
}
```
> Los fragmentos siguientes muestran **solo el núcleo** (lo que va dentro de `onShow()`). Para ejecutar, colócalos en el esqueleto `MainWindow` de arriba.

## Alert (confirmar / avisar)
Los textos de los botones van en el **constructor**; la acción de cada uno se vincula por **índice** con `buttonAction`:
```java
// botones: índice 0 = "Cancelar", índice 1 = "Excluir"
Alert a = new Alert("Excluir", "Confirma a exclusão deste item?", "Cancelar", "Excluir");
a.buttonAction(1, c -> excluirItem());   // la acción viene de aquí, NO de show(cb); Cancelar solo cierra
a.show();
```

## ActionSheet (elegir una acción)
También recibe los textos en el constructor (el **primer** argumento es el texto de cancelar):
```java
ActionSheet sheet = new ActionSheet("Cancelar", "E-mail", "Mensagem");
sheet.buttonAction(0, c -> enviarPorEmail());   // índice 0 = "E-mail"
sheet.buttonAction(1, c -> enviarPorSMS());     // índice 1 = "Mensaje"
sheet.cancelAction(c -> {});                     // opcional: acción al cancelar
sheet.show();
```

## Hint (aviso efímero — sustituye a Toast/ToolTip)
```java
Hint.show("Salvo com sucesso", 2000);     // desaparece solo
```

## Configurar la apariencia del popup — `WindowStyle`
Un popup se dimensiona/posiciona mediante el `WindowStyle` de la ventana. Campos útiles:

| Campo | Efecto |
|---|---|
| `widthRatio` / `heightRatio` | tamaño como fracción de la pantalla |
| `yRatio` / `xAbs` / `yAbs` | posición |
| `fadeBackground` | oscurece el fondo detrás del popup |
| `canHide` | tocar fuera cierra el popup |
| `canMove` | el usuario puede arrastrar |
| `transition` / `transitionDuration` | animación de entrada/salida (predeterminado `NONE`, `0.5s`) |

```java
getStyle().widthRatio = 0.85f;                       // 85% del ancho
getStyle().fadeBackground = true;                     // fondo oscurecido
getStyle().transition = UIConstants.Transition.FADE;  // aparece con fade
```

## Buenas prácticas
- Etiquetas de botón claras ("Excluir" en lugar de "OK"); la acción destructiva al final.
- Prefiere `Hint` a `Alert` para confirmaciones no bloqueantes.

## Errores comunes
- **`alert.show(cb)` esperando que el `cb` se dispare** — no se dispara; vincula la acción con `buttonAction(i, callback)`.
- Llamar a `addButton(...)`/`addOption(...)` — no existen; los textos van en el **constructor** y las acciones por **índice**.
- Apilar varios popups sobre el mismo evento.

## Ver también
- [Devolver valores](/docs/ui/navigation/returning-results) · [La pila de ventanas](/docs/ui/navigation/the-window-stack)
- Catálogo: [Alert](/docs/ui/widgets/alert) · [ActionSheet](/docs/ui/widgets/actionsheet) · [Hint](/docs/ui/widgets/hint)
