This package introduces eight new form fields for FilamentPHP. Four of them are based on Radio, and four are based on CheckboxList.
- Filament 4/5
1. Install with Composer:
composer require codewithdennis/filament-advanced-choice2. To make sure styling works, add this to your custom FilamentPHP theme:
@source '../../../../vendor/codewithdennis/filament-advanced-choice/resources/**/*.blade.php';3. Run npm run build or npm run dev so the theme rebuilds.
Prefer the singular field classes (RadioCard, RadioStackedCard, CheckboxCard, CheckboxStackedCard). The plural names (RadioCards, RadioStackedCards, CheckboxCards, CheckboxStackedCards) remain as deprecated aliases for backward compatibility.
Vertical list layout with descriptions for multiple selections.
CheckboxList::make('delivery_type')
->searchable()
->bulkToggleable()
->options([
'standard' => 'Standard Delivery',
'express' => 'Express Delivery',
'overnight' => 'Overnight Delivery',
'same_day' => 'Same Day Delivery',
'economy' => 'Economy Delivery',
'premium' => 'Premium Delivery',
'international' => 'International Delivery',
'local' => 'Local Delivery',
])
->descriptions([
'standard' => 'Delivery within 5-7 business days',
'express' => 'Delivery within 2-3 business days',
'overnight' => 'Next day delivery available',
'same_day' => 'Delivery on the same day',
'economy' => 'Budget-friendly delivery option',
'premium' => 'Premium service with tracking',
'international' => 'Worldwide shipping available',
'local' => 'Same city delivery service',
])
->extras([
'standard' => '$5.00 flat rate',
'express' => '$10.00 flat rate',
'overnight' => '$20.00 flat rate',
'same_day' => '$25.00 flat rate',
'economy' => '$3.00 flat rate',
'premium' => '$15.00 flat rate',
'international' => '$50.00 flat rate',
'local' => '$8.00 flat rate',
]);Card-based layout with descriptions and extras support for multiple selections.
CheckboxCard::make('delivery_type')
->searchable()
->bulkToggleable()
->options([
'standard' => 'Standard Delivery',
'express' => 'Express Delivery',
'overnight' => 'Overnight Delivery',
'same_day' => 'Same Day Delivery',
'economy' => 'Economy Delivery',
'premium' => 'Premium Delivery',
'international' => 'International Delivery',
'local' => 'Local Delivery',
])
->descriptions([
'standard' => 'Delivery within 5-7 business days',
'express' => 'Delivery within 2-3 business days',
'overnight' => 'Next day delivery available',
'same_day' => 'Delivery on the same day',
'economy' => 'Budget-friendly delivery option',
'premium' => 'Premium service with tracking',
'international' => 'Worldwide shipping available',
'local' => 'Same city delivery service',
])
->extras([
'standard' => '$5.00 flat rate',
'express' => '$10.00 flat rate',
'overnight' => '$20.00 flat rate',
'same_day' => '$25.00 flat rate',
'economy' => '$3.00 flat rate',
'premium' => '$15.00 flat rate',
'international' => '$50.00 flat rate',
'local' => '$8.00 flat rate',
]);Stacked card layout with descriptions and extras support for multiple selections.
CheckboxStackedCard::make('delivery_type')
->options(DeliveryTypeEnum::class)
->searchable()
->bulkToggleable();Responsive table layout with descriptions for multiple selections.
CheckboxTable::make('delivery_type')
->options(DeliveryTypeEnum::class)
->searchable()
->bulkToggleable();Vertical list layout with descriptions.
RadioList::make('delivery_type')
->options(DeliveryTypeEnum::class);Responsive table layout with descriptions.
RadioTable::make('delivery_type')
->options(DeliveryTypeEnum::class);Card-based layout with descriptions and extras support.
Smallest useful example with options(), descriptions(), and extras():
RadioCard::make('plan')
->options([
'hobby' => 'Hobby',
'pro' => 'Pro',
])
->descriptions([
'hobby' => 'For side projects',
'pro' => 'For teams',
])
->extras([
'hobby' => '$9/mo',
'pro' => '$29/mo',
]);Same layout with a backed enum:
RadioCard::make('delivery_type')
->options(DeliveryTypeEnum::class);Stacked card layout with descriptions and extras support.
RadioStackedCard::make('delivery_type')
->options(DeliveryTypeEnum::class);These come from FilamentPHP’s Radio and CheckboxList APIs (inherited unchanged).
Search:
CheckboxList::make('delivery_type')
->options(DeliveryTypeEnum::class)
->searchable()
->searchPrompt('Search delivery types...')
->noSearchResultsMessage('No delivery types found.');Bulk select (checkbox-style fields only):
CheckboxList::make('delivery_type')
->options(DeliveryTypeEnum::class)
->bulkToggleable();Disable one option:
CheckboxList::make('delivery_type')
->options(DeliveryTypeEnum::class)
->disableOptionWhen(fn (string $value): bool => $value === 'premium');Pass a backed enum class name to options() instead of an array. Implement:
Filament\Support\Contracts\HasLabel(main label)Filament\Support\Contracts\HasDescription(subtitle)CodeWithDennis\FilamentAdvancedChoice\Filament\Interfaces\HasExtra(extras()column)
Full enum example
<?php
declare(strict_types=1);
namespace App\Enums;
use CodeWithDennis\FilamentAdvancedChoice\Filament\Interfaces\HasExtra;
use Filament\Support\Contracts\HasDescription;
use Filament\Support\Contracts\HasLabel;
enum DeliveryTypeEnum: string implements HasDescription, HasExtra, HasLabel
{
case Standard = 'standard';
case Express = 'express';
case Overnight = 'overnight';
case SameDay = 'same_day';
case Economy = 'economy';
case Premium = 'premium';
case International = 'international';
case Local = 'local';
public function getLabel(): string
{
return match ($this) {
self::Standard => __('Standard Delivery'),
self::Express => __('Express Delivery'),
self::Overnight => __('Overnight Delivery'),
self::SameDay => __('Same Day Delivery'),
self::Economy => __('Economy Delivery'),
self::Premium => __('Premium Delivery'),
self::International => __('International Delivery'),
self::Local => __('Local Delivery'),
};
}
public function getDescription(): string
{
return match ($this) {
self::Standard => __('Delivery within 5-7 business days'),
self::Express => __('Delivery within 2-3 business days'),
self::Overnight => __('Next day delivery available'),
self::SameDay => __('Delivery on the same day'),
self::Economy => __('Budget-friendly delivery option'),
self::Premium => __('Premium service with tracking'),
self::International => __('Worldwide shipping available'),
self::Local => __('Same city delivery service'),
};
}
public function getExtra(): ?string
{
return match ($this) {
self::Standard => __('$5.00 flat rate'),
self::Express => __('$10.00 flat rate'),
self::Overnight => __('$20.00 flat rate'),
self::SameDay => __('$25.00 flat rate'),
self::Economy => __('$3.00 flat rate'),
self::Premium => __('$15.00 flat rate'),
self::International => __('$50.00 flat rate'),
self::Local => __('$8.00 flat rate'),
};
}
}Example schema snippet
use App\Enums\DeliveryTypeEnum;
use CodeWithDennis\FilamentAdvancedChoice\Filament\Forms\Components\RadioStackedCard;
use Filament\Schemas\Schema;
public static function configure(Schema $schema): Schema
{
return $schema
->columns(1)
->components([
RadioStackedCard::make('delivery_type')
->options(DeliveryTypeEnum::class),
]);
}If a case implements getColor(), some layouts tint that option (same idea as core FilamentPHP enums).
Either pass extras([...]) keyed by the enum value, or rely on getExtra() on each case.
use Filament\Support\Colors\Color;
CheckboxCard::make('plan')
->options(Plan::class)
->color(Color::Rose);CheckboxCard::make('delivery_type')
->options(DeliveryTypeEnum::class)
->hiddenInputs();Hidden input icon
By default, the hidden input icon for card components is heroicon-s-check-circle. You can override it:
RadioCard::make('delivery_type')
->options(DeliveryTypeEnum::class)
->hiddenInputIcon('heroicon-o-chevron-double-down')
->hiddenInputs();visibleInputs() reverses hiddenInputs() (shows the native control again).
Contributions and pull requests are always welcome and appreciated. If you want to discuss a bigger idea first, feel free to open a GitHub issue, but you do not have to. When you open a PR, running composer format first helps keep CI green.
Report suspected vulnerabilities per .github/SECURITY.md. Do not post exploit details in a public issue.
This package is released under the MIT License. The complete terms are in LICENSE.







