Skip to content

Commit 4880a5e

Browse files
committed
fix(material-experimental/mdc-list): make internal input non-interactive
Due to how MDC's checkbox styles are set up, we always have to keep an `input` inside the `mat-list-option`, however our current setup where we only set `tabindex="-1"` on it is invalid, because the input is still interactive either through clicking on it, or by using a screen reader's forms mode. These changes completely remove the input from the accessibility model by setting it to `display: none`.
1 parent 71b7b15 commit 4880a5e

File tree

3 files changed

+14
-10
lines changed

3 files changed

+14
-10
lines changed

src/material-experimental/mdc-list/list-option.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
no accidental change event leaks out of the list option or selection list when
1616
the checkbox is directly clicked.
1717
-->
18-
<input type="checkbox" tabindex="-1" class="mdc-checkbox__native-control"
19-
[checked]="selected" [disabled]="disabled" [attr.aria-describedby]="_optionTextId"
20-
(change)="$event.stopPropagation()" />
18+
<input type="checkbox" class="mdc-checkbox__native-control"
19+
[checked]="selected" [disabled]="disabled"
20+
(change)="$event.stopPropagation()"/>
2121
<div class="mdc-checkbox__background">
2222
<svg class="mdc-checkbox__checkmark"
2323
viewBox="0 0 24 24">
@@ -41,7 +41,7 @@
4141
</ng-template>
4242

4343
<!-- Text -->
44-
<span class="mdc-list-item__text" #text [id]="_optionTextId">
44+
<span class="mdc-list-item__text" #text>
4545
<ng-content></ng-content>
4646
</span>
4747

src/material-experimental/mdc-list/list-option.scss

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,13 @@
44
// The MDC-based list-option uses the MDC checkbox for the selection indicators.
55
// We need to ensure that the checkbox styles are included for the list-option.
66
@include mdc-checkbox-without-ripple($query: $mat-base-styles-query);
7+
8+
// The internal checkbox is purely decorative, but because it's an `input`, the user can still
9+
// focus it by tabbing or clicking. Furthermore, `mat-list-option` has the `option` role which
10+
// doesn't allow a nested `input`. We use `display: none` both to remove it from the tab order
11+
// and to prevent focus from reaching it through the screen reader's forms mode. Ideally we'd
12+
// remove the `input` completely, but we can't because MDC uses a `:checked` selector to
13+
// toggle the selected styles.
14+
.mat-mdc-list-option .mdc-checkbox__native-control {
15+
display: none;
16+
}

src/material-experimental/mdc-list/list-option.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@ export interface SelectionList extends MatListBase {
5151
_onTouched: () => void;
5252
}
5353

54-
/** Unique id for created list options. */
55-
let uniqueId = 0;
56-
5754
@Component({
5855
selector: 'mat-list-option',
5956
exportAs: 'matListOption',
@@ -89,9 +86,6 @@ export class MatListOption extends MatListItemBase implements ListOption, OnInit
8986
@ContentChildren(MatLine, {read: ElementRef, descendants: true}) lines:
9087
QueryList<ElementRef<Element>>;
9188

92-
/** Unique id for the text. Used for describing the underlying checkbox input. */
93-
_optionTextId: string = `mat-mdc-list-option-text-${uniqueId++}`;
94-
9589
/** Whether the label should appear before or after the checkbox. Defaults to 'after' */
9690
@Input() checkboxPosition: MatListOptionCheckboxPosition = 'after';
9791

0 commit comments

Comments
 (0)