Hold the navigation bar item to its own label and state-layer tokens
NavigationBarTokens names one label font for both icon positions, label-medium; the horizontal layout had taken label-large from the rail's item, a different component with a token of its own. And the item's state layer washed in on-surface over a secondary-container pill, where the only state-layer tokens M3 states for a navigation item — the rail's, which the rail already follows — are on-secondary-container for all six states. Plan: docs/plans/material-3-alignment.md, step 21 (navigation N-08, N-19). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
co-authored by
Claude Opus 5
parent
59ca88a0cf
commit
c3bed743aa
@@ -160,14 +160,16 @@
|
|||||||
min-width: max-content;
|
min-width: max-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The label stays label-medium: NavigationBarTokens.LabelTextFont is the bar's only label
|
||||||
|
token, and Compose's ShortNavigationBarItem passes it for both icon positions. (The
|
||||||
|
*rail's* horizontal item is label-large — NavigationRailHorizontalItemTokens — which is
|
||||||
|
a different component.) */
|
||||||
[data-navigation-bar-item] [data-navigation-pill] {
|
[data-navigation-bar-item] [data-navigation-pill] {
|
||||||
position: relative;
|
position: relative;
|
||||||
isolation: isolate;
|
isolation: isolate;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
height: 2.5rem;
|
height: 2.5rem;
|
||||||
padding-inline: 1rem;
|
padding-inline: 1rem;
|
||||||
font: var(--md-sys-typescale-label-lg);
|
|
||||||
letter-spacing: var(--md-sys-typescale-label-lg-tracking);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-navigation-bar-item] [data-navigation-label] {
|
[data-navigation-bar-item] [data-navigation-label] {
|
||||||
@@ -538,6 +540,14 @@
|
|||||||
transition: opacity var(--md-sys-motion-effects-fast-duration) var(--md-sys-motion-effects-fast);
|
transition: opacity var(--md-sys-motion-effects-fast-duration) var(--md-sys-motion-effects-fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* A navigation item's state layer is on-secondary-container, active or not: the only
|
||||||
|
state-layer tokens M3 states for one are NavigationRailColorTokens', which give that colour
|
||||||
|
to all six. The rail follows them two blocks below; the bar follows them here, over its
|
||||||
|
secondary-container pill. */
|
||||||
|
[data-navigation-bar-item] :is([data-navigation-indicator], [data-navigation-pill])::before {
|
||||||
|
background-color: var(--md-sys-color-on-secondary-container);
|
||||||
|
}
|
||||||
|
|
||||||
@container (width < 37.5rem) {
|
@container (width < 37.5rem) {
|
||||||
[data-navigation-bar-item] [data-navigation-pill]::before {
|
[data-navigation-bar-item] [data-navigation-pill]::before {
|
||||||
display: none;
|
display: none;
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
it('draws a navigation landmark around its items', function () {
|
it('draws a navigation landmark around its items', function () {
|
||||||
expect((string) $this->blade('<x-navigation-bar><x-navigation-bar-item label="Inbox" icon="inbox" link="/inbox" /></x-navigation-bar>'))
|
expect((string) $this->blade('<x-navigation-bar><x-navigation-bar-item label="Inbox" icon="inbox" link="/inbox" /></x-navigation-bar>'))
|
||||||
->toContain('<nav aria-label="Main" data-navigation-bar')
|
->toContain('<nav aria-label="Main" data-navigation-bar')
|
||||||
@@ -46,3 +48,15 @@ it('badges the icon with a dot or a count that screen readers hear', function ()
|
|||||||
->and($dot)->toContain('size-1.5')->toContain('<span class="sr-only">, New mail</span>')
|
->and($dot)->toContain('size-1.5')->toContain('<span class="sr-only">, New mail</span>')
|
||||||
->and((string) $this->blade('<x-navigation-bar-item label="Inbox" icon="inbox" link="/inbox" />'))->not->toContain('sr-only');
|
->and((string) $this->blade('<x-navigation-bar-item label="Inbox" icon="inbox" link="/inbox" />'))->not->toContain('sr-only');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('keeps the bar item on the label and state-layer colours M3 tokens', function () {
|
||||||
|
$css = file_get_contents(__DIR__.'/../../../resources/css/components/navigation.css');
|
||||||
|
$horizontal = Str::of($css)->after('@container (width >= 37.5rem)')->before('/* ------')->toString();
|
||||||
|
|
||||||
|
expect($horizontal)
|
||||||
|
// NavigationBarTokens names one label font for both icon positions: label-medium (N-08).
|
||||||
|
->not->toContain('--md-sys-typescale-label-lg')
|
||||||
|
->and($css)
|
||||||
|
// The indicator and the pill wash in on-secondary-container, as the rail's do (N-19).
|
||||||
|
->toContain('[data-navigation-bar-item] :is([data-navigation-indicator], [data-navigation-pill])::before {');
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user