@if ($homeUrl = filament()->getHomeUrl())
-
+
@else
diff --git a/packages/panels/resources/views/components/topbar/item.blade.php b/packages/panels/resources/views/components/topbar/item.blade.php
index 2d78866d79..d455246423 100644
--- a/packages/panels/resources/views/components/topbar/item.blade.php
+++ b/packages/panels/resources/views/components/topbar/item.blade.php
@@ -20,13 +20,7 @@
>
<{{ $tag }}
@if ($url)
- href="{{ $url }}"
-
- @if ($shouldOpenUrlInNewTab)
- target="_blank"
- @else
- wire:navigate
- @endif
+ {{ \Filament\Support\generate_href_html($url, $shouldOpenUrlInNewTab) }}
@else
type="button"
@endif
diff --git a/packages/panels/resources/views/components/user-menu.blade.php b/packages/panels/resources/views/components/user-menu.blade.php
index f89a377263..b21094aff3 100644
--- a/packages/panels/resources/views/components/user-menu.blade.php
+++ b/packages/panels/resources/views/components/user-menu.blade.php
@@ -40,7 +40,7 @@
:color="$profileItem?->getColor()"
:icon="$profileItem?->getIcon() ?? 'heroicon-m-user-circle'"
:href="$profileItemUrl ?? filament()->getProfileUrl()"
- :should-open-url-in-new-tab="$profileItem?->shouldOpenUrlInNewTab() ?? false"
+ :target="($profileItem?->shouldOpenUrlInNewTab() ?? false) ? '_blank' : null"
icon-alias="panels::user-menu.profile-item"
tag="a"
>
@@ -71,7 +71,7 @@
diff --git a/packages/panels/src/Panel.php b/packages/panels/src/Panel.php
index 097e83426a..19cf4cff00 100644
--- a/packages/panels/src/Panel.php
+++ b/packages/panels/src/Panel.php
@@ -6,6 +6,7 @@ use Closure;
use Filament\Support\Components\Component;
use Filament\Support\Facades\FilamentColor;
use Filament\Support\Facades\FilamentIcon;
+use Filament\Support\Facades\FilamentView;
class Panel extends Component
{
@@ -29,6 +30,7 @@ class Panel extends Component
use Panel\Concerns\HasRenderHooks;
use Panel\Concerns\HasRoutes;
use Panel\Concerns\HasSidebar;
+ use Panel\Concerns\HasSpaMode;
use Panel\Concerns\HasTenancy;
use Panel\Concerns\HasTheme;
use Panel\Concerns\HasTopNavigation;
@@ -59,6 +61,8 @@ class Panel extends Component
FilamentIcon::register($this->icons);
+ FilamentView::spa($this->hasSpaMode());
+
$this->registerRenderHooks();
$this->registerLivewireComponents();
diff --git a/packages/panels/src/Panel/Concerns/HasSpaMode.php b/packages/panels/src/Panel/Concerns/HasSpaMode.php
new file mode 100644
index 0000000000..eda55a0fbb
--- /dev/null
+++ b/packages/panels/src/Panel/Concerns/HasSpaMode.php
@@ -0,0 +1,22 @@
+hasSpaMode = $condition;
+
+ return $this;
+ }
+
+ public function hasSpaMode(): bool
+ {
+ return (bool) $this->evaluate($this->hasSpaMode);
+ }
+}
diff --git a/packages/panels/src/helpers.php b/packages/panels/src/helpers.php
index 20c2ca0106..daad3f027f 100644
--- a/packages/panels/src/helpers.php
+++ b/packages/panels/src/helpers.php
@@ -8,7 +8,7 @@ use Illuminate\Auth\Access\Response;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Gate;
-if (! function_exists('authorize')) {
+if (! function_exists('Filament\authorize')) {
/**
* @throws AuthorizationException
*/
diff --git a/packages/support/resources/views/components/breadcrumbs.blade.php b/packages/support/resources/views/components/breadcrumbs.blade.php
index 805960cb85..f052eb064d 100644
--- a/packages/support/resources/views/components/breadcrumbs.blade.php
+++ b/packages/support/resources/views/components/breadcrumbs.blade.php
@@ -32,8 +32,7 @@
@endif
{{ $label }}
diff --git a/packages/support/resources/views/components/button/index.blade.php b/packages/support/resources/views/components/button/index.blade.php
index 344794a6bc..6ea8a6e265 100644
--- a/packages/support/resources/views/components/button/index.blade.php
+++ b/packages/support/resources/views/components/button/index.blade.php
@@ -11,6 +11,7 @@
'disabled' => false,
'form' => null,
'grouped' => false,
+ 'href' => null,
'icon' => null,
'iconAlias' => null,
'iconPosition' => IconPosition::Before,
@@ -21,6 +22,7 @@
'outlined' => false,
'size' => 'md',
'tag' => 'button',
+ 'target' => null,
'tooltip' => null,
'type' => 'button',
])
@@ -280,6 +282,7 @@
@elseif ($tag === 'a')
null,
'color' => 'gray',
'disabled' => false,
+ 'href' => null,
'icon' => null,
'iconAlias' => null,
'iconSize' => IconSize::Medium,
'image' => null,
'keyBindings' => null,
'tag' => 'button',
- 'shouldOpenUrlInNewTab' => false,
+ 'target' => null,
])
@php
@@ -119,11 +120,7 @@
@elseif ($tag === 'a')
map(fn (string $keyBinding): string => str_replace('+', '-', $keyBinding))->implode('.') }}
diff --git a/packages/support/resources/views/components/icon-button.blade.php b/packages/support/resources/views/components/icon-button.blade.php
index 3e216a01b7..dd25d8c61a 100644
--- a/packages/support/resources/views/components/icon-button.blade.php
+++ b/packages/support/resources/views/components/icon-button.blade.php
@@ -9,6 +9,7 @@
'color' => 'primary',
'disabled' => false,
'form' => null,
+ 'href' => null,
'icon' => null,
'iconAlias' => null,
'iconSize' => null,
@@ -16,6 +17,7 @@
'label' => null,
'size' => 'md',
'tag' => 'button',
+ 'target' => null,
'tooltip' => null,
'type' => 'button',
])
@@ -123,6 +125,7 @@
@elseif ($tag === 'a')
'primary',
'disabled' => false,
'form' => null,
+ 'href' => null,
'icon' => null,
'iconAlias' => null,
'iconPosition' => IconPosition::Before,
@@ -17,6 +18,7 @@
'keyBindings' => null,
'size' => 'md',
'tag' => 'a',
+ 'target' => null,
'tooltip' => null,
'type' => 'button',
])
@@ -88,6 +90,7 @@
@if ($tag === 'a')
null,
'badge' => null,
'badgeColor' => null,
+ 'href' => null,
'icon' => null,
'iconColor' => 'gray',
'iconPosition' => IconPosition::Before,
'tag' => 'button',
+ 'target' => null,
'type' => 'button',
])
@@ -35,6 +37,8 @@
<{{ $tag }}
@if ($tag === 'button')
type="{{ $type }}"
+ @elseif ($tag === 'a')
+ {{ \Filament\Support\generate_href_html($href, $target === '_blank') }}
@endif
@if ($hasAlpineActiveClasses)
x-bind:class="{
diff --git a/packages/support/src/Facades/FilamentView.php b/packages/support/src/Facades/FilamentView.php
index 81d2e78795..21af3e4eca 100644
--- a/packages/support/src/Facades/FilamentView.php
+++ b/packages/support/src/Facades/FilamentView.php
@@ -8,6 +8,7 @@ use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Support\Facades\Facade;
/**
+ * @method static bool hasSpaMode()
* @method static Htmlable renderHook(string $name, string | array | null $scopes = null)
*
* @see ViewManager
@@ -28,4 +29,11 @@ class FilamentView extends Facade
$viewManager->registerRenderHook($name, $hook, $scopes);
});
}
+
+ public static function spa(bool $condition = true): void
+ {
+ static::resolved(function (ViewManager $viewManager) use ($condition) {
+ $viewManager->spa($condition);
+ });
+ }
}
diff --git a/packages/support/src/View/ViewManager.php b/packages/support/src/View/ViewManager.php
index 2a452ecb20..cc791c4a93 100644
--- a/packages/support/src/View/ViewManager.php
+++ b/packages/support/src/View/ViewManager.php
@@ -14,6 +14,8 @@ class ViewManager
*/
protected array $renderHooks = [];
+ protected bool $hasSpaMode = false;
+
/**
* @param string | array | null $scopes
*/
@@ -66,4 +68,14 @@ class ViewManager
return new HtmlString(implode('', $hooks));
}
+
+ public function spa(bool $condition = true): void
+ {
+ $this->hasSpaMode = $condition;
+ }
+
+ public function hasSpaMode(): bool
+ {
+ return $this->hasSpaMode;
+ }
}
diff --git a/packages/support/src/helpers.php b/packages/support/src/helpers.php
index c314968723..854aef8fd0 100644
--- a/packages/support/src/helpers.php
+++ b/packages/support/src/helpers.php
@@ -2,7 +2,9 @@
namespace Filament\Support;
+use Filament\Support\Facades\FilamentView;
use Illuminate\Contracts\Support\Htmlable;
+use Illuminate\Support\HtmlString;
use Illuminate\Support\Str;
use Illuminate\Translation\MessageSelector;
use Illuminate\View\ComponentAttributeBag;
@@ -111,3 +113,20 @@ if (! function_exists('Filament\Support\is_slot_empty')) {
) === '';
}
}
+
+if (! function_exists('Filament\Support\generate_href_html')) {
+ function generate_href_html(?string $url, bool $shouldOpenInNewTab = false): Htmlable
+ {
+ $html = "href=\"{$url}\"";
+
+ if (FilamentView::hasSpaMode() && str($url)->startsWith(request()->root())) {
+ $html .= ' wire:navigate';
+ }
+
+ if ($shouldOpenInNewTab) {
+ $html .= ' target="_blank"';
+ }
+
+ return new HtmlString($html);
+ }
+}
diff --git a/packages/tables/resources/views/components/columns/column.blade.php b/packages/tables/resources/views/components/columns/column.blade.php
index 46f9bd3c3a..fedc411a7d 100644
--- a/packages/tables/resources/views/components/columns/column.blade.php
+++ b/packages/tables/resources/views/components/columns/column.blade.php
@@ -43,8 +43,7 @@
>
@if (($url || ($recordUrl && $action === null)) && (! $isClickDisabled))
{{ $slot }}
diff --git a/packages/tables/resources/views/index.blade.php b/packages/tables/resources/views/index.blade.php
index 0f0b2f1e34..04cc4aba93 100644
--- a/packages/tables/resources/views/index.blade.php
+++ b/packages/tables/resources/views/index.blade.php
@@ -650,7 +650,7 @@