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) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
co-authored by
Claude Opus 5
parent
5a9211acd4
commit
480387a64e
@@ -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] {
|
||||
|
||||
@@ -86,11 +86,11 @@
|
||||
</div>
|
||||
|
||||
<template x-if="current.action">
|
||||
<button type="button" data-md-toast-action x-text="current.action.label" x-on:click="act()"></button>
|
||||
<button type="button" class="md-state-layer md-focus-ring md-touch-target" data-md-toast-action x-text="current.action.label" x-on:click="act()"></button>
|
||||
</template>
|
||||
|
||||
<template x-if="current.action || ! current.timeout">
|
||||
<button type="button" data-md-toast-dismiss aria-label="{{ __('Dismiss') }}" x-on:click="dismiss()">
|
||||
<button type="button" class="md-state-layer md-focus-ring md-touch-target" data-md-toast-dismiss aria-label="{{ __('Dismiss') }}" x-on:click="dismiss()">
|
||||
<x-livewire-material::icon name="close" size="20" />
|
||||
</button>
|
||||
</template>
|
||||
|
||||
@@ -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)',
|
||||
|
||||
Reference in New Issue
Block a user