Let a rail hide when collapsed instead of narrowing
Plan step 25 (navigation Missing): M3's "Expanded behavior | Hide when collapsed" was only implicit below `medium` in the adaptive rail. `<x-navigation-rail hide-when-collapsed>` (collapsible and adaptive rails) takes the rail out of the layout when it is collapsed; `$store.rail.show()` from an app-bar menu button brings it back expanded over a scrim, sliding in, and its own menu button docks it again. It does not reach the bands where the window, not the visitor, collapses a rail (below `medium` for collapsible, `medium` for adaptive), since M3's collapsed rail may never hide. Every `rail-collapsed` branch now stops while the rail is open. `<x-app-shell hide-rail-when-collapsed>` exposes it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
co-authored by
Claude Opus 5
parent
a5acbe7f6b
commit
9c047a8fb1
@@ -56,7 +56,11 @@
|
||||
phone opens. `label` names both navigation landmarks ("Main"); `rail-width` is the expanded
|
||||
rail's width; `tall-bar` picks M3's 80px navigation bar over the 64px one, and the bottom
|
||||
offset every pinned thing reads follows it; `hide-bar-on-scroll` lets the bar leave the window
|
||||
while the page scrolls down, and `--material-bottom-bar` goes down and comes back with it.
|
||||
while the page scrolls down, and `--material-bottom-bar` goes down and comes back with it;
|
||||
`hide-rail-when-collapsed` is M3's immersive configuration — from `expanded` the rail leaves
|
||||
the layout when the menu button collapses it, rather than narrowing to 96px, so the page has
|
||||
the whole window. The only way back is `$store.rail.show()`, so put a menu button in the app
|
||||
bar at every width, not just below `medium`.
|
||||
|
||||
`banner` or `top` is a decision about what the bar belongs to: an application-wide bar — one
|
||||
search, one account menu, the same on every page — spans the window and the rail starts under
|
||||
@@ -86,6 +90,7 @@
|
||||
'railWidth' => '16rem',
|
||||
'tallBar' => false,
|
||||
'hideBarOnScroll' => false,
|
||||
'hideRailWhenCollapsed' => false,
|
||||
])
|
||||
|
||||
@php
|
||||
@@ -132,7 +137,7 @@
|
||||
@endisset
|
||||
|
||||
<div class="flex-1 medium:flex">
|
||||
<x-livewire-material::navigation-rail mode="adaptive" :label="$label" :width="$railWidth">
|
||||
<x-livewire-material::navigation-rail mode="adaptive" :label="$label" :width="$railWidth" :hide-when-collapsed="$hideRailWhenCollapsed">
|
||||
@isset($brand)
|
||||
<x-slot:brand>{{ $brand }}</x-slot:brand>
|
||||
@endisset
|
||||
|
||||
@@ -60,7 +60,13 @@
|
||||
puts the destinations at the rail's vertical centre — M3 prefers that on a tablet, for reach —
|
||||
while the menu button, the brand and the FAB stay at the top and the footer at the foot, as M3
|
||||
asks; more destinations than fit go back to the top rather than out of reach above the
|
||||
scroller; `menu` shows the menu button (by default for `collapsible`,
|
||||
scroller; `hide-when-collapsed` is M3's other expanded behaviour, for a `collapsible` or
|
||||
`adaptive` rail: collapsing it takes it out of the layout altogether instead of narrowing it
|
||||
to 96px, and it comes back expanded over a scrim when something calls `$store.rail.show()` —
|
||||
a menu button in the app bar, which is the only way back, so put one there. Its own menu
|
||||
button then docks it into the layout again. Not below `medium` for a collapsible rail, nor at
|
||||
`medium` for an adaptive one: there it is the window and not the visitor that collapses a
|
||||
rail, and M3's collapsed rail may never hide; `menu` shows the menu button (by default for `collapsible`,
|
||||
`modal` and `adaptive`); `divider` draws M3's optional vertical divider on the edge the page
|
||||
is on — which is also what M3 asks for when a page scrolls underneath a fixed rail; `fill`
|
||||
(`false`) drops the container colour for a transparent rail over the page's own background,
|
||||
@@ -83,6 +89,7 @@
|
||||
'label' => null,
|
||||
'width' => '16rem',
|
||||
'align' => 'top',
|
||||
'hideWhenCollapsed' => false,
|
||||
'menu' => null,
|
||||
'divider' => false,
|
||||
'fill' => true,
|
||||
@@ -91,7 +98,10 @@
|
||||
@php
|
||||
$mode = in_array($mode, ['collapsed', 'expanded', 'collapsible', 'modal', 'adaptive'], true) ? $mode : 'collapsible';
|
||||
$interactive = in_array($mode, ['collapsible', 'modal', 'adaptive'], true);
|
||||
$canOpen = in_array($mode, ['modal', 'adaptive'], true);
|
||||
// Only a rail that has a collapsed *and* an expanded state of its own can hide instead of
|
||||
// narrowing; a `modal` one is already over the page, and the two fixed modes mean what they say.
|
||||
$hideWhenCollapsed = $hideWhenCollapsed && in_array($mode, ['collapsible', 'adaptive'], true);
|
||||
$canOpen = in_array($mode, ['modal', 'adaptive'], true) || $hideWhenCollapsed;
|
||||
$menu ??= $interactive;
|
||||
$collapsedAtFirst = in_array($mode, ['collapsed', 'modal'], true);
|
||||
$narrow = $width === 'narrow';
|
||||
@@ -103,10 +113,11 @@
|
||||
data-navigation-rail="{{ $mode }}"
|
||||
@if ($narrow) data-width="narrow" @endif
|
||||
@if ($centred) data-align="center" @endif
|
||||
@if ($hideWhenCollapsed) data-hide-when-collapsed @endif
|
||||
@if ($divider) data-divider @endif
|
||||
@unless ($fill) data-fill="false" @endunless
|
||||
@if ($interactive)
|
||||
x-data="materialNavigationRail('{{ $mode }}')"
|
||||
x-data="materialNavigationRail('{{ $mode }}', {{ $hideWhenCollapsed ? 'true' : 'false' }})"
|
||||
x-bind:data-open="open"
|
||||
@endif
|
||||
{{ $attributes->merge(['style' => "--navigation-rail-width: {$width}"]) }}
|
||||
|
||||
@@ -138,6 +138,24 @@
|
||||
</div>
|
||||
</div>
|
||||
BLADE,
|
||||
'Rail that hides when collapsed' => <<<'BLADE'
|
||||
<div class="flex h-[30rem] w-full overflow-hidden rounded-corner-lg border border-outline-variant">
|
||||
<x-navigation-rail label="Immersive example" hide-when-collapsed>
|
||||
<x-slot:brand>
|
||||
<span class="block truncate type-title-lg">Studio</span>
|
||||
</x-slot:brand>
|
||||
|
||||
<x-navigation-rail-item label="Canvas" icon="brush" link="#navigation" no-wire-navigate active />
|
||||
<x-navigation-rail-item label="Layers" icon="layers" link="#navigation" no-wire-navigate />
|
||||
<x-navigation-rail-item label="Exports" icon="download" link="#navigation" no-wire-navigate />
|
||||
</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">
|
||||
<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()" />
|
||||
</div>
|
||||
</div>
|
||||
BLADE,
|
||||
];
|
||||
@endphp
|
||||
|
||||
|
||||
Reference in New Issue
Block a user