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

Laravel Livewire Widgets Laravel Package

bernskioldmedia/laravel-livewire-widgets

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require bernskioldmedia/laravel-livewire-widgets
    

    Publish the package assets:

    php artisan vendor:publish --provider="BernskioldMedia\LivewireWidgets\LivewireWidgetsServiceProvider" --tag="public"
    
  2. 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";
    
  3. 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);
    }
    
  4. Render the Widget: Use the Blade directive in your view:

    @livewireWidgets('example')
    

Implementation Patterns

Core Workflows

  1. Widget Registration:

    • Dynamic Registration: Use LivewireWidgets::add() in a service provider or boot method.
    • Named Slots: Register widgets with named slots for modular layouts:
      LivewireWidgets::add('sidebar', \App\Http\Livewire\SidebarWidget::class, 'sidebar');
      
    • Conditional Loading: Leverage LivewireWidgets::when() for environment/role-based widgets:
      LivewireWidgets::when(fn() => Auth::check(), function ($widgets) {
          $widgets->add('user-dashboard', \App\Http\Livewire\UserDashboardWidget::class);
      });
      
  2. Component Structure:

    • Traits: Extend the Widget trait for built-in methods like getWidgetId(), getWidgetView(), and getWidgetConfig().
    • Configuration: Pass settings via $widgetConfig property:
      public $widgetConfig = [
          'theme' => 'dark',
          'itemsPerPage' => 10,
      ];
      
    • Views: Override getWidgetView() to customize the Blade template path:
      protected function getWidgetView(): string
      {
          return 'widgets.example-custom';
      }
      
  3. Integration with Livewire:

    • State Management: Use Livewire’s built-in state management (e.g., $property, public $property).
    • Events: Emit widget-specific events:
      $this->emit('widget-event', ['data' => 'payload']);
      
    • Listeners: Attach listeners in your parent Livewire component or Blade view:
      @script
          window.addEventListener('widget-event', (e) => {
              console.log(e.detail.data);
          });
      @endscript
      
  4. Layout Patterns:

    • Grid/System: Use the package’s CSS classes (widget-grid, widget-item) for responsive layouts:
      <div class="widget-grid">
          @livewireWidgets(['example', 'stats'])
      </div>
      
    • Nested Widgets: Embed widgets within other widgets by rendering them in the child component’s view.

Advanced Patterns

  1. Widget Templates:

    • Shared Views: Store widget views in resources/views/widgets/ for consistency.
    • Dynamic Content: Use Blade components or slots:
      <div class="widget-container">
          {{ $slot }}
          @livewire($widgetComponent, $widgetConfig)
      </div>
      
  2. Authentication/Authorization:

    • Middleware: Apply Livewire middleware to widgets:
      public function mount()
      {
          $this->middleware('auth');
      }
      
    • Policy Checks: Integrate Laravel policies in rules():
      public function rules()
      {
          return [
              'user_id' => ['required', Rule::exists('users')->where(fn($query) => $query->where('id', $this->user_id))],
          ];
      }
      
  3. Internationalization:

    • Translation Keys: Use Laravel’s translation system in widget views:
      {{ __('widgets.example.title') }}
      
    • Dynamic Languages: Pass locale via widgetConfig:
      public $widgetConfig = ['locale' => app()->getLocale()];
      
  4. Performance Optimization:

    • Lazy Loading: Use defer for non-critical widgets:
      @livewireWidgets(['analytics'], ['defer' => true])
      
    • Caching: Cache widget data in booted():
      protected $cachedData;
      public function booted()
      {
          $this->cachedData = Cache::remember("widget_{$this->widgetId}_data", now()->addHours(1), function() {
              return $this->fetchData();
          });
      }
      

Gotchas and Tips

Common Pitfalls

  1. CSS Conflicts:

    • Issue: Widget styles may be overridden by Tailwind or other CSS.
    • Fix: Ensure 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;
      }
      
  2. State Persistence:

    • Issue: Widget state may reset on page reload if not properly managed.
    • Fix: Use Livewire’s persistent property or session storage:
      public $persistent = true;
      
      Or manually save to session:
      session()->put("widget_{$this->widgetId}_state", $this->state);
      
  3. Component Naming Collisions:

    • Issue: Custom widget classes may conflict with Laravel/Livewire core classes.
    • Fix: Use fully qualified namespaces or aliases:
      use Widget = \App\Http\Livewire\Widgets\ExampleWidget;
      
  4. Event Listeners:

    • Issue: Widget events may not fire due to scope or timing.
    • Fix: Use wire:ignore for non-Livewire elements and ensure listeners are attached in the correct lifecycle (e.g., mounted()).

Debugging Tips

  1. Widget Registration:

    • Verify registration with:
      dd(\BernskioldMedia\LivewireWidgets\Facades\LivewireWidgets::all());
      
    • Check for typos in widget names or class paths.
  2. Livewire Logs:

    • Enable Livewire logging in config/livewire.php:
      'log' => env('LIVEWIRE_LOG', true),
      
    • Inspect logs in storage/logs/livewire.log.
  3. View Resolution:

    • Debug missing views with:
      dd(\BernskioldMedia\LivewireWidgets\Facades\LivewireWidgets::resolveView('example'));
      
  4. Network Requests:

    • Use browser dev tools to verify widget assets (JS/CSS) are loaded. Check for 404s on /livewire/ endpoints.

Extension Points

  1. Custom Directives:

    • Extend Blade directives by publishing the package’s views:
      php artisan vendor:publish --provider="BernskioldMedia\LivewireWidgets\LivewireWidgetsServiceProvider" --tag="views"
      
    • Override app/Providers/AppServiceProvider.php:
      Blade::directive('livewireWidgets', function ($expression) {
          return "<?php echo \\BernskioldMedia\\LivewireWidgets\\LivewireWidgets::render($expression); ?>";
      });
      
  2. Widget Factories:

    • Create a factory for reusable widget configurations:
      class WidgetFactory
      {
          public static function createStatsWidget(array $config): string
          {
              return \BernskioldMedia\LivewireWidgets\Facades\LivewireWidgets::add('stats', StatsWidget::class, [], $config);
          }
      }
      
  3. Testing:

    • Mock widgets in tests:
      $widgets = \Mockery::mock(\BernskioldMedia\LivewireWidgets\LivewireWidgets::class);
      $widgets->shouldReceive('render')->andReturn('<div>Mocked Widget</div>');
      $this->app->instance(\BernskioldMedia\LivewireWidgets\Facades\LivewireWidgets::class, $widgets);
      
  4. API Integration:

    • Fetch widget data via API in mount():
      public function mount()
      {
          $this->data = Http
      
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.
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
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