You can install the package via composer:
composer require shkubu18/filament-widget-tabs
In an effort to align with Filament's theming methodology you will need to use a custom theme to use this plugin.
[!IMPORTANT] If you have not set up a custom theme and are using a Panel follow the instructions in the Filament Docs.
@import '<path-to-vendor>/shkubu18/filament-widget-tabs/resources/css/widget-tabs.css';
tailwind.config.js
file.content: [ '<path-to-vendor>/shkubu18/filament-widget-tabs/resources/**/*.blade.php',]
If you need to customize the views, you can publish them with:
php artisan vendor:publish --tag=filament-widget-tabs-views
Filament Widget Tabs works similarly to Filament Tabs, but displays each tab as a “widget” that can filter your resource’s table with a single click.
HasWidgetTabs
traitAdd the HasWidgetTabs
trait to your Filament resource page.
getWidgetTabs()
methodDefine your widget tabs by implementing the getWidgetTabs()
method in your page class.
Each tab is created with the WidgetTab::make()
component, allowing you to specify label, icon, value, and filtering
behavior:
use App\Enums\PostStatusEnum;use Illuminate\Database\Eloquent\Builder;use Filament\Resources\Pages\ListRecords;use Shkubu\FilamentWidgetTabs\Concerns\HasWidgetTabs;use Shkubu\FilamentWidgetTabs\Components\WidgetTab; class ListPosts extends ListRecords{ use HasWidgetTabs; public function getWidgetTabs(): array { return [ 'all' => WidgetTab::make() ->label('All Posts') ->icon('heroicon-o-chat-bubble-left-right') ->value(Post::count()), 'published' => WidgetTab::make() ->label('Published') ->icon('heroicon-o-eye') ->value(Post::where('status', PostStatusEnum::PUBLISHED)->count()) ->modifyQueryUsing(fn (Builder $query): Builder => $query->where('status', PostStatusEnum::PUBLISHED)), 'drafts' => WidgetTab::make() ->label('Drafts') ->icon('heroicon-o-archive-box') ->value(Post::where('status', PostStatusEnum::DRAFT)->count()) ->modifyQueryUsing(fn (Builder $query): Builder => $query->where('status', PostStatusEnum::DRAFT)), ]; }}
That's all you need to get started with Widget Tabs! Your resource list page will now display beautiful widget-style tabs that filter your table data just like default Filament tabs, but with the added benefit of displaying important data values within each tab widget.
By default, widget tabs will not automatically load a default active widget tab when the page mounts. If you want to
enable automatic loading of the default widget tab, you can override the shouldAutoLoadDefaultActiveWidgetTab
method
in your page class:
protected function shouldAutoLoadDefaultActiveWidgetTab(): bool{ return true; // Enable auto-loading of the default active widget tab}
You can customize how many widget tabs appear in each row by overriding the getWidgetsPerRow()
method in your page
class:
protected function getWidgetsPerRow(): int|array{ return 4; // Default is 3 widgets per row}
It is also possible to specify an array of breakpoints for different display sizes:
protected function getWidgetsPerRow(): int|array{ return ['sm' => 2, 'md' => 3, 'lg' => 4];}
Add a descriptive label to your widget tab:
WidgetTab::make() ->label('Published Posts')
Add an icon to visually enhance your widget tab:
WidgetTab::make() ->icon('heroicon-o-document-text')
You can also specify the icon size:
use Filament\Support\Enums\IconSize; WidgetTab::make() ->icon('heroicon-o-document-text') ->iconSize(IconSize::Large)
Display a count or other relevant value in your widget tab:
WidgetTab::make() ->value(Post::count())
You can control the decimal precision of numeric values:
WidgetTab::make() ->label('Average Rating') ->value(Post::avg('rating')) ->precision(2) // Will display with 2 decimal places, e.g., "4.75"
When enabled, the percentage method formats your value as a percentage, displaying it with a % symbol instead of as a regular number:
WidgetTab::make() ->value(25) ->percentage() // This will display as "25%" instead of "25"
You can control the decimal precision of percentage values independently from regular numeric values, giving you fine-grained control over how different types of data are displayed:
WidgetTab::make() ->label('Published Ratio') ->value(fn (): float => (Post::where('status', 'published')->count() / Post::count()) * 100) ->percentage() ->percentagePrecision(1) // Will display as "25.4%" instead of "25%"
Widget Tabs supports advanced theming with pre-built color schemes and gradients.
Apply different color themes to your widget tabs:
WidgetTab::make() ->label('Success Posts') ->value(Post::where('status', 'published')->count()) ->success() WidgetTab::make() ->label('Failed Posts') ->value(Post::where('status', 'failed')->count()) ->danger() WidgetTab::make() ->label('Draft Posts') ->value(Post::where('status', 'draft')->count()) ->info() //...
Preview:
Success Theme | Danger Theme | Info Theme |
---|---|---|
![]() |
![]() |
![]() |
Warning Theme | Secondary Theme | |
![]() |
![]() |
You can also use the generic theme()
method with enum or string values:
use Shkubu\FilamentWidgetTabs\Enums\WidgetTabTheme; WidgetTab::make() ->theme(WidgetTabTheme::Success) // Using enum
Add beautiful gradient backgrounds to your widget tabs:
WidgetTab::make() ->label('Premium Posts') ->value(Post::where('is_premium', true)->count()) ->success() ->gradient() // Adds gradient effect
Preview:
For advanced customization, you can add custom CSS classes:
WidgetTab::make() ->label('Custom Styled') ->value(100) ->customThemeClasses([ 'custom-shadow', 'custom-border', 'my-special-theme' ]) // Or use a closure for dynamic classesWidgetTab::make() ->customThemeClasses(fn () => [ 'dynamic-class-' . now()->format('Y'), 'user-role-' . auth()->user()->role ])
Add extra HTML attributes to your widget tab:
WidgetTab::make() ->extraAttributes(['attribute' => 'value'])
Filter the resource table based on the selected tab:
WidgetTab::make() ->modifyQueryUsing(fn (Builder $query): Builder => $query->where('status', 'published'))
Or use the shorter query()
method:
WidgetTab::make() ->query(fn (Builder $query): Builder => $query->where('status', 'published'))
Please see CONTRIBUTING for details.
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.
Data is a passionate developer who loves working with Laravel, PHP, and modern web technologies. He enjoys building scalable applications and is particularly enthusiastic about Filament – it's made creating beautiful admin panels so much fun! Always curious and learning, he’s on a journey to level up his coding skills, while solving interesting problems along the way.