Skip to content

Commit 85591e2

Browse files
crisbetommalerba
authored andcommitted
fix(material/badge): avoid emitting the structural styles more than once (#23011)
The badge structural styles are currently in the theme, because the badge is a directive and Angular doesn't support associating styles with directives. The problem is that it'll cause the same structural styles to be emitted multiple times unnecessarily. These changes add some logic that will try to prevent the structural styles from being emitted more than once. **Disclaimer:** this change might not work across multiple compilation units, however I still think it's worthwhile, because the apps that only have one global stylesheet for their theme will get the benefit, while everybody else will work the same as before. These changes shave off more than 4kb of minified CSS. (cherry picked from commit b7db96c)
1 parent 3bbae97 commit 85591e2

File tree

1 file changed

+64
-45
lines changed

1 file changed

+64
-45
lines changed

src/material/badge/_badge-theme.scss

Lines changed: 64 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ $font-weight: 600;
1414
$default-size: 22px !default;
1515
$small-size: $default-size - 6;
1616
$large-size: $default-size + 6;
17+
$_badge-structure-emitted: false !default;
1718

1819
// Mixin for building offset given different sizes
1920
@mixin _badge-size($size) {
@@ -93,6 +94,57 @@ $large-size: $default-size + 6;
9394
// stylelint-enable
9495
}
9596

97+
// Structural styles for the badge. They have to be included as a part of the theme,
98+
// because the badge is a directive and we have no other way of attaching styles to it.
99+
@mixin _badge-structure {
100+
.mat-badge {
101+
position: relative;
102+
}
103+
104+
.mat-badge-hidden {
105+
.mat-badge-content {
106+
display: none;
107+
}
108+
}
109+
110+
.mat-badge-content {
111+
position: absolute;
112+
text-align: center;
113+
display: inline-block;
114+
border-radius: 50%;
115+
transition: transform 200ms ease-in-out;
116+
transform: scale(0.6);
117+
overflow: hidden;
118+
white-space: nowrap;
119+
text-overflow: ellipsis;
120+
pointer-events: none;
121+
}
122+
123+
.ng-animate-disabled .mat-badge-content,
124+
.mat-badge-content._mat-animation-noopable {
125+
transition: none;
126+
}
127+
128+
// The active class is added after the element is added
129+
// so it can animate scale to default
130+
.mat-badge-content.mat-badge-active {
131+
// Scale to `none` instead of `1` to avoid blurry text in some browsers.
132+
transform: none;
133+
}
134+
135+
.mat-badge-small {
136+
@include _badge-size($small-size);
137+
}
138+
139+
.mat-badge-medium {
140+
@include _badge-size($default-size);
141+
}
142+
143+
.mat-badge-large {
144+
@include _badge-size($large-size);
145+
}
146+
}
147+
96148
@mixin color($config-or-theme) {
97149
$config: theming.get-color-config($config-or-theme);
98150
$accent: map.get($config, accent);
@@ -125,16 +177,6 @@ $large-size: $default-size + 6;
125177
}
126178
}
127179

128-
.mat-badge {
129-
position: relative;
130-
}
131-
132-
.mat-badge-hidden {
133-
.mat-badge-content {
134-
display: none;
135-
}
136-
}
137-
138180
.mat-badge-disabled {
139181
.mat-badge-content {
140182
$app-background: theming.get-color-from-palette($background, 'background');
@@ -156,41 +198,6 @@ $large-size: $default-size + 6;
156198
color: theming.get-color-from-palette($foreground, disabled-text);
157199
}
158200
}
159-
160-
.mat-badge-content {
161-
position: absolute;
162-
text-align: center;
163-
display: inline-block;
164-
border-radius: 50%;
165-
transition: transform 200ms ease-in-out;
166-
transform: scale(0.6);
167-
overflow: hidden;
168-
white-space: nowrap;
169-
text-overflow: ellipsis;
170-
pointer-events: none;
171-
}
172-
173-
.ng-animate-disabled .mat-badge-content,
174-
.mat-badge-content._mat-animation-noopable {
175-
transition: none;
176-
}
177-
178-
// The active class is added after the element is added
179-
// so it can animate scale to default
180-
.mat-badge-content.mat-badge-active {
181-
// Scale to `none` instead of `1` to avoid blurry text in some browsers.
182-
transform: none;
183-
}
184-
185-
.mat-badge-small {
186-
@include _badge-size($small-size);
187-
}
188-
.mat-badge-medium {
189-
@include _badge-size($default-size);
190-
}
191-
.mat-badge-large {
192-
@include _badge-size($large-size);
193-
}
194201
}
195202

196203
@mixin typography($config-or-theme) {
@@ -221,6 +228,18 @@ $large-size: $default-size + 6;
221228
$density: theming.get-density-config($theme);
222229
$typography: theming.get-typography-config($theme);
223230

231+
// Try to reduce the number of times that the structural styles are emitted.
232+
@if not $_badge-structure-emitted {
233+
@include _badge-structure;
234+
235+
// Only flip the flag if the mixin is included at the top level. Otherwise the first
236+
// inclusion might be inside of a theme class which will exclude the structural styles
237+
// from all other themes.
238+
@if not & {
239+
$_badge-structure-emitted: true !global;
240+
}
241+
}
242+
224243
@if $color != null {
225244
@include color($color);
226245
}

0 commit comments

Comments
 (0)