vodafoneziggonl/filament-multi-widget
Installation
composer require vodafoneziggonl/filament-multi-widget
Ensure compatibility with your Filament version (5.x for Filament 5.x, 3.x for Filament 4.x).
Publish Assets (if needed)
Run php artisan vendor:publish --provider="VodafoneZiggoNL\MultiWidget\MultiWidgetServiceProvider" to customize default styles (e.g., tab styling).
First Use Case Create a simple multi-widget combining two existing widgets:
// app/Filament/Widgets/DashboardMultiWidget.php
use VodafoneZiggoNL\MultiWidget\MultiWidget;
class DashboardMultiWidget extends MultiWidget
{
public array $widgets = [
\App\Filament\Widgets\StatsOverview::class,
\App\Filament\Widgets\RecentActivity::class,
];
public string $heading = 'Dashboard Analytics';
}
Register it in app/Providers/Filament/AdminPanelProvider.php:
public function panel(Panel $panel): Panel
{
return $panel
->widgets([
DashboardMultiWidget::class,
]);
}
Tab-Based Organization
public array $widgets = [
UserActivityWidget::class,
UserEngagementWidget::class,
];
public string $heading = 'User Insights';
Dynamic Widget Loading
public function getWidgets(): array
{
return [
fn () => new StatsWidget($this->userId),
fn () => new AlertsWidget($this->alertThreshold),
];
}
Conditional Widgets
public function getWidgets(): array
{
$widgets = [AdminStats::class];
if (auth()->user()->can('view_reports')) {
$widgets[] = SalesReports::class;
}
return $widgets;
}
Nested Multi-Widgets
// Parent MultiWidget
public array $widgets = [
MarketingMultiWidget::class,
SupportMultiWidget::class,
];
Custom Tab Icons/Colors
protected static string $tabIcon = 'heroicon-o-chart-bar';
protected static string $tabColor = 'success';
polling, columnSpanFull).
public array $widgets = [
fn () => new RecentOrdersWidget(['polling' => 60]),
];
use trait to share data between tabs:
use Filament\Widgets\Concerns\HasWidgets;
public function mount(): void
{
$this->sharedData = $this->getSharedData();
}
__() helper:
public string $heading = __('widgets.multi.heading');
Widget Initialization Order
mount() or getWidgets() for initialization.CSS Conflicts
/* resources/css/filament/multi-widget.css */
.filament-multi-widget-tabs [data-tab] {
background: #f0f0f0;
}
Performance with Heavy Widgets
polling or lazy-loading:
fn () => new DataTableWidget(['query' => fn () => User::lazy()]),
Missing Tab Labels
heading, tabs will show its class name. Ensure all sub-widgets define:
protected static string $heading = 'Orders';
Service Provider Registration
config/app.php under providers will break the widget.dd($this->widgets) in getWidgets() to verify the array structure.php artisan filament:cache:clear) if tabs fail to render.Custom Tab Rendering Override the default tab template:
public function getTabView(): string
{
return 'filament-multi-widget::tabs.custom';
}
Widget Filtering Dynamically filter widgets based on context:
public function getWidgets(): array
{
return array_filter($this->widgets, fn ($widget) => $this->shouldShow($widget));
}
Event Hooks Listen to tab changes via JavaScript:
document.addEventListener('filament-multi-widget-tab-changed', (e) => {
console.log('Active tab:', e.detail.tab);
});
Server-Side Logic
Use Filament’s beforeRender to modify widgets before display:
protected function beforeRender(): void
{
$this->widgets = collect($this->widgets)->map(fn ($widget) => $this->modifyWidget($widget));
}
How can I help you explore Laravel packages today?