| name | filament-infolists |
| description | Create FilamentPHP v4 infolists with entries, sections, and layouts for view pages |
FilamentPHP Infolists Generation Skill
Overview
This skill generates FilamentPHP v4 infolists for displaying read-only data in view pages and modals.
Documentation Reference
CRITICAL: Before generating infolists, read:
/home/mwguerra/projects/mwguerra/claude-code-plugins/filament-specialist/skills/filament-docs/references/infolists/
Basic Infolist Structure
use Filament\Infolists;
use Filament\Infolists\Infolist;
public static function infolist(Infolist $infolist): Infolist
{
return $infolist
->schema([
// Entries here
]);
}
Entry Types
Text Entry
// Basic text
Infolists\Components\TextEntry::make('name')
->label('Name');
// With formatting
Infolists\Components\TextEntry::make('price')
->money('usd');
// Date formatting
Infolists\Components\TextEntry::make('created_at')
->dateTime('F j, Y H:i');
// Relative date
Infolists\Components\TextEntry::make('updated_at')
->since();
// With limit
Infolists\Components\TextEntry::make('description')
->limit(100)
->tooltip(fn ($record) => $record->description);
// HTML content
Infolists\Components\TextEntry::make('content')
->html()
->prose();
// Markdown content
Infolists\Components\TextEntry::make('readme')
->markdown();
// Copyable
Infolists\Components\TextEntry::make('uuid')
->copyable()
->copyMessage('Copied!')
->copyMessageDuration(1500);
// With color
Infolists\Components\TextEntry::make('status')
->color(fn (string $state): string => match ($state) {
'draft' => 'gray',
'published' => 'success',
default => 'primary',
});
// With icon
Infolists\Components\TextEntry::make('email')
->icon('heroicon-o-envelope')
->iconColor('primary');
// With badge
Infolists\Components\TextEntry::make('status')
->badge()
->color(fn (string $state): string => match ($state) {
'draft' => 'warning',
'published' => 'success',
default => 'gray',
});
// List of values
Infolists\Components\TextEntry::make('tags.name')
->listWithLineBreaks()
->bulleted();
// With URL
Infolists\Components\TextEntry::make('website')
->url(fn ($record) => $record->website)
->openUrlInNewTab();
Icon Entry
// Boolean icon
Infolists\Components\IconEntry::make('is_active')
->boolean();
// Custom icons
Infolists\Components\IconEntry::make('status')
->icon(fn (string $state): string => match ($state) {
'draft' => 'heroicon-o-pencil',
'reviewing' => 'heroicon-o-clock',
'published' => 'heroicon-o-check-circle',
})
->color(fn (string $state): string => match ($state) {
'draft' => 'info',
'reviewing' => 'warning',
'published' => 'success',
default => 'gray',
});
Image Entry
// Basic image
Infolists\Components\ImageEntry::make('avatar')
->circular()
->size(80);
// Multiple images
Infolists\Components\ImageEntry::make('images')
->stacked()
->limit(3)
->limitedRemainingText();
// Square image
Infolists\Components\ImageEntry::make('logo')
->square()
->size(100);
// With default
Infolists\Components\ImageEntry::make('photo')
->defaultImageUrl(url('/images/placeholder.png'));
Color Entry
Infolists\Components\ColorEntry::make('color')
->copyable();
Key-Value Entry
Infolists\Components\KeyValueEntry::make('metadata');
Repeatable Entry (For HasMany)
Infolists\Components\RepeatableEntry::make('comments')
->schema([
Infolists\Components\TextEntry::make('author.name')
->label('Author'),
Infolists\Components\TextEntry::make('content')
->columnSpanFull(),
Infolists\Components\TextEntry::make('created_at')
->dateTime(),
])
->columns(2);
View Entry (Custom)
Infolists\Components\ViewEntry::make('custom')
->view('filament.infolists.entries.custom-entry');
Layout Components
Section
Infolists\Components\Section::make('Personal Information')
->description('Basic user details')
->icon('heroicon-o-user')
->collapsible()
->schema([
Infolists\Components\TextEntry::make('name'),
Infolists\Components\TextEntry::make('email'),
Infolists\Components\TextEntry::make('phone'),
])
->columns(3);
Fieldset
Infolists\Components\Fieldset::make('Address')
->schema([
Infolists\Components\TextEntry::make('street'),
Infolists\Components\TextEntry::make('city'),
Infolists\Components\TextEntry::make('state'),
Infolists\Components\TextEntry::make('zip'),
])
->columns(2);
Tabs
Infolists\Components\Tabs::make('Tabs')
->tabs([
Infolists\Components\Tabs\Tab::make('Overview')
->icon('heroicon-o-information-circle')
->schema([
Infolists\Components\TextEntry::make('name'),
Infolists\Components\TextEntry::make('email'),
]),
Infolists\Components\Tabs\Tab::make('Details')
->icon('heroicon-o-document-text')
->schema([
Infolists\Components\TextEntry::make('bio')
->columnSpanFull(),
]),
Infolists\Components\Tabs\Tab::make('Settings')
->icon('heroicon-o-cog')
->badge(3)
->schema([
Infolists\Components\IconEntry::make('is_active')
->boolean(),
]),
])
->columnSpanFull();
Grid
Infolists\Components\Grid::make()
->schema([
Infolists\Components\TextEntry::make('name')
->columnSpan(1),
Infolists\Components\TextEntry::make('email')
->columnSpan(1),
Infolists\Components\TextEntry::make('bio')
->columnSpanFull(),
])
->columns(2);
Split
Infolists\Components\Split::make([
Infolists\Components\Section::make('Main Content')
->schema([
Infolists\Components\TextEntry::make('title'),
Infolists\Components\TextEntry::make('content')
->html()
->prose(),
]),
Infolists\Components\Section::make('Metadata')
->schema([
Infolists\Components\TextEntry::make('created_at')
->dateTime(),
Infolists\Components\TextEntry::make('author.name'),
])
->grow(false),
]);
Group
Infolists\Components\Group::make([
Infolists\Components\TextEntry::make('first_name'),
Infolists\Components\TextEntry::make('last_name'),
])
->columns(2);
Complete Infolist Example
<?php
declare(strict_types=1);
namespace App\Filament\Resources\PostResource\Pages;
use App\Filament\Resources\PostResource;
use Filament\Infolists;
use Filament\Infolists\Infolist;
use Filament\Resources\Pages\ViewRecord;
class ViewPost extends ViewRecord
{
protected static string $resource = PostResource::class;
public function infolist(Infolist $infolist): Infolist
{
return $infolist
->schema([
Infolists\Components\Split::make([
// Main content
Infolists\Components\Group::make([
Infolists\Components\Section::make('Post Details')
->schema([
Infolists\Components\TextEntry::make('title')
->size(Infolists\Components\TextEntry\TextEntrySize::Large)
->weight(\Filament\Support\Enums\FontWeight::Bold),
Infolists\Components\TextEntry::make('slug')
->icon('heroicon-o-link')
->copyable(),
Infolists\Components\TextEntry::make('excerpt')
->columnSpanFull(),
])
->columns(2),
Infolists\Components\Section::make('Content')
->schema([
Infolists\Components\TextEntry::make('content')
->html()
->prose()
->columnSpanFull(),
]),
Infolists\Components\Section::make('Comments')
->schema([
Infolists\Components\RepeatableEntry::make('comments')
->schema([
Infolists\Components\TextEntry::make('author.name')
->label('Author')
->weight(\Filament\Support\Enums\FontWeight::Bold),
Infolists\Components\TextEntry::make('created_at')
->since()
->color('gray'),
Infolists\Components\TextEntry::make('content')
->columnSpanFull(),
])
->columns(2),
])
->collapsible(),
]),
// Sidebar
Infolists\Components\Group::make([
Infolists\Components\Section::make('Meta')
->schema([
Infolists\Components\TextEntry::make('status')
->badge()
->color(fn (string $state): string => match ($state) {
'draft' => 'warning',
'published' => 'success',
default => 'gray',
}),
Infolists\Components\TextEntry::make('author.name')
->icon('heroicon-o-user'),
Infolists\Components\TextEntry::make('category.name')
->icon('heroicon-o-folder'),
Infolists\Components\TextEntry::make('tags.name')
->badge()
->separator(','),
]),
Infolists\Components\Section::make('Image')
->schema([
Infolists\Components\ImageEntry::make('featured_image')
->hiddenLabel()
->grow(false),
]),
Infolists\Components\Section::make('Dates')
->schema([
Infolists\Components\TextEntry::make('published_at')
->dateTime()
->icon('heroicon-o-calendar'),
Infolists\Components\TextEntry::make('created_at')
->dateTime()
->icon('heroicon-o-clock'),
Infolists\Components\TextEntry::make('updated_at')
->since()
->icon('heroicon-o-arrow-path'),
]),
])
->grow(false),
])
->from('md')
->columnSpanFull(),
]);
}
protected function getHeaderActions(): array
{
return [
\Filament\Actions\EditAction::make(),
\Filament\Actions\DeleteAction::make(),
];
}
}
Entry Modifiers
Infolists\Components\TextEntry::make('name')
// Label
->label('Full Name')
->hiddenLabel()
// Visibility
->visible(fn ($record) => $record->is_public)
->hidden(fn ($record) => $record->is_private)
// Placeholder for empty
->placeholder('Not specified')
->default('N/A')
// Column span
->columnSpan(2)
->columnSpanFull()
// Weight and size
->weight(\Filament\Support\Enums\FontWeight::Bold)
->size(Infolists\Components\TextEntry\TextEntrySize::Large)
// Extra attributes
->extraAttributes(['class' => 'my-custom-class']);
Output
Generated infolists include:
- Proper entry type selection
- Layout structure
- Relationship handling
- Formatting and styling
- Conditional visibility
- Section organization