From 433ddb2baa7c37c0896ab0c64c06441663070811 Mon Sep 17 00:00:00 2001 From: Andreas Reinhold / reini Date: Sun, 13 Sep 2026 21:36:35 +0200 Subject: [PATCH] Keep aria-pressed off a selected link button ARIA defines aria-pressed for buttons, not links, so a selected keeps the selected look without announcing itself as a toggle; the caller marks the page with aria-current. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01RHoXZSHc8gGpZjFmA5fPc2 --- resources/views/components/button.blade.php | 8 +++++--- tests/Feature/Components/ButtonTest.php | 7 +++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/resources/views/components/button.blade.php b/resources/views/components/button.blade.php index e5e6463a..d8eb90b3 100644 --- a/resources/views/components/button.blade.php +++ b/resources/views/components/button.blade.php @@ -13,8 +13,8 @@ With an `icon` and no label it is an icon button: `width` is `narrow`, `default` or `wide`, `variant="text"` is M3's standard icon button, and the tooltip or label names it for screen - readers. `selected` makes it a toggle: `true` or `false` sets `aria-pressed` and M3's - selected colours, and a selected round button turns square (a selected square icon button + readers. `selected` makes it a toggle: `true` or `false` sets `aria-pressed` (not on a `link`, + which is no toggle — give it `aria-current` instead) and M3's selected colours, and a selected round button turns square (a selected square icon button turns round). Text buttons are not toggles in M3; a selected one takes the tonal container. Values from androidx Compose Material 3's tokens (Button*Tokens, *IconButtonTokens, @@ -191,7 +191,9 @@ 'type' => $isLink ? null : $type, 'disabled' => ! $isLink && $disabled ? true : null, 'aria-label' => $iconOnly && ! $attributes->has('aria-label') ? ($label ?? $tip) : null, - 'aria-pressed' => $selected === null ? null : ($selected ? 'true' : 'false'), + // A link is not a toggle: ARIA defines aria-pressed for buttons only. A selected link keeps + // the selected look; `aria-current` is the caller's to set (`:aria-current="'page'"`). + 'aria-pressed' => $selected === null || $isLink ? null : ($selected ? 'true' : 'false'), 'data-icon-button' => $iconOnly ? true : null, 'wire:loading.attr' => $spinnerTarget ? 'disabled' : null, 'wire:target' => $spinnerTarget, diff --git a/tests/Feature/Components/ButtonTest.php b/tests/Feature/Components/ButtonTest.php index d3c29c42..15b7c304 100644 --- a/tests/Feature/Components/ButtonTest.php +++ b/tests/Feature/Components/ButtonTest.php @@ -156,3 +156,10 @@ it('submits a form when asked', function () { $this->blade('') ->assertSee('type="submit"', false); }); + +it('keeps aria-pressed off a selected link, which is not a toggle', function () { + expect((string) $this->blade('')) + ->not->toContain('aria-pressed') + ->and((string) $this->blade('')) + ->toContain('aria-pressed="true"'); +});