Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Radio Deck Laravel Package

jaocero/radio-deck

FilamentPHP plugin that upgrades the default radio field into selectable “card” options with icons, titles, and descriptions. Built for Filament v4 (Laravel 11, PHP 8.2+, Tailwind v4) with support via custom theme @source directive.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:
    composer require jaocero/radio-deck
    
  2. Create a custom Filament theme (required for v4):
    php artisan make:filament-theme
    
  3. Add the package's views to your theme CSS (resources/css/filament/admin/theme.css):
    @source '../../../../vendor/jaocero/radio-deck/resources/views';
    
  4. Use in a form:
    use JaOcero\RadioDeck\Forms\Components\RadioDeck;
    
    RadioDeck::make('platform')
        ->options([
            'ios' => 'iOS',
            'android' => 'Android',
        ])
        ->icons([
            'ios' => 'heroicon-m-device-phone-mobile',
            'android' => 'heroicon-m-device-phone-mobile',
        ]);
    

First Use Case

Replace a standard Filament radio button group with a visually rich card-based selector for platform selection in a user profile form. Example:

public static function form(Form $form): Form
{
    return $form->schema([
        RadioDeck::make('preferred_platform')
            ->options([
                'web' => 'Web',
                'mobile' => 'Mobile',
                'desktop' => 'Desktop',
            ])
            ->icons([
                'web' => 'heroicon-o-globe-alt',
                'mobile' => 'heroicon-o-phone',
                'desktop' => 'heroicon-o-desktop-computer',
            ])
            ->descriptions([
                'web' => 'Browser-based experience',
                'mobile' => 'Optimized for phones',
                'desktop' => 'Full desktop features',
            ])
            ->columns(2),
    ]);
}

Implementation Patterns

Common Workflows

1. Basic Replacement Pattern

Replace standard radio inputs with visual cards:

// Before
Radio::make('status')->options(['active', 'inactive']);

// After
RadioDeck::make('status')
    ->options([
        'active' => 'Active',
        'inactive' => 'Inactive',
    ])
    ->icons([
        'active' => 'heroicon-o-check-circle',
        'inactive' => 'heroicon-o-x-circle',
    ]);

2. Enum Integration Pattern

Use enums for type safety and maintainability:

// Define enum
enum UserRole: string implements HasLabel, HasIcons
{
    case ADMIN = 'admin';
    case EDITOR = 'editor';
    case VIEWER = 'viewer';

    public function getLabel(): string
    {
        return match ($this) {
            self::ADMIN => 'Administrator',
            self::EDITOR => 'Editor',
            self::VIEWER => 'Viewer',
        };
    }

    public function getIcon(): string
    {
        return match ($this) {
            self::ADMIN => 'heroicon-o-shield-check',
            self::EDITOR => 'heroicon-o-pencil',
            self::VIEWER => 'heroicon-o-eye',
        };
    }
}

// Usage
RadioDeck::make('role')
    ->options(UserRole::class)
    ->icons(UserRole::class);

3. Responsive Layout Pattern

Adjust column count per screen size:

RadioDeck::make('category')
    ->options(['books', 'movies', 'music'])
    ->columns([
        'sm' => 1,
        'md' => 2,
        'lg' => 3,
    ]);

4. Conditional Styling Pattern

Dynamic colors based on state:

RadioDeck::make('priority')
    ->options(['low', 'medium', 'high'])
    ->colors([
        'low' => 'gray',
        'medium' => 'yellow',
        'high' => 'red',
    ]);

5. Multi-Select Workflow

Enable multiple selections with checkboxes:

RadioDeck::make('tags')
    ->options(['laravel', 'filament', 'livewire'])
    ->multiple()
    ->columns(3);

Integration Tips

  1. Theme Consistency:

    • Use ->colors('primary') to match Filament's theme colors
    • Customize via extraCardsAttributes for border-radius, shadows, etc.
  2. Accessibility:

    RadioDeck::make('accessibility')
        ->options(['high', 'medium', 'low'])
        ->descriptions([
            'high' => 'Fully accessible',
            'medium' => 'Partial accessibility',
            'low' => 'Basic accessibility',
        ])
        ->iconSizes(IconSize::Large);
    
  3. Form Validation:

    RadioDeck::make('status')
        ->options(['published', 'draft'])
        ->required()
        ->rules(['required', 'in:published,draft']);
    
  4. Dynamic Data:

    RadioDeck::make('region')
        ->options(fn () => Region::query()->pluck('name', 'id'))
        ->descriptions(fn () => Region::query()->pluck('description', 'id'))
        ->icons(fn () => Region::query()->pluck('icon', 'id'));
    

Gotchas and Tips

Common Pitfalls

  1. Theme Configuration:

    • Gotcha: Forgetting to add @source directive to custom theme CSS
    • Fix: Run php artisan filament:theme if theme isn't applying styles
  2. Multiple Selection:

    • Gotcha: State management issues when using multiple()
    • Fix: Ensure your model handles array values:
      protected $casts = [
          'selected_options' => 'array',
      ];
      
  3. Icon Visibility:

    • Gotcha: Icons not showing in light mode
    • Fix: Use heroicon-o-* (outline) variants instead of heroicon-m-* (mini) for better visibility
  4. Column Layout:

    • Gotcha: Columns not respecting breakpoints
    • Fix: Use responsive array syntax:
      ->columns(['sm' => 1, 'md' => 2, 'lg' => 3])
      
  5. Enum Implementation:

    • Gotcha: Forgetting to implement HasIcons or HasDescriptions
    • Fix: Use trait imports:
      use JaOcero\RadioDeck\Contracts\HasIcons;
      use JaOcero\RadioDeck\Contracts\HasDescriptions;
      

Debugging Tips

  1. View Compilation:

    • Clear cached views: php artisan view:clear
    • Check theme compilation: php artisan filament:theme
  2. State Persistence:

    • Verify model casting for radio deck values:
      protected $casts = [
          'platform' => 'string', // For single selection
          'tags' => 'array',      // For multiple selection
      ];
      
  3. CSS Conflicts:

    • Inspect element to check for overridden styles
    • Use !important in extraCardsAttributes as last resort:
      ->extraCardsAttributes(['class' => '!rounded-xl'])
      

Extension Points

  1. Custom Components:

    // Create custom card component
    RadioDeck::make('custom')
        ->extraCardsAttributes([
            'class' => 'bg-gradient-to-r from-blue-500 to-purple-600',
            'x-data' => '{}',
        ]);
    
  2. Dynamic Content:

    RadioDeck::make('dynamic_options')
        ->options(fn () => $this->getDynamicOptions())
        ->descriptions(fn () => $this->getDescriptions())
        ->reactive();
    
  3. Event Handling:

    RadioDeck::make('event_trigger')
        ->options(['send', 'archive'])
        ->extraOptionsAttributes([
            'x-on:click' => 'handleSelection($event, $value)'
        ]);
    
  4. Localization:

    RadioDeck::make('language')
        ->options([
            'en' => __('English'),
            'es' => __('Spanish'),
        ])
        ->descriptions([
            'en' => __('English description'),
            'es' => __('Spanish description'),
        ]);
    

Performance Considerations

  1. Lazy Loading:

    // For large option sets
    RadioDeck::make('large_set')
        ->options(fn () => Option::query()->limit(50)->get())
        ->descriptions(fn () => Option::query()->limit(50)->pluck('description'))
        ->icons(fn () => Option::query()->limit(50)->pluck('icon'));
    
  2. Memoization:

    // Cache expensive option generation
    RadioDeck::make('cached_options')
        ->options(fn () => cache()->remember('radio_deck_options', now()->addHours(1), function () {
            return Option::all();
        }));
    
  3. Asset Optimization:

    • Use SVG icons directly instead of Heroicons for reduced HTTP requests
    • Minimize custom CSS classes to reduce bundle size

Configuration Quirks

  1. Color System:
    • Supports
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor