Global Component Configuration 之後是接續 Macros 跟 review base component 由於之前已經有針對 Macro 深入理解過,這邊就直接進入構建自定義欄位。
要把 https://iro.js.org/ 整合到自訂欄位內: 創建自訂欄位
$ php artisan make:form-field ColorPicker
//創建 demo form
$ php artisan make:livewire-form DemoForm
開啟 color-picker.blade.php
將 iro.js CDN 掛入並且 new instance:
<script src="https://cdn.jsdelivr.net/npm/@jaames/iro@5"></script>
<x-dynamic-component
:component="$getFieldWrapperView()"
:field="$field"
>
// alpine.js x-*
<div x-data="{ state: $wire.$entangle('{{ $getStatePath() }}') }"
x-init="
const colorPicker = new iro.ColorPicker($refs.picker);
">
<div x-ref="picker"></div> // 配置 ref
</div>
</x-dynamic-component>
添加忽略 wire:ignore
防止 livewire refresh 頁面
<div wire:ignore x-ref="picker"></div>
到 DemoForm
嘗試添加組件:
ColorPicker::make('color1')
添加 default
ColorPicker::make('color1')->default('#ff0000')
到 color-picker.blade.php
進行 state 綁定:
const colorPicker = new iro.ColorPicker($refs.picker, {
color: state
});
// 監聽 picker 顏色如果改變則更新 state
colorPicker.on('color:change', (color) => {
state = color.hexString;
});
添加額外方法 width
class ColorPicker extends Field
{
protected int | \Closure | null $width = null;
public function width(int | \Closure | null $width): static
{
$this->width = $width;
return $this;
}
public function getWidth(): ?int
{
return $this->evaluate($this->width);
}
color-picker.blade.php
進行混合綁定:
<div x-data="{ state: $wire.$entangle('{{ $getStatePath() }}') }"
x-init="
const colorPicker = new iro.ColorPicker($refs.picker, {
@if($getWidth())
width: @js($getWidth()),
@endif
color: state
});
colorPicker.on('color:change', (color) => {
state = color.hexString;
});
">
ColorPicker::make('color1')
->default('#ff0000')
->width(200),
ColorPicker::make('color2')
->default('#000000')
->width(50),