From 7ff6928d4af3c6df4e92a5546a962e833e75038d Mon Sep 17 00:00:00 2001 From: Andreas Reinhold / reini Date: Mon, 14 Sep 2026 18:10:26 +0200 Subject: [PATCH] Draw the alert's dismiss button from the interaction classes Plan step 36 ("Interaction is the shared classes", the user, 2026-09-14). The dismiss button hand-rolled md-state-layer, md-focus-ring and md-touch-target, and alert.css's own header said so; it now renders the classes and keeps only its own size, offset and colour. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9 --- resources/css/components/alert.css | 54 ++-------------------- resources/views/components/alert.blade.php | 6 +-- tests/Feature/Components/AlertTest.php | 10 ++-- 3 files changed, 11 insertions(+), 59 deletions(-) diff --git a/resources/css/components/alert.css b/resources/css/components/alert.css index ab07337d..a37bd12e 100644 --- a/resources/css/components/alert.css +++ b/resources/css/components/alert.css @@ -7,11 +7,9 @@ * * `data-md-color`: info (the default), success, warning, error, primary, secondary, tertiary or * neutral (surface-container-high, on-surface — it has no state colour of its own). The dismiss - * button is drawn at 40px, pulled 8px out into the alert's padding, and reaches M3's 48px target - * (ACT-18) through an `::after`. Its state layer, focus ring and target are the declarations of - * the foundation's `md-state-layer`, `md-focus-ring` and `md-touch-target` - * (foundation/interaction.css), keyed on the button itself as button.css does, because the view - * writes no class list. + * button is drawn at 40px, pulled 8px out into the alert's padding, and renders the foundation's + * `md-state-layer`, `md-focus-ring` and `md-touch-target` (foundation/interaction.css) to reach + * M3's 48px target (ACT-18); nothing here copies their rules. */ @layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility; @@ -95,8 +93,6 @@ } [data-md-alert-dismiss] { - position: relative; - isolation: isolate; display: inline-flex; flex-shrink: 0; align-items: center; @@ -106,49 +102,5 @@ margin: -8px; border-radius: var(--md-sys-shape-corner-full); cursor: pointer; - outline: none; - - &::before { - content: ''; - position: absolute; - inset: 0; - z-index: -1; - border-radius: inherit; - background-color: currentColor; - opacity: 0; - pointer-events: none; - transition: opacity var(--md-sys-motion-effects-fast-duration) var(--md-sys-motion-effects-fast); - } - - &::after { - content: ''; - position: absolute; - top: 50%; - left: 50%; - width: 100%; - height: 100%; - min-width: var(--md-sys-measurement-space600); - min-height: var(--md-sys-measurement-space600); - translate: -50% -50%; - } - - @media (hover: hover) { - &:hover::before { - opacity: var(--md-sys-state-hover-state-layer-opacity); - } - } - - &:focus-visible { - outline: 3px solid var(--md-sys-color-secondary); - outline-offset: 2px; - } - - &:focus-visible::before { - opacity: var(--md-sys-state-focus-state-layer-opacity); - } - - &:active::before { - opacity: var(--md-sys-state-pressed-state-layer-opacity); - } } } diff --git a/resources/views/components/alert.blade.php b/resources/views/components/alert.blade.php index 595dddf1..ca6f80a4 100644 --- a/resources/views/components/alert.blade.php +++ b/resources/views/components/alert.blade.php @@ -15,8 +15,8 @@ something the person just did (ACT-36). M3 publishes no banner; the nearest thing it does publish, the snackbar, says polite and never assertive. - Drawn by resources/css/components/alert.css from `data-md-alert` and `data-md-color`; no - class list. --}} + Drawn by resources/css/components/alert.css from `data-md-alert` and `data-md-color`; the + dismiss button carries only the foundation's interaction classes. --}} @props([ 'title' => null, @@ -63,7 +63,7 @@ @if ($dismissible) - @endif diff --git a/tests/Feature/Components/AlertTest.php b/tests/Feature/Components/AlertTest.php index d592b7a3..569ea6e6 100644 --- a/tests/Feature/Components/AlertTest.php +++ b/tests/Feature/Components/AlertTest.php @@ -47,17 +47,17 @@ it('takes actions, drops its icon on request, and can be dismissed', function () ->and(substr_count($html, 'toBe(1); }); -it('reaches 48px from its 40px dismiss button', function () { +it('reaches 48px from its 40px dismiss button, from the foundation\'s class, not a copy', function () { $css = ComponentStylesheet::read('alert'); expect($css->declarations('[data-md-alert-dismiss]'))->toMatchArray([ 'width' => 'var(--md-sys-measurement-space500)', 'height' => 'var(--md-sys-measurement-space500)', ]) - ->and($css->declarations('[data-md-alert-dismiss]::after'))->toMatchArray([ - 'min-width' => 'var(--md-sys-measurement-space600)', - 'min-height' => 'var(--md-sys-measurement-space600)', - ]); + ->and($css->has('[data-md-alert-dismiss]::after'))->toBeFalse() + ->and($css->has('[data-md-alert-dismiss]::before'))->toBeFalse() + ->and((string) $this->blade('')) + ->toMatch('/class="md-state-layer md-focus-ring md-touch-target" data-md-alert-dismiss/'); }); it('draws neutral in surface-container-high, on-surface', function () {