
Learn how to use enums in Laravel Filament to simplify your code, improve validation, and manage fixed values efficiently. This complete guide covers practical examples, best practices, and tips to boost your Laravel development.
Learn more about enums here.
Introduction to Enums in Laravel Filament
In many Laravel apps, we often use strings like 'pending'
or 'approved'
to represent statuses. The problem? It’s easy to mistype and hard to manage.
Enums solve this by letting you define a fixed set of values in a clean, readable way. With PHP 8.1+, enums are built-in, you can use them directly in forms, tables, route and validation — making your code safer and smarter.
Creating Enums in Laravel
Creating an enum in laravel is super easy. For example:
enum OrderStatus: string {
case Pending = 'pending';
case Shipping = "shipping";
case Approved = 'approved';
case Delivered = "delivered";
}
Now instead of using string everywhere, you use OrderStatus::Pending, which avoids mistake and also improves readability. The above enum and database type enum are completely different.
You may also have seen the real world projects where the roles are based on enum.
enum UserRole: string{
case User = "user"; // or int like 0
case Admin = "admin"; // or int like 1
case SuperAdmin = "super_admin"; // or int like 2
}
Enum Casting
Laravel makes it easy to cast model attributes to enums. This means your database values automatically convert to enum instances when you access them, and back to strings (or integers) when saving.
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
protected $casts = [
'status' => OrderStatus::class, // cast 'status' column to enum
];
}
Now, we can use them directly:
$order = Order::find(1);
if ($order->status === OrderStatus::Pending) {
$order->status = OrderStatus::Approved;
$order->save();
}
Enum Labels
Lets first look, how we can change the enum label without changing the key.
use Filament\Support\Contracts\HasLabel;
enum OrderStatus: string implements HasLabel
{
case Pending = 'pending';
case Shipping = "shipping";
case Approved = 'approved';
case Delivered = "delivered";
public function getLabel(): ?string
{
return $this->name;
// or you can customize the labels below..
return match ($this) {
self::Pending => 'Pending',
self::Shipping => 'Shipping',
self::Approved => 'Approved',
self::Delivered => 'Delivered',
};
}
}
So, note when we use HasLabel, the enum value will be its key and the label will be its value.
Enum in Filament Form
Lets see, how we can show those enums in our filament form.
use Filament\Forms\Components\CheckboxList;
use Filament\Forms\Components\Radio;
use Filament\Forms\Components\Select;
use Filament\Tables\Columns\SelectColumn;
use Filament\Tables\Filters\SelectFilter;
Select::make('status')
->options(OrderStatus::class)
CheckboxList::make('status')
->options(OrderStatus::class)
Radio::make('status')
->options(OrderStatus::class)
SelectColumn::make('status')
->options(OrderStatus::class)
SelectFilter::make('status')
->options(OrderStatus::class)
Enum in TextColumn
If you have cast your column as Enums in model, Filament will automatically use the HasLabel to display the label name instead of its raw value.
Enum Colors
Lets discuss, how we can show different colors for our enums. For that we need to implment HasColor.
use Filament\Support\Contracts\HasColor;
enum OrderStatus: string implements HasColor
{
case Pending = 'pending';
case Shipping = "shipping";
case Approved = 'approved';
case Delivered = "delivered";
public function getColor(): string | array | null
{
return match ($this) {
self::Pending => 'warning',
self::Shipping => 'success',
self::Approved => 'info',
self::Delivered => 'gray',
};
}
}
Now, when we use badge() in our TextColumn, it will automatically use the interface and display label in that color.
Enum Icons
Now, lets look at how we can display icons . For that we need to implement HasIcon
use Filament\Support\Contracts\HasIcon;
enum Status: string implements HasIcon
{
case Pending = 'pending';
case Shipping = "shipping";
case Approved = 'approved';
case Delivered = "delivered";
public function getIcon(): ?string
{
return match ($this) {
self::Pending => 'heroicon-m-clock',
self::Shipping => 'heroicon-m-truck',
self::Approved => 'heroicon-m-check-circle',
self::Delivered => 'heroicon-m-gift'
};
}
}
Now, when we use badge() in our TextColumn, it will automatically use the interface and display label with icon.
Enum Description
Lets also check how we can show the description. For this we need to implement HasDescription.
use Filament\Support\Contracts\HasDescription;
use Filament\Support\Contracts\HasLabel;
enum Status: string implements HasLabel, HasDescription
{
case Pending = 'pending';
case Shipping = 'shipping';
case Approved = 'approved';
case Delivered = 'delivered';
public function getLabel(): ?string
{
return match ($this) {
self::Pending => 'Pending',
self::Shipping => 'Shipping',
self::Approved => 'Approved',
self::Delivered => 'Delivered',
};
}
public function getDescription(): ?string
{
return match ($this) {
self::Pending => 'The order has been placed and is awaiting processing.',
self::Shipping => 'The order is on the way to the customer.',
self::Approved => 'The order has been confirmed and approved for shipping.',
self::Delivered => 'The order has been successfully delivered to the customer.',
};
}
}
The above description is applied to Checkbox and Radio. Read more in official docs to implement Enums in Laravel Filament.