Add the rail's narrow collapsed width

Plan step 25 (navigation Missing): NavigationRailCollapsedTokens
.NarrowContainerWidth, 80dp, had no way in — only the default 96.
`<x-navigation-rail width="narrow">` takes it; the collapsed width is now a
variable, so the four rules that each have their own reason to name it follow
without a specificity fight. No label fits under a 56px indicator at 80px, so a
narrow rail's items are their icons alone, with the label taken out of the
drawing and left in the accessibility tree, where it names the destination.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
Andreas Reinhold / reini
2026-09-14 06:39:31 +02:00
co-authored by Claude Fable 5.1
parent ce1cd6eec0
commit cef350d739
5 changed files with 86 additions and 12 deletions
@@ -52,7 +52,11 @@
Nothing that shows while collapsed may be wider than 96px.
Props: `label` names the landmark ("Main"); `width` is the expanded width (`16rem`, held
between M3's 220 and 360dp); `menu` shows the menu button (by default for `collapsible`,
between M3's 220 and 360dp) or the word `narrow`, M3's other *collapsed* width
(NavigationRailCollapsedTokens.NarrowContainerWidth, 80px against the default 96), where the
items are their icons alone because no label fits under a 56px indicator at that width; the
labels stay in the accessibility tree, since they are what name the destinations, and a
narrow rail expands to the default 16rem; `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,
@@ -85,10 +89,13 @@
$canOpen = in_array($mode, ['modal', 'adaptive'], true);
$menu ??= $interactive;
$collapsedAtFirst = in_array($mode, ['collapsed', 'modal'], true);
$narrow = $width === 'narrow';
$width = $narrow ? '16rem' : $width;
@endphp
<div
data-navigation-rail="{{ $mode }}"
@if ($narrow) data-width="narrow" @endif
@if ($divider) data-divider @endif
@unless ($fill) data-fill="false" @endunless
@if ($interactive)
@@ -112,7 +119,9 @@
@if ($menu || isset($brand) || isset($header))
<div data-navigation-rail-header>
@if ($menu || isset($brand))
<div @class(['flex w-full min-w-0 items-center gap-3 pe-5', 'ps-7' => $menu, 'ps-5' => ! $menu])>
{{-- The menu button is centred on the collapsed rail: 28px either side of a
40px button in 96, 20px in a narrow 80. --}}
<div @class(['flex w-full min-w-0 items-center gap-3 pe-5', 'ps-7' => $menu, 'rail-collapsed:ps-5' => $menu && $narrow, 'ps-5' => ! $menu])>
@if ($menu)
<button
type="button"
@@ -136,7 +145,8 @@
@endif
@isset($header)
<div {{ $header->attributes->class(['flex w-full flex-col items-start gap-2 px-5']) }}>{{ $header }}</div>
{{-- And so is a 56px FAB: 20px either side in 96, 12px in a narrow 80. --}}
<div {{ $header->attributes->class(['flex w-full flex-col items-start gap-2 px-5', 'rail-collapsed:px-3' => $narrow]) }}>{{ $header }}</div>
@endisset
</div>
@endif