Filament color is not reactive

At first, i found out the badge color inside table doesn't update alone with the text. For example, when the status value is changed from activated to deactivated, the text inside badge will update to the getLabel() value, however, the color of the badge stay the same. I thought it was an issue relating to badge. The text column code:
Tables\Columns\TextColumn::make('status'),
Tables\Columns\TextColumn::make('status'),
The enum status code:
<?php

namespace App\Enums;

use Filament\Support\Contracts\HasColor;
use Filament\Support\Contracts\HasLabel;

enum UserStatus: string implements HasLabel, HasColor
{
case Activated = 'activated';
case Deactivated = 'deactivated';

public function getLabel(): ?string
{
return match ($this) {
self::Activated => 'activated',
self::Deactivated => 'deactivated',
};
}

public function getColor(): array|string
{
return match ($this) {
self::Activated => 'success',
self::Deactivated => 'danger',
};
}
}
<?php

namespace App\Enums;

use Filament\Support\Contracts\HasColor;
use Filament\Support\Contracts\HasLabel;

enum UserStatus: string implements HasLabel, HasColor
{
case Activated = 'activated';
case Deactivated = 'deactivated';

public function getLabel(): ?string
{
return match ($this) {
self::Activated => 'activated',
self::Deactivated => 'deactivated',
};
}

public function getColor(): array|string
{
return match ($this) {
self::Activated => 'success',
self::Deactivated => 'danger',
};
}
}
Upon some more troubleshooting, i realized all colors are not reactive. Even when i have a method that dynamically return filament action, lets say ban or unban action, which has danger or success color. The dynamic action will update based on user status, however, the color of the action itself doesnt change.
7 Replies
LeandroFerreira
LeandroFerreira2mo ago
Are you using something like this in the action?
...
->color(fn (YourModel $record) => $record->is_active ? 'success' : 'warning')
...
->color(fn (YourModel $record) => $record->is_active ? 'success' : 'warning')
Xiaohou
XiaohouOP2mo ago
Actions\ActionGroup::make([
...
$this->getUpdateStatusAction(),
]);

public function getUpdateStatusAction()
{
if ($this->record->status != UserStatus::Banned) {
return Actions\Action::make('ban_user')
->color('danger')
->action(function (User $record, array $data, $action) {
...
});
} else {
return Actions\Action::make('unban_user')
->color('success')
->action(function (User $record, array $data, $action) {
...
});
}
}
Actions\ActionGroup::make([
...
$this->getUpdateStatusAction(),
]);

public function getUpdateStatusAction()
{
if ($this->record->status != UserStatus::Banned) {
return Actions\Action::make('ban_user')
->color('danger')
->action(function (User $record, array $data, $action) {
...
});
} else {
return Actions\Action::make('unban_user')
->color('success')
->action(function (User $record, array $data, $action) {
...
});
}
}
The color will render correctly initially, both badge and action text label, icon works fine, its just the color doesn't update unless the whole page refresh.
Dennis Koch
Dennis Koch2mo ago
Try using ->visible()/->hidden() on the action instead of returning different actiosn
LeandroFerreira
LeandroFerreira2mo ago
Actions\Action::make('toggle')
->label(fn (YourModel $record) => $record->status === 'banned' ? 'unban' : 'ban')
->color(fn (YourModel $record) => $record->status === 'banned' ? 'danger' : 'success')
->action(fn (YourModel $record) => $record->update(['status' => ...)
Actions\Action::make('toggle')
->label(fn (YourModel $record) => $record->status === 'banned' ? 'unban' : 'ban')
->color(fn (YourModel $record) => $record->status === 'banned' ? 'danger' : 'success')
->action(fn (YourModel $record) => $record->update(['status' => ...)
Xiaohou
XiaohouOP2mo ago
Actions\Action::make('toggle')
->label(fn(User $record) => $record->status === UserStatus::Banned ? 'unban' : 'ban')
->color(fn(User $record) => $record->status === UserStatus::Banned ? 'danger' : 'success')
->action(fn(User $record) => $record->status === UserStatus::Banned ? UserService::unban($record) : UserService::ban($record)),
Actions\Action::make('toggle')
->label(fn(User $record) => $record->status === UserStatus::Banned ? 'unban' : 'ban')
->color(fn(User $record) => $record->status === UserStatus::Banned ? 'danger' : 'success')
->action(fn(User $record) => $record->status === UserStatus::Banned ? UserService::unban($record) : UserService::ban($record)),
I have tried toggle, same thing happend. The ban and unban label will update according to user status, and the badge label on table and infolist will update too, but none of the color update unless the page refresh.
Dennis Koch
Dennis Koch2mo ago
Are you on the latest versions of Filament and Livewire?
Xiaohou
XiaohouOP2mo ago
Actions\Action::make('ban')
->label('ban')
->color('danger')
->visible(fn(User $record) => $record->status !== UserStatus::Banned)
->action(fn(User $record) => UserService::ban($record)),

Actions\Action::make('unban')
->label('uban')
->color('success')
->visible(fn(User $record) => $record->status === UserStatus::Banned)
->action(fn(User $record) => UserService::unban($record)),
Actions\Action::make('ban')
->label('ban')
->color('danger')
->visible(fn(User $record) => $record->status !== UserStatus::Banned)
->action(fn(User $record) => UserService::ban($record)),

Actions\Action::make('unban')
->label('uban')
->color('success')
->visible(fn(User $record) => $record->status === UserStatus::Banned)
->action(fn(User $record) => UserService::unban($record)),
Even hard coding to color into action result the same, action will render correct label, the color doesn't change. For example, when ban button (red color) is triggered, now it updates and should render unban button (green color), it does update the text to unban, but color is still red. After a page refresh, it correctlly display the color to green. Yes, i'm on "filament/filament": "^3.2", and livewire v3.5.12 I don't know if this will help, but when the button rerender, everything inside <button> tag updates, excepts for style, which of course decide the color.
<button style="--c-400:var(--success-400);--c-500:var(--success-500);--c-600:var(--success-600);" class="fi-btn relative grid-flow-col items-center justify-center font-semibold outline-none transition duration-75 focus-visible:ring-2 rounded-lg fi-color-custom fi-btn-color-success fi-color-success fi-size-md fi-btn-size-md gap-1.5 px-3 py-2 text-sm inline-grid shadow-sm bg-custom-600 text-white hover:bg-custom-500 focus-visible:ring-custom-500/50 dark:bg-custom-500 dark:hover:bg-custom-400 dark:focus-visible:ring-custom-400/50 fi-ac-action fi-ac-btn-action" type="button" wire:loading.attr="disabled" wire:click="mountAction('unban')">
<button style="--c-400:var(--success-400);--c-500:var(--success-500);--c-600:var(--success-600);" class="fi-btn relative grid-flow-col items-center justify-center font-semibold outline-none transition duration-75 focus-visible:ring-2 rounded-lg fi-color-custom fi-btn-color-success fi-color-success fi-size-md fi-btn-size-md gap-1.5 px-3 py-2 text-sm inline-grid shadow-sm bg-custom-600 text-white hover:bg-custom-500 focus-visible:ring-custom-500/50 dark:bg-custom-500 dark:hover:bg-custom-400 dark:focus-visible:ring-custom-400/50 fi-ac-action fi-ac-btn-action" type="button" wire:loading.attr="disabled" wire:click="mountAction('unban')">
I've run composer update on both livewire an filament, still not sure where exactlly the issue were, but it seems to fixed. Thanks!
Want results from more Discord servers?
Add your server