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
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
78 lines
2.9 KiB
PHP
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>
|