# Estilizar componentes

> ComponentStyle — API fluida para color, borde, esquinas, gaps, fuente y sombra de un componente.

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

# Estilizar componentes (`ComponentStyle`)

`ComponentStyle` encapsula **toda** la apariencia de un componente. Se construye con **API fluida** y
se aplica con `componente.style(...)`.

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

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;   // ComponentStyle, Styles
import dev.crossfly.ui.graphics.*; // Relative

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

      // ComponentStyle armado desde cero, aplicado con .style(...)
      Button salvar = new Button("Salvar");
      salvar.style(new ComponentStyle()
         .backColor(0xFF0173ED)          // fondo azul (ARGB)
         .textColor(0xFFFFFFFF)          // texto blanco
         .borderColor(0)                 // sin borde
         .borderRadius(0.6f)             // esquinas redondeadas
         .ingap(Gap.ofFont(0.8f, 0.4f, 0.8f, 0.4f))  // padding interno (l,t,r,b)
         .autoWidth(Relative.ofScreen(0.6f))
         .pressable());                  // reacciona al toque
      add(LAY_AUTO, salvar);

      // Recomendado: derivar del estilo del tema y solo ajustar lo necesario
      Button tema = new Button("Cor do tema");
      tema.style(Styles.button()
         .backColor(Styles.primaryColor) // PalColor del tema (sigue claro/oscuro)
         .borderRadius(1f));
      add(LAY_AUTO, tema);
   }
}
```
> 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
Button salvar = new Button("Salvar");
salvar.style(new ComponentStyle()
   .backColor(0xFF0173ED)              // fondo azul (ARGB)
   .textColor(0xFFFFFFFF)              // texto blanco
   .borderColor(0)                     // sin borde
   .borderRadius(0.6f)                 // esquinas redondeadas
   .ingap(Gap.ofFont(0.8f, 0.4f, 0.8f, 0.4f))      // padding interno
   .pressable());                      // reacciona al toque
```

## Aplicar por estado
```java
salvar.style(normal)
      .focusedStyle(comFoco)     // mientras está enfocado
      .pressedStyle(apertado);   // mientras está presionado
```

## Partir de un estilo del Skin (recomendado)
En lugar de montar desde cero, **deriva** de un estilo del `Skin` para heredar fuente/gaps/colores del tema:
```java
// toma el estilo de botón del tema actual y solo ajusta lo necesario
salvar.style(Styles.button()
   .backColor(Styles.primaryColor)     // usa el color primario del tema
   .borderRadius(1f));
```

## Propiedades principales (setters fluidos)
| Setter | Efecto |
|---|---|
| `backColor(int\|PalColor)` | color de fondo (`0` = transparente) |
| `textColor(int\|PalColor)` | color del texto |
| `borderColor(int)` · `borderThick(float)` | borde (`0` = sin borde) |
| `borderRadius(float)` / `borderRadius(tl,tr,bl,br)` | esquinas redondeadas |
| `font(Font)` | fuente — ej. `Font.get(1.25f, BOLD)` |
| `ingap(Gap)` / `outgap(Gap)` | padding interno / margen externo |
| `icongap(Gap)` · `iconColor(int)` | espacio y color del icono |
| `autoWidth(Relative)` / `autoHeight(Relative)` | tamaño automático responsivo |
| `textAlign(Position h, Position v)` | alineación del texto |
| `shadow(offX, offY, blur, color)` | sombra |
| `pressable()` | habilita resalte al presionar |

## Colores: `int` ARGB o `PalColor`
- **`int` ARGB** (`0xAARRGGBB`) — color fijo: `0xFF0173ED`.
- **`PalColor`** (de `Styles`/`ColorScheme`) — color **del tema**, que se re-resuelve solo al cambiar
  entre claro/oscuro: `Styles.primaryColor`, `Styles.textColor`. **Prefiere `PalColor`** para seguir el tema.

## Buenas prácticas
- Deriva de `Styles.button()`/`Styles.label()`/`Styles.textField()` en lugar de recrear todo.
- Usa `PalColor` del tema (`Styles.primaryColor`, `cs.surface`) — el color fijo no sigue el modo oscuro.
- Espaciados con `Gap.ofFont(...)` (escala con la fuente) — nunca píxeles fijos.

## Errores comunes
- Llamar `setStyle(...)` — el método es **`style(...)`**.
- Usar `new Color(...)` — la clase `Color` fue eliminada; usa `int` ARGB o `ColorUtils`.
- Color fijo en toda la UI y luego extrañarse de que el modo oscuro "no toma".

## Véase también
- [Esquemas de colores](/docs/ui/theming/color-schemes) · [Modo claro/oscuro](/docs/ui/theming/dark-mode) · [Skins](/docs/ui/theming/skins)
