Keep the current section lit while a Livewire component updates
<x-section-nav> and <x-app-shell> mark an item current when its URL is the request's. While a Livewire component on the page re-renders, the request is Livewire's update endpoint, so no section or destination stayed lit after the morph. Both now compare with the page's URL from Livewire::originalUrl() during a Livewire update request; a normal request compares exactly as before. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RHoXZSHc8gGpZjFmA5fPc2
This commit is contained in:
co-authored by
Claude Opus 5
parent
d77ecf5e2a
commit
fdb13313f7
@@ -2,6 +2,8 @@
|
||||
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Livewire\Component;
|
||||
use Livewire\Livewire;
|
||||
|
||||
function shellDestinations(): array
|
||||
{
|
||||
@@ -54,6 +56,29 @@ it('marks the destination at the current URL when none says it is active', funct
|
||||
->and(substr_count($html, 'aria-current="page"'))->toBe(2);
|
||||
});
|
||||
|
||||
it('keeps the destination at the page\'s URL current while a Livewire component on it updates', function () {
|
||||
Livewire::component('app-shell-probe', new class extends Component
|
||||
{
|
||||
public string $page = '';
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->page = url()->current();
|
||||
}
|
||||
|
||||
public function render(): string
|
||||
{
|
||||
return '<div><x-app-shell :destinations="[[\'title\' => \'Inbox\', \'icon\' => \'inbox\', \'url\' => $page], [\'title\' => \'Sent\', \'icon\' => \'send\', \'url\' => \'/sent\']]" /></div>';
|
||||
}
|
||||
});
|
||||
|
||||
$probe = Livewire::test('app-shell-probe');
|
||||
|
||||
expect(substr_count($probe->html(), 'aria-current="page"'))->toBe(2)
|
||||
->and(substr_count($probe->call('$refresh')->html(), 'aria-current="page"'))->toBe(2)
|
||||
->and($probe->html())->toMatch('/href="[^"]*\/livewire-unit-test-endpoint\/[^"]*"[^>]*aria-current="page"/');
|
||||
});
|
||||
|
||||
it('lifts the snackbar above the bar only when there is a bar', function () {
|
||||
expect((string) $this->blade('<x-app-shell :destinations="$destinations" />', ['destinations' => shellDestinations()]))
|
||||
->toContain('max-sm:[--material-bottom-bar:calc(4rem+var(--material-safe-bottom,env(safe-area-inset-bottom))+var(--material-bottom-extra,0px))]')
|
||||
|
||||
@@ -80,3 +80,28 @@ it('marks the section whose url is the request\'s, and wraps many sections onto
|
||||
->toMatch('/data-tab\s+aria-current="page"\s*>\s*<span data-tab-content>\s*<span class="truncate">S3/')
|
||||
->not->toContain('wire:navigate');
|
||||
});
|
||||
|
||||
it('keeps the page\'s section current while a Livewire component on it updates', function () {
|
||||
Livewire::component('section-nav-probe', new class extends Component
|
||||
{
|
||||
public string $page = '';
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->page = url()->current();
|
||||
}
|
||||
|
||||
public function render(): string
|
||||
{
|
||||
return '<div><x-section-nav :items="[[\'title\' => \'Here\', \'url\' => $page], [\'title\' => \'Elsewhere\', \'url\' => \'/elsewhere\']]" no-wire-navigate /></div>';
|
||||
}
|
||||
});
|
||||
|
||||
$current = '/href="[^"]*\/livewire-unit-test-endpoint\/[^"]*"\s+data-tab\s+aria-current="page"/';
|
||||
|
||||
$probe = Livewire::test('section-nav-probe');
|
||||
|
||||
expect($probe->html())->toMatch($current)
|
||||
->and($probe->call('$refresh')->html())->toMatch($current)
|
||||
->and(substr_count($probe->html(), 'aria-current="page"'))->toBe(1);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user