Add the navigation bar, navigation rail and app shell

M3 Expressive's flexible navigation bar, the collapsed, expanded and
modal navigation rail with its state applied before the first paint,
and an adaptive app shell composing them. The head script now restores
the theme and rail attributes that wire:navigate strips from <html>.
Completes Phase 8.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
This commit is contained in:
Andreas Reinhold / reini
2026-09-13 08:54:51 +02:00
co-authored by Claude Opus 5
parent f4be9848e2
commit ab692b66bb
24 changed files with 1995 additions and 5 deletions
+22 -2
View File
@@ -2,7 +2,7 @@
it('follows the operating system until the visitor chooses, by default', function () {
$this->blade('<x-theme-script />')
->assertSee('({"default":"system","key":"material-theme","legacy":[]})', false);
->assertSee('({"default":"system","key":"material-theme","legacy":[],"rail":{"default":"expanded","key":"material-rail"}})', false);
});
it('takes the application\'s default, key and legacy keys', function () {
@@ -13,7 +13,7 @@ it('takes the application\'s default, key and legacy keys', function () {
]]);
$this->blade('<x-theme-script />')
->assertSee('({"default":"dark","key":"sealshare-theme","legacy":["mary-theme"]})', false);
->assertSee('"default":"dark","key":"sealshare-theme","legacy":["mary-theme"]', false);
});
it('falls back to the operating system for a default it does not know', function () {
@@ -22,3 +22,23 @@ it('falls back to the operating system for a default it does not know', function
$this->blade('<x-theme-script />')
->assertSee('"default":"system"', false);
});
it('starts a collapsible rail as the application says, expanded otherwise', function () {
config(['livewire-material.rail' => ['default' => 'collapsed', 'storage_key' => 'sealshare-rail']]);
$this->blade('<x-theme-script />')
->assertSee('"rail":{"default":"collapsed","key":"sealshare-rail"}', false)
->assertSee("root.setAttribute('data-rail', rail);", false);
config(['livewire-material.rail.default' => 'sideways']);
$this->blade('<x-theme-script />')
->assertSee('"rail":{"default":"expanded","key":"sealshare-rail"}', false);
});
it('puts its attributes back on <html> when wire:navigate swaps the page', function () {
$this->blade('<x-theme-script />')
->assertSee("document.addEventListener('livewire:navigating'", false)
->assertSee("['data-theme', 'data-theme-choice', 'data-theme-key', 'data-rail', 'data-rail-key']", false)
->assertSee('event.detail.onSwap(', false);
});