Add the pane layout component
Plan step 35: <x-pane>, a content region with M3's margins (16px below medium, 24px from it) drawn once however panes and layouts nest, a width cap, and an optional pane app bar - <x-app-bar> as a direct child of the pane with title, subtitle, actions, a back link or action, a leading slot, and the section navigation under 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
e99c5993d8
commit
b4f1e005de
@@ -0,0 +1,88 @@
|
||||
{{-- A pane: a content region with M3's margins, and its own top app bar if it has a title.
|
||||
|
||||
<x-pane title="Settings" subtitle="Your account" width="narrow">
|
||||
<x-slot:actions><x-button icon="help" tooltip="Help" /></x-slot:actions>
|
||||
<x-slot:navigation><x-section-nav :items="$sections" /></x-slot:navigation>
|
||||
…
|
||||
</x-pane>
|
||||
|
||||
M3 puts every piece of content in a pane and lets each carry its own top app bar
|
||||
(docs/reference/m3/foundations.md § Layout → Scaffold). The body is kept off the window's edge
|
||||
by M3's margin, 16px below medium (600px) and 24px from it
|
||||
(docs/reference/m3/foundations-supplement.md § Breakpoints); a pane inside something that
|
||||
already keeps that margin — the scaffold's content region, a canonical layout, another pane's
|
||||
body — draws none, so the margin is never doubled; on an `<x-surface>` it draws it again.
|
||||
|
||||
`width` caps the pane and centres it: `narrow` (40rem, M3's 40–60 characters a line),
|
||||
`medium` (60rem), `wide` (80rem) or `full` (the default, all the room it has).
|
||||
|
||||
The app bar is `<x-app-bar>`, drawn when there is a `title`, `actions`, a `leading` slot or
|
||||
`back`: `title` and `subtitle`, `heading` (`h1` by default; the second pane of a canonical
|
||||
layout passes `h2`), `sticky` (true: it holds to the top of the window for as long as the pane
|
||||
is on screen), the `actions` slot at its end. Its leading icon button is the `leading` slot,
|
||||
or `back`: a URL makes it a link back there, and `true` calls `back()` in the Alpine scope
|
||||
around it, which `<x-list-detail>` provides — and which it hides where both panes show, as M3
|
||||
shows a back button only in a single-pane list-detail. The back arrow mirrors in a
|
||||
right-to-left document.
|
||||
|
||||
`navigation` is the pane's section navigation (`<x-section-nav>`, `<x-tabs>`), under the bar
|
||||
and above the body, with the body's margins; it is not the bar's leading button.
|
||||
|
||||
It takes `as` (`div` by default: `section`, `article`, `main` …), `hide-below` and `hide-from`
|
||||
like every layout component, and the caller's `class` and `style` land on it untouched. Drawn
|
||||
by resources/css/layout/pane.css. --}}
|
||||
|
||||
@props([
|
||||
'as' => null,
|
||||
'title' => null,
|
||||
'subtitle' => null,
|
||||
'heading' => 'h1',
|
||||
'sticky' => true,
|
||||
'back' => null,
|
||||
'width' => null,
|
||||
'hideBelow' => null,
|
||||
'hideFrom' => null,
|
||||
])
|
||||
|
||||
@php
|
||||
$layout = \NoNameWeb\LivewireMaterial\Support\Layout::class;
|
||||
$element = $layout::element($as);
|
||||
$backLink = is_string($back) && $back !== '' ? $back : null;
|
||||
$backAction = $back === true;
|
||||
$bar = filled($title) || isset($actions) || isset($leading) || $backLink !== null || $backAction;
|
||||
|
||||
$attributes = $attributes->merge(array_filter([
|
||||
'data-md-pane' => true,
|
||||
'data-md-width' => $layout::choice($width, ['full', 'narrow', 'medium', 'wide']),
|
||||
] + $layout::visibility($hideBelow, $hideFrom), fn ($value): bool => $value !== null));
|
||||
@endphp
|
||||
|
||||
<{{ $element }} {{ $attributes }}>
|
||||
@if ($bar)
|
||||
<x-livewire-material::app-bar :title="$title" :subtitle="$subtitle" :heading="$heading" :sticky="$sticky" data-md-pane-bar>
|
||||
@if (isset($leading))
|
||||
<x-slot:navigation>{{ $leading }}</x-slot:navigation>
|
||||
@elseif ($backLink !== null || $backAction)
|
||||
<x-slot:navigation>
|
||||
<span data-md-pane-back @if ($backAction) data-md-list-detail-back @endif>
|
||||
@if ($backLink !== null)
|
||||
<x-livewire-material::button icon="arrow_back" :tooltip="__('Back')" :link="$backLink" />
|
||||
@else
|
||||
<x-livewire-material::button icon="arrow_back" :tooltip="__('Back')" x-on:click="back()" />
|
||||
@endif
|
||||
</span>
|
||||
</x-slot:navigation>
|
||||
@endif
|
||||
|
||||
@isset($actions)
|
||||
<x-slot:actions>{{ $actions }}</x-slot:actions>
|
||||
@endisset
|
||||
</x-livewire-material::app-bar>
|
||||
@endif
|
||||
|
||||
@isset($navigation)
|
||||
<div data-md-pane-navigation>{{ $navigation }}</div>
|
||||
@endisset
|
||||
|
||||
<div data-md-pane-body>{{ $slot }}</div>
|
||||
</{{ $element }}>
|
||||
Reference in New Issue
Block a user