MCPInstall

actions

Create FilamentPHP v4 actions with modals, confirmation, forms, and bulk operations

Installs
76
Last 24h
—
Trending rank
—
Security
Not audited

Install

Works with every agent the skills CLI supports.

npx skills add https://github.com/mwguerra/claude-code-plugins --skill actions
  1. 01

    Install

    Run the command in your project. The CLI asks which agents to install for.

  2. 02

    Describe the task

    Ask your agent for something this skill covers. It loads actions automatically when relevant.

  3. 03

    Review the result

    The agent follows the SKILL.md steps, scripts and references bundled with the skill.

SKILL.md

The instructions your agent reads when the skill is triggered.

FilamentPHP Actions Generation Skill

Overview

This skill generates FilamentPHP v4 actions for resources, pages, and tables including modal actions, form actions, bulk operations, and custom workflows.

Documentation Reference

CRITICAL: Before generating actions, read:

  • /home/mwguerra/projects/mwguerra/claude-code-plugins/filament-specialist/skills/docs/references/actions/

Action Types

Standard CRUD Actions

use Filament\Actions;

// Create action
Actions\CreateAction::make()
    ->label('New Post')
    ->icon('heroicon-o-plus');

// Edit action
Actions\EditAction::make()
    ->label('Edit')
    ->icon('heroicon-o-pencil');

// View action
Actions\ViewAction::make()
    ->label('View Details')
    ->icon('heroicon-o-eye');

// Delete action
Actions\DeleteAction::make()
    ->requiresConfirmation()
    ->modalHeading('Delete post')
    ->modalDescription('Are you sure you want to delete this post? This action cannot be undone.')
    ->modalSubmitActionLabel('Yes, delete');

// Force delete (soft deletes)
Actions\ForceDeleteAction::make()
    ->requiresConfirmation();

// Restore (soft deletes)
Actions\RestoreAction::make();

Custom Actions with Modals

// Simple confirmation action
Actions\Action::make('publish')
    ->label('Publish')
    ->icon('heroicon-o-check-circle')
    ->color('success')
    ->requiresConfirmation()
    ->modalHeading('Publish Post')
    ->modalDescription('Are you sure you want to publish this post?')
    ->modalSubmitActionLabel('Yes, publish')
    ->action(function (Model $record): void {
        $record->update(['status' => 'published', 'published_at' => now()]);

        Notification::make()
            ->title('Post published')
            ->success()
            ->send();
    });

// Action with form modal
Actions\Action::make('send_email')
    ->label('Send Email')
    ->icon('heroicon-o-envelope')
    ->color('info')
    ->form([
        Forms\Components\TextInput::make('subject')
            ->label('Subject')
            ->required()
            ->maxLength(255),
        Forms\Components\Select::make('template')
            ->label('Template')
            ->options([
                'welcome' => 'Welcome Email',
                'reminder' => 'Reminder',
                'promotion' => 'Promotion',
            ])
            ->required(),
        Forms\Components\RichEditor::make('body')
            ->label('Message')
            ->required()
            ->columnSpanFull(),
    ])
    ->action(function (Model $record, array $data): void {
        Mail::to($record->email)->send(new CustomEmail(
            subject: $data['subject'],
            template: $data['template'],
            body: $data['body'],
        ));

        Notification::make()
            ->title('Email sent successfully')
            ->success()
            ->send();
    });

// Wizard action (multi-step)
Actions\Action::make('create_order')
    ->label('Create Order')
    ->icon('heroicon-o-shopping-cart')
    ->steps([
        Forms\Components\Wizard\Step::make('Customer')
            ->schema([
                Forms\Components\Select::make('customer_id')
                    ->relationship('customer', 'name')
                    ->required()
                    ->searchable(),
            ]),
        Forms\Components\Wizard\Step::make('Products')
            ->schema([
                Forms\Components\Repeater::make('items')
                    ->schema([
                        Forms\Components\Select::make('product_id')
                            ->relationship('product', 'name')
                            ->required(),
                        Forms\Components\TextInput::make('quantity')
                            ->numeric()
                            ->required()
                            ->default(1),
                    ])
                    ->columns(2),
            ]),
        Forms\Components\Wizard\Step::make('Shipping')
            ->schema([
                Forms\Components\Textarea::make('address')
                    ->required(),
                Forms\Components\Select::make('shipping_method')
                    ->options([
                        'standard' => 'Standard',
                        'express' => 'Express',
                    ]),
            ]),
    ])
    ->action(function (array $data): void {
        Order::create($data);
    });

Action Visibility and Authorization

Actions\Action::make('approve')
    // Visible only for specific status
    ->visible(fn (Model $record): bool => $record->status === 'pending')

    // Hidden in certain conditions
    ->hidden(fn (Model $record): bool => $record->is_archived)

    // Authorization check
    ->authorize('approve')

    // Or with closure
    ->authorized(fn (): bool => auth()->user()->can('approve_posts'));

Actions with Side Effects

// Action that refreshes data
Actions\Action::make('refresh')
    ->icon('heroicon-o-arrow-path')
    ->action(fn () => null)  // No action needed
    ->after(fn ($livewire) => $livewire->dispatch('refresh'));

// Action with redirect
Actions\Action::make('view_invoice')
    ->icon('heroicon-o-document')
    ->url(fn (Model $record): string => route('invoices.show', $record->invoice_id))
    ->openUrlInNewTab();

// Action with download
Actions\Action::make('download_pdf')
    ->icon('heroicon-o-arrow-down-tray')
    ->action(function (Model $record) {
        return response()->download(
            storage_path("invoices/{$record->invoice_id}.pdf")
        );
    });

Table Row Actions

use Filament\Tables\Actions;

public static function table(Table $table): Table
{
    return $table
        ->columns([...])
        ->actions([
            // Icon-only actions
            Actions\ActionGroup::make([
                Actions\ViewAction::make(),
                Actions\EditAction::make(),
                Actions\DeleteAction::make(),
            ])->dropdownPlacement('bottom-end'),

            // Or inline
            Actions\ViewAction::make()
                ->iconButton(),
            Actions\EditAction::make()
                ->iconButton(),

            // Custom inline action
            Actions\Action::make('duplicate')
                ->icon('heroicon-o-document-duplicate')
                ->iconButton()
                ->action(function (Model $record): void {
                    $replica = $record->replicate();
                    $replica->name = $record->name . ' (Copy)';
                    $replica->save();
                }),
        ]);
}

Bulk Actions

use Filament\Tables\Actions;

->bulkActions([
    Actions\BulkActionGroup::make([
        // Standard bulk delete
        Actions\DeleteBulkAction::make(),

        // Custom bulk action
        Actions\BulkAction::make('publish')
            ->label('Publish Selected')
            ->icon('heroicon-o-check-circle')
            ->color('success')
            ->requiresConfirmation()
            ->action(function (Collection $records): void {
                $records->each->update(['status' => 'published']);

                Notification::make()
                    ->title(count($records) . ' posts published')
                    ->success()
                    ->send();
            })
            ->deselectRecordsAfterCompletion(),

        // Bulk action with form
        Actions\BulkAction::make('assign_category')
            ->label('Assign Category')
            ->icon('heroicon-o-tag')
            ->form([
                Forms\Components\Select::make('category_id')
                    ->label('Category')
                    ->relationship('category', 'name')
                    ->required(),
            ])
            ->action(function (Collection $records, array $data): void {
                $records->each->update(['category_id' => $data['category_id']]);
            }),

        // Export bulk action
        Actions\BulkAction::make('export')
            ->label('Export to CSV')
            ->icon('heroicon-o-arrow-down-tray')
            ->action(function (Collection $records) {
                return Excel::download(
                    new RecordsExport($records),
                    'records.csv'
                );
            }),
    ]),
]);

Header Actions

use Filament\Tables\Actions;

->headerActions([
    // Create action
    Actions\CreateAction::make()
        ->label('New Post'),

    // Import action
    Actions\Action::make('import')
        ->label('Import')
        ->icon('heroicon-o-arrow-up-tray')
        ->form([
            Forms\Components\FileUpload::make('file')
                ->label('CSV File')
                ->acceptedFileTypes(['text/csv'])
                ->required(),
        ])
        ->action(function (array $data): void {
            // Import logic
        }),

    // Attach action (for relationships)
    Actions\AttachAction::make()
        ->preloadRecordSelect()
        ->recordSelectSearchColumns(['name', 'email']),
]);

Relation Manager Actions

// In RelationManager class

protected function getHeaderActions(): array
{
    return [
        Tables\Actions\CreateAction::make(),
        Tables\Actions\AttachAction::make()
            ->preloadRecordSelect()
            ->form(fn (Tables\Actions\AttachAction $action): array => [
                $action->getRecordSelect(),
                Forms\Components\TextInput::make('role')
                    ->required(),
            ]),
        Tables\Actions\AssociateAction::make(),
    ];
}

public function table(Table $table): Table
{
    return $table
        ->columns([...])
        ->actions([
            Tables\Actions\EditAction::make(),
            Tables\Actions\DetachAction::make(),
            Tables\Actions\DissociateAction::make(),
            Tables\Actions\DeleteAction::make(),
        ])
        ->bulkActions([
            Tables\Actions\BulkActionGroup::make([
                Tables\Actions\DetachBulkAction::make(),
                Tables\Actions\DeleteBulkAction::make(),
            ]),
        ]);
}

Page Actions

// In resource page classes

protected function getHeaderActions(): array
{
    return [
        Actions\EditAction::make(),
        Actions\DeleteAction::make(),

        // Custom action
        Actions\Action::make('preview')
            ->icon('heroicon-o-eye')
            ->url(fn (): string => route('posts.show', $this->record))
            ->openUrlInNewTab(),
    ];
}

// For List page
protected function getHeaderActions(): array
{
    return [
        Actions\CreateAction::make(),

        // Global action
        Actions\Action::make('settings')
            ->icon('heroicon-o-cog')
            ->url(fn (): string => route('filament.admin.pages.settings')),
    ];
}

Action Styling and Configuration

Actions\Action::make('custom')
    // Label and icon
    ->label('Custom Action')
    ->icon('heroicon-o-star')
    ->iconPosition(IconPosition::After)

    // Colors
    ->color('success')  // primary, secondary, success, warning, danger, info, gray

    // Size
    ->size(ActionSize::Large)

    // Button style
    ->button()
    ->outlined()
    ->iconButton()
    ->link()

    // Keyboard shortcut
    ->keyBindings(['mod+s'])

    // Extra attributes
    ->extraAttributes([
        'class' => 'my-custom-class',
        'data-action' => 'custom',
    ])

    // Badge
    ->badge(fn () => 5)
    ->badgeColor('danger')

    // Tooltip
    ->tooltip('Click to perform action');

Notifications with Actions

use Filament\Notifications\Notification;
use Filament\Notifications\Actions\Action;

Notification::make()
    ->title('Post created successfully')
    ->success()
    ->body('Your post has been created.')
    ->actions([
        Action::make('view')
            ->button()
            ->url(route('posts.show', $record)),
        Action::make('undo')
            ->color('gray')
            ->action(fn () => $record->delete()),
    ])
    ->send();

Output

Generated actions include:

  1. Proper action type selection
  2. Modal configurations
  3. Form schemas for modal forms
  4. Authorization checks
  5. Notifications
  6. Proper styling and icons

FAQ

What does the actions skill do?

Create FilamentPHP v4 actions with modals, confirmation, forms, and bulk operations

How do I install actions?

Run npx skills add https://github.com/mwguerra/claude-code-plugins --skill actions in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/actions/ (personal) or .claude/skills/actions/ (project).

Which AI agents can use actions?

Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.

Is actions safe to install?

No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.

Who maintains actions?

It is published by mwguerra in mwguerra/claude-code-plugins. It has 76 recorded installs.

More from mwguerra/claude-code-plugins

View all →

filament-resource

mwguerra/claude-code-plugins

Generate FilamentPHP v4 resources with form, table, relation managers, and actions

1.2K installs

resource

mwguerra/claude-code-plugins

Generate FilamentPHP v4 resources with form, table, relation managers, and actions

214 installs

forms

mwguerra/claude-code-plugins

Create FilamentPHP v4 forms with fields, validation, sections, tabs, and relationships

95 installs

tables

mwguerra/claude-code-plugins

Open the skill to read its SKILL.md instructions.

88 installs

widgets

mwguerra/claude-code-plugins

Create FilamentPHP v4 dashboard widgets - stats overviews, charts, and custom components

Data & Databases75 installs

dashboard

mwguerra/claude-code-plugins

Open the skill to read its SKILL.md instructions.

Data & Databases71 installs

Popular other skills

View category →

hyperframes-cli

heygen-com/hyperframes

The HyperFrames CLI by job - scaffold, check, look at frames, edit the timeline, preview, render locally or in the cloud, publish, project history - plus reading its JSON and recovering from build or render failures.

1.3M installs

triage

mattpocock/skills

Move issues and external PRs through a state machine of triage roles, categorise, verify, grill if needed, and write agent-ready briefs.

1M installs

ask-matt

mattpocock/skills

Ask which skill or flow fits your situation. A router over the skills in this repo.

778.4K installs

to-questionnaire

mattpocock/skills

Turn a decision you can't fully answer into a questionnaire for someone else to fill in.

508.9K installs

wait-what

mattpocock/skills

Stop. That last message did not land: re-pitch it.

459.7K installs

loop-me

mattpocock/skills

Grill me about specs for the workflows I want to build, within this workspace.

447.9K installs