Vertical form
The standard form layout, with labels above the fields. There is no separate component; the fields are arranged with Tailwind spacing and grid classes.
Single column
In short forms, stack the fields with space-y-4. Each field carries its own label, hint and error message; no extra wrapper is needed.
<form class="space-y-4">
<acun:input name="contact_name" label="Full name" />
<acun:input name="contact_email" type="email" label="Email" />
<acun:select name="contact_subject" label="Subject" :options="['order' => 'Order', 'billing' => 'Billing', 'other' => 'Other']" placeholder="Select…" />
<acun:textarea name="contact_message" label="Message" rows="3" />
<acun:button type="submit" class="w-full">Send</acun:button>
</form>
| Prop | Values |
|---|---|
space-y-4 | Vertical space between the fields |
Two columns
In long forms, use two columns on wide screens with grid md:grid-cols-2; on mobile the fields drop to a single column. Stretch long fields such as the address, and the button row, to full width with md:col-span-2.
<acun:card title="Customer record">
<form class="grid gap-4 md:grid-cols-2">
<acun:input name="first_name" label="First name" />
<acun:input name="last_name" label="Last name" />
<acun:input-group name="phone" label="Phone" prefix="+90" />
<acun:select name="group" label="Customer group" :options="['1' => 'Individual', '2' => 'Business']" placeholder="Select…" />
<div class="md:col-span-2"><acun:textarea name="address" label="Address" rows="2" /></div>
<div class="flex gap-2 md:col-span-2">
<acun:button type="submit">Save</acun:button>
<acun:button variant="white">Cancel</acun:button>
</div>
</form>
</acun:card>
| Prop | Values |
|---|---|
grid gap-4 md:grid-cols-2 | Two columns on wide screens |
md:col-span-2 | Stretches the field to full width |
Required fields and hints
When required is added to acun:input, acun:select, acun:textarea and acun:input-group, a red asterisk appears next to the label. State format expectations below the field with hint.
<form class="grid gap-4 md:grid-cols-2">
<acun:input name="req_name" label="Full name" required />
<acun:input-group name="req_phone" label="Phone" prefix="+90" required hint="10 digits, without the leading 0." />
<acun:select name="req_city" label="City" :options="['istanbul' => 'Istanbul', 'izmir' => 'Izmir']" placeholder="Select…" required />
<acun:textarea name="req_note" label="Note" rows="2" hint="Optional." />
</form>
| Prop | Values |
|---|---|
required | Adds * to the label |
hint | Help text below the field |
With Livewire
Fields with wire:model take their names from that property, so you do not need to write name, and validation errors match the same name. acun:form renders a plain <form>; if you add dirty-check, unsaved-changes protection is turned on (see the Form protection page).
<acun:form wire:submit="save" dirty-check class="grid gap-4 md:grid-cols-2">
<acun:input wire:model="firstName" label="First name" required />
<acun:input wire:model="lastName" label="Last name" required />
<acun:input-group wire:model="phone" label="Phone" prefix="+90" />
<acun:select wire:model="groupId" label="Customer group" :options="$groups" placeholder="Select…" />
<div class="md:col-span-2">
<acun:button type="submit">Save</acun:button>
</div>
</acun:form>
| Prop | Values |
|---|---|
wire:submit | Method called on submit |
dirty-check | Unsaved-changes protection |