Wirestrap is still in active development

This project is pre-1.0 and may introduce breaking changes at any time without prior notice.

Select

Custom select dropdown with single and multiple selection and optional search. Options are provided either as a PHP array via options, or through a Livewire method via wire-options. Pass options for fixed or PHP-generated lists. When the list is large, expensive to produce, or depends on database state, wire-options is a better fit: the method is called once on first open and the result is cached client-side. If a value is already bound on load, the method is called immediately to resolve the display label. Because selection changes are applied via $wire.$set() internally, wire:model.live has no effect: use the live prop instead.

Keyboard:

  • to navigate.
  • Enter to select when the dropdown is open.
    When closed, Enter submits the parent form if there is one, or opens the dropdown otherwise.
  • Escape to close.

Basic usage

Declare a method on your Livewire component and pass its name to wire-options. Use icon to add an icon, and floating for a floating label layout.

Language
Select an option
Select an option
Language
#[Renderless]
public function getLanguages(): array
{
    return [
        ['value' => 'en', 'label' => 'English'],
        ['value' => 'fr', 'label' => 'French'],
    ];
}
{{-- Standard --}}
<x-wirestrap::select
    id="language-select"
    label="Language"
    wire:model="language"
    wire-options="getLanguages"
    icon="bi-translate"
/>

{{-- Floating label --}}
<x-wirestrap::select ... floating />

Icon prop

The icon prop accepts any class string from your preferred icon library, or an array of attributes for full control. Custom icon components are also supported, see icon configuration.

Multiple

Add multiple to enable multi-selection. wire:model must bind to an array property. Selected options appear as badges with remove buttons, sorted alphabetically.

Languages
Select an option
Select an option
Languages
public array $selectedLanguages = [];
<x-wirestrap::select ... multiple />

Search

Add search to show a text input at the top of the dropdown. Options are filtered as you type. When the dropdown opens, focus moves to the search input automatically.

Language
Select an option
Select an option
Languages
<x-wirestrap::select ... search />

Reactive list

Use wire-options-watch to invalidate the options cache when a Livewire property changes. The list reloads immediately if the dropdown is open or has a selected value, so the label can be resolved. Otherwise, it will reload the next time the dropdown is opened. To force a reload imperatively, use $wirestrap.select.refresh(id).

Category
Select an option
Select an option
Item
<x-wirestrap::select
    ...
    wire:model="category"
    wire-options="getCategories"
/>

<x-wirestrap::select
    ...
    wire:model="categoryItem"
    wire-options="getCategoryItems"
    wire-options-watch="category"
/>

Option groups

Add an optgroup field to options that should be grouped. Options sharing the same value are rendered together under that label. Options without optgroup appear after all groups.

Country
Select an option
Select an option
Countries
#[Renderless]
public function getCountries(): array
{
    return [
        ['value' => 'fr', 'label' => 'France', 'optgroup' => 'Europe'],
        ['value' => 'de', 'label' => 'Germany', 'optgroup' => 'Europe'],
        ['value' => 'us', 'label' => 'United States', 'optgroup' => 'Americas'],

        // No optgroup: appears after all groups
        ['value' => 'xx', 'label' => 'Other'],
    ];
}

Empty value

When the bound value equals empty-value, the component displays the placeholder instead of a selection. Useful for filters where a specific value like "0" or "all" means "no filter applied".

Language
Select an option
Select an option
Language
<x-wirestrap::select ... empty-value="0" />

Disabled

Use disabled to disable the whole component. Individual options can be disabled by setting 'disabled' => true on their array entry.

Language
Select an option
Select an option
Languages
<x-wirestrap::select ... disabled />
// Set disabled on individual entries in the returned array
[
    'value' => 'de',
    'label' => 'German',
    'disabled' => true,
],

Rich content

Use html_prefix and html_suffix on individual option entries to inject raw HTML before and after the label. The label itself is always rendered as plain text. Use class on an option to apply a CSS class to its element.

Assign to
Select an option
Select an option
Assign to
// Pass free HTML before and / or after the label
[
    'value' => $user->id,
    'html_prefix' => '<i class="bi bi-person"></i>',
    'label' => $user->name,
    'html_suffix' => '<span class="badge-' . $user->role->color . '">' . $user->role->name . '</span>',
],

Inline options

Pass options directly as a PHP array with options instead of a Livewire method. The short form accepts an associative array of value => label pairs. The full form supports the same fields as a wire-options method would return: disabled, optgroup, class, html_prefix, html_suffix. Options update automatically when Livewire re-renders the component.

Assign to
Select an option
Select an option
Hobbies
{{-- Short syntax --}}
<x-wirestrap::select
    ...
    :options="[
        'fr' => 'France',
        'de' => 'Germany',
        'es' => 'Spain'
    ]"
/>

{{-- Full form with html_prefix / html_suffix --}}
<x-wirestrap::select
    ...
    :options="[
        ['value' => 1, 'label' => 'Alice Martin', ...],
        ['value' => 2, 'label' => 'Bob Dupont', ...],
    ]"
    search
/>

Validation

The component checks $errors for the wire:model key and applies the invalid state if found. Try submitting without selecting a language.

Language
Select an option
Select an option
Language
{{-- Suppress both the invalid class and the error message --}}
<x-wirestrap::select ... :has-validation="false" />

{{-- Keep the invalid class, hide the error message --}}
<x-wirestrap::select ... :has-validation-message="false" />

Props

Global configuration

Most prop defaults can be overridden globally via config/wirestrap.php.

x-wirestrap::select

Prop Type Default Description
id string|null null Unique identifier. Required (strict mode is on by default).
label ComponentSlot|string|null null Label text or slot content. No label element is rendered when null.
icon string|array null Icon identifier forwarded to the configured icon component. Always placed at start.
options array|null null Options as a PHP array. Short form: ['value' => 'Label']. Full form: array of option definitions — see Option definition below. Updates automatically on Livewire re-render. Mutually exclusive with wire-options.
wire-options string|null null Livewire method name returning the options array — see Option definition below. Called once on first open and cached client-side. Called immediately on load if a value is already bound.
wire-options-watch string|null null Livewire property to watch. Invalidates the cache on change; reloads immediately if the dropdown is open. Requires wire-options.
placeholder string config Text shown when no option is selected.
search-placeholder string config Placeholder text for the search input.
floating bool false Use floating label layout.
disabled bool false Disable the component.
multiple bool config Enable multiple selection. wire:model must bind to an array property.
search bool config Show a search input inside the dropdown. Filtering is client-side.
live bool config Trigger a server round-trip on each selection change instead of deferring.
has-validation-message bool config Render the error message below the field.
has-validation bool config Apply the invalid class when the wire:model key has an error.
empty-value mixed config Value treated as empty: shows the placeholder and removes the selected state.
default-attributes array config Default HTML attributes merged onto the root element.
dropdown-offset int config Y-axis offset in pixels between the trigger and the dropdown.
No results found

Option definition

Prop Type Default Description
value mixed -- The value bound to wire:model on selection.
label string '' Display text. Always rendered as plain text.
disabled bool false Disables the option.
optgroup string null Group label. Options sharing the same value are rendered together. Options without optgroup appear after all groups.
class string null Extra CSS class applied to the option element.
html_prefix string null Raw HTML injected before the label.
html_suffix string null Raw HTML injected after the label.
No results found

$wirestrap.select

Method Type Default Description
$wirestrap.select.refresh(id) -- -- Discard the cached options and call wire-options immediately. id is the component's id attribute.
No results found