Widgets
A Widget is a statistics card on the panel dashboard: a value, computed live on every request, with optional color, icon and description. They are registered on the Panel, not on a Resource:
php
$panels->register(
Panel::make('admin')
->widgets([
Widget::make('total_posts')
->label('Total Posts')
->value(fn (): int => Post::count())
->description('All time')
->icon('document-text'),
Widget::make('published_posts')
->label('Published Posts')
->value(fn (): int => Post::where('is_published', true)->count())
->color('success'),
])
);API
| Method | Description |
|---|---|
make(string $name) | Internal identifier of the widget. |
label(string|Closure $label) | Title of the card. By default, Str::headline($name). A closure lets you translate it. |
value(Closure $callback) | Computes the value shown. It runs on every dashboard request, and there is no cache by default. |
color(string|Closure $color) | Color of the card. As a closure, it receives the already computed value (fn (mixed $value) => ...). |
description(string|Closure $description) | Secondary text under the value. Same rule as color() when it is a closure. |
icon(string $icon) | See the list of available icons in Actions. |
visible(Closure $callback) | If it returns false, the widget is not shown. It is evaluated on every request. |
color() and description() accept a fixed value or a closure that depends on the widget's own value, useful to change the color depending on whether the figure is good or bad without duplicating the logic of value().
The widgets of a Panel all appear together on the dashboard. Those with visible() are filtered per user, and since the closure is evaluated on every request, it can depend on the authenticated user:
php
Widget::make('my_pending')
->label('My pending tasks')
->value(fn (): int => auth()->user()->tasks()->pending()->count())
->visible(fn (): bool => auth()->user()->can('tasks.view'))A widget with a false visible() is also left out of the dashboard API response.