laravel-filament

Auto-invoked skill

Build admin panels with resources, pages, widgets

Trigger Keywords

This skill automatically activates when Claude detects these keywords:

filament admin panel dashboard widget resource

Overview

The laravel-filament skill provides expertise for building admin panels with Filament. It covers resources, forms, tables, widgets, and custom pages.

What This Skill Provides

  • Resources - CRUD interfaces for models
  • Form Builder - Fields, layouts, validation
  • Table Builder - Columns, filters, actions
  • Widgets - Stats, charts, custom dashboards
  • Custom Pages - Beyond CRUD functionality
  • Relation Managers - Nested resource management

Example Conversations

# Creating a resource
"Create a Filament resource for managing products with categories"

# Custom forms
"Add a rich text editor and image upload to my post form"

# Table filters
"Add date range and status filters to my orders table"

# Dashboard widgets
"Create a stats widget showing today's sales and orders"

Filament Resource Example

<?php

namespace App\Filament\Resources;

use App\Models\Product;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;

class ProductResource extends Resource
{
    protected static ?string $model = Product::class;
    protected static ?string $navigationIcon = 'heroicon-o-shopping-bag';

    public static function form(Form $form): Form
    {
        return $form->schema([
            Forms\Components\TextInput::make('name')
                ->required()
                ->maxLength(255),

            Forms\Components\RichEditor::make('description')
                ->columnSpanFull(),

            Forms\Components\TextInput::make('price')
                ->required()
                ->numeric()
                ->prefix('$'),

            Forms\Components\Select::make('category_id')
                ->relationship('category', 'name')
                ->searchable()
                ->preload(),

            Forms\Components\FileUpload::make('image')
                ->image()
                ->directory('products'),
        ]);
    }

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                Tables\Columns\ImageColumn::make('image'),
                Tables\Columns\TextColumn::make('name')
                    ->searchable()
                    ->sortable(),
                Tables\Columns\TextColumn::make('category.name'),
                Tables\Columns\TextColumn::make('price')
                    ->money()
                    ->sortable(),
            ])
            ->filters([
                Tables\Filters\SelectFilter::make('category')
                    ->relationship('category', 'name'),
            ])
            ->actions([
                Tables\Actions\EditAction::make(),
                Tables\Actions\DeleteAction::make(),
            ]);
    }
}

Common Form Fields

Component Use Case
TextInput Single line text, numbers, emails
Select Dropdowns, relationships
RichEditor WYSIWYG content
FileUpload Images, documents
Repeater Dynamic lists of fields

Relation Manager

// In ProductResource
public static function getRelations(): array
{
    return [
        RelationManagers\ReviewsRelationManager::class,
    ];
}

// ReviewsRelationManager.php
class ReviewsRelationManager extends RelationManager
{
    protected static string $relationship = 'reviews';

    public function table(Table $table): Table
    {
        return $table
            ->columns([
                Tables\Columns\TextColumn::make('user.name'),
                Tables\Columns\TextColumn::make('rating'),
                Tables\Columns\TextColumn::make('comment')->limit(50),
            ]);
    }
}

Custom Actions

Tables\Actions\Action::make('approve')
    ->action(fn (Product $record) => $record->approve())
    ->requiresConfirmation()
    ->color('success')
    ->icon('heroicon-o-check'),

Tables\Actions\BulkAction::make('export')
    ->action(fn (Collection $records) => Excel::download($records))

Common Pitfalls

// 1. Missing Navigation Icon - Filament requires icons
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';

// 2. Not Registering Resources - Add to Panel Provider
->discoverResources(
    in: app_path('Filament/Resources'),
    for: 'App\\Filament\\Resources'
)

// 3. Form Field Name Mismatch - Match model attributes
// BAD - if column is 'product_name'
Forms\Components\TextInput::make('name'),

// GOOD
Forms\Components\TextInput::make('product_name'),

// 4. Missing Relationship Method
public function category(): BelongsTo
{
    return $this->belongsTo(Category::class);
}

// 5. Select Without Searchable - Large lists need search
Forms\Components\Select::make('category_id')
    ->relationship('category', 'name')
    ->searchable()
    ->preload(),

// 6. Not Using Soft Deletes - Add restore action
Tables\Actions\RestoreAction::make(),
Tables\Filters\TrashedFilter::make(),

// 7. Heavy Queries in Table - Use withSum/withCount
Tables\Columns\TextColumn::make('items_sum_price')
    ->label('Total'),

Package Integration

  • bezhansalleh/filament-shield - Roles and permissions
  • filament/spatie-laravel-media-library-plugin - Media management
  • filament/spatie-laravel-settings-plugin - Settings management
  • ralphjsmit/laravel-seo - SEO fields

Best Practices

  • Use Sections to organize forms
  • Add search to Select fields
  • Use soft deletes with restore action
  • Implement proper authorization
  • Add global search
  • Use relation managers for related data
  • Keep forms under 15 fields per section
  • Use tabs for complex resources

Related Commands

Related Agent