From 480387a64ef6f3f75de8fb27c37f824d7f8f654d Mon Sep 17 00:00:00 2001 From: Andreas Reinhold / reini Date: Mon, 14 Sep 2026 18:10:16 +0200 Subject: [PATCH] Draw the snackbar's action and close buttons from the classes Plan step 36 ("Interaction is the shared classes", the user, 2026-09-14). The action and the close button hand-rolled md-state-layer, md-focus-ring and md-touch-target, and toast.css's own header said so; both now render the classes and keep only their own size and colour. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9 --- resources/css/components/toast.css | 54 ++-------------------- resources/views/components/toast.blade.php | 4 +- tests/Feature/Components/ToastTest.php | 8 ++-- 3 files changed, 9 insertions(+), 57 deletions(-) diff --git a/resources/css/components/toast.css b/resources/css/components/toast.css index 02ba794c..8239511e 100644 --- a/resources/css/components/toast.css +++ b/resources/css/components/toast.css @@ -17,11 +17,9 @@ * Below `medium` it is full width; from there it hugs its line length, which an application's own * class can still bound. * - * The action and the close button are both drawn at 40px and reach M3's 48px target (ACT-18) - * through an `::after`. Their 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 buttons themselves as button.css does, because the - * view writes no class list. + * The action and the close button are both drawn at 40px and render 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. * * It enters on a translate and a fade on the fast spatial spring, `@starting-style` giving both a * start. No state icon: M3 says to avoid one in a snackbar (ACT-20). The live region is the host @@ -113,55 +111,9 @@ } :is([data-md-toast-action], [data-md-toast-dismiss]) { - position: relative; - isolation: isolate; flex-shrink: 0; 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); - } } [data-md-toast-action] { diff --git a/resources/views/components/toast.blade.php b/resources/views/components/toast.blade.php index e1ea0dff..9bbf8428 100644 --- a/resources/views/components/toast.blade.php +++ b/resources/views/components/toast.blade.php @@ -86,11 +86,11 @@ diff --git a/tests/Feature/Components/ToastTest.php b/tests/Feature/Components/ToastTest.php index cdbf2316..24651549 100644 --- a/tests/Feature/Components/ToastTest.php +++ b/tests/Feature/Components/ToastTest.php @@ -25,12 +25,12 @@ it('draws no state icon, and reaches 48px from its 40px controls', function () { ->and($html)->not->toContain('text-inverse-success') ->toContain('data-md-toast-action') ->toContain('data-md-toast-dismiss') + // 48px, from the foundation's md-touch-target class, not a copy of its own. + ->toMatch('/class="md-state-layer md-focus-ring md-touch-target" data-md-toast-action/') + ->toMatch('/class="md-state-layer md-focus-ring md-touch-target" data-md-toast-dismiss/') ->and($css->declarations(':is([data-md-toast-action], [data-md-toast-dismiss])')) ->toHaveKey('border-radius', 'var(--md-sys-shape-corner-full)') - ->and($css->declarations(':is([data-md-toast-action], [data-md-toast-dismiss])::after'))->toMatchArray([ - 'min-width' => 'var(--md-sys-measurement-space600)', - 'min-height' => 'var(--md-sys-measurement-space600)', - ]) + ->and($css->has(':is([data-md-toast-action], [data-md-toast-dismiss])::after'))->toBeFalse() ->and($css->declarations('[data-md-toast-dismiss]'))->toMatchArray([ 'width' => 'var(--md-sys-measurement-space500)', 'height' => 'var(--md-sys-measurement-space500)',