---
title: "Custom Layout"
slug: "custom-layout"
category: "Widgets"
reactComponent: "ArcWidgetLayout"
reactTier: "mini"
reactSince: "0.1.0-alpha.5"
reactExample: "layout.tsx"
locale: "es"
hosts: "react"
---

# Layout en React

Organiza widgets horizontal o verticalmente. Para rejillas responsivas puedes combinar el layout con CSS Grid o Flexbox de tu aplicación.

Referencia para `@arcrider/arcwidgets-react@0.1.0-alpha.5`. [Instalación](/docs/react/intro/setup-react) · [Todos los componentes](/docs/react/intro/react-components).

## Ejemplo completo

```tsx
import {
  ArcWidgetBadge,
  ArcWidgetButton,
  ArcWidgetLayout,
  ArcWidgetText,
} from '@arcrider/arcwidgets-react';
import { useState } from 'react';

const lang = document.documentElement.lang.startsWith('en')
  ? 'en'
  : document.documentElement.lang.startsWith('es')
    ? 'es'
    : 'de';
const requested = new URLSearchParams(location.search).get('data');
const pack = requested === 'empty' || requested === 'busy' ? requested : 'demo';
const t = (de: string, en: string, es: string) =>
  lang === 'en' ? en : lang === 'es' ? es : de;

export default function Example() {
  const [count, setCount] = useState(pack === 'busy' ? 12 : 0);
  const badges =
    pack === 'empty'
      ? []
      : [
          { value: t('Offen', 'Open', 'Abierto'), color: '#d97706' },
          { value: t('Live', 'Live', 'En vivo'), color: '#15803d' },
          ...(pack === 'busy'
            ? [
                {
                  value: t('Priorität', 'Priority', 'Prioridad'),
                  color: '#be123c',
                },
                { value: t('Messe', 'Fair', 'Feria'), color: '#7c3aed' },
              ]
            : []),
        ];
  return (
    <ArcWidgetLayout
      id="layout"
      data={{
        embedded: false,
        height: '240px',
        direction: 'vertical',
        gap: '12px',
        blocks: [
          {
            height: 'auto',
            value: (
              <ArcWidgetText
                data={{
                  value: `${t('Klicks', 'Clicks', 'Clics')}: ${count}`,
                  fontSize: '20px',
                }}
              />
            ),
          },
          ...(badges.length
            ? [
                {
                  height: 'auto' as const,
                  value: (
                    <ArcWidgetLayout
                      data={{
                        embedded: true,
                        direction: 'horizontal',
                        gap: '8px',
                        height: 'auto',
                        blocks: badges.map((badge) => ({
                          width: 'auto',
                          height: 'auto',
                          value: (
                            <ArcWidgetBadge
                              data={{
                                value: badge.value,
                                singleColor: badge.color,
                                borderRadius: '6px',
                                paddingX: '10px',
                                paddingY: '4px',
                              }}
                            />
                          ),
                        })),
                      }}
                    />
                  ),
                },
              ]
            : []),
          {
            height: 'fraction',
            value: (
              <ArcWidgetButton
                data={{
                  title: t('Weiter', 'Continue', 'Continuar'),
                  width: '160px',
                  backgroundColor: '#18181b',
                  fontColor: '#ffffff',
                }}
                onClick={() => setCount((value) => value + 1)}
              />
            ),
          },
        ],
      }}
    />
  );
}
```

## Props del componente

### id

ID opcional y estable de la instancia del widget. Sin especificarlo, React genera un ID.

### data

Configuración de tipo `ArcWidgetLayoutData`. Pasa los cambios como objetos nuevos; gestiona los datos de negocio y la selección en el estado de React.

### onAction

Fallback opcional `(type: string, ...args: unknown[]) => unknown`. El callback concreto tiene prioridad. Detalles: [Estado y eventos](/docs/react/patterns/react-state-events).

### onClick

Notifica el clic. Ten en cuenta los argumentos específicos del widget más abajo.

```typescript
onClick?: () => void;
```

### onBlockClick

Índice de base cero en `data.blocks`.

```typescript
onBlockClick?: (block_index: number) => void;
```

## Configuración

Los siguientes campos pertenecen a `data`. Los tamaños se indican como strings, los números y valores de tiempo según su tipo respectivo.

### embedded

Adapta el widget a un área de contenido circundante.

Tipo: `boolean`.

### direction

Disposición horizontal o vertical.

Tipo: `'horizontal' | 'vertical' | string`.

### alignX

Alineación horizontal.

Tipo: `'left' | 'center' | 'right' | string`.

### alignY

Alineación vertical.

Tipo: `'top' | 'center' | 'bottom' | string`.

### width

Ancho del widget como valor de tamaño.

Tipo: `string`.

### height

Altura del widget, p. ej. `"320px"`. Los valores porcentuales necesitan un contenedor padre con altura definida.

Tipo: `string`.

### gap

Espacio entre los contenidos.

Tipo: `string`.

### backgroundColor

Color de fondo.

Tipo: `string`.

### paddingX

Espaciado interno a izquierda y derecha.

Tipo: `string`.

### paddingY

Espaciado interno arriba y abajo.

Tipo: `string`.

### scrollSettings

Comportamiento de scroll del área de contenido.

Tipo: `ArcWidgetLayoutScrollSettings`.

### clickable

Activa el callback de clic del widget.

Tipo: `boolean`.

### blocks

Áreas de layout con tamaño, alineación y contenido en `value`.

Tipo: `ArcWidgetLayoutBlock[]`.

## Comportamiento y límites

- Establece `direction` de forma explícita. `fraction` distribuye el espacio restante en el eje correspondiente; una altura de `100%` necesita un contenedor padre con límite definido.

- `blocks[].value` admite JSX. Vincula los eventos de componentes anidados directamente a sus props de callback.

- Para clics en el layout o en un bloque debe establecerse `clickable: true` en el objeto correspondiente. `onBlockClick` recibe el índice en `blocks`.

- Para pantalla completa y layout de página usa el contenedor de tu aplicación React. Los campos históricos `fullscreen`, `fullscreenMode`, `page` y `showAdminTools` no son una API de routing de React.

Los campos `ArcWidgetSlot` admitidos permiten elementos JSX individuales, texto o descriptores de widget. Pasa texto externo como texto JSX; los strings HTML se interpretan como HTML. [Combinar contenidos](/docs/react/patterns/nested-widget-descriptors).

## Tipos de datos

Estos tipos relacionados con el widget se exportan desde el paquete. También están disponibles tipos comunes como `ArcWidgetSlot`, `ArcWidgetStyles` y `ArcReactWidgetProps`. Las firmas de índice permiten extensiones; no garantizan que el widget evalúe campos arbitrarios.

```typescript
export interface ArcWidgetLayoutBlock {
	width?: string;
	height?: string;
	lineHeight?: string;
	alignX?: 'left' | 'center' | 'right' | string;
	alignY?: 'top' | 'center' | 'bottom' | string;
	color?: string;
	styles?: ArcWidgetStyles | string;
	value?: ArcWidgetSlot;
	clickable?: boolean;
	[key: string]: unknown;
}

export interface ArcWidgetLayoutScrollSettings {
	scrollY?: boolean;
	scrollX?: boolean;
	[key: string]: unknown;
}

export interface ArcWidgetLayoutData extends Omit<ArcWidgetBaseData, 'actions'> {
	embedded?: boolean;
	direction?: 'horizontal' | 'vertical' | string;
	alignX?: 'left' | 'center' | 'right' | string;
	alignY?: 'top' | 'center' | 'bottom' | string;
	width?: string;
	height?: string;
	gap?: string;
	backgroundColor?: string;
	paddingX?: string;
	paddingY?: string;
	fullscreen?: boolean;
	fullscreenMode?: string;
	page?: boolean;
	showAdminTools?: boolean;
	scrollSettings?: ArcWidgetLayoutScrollSettings;
	clickable?: boolean;
	blocks?: ArcWidgetLayoutBlock[];
}

export interface ArcWidgetLayoutProps extends ArcReactWidgetProps<ArcWidgetLayoutData> {
	onClick?: () => void;
	onBlockClick?: (block_index: number) => void;
}
```
