Reach M3's 48px target from every 40px navigation control
The theme toggle and the account-menu avatar are drawn 40px and had no target extension; both now carry `touch-target`, and the avatar's clipping moves from the button (which would have cut the pseudo-target off) to the <img>. The rail's hand-rolled `after:` target becomes the same utility. Plan: docs/plans/material-3-alignment.md, step 14 (navigation N-01). 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
0adfb6fff4
commit
4a4982b1ef
@@ -38,10 +38,10 @@
|
||||
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"
|
||||
class="touch-target focus-ring inline-flex size-10 shrink-0 cursor-pointer items-center justify-center rounded-corner-full bg-primary-container type-label-lg text-on-primary-container"
|
||||
>
|
||||
@if ($image)
|
||||
<img src="{{ $avatar }}" alt="" class="size-full object-cover" />
|
||||
<img src="{{ $avatar }}" alt="" class="size-full rounded-corner-full object-cover" />
|
||||
@elseif (filled($initials))
|
||||
{{ $initials }}
|
||||
@else
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
x-on:click="menu()"
|
||||
x-bind:aria-label="expanded ? @js(__('Collapse navigation')) : @js(__('Expand navigation'))"
|
||||
x-bind:aria-expanded="expanded.toString()"
|
||||
class="state-layer focus-ring inline-flex size-10 shrink-0 cursor-pointer items-center justify-center rounded-corner-full text-on-surface-variant after:absolute after:top-1/2 after:left-1/2 after:size-12 after:-translate-x-1/2 after:-translate-y-1/2"
|
||||
class="state-layer touch-target focus-ring inline-flex size-10 shrink-0 cursor-pointer items-center justify-center rounded-corner-full text-on-surface-variant"
|
||||
>
|
||||
<span class="contents rail-collapsed:hidden"><x-livewire-material::icon name="menu_open" class="size-6" /></span>
|
||||
<span class="hidden rail-collapsed:contents"><x-livewire-material::icon name="menu" class="size-6" /></span>
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
x-bind:aria-pressed="($store.theme.resolved === 'dark').toString()"
|
||||
x-on:click="$store.theme.toggle()"
|
||||
@endif
|
||||
{{ $attributes->class(['state-layer focus-ring inline-flex size-10 shrink-0 cursor-pointer items-center justify-center rounded-corner-full text-on-surface-variant transition-[border-radius] duration-(--md-sys-motion-spatial-fast-duration) ease-spatial-fast active:rounded-corner-sm']) }}
|
||||
{{ $attributes->class(['state-layer touch-target focus-ring inline-flex size-10 shrink-0 cursor-pointer items-center justify-center rounded-corner-full text-on-surface-variant transition-[border-radius] duration-(--md-sys-motion-spatial-fast-duration) ease-spatial-fast active:rounded-corner-sm']) }}
|
||||
>
|
||||
@if ($mode === 'cycle')
|
||||
<x-livewire-material::icon name="light_mode" x-cloak x-show="$store.theme.choice === 'light'" />
|
||||
|
||||
@@ -86,6 +86,8 @@ it('switches the theme through the store in three shapes', function () {
|
||||
expect((string) $this->blade('<x-theme-toggle />'))
|
||||
->toContain('data-theme-toggle="toggle"')
|
||||
->toContain('aria-label="Dark theme"')
|
||||
// 40px drawn, 48px reached: M3's minimum target (N-01).
|
||||
->toContain('touch-target')
|
||||
->toContain('$store.theme.toggle()')
|
||||
->and((string) $this->blade('<x-theme-toggle mode="cycle" />'))
|
||||
->toContain('data-theme-toggle="cycle"')
|
||||
@@ -107,12 +109,15 @@ it('opens an account menu from the initials of a name', function () {
|
||||
expect($html)
|
||||
->toContain('aria-label="Account"')
|
||||
->toContain('data-account-menu')
|
||||
// The 40px avatar reaches 48px, and nothing clips the pseudo-target (N-01).
|
||||
->toContain('touch-target')
|
||||
->not->toContain('overflow-hidden')
|
||||
->toMatch('/>\s*AM\s*<\/button>/')
|
||||
->toContain('anna@example.com')
|
||||
->toContain('Settings')
|
||||
->toContain('data-account-theme')
|
||||
->toContain('Sign out')
|
||||
->and((string) $this->blade('<x-account-menu avatar="/anna.jpg" :theme="false" />'))
|
||||
->toContain('<img src="/anna.jpg"')
|
||||
->toContain('<img src="/anna.jpg" alt="" class="size-full rounded-corner-full object-cover" />')
|
||||
->not->toContain('data-account-theme');
|
||||
});
|
||||
|
||||
@@ -22,6 +22,8 @@ it('gives the collapsible, modal and adaptive rails a menu button and the store'
|
||||
->toContain('data-navigation-rail-menu')
|
||||
->toContain('aria-label="Collapse navigation"')
|
||||
->toContain('aria-expanded="true"')
|
||||
// The 40px menu button reaches M3's 48px target through the shared utility (N-01).
|
||||
->toContain('touch-target')
|
||||
->not->toContain('data-navigation-rail-scrim')
|
||||
->not->toContain('x-trap')
|
||||
->and((string) $this->blade('<x-navigation-rail mode="modal" />'))
|
||||
|
||||
Reference in New Issue
Block a user