panel:icons
Membangun ulang frontend icon registry berdasarkan nama icon yang benar-benar diminta oleh source PHP.
Jalankan setiap kali Anda menambahkan:
->icon('...')atau:
$navigationIconGunakan --check di CI agar icon registry yang lupa diregenerate membuat build gagal, bukan menghasilkan button kosong di production.
php artisan panel:iconsOutput:
INFO Registered 24 icons.Lucide menyediakan sangat banyak icon, sementara sebuah Panel biasanya hanya memakai puluhan. Registry memastikan bundle hanya membawa icon yang benar-benar dibutuhkan.
Registry tetap merupakan build-time allowlist:
nama icon yang tidak ada di registry tetap tidak dapat di-resolve.
Bedanya, list tersebut sekarang dibangun otomatis dari source, bukan dipelihara manual.
Signature
panel:icons
{--check : Fail instead of writing, for CI}2
| Option | Default | Efek |
|---|---|---|
--check | off | Tidak menulis file. Membandingkan output yang seharusnya dihasilkan dengan file di disk dan gagal jika berbeda. |
php artisan panel:icons
php artisan panel:icons --check2
Source yang Dipindai
Dua root dipindai untuk file .php:
| Root | Alasan |
|---|---|
app_path() | Panels, Resources, Pages, Widgets, dan Actions milik application. |
src/ milik package | Built-in actions juga memiliki icon seperti delete/edit/export. Jika hanya app/ yang dipindai, built-in icon dapat hilang dari registry. |
Nama icon dibaca langsung dari source, bukan dari Panel yang sudah diboot.
Alasannya, icon dapat dideklarasikan di lokasi yang tidak selalu ditemukan oleh runtime traversal, misalnya:
- wizard step;
- filter tab;
- header action di dalam method.
String literal pada source adalah common denominator yang lebih dapat diandalkan.
Pola yang Dikenali
Lima pola utama:
| Bentuk | Contoh |
|---|---|
->icon('…') | Action::make('delete')->icon('trash') |
$navigationIcon = '…' | protected static ?string $navigationIcon = 'folder'; |
icon: '…' | named argument pada Stat::make(...)->icon(icon: 'users') |
'icon' => '…' | array key pada serialized action/navigation |
Icon::make('…') | PandaPanel\Forms\Prime\Icon::make('shield') |
use PandaPanel\Actions\Action;
use PandaPanel\Forms\Prime\Icon;
Action::make('approve')->icon('check'); // ditemukan
protected static ?string $navigationIcon = 'users'; // ditemukan
Icon::make('shield'); // ditemukan2
3
4
5
6
Special Case: Method icon()
Contoh:
public function icon(): string
{
return match ($this) {
self::Draft => 'pencil',
self::Published => 'check',
};
}2
3
4
5
6
7
Enum sering mengembalikan icon name melalui match, yang tidak cocok dengan lima pola di atas.
Karena itu seluruh body method dengan signature icon(): string dipindai untuk single-quoted lowercase-kebab strings.
Scan dibatasi hanya pada method tersebut agar string biasa di match lain tidak salah dianggap sebagai icon.
Hanya nama lowercase kebab yang dikenali:
[a-z0-9-]+Icon name yang disimpan di constant atau dirakit melalui concatenation tidak terlihat oleh scanner.
File yang Ditulis
Default:
resources/js/panel/icons/registry.tsPath di-resolve melalui:
PandaPanel\Support\FrontendPaths::panel('icons/registry.ts')Jadi project yang mengubah frontend.panel_path tetap mendapatkan registry di lokasi yang benar.
Contoh output:
import {
Check,
Folder,
Trash,
Users,
} from '@lucide/vue';
import type { Component } from 'vue';
const ICONS = {
check: Check,
folder: Folder,
trash: Trash,
users: Users,
} satisfies Record<string, Component>;
export type PanelIconName = keyof typeof ICONS;
export function isPanelIconName(name: string): name is PanelIconName {
return name in ICONS;
}
export function resolveIcon(name: string | null | undefined): Component | null {
// …
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Nama di-sort agar file stabil antar-run dan antar-machine.
Kebab name menggunakan quoted key, misalnya:
'rotate-ccw': RotateCcwsingle-word name dapat menggunakan key biasa.
resolveIcon() mengembalikan null untuk icon yang tidak tersedia.
Pada development, unknown icon juga memunculkan warning satu kali:
[panel] The icon [trash-2] is not in the icon registry, so nothing is drawn for
it. Run `php artisan panel:icons` to rebuild the registry from the icons your
panels declare.2
3
Jangan edit registry secara manual. Run berikutnya akan menimpanya.
Validasi Nama terhadap Lucide
Setiap icon yang ditemukan dicek terhadap file yang benar-benar disediakan Lucide:
node_modules/@lucide/vue/dist/esm/icons/*.mjsTypo menghasilkan:
ERROR Not a Lucide icon: trahs, user-circle-2Unknown name:
- dibuang dari registry;
- membuat command exit non-zero.
Tanpa validation ini, typo hanya akan menghasilkan UI tanpa icon dan tidak ada runtime error.
Jika @lucide/vue belum diinstall:
WARN @lucide/vue is not installed; nothing to check names against.Dalam kondisi tersebut semua nama diterima apa adanya.
Framework tidak menganggap semua nama invalid karena menjalankan command sebelum npm install seharusnya tidak menghapus seluruh registry.
--check untuk CI
php artisan panel:icons --checkJika up-to-date:
INFO The icon registry is up to date.Jika tidak:
ERROR The icon registry is out of date. Run php artisan panel:icons.Tidak ada file yang ditulis.
Contoh CI:
- run: npm ci
- run: php artisan panel:icons --check2
Jalankan npm ci lebih dahulu agar command dapat memvalidasi icon terhadap Lucide package.
Exit Codes
| Run | Hasil | Code |
|---|---|---|
| default | Registry ditulis, semua nama valid | 0 |
| default | Registry ditulis, ada nama bukan icon Lucide | 1 |
--check | File match dan semua nama valid | 0 |
--check | File match tetapi ada unknown name | 1 |
--check | File berbeda dari expected output | 1 |
Default run tetap menulis registry walaupun ada unknown icon. Icon yang valid tetap harus tersedia; non-zero exit hanya menandakan typo/unknown name.
Hal yang Perlu Diperhatikan
- Registry adalah build artifact tetapi juga committed file. Perubahan file tracked inilah yang membuat
--checkberguna di CI. - Regenerate registry saja belum cukup. Jalankan
npm run devataunpm run buildkarena file TypeScript harus dikompilasi. - Nama yang disimpan pada variable/constant tidak terdeteksi.
- Nama harus lowercase kebab.
'ArrowRight'tidak cocok scanner. - Menjalankan sebelum
npm installmenonaktifkan validation terhadap Lucide. - Scanner membaca
app/dansrc/package ini saja. Plugin dari Composer package lain tidak ikut dipindai. Icon plugin perlu dideklarasikan di bawahapp/atau diakomodasi melalui published plugin component.