Show M3's window size classes on a Layout page of the showcase

The page names the class this window is in, lights the five cards through the
compiled variants themselves, and tabulates what each class changes: navigation,
panes, dialogs and sheets, margins. Plan step 28, in part.

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 05:44:53 +02:00
co-authored by Claude Fable 5.1
parent 18023166bb
commit 0adfb6fff4
2 changed files with 106 additions and 0 deletions
@@ -0,0 +1,105 @@
{{-- M3's window size classes, live: the one this window is in, what each one changes, and the
variants that key on them. The five cards light up through the variants themselves, so the
page proves the compiled breakpoints rather than describing them. --}}
<section id="layout" class="scroll-mt-24 space-y-6">
<h2 class="type-headline-md">Layout</h2>
<p class="max-w-3xl type-body-md text-on-surface-variant">
Widths are M3's window size classes and nothing else: compact below 600px, then <code>medium:</code> 600,
<code>expanded:</code> 840, <code>large:</code> 1200 and <code>extra-large:</code> 1600, with
<code>max-medium:</code> and friends for "below". Tailwind's <code>sm:</code>…<code>2xl:</code> compile to
nothing. Scripts read the same numbers from <code>resources/js/breakpoints.js</code>.
</p>
<div
x-data="{ width: window.innerWidth }"
x-on:resize.window="width = window.innerWidth"
class="flex flex-wrap items-baseline gap-x-4 gap-y-1 rounded-corner-lg bg-surface-container-low p-6"
data-test="window-class"
>
<span class="type-label-lg text-on-surface-variant">This window</span>
<span class="type-emphasized-headline-sm tabular-nums" x-text="width + 'px'"></span>
<span class="type-title-md" x-text="width < 600 ? 'compact' : width < 840 ? 'medium' : width < 1200 ? 'expanded' : width < 1600 ? 'large' : 'extra-large'"></span>
</div>
<div class="grid gap-3 medium:grid-cols-5">
<div class="rounded-corner-md bg-surface-container p-4 max-medium:bg-primary-container max-medium:text-on-primary-container">
<p class="type-title-sm">Compact</p>
<p class="type-body-sm">below 600px</p>
</div>
<div class="rounded-corner-md bg-surface-container p-4 medium:max-expanded:bg-primary-container medium:max-expanded:text-on-primary-container">
<p class="type-title-sm">Medium</p>
<p class="type-body-sm">600839px</p>
</div>
<div class="rounded-corner-md bg-surface-container p-4 expanded:max-large:bg-primary-container expanded:max-large:text-on-primary-container">
<p class="type-title-sm">Expanded</p>
<p class="type-body-sm">8401199px</p>
</div>
<div class="rounded-corner-md bg-surface-container p-4 large:max-extra-large:bg-primary-container large:max-extra-large:text-on-primary-container">
<p class="type-title-sm">Large</p>
<p class="type-body-sm">12001599px</p>
</div>
<div class="rounded-corner-md bg-surface-container p-4 extra-large:bg-primary-container extra-large:text-on-primary-container">
<p class="type-title-sm">Extra-large</p>
<p class="type-body-sm">from 1600px</p>
</div>
</div>
<div class="overflow-x-auto rounded-corner-lg border border-structure">
<table class="w-full type-body-md" data-table>
<thead>
<tr>
<th class="text-start">Class</th>
<th class="text-start">Navigation</th>
<th class="text-start">Panes</th>
<th class="text-start">Dialogs and sheets</th>
<th class="text-start">Margin</th>
</tr>
</thead>
<tbody>
<tr>
<td>Compact</td>
<td>Navigation bar; the rail opens as a modal</td>
<td>One</td>
<td>Full-screen dialogs, bottom sheets for choices, date pickers as dialogs</td>
<td>16px</td>
</tr>
<tr>
<td>Medium</td>
<td>Collapsed navigation rail</td>
<td>One</td>
<td>Basic dialogs, docked search and pickers</td>
<td>24px</td>
</tr>
<tr>
<td>Expanded</td>
<td>Navigation rail, collapsible; starts collapsed</td>
<td>Two: list-detail (<code>&lt;x-drawer pane&gt;</code>) or a 360px supporting pane</td>
<td>Basic dialogs, side sheets</td>
<td>24px</td>
</tr>
<tr>
<td>Large</td>
<td>Navigation rail, expanded by default</td>
<td>Two; a fixed pane is 412px</td>
<td>Basic dialogs, side sheets</td>
<td>24px</td>
</tr>
<tr>
<td>Extra-large</td>
<td>Navigation rail, expanded</td>
<td>Two, a third as a side sheet</td>
<td>Basic dialogs, side sheets</td>
<td>24px</td>
</tr>
</tbody>
</table>
</div>
<p class="max-w-3xl type-body-md text-on-surface-variant">
<code>&lt;x-app-shell&gt;</code> does all of this: resize this showcase and watch the bar, the rail and the
content margin (<code>--material-margin</code>) change at 600, 840 and 1200px. A visitor who has chosen a rail
width keeps it; until then the rail follows the class.
</p>
</section>
+1
View File
@@ -87,6 +87,7 @@ class Sections
'shape' => ['title' => 'Shape', 'icon' => 'interests', 'group' => 'Foundations', 'description' => 'Corner radii and the 35 M3 Expressive shapes.'],
'elevation' => ['title' => 'Elevation', 'icon' => 'layers', 'group' => 'Foundations', 'description' => 'Shadows for what floats over content.'],
'motion' => ['title' => 'Motion', 'icon' => 'animation', 'group' => 'Foundations', 'description' => 'Spatial springs and effects easings.'],
'layout' => ['title' => 'Layout', 'icon' => 'devices', 'group' => 'Foundations', 'description' => 'M3\'s window size classes, what changes at each, and the app shell\'s response.'],
'icons' => ['title' => 'Icons', 'icon' => 'emoji_symbols', 'group' => 'Foundations', 'description' => 'Every Material Symbol, searchable, outlined and filled.'],
'buttons' => ['title' => 'Buttons', 'icon' => 'smart_button', 'group' => 'Actions', 'description' => 'Buttons, icon buttons, groups, split buttons and FABs.'],
'menus' => ['title' => 'Menus', 'icon' => 'menu_open', 'group' => 'Actions', 'description' => 'Menus with items, groups, choices and shortcuts.'],