rawilk / filament-inner-nav
为 filament 面板页面添加内嵌导航。
Requires
- php: ^8.1|^8.2|^8.3
- filament/support: ^3.0
- illuminate/contracts: ^10.0
- spatie/laravel-package-tools: ^1.14
Requires (Dev)
- filament/filament: ^3.0
- laravel/pint: ^1.0
- nunomaduro/collision: ^7.9
- nunomaduro/larastan: ^2.0.1
- orchestra/testbench: ^8.0
- pestphp/pest: ^2.10
- pestphp/pest-plugin-laravel: ^2.2
- spatie/laravel-ray: ^1.31
This package is auto-updated.
Last update: 2024-09-23 06:28:49 UTC
README
filament-inner-nav
包允许您将 Filament 面板中的资源页面组织成一组“内嵌导航”页面。这对于拥有许多子页面的资源页面非常有用,例如查看/编辑用户记录时。
安装
您可以通过 composer 安装此包
composer require rawilk/filament-inner-nav
您可以使用以下命令发布配置文件
php artisan vendor:publish --tag="filament-inner-nav-config"
您可以在以下位置查看默认配置: https://github.com/rawilk/filament-inner-nav/blob/main/config/filament-inner-nav.php
可以使用以下命令发布视图
php artisan vendor:publish --tag="filament-inner-nav-views"
用法
-
首先,您需要生成一个 Filament 资源页面,然后将您的自定义资源页面添加到
getPages
数组中。例如,一个UserResource
use App\Filament\Resources\UserResource\Pages; use Filament\Resources\Resource; class UserResource extends Resource { // ... public static function getPages(): array { 'index' => Pages\ListUsers::route('/'), 'create' => Pages\CreateUser::route('/create'), 'edit' => Pages\EditUser::route('/{record}/edit'), // custom pages... 'authentication' => Pages\UserAuthentication::route('/{record}/authentication'), 'contact' => Pages\Contact::route('/{record}/contact'), 'activity' => Pages\Activity::route('/{record}/activity'), } // ... }
-
在您的每个自定义资源页面上定义一个
$record
属性public ModelName $record; // public User $record;
请务必将
ModelName
更改为您的模型类名。 -
在您的资源上定义一个
innerNav
静态方法use App\Models\User; use Filament\Resources\Resource; use Rawilk\FilamentInnerNav\InnerNav; use Rawilk\FilamentInnerNav\InnerNavItem; class UserResource extends Resource { // ... public static function innerNav(User $record): InnerNav { return InnerNav::make() ->setNavigationItems([ InnerNavItem::make('Edit User') ->url(fn (): string => static::getUrl('edit', ['record' => $record])), InnerNavItem::make('Password & Authentication') ->url(fn (): string => static::getUrl('authentication', ['record' => $record])), InnerNavItem::make('Contact Information') ->url(fn (): string => static::getUrl('contact', ['record' => $record])), InnerNavItem::make('Activity') ->url(fn (): string => static::getUrl('activity', ['record' => $record])), ]); } }
-
在每个自定义页面上,使用
<x-filament-inner-nav::page>
Blade 组件包裹内容<!-- file: filament.resources.user-resource.pages.authentication --> <x-filament-panels::page> <x-filament-inner-nav::page> <!-- page content here --> </x-filament-inner-nav::page> </x-filament-panels::page>
如果导航样式不正确,您可能需要运行
filament:upgrade
命令来确保发布最新的资源。
高级用法
启用 wire:navigate
通过在 InnerNav
对象上使用 wireNavigate()
方法,允许使用 livewire 的 wire:navigate
public static function innerNav(User $record): InnerNav { return InnerNav::make() ->wireNavigate() ->setNavigationItems([ // ... ]); }
此选项可以在服务提供器中全局配置。请参阅 全局配置。
标题 & 描述
您可以通过在 InnerNav
对象上使用 setTitle()
和 setDescription()
方法设置导航的标题和/或描述。这些将直接显示在导航项上方。
public static function innerNav(User $record): InnerNav { return InnerNav::make() ->setTitle('Nav title') ->setDescription('Nav description') ->setNavigationItems([ // ... ]); }
对于更高级的定制,您可以从闭包中返回一个 HtmlString
对象,使用这些方法中的任何一个
public static function innerNav(User $record): InnerNav { return InnerNav::make() ->setTitle(fn (): HtmlString => new HtmlString('<h1>' . $record->name . '</h1>')) ->setDescription(fn (): HtmlString => new HtmlString('<p>Nav description</p>')) ->setNavigationItems([ // ... ]); }
如果需要,您也可以通过在
title()
方法的闭包中调用view('...')
来返回一个自定义视图。
项目图标
您可以通过在 InnerNavItem
对象上使用 icon()
方法为每个导航项设置一个图标。
public static function innerNav(User $record): InnerNav { return InnerNav::make() ->setNavigationItems([ InnerNavItem::make('Edit User') ->url(fn (): string => static::getUrl('edit', ['record' => $record])) ->icon('heroicon-o-pencil'), ]); }
项目激活状态
默认情况下,没有设置任何导航项的激活状态。您可以通过在 InnerNavItem
对象上调用 isActiveWhen()
方法来设置激活状态。
public static function innerNav(User $record): InnerNav { return InnerNav::make() ->setNavigationItems([ InnerNavItem::make('Edit User') ->url(fn (): string => static::getUrl('edit', ['record' => $record])) ->isActiveWhen(fn (): bool => request()->route()->action['as'] === 'filament.resources.users.edit') ]); }
项目可见性
可以通过在 InnerNav
对象上调用 visible()
或 hidden()
方法来隐藏项目,使其在 UI 中不可见。
public static function innerNav(User $record): InnerNav { return InnerNav::make() ->setNavigationItems([ InnerNavItem::make('Edit User') ->url(fn (): string => static::getUrl('edit', ['record' => $record])) ->visible(fn (): bool => auth()->user()->can('edit', $record)), ]); }
禁用项目
在某些情况下,您可能仍然想显示导航链接,但禁用用户实际访问它。您可以使用 InnerNavItem
对象上的 isDisabledWhen()
方法来实现这一点。
public static function innerNav(User $record): InnerNav { return InnerNav::make() ->setNavigationItems([ InnerNavItem::make('Edit User') ->url(fn (): string => static::getUrl('edit', ['record' => $record])) ->isDisabledWhen(fn (): bool => ! auth()->user()->can('edit', $record)), ]); }
项目徽章
您可以通过在 InnerNavItem
对象上调用 badge()
方法向任何导航项添加徽章。
public static function innerNav(User $record): InnerNav { return InnerNav::make() ->setNavigationItems([ InnerNavItem::make('Edit User') ->url(fn (): string => static::getUrl('edit', ['record' => $record])) ->badge('New'), ]); }
分组
您可以使用 InnerNavGroup
对象在导航中将项目分组。一个组可以是可折叠的或静态的。可折叠的组可以嵌套在静态组内部。下面是每个组的示例。
可折叠组
可折叠分组允许您在可以切换项目可见性的按钮下方嵌套一组导航项。这个UI的设计灵感来源于GitHub在您的账户设置页面上处理子导航的方式。
public static function innerNav(User $record): InnerNav { return InnerNav::make() ->setNavigationItems([ InnerNavItem::make('Edit User') ->url(fn (): string => static::getUrl('edit', ['record' => $record])), InnerNavGroup::make('Settings') ->icon('heroicon-o-cog') ->items([ InnerNavItem::make('Group item 1') ->url('#'), InnerNavItem::make('Group Item 2') ->url('#'), ]) ]); }
注意:在InnerNavGroup
对象上,icon
方法是可选的。
在
InnerNavGroup
下方的InnerNavItem
对象不允许有图标。
默认情况下,可折叠分组是折叠的。您可以通过调用
InnerNavGroup
对象上的expandByDefault()
方法来更改此设置。如果组内的任何项目被设置为活动状态,组也将展开。
静态分组
也受GitHub UI的启发,静态分组允许您在标题下方渲染导航链接。您需要做的就是向InnerNavGroup
对象上的collapsible()
方法提供一个假值。
public static function innerNav(User $record): InnerNav { return InnerNav::make() ->setNavigationItems([ InnerNavItem::make('Edit User') ->url(fn () => self::getUrl('edit', ['record' => $record])) ->icon('heroicon-o-user'), InnerNavGroup::make('Settings') ->collapsible(false) ->items([ InnerNavGroup::make('Sub Group') ->icon('heroicon-o-rectangle-stack') ->items([ InnerNavItem::make('Sub group item 1') ->url('#'), ]), InnerNavItem::make('Group item 1') ->icon('heroicon-o-rectangle-stack') ->url('#'), InnerNavItem::make('Group Item 2') ->icon('heroicon-o-rectangle-stack') ->url('#'), ]), }
与可折叠分组不同,直接
InnerNavItem
子项允许有图标。
顶部布局
如果您想将链接渲染在内容顶部而不是侧边,您可以使用InnerNav
对象上的setLayout()
方法。
use Rawilk\FilamentInnerNav\Enums\InnerNavLayout; use Rawilk\FilamentInnerNav\InnerNav; public static function innerNav(User $record): InnerNav { return InnerNav::make() ->setLayout(InnerNavLayout::Top) ->setNavigationItems([ // ... ]); }
使用此布局添加的任何
InnerNavGroup
对象都将渲染为下拉菜单。
全局配置
许多在InnerNav
、InnerNavItem
和InnerNavGroup
对象上的选项都可以进行全局配置,通常在某个服务提供者中。
use Illuminate\Support\ServiceProvider; use Rawilk\FilamentInnerNav\Enums\InnerNavLayout; use Rawilk\FilamentInnerNav\InnerNav; use Rawilk\FilamentInnerNav\InnerNavGroup; class AppServiceProvider extends ServiceProvider { public function boot(): void { InnerNav::configureUsing(function (InnerNav $nav) { $nav ->wireNavigate() ->setLayout(InnerNavLayout::Side); }); InnerNavGroup::configureUsing(function (InnerNavGroup $group) { // Expand collapsible groups by default. $group->expandByDefault(); }); } }
样式
此包提供的UI的许多部分都带有自定义CSS类前缀,您可以使用自己的样式覆盖这些样式。所有类名都将以fi-inner-nav-
开头,例如,导航项都有一个类名为fi-inner-nav-item
。
在此列出和维护所有使用的类名并不实用,因此如果您想要对某个元素进行不同的样式设计,您可以在浏览器中检查该元素或查看此存储库中blade组件的源代码。
如果需要样式的元素没有自定义类,您可以提交一个PR来添加一个类,但我不能保证我会合并它。
脚本
设置
为了方便,您可以运行设置二进制脚本来轻松安装本地开发。
./bin/setup.sh
格式化
虽然格式化是通过工作流程自动完成的,但您可以在提交之前使用composer脚本来本地格式化PHP代码。
composer format
测试
composer test
变更日志
请参阅变更日志以获取有关最近更改的更多信息。
贡献
请参阅贡献指南以获取详细信息。
安全性
请审查我的安全策略以了解如何报告安全漏洞。
致谢
替代方案
此包的一些替代方案包括
如果您有类似的包想要添加,请提交一个PR并更新README。
许可协议
MIT许可协议(MIT)。请参阅许可文件以获取更多信息。