# LabelItem y CheckLabelItem

> Cards listos de ítem de lista — solo rótulo (SINGLE) o checkbox + rótulo (MULTIPLE).

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

# LabelItem y CheckLabelItem

`LabelItem` y `CheckLabelItem` son "cards" de ítem de lista listos, en el paquete `dev.crossfly.ui.listitem`. Ambos extienden `Component` y son usados internamente por [`ListView`](/docs/ui/widgets/listview):

- **`LabelItem`** — un único `Label` con salto de línea. Usado en el modo `SINGLE`.
- **`CheckLabelItem`** — un `Option` (check) + `Label`. Usado en el modo `MULTIPLE`.

Normalmente **no** los instancias directamente — el `ListView` crea el tipo correcto según el `ItemType`. Úsalos cuando montes una lista a mano y quieras la misma apariencia/comportamiento de card.

> 🟡 · **Paquete:** `dev.crossfly.ui.listitem` · **Extienden:** `Component` · **Estilo:** `ComponentStyle` (card) + `LabelStyle` (rótulo)

## Cuándo usar
- Construir una lista manualmente (fuera del `ListView`) reutilizando el aspecto de card por defecto.
- Un ítem clicable aislado con apariencia consistente con las listas del framework.

## Cuándo NO usar
- Lista de selección lista → deja que el [`ListView`](/docs/ui/widgets/listview) cree los ítems por ti.
- Fila rica con imagen/múltiples campos → monta un `Component` propio (o usa `itemFactory` del `ListView`).

## Apariencia
Card con fondo/borde del tema de selección (`selectionCardBackColor`/`selectionCardBorderColor`), `pressable`, con gaps por defecto. `LabelItem` muestra el texto alineado START/CENTER; `CheckLabelItem` pone el check a la izquierda (ancho automático) y el label ocupando 90%.

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

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.listitem.*;   // LabelItem, CheckLabelItem

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

      // Lista armada a mano reutilizando el visual de card estándar.
      Component lista = new Component();
      lista.setLayout(new GridLayout(Position.CENTER, Position.START));
      lista.setScrollable(ScrollDirection.VERTICAL);

      String[] linhas = {"Alpha", "Beta", "Gamma"};
      for (int i = 0; i < linhas.length; i++) {
         LabelItem item = new LabelItem(linhas[i], i);
         final int idx = i;
         item.onAction(e -> System.out.println("selecionou " + idx));
         lista.add(.95f, item);
      }

      CheckLabelItem termos = new CheckLabelItem("Aceito os termos", linhas.length);
      termos.onAction(e -> { termos.toggle(); System.out.println(termos.isChecked()); });
      lista.add(.95f, termos);

      add(LAY_FILL, lista);   // las listas usan LAY_FILL (absorben la altura)
   }
}
```

> Los fragmentos de abajo 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
// LabelItem — ítem clicable de rótulo único
LabelItem item = new LabelItem("Linha", 0);
item.onAction(e -> System.out.println("clicou " + item.index));
layout.add(.95f, item);

// CheckLabelItem — ítem con checkbox
CheckLabelItem c = new CheckLabelItem("Aceito os termos", 0);
c.onAction(e -> { c.toggle(); System.out.println(c.isChecked()); });
layout.add(.95f, c);
```

### LabelItem
| Constructor | Descripción |
|---|---|
| `LabelItem(String text, int index)` | Estilos por defecto |
| `LabelItem(String text, int index, ComponentStyle cardStyle, LabelStyle labelStyle)` | Estilos personalizados |

### CheckLabelItem
| Constructor | Descripción |
|---|---|
| `CheckLabelItem(String text, int index)` | Estilo por defecto |
| `CheckLabelItem(String text, int index, ComponentStyle cardStyle)` | Estilo de card personalizado |

Los campos `text` e `index` son `public final`.

## Propiedades y personalización
| Miembro | Clase | Qué hace |
|---|---|---|
| `text` (final) | ambos | Texto del ítem |
| `index` (final) | ambos | Índice del ítem en la lista |
| `getAutoHeight()` | ambos | Altura preferida (rótulo/check + ingap) |
| `isChecked()` | `CheckLabelItem` | Estado actual del check |
| `setChecked(boolean)` | `CheckLabelItem` | Define el estado |
| `toggle()` | `CheckLabelItem` | Alterna el estado |
| `getCheck()` | `CheckLabelItem` | Acceso al `Option` interno |
| `defaultItemStyle()` (static) | ambos | Estilo de card reutilizable (selection card, `pressable`) |
| `defaultLabelStyle()` (static) | `LabelItem` | Estilo de rótulo reutilizable |

## Callbacks y eventos
| Callback | Cuándo se dispara |
|---|---|
| `onAction(Action)` | Al tocar el card (heredado de `Component`) |

En `CheckLabelItem`, el toque **no** alterna el check por sí solo — llama a `toggle()` en tu callback (es lo que el `ListView` hace internamente).

## Estados
- **pressed** — ambos son `pressable` por defecto (feedback al toque).
- **checked** — solo `CheckLabelItem`: controlado por `setChecked`/`toggle`, consultable con `isChecked`.

### Lista manual reutilizando el aspecto de card
```java
Component lista = new Component();
lista.setLayout(new GridLayout(Position.CENTER, Position.START));
lista.setScrollable(ScrollDirection.VERTICAL);
String[] linhas = {"Alpha", "Beta", "Gamma"};
for (int i = 0; i < linhas.length; i++) {
   LabelItem item = new LabelItem(linhas[i], i);
   final int idx = i;
   item.onAction(e -> System.out.println("selecionou " + idx));
   lista.add(.95f, item);
}
layout.add(LAY_FILL, lista);
```

### CheckLabelItem con card personalizado
```java
ComponentStyle card = CheckLabelItem.defaultItemStyle()
   .copy()
   .backColor(0xFFF5F5F5);
CheckLabelItem opt = new CheckLabelItem("Receber notificações", 0, card);
opt.setChecked(true);
opt.onAction(e -> { opt.toggle(); });
layout.add(.95f, opt);
```

## Buenas prácticas
- Reutiliza `defaultItemStyle()` / `defaultLabelStyle()` (con `.copy()`) para mantener la cohesión visual con las listas del framework.
- Agrega los ítems con ancho `.95f` en un `GridLayout(CENTER, START)` para reproducir el espaciado del `ListView`.

## Errores comunes
- **Esperar que `CheckLabelItem` alterne el check al tocar automáticamente** — llama a `toggle()` en el `onAction`.
- **Instanciar estos ítems cuando ya usas `ListView`** — el `ListView` ya crea el tipo correcto según el `ItemType`.

## Ver también
- Guía del área: [`ui/`](/docs/ui) · Recetas: [`cookbook/`](/docs/cookbook)
- Componentes relacionados: [`ListView`](/docs/ui/widgets/listview) · [`ListViewWindow`](/docs/ui/widgets/listviewwindow)
