---
title: Form
description: A form wrapper that sets one error-announcement policy for every control inside.
category: Form
---

# Form

`<x-wirekit::form>` is a real `<form>` element that also carries **one setting**
governing how every control inside announces its validation errors to screen
readers. Drop your `wire:submit`, `action`, and `method` onto it exactly as you
would a native form.

:::preview
<x-wirekit::form style="max-width: 24rem;">
    <x-wirekit::stack gap="md">
        <x-wirekit::input name="email" label="Email" placeholder="Your email address" />
        <x-wirekit::input name="password" type="password" label="Password" />
        <x-wirekit::button type="submit">Sign in</x-wirekit::button>
    </x-wirekit::stack>
</x-wirekit::form>
:::

## Why a form-level setting

Every WireKit form control can announce its error in an `aria-live` region so a
validation message that appears dynamically is read out. That is the right
default — but whether you *want* it is a property of the **form**, not the app:

- A form that renders its **own** error summary — a `role="alert"` list that
  announces every message and pulls focus (the standard WCAG 3.3.1 pattern) —
  should turn the per-field live regions **off**, or every error is announced
  twice.
- A form with no summary needs them **on**, or a dynamically-appearing error is
  never announced at all.

The global `wirekit.a11y.announce_error` config can only pick one for the whole
app. `<x-wirekit::form>` scopes the choice to a single form:

```blade
{{-- This form renders its own summary, so silence the per-field live regions. --}}
<x-wirekit::form :announce-errors="false" wire:submit="login">
    {{-- your own <div role="alert"> summary here --}}
    <x-wirekit::input name="email" label="Email" />
    <x-wirekit::input name="password" type="password" label="Password" />
</x-wirekit::form>
```

## Precedence

An explicit `:announce-error` on a single control always wins, so you can opt one
control back in even inside a silenced form:

```blade
<x-wirekit::form :announce-errors="false">
    <x-wirekit::input name="email" label="Email" />
    {{-- this one still announces, summary or not --}}
    <x-wirekit::input name="code" label="2FA code" :announce-error="true" />
</x-wirekit::form>
```

The order, highest priority first:

1. A per-control `:announce-error`.
2. The surrounding `<x-wirekit::form :announce-errors="…">`.
3. The global `wirekit.a11y.announce_error` config (default `true`).

## Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `announceErrors` | `bool\|null` | `null` | `false` silences every control's `aria-live` error region inside this form; `true` forces it on; `null` inherits the global config. |
| `scope` | `string\|null` | `null` | Class-scope override for the `<form>` element. |

All other attributes (`wire:submit`, `action`, `method`, `class`, …) pass through
to the underlying `<form>`.

## Accessibility

- When `announce-errors` is `false`, provide your own announcement — a
  `role="alert"` error summary is the usual choice, and it should receive focus
  when submission fails so the reader is taken straight to it.
- When `announce-errors` is left `true`/`null`, each control announces its own
  error in a polite live region; do **not** also render a summary, or the reader
  hears every message twice.

## Keyboard Interaction

The wrapper is a native `<form>` and adds no keyboard behavior of its own — the
controls inside keep theirs, and <kbd>Enter</kbd> in a text field submits the
form exactly as the browser does natively.
