# Dropdown

> ComboBox — botão com seta que abre uma lista para escolha única.

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

# Dropdown

`Dropdown` é um componente tipo **ComboBox**: um botão com texto + seta (`expand_more`) que, ao ser tocado, abre uma `ListViewWindow` com a lista de itens, posicionada acima ou abaixo conforme o espaço disponível. Após a seleção, o texto do botão passa a mostrar o item escolhido. Enquanto nada é selecionado, exibe o **placeholder**.

> 🟡 · **Pacote:** `dev.crossfly.ui` · **Estende:** `Button` · **Estilo:** `DropdownStyle`

## Quando usar
- Escolha **única** dentre uma lista média de opções, economizando espaço na tela.
- Quando o valor selecionado deve ficar visível após a escolha.

## Quando NÃO usar
- Para 2–3 opções sempre visíveis → use [`option`](/docs/ui/widgets/option) em [`group`](/docs/ui/widgets/group).

## Aparência
Texto à esquerda; a seta é posicionada conforme `DropdownStyle.iconPosition`: `START` (colada à borda esquerda), `CENTER` (ao lado do texto, layout padrão `TEXT_AT_LEFT` do `Button`) ou `END` (colada à borda direita). O popup abre como uma janela branca de bordas arredondadas que fecha ao tocar fora (`canMove(false).canHide(true)`).

## 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());

      Label saida = new Label("Nada selecionado");
      add(LAY_AUTO, saida);

      String[] itens = {"One", "Two", "Three", "Four", "Five"};
      Dropdown cb = new Dropdown("Selecione...", itens);
      // onSelect dispara depois de confirmar a escolha no popup
      cb.onSelect(e -> saida.setText("Escolhido: " + cb.getSelectedText()
                                     + " (idx " + cb.getSelectedIndex() + ")"));
      add(LAY_AUTO, cb);
   }
}
```

> 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
String[] itens = {"One", "Two", "Three", "Four", "Five"};
Dropdown cb = new Dropdown("Selecione...", itens);
cb.onSelect(e -> {
   String escolhido = cb.getSelectedText();
   System.out.println("escolhido: " + escolhido);
});
container.add(.95f, cb);
```

## Construtores
| Construtor | Descrição |
|---|---|
| `Dropdown(String placeholder, String[] items)` | Placeholder + itens. |
| `Dropdown(String[] items)` | Itens com placeholder padrão `"Select..."`. |

## Propriedades e personalização
| Propriedade / método | Tipo | Padrão | O que faz |
|---|---|---|---|
| `onSelect(Action)` | `Dropdown` (fluente) | — | Callback ao confirmar uma seleção. |
| `popupHeightRatio(float)` | `Dropdown` (fluente) | `0.4` | Altura do popup (0..1 da tela), usada quando a altura ideal não é medida. |
| `popupWidthRatio(float)` | `Dropdown` (fluente) | `-1` | Largura do popup (0..1 da tela); negativo = largura do próprio Dropdown. |
| `getSelectedIndex()` | `int` | `-1` | Índice do item atual (ou `-1`). |
| `getSelectedText()` | `String` | `null` | Texto do item atual (ou `null`). |
| `setSelectedIndex(int)` | `Dropdown` (fluente) | — | Seleciona programaticamente; índice inválido (ex.: `-1`) → volta ao placeholder. |

## Callbacks e eventos
| Callback | Quando dispara |
|---|---|
| `onSelect(Action)` | **Depois** de confirmar uma seleção no popup. Use `getSelectedText()`/`getSelectedIndex()` dentro dele. |

`onTouchUp` herda do `Button` e agenda `openPopup()` via `onUI(...)`.

## Estados
- **placeholder**: nenhum item selecionado (`selectedIndex == -1`); exibe o texto de placeholder.
- **selecionado**: `selectedIndex >= 0`; exibe o texto do item.
- **pressed**: herdado do `Button` (fade de pressionar).

### Seleção programática e limpar de volta ao placeholder
```java
String[] numeros = {"One", "Two", "Three"};
Dropdown cb = new Dropdown("", numeros);
cb.onSelect(e -> System.out.println("idx: " + cb.getSelectedIndex()));
container.add(.95f, cb);

cb.setSelectedIndex(1);   // seleciona "Two" programaticamente
cb.setSelectedIndex(-1);  // limpa: volta ao placeholder
```

## Boas práticas
- Leia a escolha via `getSelectedText()`/`getSelectedIndex()` dentro do `onSelect`.
- Use `setSelectedIndex(-1)` para "resetar" o campo ao placeholder (ex.: num botão "Limpar").

## Erros comuns
- Passar `items` nulo: o construtor trata (`new String[0]`), mas o popup **não abre** se a lista estiver vazia.
- Esperar multisseleção: `Dropdown` é escolha única; para múltipla, use `ListView` `MULTIPLE`.

## Veja também
- Guia da área: [`ui/`](/docs/ui) · Receitas: [`cookbook/`](/docs/cookbook)
- Conceito (janelas e popups): [`concepts/`](/docs/concepts)
- Componentes relacionados: [`option`](/docs/ui/widgets/option) · [`group`](/docs/ui/widgets/group)
