Hide field, search and chip text with md-visually-hidden again

Plan step 36 review. 52fd65a3 replaced the md-visually-hidden class on
field's spoken counter, search's result count and a bound filter chip's
native checkbox with hooks carrying copies of its clip, on the reading
that a package view writes no class but the interaction classes. The
brief and step 34 let a view write the text classes too, and one shared
source beats three copies: the class is back, the copies and the
data-md-field-live and data-md-chip-native hooks are gone
(data-md-search-status predates them and stays). chip.css keeps its
tooltip.css import.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
Andreas Reinhold / reini
2026-09-14 19:31:39 +02:00
co-authored by Claude Opus 5
parent a3eef657cc
commit e3fcbf39ed
9 changed files with 6 additions and 52 deletions
-16
View File
@@ -195,22 +195,6 @@
pointer-events: none; pointer-events: none;
} }
/* A filter chip bound with `x-model` keeps a real, focusable `<input type="checkbox">` under the
label for its native semantics and `:has(:checked)`, visually hidden the way `md-visually-hidden`
hides text — a hook, not a class, because a package view writes no class but the interaction
classes (plan step 36). */
[data-md-chip-native] {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
border-width: 0;
}
/* ---- Contents ------------------------------------------------------------------------------ */ /* ---- Contents ------------------------------------------------------------------------------ */
[data-md-chip-label] { [data-md-chip-label] {
-15
View File
@@ -408,21 +408,6 @@
color: var(--md-sys-color-error); color: var(--md-sys-color-error);
} }
/* The counter's spoken form: the same visually-hidden clip the text classes give
`md-visually-hidden`, kept as a hook because a package view writes no class but the
interaction classes (plan step 36). */
[data-md-field-live] {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
border-width: 0;
}
/* ---- The filled text field ---------------------------------------------------------------- */ /* ---- The filled text field ---------------------------------------------------------------- */
[data-md-field][data-md-variant='filled'] [data-md-field-box] { [data-md-field][data-md-variant='filled'] [data-md-field-box] {
-15
View File
@@ -304,19 +304,4 @@
letter-spacing: var(--md-sys-typescale-body-md-tracking); letter-spacing: var(--md-sys-typescale-body-md-tracking);
font-variation-settings: normal; font-variation-settings: normal;
} }
/* The result count's spoken form: the same visually-hidden clip the text classes give
`md-visually-hidden`, kept as a hook because a package view writes no class but the
interaction classes (plan step 36). */
[data-md-search-status] {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
border-width: 0;
}
} }
+1 -1
View File
@@ -152,7 +152,7 @@
'value' => $value, 'value' => $value,
'checked' => $checked ? true : null, 'checked' => $checked ? true : null,
'disabled' => $disabled ? true : null, 'disabled' => $disabled ? true : null,
'data-md-chip-native' => true, 'class' => 'md-visually-hidden',
], fn ($attribute): bool => $attribute !== null)) ], fn ($attribute): bool => $attribute !== null))
: null; : null;
+1 -1
View File
@@ -137,7 +137,7 @@
x-bind:data-md-over="used > max" x-bind:data-md-over="used > max"
> >
<span aria-hidden="true" x-text="`${used}/${max}`">0/{{ $counter }}</span> <span aria-hidden="true" x-text="`${used}/${max}`">0/{{ $counter }}</span>
<span data-md-field-live aria-live="polite" aria-atomic="true" x-text="spoken"></span> <span class="md-visually-hidden" aria-live="polite" aria-atomic="true" x-text="spoken"></span>
</span> </span>
@endif @endif
</div> </div>
+1 -1
View File
@@ -149,5 +149,5 @@
@endif @endif
</div> </div>
<span data-md-search-status aria-live="polite" aria-atomic="true" x-text="announcement"></span> <span data-md-search-status class="md-visually-hidden" aria-live="polite" aria-atomic="true" x-text="announcement"></span>
</div> </div>
+1 -1
View File
@@ -123,7 +123,7 @@ it('makes a bound filter chip a native checkbox under the chip', function () {
->toContain('type="checkbox"') ->toContain('type="checkbox"')
->toContain('value="photos"') ->toContain('value="photos"')
->toContain('x-model="kinds"') ->toContain('x-model="kinds"')
->toContain('data-md-chip-native') ->toContain('class="md-visually-hidden"')
->not->toContain('me-4') ->not->toContain('me-4')
->not->toContain('checked') ->not->toContain('checked')
->and($html) ->and($html)
+1 -1
View File
@@ -173,7 +173,7 @@ it('counts the characters of a field that has a maximum', function () {
->toContain('data-md-field-support-row') ->toContain('data-md-field-support-row')
->toContain('data-md-field-counter') ->toContain('data-md-field-counter')
->toContain('x-bind:data-md-over="used > max"') ->toContain('x-bind:data-md-over="used > max"')
->toContain('data-md-field-live') ->toContain('<span class="md-visually-hidden" aria-live="polite" aria-atomic="true" x-text="spoken"></span>')
->toContain('maxlength="60"') ->toContain('maxlength="60"')
->toContain('max: 60,') ->toContain('max: 60,')
->toContain('>0/60</span>') ->toContain('>0/60</span>')
+1 -1
View File
@@ -34,7 +34,7 @@ it('announces how many results there are, politely', function () {
$html = (string) $this->blade('<x-search />'); $html = (string) $this->blade('<x-search />');
expect($html) expect($html)
->toContain('data-md-search-status') ->toContain('data-md-search-status class="md-visually-hidden"')
->toContain('aria-live="polite"') ->toContain('aria-live="polite"')
->toContain('aria-atomic="true"') ->toContain('aria-atomic="true"')
->toContain('No results') ->toContain('No results')