Filament Dashboard Widgets
Construisez des tableaux de bord Filament cohérents avec quinze widgets prêts à étendre : métriques, objectifs, tendances, funnels, quotas, comparaisons et plus.
Compatibilité
| PHP | ^8.3 |
|---|---|
| Laravel | ^12.0|^13.0 |
| Filament | ^4.12|^5.7.1 |
| Version | v1.0.0 |
| Licence | MIT |
Installation
composer require laboiteacode/filament-dashboard-widgets
Présentation
Filament fournit d’excellentes primitives, mais les mêmes besoins reviennent d’un back-office à l’autre : une carte KPI, la progression vers un objectif, une répartition, une liste récente ou un quota consommé. Filament Dashboard Widgets rassemble ces motifs dans quinze widgets cohérents, prêts à être étendus par l’application.
Chaque widget sépare la présentation des données. L’application crée une petite classe, renvoie un objet typé et conserve la maîtrise complète de ses requêtes. Le package ne devine pas le métier et n’exécute aucune requête à votre place.
Quinze briques pour les dashboards métier
La collection couvre les indicateurs, objectifs, éléments récents, répartitions, tendances, compositions, listes de détails, bullet graphs, funnels, timelines, écarts, barres segmentées, limites d’usage, comparaisons et cartes d’action.
Ces widgets répondent aux besoins fréquents des SaaS, CRM et outils internes :
- suivre un MRR et son évolution avec une sparkline ;
- mesurer l’avancement vers un objectif et son échéance ;
- présenter un funnel de conversion et la perte entre chaque étape ;
- comparer plusieurs séries temporelles ;
- afficher la consommation de sièges, stockage ou appels API ;
- résumer une fiche client ou les derniers événements importants.
Une API uniforme et typée
Les données sont portées par des objets fluents comme Metric, Goal, RecentItem, FunnelStage, UsageLimit ou ChartSeries. Valeurs statiques et closures calculées au rendu utilisent le même contrat. Les badges, icônes, liens, boutons et états vides restent des composants Filament natifs.
La palette est résolue depuis les couleurs enregistrées sur le panel. Les quinze widgets suivent donc automatiquement la couleur d’accent, le mode sombre et les thèmes personnalisés. Le CSS est léger, injecté automatiquement et ne demande aucune étape de build front-end.
Pensé pour rester accessible
Le HTML est structuré, les lignes cliquables disposent d’un focus clavier visible, les libellés nécessaires aux lecteurs d’écran sont inclus et les animations respectent prefers-reduced-motion. Les contrastes ont été prévus pour les thèmes clairs et sombres.
La collection est open source sous licence MIT, compatible avec Filament 4.12+ et 5.7.1+, et livrée avec les traductions françaises et anglaises.
Documentation
Installation
Installez la collection avec Composer :
composer require laboiteacode/filament-dashboard-widgets
Enregistrez le plugin sur le panel :
use LaBoiteACode\FilamentDashboardWidgets\FilamentDashboardWidgetsPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
FilamentDashboardWidgetsPlugin::make(),
]);
}
Les ressources fonctionnent sans publication ni build front-end. La configuration et les traductions restent publiables si nécessaire :
php artisan vendor:publish --tag="filament-dashboard-widgets-config"
php artisan vendor:publish --tag="filament-dashboard-widgets-translations"
Créer un widget
Chaque widget fourni est une classe abstraite. Étendez-la, fournissez son objet de données, puis enregistrez la classe obtenue comme n’importe quel widget Filament :
use Illuminate\Support\Number;
use LaBoiteACode\FilamentDashboardWidgets\Data\Metric;
use LaBoiteACode\FilamentDashboardWidgets\Widgets\MetricWidget;
class MonthlyRevenueWidget extends MetricWidget
{
protected function getMetric(): Metric
{
return Metric::make('Revenu mensuel', 24_850)
->formatUsing(fn (int $value) => Number::currency($value, 'EUR'))
->description('Par rapport au mois précédent')
->trend(12.4)
->icon('heroicon-o-banknotes')
->color('success')
->sparkline([12, 14, 13, 18, 20, 19, 24])
->url(route('filament.admin.resources.orders.index'));
}
}
Enregistrez ensuite vos classes concrètes :
protected function getHeaderWidgets(): array
{
return [
MonthlyRevenueWidget::class,
ConversionGoalWidget::class,
CustomerBreakdownWidget::class,
];
}
Les quinze widgets
| Widget | Usage |
|---|---|
MetricWidget |
KPI, tendance, sparkline et lien |
GoalProgressWidget |
Progression vers une cible, reste et échéance |
RecentItemsWidget |
Liste courte avec avatar, badge, métadonnées et action |
BreakdownWidget |
Répartition proportionnelle et tri optionnel |
TrendWidget |
Série temporelle avec valeur résumée et comparaison |
CompositionWidget |
Diagramme doughnut, pie ou polar area |
DetailListWidget |
Liste sémantique clé-valeur pour une fiche |
BulletWidget |
Valeur face à une cible, des seuils et un benchmark |
FunnelWidget |
Étapes de conversion, taux intermédiaires et taux global |
TimelineWidget |
Flux d’événements avec regroupement par jour |
VarianceWidget |
Écarts positifs et négatifs autour d’un axe zéro |
SegmentBarWidget |
Répartition d’un total dans une barre empilée |
UsageLimitsWidget |
Consommation de quotas et seuil d’avertissement |
ComparisonChartWidget |
Plusieurs séries sur des libellés partagés |
CardWidget |
Carte flexible : stat, icône, contenu ou appel à l’action |
Les widgets de graphique s’appuient sur l’intégration Chart.js native de Filament. Aucun JavaScript supplémentaire n’est livré par le package.
Exemple d’objectif
use LaBoiteACode\FilamentDashboardWidgets\Data\Goal;
use LaBoiteACode\FilamentDashboardWidgets\Widgets\GoalProgressWidget;
class ConversionGoalWidget extends GoalProgressWidget
{
protected function getGoal(): Goal
{
return Goal::make('Objectif mensuel', current: 72_500, target: 100_000)
->deadline(now()->endOfMonth())
->color('primary')
->showRemaining()
->showPercentage();
}
}
Exemple de funnel
use LaBoiteACode\FilamentDashboardWidgets\Data\FunnelStage;
use LaBoiteACode\FilamentDashboardWidgets\Widgets\FunnelWidget;
class SignupFunnelWidget extends FunnelWidget
{
protected function getStages(): array
{
return [
FunnelStage::make('Visiteurs', 4_200),
FunnelStage::make('Inscriptions', 1_280),
FunnelStage::make('Activés', 640),
FunnelStage::make('Payants', 210)->color('success'),
];
}
}
Personnalisation
Les options communes restent identiques d’un objet à l’autre :
->color('primary')
->icon('heroicon-o-chart-bar')
->url('/admin/orders')
->openUrlInNewTab()
Les titres et états vides se personnalisent dans la classe du widget. La largeur utilise directement le columnSpan Filament :
protected ?string $heading = 'Commandes récentes';
protected int | string | array $columnSpan = 2;
Les actions sont représentées par WidgetAction et reprennent les boutons, icônes et liens Filament.
Thème et accessibilité
Les couleurs sont résolues depuis celles enregistrées sur le panel. Une couleur personnalisée, le mode sombre ou un changement de couleur primaire s’appliquent à l’ensemble des widgets.
Les composants utilisent des titres structurés, des libellés pour lecteurs d’écran, des styles de focus clavier et des contrastes WCAG AA. Les effets interactifs sont réduits lorsque l’utilisateur active prefers-reduced-motion.
Les valeurs sont échappées par défaut. Le package n’exécute aucune requête : l’application décide entièrement comment calculer et mettre en cache ses données.
Polling et cache
Le polling est désactivé par défaut. Définissez un intervalle global dans la configuration ou surchargez-le sur un widget :
class LiveVisitorsWidget extends MetricWidget
{
protected ?string $pollingInterval = '10s';
}
Le package ne met pas les données métier en cache automatiquement. Utilisez le cache Laravel autour du calcul :
protected function getMetric(): Metric
{
return Cache::remember(
'dashboard.monthly-revenue',
now()->addMinutes(5),
fn () => Metric::make('Revenu mensuel', $this->computeRevenue()),
);
}
Traductions
Les textes partagés sont fournis en français et en anglais : actions, valeurs restantes, objectif atteint, états vides et autres libellés du composant.
Publiez les traductions pour les adapter :
php artisan vendor:publish --tag="filament-dashboard-widgets-translations"
Les titres et données métier viennent toujours de l’application.