Components

Select

Displays a list of options for the user to pick from, triggered by a button.

php artisan blatui:add select
<x-ui.select>
    <x-ui.select-trigger class="w-[180px]" aria-label="Theme">
        <x-ui.select-value placeholder="Theme" />
    </x-ui.select-trigger>
    <x-ui.select-content>
        <x-ui.select-item value="light">Light</x-ui.select-item>
        <x-ui.select-item value="dark">Dark</x-ui.select-item>
        <x-ui.select-item value="system">System</x-ui.select-item>
    </x-ui.select-content>
</x-ui.select>

Branded

The color prop brands the trigger's focus ring.

<div class="flex max-w-xs flex-col gap-3">
    <x-ui.select color="#0891b2" placeholder="Pick a theme" :options="['Light', 'Dark', 'System']" />
    <p class="text-muted-foreground text-xs">The <code>color</code> prop brands the trigger's focus ring.</p>
</div>

Disabled

<x-ui.select>
    <x-ui.select-trigger class="w-[180px] disabled:cursor-not-allowed disabled:opacity-50" aria-label="Theme" disabled>
        <x-ui.select-value placeholder="Theme" />
    </x-ui.select-trigger>
    <x-ui.select-content>
        <x-ui.select-item value="light">Light</x-ui.select-item>
        <x-ui.select-item value="dark">Dark</x-ui.select-item>
        <x-ui.select-item value="system">System</x-ui.select-item>
    </x-ui.select-content>
</x-ui.select>

Grouped

<x-ui.select>
    <x-ui.select-trigger class="w-[180px]" aria-label="Select a fruit">
        <x-ui.select-value placeholder="Select a fruit" />
    </x-ui.select-trigger>
    <x-ui.select-content>
        <x-ui.select-group>
            <x-ui.select-label>Fruits</x-ui.select-label>
            <x-ui.select-item value="apple">Apple</x-ui.select-item>
            <x-ui.select-item value="banana">Banana</x-ui.select-item>
            <x-ui.select-item value="blueberry">Blueberry</x-ui.select-item>
            <x-ui.select-item value="pineapple">Pineapple</x-ui.select-item>
        </x-ui.select-group>
    </x-ui.select-content>
</x-ui.select>

Indicators

{{-- The custom listbox marks the selected option with a trailing check by default.
     Switch to `radio` or `checkbox` — in the compositional API set `indicator` on
     <x-ui.select-content> and it cascades to every item. --}}
<x-ui.select :options="['light' => 'Light', 'dark' => 'Dark', 'system' => 'System']" value="system" indicator="radio" />

Multiple

<x-ui.select
    multiple
    name="frameworks"
    placeholder="Select frameworks..."
    class="w-[260px]"
    :value="['next', 'remix']"
    :options="[
        'next' => 'Next.js',
        'sveltekit' => 'SvelteKit',
        'nuxt' => 'Nuxt.js',
        'remix' => 'Remix',
        'astro' => 'Astro',
    ]"
/>

Native

{{-- native: a BlatUI-styled real <select> — submits without JS, name-bound, validation-
     friendly. Put <option>s in the slot and mark the selected one with `selected`. --}}
<x-ui.select native name="status" aria-label="Status" class="w-[200px]">
    <option value="" disabled>Select status…</option>
    <option value="active">Active</option>
    <option value="pending" selected>Pending</option>
    <option value="declined">Declined</option>
</x-ui.select>

Options Array

{{-- Shorthand: pass an [value => label] array instead of composing items by hand. --}}
<x-ui.select
    value="banana"
    :options="['apple' => 'Apple', 'banana' => 'Banana', 'cherry' => 'Cherry', 'grape' => 'Grape']"
    placeholder="Pick a fruit"
    class="w-[200px]"
/>

Scrollable

<x-ui.select>
    <x-ui.select-trigger class="w-[220px]" aria-label="Select a timezone">
        <x-ui.select-value placeholder="Select a timezone" />
    </x-ui.select-trigger>
    <x-ui.select-content>
        <x-ui.select-group>
            <x-ui.select-label>North America</x-ui.select-label>
            <x-ui.select-item value="est">Eastern Standard Time (EST)</x-ui.select-item>
            <x-ui.select-item value="cst">Central Standard Time (CST)</x-ui.select-item>
            <x-ui.select-item value="mst">Mountain Standard Time (MST)</x-ui.select-item>
            <x-ui.select-item value="pst">Pacific Standard Time (PST)</x-ui.select-item>
        </x-ui.select-group>
        <x-ui.select-group>
            <x-ui.select-label>Europe &amp; Africa</x-ui.select-label>
            <x-ui.select-item value="gmt">Greenwich Mean Time (GMT)</x-ui.select-item>
            <x-ui.select-item value="cet">Central European Time (CET)</x-ui.select-item>
            <x-ui.select-item value="eet">Eastern European Time (EET)</x-ui.select-item>
            <x-ui.select-item value="cat">Central Africa Time (CAT)</x-ui.select-item>
        </x-ui.select-group>
        <x-ui.select-group>
            <x-ui.select-label>Asia</x-ui.select-label>
            <x-ui.select-item value="ist">India Standard Time (IST)</x-ui.select-item>
            <x-ui.select-item value="jst">Japan Standard Time (JST)</x-ui.select-item>
            <x-ui.select-item value="gst">Gulf Standard Time (GST)</x-ui.select-item>
        </x-ui.select-group>
    </x-ui.select-content>
</x-ui.select>

Sizes

{{-- Trigger sizes via the `size` prop. --}}
<div class="flex flex-wrap items-center gap-3">
    @foreach (['sm' => 'Small', 'default' => 'Default', 'lg' => 'Large'] as $size => $label)
        <x-ui.select>
            <x-ui.select-trigger size="{{ $size }}" class="w-[150px]" aria-label="{{ $label }} size">
                <x-ui.select-value placeholder="{{ $label }}" />
            </x-ui.select-trigger>
            <x-ui.select-content>
                <x-ui.select-item value="apple">Apple</x-ui.select-item>
                <x-ui.select-item value="banana">Banana</x-ui.select-item>
                <x-ui.select-item value="cherry">Cherry</x-ui.select-item>
            </x-ui.select-content>
        </x-ui.select>
    @endforeach
</div>

Utility Class

{{-- Raw <select> styled by .blat-select — native submit, name-bound, and safe to nest inside
     slots. Prefer this over the x-ui.select native component when the control is re-wrapped by
     another anonymous component's slot. --}}
<select class="blat-select w-full max-w-sm" name="status" aria-label="Status">
    <option value="" disabled selected>Select status…</option>
    <option>Active</option>
    <option>Pending</option>
    <option>Declined</option>
</select>

With Icons

<x-ui.select>
    <x-ui.select-trigger class="w-[180px]" aria-label="Status">
        <x-ui.select-value placeholder="Status" />
    </x-ui.select-trigger>
    <x-ui.select-content>
        <x-ui.select-item value="online"><x-lucide-circle-check aria-hidden="true" /> Online</x-ui.select-item>
        <x-ui.select-item value="away"><x-lucide-clock aria-hidden="true" /> Away</x-ui.select-item>
        <x-ui.select-item value="busy"><x-lucide-minus-circle aria-hidden="true" /> Busy</x-ui.select-item>
        <x-ui.select-item value="offline"><x-lucide-circle aria-hidden="true" /> Offline</x-ui.select-item>
    </x-ui.select-content>
</x-ui.select>

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.select wire:model="plan" :options="['free' => 'Free', 'pro' => 'Pro']" />

API Reference

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

Props

Prop Type Default Description
options [value => label] Shorthand that auto-composes the trigger, content and items (or native <option>s). Associative keys are values; a plain list uses the value as its own label. Omit it to build the listbox with the compositional slot API instead.
value string|array '' The initially selected value. Pass an array of values when multiple is true.
name string Form field name. A hidden input mirrors the selection so it submits with a form (as name[] when multiple).
placeholder string '' Trigger text shown when nothing is selected. Pass a translated string; empty by default so no English leaks.
multiple bool false Allow picking many values. Selected items render as removable chips in the trigger and the list stays open after each pick.
native bool false Render a styled native <select> (submits without JS) instead of the rich JS listbox. Put <option>s in the slot when not using options.
size string 'default' Trigger height. Applies to the native variant.
sm default lg
color string A CSS color that brands the trigger's focus ring and selected accent for this instance only.
indicator string 'check' How a selected option is marked in the custom listbox (ignored when native): a trailing check, a checkbox box, or a radio dot. In the compositional API, set it on <x-ui.select-content> instead — it cascades to the items.
check checkbox radio

Slots

Slot Description
default The compositional listbox when options is omitted: <x-ui.select-trigger> (with <x-ui.select-value>) followed by <x-ui.select-content> wrapping <x-ui.select-item> entries (optionally grouped with select-group/select-label/select-separator). For the native variant, place plain <option> elements here.

Methods

Available on the component's Alpine scope — call them from markup in the slot (e.g. @click="…").

Method Description
openList() Opens the listbox and moves focus to the selected (or first) option.
toggleList() Opens the listbox if closed, otherwise closes it.
close() Closes the listbox and returns focus to the trigger.
selectOption(value, label) Selects the given value (toggles it when multiple). Single select also closes the list.