Навігація · Filament
Вступ
За замовчуванням Filament реєструє елементи навігації для кожного з ваших ресурсів, кастомних сторінок і кластерів. Ці класи містять статичні властивості й методи, які можна перевизначити, щоб налаштувати відповідний елемент навігації.
Якщо вам потрібен другий рівень навігації в застосунку, скористайтеся кластерами. Вони зручні для групування ресурсів і сторінок разом.
Налаштування підпису елемента навігації
За замовчуванням підпис навігації генерується з назви ресурсу або сторінки. Змінити його можна властивістю $navigationLabel:
protected static ?string $navigationLabel = 'Custom Navigation Label';
Як варіант, можна перевизначити метод getNavigationLabel():
public static function getNavigationLabel(): string
{
return 'Custom Navigation Label';
}
Налаштування іконки елемента навігації
Щоб змінити іконку елемента навігації, перевизначте властивість $navigationIcon у класі ресурсу або сторінки:
use BackedEnum;
use Filament\Support\Icons\Heroicon;
protected static string | BackedEnum | null $navigationIcon = Heroicon::OutlinedDocumentText;
Якщо ви вкажете $navigationIcon = null для всіх елементів у межах однієї групи навігації, ці елементи будуть обʼєднані вертикальною рискою під підписом групи.
Заміна іконки елемента навігації, коли він активний
Ви можете задати іконку навігації, яка використовуватиметься лише для активних елементів, через властивість $activeNavigationIcon:
use BackedEnum;
use Filament\Support\Icons\Heroicon;
protected static string | BackedEnum | null $activeNavigationIcon = Heroicon::OutlinedDocumentText;
Сортування елементів навігації
За замовчуванням елементи навігації сортуються за алфавітом. Це можна змінити властивістю $navigationSort:
protected static ?int $navigationSort = 3;
Тепер елементи навігації з меншим значенням сортування зʼявляться перед тими, у яких воно більше: порядок за зростанням.
Додавання бейджа до елемента навігації
Щоб додати бейдж (badge) поруч з елементом навігації, скористайтеся методом getNavigationBadge() і поверніть вміст бейджа:
public static function getNavigationBadge(): ?string
{
return static::getModel()::count();
}
Якщо getNavigationBadge() повертає значення, бейдж за замовчуванням відображається основним кольором. Щоб задати колір за контекстом, поверніть з методу getNavigationBadgeColor() одне зі значень: danger, gray, info, primary, success або warning:
public static function getNavigationBadgeColor(): ?string
{
return static::getModel()::count() > 10 ? 'warning' : 'primary';
}
Власну підказку (tooltip) для бейджа навігації можна задати у $navigationBadgeTooltip:
protected static ?string $navigationBadgeTooltip = 'The number of users';
Або повернути її з getNavigationBadgeTooltip():
public static function getNavigationBadgeTooltip(): ?string
{
return 'The number of users';
}
Групування елементів навігації
Елементи навігації можна групувати, вказавши властивість $navigationGroup у ресурсі та кастомній сторінці:
use UnitEnum;
protected static string | UnitEnum | null $navigationGroup = 'Settings';
Усі елементи в одній групі навігації відображаються разом під спільним підписом групи, у цьому випадку «Settings». Елементи без групи залишаються на початку навігації.
Групування елементів навігації під іншими елементами
Елементи навігації можна робити дочірніми до інших елементів через властивість $navigationParentItem. Батьківський елемент можна вказати або класом його сторінки чи ресурсу, або його підписом:
use App\Filament\Resources\Notifications\NotificationResource;
use UnitEnum;
protected static ?string $navigationParentItem = NotificationResource::class;
protected static string | UnitEnum | null $navigationGroup = 'Settings';
Як варіант, можна вказати батьківський елемент його підписом:
use UnitEnum;
protected static ?string $navigationParentItem = 'Notifications';
protected static string | UnitEnum | null $navigationGroup = 'Settings';
Також можна визначати батьківський елемент динамічно методом getNavigationParentItem():
use App\Filament\Resources\Notifications\NotificationResource;
public static function getNavigationParentItem(): ?string
{
return NotificationResource::class;
}
Як варіант, можна повернути підпис батьківського елемента:
public static function getNavigationParentItem(): ?string
{
return __('filament/navigation.groups.settings.items.notifications');
}
Батьківський і дочірній елементи мусять належати до однієї групи навігації. Якщо в батьківського елемента є група навігації, ця сама група мусить бути визначена й у дочірнього, інакше правильний батьківський елемент не вдасться визначити. Це діє однаково, чи ви вказуєте батьківський елемент класом, чи підписом.
Якщо ви тягнетеся до третього рівня навігації в такий спосіб, варто розглянути кластери: це логічне групування ресурсів і кастомних сторінок, які можуть мати власну окрему навігацію.
Налаштування груп навігації
Групи навігації можна налаштувати, викликавши navigationGroups() у конфігурації і передавши обʼєкти NavigationGroup у потрібному порядку:
use Filament\Navigation\NavigationGroup;
use Filament\Panel;
use Filament\Support\Icons\Heroicon;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->navigationGroups([
NavigationGroup::make()
->label('Shop')
->icon(Heroicon::OutlinedShoppingCart),
NavigationGroup::make()
->label('Blog')
->icon(Heroicon::OutlinedPencil),
NavigationGroup::make()
->label(fn (): string => __('navigation.settings'))
->icon(Heroicon::OutlinedCog6Tooth)
->collapsed(),
]);
}
У цьому прикладі ми передаємо для груп власну icon() і робимо одну з них згорнутою (collapsed()) за замовчуванням.
Порядок груп навігації
Викликаючи navigationGroups(), ви задаєте новий порядок груп навігації. Якщо потрібно лише перевпорядкувати групи, а не описувати цілий обʼєкт NavigationGroup, достатньо передати підписи груп у новому порядку:
$panel
->navigationGroups([
'Shop',
'Blog',
'Settings',
])
Як зробити групи навігації незгортуваними
За замовчуванням групи навігації можна згортати.
Вимкнути цю поведінку можна викликом collapsible(false) на обʼєкті NavigationGroup:
use Filament\Navigation\NavigationGroup;
use Filament\Support\Icons\Heroicon;
NavigationGroup::make()
->label('Settings')
->icon(Heroicon::OutlinedCog6Tooth)
->collapsible(false);
Або ж зробити це глобально для всіх груп у конфігурації:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->collapsibleNavigationGroups(false);
}
Додавання додаткових HTML-атрибутів до груп навігації
Групі навігації можна передати додаткові HTML-атрибути, які буде обʼєднано із зовнішнім DOM-елементом. Передайте масив атрибутів у метод extraSidebarAttributes() або extraTopbarAttributes(), де ключ - це назва атрибута, а значення - його значення:
NavigationGroup::make()
->extraSidebarAttributes(['class' => 'featured-sidebar-group']),
->extraTopbarAttributes(['class' => 'featured-topbar-group']),
extraSidebarAttributes() застосовується до елементів груп навігації в сайдбарі, а extraTopbarAttributes() - лише до випадних списків груп навігації у верхній панелі, коли використовується верхня навігація.
Реєстрація груп навігації через enum
Для реєстрації груп навігації можна використати клас-перелік (enum): це дозволяє керувати їхніми підписами, іконками й порядком в одному місці, без реєстрації в конфігурації.
Для цього створіть клас-enum із кейсом для кожної групи:
enum NavigationGroup
{
case Shop;
case Blog;
case Settings;
}
Порядок, у якому визначено кейси, визначає порядок груп навігації.
Щоб використати enum-групу навігації для ресурсу чи кастомної сторінки, вкажіть кейс переліку у властивості $navigationGroup:
protected static string | UnitEnum | null $navigationGroup = NavigationGroup::Shop;
Також можна реалізувати в класі-переліку інтерфейс HasLabel, щоб задати власний підпис для кожної групи:
use Filament\Support\Contracts\HasLabel;
enum NavigationGroup implements HasLabel
{
case Shop;
case Blog;
case Settings;
public function getLabel(): string
{
return match ($this) {
self::Shop => __('navigation-groups.shop'),
self::Blog => __('navigation-groups.blog'),
self::Settings => __('navigation-groups.settings'),
};
}
}
Так само можна реалізувати інтерфейс HasIcon, щоб задати власну іконку для кожної групи:
use BackedEnum;
use Filament\Support\Contracts\HasIcon;
use Filament\Support\Icons\Heroicon;
use Illuminate\Contracts\Support\Htmlable;
enum NavigationGroup implements HasIcon
{
case Shop;
case Blog;
case Settings;
public function getIcon(): string | BackedEnum | Htmlable | null
{
return match ($this) {
self::Shop => Heroicon::OutlinedShoppingCart,
self::Blog => Heroicon::OutlinedPencil,
self::Settings => Heroicon::OutlinedCog6Tooth,
};
}
}
Згортуваний сайдбар на десктопі
Щоб сайдбар згортався не лише на мобільних, а й на десктопі, скористайтеся конфігурацією:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->sidebarCollapsibleOnDesktop();
}
За замовчуванням, коли ви згортаєте сайдбар на десктопі, іконки навігації лишаються видимими. Згорнути сайдбар повністю можна методом sidebarFullyCollapsibleOnDesktop():
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->sidebarFullyCollapsibleOnDesktop();
}
Групи навігації у згортуваному сайдбарі на десктопі
Цей підрозділ стосується лише
sidebarCollapsibleOnDesktop(), а неsidebarFullyCollapsibleOnDesktop(), бо повністю згортуваний інтерфейс просто ховає весь сайдбар, а не змінює його вигляд.
Разом зі згортуваним сайдбаром на десктопі ви часто будете використовувати групи навігації. За замовчуванням підписи груп навігації приховуються, коли сайдбар згорнуто, бо для них немає місця. Навіть якщо сама група навігації згортувана, усі її елементи все одно видимі у згорнутому сайдбарі, адже немає підпису групи, на який можна клікнути, щоб її розгорнути.
Ці проблеми вирішуються, і сайдбар набуває дуже мінімалістичного вигляду, якщо передати icon() обʼєктам груп навігації. Коли іконку визначено, у згорнутому сайдбарі замість елементів завжди показується іконка. Клік по іконці відкриває збоку від неї випадний список з елементами групи.
Якщо групі навігації передано іконку, інтерфейс розгорнутого сайдбару не показуватиме іконки елементів, навіть коли вони в елементів є. Так зберігається зрозуміла ієрархія навігації й мінімалістичний дизайн. А от у випадних списках згорнутого сайдбару іконки елементів показуються, бо ієрархія вже ясна з того, що список відкрито.
Реєстрація власних елементів навігації
Щоб зареєструвати нові елементи навігації, скористайтеся конфігурацією:
use Filament\Navigation\NavigationItem;
use Filament\Pages\Dashboard;
use Filament\Panel;
use Filament\Support\Icons\Heroicon;
use function Filament\Support\original_request;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->navigationItems([
NavigationItem::make('Analytics')
->url('https://filament.pirsch.io', shouldOpenInNewTab: true)
->icon(Heroicon::OutlinedPresentationChartLine)
->group('Reports')
->sort(3),
NavigationItem::make('dashboard')
->label(fn (): string => __('filament-panels::pages/dashboard.title'))
->url(fn (): string => Dashboard::getUrl())
->isActiveWhen(fn () => original_request()->routeIs('filament.admin.pages.dashboard')),
// ...
]);
}
Умовне приховування елементів навігації
Елемент навігації можна приховати за умовою, використавши методи visible() або hidden() і передавши умову для перевірки:
use Filament\Navigation\NavigationItem;
NavigationItem::make('Analytics')
->visible(fn(): bool => auth()->user()->can('view-analytics'))
// або
->hidden(fn(): bool => ! auth()->user()->can('view-analytics')),
Вимкнення елементів навігації для ресурсу чи сторінки
Щоб ресурси або сторінки не зʼявлялися в навігації, використайте:
protected static bool $shouldRegisterNavigation = false;
Або перевизначте метод shouldRegisterNavigation():
public static function shouldRegisterNavigation(): bool
{
return false;
}
shouldRegisterNavigation()лише прибирає посилання із сайдбару: він не забороняє користувачу ввести URL напряму. Щоб справді обмежити доступ, застосуйте авторизацію ресурсу або авторизацію сторінки.
Використання верхньої навігації
За замовчуванням Filament використовує навігацію в сайдбарі. Замість неї можна увімкнути верхню навігацію через конфігурацію:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->topNavigation();
}
Налаштування ширини сайдбару
Ширину сайдбару можна задати, передавши її в метод sidebarWidth() у конфігурації:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->sidebarWidth('40rem');
}
Крім того, якщо ви використовуєте метод sidebarCollapsibleOnDesktop(), ширину смуги зі згорнутими іконками можна задати методом collapsedSidebarWidth() у конфігурації:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->sidebarCollapsibleOnDesktop()
->collapsedSidebarWidth('9rem');
}
Розширене налаштування навігації
Метод navigation() можна викликати з конфігурації. Він дозволяє побудувати власну навігацію, яка перекриває автоматично згенеровані Filament елементи. Цей API створено, щоб дати вам повний контроль над навігацією.
Реєстрація власних елементів навігації
Щоб зареєструвати елементи навігації, викличте метод items():
use App\Filament\Pages\Settings;
use App\Filament\Resources\Users\UserResource;
use Filament\Navigation\NavigationBuilder;
use Filament\Navigation\NavigationItem;
use Filament\Pages\Dashboard;
use Filament\Panel;
use Filament\Support\Icons\Heroicon;
use function Filament\Support\original_request;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->navigation(function (NavigationBuilder $builder): NavigationBuilder {
return $builder->items([
NavigationItem::make('Dashboard')
->icon(Heroicon::OutlinedHome)
->isActiveWhen(fn (): bool => original_request()->routeIs('filament.admin.pages.dashboard'))
->url(fn (): string => Dashboard::getUrl()),
...UserResource::getNavigationItems(),
...Settings::getNavigationItems(),
]);
});
}
Реєстрація власних груп навігації
Якщо потрібно зареєструвати групи, викличте метод groups():
use App\Filament\Pages\HomePageSettings;
use App\Filament\Resources\Categories\CategoryResource;
use App\Filament\Resources\Pages\PageResource;
use Filament\Navigation\NavigationBuilder;
use Filament\Navigation\NavigationGroup;
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->navigation(function (NavigationBuilder $builder): NavigationBuilder {
return $builder->groups([
NavigationGroup::make('Website')
->items([
...PageResource::getNavigationItems(),
...CategoryResource::getNavigationItems(),
...HomePageSettings::getNavigationItems(),
]),
]);
});
}
Вимкнення навігації
Навігацію можна вимкнути повністю, передавши false у метод navigation():
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->navigation(false);
}
Як варіант, можна передати замикання, що повертає логічне значення, і вирішувати динамічно. Значення false ховає навігацію, а true рендерить стандартні автоматично знайдені елементи навігації. Це корисно для сценаріїв на кшталт онбордингу чи майстрів налаштування, де навігація має зʼявлятися лише після того, як користувач дійшов до певного стану:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->navigation(fn (): bool => auth()->user()->hasCompletedOnboarding());
}
Вимкнення верхньої панелі
Верхню панель можна вимкнути повністю, передавши false у метод topbar():
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->topbar(false);
}
Заміна Livewire-компонентів сайдбару й верхньої панелі
Livewire-компоненти, які рендерять сайдбар і верхню панель, можна повністю замінити, передавши назву власного класу Livewire-компонента в метод sidebarLivewireComponent() або topbarLivewireComponent():
use App\Livewire\Sidebar;
use App\Livewire\Topbar;
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->sidebarLivewireComponent(Sidebar::class)
->topbarLivewireComponent(Topbar::class);
}
Вимкнення хлібних крихт
Стандартний макет показує хлібні крихти (breadcrumbs), які вказують розташування поточної сторінки в ієрархії застосунку.
Вимкнути їх можна у вашій конфігурації:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->breadcrumbs(false);
}
Додавання хлібної крихти до кастомної сторінки
Кастомні сторінки за замовчуванням не містять хлібної крихти для поточної сторінки. Додати її можна властивістю $breadcrumb:
use Filament\Pages\Page;
class Settings extends Page
{
protected static ?string $breadcrumb = 'Settings';
// ...
}
Включення ієрархії навігації у хлібні крихти
За замовчуванням хлібні крихти сторінки будуються з її ресурсу та звʼязків із батьківськими записами. Наприклад, хлібні крихти сторінки EditRecord виводяться зі сторінок списку й перегляду її ресурсу, а також із батьківських ресурсів у випадку вкладених ресурсів.
Якщо ви хочете, щоб хлібні крихти також відображали повну ієрархію навігації сторінки, включно з її кластером, групою навігації і батьківським елементом навігації, увімкніть цю поведінку у вашій конфігурації:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->breadcrumbs(hasNavigationHierarchy: true);
}
Коли це ввімкнено, ієрархія навігації додається на початок наявних хлібних крихт сторінки. Якщо кастомна сторінка не має $breadcrumb, її заголовок використовується як поточна хлібна крихта, коли ієрархію навігації вдається визначити. Якщо сторінки немає в навігації, використовуються її наявні хлібні крихти.
Перезавантаження сайдбару й верхньої панелі
Після того як сторінку панелі завантажено, сайдбар і верхня панель не перезавантажуються, доки ви не перейдете з цієї сторінки або доки клік по елементу меню не запустить дію. Ви можете вручну перезавантажити ці компоненти, щоб оновити їх, надіславши подію браузера refresh-sidebar або refresh-topbar.
Щоб надіслати подію з PHP, викличте метод $this->dispatch() у будь-якому Livewire-компоненті: класі сторінки, класі менеджера звʼязків або класі віджета:
$this->dispatch('refresh-sidebar');
Коли ваш код живе поза Livewire-компонентом, наприклад у класі власної дії, можна впровадити аргумент $livewire у функцію-замикання і викликати dispatch() на ньому:
use Filament\Actions\Action;
use Livewire\Component;
Action::make('create')
->action(function (Component $livewire) {
// ...
$livewire->dispatch('refresh-sidebar');
})
Як варіант, подію можна надіслати з JavaScript через хелпер $dispatch() з Alpine.js або через нативний браузерний метод window.dispatchEvent():
<button x-on:click="$dispatch('refresh-sidebar')" type="button">
Refresh Sidebar
</button>
window.dispatchEvent(new CustomEvent('refresh-sidebar'));
Перекладаємо з офіційної документації, розділ за розділом, і не ховаємо недоперекладене. Помітили неточність у терміні чи реченні: напишіть, виправимо.