bernskioldmedia/laravel-livewire-widgets
Installation:
composer require bernskioldmedia/laravel-livewire-widgets
Publish the package assets:
php artisan vendor:publish --provider="BernskioldMedia\LivewireWidgets\LivewireWidgetsServiceProvider" --tag="public"
CSS Integration:
Add the base styles to your resources/scss/app.scss (or equivalent) before Tailwind imports:
@import "../../vendor/bernskioldmedia/laravel-livewire-widgets/resources/css/widgets.css";
First Widget:
Create a Livewire component (e.g., app/Http/Livewire/ExampleWidget.php):
namespace App\Http\Livewire;
use BernskioldMedia\LivewireWidgets\Traits\Widget;
class ExampleWidget extends \Livewire\Component
{
use Widget;
public $title = "Hello, Widget!";
}
Register it in app/Providers/AppServiceProvider.php:
public function boot()
{
\BernskioldMedia\LivewireWidgets\Facades\LivewireWidgets::add('example', \App\Http\Livewire\ExampleWidget::class);
}
Render the Widget: Use the Blade directive in your view:
@livewireWidgets('example')
Widget Registration:
LivewireWidgets::add() in a service provider or boot method.LivewireWidgets::add('sidebar', \App\Http\Livewire\SidebarWidget::class, 'sidebar');
LivewireWidgets::when() for environment/role-based widgets:
LivewireWidgets::when(fn() => Auth::check(), function ($widgets) {
$widgets->add('user-dashboard', \App\Http\Livewire\UserDashboardWidget::class);
});
Component Structure:
Widget trait for built-in methods like getWidgetId(), getWidgetView(), and getWidgetConfig().$widgetConfig property:
public $widgetConfig = [
'theme' => 'dark',
'itemsPerPage' => 10,
];
getWidgetView() to customize the Blade template path:
protected function getWidgetView(): string
{
return 'widgets.example-custom';
}
Integration with Livewire:
$property, public $property).$this->emit('widget-event', ['data' => 'payload']);
@script
window.addEventListener('widget-event', (e) => {
console.log(e.detail.data);
});
@endscript
Layout Patterns:
widget-grid, widget-item) for responsive layouts:
<div class="widget-grid">
@livewireWidgets(['example', 'stats'])
</div>
Widget Templates:
resources/views/widgets/ for consistency.<div class="widget-container">
{{ $slot }}
@livewire($widgetComponent, $widgetConfig)
</div>
Authentication/Authorization:
public function mount()
{
$this->middleware('auth');
}
rules():
public function rules()
{
return [
'user_id' => ['required', Rule::exists('users')->where(fn($query) => $query->where('id', $this->user_id))],
];
}
Internationalization:
{{ __('widgets.example.title') }}
widgetConfig:
public $widgetConfig = ['locale' => app()->getLocale()];
Performance Optimization:
defer for non-critical widgets:
@livewireWidgets(['analytics'], ['defer' => true])
booted():
protected $cachedData;
public function booted()
{
$this->cachedData = Cache::remember("widget_{$this->widgetId}_data", now()->addHours(1), function() {
return $this->fetchData();
});
}
CSS Conflicts:
widgets.css is imported before Tailwind directives. Use !important sparingly; prefer specificity:
.widget-container {
@apply p-4 border rounded-lg;
/* Override Tailwind if needed */
border-color: theme('colors.blue.500') !important;
}
State Persistence:
persistent property or session storage:
public $persistent = true;
Or manually save to session:
session()->put("widget_{$this->widgetId}_state", $this->state);
Component Naming Collisions:
use Widget = \App\Http\Livewire\Widgets\ExampleWidget;
Event Listeners:
wire:ignore for non-Livewire elements and ensure listeners are attached in the correct lifecycle (e.g., mounted()).Widget Registration:
dd(\BernskioldMedia\LivewireWidgets\Facades\LivewireWidgets::all());
Livewire Logs:
config/livewire.php:
'log' => env('LIVEWIRE_LOG', true),
storage/logs/livewire.log.View Resolution:
dd(\BernskioldMedia\LivewireWidgets\Facades\LivewireWidgets::resolveView('example'));
Network Requests:
/livewire/ endpoints.Custom Directives:
php artisan vendor:publish --provider="BernskioldMedia\LivewireWidgets\LivewireWidgetsServiceProvider" --tag="views"
app/Providers/AppServiceProvider.php:
Blade::directive('livewireWidgets', function ($expression) {
return "<?php echo \\BernskioldMedia\\LivewireWidgets\\LivewireWidgets::render($expression); ?>";
});
Widget Factories:
class WidgetFactory
{
public static function createStatsWidget(array $config): string
{
return \BernskioldMedia\LivewireWidgets\Facades\LivewireWidgets::add('stats', StatsWidget::class, [], $config);
}
}
Testing:
$widgets = \Mockery::mock(\BernskioldMedia\LivewireWidgets\LivewireWidgets::class);
$widgets->shouldReceive('render')->andReturn('<div>Mocked Widget</div>');
$this->app->instance(\BernskioldMedia\LivewireWidgets\Facades\LivewireWidgets::class, $widgets);
API Integration:
mount():
public function mount()
{
$this->data = Http
How can I help you explore Laravel packages today?