Components

Radio Group

A set of checkable buttons where no more than one can be checked at a time.

php artisan blatui:add radio-group
<x-ui.radio-group value="comfortable">
    <div class="flex items-center gap-3">
        <x-ui.radio-group-item value="default" id="r1" />
        <x-ui.label for="r1">Default</x-ui.label>
    </div>
    <div class="flex items-center gap-3">
        <x-ui.radio-group-item value="comfortable" id="r2" />
        <x-ui.label for="r2">Comfortable</x-ui.label>
    </div>
    <div class="flex items-center gap-3">
        <x-ui.radio-group-item value="compact" id="r3" />
        <x-ui.label for="r3">Compact</x-ui.label>
    </div>
</x-ui.radio-group>

Cards

<x-ui.radio-group value="pro" class="grid w-full max-w-md gap-3 sm:grid-cols-3">
    <label @click="value = 'starter'; rovingValue = 'starter'"
        class="border-input has-[[data-state=checked]]:border-primary has-[[data-state=checked]]:ring-ring/40 has-[[data-state=checked]]:ring-[3px] relative flex cursor-pointer flex-col gap-1 rounded-lg border p-4 transition-[color,box-shadow]">
        <div class="flex items-center justify-between">
            <span class="text-sm font-medium">Starter</span>
            <x-ui.radio-group-item value="starter" aria-label="Starter plan" />
        </div>
        <span class="text-muted-foreground text-xs">$0 / month</span>
    </label>
    <label @click="value = 'pro'; rovingValue = 'pro'"
        class="border-input has-[[data-state=checked]]:border-primary has-[[data-state=checked]]:ring-ring/40 has-[[data-state=checked]]:ring-[3px] relative flex cursor-pointer flex-col gap-1 rounded-lg border p-4 transition-[color,box-shadow]">
        <div class="flex items-center justify-between">
            <span class="text-sm font-medium">Pro</span>
            <x-ui.radio-group-item value="pro" aria-label="Pro plan" />
        </div>
        <span class="text-muted-foreground text-xs">$12 / month</span>
    </label>
    <label @click="value = 'team'; rovingValue = 'team'"
        class="border-input has-[[data-state=checked]]:border-primary has-[[data-state=checked]]:ring-ring/40 has-[[data-state=checked]]:ring-[3px] relative flex cursor-pointer flex-col gap-1 rounded-lg border p-4 transition-[color,box-shadow]">
        <div class="flex items-center justify-between">
            <span class="text-sm font-medium">Team</span>
            <x-ui.radio-group-item value="team" aria-label="Team plan" />
        </div>
        <span class="text-muted-foreground text-xs">$32 / month</span>
    </label>
</x-ui.radio-group>

Colors

{{-- Checked-state colours via the semantic tokens. --}}
<x-ui.radio-group value="success" class="flex flex-wrap items-center gap-5">
    <div class="flex items-center gap-2">
        <x-ui.radio-group-item value="success" id="c-success" class="text-success data-[state=checked]:border-success" />
        <x-ui.label for="c-success">Success</x-ui.label>
    </div>
    <div class="flex items-center gap-2">
        <x-ui.radio-group-item value="info" id="c-info" class="text-info data-[state=checked]:border-info" />
        <x-ui.label for="c-info">Info</x-ui.label>
    </div>
    <div class="flex items-center gap-2">
        <x-ui.radio-group-item value="warning" id="c-warning" class="text-warning data-[state=checked]:border-warning" />
        <x-ui.label for="c-warning">Warning</x-ui.label>
    </div>
    <div class="flex items-center gap-2">
        <x-ui.radio-group-item value="danger" id="c-danger" class="text-destructive data-[state=checked]:border-destructive" />
        <x-ui.label for="c-danger">Danger</x-ui.label>
    </div>
</x-ui.radio-group>

Disabled

<x-ui.radio-group value="comfortable">
    <div class="flex items-center gap-3">
        <x-ui.radio-group-item value="default" id="rd1" />
        <x-ui.label for="rd1">Default</x-ui.label>
    </div>
    <div class="flex items-center gap-3">
        <x-ui.radio-group-item value="comfortable" id="rd2" />
        <x-ui.label for="rd2">Comfortable</x-ui.label>
    </div>
    <div class="flex items-center gap-3">
        <x-ui.radio-group-item value="compact" id="rd3" disabled />
        <x-ui.label for="rd3">Compact (unavailable)</x-ui.label>
    </div>
</x-ui.radio-group>

Horizontal

{{-- Options laid out in a row. --}}
<x-ui.radio-group value="card" class="flex flex-wrap items-center gap-5">
    <div class="flex items-center gap-2">
        <x-ui.radio-group-item value="card" id="pay-card" />
        <x-ui.label for="pay-card">Card</x-ui.label>
    </div>
    <div class="flex items-center gap-2">
        <x-ui.radio-group-item value="paypal" id="pay-paypal" />
        <x-ui.label for="pay-paypal">PayPal</x-ui.label>
    </div>
    <div class="flex items-center gap-2">
        <x-ui.radio-group-item value="apple" id="pay-apple" />
        <x-ui.label for="pay-apple">Apple Pay</x-ui.label>
    </div>
</x-ui.radio-group>

With Description

Get notified for every new message.

Only notify me when I'm mentioned.

Turn off all notifications.

<x-ui.radio-group value="all" class="gap-4">
    <div class="flex items-start gap-3">
        <x-ui.radio-group-item value="all" id="rn-all" class="mt-0.5" />
        <div class="grid gap-1">
            <x-ui.label for="rn-all">All new messages</x-ui.label>
            <p class="text-muted-foreground text-sm">Get notified for every new message.</p>
        </div>
    </div>
    <div class="flex items-start gap-3">
        <x-ui.radio-group-item value="mentions" id="rn-mentions" class="mt-0.5" />
        <div class="grid gap-1">
            <x-ui.label for="rn-mentions">Direct messages and mentions</x-ui.label>
            <p class="text-muted-foreground text-sm">Only notify me when I'm mentioned.</p>
        </div>
    </div>
    <div class="flex items-start gap-3">
        <x-ui.radio-group-item value="none" id="rn-none" class="mt-0.5" />
        <div class="grid gap-1">
            <x-ui.label for="rn-none">Nothing</x-ui.label>
            <p class="text-muted-foreground text-sm">Turn off all notifications.</p>
        </div>
    </div>
</x-ui.radio-group>

Using with Livewire

wire:model

The examples above are the frontend (Blade + Alpine) usage. Inside a Livewire component, bind wire:model for two-way state — same component, no wrappers. Full Livewire guide →

app/Livewire/Demo.php
use Livewire\Component;

class Demo extends Component
{
    public string $plan = 'pro';

    public function render()
    {
        return view('livewire.demo');
    }
}
resources/views/livewire/demo.blade.php
<x-ui.radio-group wire:model="plan">
    <x-ui.radio-group-item value="free" /> Free
    <x-ui.radio-group-item value="pro" /> Pro
</x-ui.radio-group>

API Reference

Props, slots and exposed methods for <x-ui.radio-group>.

Props

Prop Type Default Description
name string Form field name. When set, a hidden input mirrors the selected value so the group submits with a form.
value string The initially selected option, matched against each item's value. Leave unset for no default selection.

Slots

Slot Description
default The radio items — place one or more <x-ui.radio-group-item> (typically paired with an <x-ui.label>) here. They share the group's Alpine scope, which drives selection and roving arrow-key focus.