Skip to content

Commit

Permalink
add (Livewire) combobox component
Browse files Browse the repository at this point in the history
  • Loading branch information
anotherfrontendguy committed Sep 17, 2024
1 parent 9c1c3aa commit 8705b4f
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 0 deletions.
66 changes: 66 additions & 0 deletions app/Livewire/UI/Combobox.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace App\Livewire\UI;

use Livewire\Attributes\Modelable;
use Livewire\Component;

class Combobox extends Component

Check failure on line 8 in app/Livewire/UI/Combobox.php

View workflow job for this annotation

GitHub Actions / phpstan

Class App\Livewire\UI\Combobox extends unknown class Livewire\Component.

Check failure on line 8 in app/Livewire/UI/Combobox.php

View workflow job for this annotation

GitHub Actions / phpstan

Class App\Livewire\UI\Combobox extends unknown class Livewire\Component.
{
#[Modelable]

Check failure on line 10 in app/Livewire/UI/Combobox.php

View workflow job for this annotation

GitHub Actions / phpstan

Attribute class Livewire\Attributes\Modelable does not exist.

Check failure on line 10 in app/Livewire/UI/Combobox.php

View workflow job for this annotation

GitHub Actions / phpstan

Attribute class Livewire\Attributes\Modelable does not exist.
public $value;

public $model;

public $searchable = [];

public int $limit = 5;

public $search = '';

public $show = false;

public $placeholder = '';

public $selected;

public $display = '';

public $results = [];

public function mount()
{
if ($this->value) {
$result = $this->model::findOrFail($this->value);
$this->selected = $result;
}

$this->results = collect([]);
}

public function updatedSearch($value)
{
$query = $this->model::query();

foreach ($this->searchable as $search) {
$query->where($search, 'like', "%$value%");
}

$this->results = $query->limit($this->limit)->get();
}

public function select($result)
{
$result = $this->results->find($result);

$this->value = $result->id;
$this->selected = $result;
$this->show = false;
$this->reset(['search', 'results']);

Check failure on line 59 in app/Livewire/UI/Combobox.php

View workflow job for this annotation

GitHub Actions / phpstan

Call to an undefined method App\Livewire\UI\Combobox::reset().

Check failure on line 59 in app/Livewire/UI/Combobox.php

View workflow job for this annotation

GitHub Actions / phpstan

Call to an undefined method App\Livewire\UI\Combobox::reset().
}

public function render()
{
return view('livewire.combobox.index');
}
}
41 changes: 41 additions & 0 deletions resources/views/livewire/combobox/index.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<div>
<x-popover wire:model="show">
<x-popover.trigger>
<button
class="inline-flex items-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2 w-[200px] justify-between"
>
@if ($selected)
{{ $selected->{$display} }}
@else
{{ __($placeholder) }}
@endif
<x-lucide-chevrons-up-down class="ml-2 size-4 shrink-0 opacity-50" />
</button>
</x-popover.trigger>
<x-popover.content class="w-[200px] p-0">
<div class="flex items-center border-b px-3">
<x-lucide-search class="size-4 mr-2 shrink-0 opacity-50" />
<x-input
wire:model.live="search"
placeholder="{{ __($placeholder) }}"
class="py-3 px-0 outline-none border-none focus-visible:ring-0"
/>
</div>
@foreach ($results as $result)
<div
wire:click="select('{{ $result->id }}')"
class="hover:bg-accent relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50",
>
{{ $result->{$display} }}

@if ($value === $result->id)
<x-lucide-check class="size-4 ml-auto h-4 w-4 opacity-100" />
@endif
</div>
@endforeach
@if ($search && $results->isEmpty())
<p class="py-6 text-center text-sm">{{ __('No results found') }}</p>
@endif
</x-popover.content>
</x-popover>
</div>
14 changes: 14 additions & 0 deletions src/LaravelLuviServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ class LaravelLuviServiceProvider extends ServiceProvider
'typography',
];

protected $livewireComponents = [
'combobox',
];

/**
* Register any application services.
*/
Expand All @@ -57,6 +61,16 @@ public function boot(): void
], $component);
}

foreach ($this->livewireComponents as $livewireComponent) {
$this->publishes([
__DIR__."/../resources/views/livewire/{$livewireComponent}" => resource_path("views/livewire/{$livewireComponent}"),
], $livewireComponent);

$this->publishes([
__DIR__.'/../app/Livewire/UI/'.str($livewireComponent)->ucfirst().'.php' => app_path('Livewire/UI/'.str($livewireComponent)->ucfirst()).'.php',
], $livewireComponent);
}

$this->publishes([
__DIR__.'/../App/Services/ButtonCvaService.php' => app_path('Services/ButtonCvaService.php'),
], 'button');
Expand Down

0 comments on commit 8705b4f

Please sign in to comment.