Files
livewire-material/resources/views/components/account-menu.blade.php
T
Andreas Reinhold / reiniandClaude Opus 5 1e580c573e Resolve the package's own components through its namespace
Package views now write <x-livewire-material::button>, so a configured
prefix (which Blade spells <x-m::button>) and an application component
of the same name can no longer break or shadow them. The showcase
rewrites its examples to the configured prefix. Adds the README, and
waits for the adaptive rail to hear a resize before the navigation
tests press its menu button.

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

80 lines
3.1 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-livewire-material::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-livewire-material::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-livewire-material::menu-separator />
@endif
{{ $slot }}
@if ($theme)
<x-livewire-material::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-livewire-material::menu-item>
@endif
@isset($footer)
<x-livewire-material::menu-separator />
{{ $footer }}
@endisset
</x-livewire-material::menu>