Skip to content

Commit 22bd693

Browse files
crisbetoannieyw
authored andcommitted
fix(material-experimental/mdc-list): make internal input non-interactive (#21438)
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`. (cherry picked from commit c268246)
1 parent bc5c3a7 commit 22bd693

File tree

3 files changed

+13
-15
lines changed

3 files changed

+13
-15
lines changed

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

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,8 @@
99

1010
<ng-template #checkbox>
1111
<div class="mdc-checkbox" [class.mdc-checkbox--disabled]="disabled">
12-
<!--
13-
Note: We stop propagation of the change event for the indicator checkbox so that
14-
no accidental change event leaks out of the list option or selection list when
15-
the checkbox is directly clicked.
16-
-->
17-
<input type="checkbox" tabindex="-1" class="mdc-checkbox__native-control"
18-
[checked]="selected" [disabled]="disabled" [attr.aria-describedby]="_optionTextId"
19-
(change)="$event.stopPropagation()" />
12+
<input type="checkbox" class="mdc-checkbox__native-control"
13+
[checked]="selected" [disabled]="disabled"/>
2014
<div class="mdc-checkbox__background">
2115
<svg class="mdc-checkbox__checkmark"
2216
viewBox="0 0 24 24">
@@ -37,7 +31,7 @@
3731
</span>
3832

3933
<!-- Text -->
40-
<span class="mdc-list-item__text" #text [id]="_optionTextId">
34+
<span class="mdc-list-item__text" #text>
4135
<ng-content></ng-content>
4236
</span>
4337

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
@@ -50,9 +50,6 @@ export interface SelectionList extends MatListBase {
5050
_onTouched: () => void;
5151
}
5252

53-
/** Unique id for created list options. */
54-
let uniqueId = 0;
55-
5653
@Component({
5754
selector: 'mat-list-option',
5855
exportAs: 'matListOption',
@@ -86,9 +83,6 @@ export class MatListOption extends MatListItemBase implements OnInit, OnDestroy
8683
@ContentChildren(MatLine, {read: ElementRef, descendants: true}) lines:
8784
QueryList<ElementRef<Element>>;
8885

89-
/** Unique id for the text. Used for describing the underlying checkbox input. */
90-
_optionTextId: string = `mat-mdc-list-option-text-${uniqueId++}`;
91-
9286
/** Whether the label should appear before or after the checkbox. Defaults to 'after' */
9387
@Input() checkboxPosition: 'before' | 'after' = 'after';
9488

0 commit comments

Comments
 (0)