Color Picker
PandaPanel\Forms\Components\ColorPicker menyimpan warna sebagai teks dan mengeditnya menggunakan native color input, text box, serta optional row berisi preset swatches. Gunakan field ini ketika sebuah record menyimpan warna yang nantinya akan dirender — misalnya badge, tag, atau aksen theme. Nilai akhirnya digunakan di dalam inline style, sehingga field memvalidasi syntax daripada mempercayai begitu saja input dari browser.
Contoh minimal
use PandaPanel\Forms\Components\ColorPicker;
use PandaPanel\Forms\FormSchema;
FormSchema::make()->schema([
ColorPicker::make('accent_color')
->default('#4f46e5')
->swatches(['#4f46e5', '#059669', '#dc2626', '#d97706']),
]);2
3
4
5
6
7
8
Method
public function swatches(array $swatches): self // list<string>
public static function isColor(string $value): bool2
ColorPicker hanya menambahkan dua method tersebut. Sisanya diwarisi dari Field, termasuk label(), helperText(), placeholder(), default(), required(), columnSpan(), visibility methods, dan lifecycle hooks.
swatches()
Daftar pilihan satu klik yang ditampilkan di bawah control. Setiap value difilter melalui isColor() ketika dikonfigurasi, sehingga entry yang bukan warna tidak pernah dikirim ke browser dan tidak pernah menjadi background-color:
use PandaPanel\Forms\Components\ColorPicker;
ColorPicker::make('accent_color')->swatches([
'#0f172a',
'rgb(79, 70, 229)',
'hsl(160 84% 39%)',
'red; background: url(x)', // dropped
]);2
3
4
5
6
7
8
Ketika swatch diklik, field diisi dengan string tersebut secara persis.
isColor()
Static predicate ini dibuat public karena ColorEntry pada infolist menggunakan pemeriksaan yang sama terhadap value yang sama. Tiga syntax berikut diterima:
| Syntax | Pola | Contoh |
|---|---|---|
| Hex | # diikuti 3, 4, 6, atau 8 digit hex | #fff, #fff8, #4f46e5, #4f46e5cc |
rgb() / rgba() | digit, titik, spasi, koma, %, / | rgb(79, 70, 229), rgba(0 0 0 / 50%) |
hsl() / hsla() | sama seperti di atas ditambah deg | hsl(160 84% 39%) |
use PandaPanel\Forms\Components\ColorPicker;
ColorPicker::isColor('#a1b2c3'); // true
ColorPicker::isColor('rgb(1, 2, 3)'); // true
ColorPicker::isColor('red; background: url(x)'); // false
ColorPicker::isColor('expression(alert(1))'); // false2
3
4
5
6
Dua contoh terakhir adalah alasan pemeriksaan ini penting. Stored color akan diinterpolasi ke attribute style; tanpa validation, string dari database dapat menjadi arbitrary CSS.
Validasi
use PandaPanel\Forms\Components\ColorPicker;
use PandaPanel\Forms\FormSchema;
FormSchema::make()
->schema([ColorPicker::make('accent_color')->required()])
->validationRules();
// [
// 'accent_color' => [
// 'required',
// 'string',
// 'regex:/^#(?:[0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i',
// ],
// ]2
3
4
5
6
7
8
9
10
11
12
13
14
Value yang disubmit harus berupa hex. Built-in rule hanya menerima pola hex, bukan seluruh format yang diterima isColor(). Ini sengaja lebih sempit karena native color input hanya menghasilkan #rrggbb, sehingga hex adalah format yang secara normal dikirim oleh form. Konsekuensinya, sisi display dan sisi write menerima set format yang berbeda. Lihat bagian gotcha di bawah.
Hydration
protected function castForForm(mixed $value): ?stringStored value diteruskan jika berupa string yang diterima isColor(), dan menjadi null jika tidak valid. Record yang menyimpan red atau var(--brand) akan muncul sebagai field kosong karena picker tidak dapat merepresentasikan value tersebut.
use PandaPanel\Forms\Components\ColorPicker;
ColorPicker::make('accent_color')->formValue($record); // '#4f46e5', or null2
3
Behavior control
resources/js/panel/forms/fields/ColorPickerField.vue merender tiga bagian:
- native
<input type="color">yang harus memiliki hex enam digit valid. Value yang belum dapat di-parse tampil hitam di control tersebut, sementara text box tetap mempertahankan teks yang diketik, sehingga input setengah jadi seperti#abtidak diubah di bawah cursor; - text input yang terikat ke raw value sehingga
rgb()danhsl()masih dapat dibaca dan diedit; - row swatches jika
swatches()memiliki isi, dengan indikator pada value yang sedang aktif.
Data yang dikirim ke frontend
interface ColorPickerFieldDefinition extends BaseFieldDefinition {
type: 'color_picker';
swatches: string[];
}2
3
4
Hal yang perlu diperhatikan
swatches() menerima lebih banyak format daripada validation rule. Swatch rgb() atau hsl() dapat tampil dan diklik, tetapi value tersebut kemudian ditolak rule regex saat submit. Gunakan swatch hex kecuali Anda memang mengubah strategi validation:
use PandaPanel\Forms\Components\ColorPicker;
ColorPicker::make('accent_color')
->swatches(['rgb(79, 70, 229)'])
->rules(['regex:/^(#[0-9a-f]{3,8}|rgba?\(.+\)|hsla?\(.+\))$/i']);2
3
4
5
Namun perlu diingat bahwa rules() menambahkan rule; built-in regex hex tetap ada dan keduanya harus lolos. Jika benar-benar ingin menerima format non-hex, package tidak menyediakan setter untuk memperlebar regex bawaan. Pilihan yang konsisten adalah tetap menggunakan hex, atau menyimpan warna melalui TextInput dan memvalidasinya sendiri.
Stored value yang invalid menjadi kosong tanpa error. castForForm() mengembalikan null untuk apa pun yang ditolak isColor(), sehingga legacy data seperti red atau blue terlihat seperti field kosong. Migrasikan data atau petakan melalui formatUsing().
Tidak ada alpha control. Rule menerima hex 4 dan 8 digit, tetapi native color input tidak dapat menghasilkannya. Alpha harus diketik manual melalui text box.
Value selalu berupa string. Tidak ada cast otomatis saat keluar. Simpan dalam varchar pendek; sembilan karakter cukup untuk seluruh bentuk hex yang didukung.
Lihat juga
- Text — jika format warna ditentukan sendiri
- Visibility
- Validation
- Table Columns —
ColorColumn, yang menampilkan value yang disimpan field ini - Infolist Entries —
ColorEntry, yang menggunakan kembaliisColor() - Forms and Schemas