Referensi Entry
Setiap tipe entry, setiap opsi tambahan, nilai default, dan bentuk persis yang diserialisasikan dijelaskan di halaman ini. Biarkan halaman ini terbuka saat menulis infolist; API bersama yang diwarisi semua tipe ada di Entries.
Sebelas tipe entry
| Class | EntryType | type | value yang diserialisasi | TypeScript |
|---|---|---|---|---|
TextEntry | Text | text | string|null | TextEntryDefinition |
BadgeEntry | Badge | badge | {label, color}|null | BadgeEntryDefinition |
BooleanEntry | Boolean | boolean | bool | BooleanEntryDefinition |
DateTimeEntry | DateTime | datetime | string|null | DateTimeEntryDefinition |
KeyValueEntry | KeyValue | key-value | list<{key, value}> | KeyValueEntryDefinition |
IconEntry | Icon | icon | {icon, color, label}|null | IconEntryDefinition |
ImageEntry | Image | image | string|null | ImageEntryDefinition |
ColorEntry | Color | color | string|null | ColorEntryDefinition |
CodeEntry | Code | code | string|null | CodeEntryDefinition |
RepeatableEntry | Repeatable | repeatable | list<{label, schema}> | RepeatableEntryDefinition |
CustomEntry | Custom | custom | unknown | CustomEntryDefinition |
Semua class berada di PandaPanel\Infolists\Components. Case enum berada di PandaPanel\Infolists\Enums\EntryType; union TypeScript berada di resources/js/panel/types/infolist.ts.
Satu contoh untuk tiap tipe
use PandaPanel\Forms\Enums\CodeLanguage;
use PandaPanel\Infolists\Components\BadgeEntry;
use PandaPanel\Infolists\Components\BooleanEntry;
use PandaPanel\Infolists\Components\CodeEntry;
use PandaPanel\Infolists\Components\ColorEntry;
use PandaPanel\Infolists\Components\DateTimeEntry;
use PandaPanel\Infolists\Components\IconEntry;
use PandaPanel\Infolists\Components\ImageEntry;
use PandaPanel\Infolists\Components\KeyValueEntry;
use PandaPanel\Infolists\Components\TextEntry;
use PandaPanel\Tables\Enums\BadgeColor;
return $schema->columns(2)->schema([
TextEntry::make('name'),
BadgeEntry::make('status')->colors(['live' => BadgeColor::Success]),
BooleanEntry::make('is_admin')->labels('Administrator', 'Member'),
DateTimeEntry::make('created_at')->format('Y-m-d'),
KeyValueEntry::make('meta'),
IconEntry::make('status')->icons(['live' => 'check', 'draft' => 'pencil']),
ImageEntry::make('avatar')->disk('public')->circular(),
ColorEntry::make('brand')->copyable(),
CodeEntry::make('payload')->language(CodeLanguage::Json)->copyable(),
]);2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Definisi dasar
Setiap entry lebih dulu menyerialisasikan key berikut sebelum menambahkan data khusus miliknya:
| Key | Tipe | Sumber |
|---|---|---|
component | 'entry' | Tetap — node discriminant |
name | string | make() |
label | string | label(), atau Str::headline() dari nama |
type | nilai EntryType | Class entry |
value | bervariasi | toValue() |
placeholder | string|null | placeholder() |
helperText | string|null | helperText() |
columnSpan | int|'full' | columnSpan() / columnSpanFull() |
action | ActionDefinition|null | action(), null jika hidden, unauthorized, atau record belum ada |
toArray() mengembalikan null sepenuhnya ketika visible() bernilai false.
TextEntry
Pilihan default untuk nilai yang dibaca sebagai kata-kata atau angka.
| Method | Signature | Default |
|---|---|---|
limit() | limit(int $characters): self | null — tanpa truncation |
prose() | prose(bool $prose = true): self | false |
use PandaPanel\Infolists\Components\TextEntry;
TextEntry::make('reference');
TextEntry::make('name')->limit(5);
// 'Grace Hopper' → 'Grace...'
TextEntry::make('body')->prose()->columnSpanFull();2
3
4
5
6
7
8
limit() memotong string menggunakan Str::limit() di server, sehingga payload tetap kecil daripada mengirim seluruh nilai lalu menyembunyikannya dengan CSS. Ellipsis menjadi bagian dari string hasil.
prose() mengganti class renderer dari truncate menjadi text-pretty, sehingga kalimat dapat membungkus ke baris berikutnya alih-alih terpotong satu baris. Ini hanya presentation dan tidak mengubah nilai.
Nilai. Null jika input null atau ''. Scalar dicast dengan (string); selain itu akan di-json_encode(), dan nilai yang gagal diencode menghasilkan null.
['type' => 'text', 'value' => 'Grace Hopper', 'prose' => false]BadgeEntry
Status pendek yang ditampilkan sebagai pill berwarna.
| Method | Signature | Default |
|---|---|---|
colors() | colors(array $colors, BadgeColor $default = BadgeColor::Neutral): self | [], default Neutral |
use PandaPanel\Infolists\Components\BadgeEntry;
use PandaPanel\Tables\Enums\BadgeColor;
BadgeEntry::make('status')->colors([
'open' => BadgeColor::Info,
'done' => BadgeColor::Success,
'void' => BadgeColor::Danger,
], default: BadgeColor::Warning);2
3
4
5
6
7
8
Array colors() di-key berdasarkan nilai yang diwakili badge — setelah formatUsing() jika formatter dideklarasikan. Warna di-resolve di server sehingga frontend hanya perlu memetakan nama warna ke class literal, bukan memutuskan makna sebuah nilai.
PandaPanel\Tables\Enums\BadgeColor adalah closed set: Neutral, Success, Warning, Danger, Info. Set ini tertutup karena setiap case dipetakan ke class Tailwind literal di resources/js/panel/palette.ts, yang dipakai bersama tabel dan form — status yang sama memakai warna yang sama di mana pun ditampilkan.
Nilai. Null untuk null atau ''. Nilai non-scalar menjadi label kosong dan kemudian menggunakan warna default.
['type' => 'badge', 'value' => ['label' => 'open', 'color' => 'info']]BooleanEntry
Tanda centang atau silang dengan teks di sampingnya.
| Method | Signature | Default |
|---|---|---|
labels() | labels(string $true, string $false): self | 'Yes' / 'No' |
use PandaPanel\Infolists\Components\BooleanEntry;
BooleanEntry::make('email_verified_at')->labels('Verified', 'Unverified');2
3
Semua nilai dapat digunakan, tidak hanya kolom boolean: nilai dicast dengan (bool), sehingga timestamp nullable dapat dibaca sebagai pertanyaan "apakah ini sudah pernah terjadi".
Nilai. Selalu boolean nyata dan tidak pernah null — itulah sebabnya placeholder() tidak pernah digunakan pada tipe ini.
['type' => 'boolean', 'value' => true, 'trueLabel' => 'Verified', 'falseLabel' => 'Unverified']DateTimeEntry
| Method | Signature | Default |
|---|---|---|
format() | format(string $format): self | 'M j, Y g:ia' |
since() | since(bool $since = true): self | false |
use PandaPanel\Infolists\Components\DateTimeEntry;
DateTimeEntry::make('created_at')->label('Joined'); // 'Aug 15, 2026 6:34pm'
DateTimeEntry::make('created_at')->format('Y-m-d'); // '2026-08-15'
DateTimeEntry::make('updated_at')->since(); // '3 days ago'2
3
4
5
format() menerima string format tanggal PHP yang diteruskan ke Carbon::format().
since() menampilkan diffForHumans() yang dihitung di server. String tidak terus berubah ketika halaman dibiarkan terbuka; refresh yang memperbaruinya. Jika format() dan since() sama-sama diaktifkan, since() menang.
Nilai. Null hanya jika input benar-benar null. DateTimeInterface digunakan langsung; selain itu nilai dicast ke string lalu diparse melalui Date::parse().
['type' => 'datetime', 'value' => '3 days ago']KeyValueEntry
Array atau kolom JSON yang dirender menjadi pasangan key/value dalam daftar tiga kolom.
Tipe ini tidak menambahkan method apa pun. Semua kebutuhan dasarnya berasal dari Entry.
use PandaPanel\Infolists\Components\KeyValueEntry;
KeyValueEntry::make('meta')->placeholder('Nothing recorded.');2
3
Nilai. [] jika nilainya bukan array. Key dicast dengan (string); item scalar dicast, sedangkan nilai nested di-json_encode():
['plan' => 'pro', 'seats' => 4, 'flags' => ['beta']]
// becomes
[
['key' => 'plan', 'value' => 'pro'],
['key' => 'seats', 'value' => '4'],
['key' => 'flags', 'value' => '["beta"]'],
]2
3
4
5
6
7
8
Flattening dilakukan di sini, bukan di Vue, sehingga nilai nested tidak pernah tiba sebagai object yang tidak memiliki branch pada renderer.
['type' => 'key-value', 'value' => [['key' => 'plan', 'value' => 'pro']]]IconEntry
Nilai yang ditampilkan sebagai ikon, bukan sebagai teks.
| Method | Signature | Default |
|---|---|---|
icons() | icons(array $icons): self | [] |
colors() | colors(array $colors, BadgeColor $default = BadgeColor::Neutral): self | [], default Neutral |
iconUsing() | iconUsing(Closure $callback): self | null |
use PandaPanel\Infolists\Components\IconEntry;
use PandaPanel\Tables\Enums\BadgeColor;
IconEntry::make('two_factor_confirmed_at')
->label('Two-factor')
->formatUsing(static fn (mixed $value): string => $value === null ? 'off' : 'on')
->icons(['on' => 'shield', 'off' => 'x'])
->colors(['on' => BadgeColor::Success, 'off' => BadgeColor::Neutral]);2
3
4
5
6
7
8
icons() dan colors() sama-sama menggunakan nilai yang diwakilinya sebagai key. Gunakan iconUsing() jika pemilihan ikon bergantung pada lebih dari nilai itu sendiri:
use Illuminate\Database\Eloquent\Model;
IconEntry::make('status')
->iconUsing(static fn (mixed $value, Model $record): ?string => $record->is_locked ? 'shield' : 'check');2
3
4
Jika iconUsing() ditentukan, callback tersebut menggantikan lookup icons() sepenuhnya, tetapi warna tetap di-lookup berdasarkan nilai.
Ikon adalah registry key yang di-resolve melalui resources/js/panel/icons/registry.ts, bukan markup. Nama yang belum diregistrasikan menghasilkan tidak ada ikon, bukan elemen arbitrer. Jalankan php artisan panel:icons setelah menambahkan nama ikon.
Nilai. Null jika ikon yang berhasil di-resolve bukan string non-kosong — sehingga nilai yang tidak memiliki mapping di icons() menampilkan placeholder. Label ikut dikirim bersama ikon karena ikon tanpa teks tidak memiliki nama yang dapat dibaca screen reader; label adalah key nilai yang dicast ke string.
['type' => 'icon', 'value' => ['icon' => 'shield', 'color' => 'success', 'label' => 'on']]ImageEntry
Path file tersimpan yang ditampilkan sebagai gambar.
| Method | Signature | Default |
|---|---|---|
disk() | disk(string $disk): self | null — nilai digunakan apa adanya |
size() | size(int $pixels): self | 96 |
circular() | circular(bool $circular = true): self | false |
use PandaPanel\Infolists\Components\ImageEntry;
ImageEntry::make('avatar')->disk('public')->size(64)->circular();2
3
URL dibangun di server, sehingga browser tidak pernah mengubah nama disk menjadi link:
| Nilai | Hasil |
|---|---|
Bukan string, atau '' | null |
Diawali http:// atau https:// | Digunakan apa adanya — URL absolut sudah menjadi jawaban |
Sebuah path, tanpa disk() | Digunakan apa adanya |
Sebuah path, dengan disk() | Storage::disk($disk)->url($value) |
| Path pada disk tanpa public URL | null — driver melempar RuntimeException dan exception ditangkap |
Untuk private disk, null adalah hasil yang lebih jujur daripada URL yang nantinya 404; renderer kemudian menampilkan placeholder.
size() mengatur width dan height hasil render dalam pixel. Method ini tidak mengubah ukuran file aslinya.
['type' => 'image', 'value' => 'https://…/avatars/one.png', 'size' => 64, 'circular' => true]ColorEntry
Warna tersimpan yang ditampilkan sebagai swatch di samping nilainya.
| Method | Signature | Default |
|---|---|---|
copyable() | copyable(bool $copyable = true): self | false |
use PandaPanel\Infolists\Components\ColorEntry;
ColorEntry::make('brand')->copyable();2
3
Nilai. Divalidasi menggunakan PandaPanel\Forms\Components\ColorPicker::isColor() — pola yang sama dengan color field — dan menjadi null jika gagal. Nilai ini masuk ke attribute style, sehingga string yang sebenarnya stylesheet dan bukan warna harus ditolak sebelum dirender:
ColorEntry::make('brand')->toValue(new Project(['brand' => '#ff0000'])); // '#ff0000'
ColorEntry::make('brand')->toValue(new Project(['brand' => 'red; background: url(x)'])); // null2
Syntax yang diterima adalah hex (#rgb, #rgba, #rrggbb, #rrggbbaa), rgb()/rgba(), dan hsl()/hsla(). Named color seperti red tidak diterima.
copyable() menambahkan tombol Copy yang menulis nilai ke clipboard. Jika browser menolak akses clipboard, kegagalan dibiarkan silent karena nilai tetap terlihat dan dapat disalin manual.
['type' => 'color', 'value' => '#ff0000', 'copyable' => true]CodeEntry
Nilai yang ditampilkan sebagai preformatted text dalam blok monospace.
| Method | Signature | Default |
|---|---|---|
language() | language(CodeLanguage $language): self | CodeLanguage::Plain |
copyable() | copyable(bool $copyable = true): self | false |
use PandaPanel\Forms\Enums\CodeLanguage;
use PandaPanel\Infolists\Components\CodeEntry;
CodeEntry::make('payload')->language(CodeLanguage::Json)->copyable();2
3
4
PandaPanel\Forms\Enums\CodeLanguage adalah closed set: Plain, Json, Html, Css, JavaScript, Php, Sql, Yaml, Markdown. Enum yang sama digunakan code editor field dan dibuat tertutup karena frontend memetakan setiap case ke label tetap, bukan menerima string bebas. Nilai tidak diberi syntax highlighting: language dikirim ke frontend, tetapi renderer tetap menggambar plain monospace text karena syntax highlighting akan menambah dependency highlighter ke setiap bundle panel.
Nilai. Null untuk null atau ''. Scalar dicast ke string. Selain itu nilai di-pretty-print dengan JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES di server sehingga frontend menerima string final yang siap ditampilkan.
Karena itu, mengembalikan array dari formatUsing() adalah cara yang bersih untuk membangun summary block:
use Illuminate\Database\Eloquent\Model;
CodeEntry::make('summary')
->copyable()
->formatUsing(static fn (mixed $value, Model $record): array => [
'id' => $record->getKey(),
'admin' => (bool) $record->getAttribute('is_admin'),
'verified' => $record->getAttribute('email_verified_at') !== null,
]);2
3
4
5
6
7
8
9
['type' => 'code', 'value' => "{\n \"a\": 1\n}", 'language' => 'json', 'copyable' => true]RepeatableEntry
Satu sub-schema yang dirender sekali untuk setiap item.
| Method | Signature | Default |
|---|---|---|
schema() | schema(array $components): self | [] |
columns() | columns(int $columns): self | 1, di-clamp ke 1–4 |
itemLabel() | itemLabel(string $label): self | null |
use PandaPanel\Infolists\Components\RepeatableEntry;
use PandaPanel\Infolists\Components\TextEntry;
RepeatableEntry::make('lines')->itemLabel('Line')->schema([TextEntry::make('product')]);2
3
4
Penjelasan lengkap ada di Repeatable entries.
['type' => 'repeatable', 'columns' => 3, 'value' => [['label' => 'Line 1', 'schema' => [...]]]]CustomEntry
Nilai yang digambar menggunakan komponen Vue milik Anda sendiri.
| Method | Signature | Default |
|---|---|---|
component() | component(string $component): self | '' |
config() | config(array $config): self | [] |
state() | state(Closure $callback): self | null |
use Illuminate\Database\Eloquent\Model;
use PandaPanel\Infolists\Components\CustomEntry;
CustomEntry::make('score')
->component('Panels/Admin/Entries/Gauge')
->config(['max' => 10])
->state(static fn (Model $record): int => 7);2
3
4
5
6
7
Penjelasan lengkap ada di Custom entries.
['type' => 'custom', 'value' => 7, 'componentName' => 'Panels/Admin/Entries/Gauge', 'config' => ['max' => 10]]Memilih tipe berdasarkan nilai
| Bentuk nilai | Gunakan |
|---|---|
| Nama, reference, angka | TextEntry |
| Paragraf | TextEntry dengan prose() dan columnSpanFull() |
| Salah satu dari beberapa status | BadgeEntry, atau IconEntry jika ikon lebih cepat menyampaikan makna |
| Flag, atau timestamp nullable yang berarti "sudah terjadi atau belum" | BooleanEntry |
| Tanggal atau timestamp | DateTimeEntry |
| Object JSON datar | KeyValueEntry |
| Path file tersimpan | ImageEntry |
| String warna | ColorEntry |
| Payload, log line, config blob | CodeEntry |
| Daftar record atau row | RepeatableEntry |
| Tidak termasuk semua kategori di atas | CustomEntry |
Gotcha
DateTimeEntryhanya melakukan null-check. String kosong bukan null, sehingga''akan masuk keDate::parse('')dan hasilnya adalah now. Cast kolom atau guard melaluiformatUsing()jika nilai bisa berupa''.BooleanEntrytidak pernah menampilkan placeholder.(bool) nullbernilai false, sehingga nilai yang hilang dibaca sebagai false label. Pilih label yang eksplisit, misalnyalabels('Verified', 'Unverified'), bukan sekadarlabels('Yes', 'No').ImageEntrytanpadisk()meneruskan raw value. Ini tepat untuk kolom yang memang menyimpan URL, tetapi membingungkan untuk kolom yang menyimpan path karena browser akan me-resolve-nya relatif terhadap URL panel. Tentukan disk.ColorEntrymenolak named colour.redbukan salah satu dari tiga syntax yang diterima dan akan diserialisasi sebagai null.BadgeEntrydanIconEntrymenggunakan nilai yang sudah diformat sebagai key. JikaformatUsing()mengembalikan'Administrator', key padacolors()adalah'Administrator', bukan nilai tersimpan1.CustomEntrymengirimcomponentName, bukancomponent. Keycomponentsudah menjadi node discriminant dan bernilai'entry'untuk setiap tipe.- Tipe tanpa
extraArray()tidak mengirim data tambahan di level top-level.BadgeEntry,DateTimeEntry,KeyValueEntry, danIconEntrymemasukkan hasil resolve ke dalamvalue, sehingga opsi mereka tidak muncul sebagai key terpisah.