Skip to content

Filament Components

Overview

Custom Filament components live in app/Filament/Forms/Components/ (form fields) and app/Filament/Schemas/Components/ (infolist/view components). These are used when the built-in Filament components don't meet the design requirement.


Folder Structure

app/Filament/
├── Forms/
│   └── Components/          # Custom form fields
│       ├── Inputs/          # Text inputs with custom formatting
│       │   └── PhoneInput.php
│       ├── Selects/         # Searchable selects with custom rendering
│       │   └── CountrySelect.php
│       ├── Editors/         # Rich text editors
│       ├── Pickers/         # Date/time pickers
│       ├── Media/           # File upload with preview
│       └── Containers/      # Layout containers (tabs, wizards)

└── Schemas/
    └── Components/          # Custom infolist (view) components
        ├── Cards/           # Info cards with icon, status, actions
        ├── Stats/           # Statistics display widgets
        ├── Timeline/        # Activity log timeline
        └── Layout/          # Column layouts, sections

When to Create a Custom Component

ScenarioUse Built-inUse Custom
Simple text inputTextInput
Input with custom CSS/styling✅ Create custom Input
Dropdown with 5 optionsSelect
Dropdown with search, icons, groups✅ Create custom Select
Basic text displayTextEntry
Card with dynamic status badge✅ Create custom Card

Component Structure

Each custom component follows this pattern:

ComponentName.php
├── make()              # Static factory method
├── setUp()             # Configuration defaults
├── getXxx() methods    # Render/behavior overrides
└── views/              # Custom Blade views (if needed)

Form Component Example

php
namespace App\Filament\Forms\Components\Selects;

use Filament\Forms\Components\Select;
use Illuminate\Support\Str;

class CountrySelect extends Select
{
    protected function setUp(): void
    {
        parent::setUp();

        $this
            ->label('Country')
            ->placeholder('Select a country...')
            ->searchable()
            ->options(function () {
                return Country::query()
                    ->pluck('name', 'code')
                    ->toArray();
            })
            ->searchable()
            ->preload();
    }

    public static function make(string $name = 'country_code'): static
    {
        return parent::make($name);
    }
}

Usage in a resource:

php
use App\Filament\Forms\Components\Selects\CountrySelect;

CountrySelect::make('country_code')
    ->required(),

Infolist Component Example

php
namespace App\Filament\Schemas\Components\Cards;

use Filament\Infolists\Components\Entry;
use Closure;

class StatusCard extends Entry
{
    protected function setUp(): void
    {
        parent::setUp();

        $this
            ->view('filament.components.status-card')
            ->default(fn () => 'pending');
    }

    public static function make(string $name = 'status'): static
    {
        return parent::make($name);
    }
}

Rules

RuleDescription
Extend the baseAlways extend Filament's base class (Select, TextInput, Entry, etc.)
Use setUp()Configure defaults in setUp() — not in make()
Override make()Override make() to set a sensible default name
Keep it focusedOne component = one purpose
Consistent placeholderEvery Select must have a placeholder
Check existing firstAlways check app/Filament/Forms/Components/ before creating a new one

Creating a New Component

bash
# 1. Create the component file
touch app/Filament/Forms/Components/Inputs/{Name}Input.php

# 2. (Optional) Create a Blade view
mkdir -p resources/views/filament/components
touch resources/views/filament/components/{name}-input.blade.php

Minimal Skeleton

php
<?php

namespace App\Filament\Forms\Components\Inputs;

use Filament\Forms\Components\TextInput;

class PhoneInput extends TextInput
{
    protected function setUp(): void
    {
        parent::setUp();

        $this
            ->label('Phone')
            ->placeholder('81234567890')
            ->maxLength(15)
            ->tel();
    }

    public static function make(string $name = 'phone'): static
    {
        return parent::make($name);
    }
}

Key Files

FilePurpose
app/Filament/Forms/Components/Inputs/Custom form input components
app/Filament/Forms/Components/Selects/Custom select components
app/Filament/Forms/Components/Editors/Custom editor components
app/Filament/Forms/Components/Pickers/Custom picker components
app/Filament/Forms/Components/Media/Custom media/file components
app/Filament/Forms/Components/Containers/Custom layout containers
app/Filament/Schemas/Components/Cards/Custom infolist card components
app/Filament/Schemas/Components/Stats/Custom statistics components
app/Filament/Schemas/Components/Timeline/Custom timeline components
app/Filament/Schemas/Components/Layout/Custom layout components