カスタムテーブルカラムを作る——AbstractColumnを継承した独自列表示
カスタムテーブルカラムが必要な場面
標準のTextColumn・ImageColumn・BadgeColumnでは表現しきれないUIが必要になる場合があります。例えばプログレスバー・スター評価・カラーチップ・複合的な情報をコンパクトに表示するカラムなどです。
カスタムカラムを作ることで、テーブル定義のコードを簡潔に保ちながら独自のUI表現が実現できます。
生成コマンドとファイル構成
php artisan make:filament-table-column ProgressBarColumn
生成ファイル:
app/Tables/Columns/ProgressBarColumn.php
resources/views/tables/columns/progress-bar-column.blade.php
Columnクラスの実装
namespace App\Tables\Columns;
use Filament\Tables\Columns\Column;
class ProgressBarColumn extends Column
{
protected string $view = 'tables.columns.progress-bar-column';
// 最大値(デフォルト100)
protected int|float $maxValue = 100;
// 色の閾値設定
protected array $colorThresholds = [];
public function maxValue(int|float $max): static
{
$this->maxValue = $max;
return $this;
}
/**
* 値に応じた色を設定
* 例: ->colorThresholds(['danger' => 30, 'warning' => 70, 'success' => 100])
*/
public function colorThresholds(array $thresholds): static
{
$this->colorThresholds = $thresholds;
return $this;
}
public function getMaxValue(): int|float
{
return $this->maxValue;
}
public function getColorThresholds(): array
{
return $this->colorThresholds;
}
}
Bladeテンプレートの実装
@php
$state = $getState() ?? 0;
$maxValue = $getMaxValue();
$percentage = $maxValue > 0 ? min(100, ($state / $maxValue) * 100) : 0;
$thresholds = $getColorThresholds();
// 閾値から色を決定
$color = 'primary';
foreach ($thresholds as $colorName => $threshold) {
if ($percentage <= $threshold) {
$color = $colorName;
break;
}
}
$colorClasses = match($color) {
'danger' => 'bg-danger-500',
'warning' => 'bg-warning-500',
'success' => 'bg-success-500',
'info' => 'bg-info-500',
default => 'bg-primary-500',
};
@endphp
<div class="w-full min-w-[80px]">
<div class="flex items-center gap-2">
<div class="flex-1 bg-gray-200 dark:bg-gray-700 rounded-full h-2">
<div
class="{{ $colorClasses }} h-2 rounded-full transition-all duration-300"
style="width: {{ $percentage }}%"
></div>
</div>
<span class="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap">
{{ number_format($state) }} / {{ number_format($maxValue) }}
</span>
</div>
</div>
使用例
use App\Tables\Columns\ProgressBarColumn;
public function table(Table $table): Table
{
return $table
->columns([
TextColumn::make('name')
->label('タスク名')
->searchable(),
ProgressBarColumn::make('progress')
->label('進捗')
->maxValue(100)
->colorThresholds([
'danger' => 30,
'warning' => 70,
'success' => 100,
])
->sortable(),
ProgressBarColumn::make('score')
->label('スコア')
->maxValue(1000)
->sortable(),
]);
}
ソートのサポート
カラムが->sortable()に対応するためには、対応するデータベースカラムが存在している必要があります。カスタムカラムでもデフォルトの->sortable()は標準で機能します。
複雑なソートが必要な場合:
ProgressBarColumn::make('progress')
->sortable(query: function (Builder $query, string $direction): Builder {
return $query->orderBy('progress', $direction)
->orderBy('updated_at', $direction);
})
仮想カラム(計算値)への対応
データベースにない計算値を表示したい場合は->state()と組み合わせます。
ProgressBarColumn::make('completion_rate')
->label('完了率')
->state(fn (Project $record): float =>
$record->tasks_total > 0
? ($record->tasks_done / $record->tasks_total) * 100
: 0
)
->maxValue(100)
->colorThresholds(['danger' => 30, 'warning' => 70, 'success' => 100])
コツ・注意点・ハマりポイント
コツ: Bladeテンプレート内では$getState()がnullを返す可能性があるため、常にnullチェックやデフォルト値を設定してください。
注意点: カスタムカラムのBladeは行ごとに繰り返しレンダリングされます。複雑なPHP計算をBlade内に書くとパフォーマンスに影響するため、重い処理はモデルのアクセサやEloquentスコープに移してください。
ハマりポイント: カラムのビューパスはresources/views/からの相対パスをドット記法で指定します。tables/columns/progress-bar-column.blade.phpなら'tables.columns.progress-bar-column'です。パッケージとして公開する場合はビューのネームスペースを設定してください。
まとめ
Columnクラスを継承してBladeテンプレートを実装するだけで、テーブルに独自の列表示を追加できます。プログレスバー・評価スター・カスタムバッジなど、標準カラムでは難しい表現もFluentAPIで直感的に設定できます。