#01 FilamentPHP応用

アクションの仕組み——Table・Form・Header Actions

Actionとは何か

FilamentにおけるActionとは、ユーザーが何らかの処理を起動するための「ボタン」を抽象化したものです。単なるリンクやフォームボタンではなく、確認ダイアログ・モーダルフォーム・処理ロジックをひとつのオブジェクトとしてまとめて定義できます。

Filamentのアクションは以下の3種類の場所に配置できます。

配置場所クラス用途
テーブルの行ごとTableAction各レコードに対する操作
テーブルの複数選択BulkAction選択した複数レコードの一括操作
ページヘッダーAction(HeaderAction)ページ全体に対する操作
フォーム内FormActionフォームの文脈での操作

これらはすべて同じAPIを共有しており、一度使い方を覚えれば横断的に応用できます。

TableActionとBulkActionの違い

TableActionは各行に表示され、特定の1レコードを対象とします。

use Filament\Tables\Actions\Action;

public function table(Table $table): Table
{
    return $table
        ->actions([
            Action::make('publish')
                ->label('公開する')
                ->icon('heroicon-o-globe-alt')
                ->color('success')
                ->action(function (Post $record): void {
                    $record->update(['status' => 'published']);
                }),
        ]);
}

BulkActionはチェックボックスで選択した複数レコードを一括処理します。

use Filament\Tables\Actions\BulkAction;
use Illuminate\Database\Eloquent\Collection;

->bulkActions([
    BulkAction::make('publishAll')
        ->label('選択を公開する')
        ->icon('heroicon-o-check-circle')
        ->action(function (Collection $records): void {
            $records->each->update(['status' => 'published']);
        }),
])

BulkActionのコールバックには個別レコードではなくCollectionが渡される点が重要です。

->action(fn) でカスタム処理を定義する

アクションの核心は->action()メソッドに渡すクロージャです。引数には処理に必要なものを自由に型ヒントで受け取れます。

Action::make('archive')
    ->action(function (Post $record, array $data): void {
        $record->update([
            'status' => 'archived',
            'archived_reason' => $data['reason'],
            'archived_at' => now(),
        ]);

        Notification::make()
            ->title('アーカイブしました')
            ->success()
            ->send();
    })

$recordで対象レコード、$dataでモーダルフォームの入力値が受け取れます。

->requiresConfirmation() で確認ダイアログ

重要な操作(削除・公開など)には確認ダイアログを追加できます。

Action::make('delete')
    ->label('削除')
    ->color('danger')
    ->icon('heroicon-o-trash')
    ->requiresConfirmation()
    ->modalHeading('記事を削除しますか?')
    ->modalDescription('この操作は取り消せません。本当に削除しますか?')
    ->modalSubmitActionLabel('削除する')
    ->action(fn (Post $record) => $record->delete())

->requiresConfirmation()を付けるだけで「キャンセル」「実行」ボタン付きのモーダルが自動的に表示されます。

->form([...]) でモーダルフォーム付きアクション

アクション実行前に追加情報を入力させたい場合は、->form()でフォームフィールドを定義します。

Action::make('archive')
    ->label('アーカイブ')
    ->icon('heroicon-o-archive-box')
    ->form([
        Textarea::make('reason')
            ->label('アーカイブ理由')
            ->required()
            ->maxLength(500),
        DatePicker::make('archived_until')
            ->label('保管期限')
            ->nullable(),
    ])
    ->modalHeading('記事をアーカイブ')
    ->modalDescription('アーカイブ理由を入力してください。')
    ->modalSubmitActionLabel('アーカイブする')
    ->action(function (Post $record, array $data): void {
        $record->update([
            'status' => 'archived',
            'archived_reason' => $data['reason'],
            'archived_until' => $data['archived_until'],
        ]);
    })

フォームの入力値は->action()のコールバックで$data配列として受け取れます。

モーダルの見た目をカスタマイズする

メソッド説明
->modalHeading('タイトル')モーダルのタイトル
->modalDescription('説明')タイトル下の説明文
->modalSubmitActionLabel('実行する')実行ボタンのラベル
->modalIcon('heroicon-o-check')モーダル左上のアイコン
->modalIconColor('success')アイコンの色
->modalWidth('lg')モーダルの幅

アイコンと色の設定

FilamentはHeroiconsを標準サポートしています。->icon()にアイコン名を渡すだけで表示されます。

Action::make('approve')
    ->label('承認')
    ->icon('heroicon-o-check-badge')
    ->color('success')  // primary / success / warning / danger / gray / info

色は意味的に使い分けるとUXが向上します。

  • primary(青): 主要アクション
  • success(緑): 承認・公開など肯定的操作
  • warning(橙): 注意が必要な操作
  • danger(赤): 削除・停止など危険な操作

->visible(fn) / ->hidden(fn) の条件付き表示

レコードの状態に応じてアクションの表示・非表示を切り替えられます。

Action::make('publish')
    ->visible(fn (Post $record): bool => $record->status === 'draft'),

Action::make('unpublish')
    ->hidden(fn (Post $record): bool => $record->status !== 'published'),

認可ポリシーと組み合わせる場合は->authorize()も使えます。

Action::make('delete')
    ->authorize(fn (Post $record): bool => auth()->user()->can('delete', $record))

実例:「公開する」「アーカイブする」アクション

実際のブログ管理画面でよく使うアクション構成の例です。

public function table(Table $table): Table
{
    return $table
        ->columns([...])
        ->actions([
            Action::make('publish')
                ->label('公開する')
                ->icon('heroicon-o-globe-alt')
                ->color('success')
                ->requiresConfirmation()
                ->modalHeading('記事を公開しますか?')
                ->modalDescription('公開すると外部から閲覧可能になります。')
                ->modalSubmitActionLabel('公開する')
                ->visible(fn (Post $record) => $record->status === 'draft')
                ->action(function (Post $record): void {
                    $record->update([
                        'status' => 'published',
                        'published_at' => now(),
                    ]);
                    Notification::make()
                        ->title("「{$record->title}」を公開しました")
                        ->success()
                        ->send();
                }),

            Action::make('archive')
                ->label('アーカイブ')
                ->icon('heroicon-o-archive-box')
                ->color('warning')
                ->form([
                    Textarea::make('reason')
                        ->label('アーカイブ理由')
                        ->required(),
                ])
                ->visible(fn (Post $record) => $record->status === 'published')
                ->action(function (Post $record, array $data): void {
                    $record->update([
                        'status' => 'archived',
                        'archived_reason' => $data['reason'],
                    ]);
                    Notification::make()
                        ->title('アーカイブしました')
                        ->warning()
                        ->send();
                }),
        ]);
}

まとめ

FilamentのActionシステムは「ボタン + ダイアログ + フォーム + ロジック」をひとつのオブジェクトで管理できる強力な仕組みです。->requiresConfirmation()->form()を組み合わせることで、モーダルUIを完全にコードで制御でき、Bladeテンプレートを書かずに洗練された管理画面が作れます。次のエピソードではモーダルシステムそのものをより深く掘り下げます。