Files
livewire-material/resources/views/components/app-bar.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

78 lines
2.9 KiB
PHP

{{-- M3 Expressive's top app bar: the title of the screen, a navigation button and its actions.
`variant`: `small` (the default, 64px), `center` (the title centred), `medium` and `large` (a
big title under the row that collapses into the small one as the page scrolls), and `search`
(a search bar fills the row: put an `<x-search>` in the slot). `title` and `subtitle`; the
title is an `<h1>` unless `heading` names another element. Slots: `navigation` (the leading
icon button: back, or the menu) and `actions` (trailing icon buttons, an avatar).
Sticky at the top by default (`:sticky="false"` for one that scrolls away), under the top safe
area; the surface turns surface-container once content scrolls under it
(resources/css/components/app-bar.css, resources/js/app-bar.js). A collapsing bar needs the
window to be what scrolls: an ancestor with `overflow: hidden` or `auto` would stop it
sticking (`overflow-x: clip` is fine). --}}
@props([
'title' => null,
'subtitle' => null,
'variant' => 'small',
'sticky' => true,
'heading' => 'h1',
])
@php
$variant = in_array($variant, ['small', 'center', 'medium', 'large', 'search'], true) ? $variant : 'small';
$flexible = in_array($variant, ['medium', 'large'], true);
$heading = in_array($heading, ['h1', 'h2', 'h3', 'div', 'p'], true) ? $heading : 'h1';
@endphp
<header
x-data="materialAppBar"
x-bind:data-scrolled="scrolled ? '' : null"
x-bind:data-collapsed="collapsed ? '' : null"
x-bind:style="measured"
data-app-bar
data-variant="{{ $variant }}"
@if ($sticky) data-sticky @endif
@if (filled($subtitle)) data-subtitled @endif
{{ $attributes }}
>
<div data-app-bar-row>
@isset($navigation)
<div data-app-bar-leading>{{ $navigation }}</div>
@endisset
@if ($variant === 'search')
<div data-app-bar-search>{{ $slot }}</div>
@elseif (filled($title))
<div data-app-bar-headline @if ($flexible) aria-hidden="true" @endif>
@if ($flexible)
<span data-app-bar-title>{{ $title }}</span>
@else
<{{ $heading }} data-app-bar-title>{{ $title }}</{{ $heading }}>
@if (filled($subtitle))
<p data-app-bar-subtitle>{{ $subtitle }}</p>
@endif
@endif
</div>
@endif
@isset($actions)
<div data-app-bar-trailing>{{ $actions }}</div>
@endisset
</div>
@if ($flexible && filled($title))
<div data-app-bar-expanded>
<{{ $heading }} data-app-bar-title>{{ $title }}</{{ $heading }}>
@if (filled($subtitle))
<p data-app-bar-subtitle>{{ $subtitle }}</p>
@endif
</div>
@endif
@if ($variant !== 'search' && $slot->hasActualContent())
{{ $slot }}
@endif
</header>