Show each canonical layout on the showcase's Layout page
Plan step 35: the Layout section gains a working example of list-detail, supporting pane and feed, and one of surfaces, stacks, rows and grids, written with the layout components and md-* text classes only; the panes table names <x-list-detail> and <x-supporting-pane>. The showcase's own Tailwind stays for step 38. 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
0013e0154d
commit
d65e25b208
@@ -1,6 +1,92 @@
|
|||||||
{{-- M3's window size classes, live: the one this window is in, what each one changes, and the
|
{{-- 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
|
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. --}}
|
page proves the compiled breakpoints rather than describing them.
|
||||||
|
|
||||||
|
Then the layout components, and an example of each canonical layout — list-detail, supporting
|
||||||
|
pane, feed — written as an application writes them, with the layout components and the md-*
|
||||||
|
text classes and no Tailwind. Resize the window to watch each one change at its breakpoints. --}}
|
||||||
|
|
||||||
|
@php
|
||||||
|
$examples = [
|
||||||
|
'List-detail' => <<<'BLADE'
|
||||||
|
<x-surface level="surface" corner="lg" outlined x-data="{ message: null }" style="overflow: clip">
|
||||||
|
<x-list-detail x-model="message">
|
||||||
|
<x-slot:list>
|
||||||
|
<x-pane title="Inbox" heading="h3" :sticky="false">
|
||||||
|
<x-list label="Messages">
|
||||||
|
<x-list-item title="Anna Müller" description="The photos from Saturday" avatar="AM" link="#example-list-detail" no-wire-navigate x-on:click.prevent="selected = 1" x-bind:aria-current="selected === 1 ? 'true' : null" />
|
||||||
|
<x-list-item title="Ben Keller" description="Contract, second draft" avatar="BK" link="#example-list-detail" no-wire-navigate x-on:click.prevent="selected = 2" x-bind:aria-current="selected === 2 ? 'true' : null" />
|
||||||
|
<x-list-item title="Chiara Rossi" description="Train times for Friday" avatar="CR" link="#example-list-detail" no-wire-navigate x-on:click.prevent="selected = 3" x-bind:aria-current="selected === 3 ? 'true' : null" />
|
||||||
|
</x-list>
|
||||||
|
</x-pane>
|
||||||
|
</x-slot:list>
|
||||||
|
|
||||||
|
<x-slot:detail>
|
||||||
|
<x-pane heading="h3" back :sticky="false">
|
||||||
|
<x-stack gap="space200">
|
||||||
|
<p class="md-type-body-lg md-ink-variant" x-show="! selected">Select a message to read it.</p>
|
||||||
|
<p class="md-type-headline-sm" x-show="selected" x-text="{ 1: 'The photos from Saturday', 2: 'Contract, second draft', 3: 'Train times for Friday' }[selected]"></p>
|
||||||
|
<p class="md-type-body-lg" x-show="selected">Below 840px the list gives way to this message, with a back button that returns you — and your focus — to the list. From 840px both panes show, the list 360px wide and 412px from 1200px.</p>
|
||||||
|
</x-stack>
|
||||||
|
</x-pane>
|
||||||
|
</x-slot:detail>
|
||||||
|
</x-list-detail>
|
||||||
|
</x-surface>
|
||||||
|
BLADE,
|
||||||
|
'Supporting pane' => <<<'BLADE'
|
||||||
|
<x-supporting-pane label="Comments" compact="sheet">
|
||||||
|
<x-slot:main>
|
||||||
|
<x-surface level="surface" corner="lg" style="overflow: clip">
|
||||||
|
<x-pane title="Trip proposal" subtitle="Draft · edited today" heading="h3" :sticky="false">
|
||||||
|
<x-stack gap="space200" style="padding-block-end: var(--md-sys-measurement-space300)">
|
||||||
|
<p class="md-type-body-lg">Three days by the lake in June: the train on Friday morning, two nights at the harbour, and a walk round the old town on Sunday before the train home.</p>
|
||||||
|
<p class="md-type-body-lg">From 840px the comments sit beside the proposal, 360px wide (412px from 1200px). Below it they are a bottom sheet docked to the window: press its handle to read them.</p>
|
||||||
|
</x-stack>
|
||||||
|
</x-pane>
|
||||||
|
</x-surface>
|
||||||
|
</x-slot:main>
|
||||||
|
|
||||||
|
<x-slot:supporting>
|
||||||
|
<x-surface level="surface-container-low" corner="lg" padding="space200">
|
||||||
|
<x-list label="Comments">
|
||||||
|
<x-list-item title="Anna Müller" description="Friday works for me." avatar="AM" />
|
||||||
|
<x-list-item title="Ben Keller" description="Can we stay a third night?" avatar="BK" />
|
||||||
|
</x-list>
|
||||||
|
</x-surface>
|
||||||
|
</x-slot:supporting>
|
||||||
|
</x-supporting-pane>
|
||||||
|
BLADE,
|
||||||
|
'Feed' => <<<'BLADE'
|
||||||
|
<x-feed min-item="220px">
|
||||||
|
<x-card title="Harbour at dawn" subtitle="12 photos" variant="outlined">The boats before the ferry.</x-card>
|
||||||
|
<x-card title="Old town" subtitle="31 photos" variant="outlined">Every lane, twice.</x-card>
|
||||||
|
<x-card title="Lake swim" subtitle="4 videos" variant="outlined">Colder than it looks.</x-card>
|
||||||
|
<x-card title="Market" subtitle="18 photos" variant="outlined">Cheese, mostly.</x-card>
|
||||||
|
<x-card title="The long walk" subtitle="9 photos" variant="outlined">Up to the ridge and back.</x-card>
|
||||||
|
<x-card title="Train home" subtitle="3 photos" variant="outlined">Asleep by the second stop.</x-card>
|
||||||
|
</x-feed>
|
||||||
|
BLADE,
|
||||||
|
'Surfaces, stacks, rows and grids' => <<<'BLADE'
|
||||||
|
<x-stack gap="space300">
|
||||||
|
<x-grid :columns="['compact' => 1, 'medium' => 2, 'expanded' => 4]" gap="space200">
|
||||||
|
<x-surface level="surface-container-lowest" padding="space200" corner="md" outlined><p class="md-type-label-lg">lowest, outlined</p></x-surface>
|
||||||
|
<x-surface level="surface-container-low" padding="space200" corner="md"><p class="md-type-label-lg">low</p></x-surface>
|
||||||
|
<x-surface level="surface-container-high" padding="space200" corner="md"><p class="md-type-label-lg">high</p></x-surface>
|
||||||
|
<x-surface level="surface-container-highest" padding="space200" corner="md"><p class="md-type-label-lg">highest</p></x-surface>
|
||||||
|
</x-grid>
|
||||||
|
|
||||||
|
<x-row gap="space200" justify="between" stack-below="medium">
|
||||||
|
<x-stack gap="space50">
|
||||||
|
<p class="md-type-title-md">A row that stacks below 600px</p>
|
||||||
|
<p class="md-type-body-md md-ink-variant">Its middle item is hidden from 840px.</p>
|
||||||
|
</x-stack>
|
||||||
|
<x-stack hide-from="expanded"><p class="md-type-body-sm md-ink-variant">Widen the window past 840px and this goes.</p></x-stack>
|
||||||
|
<x-button label="Save" variant="filled" />
|
||||||
|
</x-row>
|
||||||
|
</x-stack>
|
||||||
|
BLADE,
|
||||||
|
];
|
||||||
|
@endphp
|
||||||
|
|
||||||
<section id="layout" class="scroll-mt-24 space-y-6">
|
<section id="layout" class="scroll-mt-24 space-y-6">
|
||||||
<h2 class="type-headline-md">Layout</h2>
|
<h2 class="type-headline-md">Layout</h2>
|
||||||
@@ -75,7 +161,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>Expanded</td>
|
<td>Expanded</td>
|
||||||
<td>Navigation rail, collapsible; starts collapsed</td>
|
<td>Navigation rail, collapsible; starts collapsed</td>
|
||||||
<td>Two: list-detail (<code><x-drawer pane></code>) or a 360px supporting pane</td>
|
<td>Two: <code><x-list-detail></code>, or <code><x-supporting-pane></code> at 360px</td>
|
||||||
<td>Basic dialogs, side sheets</td>
|
<td>Basic dialogs, side sheets</td>
|
||||||
<td>24px</td>
|
<td>24px</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -122,4 +208,8 @@
|
|||||||
<li><code><x-stack></code>, <code><x-row></code> and <code><x-grid></code> — arrangement inside a pane.</li>
|
<li><code><x-stack></code>, <code><x-row></code> and <code><x-grid></code> — arrangement inside a pane.</li>
|
||||||
</x-livewire-material::stack>
|
</x-livewire-material::stack>
|
||||||
</x-livewire-material::stack>
|
</x-livewire-material::stack>
|
||||||
|
|
||||||
|
@foreach ($examples as $title => $code)
|
||||||
|
<x-showcase::example :$title :$code stack />
|
||||||
|
@endforeach
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -463,3 +463,26 @@ it('draws no second margin for a pane or a canonical layout inside the scaffold\
|
|||||||
->assertScript(layoutRect('#text', 'left').' - '.layoutRect('main', 'left').' === 24')
|
->assertScript(layoutRect('#text', 'left').' - '.layoutRect('main', 'left').' === 24')
|
||||||
->assertScript(layoutStyle('#pane [data-md-pane-body]', 'paddingLeft')." === '0px'");
|
->assertScript(layoutStyle('#pane [data-md-pane-body]', 'paddingLeft')." === '0px'");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('shows each canonical layout working on the showcase\'s Layout page', function () {
|
||||||
|
$example = fn (string $title): string => "#example-{$title}";
|
||||||
|
|
||||||
|
$page = layoutReady(visit('/material/layout')->resize(1280, 900))
|
||||||
|
->assertScript("document.querySelectorAll('#example-list-detail [data-md-list-detail-pane]').length === 2")
|
||||||
|
->assertScript("[...document.querySelectorAll('#example-list-detail [data-md-list-detail-pane]')].every((pane) => pane.checkVisibility())")
|
||||||
|
->assertScript(layoutRect($example('supporting-pane').' [data-md-supporting-pane-supporting]', 'top').' === '.layoutRect($example('supporting-pane').' [data-md-supporting-pane-main]', 'top'))
|
||||||
|
->assertScript(layoutColumns($example('feed').' [data-md-feed]').' > 1');
|
||||||
|
|
||||||
|
$page->click('#example-list-detail a:has-text("Ben Keller")')
|
||||||
|
->assertSeeIn('#example-list-detail [data-md-list-detail-pane="detail"]', 'Contract, second draft')
|
||||||
|
->assertNoJavaScriptErrors();
|
||||||
|
|
||||||
|
$compact = layoutReady(visit('/material/layout')->resize(599, 900));
|
||||||
|
|
||||||
|
$compact->click('#example-list-detail a:has-text("Chiara Rossi")')
|
||||||
|
->assertSeeIn('#example-list-detail [data-md-list-detail-pane="detail"]', 'Train times for Friday')
|
||||||
|
->assertScript("! document.querySelector('#example-list-detail [data-md-list-detail-pane=\"list\"]').checkVisibility()")
|
||||||
|
->assertScript(layoutColumns($example('feed').' [data-md-feed]').' === 1')
|
||||||
|
->assertScript("document.querySelector('#example-supporting-pane [data-md-supporting-pane-handle]').checkVisibility()")
|
||||||
|
->assertNoJavaScriptErrors();
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user