Rewrite the showcase's Navigation section without Tailwind

Plan step 38 (last batch): the navigation-bar and navigation-rail
demos' bounded frames become data-md-showcase-nav-demo (`bar`,
`bar-wide` inside its own data-md-showcase-nav-scroll wrapper, `rail`,
`rail-wide`), the "the page" filler is data-md-showcase-nav-page and
the content pane beside a rail data-md-showcase-nav-content; a group
of demos moves onto <x-row>/<x-stack> with inline max-width styles for
the two arbitrary demo widths (400px, 800px) Tailwind's arbitrary
values gave them. The "Open the scaffold" link's md-link/md-ink-primary
classes match bars.blade.php's.

Every #navigation id, aria-label and visible label the Chromium
NavigationTest (against its own probes and /material/shell) relies on
is unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
Andreas Reinhold / reini
2026-09-15 05:32:58 +02:00
co-authored by Claude Sonnet 5
parent 7b7e7279f5
commit a62800e8ff
2 changed files with 100 additions and 41 deletions
+59
View File
@@ -508,6 +508,65 @@
[data-md-showcase-tabs-narrow] { [data-md-showcase-tabs-narrow] {
max-width: 384px; max-width: 384px;
} }
/* Navigation: a bounded frame around one navigation-bar or navigation-rail demo. `bar` and
`bar-wide` stack the bar under a "the page" filler the way a scaffold does; `bar-wide` drops
its own edge because its horizontal-scroll wrapper (`data-md-showcase-nav-scroll`) already
draws one, and is wide enough (600px) that a bar showing icon beside label never wraps.
`rail` and `rail-wide` sit the rail beside a content pane the way a scaffold does; `rail-wide`
is full width, for the two examples with real body text beside the rail. */
[data-md-showcase-nav-demo='bar'] {
display: flex;
flex-direction: column;
height: 224px;
overflow: hidden;
border-radius: var(--md-sys-shape-corner-lg);
border: 1px solid var(--md-sys-color-outline-variant);
background-color: var(--md-sys-color-surface);
}
[data-md-showcase-nav-demo='bar-wide'] {
display: flex;
flex-direction: column;
height: 224px;
min-width: 600px;
background-color: var(--md-sys-color-surface);
}
[data-md-showcase-nav-demo='rail'] {
display: flex;
height: 576px;
overflow: hidden;
border-radius: var(--md-sys-shape-corner-lg);
border: 1px solid var(--md-sys-color-outline-variant);
}
[data-md-showcase-nav-demo='rail-wide'] {
display: flex;
width: 100%;
height: 480px;
overflow: hidden;
border-radius: var(--md-sys-shape-corner-lg);
border: 1px solid var(--md-sys-color-outline-variant);
}
[data-md-showcase-nav-scroll] {
overflow-x: auto;
border-radius: var(--md-sys-shape-corner-lg);
border: 1px solid var(--md-sys-color-outline-variant);
}
[data-md-showcase-nav-page] {
flex: 1 1 auto;
padding: var(--md-sys-measurement-space200);
}
[data-md-showcase-nav-content] {
flex: 1 1 auto;
min-width: 0;
background-color: var(--md-sys-color-surface-container-low);
padding: var(--md-sys-measurement-space300);
}
} }
/* A handful of call sites (<x-input>, <x-datepicker>, <x-slider>) forward only `class` and /* A handful of call sites (<x-input>, <x-datepicker>, <x-slider>) forward only `class` and
@@ -1,11 +1,11 @@
@php @php
$examples = [ $examples = [
'Navigation bar' => <<<'BLADE' 'Navigation bar' => <<<'BLADE'
<div class="w-full space-y-6"> <x-stack gap="space300" style="width: 100%;">
<div class="max-w-[25rem] space-y-2"> <x-stack gap="space100" style="max-width: 400px;">
<p class="type-label-lg text-on-surface-variant">Compact: icon over label</p> <p class="md-type-label-lg md-ink-variant">Compact: icon over label</p>
<div class="flex h-56 flex-col overflow-hidden rounded-corner-lg border border-outline-variant bg-surface"> <div data-md-showcase-nav-demo="bar">
<div class="flex-1 p-4 type-body-md text-on-surface-variant">The page</div> <div data-md-showcase-nav-page class="md-type-body-md md-ink-variant">The page</div>
<x-navigation-bar> <x-navigation-bar>
<x-navigation-bar-item label="Shares" icon="folder_shared" link="#navigation" no-wire-navigate active /> <x-navigation-bar-item label="Shares" icon="folder_shared" link="#navigation" no-wire-navigate active />
<x-navigation-bar-item label="Upload" icon="upload" link="#navigation" no-wire-navigate /> <x-navigation-bar-item label="Upload" icon="upload" link="#navigation" no-wire-navigate />
@@ -13,13 +13,13 @@
<x-navigation-bar-item label="Account" icon="account_circle" link="#navigation" no-wire-navigate :badge="true" badge-label="Needs attention" /> <x-navigation-bar-item label="Account" icon="account_circle" link="#navigation" no-wire-navigate :badge="true" badge-label="Needs attention" />
</x-navigation-bar> </x-navigation-bar>
</div> </div>
</div> </x-stack>
<div class="max-w-[50rem] space-y-2"> <x-stack gap="space100" style="max-width: 800px;">
<p class="type-label-lg text-on-surface-variant">From 600px wide: icon beside label, centred</p> <p class="md-type-label-lg md-ink-variant">From 600px wide: icon beside label, centred</p>
<div class="overflow-x-auto rounded-corner-lg border border-outline-variant"> <div data-md-showcase-nav-scroll>
<div class="flex h-56 min-w-[37.5rem] flex-col bg-surface"> <div data-md-showcase-nav-demo="bar-wide">
<div class="flex-1 p-4 type-body-md text-on-surface-variant">The page</div> <div data-md-showcase-nav-page class="md-type-body-md md-ink-variant">The page</div>
<x-navigation-bar> <x-navigation-bar>
<x-navigation-bar-item label="Shares" icon="folder_shared" link="#navigation" no-wire-navigate active /> <x-navigation-bar-item label="Shares" icon="folder_shared" link="#navigation" no-wire-navigate active />
<x-navigation-bar-item label="Upload" icon="upload" link="#navigation" no-wire-navigate /> <x-navigation-bar-item label="Upload" icon="upload" link="#navigation" no-wire-navigate />
@@ -28,25 +28,25 @@
</x-navigation-bar> </x-navigation-bar>
</div> </div>
</div> </div>
</div> </x-stack>
<div class="max-w-[25rem] space-y-2"> <x-stack gap="space100" style="max-width: 400px;">
<p class="type-label-lg text-on-surface-variant">Hide on scroll: scroll the page down, then up</p> <p class="md-type-label-lg md-ink-variant">Hide on scroll: scroll the page down, then up</p>
<div class="flex h-56 flex-col overflow-hidden rounded-corner-lg border border-outline-variant bg-surface"> <div data-md-showcase-nav-demo="bar">
<div class="flex-1 p-4 type-body-md text-on-surface-variant">The bar follows the window's scrolling, not this box's: scroll the showcase down and it leaves, scroll up and it springs back. It stays while a snackbar or a bottom sheet is on screen.</div> <div data-md-showcase-nav-page class="md-type-body-md md-ink-variant">The bar follows the window's scrolling, not this box's: scroll the showcase down and it leaves, scroll up and it springs back. It stays while a snackbar or a bottom sheet is on screen.</div>
<x-navigation-bar hide-on-scroll> <x-navigation-bar hide-on-scroll>
<x-navigation-bar-item label="Shares" icon="folder_shared" link="#navigation" no-wire-navigate active /> <x-navigation-bar-item label="Shares" icon="folder_shared" link="#navigation" no-wire-navigate active />
<x-navigation-bar-item label="Upload" icon="upload" link="#navigation" no-wire-navigate /> <x-navigation-bar-item label="Upload" icon="upload" link="#navigation" no-wire-navigate />
<x-navigation-bar-item label="Inbox" icon="inbox" link="#navigation" no-wire-navigate badge="3" /> <x-navigation-bar-item label="Inbox" icon="inbox" link="#navigation" no-wire-navigate badge="3" />
</x-navigation-bar> </x-navigation-bar>
</div> </div>
</div> </x-stack>
<div class="max-w-[50rem] space-y-2"> <x-stack gap="space100" style="max-width: 800px;">
<p class="type-label-lg text-on-surface-variant">Tall (80px): icon over label whatever the width</p> <p class="md-type-label-lg md-ink-variant">Tall (80px): icon over label whatever the width</p>
<div class="overflow-x-auto rounded-corner-lg border border-outline-variant"> <div data-md-showcase-nav-scroll>
<div class="flex h-56 min-w-[37.5rem] flex-col bg-surface"> <div data-md-showcase-nav-demo="bar-wide">
<div class="flex-1 p-4 type-body-md text-on-surface-variant">The page</div> <div data-md-showcase-nav-page class="md-type-body-md md-ink-variant">The page</div>
<x-navigation-bar tall> <x-navigation-bar tall>
<x-navigation-bar-item label="Shares" icon="folder_shared" link="#navigation" no-wire-navigate active /> <x-navigation-bar-item label="Shares" icon="folder_shared" link="#navigation" no-wire-navigate active />
<x-navigation-bar-item label="Upload" icon="upload" link="#navigation" no-wire-navigate /> <x-navigation-bar-item label="Upload" icon="upload" link="#navigation" no-wire-navigate />
@@ -55,12 +55,12 @@
</x-navigation-bar> </x-navigation-bar>
</div> </div>
</div> </div>
</div> </x-stack>
</div> </x-stack>
BLADE, BLADE,
'Collapsed, narrow (centred) and expanded rails' => <<<'BLADE' 'Collapsed, narrow (centred) and expanded rails' => <<<'BLADE'
<div class="flex w-full flex-wrap items-start gap-6"> <x-row gap="space300" wrap align="start" style="width: 100%;">
<div class="flex h-[36rem] overflow-hidden rounded-corner-lg border border-outline-variant"> <div data-md-showcase-nav-demo="rail">
<x-navigation-rail mode="collapsed" label="Collapsed example" divider> <x-navigation-rail mode="collapsed" label="Collapsed example" divider>
<x-slot:header> <x-slot:header>
<x-fab label="Compose" icon="edit" /> <x-fab label="Compose" icon="edit" />
@@ -80,7 +80,7 @@
</x-navigation-rail> </x-navigation-rail>
</div> </div>
<div class="flex h-[36rem] overflow-hidden rounded-corner-lg border border-outline-variant"> <div data-md-showcase-nav-demo="rail">
<x-navigation-rail mode="collapsed" width="narrow" align="center" label="Narrow example" divider> <x-navigation-rail mode="collapsed" width="narrow" align="center" label="Narrow example" divider>
<x-slot:header> <x-slot:header>
<x-fab label="Compose" icon="edit" /> <x-fab label="Compose" icon="edit" />
@@ -96,7 +96,7 @@
</x-navigation-rail> </x-navigation-rail>
</div> </div>
<div class="flex h-[36rem] overflow-hidden rounded-corner-lg border border-outline-variant"> <div data-md-showcase-nav-demo="rail">
<x-navigation-rail mode="expanded" label="Expanded example"> <x-navigation-rail mode="expanded" label="Expanded example">
<x-slot:header> <x-slot:header>
<x-fab label="Compose" icon="edit" /> <x-fab label="Compose" icon="edit" />
@@ -115,13 +115,13 @@
</x-slot:footer> </x-slot:footer>
</x-navigation-rail> </x-navigation-rail>
</div> </div>
</div> </x-row>
BLADE, BLADE,
'Collapsible rail' => <<<'BLADE' 'Collapsible rail' => <<<'BLADE'
<div class="flex h-[30rem] w-full overflow-hidden rounded-corner-lg border border-outline-variant"> <div data-md-showcase-nav-demo="rail-wide">
<x-navigation-rail label="Collapsible example"> <x-navigation-rail label="Collapsible example">
<x-slot:brand> <x-slot:brand>
<span class="block truncate type-title-lg">Mail</span> <span class="md-type-title-lg md-truncate" style="display: block;">Mail</span>
</x-slot:brand> </x-slot:brand>
<x-slot:header> <x-slot:header>
@@ -133,16 +133,16 @@
<x-navigation-rail-item label="Sent" icon="send" link="#navigation" no-wire-navigate /> <x-navigation-rail-item label="Sent" icon="send" link="#navigation" no-wire-navigate />
</x-navigation-rail> </x-navigation-rail>
<div class="min-w-0 flex-1 bg-surface-container-low p-6 type-body-md text-on-surface-variant"> <div data-md-showcase-nav-content class="md-type-body-md md-ink-variant">
The menu button collapses and expands the rail, and the FAB morphs into an extended FAB with it. The choice is remembered and applied before the next page paints every collapsible rail follows it, <code>&lt;x-scaffold&gt;</code>'s from <code>expanded</code> (840px) too. The menu button collapses and expands the rail, and the FAB morphs into an extended FAB with it. The choice is remembered and applied before the next page paints every collapsible rail follows it, <code>&lt;x-scaffold&gt;</code>'s from <code>expanded</code> (840px) too.
</div> </div>
</div> </div>
BLADE, BLADE,
'Rail that hides when collapsed' => <<<'BLADE' 'Rail that hides when collapsed' => <<<'BLADE'
<div class="flex h-[30rem] w-full overflow-hidden rounded-corner-lg border border-outline-variant"> <div data-md-showcase-nav-demo="rail-wide">
<x-navigation-rail label="Immersive example" hide-when-collapsed> <x-navigation-rail label="Immersive example" hide-when-collapsed>
<x-slot:brand> <x-slot:brand>
<span class="block truncate type-title-lg">Studio</span> <span class="md-type-title-lg md-truncate" style="display: block;">Studio</span>
</x-slot:brand> </x-slot:brand>
<x-navigation-rail-item label="Canvas" icon="brush" link="#navigation" no-wire-navigate active /> <x-navigation-rail-item label="Canvas" icon="brush" link="#navigation" no-wire-navigate active />
@@ -150,25 +150,25 @@
<x-navigation-rail-item label="Exports" icon="download" link="#navigation" no-wire-navigate /> <x-navigation-rail-item label="Exports" icon="download" link="#navigation" no-wire-navigate />
</x-navigation-rail> </x-navigation-rail>
<div class="min-w-0 flex-1 space-y-4 bg-surface-container-low p-6 type-body-md text-on-surface-variant"> <x-stack gap="space200" data-md-showcase-nav-content class="md-type-body-md md-ink-variant">
<p>M3's other expanded behaviour: collapsing this rail takes it out of the layout instead of narrowing it to 96px, so an immersive page gets the whole window. The only way back is a menu button of the application's own — its own button then docks it again.</p> <p>M3's other expanded behaviour: collapsing this rail takes it out of the layout instead of narrowing it to 96px, so an immersive page gets the whole window. The only way back is a menu button of the application's own — its own button then docks it again.</p>
<x-button icon="menu" label="Open navigation" x-on:click="$store.rail.show()" /> <x-button icon="menu" label="Open navigation" x-on:click="$store.rail.show()" />
</div> </x-stack>
</div> </div>
BLADE, BLADE,
]; ];
@endphp @endphp
<section id="navigation" class="scroll-mt-24 space-y-6"> <x-livewire-material::stack as="section" id="navigation" gap="space300">
<h2 class="type-headline-md">Navigation</h2> <h2 class="md-type-headline-md">Navigation</h2>
<p class="max-w-3xl type-body-md text-on-surface-variant"> <p class="md-type-body-md md-ink-variant">
<code>&lt;x-navigation-bar&gt;</code> and <code>&lt;x-navigation-bar-item&gt;</code>, <code>&lt;x-navigation-rail&gt;</code>, <code>&lt;x-navigation-rail-item&gt;</code> and <code>&lt;x-navigation-rail-section&gt;</code>, <code>&lt;x-navigation-bar&gt;</code> and <code>&lt;x-navigation-bar-item&gt;</code>, <code>&lt;x-navigation-rail&gt;</code>, <code>&lt;x-navigation-rail-item&gt;</code> and <code>&lt;x-navigation-rail-section&gt;</code>,
and <code>&lt;x-scaffold&gt;</code>, which puts them together on M3's window size classes: a bar below <code>medium</code> (600px), a collapsed rail that opens as a modal through <code>medium</code>, a standard rail from <code>expanded</code> (840px) and an expanded one from <code>large</code> (1200px). and <code>&lt;x-scaffold&gt;</code>, which puts them together on M3's window size classes: a bar below <code>medium</code> (600px), a collapsed rail that opens as a modal through <code>medium</code>, a standard rail from <code>expanded</code> (840px) and an expanded one from <code>large</code> (1200px).
<a href="{{ route('livewire-material.shell') }}" class="link text-primary">Open the scaffold</a> and change the window's width. <a href="{{ route('livewire-material.shell') }}" class="md-link md-ink-primary">Open the scaffold</a> and change the window's width.
</p> </p>
@foreach ($examples as $title => $code) @foreach ($examples as $title => $code)
<x-showcase::example :$title :$code /> <x-showcase::example :$title :$code />
@endforeach @endforeach
</section> </x-livewire-material::stack>