Skip to content
OpenCloseEsc
Tips
  • Laravel
  • enums
  • php

One details() match instead of label(), color() and hint()

Put everything the UI needs about a case in one array per case, and read label() and meta() from it; adding a case means one new arm, and match still throws when it is missing.

1 min read

Three match blocks per enum means three places to forget a new case. Keep one.

enum UserStatus: string
{
    use EnumHelpers;
 
    case Active = 'active';
    case Inactive = 'inactive';
    case Blocked = 'blocked';
 
    public function details(): array
    {
        return match ($this) {
            self::Active => ['color' => 'green', 'hint' => 'Can log in and work.'],
            self::Inactive => ['color' => 'gray', 'hint' => 'Hidden from assignment lists.'],
            self::Blocked => ['color' => 'red', 'hint' => 'Cannot log in.'],
        };
    }
}

In the trait, label() returns details()['label'] ?? Str::headline($this->name), so SuperAdmin reads "Super Admin" without writing it, and meta() is Arr::except($this->details(), 'label'). A case only writes what differs from the default. toArray() sends {value, label, meta} to the frontend; cast meta to (object) or an empty array arrives in JavaScript as [].