> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lunarphp.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Extending Attributes

> How to add custom attribute field types to the Lunar admin panel.

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

```php theme={null}
use Lunar\FieldTypes\Text;

class CustomField extends Text
{
    // ...
}
```

## Create the Field Type

```php theme={null}
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.

```php theme={null}
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.

```php theme={null}
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](https://livewire.laravel.com/docs/synthesizers) for more details.

```php theme={null}
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.

```php theme={null}
use Lunar\Admin\Support\Facades\AttributeData;

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