devletes/filament-progress-bar
Reusable progress bar components for Filament 5 tables and infolists. Shared API for columns/entries, built-in success/warning/danger thresholds (ascending/descending) or custom state maps, multiple sizes and text positions, dark-mode aware styling, and proper progressbar semantics.
Installation:
composer require devletes/filament-progress-bar
php artisan filament:assets
No additional Tailwind configuration is needed—the package includes its own stylesheet.
First Use Case (Table Column):
use Devletes\FilamentProgressBar\Tables\Columns\ProgressBarColumn;
ProgressBarColumn::make('used')
->maxValue(fn ($record) => $record->quota)
->showProgressValue()
->showPercentage();
First Use Case (Infolist Entry):
use Devletes\FilamentProgressBar\Infolists\Components\ProgressBarEntry;
ProgressBarEntry::make('leave_progress')
->label('Sick Leave')
->getStateUsing(fn ($record) => [
'progress' => $record->leave_used,
'total' => $record->leave_total,
]);
ProgressBarColumn for tables and ProgressBarEntry for infolists.Data Provisioning:
maxValue() for numeric states (e.g., ->maxValue(fn ($record) => $record->quota)).state() or getStateUsing() for structured arrays (e.g., ['progress' => 50, 'total' => 100]).progress, current, used for current value; total, max for total).Threshold Configuration:
warningThreshold() and dangerThreshold().
->warningThreshold(70)
->dangerThreshold(90)
->thresholdDirection('descending')
->warningThreshold(30)
->dangerThreshold(10)
->thresholds([80 => 'success', 60 => 'warning', 0 => 'danger'])
Styling:
size('sm' | 'md' | 'lg') (default: sm).textPosition('inside' | 'outside') (default: inside).->borderRadius('4px')).showPercentage(), hideProgressValue(), etc.Dynamic Behavior:
->successColor(fn ($record) => $record->is_priority ? '#7c3aed' : null)).$record, $percentage, $status, etc.role="progressbar" for screen readers.| Pattern | Example |
|---|---|
| Battery/Fuel | ->thresholdDirection('descending')->warningThreshold(30) |
| Multi-State Score | ->thresholds([90 => 'success', 70 => 'info', 0 => 'danger']) |
| Squared Bars | ->borderRadius('4px')->size('md') |
| Compact Column | ->hideProgressValue()->hidePercentage() |
| Dynamic Colors | ->successColor(fn ($record) => $record->is_priority ? '#7c3aed' : null) |
Threshold Direction:
thresholdDirection('descending') for "low is bad" metrics (e.g., battery) will invert the thresholds.Zero Total Handling:
total is null or 0, the percentage resolves to 0% (no error).total in your closure if needed:
->state(fn ($record) => [
'progress' => $record->used,
'total' => $record->quota ?? 1, // Ensure non-zero
])
CSS Injection:
borderRadius() silently drops invalid CSS (e.g., ;, <, {). Stick to standard values like 4px or 0.5rem.null to reset to default pill shape.Closure Parameters:
$percentage and $status after resolution. Use these for dynamic logic:
->dangerLabel(fn (int $percentage) => "Critical ($percentage%)")
Infolist vs. Table:
->successLabel('On track')), but table columns intentionally omit them for compactness.Inspect State:
->state(fn ($record) => {
$state = ['progress' => $record->used, 'total' => $record->quota];
\Log::debug('ProgressBar state:', $state);
return $state;
})
Threshold Debugging:
->dangerLabel(fn (int $percentage) => "Debug: $percentage%")
Color Overrides:
var(--primary-500)) are defined in your panel.statusColors().Performance:
->maxValue(fn ($record) => expensiveCalc($record))). Cache results if needed.Custom Statuses:
->colors([...]) in your panel config:
FilamentPanel::make()->colors([
'info' => '#3b82f6',
]);
->thresholds([60 => 'info', 0 => 'danger'])
Global Defaults:
ProgressBarColumn::macro('defaultWarningThreshold', fn () => 80);
Dark Mode Tweaks:
/* resources/css/filament/progress-bar.css */
.dark .filament-progress-bar-fill {
background-color: rgba(255, 255, 255, 0.1);
}
Localization:
->dangerLabel(fn () => __("Only {current} left", ['current' => $current]))
trait UsesProgressBar {
protected function batteryProgressBar(string $field): ProgressBarColumn {
return ProgressBarColumn::make($field)
->thresholdDirection('descending')
->warningThreshold(30)
->dangerThreshold(10);
}
}
->getStateUsing() for predictable test data:
$column->getStateUsing(fn () => ['progress' => 50, 'total' => 100]);
->extraAttributes(['aria-label' => 'Usage progress'])
How can I help you explore Laravel packages today?