x-bt-select component is a powerful, flexible select/dropdown input.It supports single or multiple selection, search, remote / lazy loading, avatars, icons,
and an optional autosave mode that calls a Livewire method whenever the value changes.
x-bt-input component.Basic Usage
A simple single-value select with a custom placeholder.
Pass an associative array where keys are values and array values are labels.
1<x-bt-select2 label="Status"3 :options="[4 'draft' => 'Draft',5 'review' => 'In review',6 'published' => 'Published',7 ]"8 placeholder="Select status..."9/>
Multiple Selection
Enable :multiple="true" to select multiple values.
Selected options are shown as chips, with a +N badge when there are too many to display.
1<x-bt-select 2 label="Tags" 3 :options="[ 4 'frontend' => 'Frontend', 5 'backend' => 'Backend', 6 'devops' => 'DevOps', 7 'design' => 'Design', 8 ]" 9 :multiple="true"10 placeholder="Select one or more tags..."11/>
Using Models & Custom Fields
When using Eloquent models or complex arrays, you can control which fields are used for labels and values
via option-label and option-value.
1<x-bt-select2 label="User"3 :options="$users" {{-- e.g. User::all() --}}4 option-label="name" {{-- field used as label --}}5 option-value="id" {{-- field used as value --}}6 placeholder="Search a user..."7 searchable8/>
Remote
For large datasets, you can enable remote mode to fetch options from an API as the user types.
The endpoint should return JSON with an associative array of options.
1<x-bt-select2 label="User (remote search)"3 placeholder="Type to search..."4 remote5 searchable6 remote-url="{{ route('api.users.select') }}"7/>
Slot Before options
This slot is rendered at the top of the options dropdown, before the list of options, after the search input if searchable.
1{{-- Blade view --}} 2<x-bt-select 3 label="Default status" 4 :options="[ 5 'draft' => 'Draft', 6 'review' => 'In review', 7 'published' => 'Published', 8 ]" 9>10 <x-slot:before-options>11 <div class="p-2 text-sm text-gray-500 space-x-3">12 <em>Add new status</em>13 <a href="#" class="text-blue-600 hover:underline">Create new status</a>14 </div>15 </x-slot:before-options>16</x-bt-select>
Slot After options
This slot is rendered when a search is performed with no results.
1{{-- Blade view --}} 2<x-bt-select 3 label="Default status" 4 :options="[ 5 'draft' => 'Draft', 6 'review' => 'In review', 7 'published' => 'Published', 8 ]" 9>10 <x-slot:after-options>11 <div class="p-2 text-sm text-gray-500 space-x-3">12 <em>Cant find the status you need?</em>13 <a href="#" class="text-blue-600 hover:underline">14 Create status <span x-html="search"></span>15 </a>16 </div>17 </x-slot:after-options>18</x-bt-select>
Autosave with Livewire
The select can automatically call a Livewire method every time the value changes.
This is perfect for user preferences (e.g. default filters, default status, etc.).
How autosave works:
- Requires a
wire:modelbinding on the select. - When the value changes, the component calls
$wire.call(autosaveMethod, value, autosaveKey). autosave-keylets you reuse the same method for many selects.- The small icon at the right of the field shows: saving spinner, success check, or error.
1{{-- Blade view --}} 2<x-bt-select 3 label="Default status" 4 :options="[ 5 'draft' => 'Draft', 6 'review' => 'In review', 7 'published' => 'Published', 8 ]" 9 wire:model="defaultStatus"10 :autosave="true"11 autosave-method="savePreference"12 autosave-key="defaultStatus"13/>
Livewire Component for autosave
1public ?string $defaultStatus = null;2 3public function savePreference($value, $key)4{5 $this->toast()->success("Saved {$key} as {$value}");6}
Props
| Prop | Type | Default | Description |
|---|---|---|---|
options
|
array|Collection
|
[]
|
Data source for the select. It accepts:
label, description, icon, and avatar.
|
label
|
string|null
|
null
|
Optional label displayed above the select field.
|
placeholder
|
string
|
Seleccionar...
|
Placeholder text shown when no value is selected.
|
multiple
|
bool
|
false
|
Enables multiple selection. When
true, the bound value is an array
and the UI shows chips with a +N badge for extra items.
|
clearable
|
bool
|
true
|
Adds a clear (X) button that resets the current selection.
|
searchable
|
bool
|
true
|
Shows a search input inside the dropdown.
For local options, filtering happens on the client. For remote options, the query is sent to the remote-url endpoint.
|
remote
|
bool
|
false
|
Enables remote loading of options via
remote-url.When true, the component calls the endpoint with q parameter as the user types.
|
remote-url
|
string|null
|
null
|
URL used to fetch options in remote mode.
Expected JSON structure: { "id1": { "label": "Option 1", "description": "...", "icon": "⭐", "avatar": "..." }, "id2": { "label": "Option 2" } } |
initialValue
|
mixed
|
null
|
Initial selected value(s) when not using
wire:model.For multiple selects you can pass a scalar, an array of values, or null.
|
icon
|
string|null
|
null
|
Optional icon displayed inside the trigger (depends on your base presets).
|
size
|
string|null
|
null
|
Size preset key (e.g.
sm, md, lg) from the input preset.
|
color
|
string|null
|
null
|
Color preset key for the select trigger and dropdown (inherits from
input and select presets).
|
customError
|
string|null
|
null
|
Custom error message to force an error state independently of validation.
|
hint
|
string|null
|
null
|
Additional hint text shown below the field via the
field-help component.
|
option-label
|
string
|
label
|
Field name used to extract the option label from each item.
Fallbacks: label, name, text, value.
|
option-value
|
string
|
value
|
Field used as the option value (internal ID).
Fallbacks: id, key, value.
|
option-description
|
string
|
description
|
Field used as the secondary description line for each option.
Fallbacks: description, desc, subtitle.
|
option-icon
|
string
|
icon
|
Field that contains the icon. It can be:
|
option-avatar
|
string
|
avatar
|
Field with an avatar (URL, emoji, or short text) displayed as a small circle next to the label.
|
autosave
|
bool
|
false
|
Enables autosave mode when used with
wire:model.On every change, the select will call the Livewire method defined in autosave-method
passing (value, autosaveKey) as arguments.
|
autosave-method
|
string
|
savePreference
|
Name of the Livewire method to call when autosave is enabled.
Signature: public function methodName($value, $key).
|
autosave-key
|
string|null
|
wire:model name
|
Logical key for the setting being saved (e.g.
defaultStatus).Defaults to the bound wire:model name when not provided.
|
autosave-debounce
|
int
|
300
|
Debounce time in milliseconds before triggering the autosave call.
(Internally the select already batches calls; this prop is available for fine-tuning.) |
wire:model
|
Livewire binding
|
null
|
Binds the selected value to a Livewire property. For multiple selects, the property should be an array of values.
When
autosave is enabled, this is required.
|
start / end slots
|
slot
|
null
|
Custom content rendered inside the trigger at the start or end, in addition to clear/autosave indicators and chevron.
|
empty-message
|
string
|
'No hay resultados.'
|
Custom message displayed when there are no options available.
|
spinner
|
bool
|
true
|
When
true, shows a Livewire loading spinner when the bound value is being updated.
|
before-options
|
slot
|
null
|
Slot rendered at the top of the options dropdown, before the list of options.
|
after-options
|
slot
|
null
|
When a search is done with no results, this slot is rendered instead of the default empty-message.
|