forms
Input
Form control archetype with label, hint, error, icons, password toggle, and attribute forwarding to the native input.
Examples
Basic field
Label, hint, and placeholder with attribute forwarding.
Used for INV-2026-089 and payment receipts.
<x-ui.input
type="email"
name="billing_email"
label="Billing email"
hint="Used for INV-2026-089 and payment receipts."
placeholder="finance@tokomaju.id"
required
class="max-w-sm"
/>
<div class="w-full max-w-sm">
<label for="invoice-email" class="mb-1.5 block text-sm font-medium text-fg">Billing email</label>
<div class="relative">
<input
id="invoice-email"
type="email"
name="billing_email"
placeholder="finance@tokomaju.id"
required
aria-describedby="invoice-email-hint"
class="h-9 w-full rounded-control border border-border bg-surface-raised px-3.5 text-sm text-fg shadow-2xs tabular-nums placeholder:text-fg-subtle transition-colors duration-150 hover:border-border-strong focus:border-brand focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface"
>
</div>
<p id="invoice-email-hint" class="mt-1.5 text-xs text-fg-muted leading-relaxed">Used for INV-2026-089 and payment receipts.</p>
</div>
Password with toggle
Accessible show and hide control.
<x-ui.input
type="password"
name="password"
label="Owner password"
placeholder="Enter password"
required
class="max-w-sm"
/>
<div class="w-full max-w-sm" x-data="{ show: false }">
<label for="owner-password" class="mb-1.5 block text-sm font-medium text-fg">Owner password</label>
<div class="relative">
<input
id="owner-password"
name="password"
placeholder="Enter password"
required
x-bind:type="show ? 'text' : 'password'"
class="h-9 w-full rounded-control border border-border bg-surface-raised px-3.5 pr-10 text-sm text-fg shadow-2xs placeholder:text-fg-subtle transition-colors duration-150 hover:border-border-strong focus:border-brand focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface"
>
<button
type="button"
class="absolute inset-y-0 right-0 flex items-center px-3 text-fg-muted hover:text-fg"
x-on:click="show = !show"
x-bind:aria-label="show ? 'Hide password' : 'Show password'"
>
<svg class="size-4 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12Z" />
<circle cx="12" cy="12" r="3" />
</svg>
</button>
</div>
</div>
Validation error
Error text linked through aria-describedby.
Enter a valid 15-digit NPWP for e-Faktur.
<x-ui.input
type="text"
name="npwp"
label="NPWP"
value="10.20.30"
error="Enter a valid 15-digit NPWP for e-Faktur."
class="max-w-sm"
/>
<div class="w-full max-w-sm">
<label for="npwp-error" class="mb-1.5 block text-sm font-medium text-fg">NPWP</label>
<div class="relative">
<input
id="npwp-error"
type="text"
name="npwp"
value="10.20.30"
aria-invalid="true"
aria-describedby="npwp-error-msg"
class="h-9 w-full rounded-control border border-danger bg-surface-raised px-3.5 text-sm text-fg shadow-2xs tabular-nums placeholder:text-fg-subtle focus:border-danger focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-danger focus-visible:ring-offset-2 focus-visible:ring-offset-surface"
>
</div>
<p id="npwp-error-msg" class="mt-1.5 flex items-start gap-1.5 text-xs text-danger">
<svg class="mt-0.5 size-3.5 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v4m0 4h.01M10.3 4.2 2.8 17.1A2 2 0 0 0 4.5 20h15a2 2 0 0 0 1.7-2.9L13.7 4.2a2 2 0 0 0-3.4 0Z" />
</svg>
<span>Enter a valid 15-digit NPWP for e-Faktur.</span>
</p>
</div>
Props API
| Prop | Type | Default | Description |
|---|---|---|---|
| type | text|email|password|number|search | text | Native input type. Password adds an accessible show/hide toggle. |
| size | sm|md|lg | md | Control height and text size. |
| label | string|null | null | Visible label linked via for/id. |
| hint | string|null | null | Helper text referenced by aria-describedby. |
| error | string|null | null | Validation message. Sets aria-invalid and contributes to aria-describedby. |
| leadingIcon | slot|null | null | Optional leading decorative icon slot. |
| trailingAddon | slot|null | null | Optional trailing text addon when not using password toggle. |
Accessibility notes
Architected with WCAG 2.2 AA patterns in mind. These notes document the exact keyboard and ARIA behavior for this component.
- Generates a stable id when none is provided and wires label for, input id, and aria-describedby for hint and error.
- Error state sets aria-invalid="true" on the input.
- Pass-through attributes (name, value, required, placeholder, disabled, readonly, x-model, wire:model) land on the native input, not the wrapper.
- Password toggle is a button with an accessible label that switches between Show password and Hide password.
- Keyboard: Tab reaches the input and the password toggle. Space/Enter activates the toggle.
Built by Praesepe
Architecture & custom software partner
Praesepe uses these exact UI primitives to ship SME dashboards, inventory systems, invoicing desks, and internal tools faster, without rebuilding a design system for every client.
- Same Blade + Tailwind 4 + Alpine 3 stack you see in this docs site
- Opinionated for Indonesian SME ops: invoices, stock, roles, approvals
- Architected with WCAG 2.2 AA patterns in mind for keyboard and ARIA