Draw the app bar without Tailwind
Plan step 36 (navigation group, first stream): <x-app-bar>'s class
lists move into resources/css/components/app-bar.css, keyed on
data-md-app-bar (with data-md-variant/-sticky/-subtitled/-scrolled/
-collapsed) and its parts data-md-app-bar-row/-leading/-headline/
-title/-subtitle/-search/-trailing/-action/-overflow/-expanded. The
overflow menu (two icon buttons below 600px, four from it, N-09's
312px search cap and N-11's three-column centred row) already matched
the audit; only its hooks, units and layer needed to change. Every
length is px, spacing through the measurement tokens where one
matches (M3's own "4dp leading/trailing space" and "16dp" headline
inset had no exact token, so those stay literal). Imports button.css,
menu.css and menu-item.css for the overflow menu the view renders.
Hooks renamed: every unprefixed data-app-bar-* attribute and
data-scrolled/data-collapsed to data-md-*, updated in
tests/Feature/Components/{AppBarTest,PaneTest}.php and
tests/Browser/{BarsTest,NavigationTest}.php. app-bar.js needed no
change: it reads the bar through $root, not by hook name.
tests/Feature/Components/NavigationStylesheetsTest.php is the
navigation twin of ContainmentStylesheetsTest.php, on the same
tests/Support/ViewClasses.php rule; its dataset starts at 'app-bar'
and a 'tabs' entry (once that commit lands) will read both
tabs.blade.php and tab.blade.php, since they share one stylesheet.
Added the owed browser tests (docs/plans/material-3-browser-tests.md):
the overflow at 599/600px, keyboard in its menu, a menu closing once
its width no longer shows it, and a wire:click action from both the
icon button and the menu item form.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
b7f120af98
commit
b7641a35c2
@@ -69,3 +69,4 @@
|
||||
@import './components/error-page.css';
|
||||
|
||||
/* Navigation */
|
||||
@import './components/app-bar.css';
|
||||
|
||||
@@ -1,14 +1,25 @@
|
||||
/*
|
||||
* M3 Expressive's top app bars (AppBarTokens, AppBarSmallTokens, AppBarMediumFlexibleTokens,
|
||||
* AppBarLargeFlexibleTokens, androidx Compose Material 3, Apache-2.0).
|
||||
* `<x-app-bar>`: M3 Expressive's top app bars (AppBarTokens.kt, AppBarSmallTokens.kt,
|
||||
* AppBarMediumFlexibleTokens.kt, AppBarLargeFlexibleTokens.kt, androidx Compose Material 3,
|
||||
* Apache-2.0; docs/reference/m3/components-navigation-selection-inputs.md § Top App Bar).
|
||||
*
|
||||
* [data-md-app-bar] the bar; data-md-variant, data-md-sticky, data-md-subtitled,
|
||||
* data-md-scrolled/data-md-collapsed (resources/js/app-bar.js)
|
||||
* [data-md-app-bar-row] 64px, sticky at the top of the bar
|
||||
* [data-md-app-bar-leading] the `navigation` slot
|
||||
* [data-md-app-bar-headline] [data-md-app-bar-title], [data-md-app-bar-subtitle]
|
||||
* [data-md-app-bar-search] the `search` variant's slot
|
||||
* [data-md-app-bar-trailing] [data-md-app-bar-action], [data-md-app-bar-overflow]
|
||||
* [data-md-app-bar-expanded] medium/large's big title, under the row
|
||||
*
|
||||
* small 64px, title-large title (label-medium subtitle), 4px from the edges, the title 16px
|
||||
* from the start or straight after the navigation icon
|
||||
* center the same, the title centred — a three-column grid, so it shrinks against whatever is
|
||||
* beside it rather than ellipsising underneath it
|
||||
* beside it rather than ellipsising underneath it (N-11: a fixed inset fit exactly one
|
||||
* of M3's two trailing buttons)
|
||||
* medium 112px (136px with a subtitle): the 64px row of icons over a headline-medium title
|
||||
* large 120px (152px with a subtitle): a display-small title
|
||||
* search the row holds a search bar, full width to 312px and then half of what is left
|
||||
* search the row holds a search bar, full width to 312px and then half of what is left (N-09)
|
||||
*
|
||||
* The container is the surface, and surface-container once content scrolls under it. A medium or
|
||||
* large bar collapses into the small one without script moving anything: the bar is sticky at a
|
||||
@@ -17,13 +28,22 @@
|
||||
* has happened (resources/js/app-bar.js), so the small title can fade in and the colour change.
|
||||
*
|
||||
* Trailing actions given as a list collapse into an overflow menu below `medium` and come back
|
||||
* from it, by media query alone: both forms of every action are in the page, and each width hides
|
||||
* the one it does not use, so nothing flashes and no script counts.
|
||||
* from it, by media query alone (the site's "trailing actions collapse into an overflow menu at
|
||||
* smaller breakpoints" and "become visible again at larger sizes", read together with "up to two
|
||||
* icon buttons" and, for a wider window, "up to four trailing icons"): both forms of every action
|
||||
* are in the page, and each width hides the one it does not use, so nothing flashes and no script
|
||||
* counts.
|
||||
*/
|
||||
|
||||
@layer components {
|
||||
[data-app-bar] {
|
||||
--app-bar-row: 4rem;
|
||||
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
|
||||
|
||||
@import './button.css';
|
||||
@import './menu.css';
|
||||
@import './menu-item.css';
|
||||
|
||||
@layer material.components {
|
||||
[data-md-app-bar] {
|
||||
--app-bar-row: 64px;
|
||||
--app-bar-height: var(--app-bar-row);
|
||||
|
||||
z-index: 20;
|
||||
@@ -32,40 +52,42 @@
|
||||
padding-top: var(--material-safe-top, env(safe-area-inset-top));
|
||||
background-color: var(--md-sys-color-surface);
|
||||
color: var(--md-sys-color-on-surface);
|
||||
transition: background-color var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-effects-default);
|
||||
transition-property: background-color;
|
||||
transition-duration: var(--md-sys-motion-effects-default-duration);
|
||||
transition-timing-function: var(--md-sys-motion-effects-default);
|
||||
}
|
||||
|
||||
[data-app-bar][data-variant="medium"] {
|
||||
--app-bar-height: 7rem;
|
||||
[data-md-app-bar][data-md-variant='medium'] {
|
||||
--app-bar-height: 112px;
|
||||
}
|
||||
|
||||
[data-app-bar][data-variant="medium"][data-subtitled] {
|
||||
--app-bar-height: 8.5rem;
|
||||
[data-md-app-bar][data-md-variant='medium'][data-md-subtitled] {
|
||||
--app-bar-height: 136px;
|
||||
}
|
||||
|
||||
[data-app-bar][data-variant="large"] {
|
||||
--app-bar-height: 7.5rem;
|
||||
[data-md-app-bar][data-md-variant='large'] {
|
||||
--app-bar-height: 120px;
|
||||
}
|
||||
|
||||
[data-app-bar][data-variant="large"][data-subtitled] {
|
||||
--app-bar-height: 9.5rem;
|
||||
[data-md-app-bar][data-md-variant='large'][data-md-subtitled] {
|
||||
--app-bar-height: 152px;
|
||||
}
|
||||
|
||||
[data-app-bar][data-sticky] {
|
||||
[data-md-app-bar][data-md-sticky] {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
/* `--app-bar-measured` is the bar's real height (a title can wrap), set by app-bar.js. */
|
||||
[data-app-bar][data-sticky]:is([data-variant="medium"], [data-variant="large"]) {
|
||||
[data-md-app-bar][data-md-sticky]:is([data-md-variant='medium'], [data-md-variant='large']) {
|
||||
top: calc(var(--app-bar-row) - var(--app-bar-measured, var(--app-bar-height)));
|
||||
}
|
||||
|
||||
[data-app-bar][data-scrolled] {
|
||||
[data-md-app-bar][data-md-scrolled] {
|
||||
background-color: var(--md-sys-color-surface-container);
|
||||
}
|
||||
|
||||
[data-app-bar-row] {
|
||||
[data-md-app-bar-row] {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
@@ -73,63 +95,62 @@
|
||||
align-items: center;
|
||||
gap: 0;
|
||||
min-height: var(--app-bar-row);
|
||||
padding-inline: 0.25rem;
|
||||
padding-inline: var(--md-sys-measurement-space50);
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
[data-app-bar-leading],
|
||||
[data-app-bar-trailing] {
|
||||
[data-md-app-bar-leading],
|
||||
[data-md-app-bar-trailing] {
|
||||
display: flex;
|
||||
flex: none;
|
||||
align-items: center;
|
||||
color: var(--md-sys-color-on-surface-variant);
|
||||
}
|
||||
|
||||
[data-app-bar-leading] {
|
||||
[data-md-app-bar-leading] {
|
||||
color: var(--md-sys-color-on-surface);
|
||||
}
|
||||
|
||||
[data-app-bar-trailing] {
|
||||
[data-md-app-bar-trailing] {
|
||||
margin-inline-start: auto;
|
||||
}
|
||||
|
||||
/* `actions` as a list: every action is both an icon button and a menu item, and the width of
|
||||
the window says which one is drawn — up to two trailing icon buttons below `medium` and four
|
||||
from it, an overflow button counted among them
|
||||
(docs/reference/m3/components-navigation-selection-inputs.md § Top app bar → Behaviour and
|
||||
guidelines). The wrappers stay out of the row's layout until a width hides them. */
|
||||
[data-app-bar-action],
|
||||
[data-app-bar-overflow] {
|
||||
from it, an overflow button counted among them. The wrappers stay out of the row's layout
|
||||
until a width hides them. */
|
||||
[data-md-app-bar-action],
|
||||
[data-md-app-bar-overflow] {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
@media (width < 37.5rem) {
|
||||
[data-app-bar-action][data-overflows-compact],
|
||||
[data-app-bar-overflow="medium"] {
|
||||
@media (width < 600px) {
|
||||
[data-md-app-bar-action][data-md-overflows-compact],
|
||||
[data-md-app-bar-overflow='medium'] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 37.5rem) {
|
||||
[data-app-bar-overflow="compact"] {
|
||||
@media (width >= 600px) {
|
||||
[data-md-app-bar-overflow='compact'] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
[data-app-bar-headline] {
|
||||
[data-md-app-bar-headline] {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
flex: 1 1 0%;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding-inline: 0.75rem;
|
||||
padding-inline: 12px;
|
||||
}
|
||||
|
||||
[data-app-bar-row]:has([data-app-bar-leading]) [data-app-bar-headline] {
|
||||
padding-inline-start: 0.25rem;
|
||||
[data-md-app-bar-row]:has([data-md-app-bar-leading]) [data-md-app-bar-headline] {
|
||||
padding-inline-start: var(--md-sys-measurement-space50);
|
||||
}
|
||||
|
||||
[data-app-bar-title] {
|
||||
[data-md-app-bar-title] {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
@@ -137,7 +158,7 @@
|
||||
letter-spacing: var(--md-sys-typescale-title-lg-tracking);
|
||||
}
|
||||
|
||||
[data-app-bar-subtitle] {
|
||||
[data-md-app-bar-subtitle] {
|
||||
overflow: hidden;
|
||||
color: var(--md-sys-color-on-surface-variant);
|
||||
text-overflow: ellipsis;
|
||||
@@ -148,91 +169,92 @@
|
||||
|
||||
/* Centred: a three-column row — leading, headline, trailing — so the headline is centred in the
|
||||
window and shrinks against whatever is actually beside it. M3 allows two trailing icon
|
||||
buttons, which a fixed inset for one would have let a long title ellipsise underneath. */
|
||||
[data-app-bar][data-variant="center"] [data-app-bar-row] {
|
||||
buttons, which a fixed inset for one would have let a long title ellipsise underneath (N-11). */
|
||||
[data-md-app-bar][data-md-variant='center'] [data-md-app-bar-row] {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
}
|
||||
|
||||
[data-app-bar][data-variant="center"] [data-app-bar-leading] {
|
||||
[data-md-app-bar][data-md-variant='center'] [data-md-app-bar-leading] {
|
||||
grid-column: 1;
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
[data-app-bar][data-variant="center"] [data-app-bar-headline] {
|
||||
[data-md-app-bar][data-md-variant='center'] [data-md-app-bar-headline] {
|
||||
grid-column: 2;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
justify-self: center;
|
||||
padding-inline: 0.75rem;
|
||||
padding-inline: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
[data-app-bar][data-variant="center"] [data-app-bar-trailing] {
|
||||
[data-md-app-bar][data-md-variant='center'] [data-md-app-bar-trailing] {
|
||||
grid-column: 3;
|
||||
justify-self: end;
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
|
||||
/* The search bar fills the space between the leading and trailing elements until it is 312dp
|
||||
wide, and then grows into only half of what is left
|
||||
(docs/reference/m3/components-navigation-selection-inputs.md § Top app bar). The percentage
|
||||
is of the row rather than of that space, which CSS cannot name without measuring it; below
|
||||
312px the cap never binds, so a phone still gets the whole row. */
|
||||
[data-app-bar-search] {
|
||||
wide, and then grows into only half of what is left (N-09). The percentage is of the row
|
||||
rather than of that space, which CSS cannot name without measuring it; below 312px the cap
|
||||
never binds, so a phone still gets the whole row. */
|
||||
[data-md-app-bar-search] {
|
||||
min-width: 0;
|
||||
max-width: calc(19.5rem + (100% - 19.5rem) / 2);
|
||||
max-width: calc(312px + (100% - 312px) / 2);
|
||||
flex: 1 1 0%;
|
||||
margin-inline: auto;
|
||||
padding-inline: 0.25rem;
|
||||
padding-inline: var(--md-sys-measurement-space50);
|
||||
}
|
||||
|
||||
/* Medium and large: the row's title is the collapsed one, shown once the big one has gone. */
|
||||
[data-app-bar]:is([data-variant="medium"], [data-variant="large"]) [data-app-bar-row] [data-app-bar-headline] {
|
||||
[data-md-app-bar]:is([data-md-variant='medium'], [data-md-variant='large']) [data-md-app-bar-row] [data-md-app-bar-headline] {
|
||||
opacity: 0;
|
||||
transition: opacity var(--md-sys-motion-effects-fast-duration) var(--md-sys-motion-effects-fast);
|
||||
transition-property: opacity;
|
||||
transition-duration: var(--md-sys-motion-effects-fast-duration);
|
||||
transition-timing-function: var(--md-sys-motion-effects-fast);
|
||||
}
|
||||
|
||||
[data-app-bar][data-collapsed] [data-app-bar-row] [data-app-bar-headline] {
|
||||
[data-md-app-bar][data-md-collapsed] [data-md-app-bar-row] [data-md-app-bar-headline] {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Heights from the tokens: the title (and subtitle) lines and the space under them fill what the
|
||||
row leaves — 36 + 12px medium, 36 + 20 + 16px with a subtitle; 44 + 12px large, 44 + 24 + 20px. */
|
||||
[data-app-bar-expanded] {
|
||||
[data-md-app-bar-expanded] {
|
||||
display: flex;
|
||||
min-height: calc(var(--app-bar-height) - var(--app-bar-row));
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
padding-inline: 1rem;
|
||||
padding-bottom: 0.75rem;
|
||||
padding-inline: var(--md-sys-measurement-space200);
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
[data-app-bar][data-subtitled] [data-app-bar-expanded] {
|
||||
padding-bottom: 1rem;
|
||||
[data-md-app-bar][data-md-subtitled] [data-md-app-bar-expanded] {
|
||||
padding-bottom: var(--md-sys-measurement-space200);
|
||||
}
|
||||
|
||||
[data-app-bar][data-variant="large"][data-subtitled] [data-app-bar-expanded] {
|
||||
padding-bottom: 1.25rem;
|
||||
[data-md-app-bar][data-md-variant='large'][data-md-subtitled] [data-md-app-bar-expanded] {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
[data-app-bar-expanded] [data-app-bar-title] {
|
||||
[data-md-app-bar-expanded] [data-md-app-bar-title] {
|
||||
white-space: normal;
|
||||
font: var(--md-sys-typescale-headline-md);
|
||||
letter-spacing: var(--md-sys-typescale-headline-md-tracking);
|
||||
}
|
||||
|
||||
[data-app-bar-expanded] [data-app-bar-subtitle] {
|
||||
[data-md-app-bar-expanded] [data-md-app-bar-subtitle] {
|
||||
font: var(--md-sys-typescale-label-lg);
|
||||
letter-spacing: var(--md-sys-typescale-label-lg-tracking);
|
||||
}
|
||||
|
||||
[data-app-bar][data-variant="large"] [data-app-bar-expanded] [data-app-bar-title] {
|
||||
[data-md-app-bar][data-md-variant='large'] [data-md-app-bar-expanded] [data-md-app-bar-title] {
|
||||
font: var(--md-sys-typescale-display-sm);
|
||||
letter-spacing: var(--md-sys-typescale-display-sm-tracking);
|
||||
}
|
||||
|
||||
[data-app-bar][data-variant="large"] [data-app-bar-expanded] [data-app-bar-subtitle] {
|
||||
[data-md-app-bar][data-md-variant='large'] [data-md-app-bar-expanded] [data-md-app-bar-subtitle] {
|
||||
font: var(--md-sys-typescale-title-md);
|
||||
letter-spacing: var(--md-sys-typescale-title-md-tracking);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,5 @@
|
||||
|
||||
/* Navigation — leaving in step 36 */
|
||||
@import './components/tabs.css';
|
||||
@import './components/app-bar.css';
|
||||
@import './components/navigation.css';
|
||||
@import './components/toolbar.css';
|
||||
|
||||
@@ -16,20 +16,29 @@
|
||||
trailing icons" (said of the search app bar, the only count it gives for a wider window), and
|
||||
lets actions at the trailing edge "collapse into an overflow menu at smaller breakpoints" and
|
||||
"become visible again at larger sizes" (docs/reference/m3/components-navigation-selection-inputs.md
|
||||
§ Top app bar → Behaviour and guidelines; app-bars/guidelines § Trailing icon buttons, § Large
|
||||
screens, § Resizing). So below `medium` (600px) the bar shows at most two icon buttons and from
|
||||
there at most four, the overflow button — `more_vert`, "More options" — counted among them:
|
||||
with more actions than that, the first one (or three) stay and the rest go into its menu. Each
|
||||
width has a menu of its own holding only what overflows there, so the arrow keys never land on
|
||||
a hidden row, and it is all CSS (resources/css/components/app-bar.css): nothing moves after the
|
||||
page has drawn. Only the list overflows; markup in the slot is drawn as written. A slot and a
|
||||
list are alternatives — a slot of the same name replaces the attribute.
|
||||
§ Top App Bar → Behaviour and guidelines). So below `medium` (600px) the bar shows at most two
|
||||
icon buttons and from there at most four, the overflow button — `more_vert`, "More options" —
|
||||
counted among them: with more actions than that, the first one (or three) stay and the rest go
|
||||
into its menu. Each width has a menu of its own holding only what overflows there, so the
|
||||
arrow keys never land on a hidden row, and it is all CSS (resources/css/components/app-bar.css):
|
||||
nothing moves after the page has drawn. Only the list overflows; markup in the slot is drawn
|
||||
as written. A slot and a list are alternatives — a slot of the same name replaces the
|
||||
attribute.
|
||||
|
||||
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). --}}
|
||||
sticking (`overflow-x: clip` is fine).
|
||||
|
||||
The root renders `data-md-app-bar` with `data-md-variant`, `data-md-sticky`,
|
||||
`data-md-subtitled`, and `data-md-scrolled`/`data-md-collapsed` once the page has scrolled
|
||||
under it; its row is `data-md-app-bar-row` holding `data-md-app-bar-leading`,
|
||||
`data-md-app-bar-headline` (`data-md-app-bar-title`, `data-md-app-bar-subtitle`),
|
||||
`data-md-app-bar-search` and `data-md-app-bar-trailing` (`data-md-app-bar-action`,
|
||||
`data-md-app-bar-overflow`); a flexible bar's big title is `data-md-app-bar-expanded`. Drawn
|
||||
by resources/css/components/app-bar.css, which imports button.css, menu.css and menu-item.css
|
||||
for what the view renders. --}}
|
||||
|
||||
@props([
|
||||
'title' => null,
|
||||
@@ -71,30 +80,30 @@
|
||||
|
||||
<header
|
||||
x-data="materialAppBar"
|
||||
x-bind:data-scrolled="scrolled ? '' : null"
|
||||
x-bind:data-collapsed="collapsed ? '' : null"
|
||||
x-bind:data-md-scrolled="scrolled ? '' : null"
|
||||
x-bind:data-md-collapsed="collapsed ? '' : null"
|
||||
x-bind:style="measured"
|
||||
data-app-bar
|
||||
data-variant="{{ $variant }}"
|
||||
@if ($sticky) data-sticky @endif
|
||||
@if (filled($subtitle)) data-subtitled @endif
|
||||
data-md-app-bar
|
||||
data-md-variant="{{ $variant }}"
|
||||
@if ($sticky) data-md-sticky @endif
|
||||
@if (filled($subtitle)) data-md-subtitled @endif
|
||||
{{ $attributes }}
|
||||
>
|
||||
<div data-app-bar-row>
|
||||
<div data-md-app-bar-row>
|
||||
@isset($navigation)
|
||||
<div data-app-bar-leading>{{ $navigation }}</div>
|
||||
<div data-md-app-bar-leading>{{ $navigation }}</div>
|
||||
@endisset
|
||||
|
||||
@if ($variant === 'search')
|
||||
<div data-app-bar-search>{{ $slot }}</div>
|
||||
<div data-md-app-bar-search>{{ $slot }}</div>
|
||||
@elseif (filled($title))
|
||||
<div data-app-bar-headline @if ($flexible) aria-hidden="true" @endif>
|
||||
<div data-md-app-bar-headline @if ($flexible) aria-hidden="true" @endif>
|
||||
@if ($flexible)
|
||||
<span data-app-bar-title>{{ $title }}</span>
|
||||
<span data-md-app-bar-title>{{ $title }}</span>
|
||||
@else
|
||||
<{{ $heading }} data-app-bar-title>{{ $title }}</{{ $heading }}>
|
||||
<{{ $heading }} data-md-app-bar-title>{{ $title }}</{{ $heading }}>
|
||||
@if (filled($subtitle))
|
||||
<p data-app-bar-subtitle>{{ $subtitle }}</p>
|
||||
<p data-md-app-bar-subtitle>{{ $subtitle }}</p>
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
@@ -102,10 +111,10 @@
|
||||
|
||||
@if ($list !== null)
|
||||
@if ($count > 0)
|
||||
<div data-app-bar-trailing>
|
||||
<div data-md-app-bar-trailing>
|
||||
@foreach ($list as $index => $action)
|
||||
@if ($index < $shown['medium'])
|
||||
<span data-app-bar-action @if ($index >= $shown['compact']) data-overflows-compact @endif>
|
||||
<span data-md-app-bar-action @if ($index >= $shown['compact']) data-md-overflows-compact @endif>
|
||||
<x-livewire-material::button
|
||||
:icon="$action['icon']"
|
||||
:tooltip-bottom="$action['label']"
|
||||
@@ -122,7 +131,7 @@
|
||||
|
||||
@foreach ($shown as $width => $kept)
|
||||
@if ($count > $kept)
|
||||
<span data-app-bar-overflow="{{ $width }}">
|
||||
<span data-md-app-bar-overflow="{{ $width }}">
|
||||
<x-livewire-material::menu :label="__('More options')" position="bottom-end">
|
||||
<x-slot:trigger>
|
||||
<x-livewire-material::button icon="more_vert" :tooltip-bottom="__('More options')" />
|
||||
@@ -147,15 +156,15 @@
|
||||
</div>
|
||||
@endif
|
||||
@elseif (isset($actions))
|
||||
<div data-app-bar-trailing>{{ $actions }}</div>
|
||||
<div data-md-app-bar-trailing>{{ $actions }}</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@if ($flexible && filled($title))
|
||||
<div data-app-bar-expanded>
|
||||
<{{ $heading }} data-app-bar-title>{{ $title }}</{{ $heading }}>
|
||||
<div data-md-app-bar-expanded>
|
||||
<{{ $heading }} data-md-app-bar-title>{{ $title }}</{{ $heading }}>
|
||||
@if (filled($subtitle))
|
||||
<p data-app-bar-subtitle>{{ $subtitle }}</p>
|
||||
<p data-md-app-bar-subtitle>{{ $subtitle }}</p>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
Reference in New Issue
Block a user