shkubu18/filament-widget-tabs

Widget Tabs are modified version of Filament Tabs to display it as a widgets.

v1.0.2 2025-05-30 18:27 UTC

This package is auto-updated.

Last update: 2025-08-20 08:02:17 UTC


README

Widget Tabs Banner

Installation

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.

  1. Import the plugin's stylesheet in your theme's css file.
@import '<path-to-vendor>/shkubu18/filament-widget-tabs/resources/css/widget-tabs.css';
  1. Add the plugin's views to your tailwind.config.js file.
content: [
    '<path-to-vendor>/shkubu18/filament-widget-tabs/resources/**/*.blade.php',
]

Publishing Views

If you need to customize the views, you can publish them with:

  php artisan vendor:publish --tag=filament-widget-tabs-views

Usage

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.

Add the HasWidgetTabs trait

Add the HasWidgetTabs trait to your Filament resource page.

Implement the getWidgetTabs() method

Define 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.

Features

Auto-loading Default Active Widget Tab

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
}

Widget Tabs Layout

You can customize how many widget tabs appear in each row by overriding the getWidgetsPerRow() method in your page class:

 protected function getWidgetsPerRow(): int 
 { 
    return 4; // Default is 3 widgets per row
 }

Labels

Add a descriptive label to your widget tab:

WidgetTab::make()
    ->label('Published Posts')

Icons

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)

Values

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"

Percentages

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%"

Extra Attributes

Add extra HTML attributes to your widget tab:

WidgetTab::make()
    ->extraAttributes(['attribute' => 'value'])

Query Modification

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'))

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.