diff --git a/docs/06-navigation/01-overview.md b/docs/06-navigation/01-overview.md index 4edd174154..b21a9f59d0 100644 --- a/docs/06-navigation/01-overview.md +++ b/docs/06-navigation/01-overview.md @@ -552,6 +552,24 @@ public function panel(Panel $panel): Panel } ``` +### Replacing the sidebar and topbar Livewire components + +You may completely replace the Livewire components that are used to render the sidebar and topbar, passing your own Livewire component class name into the `sidebarLivewireComponent()` or `topbarLivewireComponent()` method: + +```php +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); +} +``` + ## 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/resources/views/components/layout/index.blade.php b/packages/panels/resources/views/components/layout/index.blade.php index 7887dab856..f957e416ab 100644 --- a/packages/panels/resources/views/components/layout/index.blade.php +++ b/packages/panels/resources/views/components/layout/index.blade.php @@ -28,7 +28,7 @@ @if ($hasTopbar) {{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::TOPBAR_BEFORE, scopes: $renderHookScopes) }} - @livewire(\Filament\Livewire\Topbar::class) + @livewire(filament()->getTopbarLivewireComponent()) {{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::TOPBAR_AFTER, scopes: $renderHookScopes) }} @endif diff --git a/packages/panels/src/Facades/Filament.php b/packages/panels/src/Facades/Filament.php index 9b25df2b87..a21ab7d1d3 100644 --- a/packages/panels/src/Facades/Filament.php +++ b/packages/panels/src/Facades/Filament.php @@ -26,6 +26,7 @@ use Illuminate\Contracts\Auth\StatefulGuard; use Illuminate\Contracts\Support\Htmlable; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Facade; +use Livewire\Component; /** * @method static bool arePasswordsRevealable() @@ -105,6 +106,7 @@ use Illuminate\Support\Facades\Facade; * @method static string | null getTenantProfileUrl(array $parameters = []) * @method static string | null getTenantRegistrationUrl(array $parameters = []) * @method static Theme getTheme() + * @method static class-string getTopbarLivewireComponent() * @method static ThemeMode getDefaultThemeMode() * @method static string | null getUserAvatarUrl(Model | Authenticatable $user) * @method static Model | null getUserDefaultTenant(HasTenants | Model | Authenticatable $user) diff --git a/packages/panels/src/FilamentManager.php b/packages/panels/src/FilamentManager.php index e4fd7c622a..7f6d712b74 100644 --- a/packages/panels/src/FilamentManager.php +++ b/packages/panels/src/FilamentManager.php @@ -34,6 +34,7 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Event; +use Livewire\Component; class FilamentManager { @@ -488,6 +489,14 @@ class FilamentManager return $this->getCurrentOrDefaultPanel()->getProfilePage(); } + /** + * @return class-string + */ + public function getTopbarLivewireComponent(): string + { + return $this->getCurrentOrDefaultPanel()->getTopbarLivewireComponent(); + } + public function getTenantProfilePage(): ?string { return $this->getCurrentOrDefaultPanel()->getTenantProfilePage(); diff --git a/packages/panels/src/Panel/Concerns/HasComponents.php b/packages/panels/src/Panel/Concerns/HasComponents.php index cff4409358..27880ff2d5 100644 --- a/packages/panels/src/Panel/Concerns/HasComponents.php +++ b/packages/panels/src/Panel/Concerns/HasComponents.php @@ -9,7 +9,6 @@ use Filament\Livewire\GlobalSearch; use Filament\Livewire\Notifications; use Filament\Livewire\Sidebar; use Filament\Livewire\SimpleUserMenu; -use Filament\Livewire\Topbar; use Filament\Pages\Page; use Filament\Resources\Pages\Page as ResourcePage; use Filament\Resources\RelationManagers\RelationGroup; @@ -493,7 +492,7 @@ trait HasComponents $this->queueLivewireComponentForRegistration(Notifications::class); $this->queueLivewireComponentForRegistration(Sidebar::class); $this->queueLivewireComponentForRegistration(SimpleUserMenu::class); - $this->queueLivewireComponentForRegistration(Topbar::class); + $this->queueLivewireComponentForRegistration($this->getTopbarLivewireComponent()); if ($this->hasEmailVerification() && is_subclass_of($emailVerificationPromptRouteAction = $this->getEmailVerificationPromptRouteAction(), Component::class)) { $this->queueLivewireComponentForRegistration($emailVerificationPromptRouteAction); diff --git a/packages/panels/src/Panel/Concerns/HasTopbar.php b/packages/panels/src/Panel/Concerns/HasTopbar.php index b7d8428db2..ee5936daa8 100644 --- a/packages/panels/src/Panel/Concerns/HasTopbar.php +++ b/packages/panels/src/Panel/Concerns/HasTopbar.php @@ -3,11 +3,15 @@ namespace Filament\Panel\Concerns; use Closure; +use Filament\Livewire\Topbar; +use Livewire\Component; trait HasTopbar { protected bool | Closure $hasTopbar = true; + protected string | Closure | null $topbarLivewireComponent = null; + public function topbar(bool | Closure $condition = true): static { $this->hasTopbar = $condition; @@ -15,8 +19,26 @@ trait HasTopbar return $this; } + /** + * @param class-string | Closure | null $component + */ + public function topbarLivewireComponent(string | Closure | null $component): static + { + $this->topbarLivewireComponent = $component; + + return $this; + } + public function hasTopbar(): bool { return (bool) $this->evaluate($this->hasTopbar); } + + /** + * @return class-string + */ + public function getTopbarLivewireComponent(): string + { + return $this->evaluate($this->topbarLivewireComponent) ?? Topbar::class; + } }