# shadcn/ui-Komponente

> Installiere eine Formularkomponente, die deine Ikiform-Felder mit deinen eigenen shadcn/ui-Komponenten rendert.

Wenn dein Projekt shadcn/ui verwendet, kannst du ein fertiges Formular installieren, statt das Markup selbst zu schreiben. Das ist eine Option unter mehreren: Dasselbe Formular funktioniert weiterhin mit [reinem HTML](https://ikiform.com/de/docs/html.md) und [fetch](https://ikiform.com/de/docs/frameworks.md).

## Installieren

`Terminal`:

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

Das kopiert `components/ikiform/form.tsx` in dein Projekt und installiert die shadcn/ui-Komponenten, die es verwendet: `button`, `checkbox`, `input`, `label`, `radio-group` und `textarea`. Die Datei gehört dir und du kannst sie bearbeiten. Auswahlfelder verwenden ein natives `<select>`, sodass es mit der Radix- und der Base-UI-Variante von shadcn/ui funktioniert.

## Verwendung

`app/contact/page.tsx`:

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

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

Beim Mounten lädt die Komponente das öffentliche Schema des Formulars und rendert ein Steuerelement pro Feld, mit den Labels, Platzhaltern, Hilfetexten und Optionen, die du im Dashboard eingestellt hast. Definiere zuerst Felder im Tab [Felder](https://ikiform.com/de/docs/fields.md) des Formulars; ein Formular ohne Felder rendert keine Eingabefelder.

- Sie validiert im Browser mit denselben Regeln und Meldungen wie der Server.
- Sie sendet JSON mit dem Honeypot und einem signierten Render-Zeitstempel, was bei der Spam-Bewertung hilft.
- Feldfehler vom Server erscheinen unter ihren Feldern; andere Fehler erscheinen über dem Button.
- Bei Erfolg ersetzt sie das Formular durch die Erfolgsmeldung des Formulars.

## Props

| Prop | Typ | Beschreibung |
| --- | --- | --- |
| `form` | `string` | Pflicht. Die Formular-ID. |
| `fields` | `IkiFormField[]` | Ersetzt die geladenen Felder. Verwendet dieselbe Form wie Felddefinitionen. |
| `onSuccess` | `({ id, values }) => void` | Wird nach einem erfolgreichen Absenden aufgerufen. |
| `submitLabel` | `string` | Button-Text. Standardmäßig das Absende-Label des Formulars. |
| `successMessage` | `ReactNode` | Wird nach dem Absenden angezeigt. Standardmäßig die Erfolgsmeldung des Formulars. |
| `turnstileSiteKey` | `string` | Nur für Formulare mit eigenen Turnstile-Schlüsseln, bei denen in Ikiform kein Site Key gespeichert ist. |
| `className` | `string` | Klassennamen für das Formularelement. |
| `baseUrl` | `string` | Standardmäßig `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)}
    />
  );
}
```

### Felder im Code

Übergib `fields`, um ohne die Definition aus dem Dashboard zu rendern. Der Server validiert weiterhin gegen die veröffentlichten Felder des Formulars, also halte beide synchron.

`Felder im Code`:

```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 } },
  ]}
/>
```

## Menschlichkeitsprüfung

Mit der Spamprüfung auf **Ikiform** bettet die Komponente einen kleinen ikiform.com-Frame ein, der versteckt bleibt, bis Turnstile einen Klick braucht, und fordert nach jedem Versuch ein neues Token an. Kann der Frame nicht laden, bietet sie an, die Prüfung in einem neuen Fenster zu öffnen. Mit eigenen Turnstile-Schlüsseln rendert sie das Turnstile-Widget mit dem Site Key des Formulars.

## Der Schema-Endpunkt

Die Komponente liest `GET https://ikiform.com/f/<formId>/schema`. Du kannst ihn selbst aufrufen, um deinen eigenen Renderer zu bauen, oder `getSchema` aus dem [SDK](https://ikiform.com/de/docs/sdk.md#getschema) verwenden.

`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"
}
```

- Offen für jeden Origin (`Access-Control-Allow-Origin: *`) und nie gecacht.
- Pausierte, deaktivierte und unbekannte Formulare geben alle dasselbe `404` zurück.
- Nur die veröffentlichten Felder und Anzeigeeinstellungen verlassen den Server. Erlaubte Domains, die Weiterleitungs-URL, Spam-Einstellungen und Rate-Limits bleiben privat.
- `challenge` ist `{ "provider": "ikiform", "url": ... }`, `{ "provider": "custom", "site_key": ... }` oder `null`. `ts` ist ein frischer signierter Render-Zeitstempel, den du als `_ikiform_ts` zurückschickst.
- Er erlaubt 60 Anfragen pro Minute pro Besucher und Formular, getrennt vom Kontingent zum Absenden.

> Der Quellcode der Komponente ist reines React und Tailwind. Lies ihn, style ihn um oder lösche die Teile, die du nicht brauchst.
