Weave 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

Filament Dashboard Widgets Laravel Package

laboiteacode/filament-dashboard-widgets

A collection of fifteen polished, ready-to-use dashboard widgets for Filament: KPI metrics, goals, breakdowns, trends, funnels, timelines and more. Typed fluent API, static or computed data, native Filament components, light/dark themes, accessible and escaped by default with no front-end build step...

View on GitHub
Deep Wiki
Context7

Getting Started

  1. composer require laboiteacode/filament-dashboard-widgets — check the constraint against your Filament major version before committing (this package targets the current Filament widget base classes; a mismatch will fail at container boot, not at install). Pin ^1.0 and commit composer.lock.
  2. Run php artisan filament:assets after install (and in your deploy pipeline). Since v1.0.1 the stylesheet is published as a browser-cached Filament asset; if it is not published the package inlines a fallback so it still works out of the box, but you lose the caching.
  3. Read the README gallery first, then open src/Widgets/ in vendor/ — with 15 widgets and a "typed API", the class signatures are the real documentation. Skim the test suite (tests/) for the canonical constructor/getData() calls; it is usually more accurate than prose for a young package.
  4. Register widgets in your PanelProvider:
->widgets([
    \LaBoiteACode\FilamentDashboardWidgets\Widgets\MetricWidget::class,
    \LaBoiteACode\FilamentDashboardWidgets\Widgets\GoalWidget::class,
])
  1. First use case: pick one screen you already own and replace a hand-rolled StatsOverviewWidget KPI row with the package's metric + goal widgets. As of v1.0.1 the cards use native Filament surface/ring/shadow/type scale, so the comparison is now purely about what the widget shows, not how it looks — which is the right basis for keeping or dropping a dependency. About 20 minutes.
  2. If the panel already has widgets, you may need to publish/register the plugin instance (->plugin(...)) for config or asset publishing — check whether the package ships a Plugin class before wiring it manually.

Implementation Patterns

Panel-level vs. resource-level. Use panel-level registration for global KPIs (MRR, active users, churn). For per-record dashboards, return widgets from getHeaderWidgets() / getFooterWidgets() on a Resource\Pages\ListRecords or a custom Page — this keeps the same widget class reusable across contexts because most of these widgets are configured via static properties, not constructor args.

Centralize configuration in subclasses. With 15 widget types and a consistent API, the dominant pattern is thin subclasses:

class RevenueMetric extends MetricWidget
{
    protected static ?string $heading = 'MRR';
    protected static int|string|array $columnSpan = ['default' => 1, 'md' => 1, 'xl' => 1];
}

That keeps panel providers readable and gives you a single place to patch when the upstream API changes — which matters given the adoption level.

Keep the query inside your code. Do not let a widget infer scope from the model. Wrap data access behind a service or query object and have the widget call it, so tenant scoping, withoutGlobalScopes, and permission checks live in one auditable place rather than inside vendor configuration callbacks.

Mix with native widgets deliberately. v1.0.1 narrowed the gap further: the package's cards now match Filament's native surface, ring, shadow, type scale and focus ring, and hover-lift on clickable cards is gone. So visual polish is no longer a reason to pick this over StatsOverviewWidget — use the package for the shapes Filament doesn't ship (funnel, bullet, variance, segment bar, usage, timeline) and use core widgets for anything you need to debug frequently. This minimizes your exposure to the package's churn.

Let it format numbers. Number and percentage rendering follows the application locale (1 234,5 / 25 % in fr). Do not pre-format values with number_format() inside getData() or bake units into $heading — you will double-format and produce 25 % %, and you will hard-code the wrong separator for non-English panels.

Live data. If a widget polls (protected static ?string $pollingInterval), pair it with a cached aggregate (Cache::remember, 60s) rather than a raw count()/sum() on every tick. Five polling widgets on a busy dashboard will otherwise dominate query time.

Recent items / detail lists are the highest-leverage widgets in day-to-day use: they turn a static dashboard into a triage surface. Wire row URLs to your resource view/edit pages so clicking through lands in the admin panel rather than a dead end. Since clickable cards no longer lift on hover, make sure the link affordance is obvious in your copy/labels — the focus ring is there for keyboard users, but the mouse cue is subtler now.

Testing. Widgets are Livewire components; Livewire::test(YourWidget::class)->assertOk() plus an assertion on rendered content catches the most common failure (an empty dataset throwing inside a formatting helper) without needing browser tests. If you have locale-sensitive assertions, set the locale explicitly in the test rather than relying on the suite default.

Gotchas and Tips

  • Adoption risk is real. 7 stars, 0 dependents, one maintainer. The 1.0.1 maintenance release is a good sign, but MIT licensing means you can vendor or fork it into app/Filament/Widgets/ if it goes stale — do that for anything business-critical, and only depend on Packagist for cosmetic widgets.
  • Pin the version. Add "laboiteacode/filament-dashboard-widgets": "^1.0" and commit composer.lock. A Filament v4 upgrade cycle will break widget base classes, and a solo-maintainer package may lag weeks behind.
  • Verify Filament compatibility before upgrading Filament. Cross-check the package's composer.json require block against your target Filament version; the release cadence suggests it tracks closely, but don't assume.
  • Colour setters now whitelist their input. v1.0.1 restricts color() / badgeColor() values to [a-zA-Z0-9_-], matching Filament's own colour classes. If you pass anything dynamic — a hex, rgb(...), or a slug containing . or / — it will no longer render as before. Normalise to a Filament palette name (success, warning, danger, …) or map untrusted values to a fixed allowlist in your own code. This closes a CSS-declaration injection path, not an XSS hole (Blade escaping already held), so it is a hardening change rather than an incident.
  • Published views opt you out of the new styling. If you published the package views, they keep working, but they will not pick up the native-Filament markup or the cached-asset integration. UPGRADING.md lists two optional markup changes per release; apply them or accept visual drift.
  • Empty-state behavior. Every widget type here aggregates data. Confirm each renders gracefully with zero rows — this is the single most common post-deploy bug (division by zero in goal/variance/usage progress, empty chart series).
  • Date ranges and timezone. Trend/timeline/variance widgets usually take a period. Make the range explicit in $heading or a description; otherwise users will read a rolling 30-day number as "this month". Set the range in app timezone, not UTC, or your "today" boundary will be wrong for non-UTC tenants. Numbers are localised, dates are up to you.
  • Multi-tenancy. If you use Filament's tenancy, double-check that widget queries go through your tenancy scope. Vendor widgets sometimes query models directly and bypass global scopes.
  • Column span is responsive. Filament accepts ['default' => ..., 'md' => ..., 'xl' => ...]. A widget that looks right on desktop can collapse badly on tablet; test with the panel's responsive preview.
  • Widget ordering. Use protected static ?int $sort and remember panel-level ->widgets([...]) order and $sort can disagree. Pick one.
  • Style overrides. With matching native styling, overriding Blade views or emitting custom CSS now costs you both the parity and the cached stylesheet for no visual gain. Prefer the config/theme hooks it exposes, and drop the widget if it needs surgery.
  • Component discovery cache. After adding widgets, php artisan filament:clear-cached-components (and optimize:clear in prod) if a new widget doesn't appear. In production, run filament:cache-components and filament:assets as part of deploy.
  • Extension point of last resort. Every widget is a class — subclass and override the data method rather than copying the Blade view. That keeps upstream style fixes (including the 1.0.1 locale and styling work) flowing while you control the query.
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.
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table