Files
livewire-material/resources/views/components/account-menu.blade.php
T
Andreas Reinhold / reiniandClaude Opus 5 f90695cedd
tests / browser (chrome, chromium) (push) Successful in 3m34s
tests / browser (safari, webkit) (push) Successful in 6m2s
tests / lint (push) Successful in 59s
tests / feature (8.4) (push) Successful in 1m6s
tests / feature (8.5) (push) Successful in 1m9s
tests / browser (firefox, firefox) (push) Successful in 4m20s
Add app bars, toolbars, tabs and the account and theme controls
M3 Expressive top app bars (small, centered, medium and large flexible,
search) that collapse with CSS sticky, docked and floating toolbars,
primary and secondary tabs with a view-transition indicator, section
navigation, the account menu and theme toggles.

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

80 lines
2.9 KiB
PHP

{{-- Who is signed in, and what belongs to them rather than to a page: an avatar that opens a menu.
`name` and `email` head the menu; `avatar` is an image URL or, by default, the initials of the
name. The slot holds the items (`<x-menu-item>`: settings, billing…), a theme item follows unless
`:theme="false"`, and the `footer` slot comes last, after a separator the place for signing
out, furthest from the thumb:
<x-account-menu :name="$user->name" :email="$user->email">
<x-menu-item label="Settings" icon="settings" :link="route('settings')" />
<x-slot:footer>
<form method="POST" action="{{ route('logout') }}">
@csrf
<x-menu-item label="Sign out" icon="logout" type="submit" />
</form>
</x-slot:footer>
</x-account-menu>
`label` names the button and the menu ("Account"). `position` as on `<x-menu>` (`bottom-end`). --}}
@props([
'name' => null,
'email' => null,
'avatar' => null,
'label' => null,
'theme' => true,
'position' => 'bottom-end',
])
@php
$label ??= __('Account');
$image = filled($avatar) && (str_contains((string) $avatar, '/') || str_contains((string) $avatar, '.'));
$initials = $image ? null : ($avatar ?? \Illuminate\Support\Str::of((string) $name)->explode(' ')->filter()->take(2)->map(fn (string $word): string => mb_strtoupper(mb_substr($word, 0, 1)))->join(''));
@endphp
<x-menu :$label :$position {{ $attributes }}>
<x-slot:trigger>
<button
type="button"
aria-label="{{ $label }}"
data-account-menu
class="focus-ring inline-flex size-10 shrink-0 cursor-pointer items-center justify-center overflow-hidden rounded-corner-full bg-primary-container type-label-lg text-on-primary-container"
>
@if ($image)
<img src="{{ $avatar }}" alt="" class="size-full object-cover" />
@elseif (filled($initials))
{{ $initials }}
@else
<x-icon name="person" />
@endif
</button>
</x-slot:trigger>
@if (filled($name) || filled($email))
<div class="px-3 pt-2 pb-3">
@if (filled($name))
<p class="truncate type-title-sm text-on-surface">{{ $name }}</p>
@endif
@if (filled($email))
<p class="truncate type-body-sm text-on-surface-variant">{{ $email }}</p>
@endif
</div>
<x-menu-separator />
@endif
{{ $slot }}
@if ($theme)
<x-menu-item icon="contrast" x-on:click="$store.theme.toggle()" data-account-theme>
<span x-text="$store.theme.resolved === 'dark' ? @js(__('Light theme')) : @js(__('Dark theme'))">{{ __('Theme') }}</span>
</x-menu-item>
@endif
@isset($footer)
<x-menu-separator />
{{ $footer }}
@endisset
</x-menu>