Skip to content

Commit 6bd3761

Browse files
kseamonandrewseguin
authored andcommitted
perf(material/checkbox): Optimize more expensive selectors (#30409)
(cherry picked from commit 1b3c42e)
1 parent d439703 commit 6bd3761

File tree

2 files changed

+34
-17
lines changed

2 files changed

+34
-17
lines changed

src/material/checkbox/_checkbox-common.scss

+29-16
Original file line numberDiff line numberDiff line change
@@ -119,15 +119,17 @@ $_fallback-size: 40px;
119119
border-color: transparent;
120120
}
121121

122-
.mdc-checkbox:hover .mdc-checkbox__native-control:not(:checked) ~ .mdc-checkbox__background,
122+
// stylelint-disable selector-combinator-space-before
123+
.mdc-checkbox:hover > .mdc-checkbox__native-control:not(:checked) ~ .mdc-checkbox__background,
123124
.mdc-checkbox:hover
124-
.mdc-checkbox__native-control:not(:indeterminate) ~ .mdc-checkbox__background {
125+
> .mdc-checkbox__native-control:not(:indeterminate) ~ .mdc-checkbox__background {
125126
@include token-utils.create-token-slot(border-color, unselected-hover-icon-color);
126127
background-color: transparent;
127128
}
129+
// stylelint-enable selector-combinator-space-before
128130

129-
.mdc-checkbox:hover .mdc-checkbox__native-control:checked ~ .mdc-checkbox__background,
130-
.mdc-checkbox:hover .mdc-checkbox__native-control:indeterminate ~ .mdc-checkbox__background {
131+
.mdc-checkbox:hover > .mdc-checkbox__native-control:checked ~ .mdc-checkbox__background,
132+
.mdc-checkbox:hover > .mdc-checkbox__native-control:indeterminate ~ .mdc-checkbox__background {
131133
@include token-utils.create-token-slot(border-color, selected-hover-icon-color);
132134
@include token-utils.create-token-slot(background-color, selected-hover-icon-color);
133135
}
@@ -147,7 +149,7 @@ $_fallback-size: 40px;
147149

148150
// Needs extra specificity to override the focus, hover, active states.
149151
.mdc-checkbox--disabled.mat-mdc-checkbox-disabled-interactive {
150-
.mdc-checkbox:hover .mdc-checkbox__native-control ~ .mdc-checkbox__background,
152+
.mdc-checkbox:hover > .mdc-checkbox__native-control ~ .mdc-checkbox__background,
151153
.mdc-checkbox .mdc-checkbox__native-control:focus ~ .mdc-checkbox__background,
152154
.mdc-checkbox__background {
153155
@include token-utils.create-token-slot(border-color, disabled-unselected-icon-color);
@@ -306,31 +308,31 @@ $_fallback-size: 40px;
306308
transition: border-color $_transition-duration $_enter-curve,
307309
background-color $_transition-duration $_enter-curve;
308310

309-
.mdc-checkbox__checkmark-path {
311+
> .mdc-checkbox__checkmark > .mdc-checkbox__checkmark-path {
310312
stroke-dashoffset: 0;
311313
}
312314
}
313315

314316
.mdc-checkbox__native-control:checked ~ .mdc-checkbox__background {
315-
.mdc-checkbox__checkmark {
317+
> .mdc-checkbox__checkmark {
316318
transition: opacity $_transition-duration * 2 $_enter-curve,
317319
transform $_transition-duration * 2 $_enter-curve;
318320
opacity: 1;
319321
}
320322

321-
.mdc-checkbox__mixedmark {
323+
> .mdc-checkbox__mixedmark {
322324
transform: scaleX(1) rotate(-45deg);
323325
}
324326
}
325327
.mdc-checkbox__native-control:indeterminate ~ .mdc-checkbox__background {
326-
.mdc-checkbox__checkmark {
328+
> .mdc-checkbox__checkmark {
327329
transform: rotate(45deg);
328330
opacity: 0;
329331
transition: opacity $_transition-duration $_exit-curve,
330332
transform $_transition-duration $_exit-curve;
331333
}
332334

333-
.mdc-checkbox__mixedmark {
335+
> .mdc-checkbox__mixedmark {
334336
transform: scaleX(1) rotate(0deg);
335337
opacity: 1;
336338
}
@@ -445,11 +447,22 @@ $_fallback-size: 40px;
445447

446448
// Conditionally disables the animations of the checkbox.
447449
@mixin checkbox-noop-animations() {
448-
&._mat-animation-noopable .mdc-checkbox {
449-
*, *::before {
450-
transition: none !important;
451-
animation: none !important;
452-
}
450+
&._mat-animation-noopable > .mat-internal-form-field > .mdc-checkbox {
451+
@include checkbox-noop-animations-internal;
452+
}
453+
}
454+
455+
@mixin checkbox-noop-animations-internal() {
456+
> .mat-mdc-checkbox-touch-target,
457+
> .mdc-checkbox__native-control,
458+
> .mdc-checkbox__ripple,
459+
> .mat-mdc-checkbox-ripple::before,
460+
> .mdc-checkbox__background,
461+
> .mdc-checkbox__background > .mdc-checkbox__checkmark,
462+
> .mdc-checkbox__background > .mdc-checkbox__checkmark > .mdc-checkbox__checkmark-path,
463+
> .mdc-checkbox__background > .mdc-checkbox__mixedmark {
464+
transition: none !important;
465+
animation: none !important;
453466
}
454467
}
455468

@@ -465,7 +478,7 @@ $_fallback-size: 40px;
465478
);
466479
}
467480

468-
> .mat-mdc-checkbox-ripple .mat-ripple-element {
481+
> .mat-mdc-checkbox-ripple > .mat-ripple-element {
469482
@include token-utils.create-token-slot(
470483
background-color,
471484
unselected-hover-state-layer-color

src/material/list/list-option.scss

+5-1
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,14 @@
6363
// We can't use the MDC checkbox here directly, because this checkbox is purely
6464
// decorative and including the MDC one will bring in unnecessary JS.
6565
@include checkbox-common.checkbox-structure(false);
66-
@include checkbox-common.checkbox-noop-animations;
6766
@include radio-common.radio-structure(false);
6867
@include radio-common.radio-noop-animations;
6968

69+
&._mat-animation-noopable > .mdc-list-item__start > .mdc-checkbox,
70+
&._mat-animation-noopable > .mdc-list-item__end > .mdc-checkbox {
71+
@include checkbox-common.checkbox-noop-animations-internal;
72+
}
73+
7074
// The internal checkbox/radio is purely decorative, but because it's an `input`, the user can
7175
// still focus it by tabbing or clicking. Furthermore, `mat-list-option` has the `option` role
7276
// which doesn't allow a nested `input`. We use `display: none` both to remove it from the tab

0 commit comments

Comments
 (0)