# Campos de texto

> TextField — leyenda flotante, iconos, contraseña con toggle y lectura del valor.

Source: https://crossfly.dev/es/docs/ui/forms-and-input/text-fields — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Campos de texto (`TextField`)

`TextField` es el campo de **una línea**. API fluida para lo esencial; el comportamiento fino viene del
`TextFieldStyle`.

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

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;   // TextFieldStyle (config de comportamiento)

/** 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());

      // Campo de nombre con leyenda flotante
      TextField nome = new TextField().caption("Nome");
      nome.<TextFieldStyle>getStyle().floatingCaption(true);
      add(LAY_AUTO, nome);

      // Campo de contraseña con botón de mostrar/ocultar
      TextField senha = new TextField().caption("Senha");
      senha.<TextFieldStyle>getStyle()
         .mode(EditMode.PASSWORD)
         .passwordToggle(true);
      add(LAY_AUTO, senha);

      // Etiqueta donde se mostrará el valor leído
      Label resultado = new Label("");
      add(LAY_AUTO, resultado);

      // NO hay callback por tecla: lee getText() al enviar
      Button enviar = new Button("Enviar");
      enviar.onAction(c -> resultado.setText("Nome = " + nome.getText()));
      add(LAY_AUTO, enviar);
   }
}
```

> Los fragmentos siguientes muestran **solo el núcleo** (lo que va dentro de `onShow()`). Para ejecutar, colócalos en el esqueleto `MainWindow` de arriba.

## Uso básico
```java
TextField nome = new TextField()
   .caption("Nome")                 // leyenda flotante
   .text("");                       // valor inicial
painel.add(LAY_AUTO, nome);

// leer el valor cuando haga falta (no hay evento por tecla):
Button enviar = new Button("Enviar");
enviar.onAction(c -> Debug.log("Nome = " + nome.getText()));
```

## Constructores y fluent API
| Miembro | Efecto |
|---|---|
| `new TextField()` / `new TextField("texto")` | campo vacío / con valor inicial |
| `.caption(String)` | leyenda (flota al enfocar, si `floatingCaption`) |
| `.text(String)` / `setText(String)` | define el valor |
| `.leftIcon(Icon)` / `.rightIcon(Icon)` | iconos en los extremos |
| `.rightIcon(Icon, Action)` | icono clicable (ej.: limpiar) |
| `.keyboard(Keyboard)` | tipo de teclado (ver [Máscaras y teclados](/docs/ui/forms-and-input/masks-and-keyboards)) |
| `getText()` / `getTextWithoutMask()` | leer valor (con / sin máscara) |
| `clearText()` | limpiar |

## Leyenda flotante
Habilítala en el estilo (`floatingCaption`) — la leyenda sube al enfocar/llenar:
```java
TextField email = new TextField().caption("E-mail");
email.<TextFieldStyle>getStyle().floatingCaption(true);
```

## Contraseña con botón de mostrar/ocultar
```java
TextField senha = new TextField().caption("Senha");
senha.<TextFieldStyle>getStyle()
   .mode(EditMode.PASSWORD)     // enmascara los caracteres
   .passwordToggle(true);       // agrega el ícono de ojo automáticamente
```
Con `passwordToggle(true)`, el icono de la derecha alterna la visibilidad por sí solo.

## Icono de acción (ej.: limpiar)
```java
TextField busca = new TextField().caption("Buscar")
   .rightIcon(new MaterialIcon(""), c -> busca.clearText());  // "close"
```

## Buenas prácticas
- Lee el valor con `getText()` en el momento del envío; para dígitos crudos usa `getTextWithoutMask()`.
- Configura el comportamiento (`mode`, `maxLength`, `floatingCaption`) vía `getStyle()` tipado
  (`campo.<TextFieldStyle>getStyle()...`).
- Limita el tamaño con `.maxLength(n)` en el estilo cuando tenga sentido.

## Errores comunes
- Buscar un `onChange`/`onTextChanged` — **no existe**; lee `getText()` cuando lo necesites.
- Confundir `getText()` (con máscara) con `getTextWithoutMask()` (sin) al guardar en la base de datos.
- Definir `mode`/`mask` en el componente — son setters del **estilo**.

## Ver también
- [Máscaras y teclados](/docs/ui/forms-and-input/masks-and-keyboards) · [Foco y validación](/docs/ui/forms-and-input/focus-and-validation) · [Áreas de texto](/docs/ui/forms-and-input/text-areas)
- Catálogo: [TextField](/docs/ui/widgets/textfield) · Referencia: Capítulo 14
