# Componente de shadcn/ui

> Instala un componente de formulario que renderiza tus campos de Ikiform con tus propios componentes de shadcn/ui.

Si tu proyecto usa shadcn/ui, puedes instalar un formulario listo en lugar de escribir el markup. Es una opción entre varias: el mismo formulario sigue funcionando con [HTML](https://ikiform.com/es/docs/html.md) y con [fetch](https://ikiform.com/es/docs/frameworks.md).

## Instalación

`Terminal`:

```bash
npx shadcn@latest add https://ikiform.com/r/form.json
```

Esto copia `components/ikiform/form.tsx` en tu proyecto e instala los componentes de shadcn/ui que usa: `button`, `checkbox`, `input`, `label`, `radio-group` y `textarea`. El archivo es tuyo para editarlo. Los selects usan un `<select>` nativo, así que funciona con las variantes Radix y Base UI de shadcn/ui.

## Uso

`app/contact/page.tsx`:

```tsx
import { IkiForm } from "@/components/ikiform/form";

export default function Contact() {
  return <IkiForm form="frm_xxxxxxxxxxxxxxxx" />;
}
```

Al montarse, el componente obtiene el esquema público del formulario y renderiza un control por campo, con las etiquetas, placeholders, textos de ayuda y opciones que configuraste en el panel. Define primero los campos en la pestaña [Fields](https://ikiform.com/es/docs/fields.md) del formulario; un formulario sin campos no renderiza inputs.

- Valida en el navegador con las mismas reglas y mensajes que el servidor.
- Envía JSON con el honeypot y una marca de tiempo de renderizado firmada, lo que ayuda a la puntuación de spam.
- Los errores de campo del servidor aparecen debajo de sus campos; los demás errores aparecen encima del botón.
- Si todo va bien, sustituye el formulario por su mensaje de éxito.

## Props

| Prop | Tipo | Descripción |
| --- | --- | --- |
| `form` | `string` | Obligatorio. El id del formulario. |
| `fields` | `IkiFormField[]` | Sustituye los campos obtenidos. Usa la misma forma que las definiciones de campos. |
| `onSuccess` | `({ id, values }) => void` | Se llama después de un envío correcto. |
| `submitLabel` | `string` | Texto del botón. Por defecto, la etiqueta de envío del formulario. |
| `successMessage` | `ReactNode` | Se muestra después del envío. Por defecto, el mensaje de éxito del formulario. |
| `turnstileSiteKey` | `string` | Solo para formularios con tus propias claves de Turnstile y sin clave de sitio guardada en Ikiform. |
| `className` | `string` | Nombres de clase para el elemento form. |
| `baseUrl` | `string` | Por defecto, `https://ikiform.com`. |

`app/waitlist/page.tsx`:

```tsx
import { IkiForm } from "@/components/ikiform/form";

export default function Waitlist() {
  return (
    <IkiForm
      form="frm_xxxxxxxxxxxxxxxx"
      submitLabel="Join the waitlist"
      successMessage="You're on the list."
      onSuccess={({ id }) => console.log("Submitted", id)}
    />
  );
}
```

### Campos en el código

Pasa `fields` para renderizar sin la definición del panel. El servidor sigue validando contra los campos publicados del formulario, así que mantén ambos sincronizados.

`Campos en el código`:

```tsx
<IkiForm
  form="frm_xxxxxxxxxxxxxxxx"
  fields={[
    { id: "email", type: "email", label: "Work email", required: true },
    { id: "team_size", type: "number", label: "Team size", validation: { min: 1, integer: true } },
  ]}
/>
```

## Verificación humana

Con la verificación antispam en **Ikiform**, el componente incrusta un pequeño frame de ikiform.com que permanece oculto hasta que Turnstile necesita un clic, y pide un token nuevo después de cada intento. Si el frame no puede cargar, ofrece abrir la verificación en una ventana nueva. Con tus propias claves de Turnstile, renderiza el widget de Turnstile con la clave de sitio del formulario.

## El endpoint del esquema

El componente lee `GET https://ikiform.com/f/<formId>/schema`. Puedes llamarlo tú para construir tu propio renderizador, o usar `getSchema` del [SDK](https://ikiform.com/es/docs/sdk.md#getschema).

`GET /f/:formId/schema`:

```json
{
  "id": "frm_xxxxxxxxxxxxxxxx",
  "title": "Contact",
  "description": null,
  "fields": [{ "id": "email", "type": "email", "label": "Email", "required": true }],
  "settings": { "submit_label": "Send", "success_message": "Thanks!" },
  "honeypot_field": "_gotcha",
  "turnstile_required": false,
  "turnstile_site_key": null,
  "challenge": null,
  "ts": "1792300000000.signature"
}
```

- Abierto a cualquier origen (`Access-Control-Allow-Origin: *`) y nunca en caché.
- Los formularios en pausa, desactivados y desconocidos devuelven el mismo `404`.
- Solo salen del servidor los campos publicados y los ajustes de visualización. Los dominios permitidos, la URL de redirección, los ajustes de spam y los límites de frecuencia siguen siendo privados.
- `challenge` es `{ "provider": "ikiform", "url": ... }`, `{ "provider": "custom", "site_key": ... }` o `null`. `ts` es una marca de tiempo de renderizado firmada y reciente que debes devolver como `_ikiform_ts`.
- Permite 60 peticiones por minuto por visitante y formulario, aparte del margen de envíos.

> El código del componente es React y Tailwind. Léelo, cámbiale el estilo o elimina las partes que no necesites.
