Claude-skill-registry filament-tables
Create FilamentPHP v4 tables with columns, filters, sorting, search, and bulk actions
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-tables" ~/.claude/skills/majiayu000-claude-skill-registry-filament-tables && rm -rf "$T"
manifest:
skills/data/filament-tables/SKILL.mdsource content
FilamentPHP Tables Generation Skill
Overview
This skill generates FilamentPHP v4 table configurations with columns, filters, actions, and bulk operations following official documentation patterns.
Documentation Reference
CRITICAL: Before generating tables, read:
/home/mwguerra/projects/mwguerra/claude-code-plugins/filament-specialist/skills/filament-docs/references/tables//home/mwguerra/projects/mwguerra/claude-code-plugins/filament-specialist/skills/filament-docs/references/tables/02-columns//home/mwguerra/projects/mwguerra/claude-code-plugins/filament-specialist/skills/filament-docs/references/tables/03-filters/
Workflow
Step 1: Analyze Requirements
Identify:
- Columns to display
- Searchable fields
- Sortable fields
- Filter requirements
- Row actions
- Bulk actions
- Relationships to display
Step 2: Read Documentation
Navigate to table documentation and extract:
- Column class names and options
- Filter configurations
- Action patterns
- Performance considerations
Step 3: Generate Table
Build table configuration:
use Filament\Tables; use Filament\Tables\Table; public static function table(Table $table): Table { return $table ->columns([ // Columns ]) ->filters([ // Filters ]) ->actions([ // Row actions ]) ->bulkActions([ // Bulk actions ]); }
Column Types Reference
Text Column
// Basic text Tables\Columns\TextColumn::make('name') ->searchable() ->sortable(); // With limit and tooltip Tables\Columns\TextColumn::make('description') ->limit(50) ->tooltip(fn ($record): string => $record->description); // Formatted Tables\Columns\TextColumn::make('price') ->money('usd') ->sortable(); // Date formatting Tables\Columns\TextColumn::make('created_at') ->dateTime('M j, Y H:i') ->sortable() ->since(); // Shows "2 hours ago" // Copyable Tables\Columns\TextColumn::make('uuid') ->copyable() ->copyMessage('UUID copied!') ->copyMessageDuration(1500); // With color Tables\Columns\TextColumn::make('status') ->color(fn (string $state): string => match ($state) { 'draft' => 'gray', 'reviewing' => 'warning', 'published' => 'success', default => 'gray', }); // HTML content Tables\Columns\TextColumn::make('content') ->html() ->wrap(); // Word/character count Tables\Columns\TextColumn::make('bio') ->words(10); // List values (array) Tables\Columns\TextColumn::make('tags') ->listWithLineBreaks() ->bulleted();
Icon Column
// Boolean icon Tables\Columns\IconColumn::make('is_active') ->boolean(); // Custom icons Tables\Columns\IconColumn::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 Column
// Basic image Tables\Columns\ImageColumn::make('avatar') ->circular() ->size(40); // Multiple images (stacked) Tables\Columns\ImageColumn::make('images') ->circular() ->stacked() ->limit(3) ->limitedRemainingText(); // With default Tables\Columns\ImageColumn::make('logo') ->defaultImageUrl(url('/images/default-logo.png')) ->square() ->size(60);
Badge Column
Tables\Columns\BadgeColumn::make('status') ->colors([ 'danger' => 'draft', 'warning' => 'reviewing', 'success' => 'published', ]) ->icons([ 'heroicon-o-pencil' => 'draft', 'heroicon-o-clock' => 'reviewing', 'heroicon-o-check' => 'published', ]); // Or with closure Tables\Columns\BadgeColumn::make('priority') ->color(fn (string $state): string => match ($state) { 'low' => 'gray', 'medium' => 'warning', 'high' => 'danger', });
Color Column
Tables\Columns\ColorColumn::make('color') ->copyable() ->copyMessage('Color code copied');
Toggle Column
// Editable inline toggle Tables\Columns\ToggleColumn::make('is_active') ->onColor('success') ->offColor('danger') ->afterStateUpdated(fn () => Notification::make() ->title('Status updated') ->success() ->send() );
Select Column
// Editable inline select Tables\Columns\SelectColumn::make('status') ->options([ 'draft' => 'Draft', 'published' => 'Published', ]);
Text Input Column
// Editable inline text Tables\Columns\TextInputColumn::make('sort_order') ->rules(['required', 'numeric']);
Checkbox Column
// Editable inline checkbox Tables\Columns\CheckboxColumn::make('is_featured');
Relationship Columns
// BelongsTo Tables\Columns\TextColumn::make('author.name') ->label('Author') ->searchable() ->sortable(); // HasMany count Tables\Columns\TextColumn::make('comments_count') ->counts('comments') ->label('Comments') ->sortable(); // HasMany sum Tables\Columns\TextColumn::make('items_sum_quantity') ->sum('items', 'quantity') ->label('Total Quantity'); // BelongsToMany list Tables\Columns\TextColumn::make('tags.name') ->badge() ->separator(',');
View Column (Custom)
Tables\Columns\ViewColumn::make('custom') ->view('filament.tables.columns.custom-column');
Column Modifiers
Tables\Columns\TextColumn::make('name') // Search ->searchable() ->searchable(isIndividual: true) // Sort ->sortable() ->sortable(['first_name', 'last_name']) // Visibility ->toggleable() ->toggleable(isToggledHiddenByDefault: true) ->visible(fn (): bool => auth()->user()->isAdmin()) ->hidden(fn ($record): bool => $record->is_private) // Sizing ->grow(false) ->width('200px') ->alignCenter() ->alignEnd() // Styling ->weight(FontWeight::Bold) ->size(TextColumn\TextColumnSize::Large) ->color('primary') ->extraAttributes(['class' => 'custom-class']);
Filters Reference
Select Filter
Tables\Filters\SelectFilter::make('status') ->options([ 'draft' => 'Draft', 'reviewing' => 'Reviewing', 'published' => 'Published', ]); // Multiple selection Tables\Filters\SelectFilter::make('status') ->multiple() ->options([ 'draft' => 'Draft', 'published' => 'Published', ]); // Relationship filter Tables\Filters\SelectFilter::make('author') ->relationship('author', 'name') ->searchable() ->preload();
Ternary Filter (Boolean)
Tables\Filters\TernaryFilter::make('is_active') ->label('Active') ->boolean() ->trueLabel('Active only') ->falseLabel('Inactive only') ->native(false);
Date Filter
Tables\Filters\Filter::make('created_at') ->form([ Forms\Components\DatePicker::make('created_from'), Forms\Components\DatePicker::make('created_until'), ]) ->query(function (Builder $query, array $data): Builder { return $query ->when( $data['created_from'], fn (Builder $query, $date): Builder => $query->whereDate('created_at', '>=', $date), ) ->when( $data['created_until'], fn (Builder $query, $date): Builder => $query->whereDate('created_at', '<=', $date), ); }) ->indicateUsing(function (array $data): array { $indicators = []; if ($data['created_from'] ?? null) { $indicators['created_from'] = 'From ' . Carbon::parse($data['created_from'])->toFormattedDateString(); } if ($data['created_until'] ?? null) { $indicators['created_until'] = 'Until ' . Carbon::parse($data['created_until'])->toFormattedDateString(); } return $indicators; });
Trashed Filter (Soft Deletes)
Tables\Filters\TrashedFilter::make();
Query Builder Filter
Tables\Filters\QueryBuilder::make() ->constraints([ Tables\Filters\QueryBuilder\Constraints\TextConstraint::make('name'), Tables\Filters\QueryBuilder\Constraints\NumberConstraint::make('price'), Tables\Filters\QueryBuilder\Constraints\DateConstraint::make('created_at'), Tables\Filters\QueryBuilder\Constraints\RelationshipConstraint::make('author') ->icon('heroicon-o-user') ->multiple(), ]);
Actions Reference
Row Actions
->actions([ Tables\Actions\ViewAction::make(), Tables\Actions\EditAction::make(), Tables\Actions\DeleteAction::make() ->requiresConfirmation(), // Custom action Tables\Actions\Action::make('publish') ->icon('heroicon-o-check') ->color('success') ->requiresConfirmation() ->action(fn (Model $record) => $record->publish()) ->visible(fn (Model $record): bool => $record->status === 'draft'), // Action with modal form Tables\Actions\Action::make('send_email') ->icon('heroicon-o-envelope') ->form([ Forms\Components\TextInput::make('subject') ->required(), Forms\Components\RichEditor::make('body') ->required(), ]) ->action(function (Model $record, array $data): void { Mail::to($record->email)->send(new CustomEmail($data)); }), // Grouped actions Tables\Actions\ActionGroup::make([ Tables\Actions\ViewAction::make(), Tables\Actions\EditAction::make(), Tables\Actions\DeleteAction::make(), ])->dropdown(), // Replicate action Tables\Actions\ReplicateAction::make() ->excludeAttributes(['slug', 'published_at']) ->beforeReplicaSaved(function (Model $replica): void { $replica->name = $replica->name . ' (Copy)'; }), ]);
Bulk Actions
->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DeleteBulkAction::make(), Tables\Actions\ForceDeleteBulkAction::make(), Tables\Actions\RestoreBulkAction::make(), // Custom bulk action Tables\Actions\BulkAction::make('publish') ->icon('heroicon-o-check') ->requiresConfirmation() ->action(fn (Collection $records) => $records->each->publish()) ->deselectRecordsAfterCompletion(), // Export bulk action Tables\Actions\BulkAction::make('export') ->icon('heroicon-o-arrow-down-tray') ->action(fn (Collection $records) => static::export($records)), ]), ]);
Header Actions
->headerActions([ Tables\Actions\CreateAction::make(), Tables\Actions\AttachAction::make() ->preloadRecordSelect(), // Import action Tables\Actions\Action::make('import') ->icon('heroicon-o-arrow-up-tray') ->form([ Forms\Components\FileUpload::make('file') ->acceptedFileTypes(['text/csv']), ]) ->action(fn (array $data) => static::import($data['file'])), ]);
Table Configuration
public static function table(Table $table): Table { return $table ->columns([...]) ->filters([...]) ->actions([...]) ->bulkActions([...]) // Pagination ->paginated([10, 25, 50, 100]) ->defaultPaginationPageOption(25) // Default sort ->defaultSort('created_at', 'desc') // Reordering ->reorderable('sort_order') ->defaultSort('sort_order') // Grouping ->groups([ Tables\Grouping\Group::make('status') ->label('Status') ->collapsible(), Tables\Grouping\Group::make('author.name') ->label('Author'), ]) // Striped rows ->striped() // Poll for updates ->poll('10s') // Empty state ->emptyStateHeading('No posts yet') ->emptyStateDescription('Create your first post to get started.') ->emptyStateIcon('heroicon-o-document-text') ->emptyStateActions([ Tables\Actions\CreateAction::make() ->label('Create Post'), ]) // Modals ->modals([ 'view' => true, ]) // Persist filters ->filtersFormColumns(3) ->persistFiltersInSession(); }
Output
Generated tables include:
- Complete column configuration
- Search and sort settings
- Filter definitions
- Row and bulk actions
- Relationship handling
- Performance optimizations