# Modo claro/oscuro

> Alternar el tema en tiempo real sin reconstruir la UI — setDarkMode + onRestyle/styled/restyle.

Source: https://crossfly.dev/es/docs/ui/theming/dark-mode — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Modo claro/oscuro

CrossFly cambia entre claro y oscuro **en tiempo real y en el sitio** — sin recrear pantallas. La clave es
`Styles.setDarkMode(...)` combinado con estilos que **se re-resuelven** a partir del tema.

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

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;   // Styles, ThemeMode, LabelRole

/** 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();
      Styles.setColorScheme(0xFF6750A4, ThemeMode.LIGHT);   // paleta base (sigue claro/oscuro)
      setLayout(new VerticalLayout());

      // styled(...) reevalúa el estilo en cada cambio de tema (re-skin automático por modo)
      Label titulo = new Label("Bem-vindo")
         .styled(() -> Styles.theme().label(LabelRole.TITLE));
      add(LAY_AUTO, titulo);

      // Switch alterna el modo; setDarkMode re-viste toda la UI abierta solo.
      Switch alternar = new Switch("Modo escuro");
      alternar.onAction(c -> Styles.setDarkMode(alternar.isChecked()));
      add(LAY_AUTO, alternar);
   }
}
```
> Los fragmentos siguientes muestran **solo el núcleo** (lo que va dentro de `onShow()`). Para ejecutar, colócalos en el esqueleto `MainWindow` de arriba.

## La forma automática (recomendada)
1. Usa **`PalColor` del tema** (`Styles.textColor`, `cs.surface`) en los estilos — se re-resuelven solos.
2. Llama `setDarkMode(...)`:
```java
Styles.toggleDarkMode();              // alterna claro ↔ oscuro
Styles.setDarkMode(true);             // fuerza oscuro
boolean escuro = Styles.isDarkMode(); // estado actual
```
`setDarkMode(...)` ya **re-aplica el tema en todas las ventanas abiertas** automáticamente (dispara
`restyleAll()` internamente), así que los estilos ligados a `PalColor` cambian de color sin ningún código extra.

## Estilos que dependen del modo → `styled(...)` / `onRestyle(...)`
Cuando el estilo **cambia de forma** según el modo (no solo el color), registra cómo debe el componente
reestilizarse. El callback se ejecuta una vez en el momento y de nuevo a cada cambio de tema:
```java
Label titulo = new Label("Bem-vindo")
   .styled(() -> Styles.theme().label(LabelRole.TITLE));   // reevaluado en cada cambio de tema

// para lógica más allá del estilo (cambiar glyph de ícono, color de gráfico, etc.):
Label l = new Label("Status");
l.onRestyle(() -> l.style(Styles.isDarkMode() ? estiloEscuro : estiloClaro));
```

## Re-skin manual de un subárbol
Si cambiaste el tema de forma no global (ej.: solo un panel), fuerza la reaplicación:
```java
window.restyle();   // re-ejecuta todos los onRestyle del árbol y repinta, sin recrear componentes
```

## Flujo completo
```java
Switch alternar = new Switch("Modo escuro");
alternar.onAction(c -> Styles.setDarkMode(alternar.isChecked()));  // toda la UI acompaña
```

## Buenas prácticas
- Prefiere **`PalColor` del tema** a colores fijos — el modo oscuro pasa a ser automático.
- Para estilos que cambian de estructura por modo, usa **`styled(...)`** (más conciso que `onRestyle`).
- Lee el modo con `Styles.isDarkMode()` / `Styles.themeMode()` al **construir** estilos.

## Errores comunes
- Guardar colores fijos (`0xFF...`) y luego tener que reconstruir la pantalla a mano para el oscuro.
- Reconstruir la UI entera al cambiar de tema — usa `restyle()`/`styled(...)` y reaprovecha los componentes.

## Véase también
- [Esquemas de colores](/docs/ui/theming/color-schemes) · [Estilizar componentes](/docs/ui/theming/styling-components) · [Skins](/docs/ui/theming/skins)
