Files
livewire-material/resources/views/showcase/shell.blade.php
T
Andreas Reinhold / reiniandClaude Opus 5 889f8a8aa1
tests / lint (push) Has been cancelled
tests / feature (8.4) (push) Has been cancelled
tests / feature (8.5) (push) Has been cancelled
tests / browser (chrome, chromium) (push) Has been cancelled
tests / browser (firefox, firefox) (push) Has been cancelled
tests / browser (safari, webkit) (push) Has been cancelled
Put the showcase in the app shell, with a page per section
The showcase is now an overview and one page per section behind a
grouped navigation rail, moved between with wire:navigate, instead of
one long page under a scrolling top bar. The switch exposed a WebKit
bug in the menu: inside a focusable region, WebKit moves focus out of
the closing popover before its toggle event, so Escape no longer
returned focus to the trigger. The menu now reads it on beforetoggle.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
2026-09-13 09:30:26 +02:00

88 lines
4.5 KiB
PHP

{{-- The app shell, as a whole page: /material/shell and its sibling pages, so the rail, the bar, the
modal rail and wire:navigate between pages can be tried at any window width. --}}
@php
$page ??= 'inbox';
$pages = [
'inbox' => ['title' => 'Inbox', 'icon' => 'inbox', 'badge' => 12],
'starred' => ['title' => 'Starred', 'icon' => 'star'],
'sent' => ['title' => 'Sent', 'icon' => 'send'],
'drafts' => ['title' => 'Drafts', 'icon' => 'draft', 'badge' => true],
'travel' => ['title' => 'Travel', 'icon' => 'flight', 'section' => 'Labels', 'bar' => false],
'receipts' => ['title' => 'Receipts', 'icon' => 'receipt_long', 'section' => 'Labels', 'bar' => false],
];
$destinations = collect($pages)
->map(fn (array $destination, string $key): array => $destination + [
'url' => route('livewire-material.shell', $key === 'inbox' ? [] : ['page' => $key]),
'active' => $key === $page,
])
->values()
->all();
$current = $pages[$page];
@endphp
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
<meta name="robots" content="noindex" />
<title>{{ $current['title'] }} · App shell · Livewire Material</title>
<x-livewire-material::theme-script />
@vite(config('livewire-material.showcase.vite'))
@livewireStyles
</head>
<body class="bg-surface font-sans text-on-surface antialiased">
<x-livewire-material::app-shell :destinations="$destinations">
<x-slot:brand>
<a href="{{ route('livewire-material.showcase') }}" class="block truncate rounded-corner-xs type-title-lg focus-ring">Livewire Material</a>
</x-slot:brand>
<x-slot:rail-header>
<span class="rail-collapsed:hidden"><x-livewire-material::fab label="Compose" icon="edit" x-on:click="materialToast('Compose opens here')" /></span>
<span class="hidden rail-collapsed:inline-flex"><x-livewire-material::fab icon="edit" tooltip-right="Compose" x-on:click="materialToast('Compose opens here')" /></span>
</x-slot:rail-header>
<x-slot:rail-footer>
<x-livewire-material::navigation-rail-item label="Settings" icon="settings" link="#settings" no-wire-navigate />
</x-slot:rail-footer>
<x-slot:actions>
<x-livewire-material::button icon="dark_mode" tooltip-right="Switch theme" x-data x-on:click="$store.theme.toggle()" />
<x-livewire-material::button icon="help" tooltip-right="Help" x-on:click="materialToast('Help opens here')" />
</x-slot:actions>
<x-slot:top>
<header class="sticky top-0 z-20 flex h-16 items-center gap-1 bg-surface px-1 pt-[env(safe-area-inset-top)] sm:px-4">
<span class="sm:hidden"><x-livewire-material::button icon="menu" tooltip="Open navigation" x-data x-on:click="$store.rail.show()" data-test="shell-menu" /></span>
<h1 class="min-w-0 flex-1 truncate px-3 type-title-lg sm:px-0">{{ $current['title'] }}</h1>
<x-livewire-material::button icon="search" tooltip="Search" />
</header>
</x-slot:top>
<div class="mx-auto w-full max-w-5xl space-y-4 px-4 pb-6 sm:px-6">
<p class="type-body-md text-on-surface-variant" data-test="shell-page">This is the {{ strtolower($current['title']) }} page.</p>
<x-livewire-material::list segmented>
@foreach (range(1, 14) as $index)
<x-livewire-material::list-item :title="$current['title'].' item '.$index" description="A line of supporting text for this item" :icon="$current['icon']" trailing="{{ $index }}h" wire:key="item-{{ $index }}" />
@endforeach
</x-livewire-material::list>
<div class="flex flex-wrap gap-2">
<x-livewire-material::button label="Show a toast" variant="tonal" x-data x-on:click="materialToast('Moved to archive', { action: { label: 'Undo', handler: () => {} } })" />
<x-livewire-material::button label="Back to the showcase" link="{{ route('livewire-material.section', 'navigation') }}" no-wire-navigate />
</div>
</div>
</x-livewire-material::app-shell>
@livewireScripts
</body>
</html>