TextColumn уміє форматувати значення без зміни самих даних.
use Filament\Tables\Columns\TextColumn;
TextColumn::make('status')
->badge()
->color(fn (string $state): string => match ($state) {
'draft' => 'gray',
'paid' => 'success',
'refunded' => 'danger',
default => 'warning',
}),
TextColumn::make('total')
->money('UAH'), // 1 250,00 ₴ з урахуванням локалі
TextColumn::make('price_cents')
->money('UAH', divideBy: 100), // ціни, що зберігаються в копійках
TextColumn::make('created_at')
->dateTime('d.m.Y H:i'),
TextColumn::make('last_login_at')
->since(), // «3 години тому»
TextColumn::make('title')
->description(fn (Post $record): string => $record->excerpt)
->limit(60),
Найчистіше рішення для статусів - enum. Якщо атрибут моделі кастується в enum, що реалізує HasLabel і HasColor, колонка з badge() сама бере підпис і колір:
use Filament\Support\Contracts\HasColor;
use Filament\Support\Contracts\HasLabel;
enum OrderStatus: string implements HasLabel, HasColor
{
case New = 'new';
case Paid = 'paid';
public function getLabel(): string
{
return match ($this) {
self::New => 'Нове',
self::Paid => 'Оплачено',
};
}
public function getColor(): string
{
return match ($this) {
self::New => 'warning',
self::Paid => 'success',
};
}
}
Той самий enum потім працює в SelectFilter::make('status')->options(OrderStatus::class) і в полях форми. Підписи статусів живуть в одному місці, а не розкидані по match у різних ресурсах.
Пастки:
formatStateUsing()змінює лише відображення: пошук і сортування працюють по сирому значенню з бази;html()чиmarkdown()санітизують вміст, алеformatStateUsing(), що повертаєHtmlString, - ні: так легко вивести неекрановані дані користувача.