{"id":15937181,"url":"https://github.com/rawilk/filament-inner-nav","last_synced_at":"2025-03-25T07:30:43.046Z","repository":{"id":195541799,"uuid":"692103068","full_name":"rawilk/filament-inner-nav","owner":"rawilk","description":"Add inner navigation to filament panel pages.","archived":false,"fork":false,"pushed_at":"2024-10-21T06:57:53.000Z","size":418,"stargazers_count":3,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-29T13:55:52.404Z","etag":null,"topics":["filament-plugin","filamentphp","laravel","navigation"],"latest_commit_sha":null,"homepage":"","language":"Blade","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rawilk.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"rawilk"}},"created_at":"2023-09-15T15:05:46.000Z","updated_at":"2024-10-21T06:57:50.000Z","dependencies_parsed_at":"2023-12-25T08:23:49.299Z","dependency_job_id":"f6e3679f-3738-4662-97c6-a69adf0b7f59","html_url":"https://github.com/rawilk/filament-inner-nav","commit_stats":{"total_commits":46,"total_committers":3,"mean_commits":"15.333333333333334","dds":0.6086956521739131,"last_synced_commit":"7fae0df41b3adf62e473fb1c14451afec840509e"},"previous_names":["rawilk/filament-inner-nav"],"tags_count":3,"template":false,"template_full_name":"rawilk/package-skeleton-laravel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rawilk%2Ffilament-inner-nav","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rawilk%2Ffilament-inner-nav/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rawilk%2Ffilament-inner-nav/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rawilk%2Ffilament-inner-nav/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rawilk","download_url":"https://codeload.github.com/rawilk/filament-inner-nav/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245418101,"owners_count":20612060,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["filament-plugin","filamentphp","laravel","navigation"],"created_at":"2024-10-07T05:00:49.839Z","updated_at":"2025-03-25T07:30:43.036Z","avatar_url":"https://github.com/rawilk.png","language":"Blade","funding_links":["https://github.com/sponsors/rawilk"],"categories":[],"sub_categories":[],"readme":"\u003e Note: This package is being abandoned because I originally thought I was going to use it, but then I found out I didn't really need it for filament. If anything, this package was a learning experience for me.\n\n# filament-inner-nav\n\n[![Latest Version on Packagist](https://img.shields.io/packagist/v/rawilk/filament-inner-nav.svg?style=flat-square)](https://packagist.org/packages/rawilk/filament-inner-nav)\n![Tests](https://github.com/rawilk/filament-inner-nav/workflows/Tests/badge.svg?style=flat-square)\n[![Total Downloads](https://img.shields.io/packagist/dt/rawilk/filament-inner-nav.svg?style=flat-square)](https://packagist.org/packages/rawilk/filament-inner-nav)\n[![PHP from Packagist](https://img.shields.io/packagist/php-v/rawilk/filament-inner-nav?style=flat-square)](https://packagist.org/packages/rawilk/filament-inner-nav)\n[![License](https://img.shields.io/github/license/rawilk/filament-inner-nav?style=flat-square)](https://github.com/rawilk/filament-inner-nav/blob/main/LICENSE.md)\n\n![Social image](https://banners.beyondco.de/Filament%20Inner%20Navigation.png?theme=light\u0026packageManager=composer+require\u0026packageName=rawilk%2Ffilament-inner-nav\u0026pattern=charlieBrown\u0026style=style_1\u0026description=Add+inner+navigation+to+filament+panel+pages.\u0026md=1\u0026showWatermark=0\u0026fontSize=100px\u0026images=cursor-click)\n\nThe `filament-inner-nav` package allows you to organize resource pages in your Filament panels into a group of \"inner navigation\" pages. This is useful for when you have a\nresource page that has many sub-pages, such as when viewing/editing a user record.\n\n![base screenshot](./images/base.png)\n\n## Installation\n\nYou can install the package via composer:\n\n```bash\ncomposer require rawilk/filament-inner-nav\n```\n\nYou can publish the config file with:\n\n```bash\nphp artisan vendor:publish --tag=\"filament-inner-nav-config\"\n```\n\nYou can view the default configuration here: https://github.com/rawilk/filament-inner-nav/blob/main/config/filament-inner-nav.php\n\nThe views can be published with:\n\n```bash\nphp artisan vendor:publish --tag=\"filament-inner-nav-views\"\n```\n\n## Usage\n\n1. First, you need to generate a filament resource page and then add your custom resource pages to the array from `getPages`. For example, a `UserResource`:\n\n    ```php\n    use App\\Filament\\Resources\\UserResource\\Pages;\n    use Filament\\Resources\\Resource;\n\n    class UserResource extends Resource\n    {\n        // ...\n\n        public static function getPages(): array\n        {\n            'index' =\u003e Pages\\ListUsers::route('/'),\n            'create' =\u003e Pages\\CreateUser::route('/create'),\n            'edit' =\u003e Pages\\EditUser::route('/{record}/edit'),\n\n            // custom pages...\n            'authentication' =\u003e Pages\\UserAuthentication::route('/{record}/authentication'),\n            'contact' =\u003e Pages\\Contact::route('/{record}/contact'),\n            'activity' =\u003e Pages\\Activity::route('/{record}/activity'),\n        }\n\n        // ...\n    }\n    ```\n\n2. Define a `$record` property on each of your custom resource pages:\n    ```php\n    public ModelName $record; // public User $record;\n    ```\n    \u003e Be sure to change `ModelName` to the class name of your model.\n3. Define an `innerNav` static method on your resource:\n\n    ```php\n    use App\\Models\\User;\n    use Filament\\Resources\\Resource;\n    use Rawilk\\FilamentInnerNav\\InnerNav;\n    use Rawilk\\FilamentInnerNav\\InnerNavItem;\n\n    class UserResource extends Resource\n    {\n        // ...\n\n        public static function innerNav(User $record): InnerNav\n        {\n            return InnerNav::make()\n                -\u003esetNavigationItems([\n                    InnerNavItem::make('Edit User')\n                        -\u003eurl(fn (): string =\u003e static::getUrl('edit', ['record' =\u003e $record])),\n                    InnerNavItem::make('Password \u0026 Authentication')\n                        -\u003eurl(fn (): string =\u003e static::getUrl('authentication', ['record' =\u003e $record])),\n                    InnerNavItem::make('Contact Information')\n                        -\u003eurl(fn (): string =\u003e static::getUrl('contact', ['record' =\u003e $record])),\n                    InnerNavItem::make('Activity')\n                        -\u003eurl(fn (): string =\u003e static::getUrl('activity', ['record' =\u003e $record])),\n                ]);\n        }\n    }\n    ```\n\n4. In each of your custom pages, wrap the content inside of the `\u003cx-filament-inner-nav::page\u003e` blade component:\n    ```html\n    \u003c!-- file: filament.resources.user-resource.pages.authentication --\u003e\n    \u003cx-filament-panels::page\u003e\n        \u003cx-filament-inner-nav::page\u003e\n            \u003c!-- page content here --\u003e\n        \u003c/x-filament-inner-nav::page\u003e\n    \u003c/x-filament-panels::page\u003e\n    ```\n\n\u003e If the navigation isn't styled correctly, you may need to run `filament:upgrade` to ensure the latest assets are published.\n\n## Advanced Usage\n\n### Enable `wire:navigate`\n\nAllow the usage of livewire's `wire:navigate` by using the `wireNavigate()` method on the `InnerNav` object:\n\n```php\npublic static function innerNav(User $record): InnerNav\n{\n    return InnerNav::make()\n        -\u003ewireNavigate()\n        -\u003esetNavigationItems([\n            // ...\n        ]);\n}\n```\n\n\u003e This option can be globally configured in a service provider. See [Global Configuration](#global-configuration).\n\n### Title \u0026 Description\n\nYou can set a title and/or description for the navigation via the `setTitle()` and `setDescription()` methods on the `InnerNav` object.\nThese will show up directly above the navigation items.\n\n```php\npublic static function innerNav(User $record): InnerNav\n{\n    return InnerNav::make()\n        -\u003esetTitle('Nav title')\n        -\u003esetDescription('Nav description')\n        -\u003esetNavigationItems([\n            // ...\n        ]);\n}\n```\n\nFor more advanced customization, you may return an `HtmlString` object from a closure with either of these methods:\n\n```php\npublic static function innerNav(User $record): InnerNav\n{\n    return InnerNav::make()\n        -\u003esetTitle(fn (): HtmlString =\u003e new HtmlString('\u003ch1\u003e' . $record-\u003ename . '\u003c/h1\u003e'))\n        -\u003esetDescription(fn (): HtmlString =\u003e new HtmlString('\u003cp\u003eNav description\u003c/p\u003e'))\n        -\u003esetNavigationItems([\n            // ...\n        ]);\n}\n```\n\n\u003e You may also return a custom view using `view('...')` from the closure on the `title()` method if needed.\n\n### Item Icons\n\nYou can set an icon for each navigation item via the `icon()` method on the `InnerNavItem` object:\n\n```php\npublic static function innerNav(User $record): InnerNav\n{\n    return InnerNav::make()\n        -\u003esetNavigationItems([\n            InnerNavItem::make('Edit User')\n                -\u003eurl(fn (): string =\u003e static::getUrl('edit', ['record' =\u003e $record]))\n                -\u003eicon('heroicon-o-pencil'),\n        ]);\n}\n```\n\n### Item Active State\n\nBy default, active state is not set on any navigation item. You may call the `isActiveWhen()` method on the `InnerNavItem` object to set active state.\n\n```php\npublic static function innerNav(User $record): InnerNav\n{\n    return InnerNav::make()\n        -\u003esetNavigationItems([\n            InnerNavItem::make('Edit User')\n                -\u003eurl(fn (): string =\u003e static::getUrl('edit', ['record' =\u003e $record]))\n                -\u003eisActiveWhen(fn (): bool =\u003e request()-\u003eroute()-\u003eaction['as'] === 'filament.resources.users.edit')\n        ]);\n}\n```\n\n### Item Visibility\n\nItems can be hidden from the UI by calling either the `visible()` or `hidden()` methods on the `InnerNav` object.\n\n```php\npublic static function innerNav(User $record): InnerNav\n{\n    return InnerNav::make()\n        -\u003esetNavigationItems([\n            InnerNavItem::make('Edit User')\n                -\u003eurl(fn (): string =\u003e static::getUrl('edit', ['record' =\u003e $record]))\n                -\u003evisible(fn (): bool =\u003e auth()-\u003euser()-\u003ecan('edit', $record)),\n        ]);\n}\n```\n\n### Disabling Items\n\nThere may be cases where you still want to show the navigation link, but disable the user from actually visiting it. You may use the `isDisabledWhen()` method on the `InnerNavItem` object for this.\n\n```php\npublic static function innerNav(User $record): InnerNav\n{\n    return InnerNav::make()\n        -\u003esetNavigationItems([\n            InnerNavItem::make('Edit User')\n                -\u003eurl(fn (): string =\u003e static::getUrl('edit', ['record' =\u003e $record]))\n                -\u003eisDisabledWhen(fn (): bool =\u003e ! auth()-\u003euser()-\u003ecan('edit', $record)),\n        ]);\n}\n```\n\n### Item Badges\n\nYou may add a badge to any navigation item by calling the `badge()` method on the `InnerNavItem` object.\n\n```php\npublic static function innerNav(User $record): InnerNav\n{\n    return InnerNav::make()\n        -\u003esetNavigationItems([\n            InnerNavItem::make('Edit User')\n                -\u003eurl(fn (): string =\u003e static::getUrl('edit', ['record' =\u003e $record]))\n                -\u003ebadge('New'),\n        ]);\n}\n```\n\n### Groups\n\nItems can be grouped in the navigation by using the `InnerNavGroup` object. A group can either be collapsible\nor static. Collapsible groups can be nested inside a static group. Below will be an example of each group.\n\n#### Collapsible Group\n\nCollapsible groups allow you to nest a group of navigation items underneath a button that can toggle the visibility of the items.\nThe UI for this is inspired by how GitHub handles their sub navigation on your account settings pages.\n\n```php\npublic static function innerNav(User $record): InnerNav\n{\n    return InnerNav::make()\n        -\u003esetNavigationItems([\n            InnerNavItem::make('Edit User')\n                -\u003eurl(fn (): string =\u003e static::getUrl('edit', ['record' =\u003e $record])),\n            InnerNavGroup::make('Settings')\n                -\u003eicon('heroicon-o-cog')\n                -\u003eitems([\n                    InnerNavItem::make('Group item 1')\n                        -\u003eurl('#'),\n                    InnerNavItem::make('Group Item 2')\n                        -\u003eurl('#'),\n                ])\n        ]);\n}\n```\n\n![collapsible group](./images/collapsible-group.png)\n\n**Note:** The `icon` method is optional on the `InnerNavGroup` object.\n\n\u003e `InnerNavItem` objects underneath an `InnerNavGroup` are not allowed to have an icon.\n\n\u003e By default, collapsible groups are collapsed. You can change this by calling the `expandByDefault()` method on the `InnerNavGroup` object.\n\u003e The group will also be expanded if any of the items inside it are set to active.\n\n#### Static Groups\n\nAlso inspired by the GitHub UI, static groups allow you to render navigation links underneath a heading. All you need to do is provide\na falsy value to the `collapsible()` method on the `InnerNavGroup` object.\n\n```php\npublic static function innerNav(User $record): InnerNav\n{\n    return InnerNav::make()\n            -\u003esetNavigationItems([\n                InnerNavItem::make('Edit User')\n                    -\u003eurl(fn () =\u003e self::getUrl('edit', ['record' =\u003e $record]))\n                    -\u003eicon('heroicon-o-user'),\n                InnerNavGroup::make('Settings')\n                    -\u003ecollapsible(false)\n                    -\u003eitems([\n                        InnerNavGroup::make('Sub Group')\n                            -\u003eicon('heroicon-o-rectangle-stack')\n                            -\u003eitems([\n                                InnerNavItem::make('Sub group item 1')\n                                    -\u003eurl('#'),\n                            ]),\n                        InnerNavItem::make('Group item 1')\n                            -\u003eicon('heroicon-o-rectangle-stack')\n                            -\u003eurl('#'),\n                        InnerNavItem::make('Group Item 2')\n                            -\u003eicon('heroicon-o-rectangle-stack')\n                            -\u003eurl('#'),\n                    ]),\n}\n```\n\n![static group](./images/static-group.png)\n\n\u003e Unlike with a collapsible group, the direct `InnerNavItem` children are allowed to have icons.\n\n### Top Layout\n\nIf you want to render the links on top of your content, instead of on the side, you may use the `setLayout()` method on the `InnerNav` object:\n\n```php\nuse Rawilk\\FilamentInnerNav\\Enums\\InnerNavLayout;\nuse Rawilk\\FilamentInnerNav\\InnerNav;\n\npublic static function innerNav(User $record): InnerNav\n{\n    return InnerNav::make()\n        -\u003esetLayout(InnerNavLayout::Top)\n        -\u003esetNavigationItems([\n            // ...\n        ]);\n}\n```\n\n![top layout](./images/top-layout.png)\n\n\u003e Any `InnerNavGroup` objects added with this layout will be rendered as a dropdown menu.\n\n### Global Configuration\n\nMany options on the `InnerNav`, `InnerNavItem`, and `InnerNavGroup` objects can be configured globally, typically in a service\nprovider somewhere.\n\n```php\nuse Illuminate\\Support\\ServiceProvider;\nuse Rawilk\\FilamentInnerNav\\Enums\\InnerNavLayout;\nuse Rawilk\\FilamentInnerNav\\InnerNav;\nuse Rawilk\\FilamentInnerNav\\InnerNavGroup;\n\nclass AppServiceProvider extends ServiceProvider\n{\n    public function boot(): void\n    {\n        InnerNav::configureUsing(function (InnerNav $nav) {\n            $nav\n                -\u003ewireNavigate()\n                -\u003esetLayout(InnerNavLayout::Side);\n        });\n\n        InnerNavGroup::configureUsing(function (InnerNavGroup $group) {\n            // Expand collapsible groups by default.\n            $group-\u003eexpandByDefault();\n        });\n    }\n}\n```\n\n## Styling\n\nMany parts of the UI provided by this package are prefixed with a custom CSS class you can hook into with your own styles to override the styling.\nAll class names will start with `fi-inner-nav-`, for example the navigation items all have a class of `fi-inner-nav-item`.\n\nIt is not practical to list and maintain all the class names used here, so if there's an element you want to style differently, you can either inspect\nthe element in your browser or view the source code of the blade components in this repository.\n\nIf there's an element that you need to style that doesn't have a custom class, you may submit a PR to add one, however I cannot guarantee that I will merge it.\n\n## Scripts\n\n### Setup\n\nFor convenience, you can run the setup bin script for easy installation for local development.\n\n```bash\n./bin/setup.sh\n```\n\n### Formatting\n\nAlthough formatting is done automatically via workflow, you can format php code locally before committing with a composer script:\n\n```bash\ncomposer format\n```\n\n## Testing\n\n```bash\ncomposer test\n```\n\n## Changelog\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.\n\n## Contributing\n\nPlease see [CONTRIBUTING](.github/CONTRIBUTING.md) for details.\n\n## Security\n\nPlease review [my security policy](.github/SECURITY.md) on how to report security vulnerabilities.\n\n## Credits\n\n- [Randall Wilk](https://github.com/rawilk)\n- [All Contributors](../../contributors)\n\n## Alternatives\n\nSome alternatives to this package include:\n\n- [Filament Page With Sidebar](https://github.com/aymanalhattami/filament-page-with-sidebar)\n\nIf you have a similar package to this that you would like to add, please submit a PR with an updated README.\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frawilk%2Ffilament-inner-nav","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frawilk%2Ffilament-inner-nav","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frawilk%2Ffilament-inner-nav/lists"}