uluumbch/alpine-select-livewire
Powerful searchable select components with multi-select and drag-ordering support for Laravel Livewire & Alpine.js.
composer require uluumbch/alpine-select-livewire
Add the package views to your TailwindCSS content configuration.
For TailwindCSS v3 (tailwind.config.js):
export default {
content: [
'./resources/**/*.blade.php',
'./vendor/uluumbch/alpine-select-livewire/resources/**/*.blade.php',
],
// ... rest of config
}
For TailwindCSS v4 (resources/css/app.css):
@import 'tailwindcss';
@source '../views';
@source '../../vendor/uluumbch/alpine-select-livewire/resources';
npm run build
The service provider will be automatically registered via Laravel's package discovery.
Basic single-select dropdown:
<x-alpine-select::default
wire:model="selectedOption"
:options="['Option 1', 'Option 2', 'Option 3']"
placeholder="Choose an option..."
/>
With object options (value/label):
<x-alpine-select::default
wire:model="religion"
:options="[
['value' => 'islam', 'label' => 'Islam'],
['value' => 'christian', 'label' => 'Christian'],
['value' => 'catholic', 'label' => 'Catholic'],
]"
placeholder="Select religion..."
searchable
clearable
/>
Basic multi-select with chips:
<x-alpine-select::multiple
wire:model="selectedItems"
:options="[
['value' => 1, 'label' => 'Option 1'],
['value' => 2, 'label' => 'Option 2'],
['value' => 3, 'label' => 'Option 3'],
]"
placeholder="Select multiple..."
/>
With drag-and-drop ordering:
<x-alpine-select::multiple
wire:model="stages"
:options="$stageOptions"
:selected="$stages"
placeholder="Select stages..."
searchable
clearable
orderable
/>
<x-alpine-select::default>)| Prop | Type | Default | Description |
|---|---|---|---|
options |
array | [] |
Array of options (strings or objects) |
placeholder |
string | 'Pilih opsi...' |
Placeholder text when no selection |
no_results_text |
string | 'Tidak ada hasil' |
Text shown when search returns no results |
searchable |
boolean | false |
Enable search functionality |
clearable |
boolean | false |
Show clear button to reset selection |
disabled |
boolean | false |
Disable the select input |
floating |
boolean | true |
Use floating dropdown (false for inline) |
selected |
string/int | null |
Initial selected value |
class |
string | '' |
Additional CSS classes for trigger |
<x-alpine-select::multiple>)| Prop | Type | Default | Description |
|---|---|---|---|
options |
array | [] |
Array of options (strings or objects) |
placeholder |
string | 'Pilih opsi...' |
Placeholder text when no selection |
no_results_text |
string | 'Tidak ada hasil' |
Text shown when search returns no results |
searchable |
boolean | false |
Enable search functionality |
clearable |
boolean | false |
Show clear button to reset all selections |
disabled |
boolean | false |
Disable the select input |
floating |
boolean | true |
Use floating dropdown (false for inline) |
selected |
array | [] |
Initial selected values (array of IDs) |
orderable |
boolean | false |
Enable drag-and-drop reordering of chips |
select_all_text |
string | 'Pilih Semua' |
Text for "Select All" button |
clear_all_text |
string | 'Hapus Semua' |
Text for "Clear All" button |
class |
string | '' |
Additional CSS classes for trigger |
The package intelligently normalizes options into a consistent format. You can pass options in various formats:
$options = ['Option 1', 'Option 2', 'Option 3'];
$options = [
['value' => 1, 'label' => 'First Option'],
['value' => 2, 'label' => 'Second Option'],
];
The package also recognizes these alternative keys:
id, key (as value)nama, text (as label)$options = [
['id' => 1, 'nama' => 'Jakarta'],
['id' => 2, 'nama' => 'Surabaya'],
];
The component supports all Livewire wire:model modifiers:
{{-- Immediate sync --}}
<x-alpine-select::default wire:model="field" :options="$options" />
{{-- Lazy sync (on blur/change) --}}
<x-alpine-select::default wire:model.lazy="field" :options="$options" />
{{-- Deferred sync (on form submit) --}}
<x-alpine-select::default wire:model.defer="field" :options="$options" />
Listen to the model-updated event for custom handling:
<div x-data @model-updated="console.log('Selection changed:', $event.detail.value)">
<x-alpine-select::default wire:model="field" :options="$options" />
</div>
Update options dynamically from your Livewire component:
class MyComponent extends Component
{
public $selectedCity;
public $cities = [];
public function mount()
{
$this->cities = City::pluck('name', 'id')->toArray();
}
public function render()
{
return view('livewire.my-component');
}
}
<x-alpine-select::default
wire:model="selectedCity"
:options="$cities"
/>
php artisan vendor:publish --tag=alpine-select-config
This publishes config/alpine-select.php for custom configuration.
php artisan vendor:publish --tag=alpine-select-views
This publishes views to resources/views/vendor/alpine-select for customization.
php artisan vendor:publish --tag=alpine-select-lang
This publishes language files to lang/vendor/alpine-select for translation.
php artisan vendor:publish --provider="Uluumbch\AlpineSelectLivewire\AlpineSelectLivewireServiceProvider"
The package supports multiple languages. Default texts are in English.
placeholder - "Select an option..."no_results - "No results found"search_placeholder - "Search..."select_all - "Select All"clear_all - "Clear All"php artisan vendor:publish --tag=alpine-select-lang
lang/vendor/alpine-select/id/alpine-select.php):<?php
return [
'placeholder' => 'Pilih opsi...',
'no_results' => 'Tidak ada hasil',
'search_placeholder' => 'Cari...',
'select_all' => 'Pilih Semua',
'clear_all' => 'Hapus Semua',
];
You can override translations for individual components:
<x-alpine-select::default
wire:model="selectedOption"
:options="$options"
placeholder="Custom placeholder text"
no_results_text="Custom no results message"
search_placeholder="Custom search placeholder"
/>
Customize colors by extending your TailwindCSS theme:
// tailwind.config.js
export default {
theme: {
extend: {
colors: {
// Override zinc colors
zinc: {
// ... your custom shades
},
// Override blue accent colors
blue: {
// ... your custom shades
}
}
}
}
}
Publish the views to your application for full control:
php artisan vendor:publish --tag=alpine-select-views
Views will be published to resources/views/vendor/alpine-select/components/.
Then modify the Blade files directly. Example color scheme change:
# Change from zinc/blue to slate/indigo
cd resources/views/vendor/alpine-select/components
sed -i 's/zinc-/slate-/g' *.blade.php
sed -i 's/blue-/indigo-/g' *.blade.php
Add custom CSS targeting component classes:
/* resources/css/app.css */
.alpine-select-trigger {
@apply border-2 border-purple-300 rounded-xl;
}
.alpine-select-option:hover {
@apply bg-purple-100;
}
Change dropdown max height:
Find max-h-48 in the component and change to your preferred height class.
Customize icons:
Replace the SVG elements in the published views with your own icons or icon library.
Adjust border radius:
Change rounded-lg to rounded-xl, rounded-2xl, etc.
Make sure options are passed as a PHP array or collection, not a JSON string:
{{-- ✅ Correct --}}
:options="$options"
{{-- ❌ Wrong --}}
options="{{ json_encode($options) }}"
Ensure your Livewire property is public and properly initialized:
class MyComponent extends Component
{
public $selectedOption = ''; // Initialize with empty string or default value
}
For dropdowns inside modals or scrollable containers, use floating="false":
<x-alpine-select::default
wire:model="field"
:options="$options"
:floating="false"
/>
The multi-select component includes wire:ignore to prevent conflicts. If you still experience issues, ensure you're using Livewire 3.x and the latest package version.
The MIT License (MIT). Please see License File for more information.
Contributions are welcome! Please feel free to submit a Pull Request.
If you encounter any issues or have questions, please open an issue on GitHub.
How can I help you explore Laravel packages today?