# Form

Renders a JSON Schema as a themed, validated form card — the agent supplies the schema, the user fills it in, and a typed submission event bubbles back.

<p class="kai-tag-sub">kai-form</p>

Point a JSON Schema at `<kai-form>` and get a fully themed, accessible, client-validated form — labels, widgets, submit button, and a read-only resolved state — without writing a single input element.

## Preview

> **tip:** 
Use `<kai-form>` when an agent needs structured input before continuing — onboarding questionnaires, task parameters, feedback forms, or any agentic step that gates on user data. The schema is the single source of truth for both UI layout and validation.

## Usage

Assign the form definition in JavaScript — it's an object, not an HTML attribute:

```html
<kai-form id="my-form"></kai-form>

<script type="module">

  await customElements.whenDefined('kai-form');

  const form = document.querySelector('#my-form');

  form.data = {
    type: 'object',
    title: 'How did we do?',
    required: ['rating'],
    'x-kai-submitLabel': 'Send feedback',
    properties: {
      rating: { type: 'integer', title: 'Overall rating', minimum: 1, maximum: 5, 'x-kai-widget': 'rating' },
      comments: { type: 'string', title: 'Comments', 'x-kai-widget': 'textarea' },
    },
  };

  form.addEventListener('kai-card', (e) => {
    if (e.detail.kind === 'submit') console.log('submission data', e.detail.data);
    if (e.detail.kind === 'action') console.log('secondary action', e.detail.action);
  });
</script>
```

- **Schema → widgets** deterministically: `string` → text; `string + enum` → radio/select; `integer + x-kai-widget: 'rating'` → stars; `boolean` → switch; `array` → repeater/checkbox group; nested `object` → fieldset. See the **Every widget** example for the full mapping.
- **`x-kai-*` hints** in the schema control field order (`x-kai-order`), submit label (`x-kai-submitLabel`), secondary buttons (`x-kai-actions`), placeholder (`x-kai-placeholder`), and dismissibility (`x-kai-dismissible`).
- **Events use the Card contract** — `kai-form` fires no events of its own; it emits a single bubbling `kai-card` CustomEvent. Relevant kinds: `submit` (`detail.data` is the validated object), `action`, `ready`, `dismiss`, and `error`.
- **`resolution`** — set `el.resolution = { kind: 'submit', data: { … } }` to swap the form for a read-only `<dl>` summary.

## Examples

### Feedback Form

Star rating, free-text textarea, enum radio group, boolean switch, and a secondary Skip action.

### Every Widget

Exercises the full schema-to-widget mapping: text, email, URL, date, password, select, number, slider, rating, switch, checkbox, tag list, checkbox group, repeater, and nested fieldset.

### Validation

Required fields, `minLength`/`maxLength`, `minimum`/`maximum`, and `format: 'email'` — submit empty to see inline errors.

### Resolved (Read-only)

After a successful submission, set `el.resolution` to render a read-only `<dl>` summary with a "Submitted" badge.

### Invalid Envelope

Pass a non-object schema to see the inline error state; the element also emits `kai-card` with `kind: 'error'`.

## Props

## Methods

## Composed from
