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) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
co-authored by
Claude Opus 5
parent
480387a64e
commit
7ff6928d4a
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 @@
|
||||
</div>
|
||||
|
||||
@if ($dismissible)
|
||||
<button type="button" data-md-alert-dismiss aria-label="{{ __('Dismiss') }}" x-on:click="shown = false">
|
||||
<button type="button" class="md-state-layer md-focus-ring md-touch-target" data-md-alert-dismiss aria-label="{{ __('Dismiss') }}" x-on:click="shown = false">
|
||||
<x-livewire-material::icon name="close" size="20" />
|
||||
</button>
|
||||
@endif
|
||||
|
||||
@@ -47,17 +47,17 @@ it('takes actions, drops its icon on request, and can be dismissed', function ()
|
||||
->and(substr_count($html, '<svg'))->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('<x-alert description="Draft." dismissible />'))
|
||||
->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 () {
|
||||
|
||||
Reference in New Issue
Block a user