Власне поле потрібне, коли жоден вбудований компонент не підходить: вибір точки на карті, редактор розкладу, інтеграція сторонньої JS-бібліотеки.
php artisan make:filament-form-field LocationPicker
Клас поля:
use Closure;
use Filament\Forms\Components\Field;
class LocationPicker extends Field
{
protected string $view = 'filament.forms.components.location-picker';
protected float | Closure | null $zoom = null;
public function zoom(float | Closure | null $zoom): static
{
$this->zoom = $zoom;
return $this;
}
public function getZoom(): ?float
{
return $this->evaluate($this->zoom); // підтримка замикань з утилітами
}
}
Шаблон поля:
<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
<div
x-data="{ state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$getStatePath()}')") }} }"
x-init="initMap($refs.map, state, {{ $getZoom() ?? 10 }})"
>
<div x-ref="map" class="h-64"></div>
</div>
</x-dynamic-component>
Ключові моменти:
$getStatePath()- шлях до властивості Livewire, де живе значення поля (data.location). Саме через нього поле читає й пише стан;$applyStateBindingModifiers()- щоб поле поважалоlive(),live(onBlur: true)тощо, як вбудовані. Без цього->live()на вашому полі нічого не змінить;$getFieldWrapperView()- стандартна обгортка з підписом, підказкою й помилками валідації;$this->evaluate()в гетері - дозволяє передавати не лише значення, а й замикання зGet,$record,$operation.
Чого не робити:
- поле - не Livewire-компонент. Публічні властивості й методи класу поля в Blade недоступні як
wire:modelчиwire:click. Потрібну конфігурацію віддають через гетери ($getZoom()); - щоб викликати PHP-метод поля з JavaScript, його позначають атрибутом
#[ExposedLivewireMethod]і викликають через$wire.callSchemaComponentMethod(). Без атрибута метод викликати не можна - це захист від виконання довільних методів; - важкі JS-бібліотеки не варто підключати глобально на кожну сторінку панелі - Filament уміє асинхронно завантажувати Alpine-компоненти через систему ресурсів, лише там, де поле є.
Валідація працює як для будь-якого поля: ->required(), ->rules([...]) на рівні PHP.