Add the list-detail canonical layout
Plan step 35: <x-list-detail>, following the reference's visible-panes table row by row - one pane below expanded, the detail replacing the list with a back button once something is selected; from 840px the list a fixed 360px (412px from 1200px) beside the detail, 24px apart. The selection binds with wire:model or x-model; below expanded focus moves to the detail and back() returns it to the item (resources/js/layout.js). Grid columns mirror in RTL, and the back arrow turns with them. 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
b4f1e005de
commit
b5c5be1fd7
@@ -802,6 +802,39 @@ A content region: M3 puts all content in panes, and each may carry its own top a
|
||||
- The bar's leading button: the `leading` slot, or `back` — a URL makes it a link, `true` calls `back()` from `<x-list-detail>` around it (hidden there where both panes show). The 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 — not the bar's leading button.
|
||||
|
||||
#### `<x-list-detail>`
|
||||
|
||||
M3's list-detail canonical layout, for parent and child content: an inbox and a message, folders and a file, settings and a category. `list` and `detail` slots.
|
||||
|
||||
| Breakpoint | Visible panes |
|
||||
| --- | --- |
|
||||
| Compact, below 600px | 1: the list, or the detail once something is selected, with a back button |
|
||||
| Medium, 600–839 | 1, as compact (M3's recommendation) |
|
||||
| Expanded, 840–1199 | 2: the list 360px, the detail the rest, 24px apart, no back button |
|
||||
| Large and extra-large, from 1200 | 2: the list 412px |
|
||||
|
||||
```blade
|
||||
<x-list-detail wire:model.live="messageId">
|
||||
<x-slot:list>
|
||||
<x-pane title="Inbox">
|
||||
<x-list>
|
||||
@foreach ($messages as $message)
|
||||
<x-list-item :title="$message->subject" :link="route('messages.show', $message)" no-wire-navigate wire:click.prevent="$set('messageId', {{ $message->id }})" :selected="$message->id === $messageId" wire:key="message-{{ $message->id }}" />
|
||||
@endforeach
|
||||
</x-list>
|
||||
</x-pane>
|
||||
</x-slot:list>
|
||||
<x-slot:detail>
|
||||
<x-pane :title="$current?->subject" heading="h2" back>…</x-pane>
|
||||
</x-slot:detail>
|
||||
</x-list-detail>
|
||||
```
|
||||
|
||||
- `selected` is what is selected: bound with `wire:model` (the server renders the right pane from the property, so the first paint is right) or `x-model`, or given once. Nothing selected is `null`, `false` or `''`; `0` is an id. Inside both slots `selected` is in Alpine scope, and `back()` clears it (a boolean to `false`, anything else to `null`). An item selects with `wire:click.prevent="$set('messageId', 7)"` or `x-on:click.prevent="selected = 7"` on a list item whose `link` (with `no-wire-navigate`) opens the same detail without script, so the keyboard reaches it.
|
||||
- The back button: `<x-pane back>` in the detail slot puts it in that pane's app bar; without one, the layout draws its own row above the detail. Hidden from `expanded` either way.
|
||||
- Focus: below `expanded`, selecting moves focus to the detail pane and `back()` returns it to the item it came from (or the list's `aria-current`/`aria-selected` item, or the list). From `expanded` focus stays where it is. Mark the selected item (`:selected`, `aria-current`) — M3 shows a selected state in the list where both panes show.
|
||||
- A right-to-left document puts the list on the right. The root's attributes belong to Alpine (`wire:ignore.self`); the slots morph as usual.
|
||||
|
||||
#### `<x-surface>`
|
||||
|
||||
A tonal region: `<x-surface level="surface-container-low" padding="space300" corner="lg" outlined>…</x-surface>`.
|
||||
|
||||
Reference in New Issue
Block a user