Claude-skill-registry filament-infolists
Create FilamentPHP v4 infolists with entries, sections, and layouts for view pages
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/filament-infolists" ~/.claude/skills/majiayu000-claude-skill-registry-filament-infolists && rm -rf "$T"
manifest:
skills/data/filament-infolists/SKILL.mdsource content
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