Skip to main content
Custom attribute field types can be added to Lunar to control how they are rendered in the panel. To render a form component from an attribute, it must be converted into a Filament form component with a suitable Livewire Synthesizer so it can be hydrated and dehydrated properly.

Create the Field

use Lunar\FieldTypes\Text;

class CustomField extends Text
{
    // ...
}

Create the Field Type

use Lunar\Admin\Support\FieldTypes\BaseFieldType;

class CustomFieldType extends BaseFieldType
{
    protected static string $synthesizer = CustomFieldSynth::class;

    public static function getFilamentComponent(Attribute $attribute): Component
    {
        return TextInput::make($attribute->handle);
    }
}

Adding Settings

Additional settings can be added to a field type. For example, the Number field has min and max settings. To define these settings, tell Filament how to render the configuration inputs.
class CustomFieldType extends BaseFieldType
{
    // ...
    
    public static function getConfigurationFields(): array
    {
        return [
            Grid::make(2)->schema([
                \Filament\Forms\Components\TextInput::make('min_length'),
                \Filament\Forms\Components\TextInput::make('max_length'),
            ]),
        ];
    }
}
These settings are stored in the configuration JSON column for the attribute and can be accessed when rendering the field in the panel.
use Lunar\Admin\Support\FieldTypes\BaseFieldType;

class CustomFieldType extends BaseFieldType
{
    // ...
    
    public static function getFilamentComponent(Attribute $attribute): Component
    {
        $min = (int) $attribute->configuration->get('min_length');
        $max = (int) $attribute->configuration->get('max_length');
        
        return TextInput::make($attribute->handle)->min($min)->max($max);
    }
}

Create the Livewire Synthesizer

A Livewire Synthesizer tells Livewire how to hydrate and dehydrate the values provided to the field type during editing. See the Livewire Synthesizers documentation for more details.
use Lunar\Admin\Support\Synthesizers\AbstractFieldSynth;
use Lunar\FieldTypes\Text;

class CustomFieldSynth extends AbstractFieldSynth
{
    public static $key = 'lunar_custom_field_field';

    protected static $targetClass = CustomField::class;
}

Register the Field

The last step is to register the field type with the AttributeData facade, typically in a service provider.
use Lunar\Admin\Support\Facades\AttributeData;

AttributeData::registerFieldType(\App\FieldTypes\CustomField::class, \App\Panel\FieldTypes\CustomFieldType::class);