diff --git a/packages/panels/docs/06-navigation.md b/packages/panels/docs/06-navigation.md index 62fa93d4ef..25f9d9a69c 100644 --- a/packages/panels/docs/06-navigation.md +++ b/packages/panels/docs/06-navigation.md @@ -374,6 +374,21 @@ public function panel(Panel $panel): Panel } ``` +### Conditionally hiding user menu items + +You can also conditionally hide a user menu item by using the `visible()` or `hidden()` methods, passing in a condition to check. Passing a function will defer condition evaluation until the menu is actually being rendered: + +```php +use App\Models\Payment; +use Filament\Navigation\MenuItem; + +MenuItem::make() + ->label('Payments') + ->visible(fn (): bool => auth()->user()->can('viewAny', Payment::class)) + // or + ->hidden(fn (): bool => ! auth()->user()->can('viewAny', Payment::class)) +``` + ## Disabling breadcrumbs The default layout will show breadcrumbs to indicate the location of the current page within the hierarchy of the app. diff --git a/packages/panels/docs/10-tenancy.md b/packages/panels/docs/10-tenancy.md index d505aa65fe..394ca36efb 100644 --- a/packages/panels/docs/10-tenancy.md +++ b/packages/panels/docs/10-tenancy.md @@ -334,6 +334,20 @@ public function panel(Panel $panel): Panel } ``` +### Conditionally hiding tenant menu items + +You can also conditionally hide a tenant menu item by using the `visible()` or `hidden()` methods, passing in a condition to check. Passing a function will defer condition evaluation until the menu is actually being rendered: + +```php +use Filament\Navigation\MenuItem; + +MenuItem::make() + ->label('Settings') + ->visible(fn (): bool => auth()->user()->can('manage-team')) + // or + ->hidden(fn (): bool => ! auth()->user()->can('manage-team')) +``` + ## Setting up avatars Out of the box, Filament uses [ui-avatars.com](https://ui-avatars.com) to generate avatars based on a user's name. However, if you user model has an `avatar_url` attribute, that will be used instead. To customize how Filament gets a user's avatar URL, you can implement the `HasAvatar` contract: diff --git a/packages/panels/src/Navigation/MenuItem.php b/packages/panels/src/Navigation/MenuItem.php index a637c87a55..b47e1fa9ba 100644 --- a/packages/panels/src/Navigation/MenuItem.php +++ b/packages/panels/src/Navigation/MenuItem.php @@ -21,6 +21,10 @@ class MenuItem extends Component protected string | Closure | Native | null $url = null; + protected bool | Closure $isHidden = false; + + protected bool | Closure $isVisible = true; + final public function __construct() { } @@ -68,6 +72,34 @@ class MenuItem extends Component return $this; } + public function hidden(bool | Closure $condition = true): static + { + $this->isHidden = $condition; + + return $this; + } + + public function visible(bool | Closure $condition = true): static + { + $this->isVisible = $condition; + + return $this; + } + + public function isVisible(): bool + { + return ! $this->isHidden(); + } + + public function isHidden(): bool + { + if ($this->evaluate($this->isHidden)) { + return true; + } + + return ! $this->evaluate($this->isVisible); + } + /** * @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null */ diff --git a/packages/panels/src/Panel/Concerns/HasTenancy.php b/packages/panels/src/Panel/Concerns/HasTenancy.php index d6879f66ad..1b34a20b3d 100644 --- a/packages/panels/src/Panel/Concerns/HasTenancy.php +++ b/packages/panels/src/Panel/Concerns/HasTenancy.php @@ -190,6 +190,7 @@ trait HasTenancy public function getTenantMenuItems(): array { return collect($this->tenantMenuItems) + ->reject(fn (MenuItem $item): bool => $item->isHidden()) ->sort(fn (MenuItem $item): int => $item->getSort()) ->all(); } diff --git a/packages/panels/src/Panel/Concerns/HasUserMenu.php b/packages/panels/src/Panel/Concerns/HasUserMenu.php index 96c31caeaa..c43963e3a2 100644 --- a/packages/panels/src/Panel/Concerns/HasUserMenu.php +++ b/packages/panels/src/Panel/Concerns/HasUserMenu.php @@ -30,6 +30,7 @@ trait HasUserMenu public function getUserMenuItems(): array { return collect($this->userMenuItems) + ->reject(fn (MenuItem $item): bool => $item->isHidden()) ->sort(fn (MenuItem $item): int => $item->getSort()) ->all(); }