Components

Field

Combine labels, controls, and help text to compose accessible form fields.

php artisan blatui:add field

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.

<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

Profile

Update your personal details.

<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

We'll never share your email with anyone.

Max 160 characters.

{{-- 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.