Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Alpine Select Livewire Laravel Package

uluumbch/alpine-select-livewire

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:
    composer require uluumbch/alpine-select-livewire
    
  2. Publish assets (if needed):
    php artisan vendor:publish --provider="Uluumbch\AlpineSelectLivewire\AlpineSelectLivewireServiceProvider"
    
  3. Add Tailwind content paths (as shown in README) to ensure styles are processed.

First Use Case: Basic Single Select

<livewire:alpine-select
    wire:model="selectedOption"
    :options="$options"
    placeholder="Choose an option"
/>
  • Livewire Component:
    public $selectedOption;
    public $options = [
        ['id' => 1, 'name' => 'Option 1'],
        ['id' => 2, 'name' => 'Option 2'],
    ];
    

First Use Case: Multi-Select with Search

<livewire:alpine-select
    wire:model="selectedOptions"
    :options="$options"
    placeholder="Select multiple..."
    multiple
    searchable
/>
  • Livewire Component:
    public $selectedOptions = [];
    public $options = collect([...]); // Large dataset (e.g., from DB)
    

Implementation Patterns

1. Data Binding & Livewire Integration

  • Two-way binding: Use wire:model for seamless reactivity.
    <livewire:alpine-select
        wire:model.defer="userRoles"  <!-- Defer updates for performance -->
        :options="$roles"
        multiple
    />
    
  • Dynamic options: Fetch options in mount() or updatedProperty():
    public function mount() {
        $this->options = Role::all()->pluck('name', 'id');
    }
    

2. Multi-Select Workflows

  • Drag-and-drop reordering: Enable with reorderable prop:
    <livewire:alpine-select
        wire:model="sortedTags"
        :options="$tags"
        multiple
        reorderable
    />
    
  • Handle reordered data in Livewire:
    public function updatedSortedTags($value) {
        $this->tags = collect($value)->sortBy('order');
    }
    

3. Search Optimization

  • Debounce search: Use Alpine’s debounce directive:
    <livewire:alpine-select
        wire:model="searchResults"
        :options="$allOptions"
        searchable
        @search.debounce.300ms="fetchOptions"
    />
    
  • Server-side search: Fetch filtered options in Livewire:
    public function fetchOptions($query) {
        $this->options = Model::where('name', 'like', "%{$query}%")->get();
    }
    

4. Custom Option Formatting

  • Label/value mapping: Pass objects or arrays:
    <livewire:alpine-select
        :options="$users"
        option-label="name"
        option-value="id"
    />
    
  • Custom templates: Override slots:
    <livewire:alpine-select>
        <xslot name="option">
            <div class="flex items-center">
                <img src="{{ $option->avatar }}" width="20">
                <span>{{ $option->name }}</span>
            </div>
        </xslot>
    </livewire:alpine-select>
    

5. Dark Mode & Theming

  • Tailwind classes: Extend base styles:
    /* resources/css/app.css */
    @layer components.alpine-select {
        .alpine-select-dark .select__dropdown {
            @apply bg-gray-800 text-white;
        }
    }
    
  • Dynamic theming: Toggle via Alpine:
    <div x-data="{ darkMode: true }">
        <button @click="darkMode = !darkMode">Toggle Dark</button>
        <livewire:alpine-select
            :class="{ 'alpine-select-dark': darkMode }"
            ...
        />
    </div>
    

Gotchas and Tips

Pitfalls

  1. Tailwind Processing:

    • Issue: Styles not applied? Ensure vendor/uluumbch/alpine-select-livewire/resources/views is in tailwind.config.js content.
    • Fix: Run npx tailwindcss -i input.css -o output.css --watch if using custom setup.
  2. Livewire Defer Conflicts:

    • Issue: wire:model.defer may cause lag with large datasets.
    • Fix: Use wire:ignore on the component and manually sync:
      <div wire:ignore>
          <livewire:alpine-select @change="syncSelection" ... />
      </div>
      
      public function syncSelection($value) {
          $this->selectedOptions = $value;
      }
      
  3. Option Format Mismatch:

    • Issue: option-label/option-value ignored if options aren’t objects/arrays.
    • Fix: Ensure options are structured consistently:
      // Correct:
      $options = collect([['id' => 1, 'name' => 'Foo']]);
      // Or:
      $options = Model::pluck('name', 'id');
      
  4. Reorderable Multi-Select:

    • Issue: Drag-and-drop doesn’t persist order.
    • Fix: Bind to an array with order keys:
      public $selectedOptions = [
          ['id' => 1, 'name' => 'First', 'order' => 1],
          ['id' => 2, 'name' => 'Second', 'order' => 2],
      ];
      

Debugging Tips

  • Inspect Alpine state: Add x-data to debug:
    <div x-data="{ select: {} }" x-init="select = $wire.model('selectedOptions')">
        {{ $wire.entangle('selectedOptions') }}
    </div>
    
  • Check Livewire logs: Enable for component updates:
    public function boot() {
        Livewire::configureToUseAlpineSelect();
        Livewire::enableLogging(); // For debugging
    }
    

Extension Points

  1. Custom Events:

    • Listen to Alpine events:
      <livewire:alpine-select
          @searching="console.log('Searching...')"
          @selected="console.log('Selected:', $event.detail)"
      />
      
    • Emit custom events in Livewire:
      public function updatedSelectedOptions($value) {
          $this->dispatch('select-changed', value: $value);
      }
      
  2. Slot Overrides:

    • Extend templates via slots (see README templates):
      <livewire:alpine-select>
          <xslot name="no-options">
              <p class="p-2 text-gray-500">No results found.</p>
          </xslot>
      </livewire:alpine-select>
      
  3. Alpine Directives:

    • Extend functionality with custom directives:
      <livewire:alpine-select
          x-init="
              $watch('selectedOptions', (val) => {
                  console.log('Custom logic:', val);
              })
          "
      />
      

Performance Quirks

  • Large Datasets: Use searchable + server-side filtering to avoid client-side overload.
  • Memory Leaks: Unbind Alpine event listeners in Livewire’s updated methods if adding custom logic:
    public function updatedCustomField() {
        $this->dispatch('alpine-init', script: '
            $wire.off("change");
        ');
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours