# Custom field

## Forget the label, help and error messages.

Don't create code for labels, help or error messages when creating a custom field, it's automatically added by the form component.

## Extend existing component, instead of creating a custom field

If you are looking to change the styling of an existing field it is enough to extend the fields Blade Class or create your own theme.

## Steps to create a custom field

### 1. Create a Field class that extends BaseField

* Name your class in a **non-conflicting** and descriptive way
* add the `$type` property,  best practice is to slug case the class name.

```php
namespace YourNameSpace;

use Tanthammar\TallForm\BaseField;

class MyField extends BaseField
{
    public $specialProp; //example adding your own properties

    // all properties that exists in BaseField or its traits should be set in the overrides() method.
    public function overrides(): self
    {
       $this->type = 'my-field'; //required property!
       return $this;
    }

    //now your field has access to all BaseField methods, you can override them or add your own
    public function specialProp($prop): self
    {
        $this->specialProp = $prop;
        return $this;
    }
}
```

### 2. Create a **Blade component class**, with the **same name**

&#x20;Extend  BaseBladeField

```php
use Illuminate\View\View;
use Illuminate\View\Component;
use Tanthammar\TallForms\Traits\BaseBladeField;

class MyField extends BaseBladeField 
{     
    public function __construct(
        public array|object      $field = [],
        public array             $attr = []
    )
    {
        parent::__construct((array)$field, $attr);
        $this->attr = array_merge($this->inputAttributes(), $attr);
    }
    
    //add defaults for headless use cases
    protected function defaults(): array
    {
        return [
            'id' => 'select', //input name and wire:model is autogenerated from the id attribute
            'placeholder' => 'my placeholder',
            'class' => 'form-input my-1 w-full shadow', //error class is autogenerated in BaseBladeField
            'wrapperClass' => null,
            'disabled' => false,
        ];
    }
    
    //add input attributes
    protected function inputAttributes(): array
    {
        $custom = data_get($this->field, 'attributes.input', []); //support field->inputAttr()
        $default = [
            $this->field->wire => $this->field->key,
            'id' => $this->field->id,
            'name' => $this->field->name
        ];
        return array_merge($default, $custom);
    }
    
    public function render(): View
    {
        return view('components.my-field'); //observe the file name
    }
}
```

### 3. Create a blade component view

* `resources/views/components/my-field.blade.php`.&#x20;
* ***Name the view the same as the field `$type`***.
* You have access to all the `$field` attributes and methods, in your blade view.

Example using an input field based on `MyField` blade component class:

```markup
<div>
    <div>{{ $field->specialProp }}</div>
    <input
        @if($field->disabled) disabled @endif
        {{ $attributes->except([...array_keys($attr), 'disabled'])
            ->merge($attr)
            ->merge(['class' => $errors->has($field->key) ? $field->errorClass : $field->class ]) 
        }} />
</div>
```

### 4. Use your field in a form component

```
MyField::make(...)
```

## Please share your field!

If you make a new field. Please share it! Make a PR or paste the code in an issue, and I'll add it to the package.
