Components
Field
Combine labels, controls, and help text to compose accessible form fields.
Building a custom DX layer that re-wraps a slot with an @aware anonymous component? <x-ui.*> passed as that slot's content stays literal (it never compiles) — the field is silently absent though the page still returns 200. In such layers, render raw elements styled by the foundation utilities (.blat-input .blat-select .blat-checkbox .blat-radio) instead.
This is your public display name.
<div class="w-full max-w-sm">
<x-ui.field>
<x-ui.field-label for="username">Username</x-ui.field-label>
<x-ui.input id="username" type="text" placeholder="shadcn" />
<x-ui.field-description>This is your public display name.</x-ui.field-description>
</x-ui.field>
</div>
Checkbox
You agree to our Terms of Service and Privacy Policy.
<div class="w-full max-w-sm">
<x-ui.field-group>
<x-ui.field orientation="horizontal">
<x-ui.checkbox id="field-terms" />
<x-ui.field-content>
<x-ui.field-label for="field-terms">Accept terms and conditions</x-ui.field-label>
<x-ui.field-description>You agree to our Terms of Service and Privacy Policy.</x-ui.field-description>
</x-ui.field-content>
</x-ui.field>
</x-ui.field-group>
</div>
Error
This is your public display name.
Must be strong.
- Must be at least 8 characters.
- Must include a number.
<div class="w-full max-w-sm">
<x-ui.field-group>
{{-- Hint (description) only --}}
<x-ui.field>
<x-ui.field-label for="err-username">Username</x-ui.field-label>
<x-ui.input id="err-username" type="text" value="shadcn" />
<x-ui.field-description>This is your public display name.</x-ui.field-description>
</x-ui.field>
{{-- Single error → the field + input go invalid automatically (aria-invalid + destructive) --}}
<x-ui.field>
<x-ui.field-label for="err-email">Email</x-ui.field-label>
<x-ui.input id="err-email" type="email" value="not-an-email" />
<x-ui.field-error>Please enter a valid email address.</x-ui.field-error>
</x-ui.field>
{{-- Multiple validation messages via the errors array → bulleted list --}}
<x-ui.field>
<x-ui.field-label for="err-password">Password</x-ui.field-label>
<x-ui.input id="err-password" type="password" value="abc" />
<x-ui.field-description>Must be strong.</x-ui.field-description>
<x-ui.field-error :messages="['Must be at least 8 characters.', 'Must include a number.']" />
</x-ui.field>
</x-ui.field-group>
</div>
Field Group
We will respond within 24 hours.
<div class="w-full max-w-sm">
<x-ui.field-group>
<x-ui.field>
<x-ui.field-label for="name">Name</x-ui.field-label>
<x-ui.input id="name" type="text" placeholder="Evil Rabbit" />
</x-ui.field>
<x-ui.field>
<x-ui.field-label for="message">Message</x-ui.field-label>
<x-ui.textarea id="message" placeholder="Type your message here." />
<x-ui.field-description>We will respond within 24 hours.</x-ui.field-description>
</x-ui.field>
</x-ui.field-group>
</div>
Field Set
<div class="w-full max-w-sm">
<x-ui.field-set>
<x-ui.field-legend>Profile</x-ui.field-legend>
<x-ui.field-description>Update your personal details.</x-ui.field-description>
<x-ui.field-group>
<x-ui.field>
<x-ui.field-label for="firstname">First name</x-ui.field-label>
<x-ui.input id="firstname" type="text" placeholder="Evil" />
</x-ui.field>
<x-ui.field>
<x-ui.field-label for="lastname">Last name</x-ui.field-label>
<x-ui.input id="lastname" type="text" placeholder="Rabbit" />
</x-ui.field>
</x-ui.field-group>
</x-ui.field-set>
</div>
Form
{{-- A complete form assembled from fields and varied controls. --}}
<form class="w-full max-w-sm" onsubmit="return false">
<x-ui.field-group>
<x-ui.field>
<x-ui.field-label for="form-name">Name</x-ui.field-label>
<x-ui.input id="form-name" placeholder="Evil Rabbit" />
</x-ui.field>
<x-ui.field>
<x-ui.field-label for="form-email">Email</x-ui.field-label>
<x-ui.input id="form-email" type="email" placeholder="[email protected]" />
<x-ui.field-description>We'll never share your email with anyone.</x-ui.field-description>
</x-ui.field>
<x-ui.field>
<x-ui.field-label for="form-role">Role</x-ui.field-label>
<x-ui.select>
<x-ui.select-trigger id="form-role" class="w-full">
<x-ui.select-value placeholder="Select a role" />
</x-ui.select-trigger>
<x-ui.select-content>
<x-ui.select-item value="developer">Developer</x-ui.select-item>
<x-ui.select-item value="designer">Designer</x-ui.select-item>
<x-ui.select-item value="manager">Manager</x-ui.select-item>
</x-ui.select-content>
</x-ui.select>
</x-ui.field>
<x-ui.field>
<x-ui.field-label for="form-bio">Bio</x-ui.field-label>
<x-ui.textarea id="form-bio" placeholder="Tell us a little about yourself" />
<x-ui.field-description>Max 160 characters.</x-ui.field-description>
</x-ui.field>
<x-ui.field>
<div class="flex items-center gap-2">
<x-ui.switch id="form-news" />
<x-ui.field-label for="form-news" class="font-normal">Subscribe to the newsletter</x-ui.field-label>
</div>
</x-ui.field>
<x-ui.button type="submit">Create account</x-ui.button>
</x-ui.field-group>
</form>
Horizontal
Receive emails about your account activity.
<div class="w-full max-w-sm">
<x-ui.field orientation="horizontal">
<x-ui.field-content>
<x-ui.field-label for="notifications">Email notifications</x-ui.field-label>
<x-ui.field-description>Receive emails about your account activity.</x-ui.field-description>
</x-ui.field-content>
<x-ui.switch id="notifications" />
</x-ui.field>
</div>
API Reference
Props, slots and exposed methods for
<x-ui.field>.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
orientation |
string
|
'vertical'
|
Layout of the label/control/description. "vertical" stacks them, "horizontal" places the control beside the content, and "responsive" stacks on small screens and goes horizontal at the @md breakpoint of a field-group container.
vertical
horizontal
responsive
|
Slots
| Slot | Description |
|---|---|
default |
The field contents — typically an x-ui.field-label, the form control, and an x-ui.field-description or x-ui.field-error. Wrap label and description in x-ui.field-content when using horizontal orientation. |