---
title: "Custom Drawing"
slug: "custom-drawing"
category: "Widgets"
reactComponent: "ArcWidgetDrawing"
reactTier: "premium"
reactSince: "0.1.0-alpha.5"
reactExample: "drawing.tsx"
locale: "es"
hosts: "react"
---

# Drawing en React

Edita formas y dibujos en un lienzo. La aplicación asigna IDs, guarda los cambios y procesa las exportaciones.

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 { ArcWidgetDrawing } from '@arcrider/arcwidgets-react';
import { useState } from 'react';
import type { ArcWidgetDrawingShape } from '@arcrider/arcwidgets-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;

const demoShapes: ArcWidgetDrawingShape[] = [
  {
    id: 'mark-1',
    clickable: true,
    shapeDataValue: {
      type: 'circle',
      cx: 140,
      cy: 120,
      r: 36,
      stroke: '#059669',
      strokeWidth: 3,
      fill: 'rgba(16,185,129,0.18)',
    },
  },
  {
    id: 'mark-2',
    clickable: true,
    shapeDataValue: {
      type: 'rect',
      x: 240,
      y: 80,
      width: 170,
      height: 100,
      rx: 12,
      stroke: '#d97706',
      strokeWidth: 3,
      fill: 'rgba(245,158,11,0.2)',
    },
  },
];

const busyShapes: ArcWidgetDrawingShape[] = [
  ...demoShapes,
  {
    id: 'mark-3',
    clickable: true,
    shapeDataValue: {
      type: 'circle',
      cx: 460,
      cy: 250,
      r: 48,
      stroke: '#e11d48',
      strokeWidth: 3,
      fill: 'rgba(244,63,94,0.16)',
    },
  },
  {
    id: 'mark-4',
    clickable: true,
    shapeDataValue: {
      type: 'rect',
      x: 80,
      y: 230,
      width: 120,
      height: 70,
      rx: 10,
      stroke: '#7c3aed',
      strokeWidth: 3,
      fill: 'rgba(139,92,246,0.16)',
    },
  },
];

export default function Example() {
  const [shapes, setShapes] = useState<ArcWidgetDrawingShape[]>(
    pack === 'empty' ? [] : pack === 'busy' ? busyShapes : demoShapes,
  );
  const [selected, setSelected] = useState(
    t(
      'Form ziehen oder skalieren',
      'Drag or resize a shape',
      'Arrastra o escala una forma',
    ),
  );
  return (
    <>
      <ArcWidgetDrawing
        id="drawing"
        data={{
          height: '420px',
          canvas: { width: 1000, height: 800 },
          artboard: { width: 600, height: 400 },
          create: { enabled: true },
          shapes,
        }}
        onShapeActivate={({ shape_id }) => setSelected(String(shape_id))}
        onShapeCreate={(payload, completion) => {
          const id = crypto.randomUUID();
          setShapes((previous) => [
            ...previous,
            { id, shapeDataValue: payload.shape_data_value },
          ]);
          completion.promise = Promise.resolve(id);
        }}
        onShapeUpdate={(payload) =>
          setShapes((previous) =>
            previous.map((shape) =>
              shape.id === payload.shape_id
                ? { ...shape, shapeDataValue: payload.shape_data_value }
                : shape,
            ),
          )
        }
      />
      <p aria-live="polite">
        {t('Formen', 'Shapes', 'Formas')}: {shapes.length} ·{' '}
        {t('Auswahl', 'Selection', 'Selección')}: {selected}
      </p>
    </>
  );
}
```

## Props del componente

### id

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

### data

Configuración de tipo `ArcWidgetDrawingData`. 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).

### onShapeCreate

Nueva forma y un objeto de completion mutable. Establece su `promise` con el ID asignado.

```typescript
onShapeCreate?: (payload: ArcWidgetDrawingCreatePayload, completion: { promise?: Promise<string | number> }) => void;
```

### onShapeUpdate

Forma modificada y su ID.

```typescript
onShapeUpdate?: (payload: { shape_id: string | number; shape_data_value: Record<string, unknown>; bag?: unknown }) => void;
```

### onShapeActivate

ID de la forma activada.

```typescript
onShapeActivate?: (payload: { shape_id: string | number }) => void;
```

### onExport

Formato de exportación e imagen como data URL.

```typescript
onExport?: (payload: { format: string; base64: string }) => 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.

### height

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

Tipo: `string`.

### canvas

Área de trabajo en píxeles.

Tipo: `{ width?: number; height?: number; [key: string]: unknown }`.

### artboard

Área de dibujo y exportación en píxeles.

Tipo: `{ width?: number; height?: number; [key: string]: unknown }`.

### shapes

Formas con `id` estable y geometría en `shapeDataValue`.

Tipo: `ArcWidgetDrawingShape[]`.

### exportSettings

Formatos de exportación y destino de salida. Para el callback, selecciona actualmente `target: "field"`.

Tipo: `Record<string, unknown>`.

### create

Permite o impide crear nuevas formas mediante `enabled`.

Tipo: `{ enabled?: boolean }`.

### tools

Herramientas de dibujo disponibles.

Tipo: `Record<string, unknown>[]`.

### stickerTypes

Stickers disponibles.

Tipo: `Record<string, unknown>[]`.

### drawingSettings

Ajustes para el dibujo.

Tipo: `Record<string, unknown>`.

### zooming

Límites e incremento del zoom.

Tipo: `{ min?: number; max?: number; step?: number }`.

## Comportamiento y límites

- Cada forma necesita un `id` estable y `shapeDataValue` como objeto o string JSON serializado. El widget React normaliza `id` para el núcleo de dibujo.

- Al crear obtienes un segundo parámetro: establece `completion.promise` con un promise que contenga el nuevo ID. Adopta la misma forma con este ID en tu estado.

- `onShapeUpdate` entrega `shape_id` y la nueva forma. Reemplaza la forma correspondiente de manera inmutable en tu estado.

- Para `onExport` se necesita actualmente `exportSettings.allowedTypes: [{ format: "png", target: "field" }]`. El valor histórico `field` selecciona el callback de data URL; no se escribe ningún campo de base de datos. `target: "file"` inicia la descarga en el navegador.

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 ArcWidgetDrawingShape {
	id: string | number;
	shapeDataValue?: string | Record<string, unknown>;
	shapeId?: string | number;
	[key: string]: unknown;
}

export interface ArcWidgetDrawingData extends ArcWidgetBaseData {
	height?: string;
	canvas?: { width?: number; height?: number; [key: string]: unknown };
	artboard?: { width?: number; height?: number; [key: string]: unknown };
	shapes?: ArcWidgetDrawingShape[];
	exportSettings?: Record<string, unknown>;
	create?: { enabled?: boolean };
	tools?: Record<string, unknown>[];
	stickerTypes?: Record<string, unknown>[];
	drawingSettings?: Record<string, unknown>;
	zooming?: { min?: number; max?: number; step?: number };
}

export interface ArcWidgetDrawingCreatePayload {
	shape_data_value: Record<string, unknown>;
	sticker_uid?: string | null;
}
export interface ArcWidgetDrawingProps extends ArcReactWidgetProps<ArcWidgetDrawingData> {
	onShapeCreate?: (payload: ArcWidgetDrawingCreatePayload, completion: { promise?: Promise<string | number> }) => void;
	onShapeUpdate?: (payload: { shape_id: string | number; shape_data_value: Record<string, unknown>; bag?: unknown }) => void;
	onShapeActivate?: (payload: { shape_id: string | number }) => void;
	onExport?: (payload: { format: string; base64: string }) => void;
}
```
