Claude
Skills
Sign in
Back

forms

Included with Lifetime
$97 forever

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

General

What this skill does


# FilamentPHP Forms Generation Skill

## Overview

This skill generates FilamentPHP v4 form schemas with proper field configurations, validation rules, relationships, and layout components.

## Documentation Reference

**CRITICAL:** Before generating forms, read:
- `/home/mwguerra/projects/mwguerra/claude-code-plugins/filament-specialist/skills/docs/references/forms/`
- `/home/mwguerra/projects/mwguerra/claude-code-plugins/filament-specialist/skills/docs/references/schemas/`

## Workflow

### Step 1: Analyze Requirements

Identify:
- Field types needed
- Validation rules
- Relationships (belongsTo, hasMany, etc.)
- Layout preferences (sections, tabs, columns)
- Conditional visibility
- Custom formatting

### Step 2: Read Documentation

Navigate to forms documentation and extract:
- Exact field class names
- Available methods and options
- Validation integration patterns
- Relationship handling

### Step 3: Generate Schema

Build the form schema with proper structure:

```php
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Select;

public static function form(Form $form): Form
{
    return $form
        ->schema([
            // Fields organized in sections/fieldsets
        ]);
}
```

## Schema Organization Requirement

**CRITICAL:** All form schemas MUST be organized using layout components. Never place fields directly at the root level of a form schema.

### Minimum Organization Rules

1. **Always use Sections or Fieldsets** - Every form must have at least one Section or Fieldset wrapping its fields
2. **Group related fields** - Fields that belong together logically should be in the same Section/Fieldset
3. **Use descriptive labels** - Sections and Fieldsets should have meaningful titles
4. **Consider collapsibility** - Make sections collapsible when forms are long

### Recommended Hierarchy

```
Form Schema
├── Section: "Primary Information"
│   ├── Fieldset: "Basic Details" (optional grouping)
│   │   ├── TextInput: name
│   │   └── TextInput: email
│   └── Fieldset: "Contact" (optional grouping)
│       ├── TextInput: phone
│       └── TextInput: address
├── Section: "Settings"
│   ├── Toggle: is_active
│   └── Select: status
└── Section: "Media" (collapsible)
    └── FileUpload: avatar
```

### Bad Example (DO NOT DO THIS)

```php
// ❌ WRONG: Fields at root level without organization
public static function form(Form $form): Form
{
    return $form
        ->schema([
            TextInput::make('name'),
            TextInput::make('email'),
            TextInput::make('phone'),
            Toggle::make('is_active'),
            FileUpload::make('avatar'),
        ]);
}
```

### Good Example (ALWAYS DO THIS)

```php
// ✅ CORRECT: Fields organized in sections
public static function form(Form $form): Form
{
    return $form
        ->schema([
            Section::make('Personal Information')
                ->description('Basic user details')
                ->schema([
                    TextInput::make('name')
                        ->required()
                        ->maxLength(255),
                    TextInput::make('email')
                        ->email()
                        ->required(),
                    TextInput::make('phone')
                        ->tel(),
                ]),

            Section::make('Settings')
                ->schema([
                    Toggle::make('is_active')
                        ->label('Active')
                        ->default(true),
                ]),

            Section::make('Profile Image')
                ->collapsible()
                ->schema([
                    FileUpload::make('avatar')
                        ->image()
                        ->disk('public')
                        ->directory('avatars'),
                ]),
        ]);
}
```

### When to Use Section vs Fieldset

| Component | Use Case |
|-----------|----------|
| **Section** | Major logical groupings, can have description, icon, collapsible |
| **Fieldset** | Smaller sub-groupings within a section, lighter visual weight |
| **Tabs** | When sections are numerous and would cause scrolling |
| **Grid** | Column layout within sections (not a replacement for sections) |

### Complex Form Example

```php
public static function form(Form $form): Form
{
    return $form
        ->schema([
            Section::make('Product Details')
                ->icon('heroicon-o-cube')
                ->schema([
                    Fieldset::make('Basic Information')
                        ->schema([
                            TextInput::make('name')
                                ->required()
                                ->maxLength(255),
                            TextInput::make('sku')
                                ->required()
                                ->unique(ignoreRecord: true),
                        ])
                        ->columns(2),

                    Fieldset::make('Pricing')
                        ->schema([
                            TextInput::make('price')
                                ->numeric()
                                ->prefix('$')
                                ->required(),
                            TextInput::make('compare_at_price')
                                ->numeric()
                                ->prefix('$'),
                        ])
                        ->columns(2),

                    RichEditor::make('description')
                        ->columnSpanFull(),
                ]),

            Section::make('Inventory')
                ->icon('heroicon-o-archive-box')
                ->collapsible()
                ->schema([
                    TextInput::make('quantity')
                        ->numeric()
                        ->default(0),
                    Toggle::make('track_inventory')
                        ->default(true),
                ]),

            Section::make('Media')
                ->icon('heroicon-o-photo')
                ->collapsible()
                ->collapsed()
                ->schema([
                    FileUpload::make('images')
                        ->multiple()
                        ->image()
                        ->reorderable(),
                ]),
        ]);
}
```

## Complete Field Reference

### Text Input Fields

```php
// Basic text input
TextInput::make('name')
    ->required()
    ->maxLength(255)
    ->placeholder('Enter name...')
    ->helperText('This will be displayed publicly')
    ->prefixIcon('heroicon-o-user');

// Email input
TextInput::make('email')
    ->email()
    ->required()
    ->unique(ignoreRecord: true);

// Password input
TextInput::make('password')
    ->password()
    ->required()
    ->confirmed()
    ->minLength(8);

// Numeric input
TextInput::make('price')
    ->numeric()
    ->prefix('$')
    ->minValue(0)
    ->maxValue(10000)
    ->step(0.01);

// Phone input
TextInput::make('phone')
    ->tel()
    ->telRegex('/^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\.\/0-9]*$/');

// URL input
TextInput::make('website')
    ->url()
    ->suffixIcon('heroicon-o-globe-alt');
```

### Textarea Fields

```php
// Basic textarea
Textarea::make('description')
    ->rows(5)
    ->cols(20)
    ->minLength(10)
    ->maxLength(1000)
    ->columnSpanFull();

// Auto-resize textarea
Textarea::make('content')
    ->autosize()
    ->columnSpanFull();
```

### Rich Text Editors

```php
// Rich editor
RichEditor::make('content')
    ->toolbarButtons([
        'blockquote',
        'bold',
        'bulletList',
        'codeBlock',
        'h2',
        'h3',
        'italic',
        'link',
        'orderedList',
        'redo',
        'strike',
        'underline',
        'undo',
    ])
    ->columnSpanFull();

// Markdown editor
MarkdownEditor::make('content')
    ->toolbarButtons([
        'bold',
        'bul

Related in General