Tables\Columns\IconColumns use a fn call to alternate icons depending on value but uses LIKE, would like to use a LIKE or CONTAINS

I am using Filament admin panel in Laravel. Filament v3.3.14, Laravel 12x

I have found this great little function to alternate my icons depending on the value (0 or 1).

             Tables\Columns\IconColumn::make('paid')
                ->icon(fn (string $state): string => match ($state) {
                    '1' => 'heroicon-o-check-circle',
                    '0' => 'heroicon-o-x-circle',
                })

I would like to use it on a different function with text values as below:

Tables\Columns\IconColumn::make('test_value')
                ->icon(fn (string $state): string => match ($state) {
                    'high' => 'heroicon-o-check-circle',
                    'medium' => 'heroicon-o-x-circle',
                    'low' => 'heroicon-o-x-circle',
                    'extreme' => 'heroicon-o-x-circle',
                })

But the test_value will often end up with values like “Medium (12)” or “Extreme (25)”.

Is there a way to loosen up the string match? Similar to a LIKE or CONTAINS?

I cannot locate any direction out in the wide yonder internet. Would greatly appreciate if you have any suggestions.

Yes, you’re on the right track — but match() in PHP is strict and doesn’t support partial matches like contains, LIKE, or regex. Since your values like "Medium (12)" or "Extreme (25)" are variable but follow a pattern, you’ll want to use str_contains() or str_starts_with() in your closure instead of match().

Solution: Use str_contains() Instead of match()

use Filament\Tables\Columns\IconColumn;
use Illuminate\Support\Str; // Optional if using Laravel helpers

IconColumn::make('test_value')
    ->icon(function (string $state): string {
        $lowerState = strtolower($state);

        if (str_contains($lowerState, 'high')) {
            return 'heroicon-o-check-circle';
        } elseif (str_contains($lowerState, 'medium')) {
            return 'heroicon-o-x-circle';
        } elseif (str_contains($lowerState, 'low')) {
            return 'heroicon-o-x-circle';
        } elseif (str_contains($lowerState, 'extreme')) {
            return 'heroicon-o-x-circle';
        }

        return 'heroicon-o-question-mark-circle'; // fallback icon
    })

Why This Works

  • str_contains() is case-sensitive by default, but you can normalize with strtolower() or use Laravel’s Str::contains() which is case-insensitive.
  • This is more flexible than match() when working with dynamic or partial strings like "Medium (12)".

Bonus: Case-Insensitive Version with Laravel’s Str Helper

use Illuminate\Support\Str;

IconColumn::make('test_value')
    ->icon(fn (string $state): string => match (true) {
        Str::contains($state, 'high') => 'heroicon-o-check-circle',
        Str::contains($state, 'medium') => 'heroicon-o-x-circle',
        Str::contains($state, 'low') => 'heroicon-o-x-circle',
        Str::contains($state, 'extreme') => 'heroicon-o-x-circle',
        default => 'heroicon-o-question-mark-circle',
    })