---
title: "Button"
slug: "buttons"
category: "Mini Widgets"
reactComponent: "ArcWidgetButton"
reactTier: "mini"
reactSince: "0.1.0-alpha.5"
reactExample: "button.tsx"
locale: "es"
hosts: "ninox"
---

# Button

## AI Defaults (read first)

- **uniqueId**: Required, e.g. `"btn-save-" + Nr`.
- **title**: Button label (use `""` for icon-only buttons).
- **actions**: Array of `{ type: "update", recordId: Nr, field: fieldId(Nr, "Feld"), value: ... }`. Prefer `type: "update"` over `customJS`.
- **Icon-only button**: Use `arcCustomButton` with `icon: arcCustomIcon({...})`, NOT a layout wrapper with `clickAction`.
- **Nested widgets**: `icon`, `title`, `subtitle`, and badge text (`badgeTitle` with `showBadge: true`) may use `arcCustomIcon`, `arcCustomBadge`, or other mini-widgets – not only strings.
- **prefix / suffix**: Mini-widget slots rendered before (`prefix`) and after (`suffix`) the main content. `suffix` is automatically pushed to the right edge when the button has an explicit `width` (e.g. `"100%"`). Both accept any mini-widget (`arcCustomIcon`, `arcCustomBadge`, `arcCustomLayout`, plain text).
- **loading**: After click, `{ show: true, indicator: { type, color, width, height }, hideOnFinish, minDuration, position, hideTitle, hideIcon, styles }`; set **`overlay`** (`true`, `{ title, message }`, or `{ sequences: [...] }`) for fullscreen overlay. Types: `dots`, `spinner`, `pulse`. In-button loading keeps **hover colors** by default (`styles` omitted or `"hover"`); use `"default"` or a `styles` object to override. **`position`**: `left` / `right` (inline next to content), **`prefix`** / **`suffix`** (pinned to slot — use `suffix` when replacing a chevron on full-width buttons). Use **`loading.hide`** to control per-slot visibility: `{ icon, title, subtitle, badge, prefix, suffix }` — `true` always hides, `false` never, `"auto"` (icon only) hides when on the same side as the indicator. Legacy `hideIcon` / `hideTitle` still work.
- **Badge**: Use flat properties `showBadge`, `badgeTitle`, `badgeColor`, `badgeBackground` – NOT a nested `badge: {}` object.
- **width/height**: Set directly, e.g. `width: "30px"`, `height: "30px"` for icon buttons.
- **borderRadius**: `"50%"` for round buttons, `"8px"` for rounded rectangles.

# Botones interactivos

![](https://framerusercontent.com/images/ILV64ahEXL4mvLmCRBdcVHiMc.png)

El widget de botón se controla mediante un objeto de configuración: label, icono, colores, loading, actions.


En Ninox, el punto de entrada se llama `arcCustomButton({ ... })` — solo en el campo de fórmula o integrado en Table, Layout, Kanban.


Además, puedes diseñar de forma individual la apariencia y el comportamiento del botón: colores, tamaños de fuente, iconos, espaciados, alineación y efectos hover se controlan mediante el objeto de configuración. También se puede integrar un badge opcional (p. ej. para mostrar un contador).

El widget es especialmente adecuado para:

- **dashboards interactivos** (p. ej. acciones rápidas como «crear nuevo pedido»),
- **cockpits de cliente** (p. ej. «descargar PDF», «contactar soporte»),
- **control de workflow** (p. ej. «cambiar estado», «siguiente paso»),
- o cualquier otro lugar donde quieras hacer accesibles acciones de forma visual.

Como en todos los arcWidgets, la configuración se realiza directamente mediante un código de aplicación (objeto JSON) en un campo de fórmula solo, o integrado en otro widget.

## Código de aplicación completo

![](https://framerusercontent.com/images/hYjjWfJ7Ja9ldr3SBPThwgP3RiM.png)

A continuación verás un código de aplicación de ejemplo para un botón:


```javascript
arcCustomButton({
        uniqueId: "Button " + Nr,
        title: "Neuen Eintrag erstellen",
        width: "",
        height: "",
        alignY: "",
        alignX: "",
        paddingX: "",
        paddingY: "",
        gap: "5px",
        icon: arcCustomIcon({
                name: "plus-bold",
                color: "#fff"
            }),
        iconPosition: "left",
        fontSize: "",
        fontColor: "#fff",
        backgroundColor: "#0062AA",
        borderColor: "#0062AA",
        borderRadius: "5px",
        showBadge: false,
        badgeTitle: "",
        badgeColor: "",
        badgeBackground: "",
        badgeBorderColor: "",
        badgePosition: "",
        badgeGap: "6px",
        hoverActions: {
            fontColor: "",
            iconColor: "",
            backgroundColor: "",
            borderColor: "",
            animation: "0.25s"
        },
        actions: [{
                type: "create",
                tableId: "",
                popup: true,
                changeFieldValues: [{
                        fieldId: "",
                        value: ""
                    }, {
                        fieldId: "",
                        value: ""
                    }]
            }]
    })
```

## Explicación de parámetros individuales

A continuación se detalla qué parámetros puedes usar y qué debes indicar en cada uno.

### uniqueId (obligatorio)

`uniqueId` es un identificador único del botón dentro de la página. Se usa internamente para el estilado (selectores CSS) y para la identificación técnica del botón.

**Tipo:** `text`
**Ejemplo:** `"create-button-123"` o `"delete " + Nr`

Este ID debería:

- ser **único por componente** (p. ej. mediante combinación de texto e ID de registro)
- **no contener caracteres especiales ni espacios** *(se sustituyen internamente de forma automática por guiones)*

💡** *****Consejo:***** **si usas varios botones en una página, p. ej. en una lista o tabla, se recomienda un formato como `"edit-" + Nr` o `"btn-" + Nr`.


```javascript
uniqueId: Nr,
uniqueId: "Button 1", // Text in "
```

### title

`title` determina el texto visible dentro del botón. Debería formularse de forma corta y clara, para que los usuarios reconozcan de inmediato qué dispara el botón.

**Tipo:** `text`
**Ejemplo:** `"Neuen Eintrag erstellen"` o `"PDF herunterladen"`

💡** *****Consejo:***** **si quieres crear un botón puramente de icono (p. ej. solo un símbolo de más), puedes simplemente poner `title` en `"`.


```javascript
title: "",
```

### width

El parámetro `width` fija el ancho con el que se muestra el botón. Si no se indica ningún valor, el botón se adapta automáticamente al contenido.

**Tipo:** *text* (con unidad CSS)
**Ejemplo:** `"120px"`, `"100%"`

💡 *Consejo:* usa `"100%"` cuando el botón deba ocupar todo el ancho disponible del contenedor — p. ej. en layouts responsivos o en vistas móviles.


```javascript
width: "100%",// Prozent-Werte in "
width: "100px",// Pixel-Werte in "
```

### height

El parámetro `height` fija la altura con la que se muestra el botón. Si no se indica ningún valor o se establece `"auto"`, la altura se ajusta al contenido y al padding.

**Tipo:** *text* (con unidad CSS)
**Ejemplo:** `"40px"`, `"auto"`

💡 *Consejo:* una altura fija puede ser útil si quieres mostrar varios botones uno junto a otro con la misma altura — p. ej. en toolbars o tablas.


```javascript
height: "100%", // Prozent-Werte in "
height: "100px", // Pixel-Werte in "
height: "", // default: auto
```

### alignY

***alignY*** controla la alineación vertical del botón dentro de su contenedor. Sin valor: centrado.

```javascript
alignY: "top",
alignY: "center", // default
alignY: "bottom",
```

### alignX

***alignX*** controla la alineación horizontal del botón dentro de su contenedor. Sin valor: centrado.

```javascript
alignX: "left",
alignX: "center", // default
alignX: "right",
```

### paddingX

***paddingX*** establece el espaciado interno horizontal (izquierda/derecha) hacia el texto o el icono. **Tipo:** text (unidad CSS, p. ej. `px`, `em`, `%`).

```javascript
paddingX: "10px",
paddingX: "1em",
```

Consejo: con `paddingX` puedes influir visualmente en el ancho del botón — independientemente de `width`.

### paddingY

***paddingY*** establece el espaciado interno vertical (arriba/abajo). **Tipo:** text (unidad CSS).

```javascript
paddingY: "6px",
paddingY: "0.5em",
```

Consejo: `paddingY` proporciona áreas de clic agradables, especialmente en dispositivos táctiles.

### gap

El parámetro `gap` fija el espacio entre texto e icono dentro del botón. Si no se establece ningún valor, el espaciado por defecto es `5px`.

**Tipo:** *text* (con unidad CSS, p. ej. `px`, `em`)
**Ejemplo:** `"4px"`, `"0.5em"`, `"8px"`

💡 *Consejo:* si usas botones solo con texto o solo con icono, puedes omitir `gap` — solo es relevante cuando ambos elementos están presentes.


```javascript
gap: "10px", // z.B. Pixel-Werte
gap: "", // default: 5px
```

### prefix

El parámetro `prefix` inserta un slot de contenido libre **antes** del contenido principal (icono + texto). Acepta todos los mini-widgets (`arcCustomIcon`, `arcCustomBadge`, `arcCustomLayout`, texto plano).

**Tipo:** *mini-widget o texto*
**Ejemplo:**

```javascript
prefix: arcCustomIcon({ name: "calendar", color: "#888", size: "14px" }),
prefix: arcCustomBadge({ value: "Neu", backgroundColor: "#34C759", fontColor: "#fff", borderColor: "#34C759" }),
prefix: "", // default: kein Prefix
```

💡 *Consejo:* para botones con `width: "100%"`, `prefix` es ideal para un icono o badge en el lado izquierdo, mientras que `suffix` ocupa el borde derecho.

### suffix

El parámetro `suffix` inserta un slot de contenido libre **después** del contenido principal. Se empuja automáticamente hacia el **borde derecho** en cuanto el botón tiene un ancho explícito (p. ej. `width: "100%"`). Acepta todos los mini-widgets.

**Tipo:** *mini-widget o texto*
**Ejemplo:**

```javascript
suffix: arcCustomIcon({ name: "chevron-right", color: "#fff", size: "14px" }),
suffix: arcCustomBadge({ value: "Aktuell", backgroundColor: "#34C759", fontColor: "#fff", borderColor: "#34C759" }),
suffix: "", // default: kein Suffix
```

💡 *Consejo:* caso de uso clásico — botón de elemento de lista con texto a la izquierda e icono de chevron a la derecha:

```javascript
arcCustomButton({
    uniqueId: "period-btn-" + Nr,
    width: "100%",
    title: "04.05.2026",
    suffix: arcCustomIcon({ name: "chevron-right", color: "#fff", size: "14px" }),
    backgroundColor: "#333",
    fontColor: "#fff",
    actions: [...]
})
```

### icon

El parámetro `icon` permite añadir al botón un icono cualquiera. El icono se genera con la ayuda del widget [arcCustomIcon](/documentation/custom-icon) y se puede diseñar libremente (nombre, color, tamaño, etc.). A través de tu [User Cockpit](https://www.arc-rider.de/documentation/user-cockpit) puedes elegir los iconos que quieras usar.

**Tipo:** *widget* (`arcCustomIcon`)
**Ejemplo:**


```javascript
icon: arcCustomIcon({
                name: "plus-bold",
                color: "#fff"
            }), // arcCustomIcon einsetzen, um Icon einzufügen.
icon: "", // default: Kein Icon wird ausgegeben.
```

💡 *Consejo:* también puedes usar el botón sin texto (`title: "`) y representarlo solo mediante un icono — ideal para toolbars compactas o barras de símbolos.

**title**, **subtitle** y **badgeTitle** (con `showBadge: true`) también pueden ser mini-widgets — p. ej. `badgeTitle: arcCustomBadge({ value: "3", ... })` — no solo texto plano.

### iconPosition

El parámetro `iconPosition` fija dónde se muestra el icono en relación con el texto. Si no se establece ningún valor, el icono se muestra a la izquierda del texto.

**Tipo:** <em>text
</em>**Ejemplo: **


```javascript
iconPosition: "left", // Icon erscheint links vom Text.
iconPosition: "right", // Icon erscheint rechts vom Text.
iconPosition: "top", // Icon erscheint oben vom Text.
iconPosition: "buttom", // Icon erscheint unten vom Text.

iconPosition: "", // default: links
```

### fontSize

El parámetro `fontSize` fija el tamaño de fuente del texto del botón. Si no se establece ningún valor, el tamaño estándar es `13px`.

**Tipo:** *text* (con unidad CSS)
**Ejemplo:** `"14px"`

💡 *Consejo:* si usas botones en distintos contextos (p. ej. en tarjetas o listas), con `fontSize` puedes crear una jerarquía visual — p. ej. botones más pequeños para acciones secundarias, más grandes para funciones centrales.


```javascript
fontSize: "18px",// Pixel-Werte in "
```

### fontColor

El parámetro `fontColor` fija el color del texto del botón. Si no se establece ningún valor, se usa por defecto un gris oscuro (`#515971`).

**Tipo:** *text* (código hex o nombre de color CSS)
**Ejemplo:** `"#ffffff"`, `"black"`, `"rgb(255, 0, 0)"`

💡 *Consejo:* presta atención a un contraste suficiente con el color de fondo (`backgroundColor`), para garantizar legibilidad y accesibilidad — especialmente en botones de color o temas oscuros.


```javascript
fontColor: "#ffffff", // HEX-Wert in "
```

### backgroundColor

El parámetro `backgroundColor` define el color de fondo del botón. Si no se indica ningún valor, el widget usa por defecto un gris claro (`#F7F8FC`).

**Tipo:** *text* (código hex o nombre de color CSS)
**Ejemplo:** `"#0062AA"`, `"white"`, `"rgba(0, 0, 0, 0.1)"`

💡 *Consejo:* para una respuesta visual clara en acciones se recomienda un tono de color intenso — ideal en combinación con texto blanco (`fontColor: "#ffffff"`).


```javascript
backgroundColor: "#4970ff", // HEX-Wert in "
```

### borderColor

El parámetro `borderColor` fija el color del borde del botón. Si no se indica ningún valor, se usa por defecto un gris claro discreto (`#E9ECF4`).

**Tipo:** *text* (código hex o nombre de color CSS)
**Ejemplo:** `"#0062AA"`, `"transparent"`, `"rgba(0, 0, 0, 0.2)"`

💡 *Consejo:* si quieres diseñar un botón completamente plano sin borde visible, puedes poner `borderColor` en `"transparent"` — o hacerlo coincidir con el color de fondo.


```javascript
 borderColor: "#EEEEEE", // HEX-Wert in "
```

### borderRadius

El parámetro `borderRadius` determina cuánto se redondean las esquinas del botón. Si no se establece ningún valor, el widget usa por defecto `3px`.

**Tipo:** *text* (con unidad CSS)
**Ejemplo:** `"0px"` (rectangular), `"5px"` (ligeramente redondeado), `"50px"` (con forma de píldora)

💡 *Consejo:* para elementos de UI modernos son adecuadas las esquinas ligeramente redondeadas (`4–8px`).


```javascript
 borderRadius: "50px", // 50px = ganz abgerundet // default Wert sind: 3px
```

### embedded

El parámetro `embedded` controla si el widget está integrado dentro de otro widget (p. ej. en una tarjeta o un contenedor de layout).

**Tipo:** *boolean* (`true` / `false`)
**Valor por defecto:** `false`


```javascript
embedded: false, // ermöglicht den Standalone Einsatz des Widgets (nicht eingebettet in anderen Widgets)
embedded: true,  // Fallback
```

### Badge

Con el sistema de badge puedes añadir al botón una pequeña marca adicional — p. ej. un contador, una etiqueta («Nuevo», «!», «3»), o un símbolo para avisos especiales. El badge se muestra visualmente diferenciado y se puede adaptar en color y posición.

<figure><table><tbody><tr><th>Parameter

</th><th>Typ

</th><th>Beschreibung

</th></tr><tr><td>`showBadge`

</td><td>*boolean*

</td><td>Determina si se muestra un badge (`true` / `false`). También se puede determinar por script: `if cnt(Dokumente)>0 then true end `

</td></tr><tr><td>`badgeTitle`

</td><td>*text*

</td><td>Texto o número en el badge

</td></tr><tr><td>`badgeColor`

</td><td>*text*

</td><td>Color de texto en el badge (p. ej. `"#ffffff"`)

</td></tr><tr><td>`badgeBackground`

</td><td>*text*

</td><td>Color de fondo del badge (p. ej. `"#e9595d"`)

</td></tr><tr><td>`badgeBorderColor`

</td><td>*text*

</td><td>Color del borde del badge (p. ej. `"#ffffff"`)

</td></tr><tr><td>`badgePosition`

</td><td>*text*

</td><td>Posicionamiento adicional del badge *(p. ej. *`*"outside"*`* para representación fuera del botón)*

</td></tr><tr><td>`badgeGap`

</td><td>*text*

</td><td>Espacio entre el contenido del botón y el badge en la posición estándar (estándar: `"6px"`). No se aplica con `badgePosition: "outside"`.

</td></tr></tbody></table></figure>### hoverActions

Con `hoverActions` puedes definir cómo se comporta visualmente el botón cuando el usuario pasa el ratón por encima («efecto hover»). Con esto puedes cambiar de forma específica color, borde y animación — tanto para el botón mismo como para el icono.


```javascript
hoverActions: {
    fontColor: "#ffffff",
    iconColor: "#ffffff",
    backgroundColor: "#0062AA",
    borderColor: "#0062AA",
    animation: "0.1s"
},
```

💡 *Consejo:* si no necesitas ningún efecto hover, puedes omitir `hoverActions` por completo. Si tu botón tiene un **color de fondo claro**, se recomienda al hacer hover un **tono más oscuro** con **texto blanco**, para aumentar la interactividad y el contraste. Así la acción se reconoce visualmente con claridad y con menos barreras.

<figure><table><tbody><tr><th>Feld

</th><th>Typ

</th><th>Beschreibung

</th><th>Beispielwert

</th></tr><tr><td>`fontColor`

</td><td>*text*

</td><td>Color de texto al hacer hover

</td><td>`"#ffffff"`

</td></tr><tr><td>`backgroundColor`

</td><td>*text*

</td><td>Color de fondo al hacer hover

</td><td>`"#004C8A"`

</td></tr><tr><td>`borderColor`

</td><td>*text*

</td><td>Color de borde al hacer hover

</td><td>`"#003366"`

</td></tr><tr><td>`iconColor`

</td><td>*text*

</td><td>Color del icono al hacer hover (solo relevante en iconos SVG)

</td><td>`"#ffffff"`

</td></tr><tr><td>`animation`

</td><td>*text*

</td><td>Tiempo de transición CSS para efectos suaves

</td><td>`"0.25s"`

</td></tr></tbody></table></figure>### actions ✅

Con el parámetro `actions` defines qué debe pasar cuando se hace clic en el botón. Puedes indicar una o varias acciones — desde abrir una URL simple hasta crear nuevos registros o ejecutar JavaScript personalizado.

**State-Bags:** para actualizaciones parciales en contenedores JSON (`type: "update"`) ver [`data-bag-actions`](../patterns/data-bag-actions.md) (`dataBag` + `patch` en lugar de sobrescribir todo el campo).

**Polling:** `update` repetido (p. ej. campo de trigger) con `polling: { intervalMs, maxAttempts, active }` — ver [`action-polling`](../patterns/action-polling.md). Combina con Loading/`sequences.when`.

**Tipo:** *lista de objetos* (array con al menos un objeto de action)
**Estructura de una action: **cada action es un objeto con al menos el campo `type` — según el tipo, se requieren o son opcionales otros campos.

#### Tipos de action admitidos

<figure><table><tbody><tr><th>`type`

</th><th>Beschreibung

</th><th>Code-Beispiel

</th></tr><tr><td>`"openUrl"`

</td><td>Abre un enlace externo en una nueva pestaña

</td><td>
```javascript
{type: "openUrl",
value: "https://example.com" }
```

</td></tr><tr><td>`"openRecord"`

</td><td>Abre un registro existente en la ventana actual

</td><td>
```javascript
{ type: "openRecord",
  recordId: first(select Dashboard).Nr}
```

</td></tr><tr><td>`"openFullscreen"`

</td><td>Abre un registro en modo pantalla completa

</td><td>
```javascript
{ type: "openFullscreen",
  recordId: Nr,
  tab: "Details" }
```

</td></tr><tr><td>`"popup"`

</td><td>Abre un registro como popup

</td><td>
```javascript
{ type: "popup",
recordId: Nr,
tab: "Info" }
```

</td></tr><tr><td>`"closeRecord"`

</td><td>Cierra el registro actual

</td><td>
```javascript
{ type: "closeRecord",
  recordId: Nr }
```

</td></tr><tr><td>`"closeFullscreen"`

</td><td>Cierra el modo de pantalla completa

</td><td>
```javascript
{ type: "closeFullscreen",
  recordId: Nr }
```

</td></tr><tr><td>`"closeAllRecords"`

</td><td>Cierra todos los registros abiertos

</td><td>
```javascript
{ type: "closeAllRecords" }
```

</td></tr><tr><td>`"delete"`

</td><td>Elimina el registro indicado

</td><td>
```javascript
{ type: "delete",
recordId: Nr }
```

</td></tr><tr><td>`"update"`

</td><td>Actualiza un campo en un registro

</td><td>
```javascript
{ type: "update",
recordId: Auftrag.Nr,
field: "A1",
value: "Erledigt" }
```

</td></tr><tr><td>`"create"`

</td><td>Crea un nuevo registro con popup opcional

</td><td>
```javascript
{ type: "create",
tableId: "A",
popup: true,
changeFieldValues: [{ fieldId: "AZ",
                      value: "Neu" }] }
```

</td></tr><tr><td>`"customJS"`

</td><td>Ejecuta código JavaScript personalizado

</td><td>
```javascript
{ type: "customJS",
value: "alert('Hallo Welt!');" }
```

</td></tr></tbody></table></figure>💡 *Consejo:* puedes ejecutar varias acciones una tras otra combinándolas en el array. La ejecución se realiza en el orden en que se indican en el array.

### loading

Muestra un estado de carga después del clic — **en el botón** o como **overlay** (backdrop sobre toda la app).

```javascript
loading: {
    show: true,
    hideOnFinish: true,
    minDuration: 300,
    indicator: {
        type: "dots",
        color: "#fff",
        width: "60px",
        height: "12px"
    },
    position: "right",
    hideTitle: false,
    hideIcon: false,
    overlay: { /* siehe unten */ }
}
```

| Property | Typ | Default | Beschreibung |
|----------|-----|---------|--------------|
| `show` | boolean | — | Activar loading |
| `hideOnFinish` | boolean | `true` | Ocultar tras el fin de las actions |
| `minDuration` | number (ms) | `0` | Duración mínima de visualización (evita parpadeos) |
| `indicator` | object | ver abajo | Apariencia del indicador de carga |
| `position` | text | `right` | Solo in-button: `left` / `right` (inline junto al contenido), **`prefix`** / **`suffix`** (fijado al slot — `suffix` sustituye al chevron en botones de ancho completo; combinar con `hide.suffix: true`) |
| `hide` | object | — | Ocultar slots durante el in-button-loading – ver tabla abajo |
| `hideTitle` | boolean | `false` | *Legacy* – oculta toda el área de contenido. Prefiere `hide.title` |
| `hideIcon` | boolean | `false` | *Legacy* – oculta el icono si está en el lado del indicador. Prefiere `hide.icon: "auto"` |
| `styles` | text / object | `hover`* | Solo in-button: qué colores rigen durante el loading (*Default: `hoverActions`, si no, normal) |
| `overlay` | boolean / object | — | establecido = modo overlay; ausente = in-button |

#### hide (in-button-loading)

Con `loading.hide` puedes ocultar slots individuales del botón durante el proceso de carga.

| Slot | Typ | Beschreibung |
|------|-----|--------------|
| `icon` | boolean / `"auto"` | `true` = ocultar siempre · `false` = nunca · `"auto"` = solo si el icono está en el lado del indicador (comportamiento legacy de `hideIcon`) |
| `title` | boolean | Ocultar el texto del botón |
| `subtitle` | boolean | Ocultar el subtítulo |
| `badge` | boolean | Ocultar el badge |
| `prefix` | boolean | Ocultar el slot prefix |
| `suffix` | boolean | Ocultar el slot suffix |

```javascript
loading: {
    show: true,
    position: "suffix",
    hide: {
        suffix: true,
    },
    indicator: { type: "spinner", color: "#fff", width: "18px", height: "18px" }
}
```

💡 *Consejo:* con `width: "100%"` y chevron a la derecha: `suffix` + `loading.position: "suffix"` + `hide.suffix: true` — el spinner queda entonces exactamente en el lugar del chevron, el texto permanece a la izquierda.

#### styles (in-button-loading)

Durante la carga, el botón no permanece en `:hover` (movimiento del ratón/`pointer-events`), sino que recibe colores **fijados de forma estable** — para que el color del indicador coincida con el estado visible.

| Wert | Verhalten |
|------|-----------|
| *(omitir)* o `"hover"` | `hoverActions` como colores fijos del botón (si están establecidos) |
| `"default"` | Colores normales del botón (`backgroundColor`, `fontColor`, …) |
| `{ backgroundColor, fontColor, borderColor, iconColor }` | Colores de loading propios (mismos campos que `hoverActions`) |

```javascript
loading: {
    show: true,
    styles: "hover",
    indicator: { type: "dots", color: "#fff" }
}
```

#### indicator

Se aplica al in-button y como base para el overlay. Se puede sobrescribir en `overlay.indicator` y por entrada en `sequences[].indicator`.

| Feld | Typ | Default | Beschreibung |
|------|-----|---------|--------------|
| `type` | text | `dots` | `dots` (tres puntos), `spinner` (círculo), `pulse` (punto pulsante) |
| `color` | text | `#4970ff` | Color |
| `width` | text | `60px` (Button) / `60px` (Overlay) | Ancho CSS |
| `height` | text | `12px` (Button) / `14px` (Overlay) | Alto CSS |

#### overlay (adicional)

Controla la **tarjeta de diálogo blanca** (no el indicador).

| Feld | Typ | Default | Beschreibung |
|------|-----|---------|--------------|
| `width` | text | `300px` | Ancho de la tarjeta overlay |
| `height` | text | `280px` | Alto de la tarjeta overlay |
| `backgroundColor` | text | `#ffffff` | Color de fondo de la tarjeta overlay |
| `indicator` | object | de `loading.indicator` | Indicador opcional distinto en el overlay |
| `title` | text / object | — | Título (texto plano o `{ value, styles }`) |
| `message` | text / object | — | Descripción (texto plano o `{ value, styles }`) |

**`title` y `message`** — como en los bloques de layout: string plano u objeto con CSS opcional (`styles` sobrescribe las clases por defecto `.arc_loading_title` / `.arc_loading_message`):

```javascript
overlay: {
    title: { value: "Wird gespeichert…", styles: "font-size: 18px; font-weight: 700; color: #0f766e;" },
    message: { value: "Bitte warten.", styles: "font-size: 13px; color: #64748b;" }
}
```

`value` también puede ser un mini-widget (p. ej. `arcCustomText({...})`), no solo texto.

#### Modos de overlay

| `overlay` | Verhalten |
|-----------|-----------|
| `true` | Solo backdrop + spinner |
| `{ title, message }` | Mensaje fijo (diálogo tipo confirmación, sin botones) |
| `{ sequences: [...] }` | Mensajes dinámicos (tiempo y/o booleanos de Ninox) |

#### sequences – timeline combinada

Cada sequence puede tener **tiempo** (`after`), **condición** (`when`) o **ambos**:

```javascript
overlay: {
    width: "320px",
    backgroundColor: "#f8fafc",
    title: "Einen Moment…",
    indicator: { type: "spinner", color: "#3e6fff", width: "32px", height: "32px" },
    sequences: [
        { after: 0, title: "Starte…", priority: 5 },
        { after: 800, title: "Verarbeite…", priority: 5 },
        { when: helper_uploading, title: "Upload läuft…", priority: 40, indicator: { type: "pulse" } },
        { after: 3000, when: helper_stillBusy, message: "Noch einen Moment…", priority: 15 }
    ]
}
```

| Feld (pro Sequence) | Typ | Beschreibung |
|------------------|-----|--------------|
| `after` | number (ms) | opcional; desde el inicio del overlay |
| `when` | boolean | opcional; campo de Ninox, se recalcula en cada reload |
| `priority` | number | opcional; mayor = más importante en caso de solapamiento |
| `title` / `message` | text / object | se requiere al menos uno; opcional `{ value, styles }` |
| `indicator` | object | opcional; objeto `indicator` completo para esta sequence (sustituye/complementa `type`, `color`, `width`, `height`) |

**Resolver:** una sequence está activa cuando se cumplen la condición de tiempo y la booleana. Con varias sequences activas, gana la `priority` más alta.


**Consejo de Ninox para `when`:** establece campos auxiliares (boolean) mediante trigger, para que la fórmula se recalcule durante acciones largas y el texto del overlay cambie.


### Conclusión

El widget `arcCustomButton` es una herramienta versátil para hacer visibles e interactivas las acciones en tu app de Ninox — ya sea que quieras diseñar enlaces simples, workflows complejos o dashboards visualmente atractivos. Gracias a las posibilidades de diseño flexibles y al potente sistema de acciones, el botón se integra sin fisuras en layouts y componentes existentes.

💡 *Consejo profesional:* en combinación con otros arcWidgets — p. ej. `arcCustomText` o `arcCustomCard` — puedes desarrollar bloques de UI completos que convencen tanto funcional como visualmente.
